@@ -23,9 +23,10 @@ namespace CSharpCodeAnalyst.GraphArea;
2323/// </summary>
2424internal class DependencyGraphViewer : IDependencyGraphViewer , IDependencyGraphBinding , INotifyPropertyChanged
2525{
26- private readonly List < IContextCommand > _contextMenuCommands = [ ] ;
27- private readonly List < IGlobalContextCommand > _globalContextMenuCommands = [ ] ;
26+ private readonly List < IDependencyContextCommand > _edgeCommands = [ ] ;
27+ private readonly List < IGlobalContextCommand > _globalCommands = [ ] ;
2828 private readonly MsaglBuilder _msaglBuilder ;
29+ private readonly List < ICodeElementContextCommand > _nodeCommands = [ ] ;
2930 private readonly IPublisher _publisher ;
3031
3132 private IHighlighting _activeHighlighting = new EdgeHoveredHighlighting ( ) ;
@@ -86,14 +87,19 @@ public void AddToGraph(IEnumerable<CodeElement> originalCodeElements, IEnumerabl
8687 RefreshGraph ( ) ;
8788 }
8889
89- public void AddContextMenuCommand ( IContextCommand command )
90+ public void AddContextMenuCommand ( ICodeElementContextCommand command )
9091 {
91- _contextMenuCommands . Add ( command ) ;
92+ _nodeCommands . Add ( command ) ;
93+ }
94+
95+ public void AddContextMenuCommand ( IDependencyContextCommand command )
96+ {
97+ _edgeCommands . Add ( command ) ;
9298 }
9399
94100 public void AddGlobalContextMenuCommand ( IGlobalContextCommand command )
95101 {
96- _globalContextMenuCommands . Add ( command ) ;
102+ _globalCommands . Add ( command ) ;
97103 }
98104
99105 public void Layout ( )
@@ -126,7 +132,7 @@ public void SaveToSvg(FileStream stream)
126132
127133 public void SetHighlightMode ( HighlightMode valueMode )
128134 {
129- _activeHighlighting ? . Clear ( _msaglViewer ) ;
135+ _activeHighlighting . Clear ( _msaglViewer ) ;
130136 switch ( valueMode )
131137 {
132138 case HighlightMode . EdgeHovered :
@@ -166,7 +172,7 @@ public void ShowGlobalContextMenu()
166172 . Select ( id => _clonedCodeGraph . Nodes [ id ] )
167173 . ToList ( ) ;
168174
169- foreach ( var command in _globalContextMenuCommands )
175+ foreach ( var command in _globalCommands )
170176 {
171177 if ( command . CanHandle ( markedElements ) is false )
172178 {
@@ -201,6 +207,21 @@ public void Clear()
201207 RefreshGraph ( ) ;
202208 }
203209
210+ public void DeleteFromGraph ( List < Dependency > dependencies )
211+ {
212+ if ( _msaglViewer is null )
213+ {
214+ return ;
215+ }
216+
217+ foreach ( var dependency in dependencies )
218+ {
219+ _clonedCodeGraph . Nodes [ dependency . SourceId ] . Dependencies . Remove ( dependency ) ;
220+ }
221+
222+ RefreshGraph ( ) ;
223+ }
224+
204225 public void DeleteFromGraph ( HashSet < string > idsToRemove )
205226 {
206227 if ( _msaglViewer is null )
@@ -390,59 +411,116 @@ bool IsCtrlPressed()
390411
391412 if ( e . RightButtonIsPressed )
392413 {
393- if ( _msaglViewer ? . ObjectUnderMouseCursor is not IViewerNode clickedObject )
414+ if ( _msaglViewer ? . ObjectUnderMouseCursor is IViewerNode clickedObject )
394415 {
395- return ;
416+ // Click on specific node
417+ var node = clickedObject . Node ;
418+ var contextMenu = new ContextMenu ( ) ;
419+ var element = GetCodeElementFromUserData ( node ) ;
420+ AddToContextMenuEntries ( element , contextMenu ) ;
421+ if ( contextMenu . Items . Count > 0 )
422+ {
423+ contextMenu . IsOpen = true ;
424+ }
425+ }
426+ else if ( _msaglViewer ? . ObjectUnderMouseCursor is IViewerEdge viewerEdge )
427+ {
428+ // Click on specific edge
429+ var edge = viewerEdge . Edge ;
430+ var contextMenu = new ContextMenu ( ) ;
431+ var dependencies = GetDependenciesFromUserData ( edge ) ;
432+ AddContextMenuEntries ( dependencies , contextMenu ) ;
433+ if ( contextMenu . Items . Count > 0 )
434+ {
435+ contextMenu . IsOpen = true ;
436+ }
437+ }
438+ else
439+ {
440+ // Click on free space
441+ ShowGlobalContextMenu ( ) ;
396442 }
397-
398- // Click on specific node
399- var node = clickedObject . Node ;
400- var contextMenu = new ContextMenu ( ) ;
401-
402- AddToContextMenuEntries ( node , contextMenu ) ;
403-
404- contextMenu . IsOpen = true ;
405443 }
406444 else
407445 {
408446 e . Handled = false ;
409447 }
410448 }
411449
450+ private void AddContextMenuEntries ( List < Dependency > dependencies , ContextMenu contextMenu )
451+ {
452+ if ( dependencies . Count == 0 )
453+ {
454+ return ;
455+ }
456+
457+ foreach ( var cmd in _edgeCommands )
458+ {
459+ var menuItem = new MenuItem { Header = cmd . Label } ;
460+ if ( cmd . CanHandle ( dependencies ) )
461+ {
462+ menuItem . Click += ( _ , _ ) => cmd . Invoke ( dependencies ) ;
463+ contextMenu . Items . Add ( menuItem ) ;
464+ }
465+ }
466+ }
467+
468+ private static List < Dependency > GetDependenciesFromUserData ( Edge edge )
469+ {
470+ var result = new List < Dependency > ( ) ;
471+ switch ( edge . UserData )
472+ {
473+ case Dependency dependency :
474+ result . Add ( dependency ) ;
475+ break ;
476+ case List < Dependency > dependencies :
477+ result . AddRange ( dependencies ) ;
478+ break ;
479+ }
480+
481+ return result ;
482+ }
483+
484+ private CodeElement ? GetCodeElementFromUserData ( Node node )
485+ {
486+ return node . UserData as CodeElement ;
487+ }
412488
413489 /// <summary>
414490 /// Commands registered for nodes
415491 /// </summary>
416- private void AddToContextMenuEntries ( Node node , ContextMenu contextMenu )
492+ private void AddToContextMenuEntries ( CodeElement ? element , ContextMenu contextMenu )
417493 {
494+ if ( element is null )
495+ {
496+ return ;
497+ }
498+
418499 var lastItemIsSeparator = true ;
419500
420- if ( node . UserData is CodeElement element )
501+ foreach ( var cmd in _nodeCommands )
421502 {
422- foreach ( var cmd in _contextMenuCommands )
503+ // Add separator command only if the last element was a real menu item.
504+ if ( cmd is SeparatorCommand )
423505 {
424- // Add separator command only if the last element was a real menu item.
425- if ( cmd is SeparatorCommand )
506+ if ( lastItemIsSeparator is false )
426507 {
427- if ( lastItemIsSeparator is false )
428- {
429- contextMenu . Items . Add ( new Separator ( ) ) ;
430- lastItemIsSeparator = true ;
431- }
432-
433- continue ;
508+ contextMenu . Items . Add ( new Separator ( ) ) ;
509+ lastItemIsSeparator = true ;
434510 }
435511
436- if ( ! cmd . CanHandle ( element ) )
437- {
438- continue ;
439- }
512+ continue ;
513+ }
440514
441- var menuItem = new MenuItem { Header = cmd . Label } ;
442- menuItem . Click += ( _ , _ ) => cmd . Invoke ( element ) ;
443- contextMenu . Items . Add ( menuItem ) ;
444- lastItemIsSeparator = false ;
515+ if ( ! cmd . CanHandle ( element ) )
516+ {
517+ continue ;
445518 }
519+
520+ var menuItem = new MenuItem { Header = cmd . Label } ;
521+ menuItem . Click += ( _ , _ ) => cmd . Invoke ( element ) ;
522+ contextMenu . Items . Add ( menuItem ) ;
523+ lastItemIsSeparator = false ;
446524 }
447525 }
448526}
0 commit comments