/// <summary> /// Supports a custom context menu. /// </summary> public override void PopulateContextMenu(PopulateItemContextMenuEventArgs <IModelItem> args) { var graph = args.Context.GetGraph(); var contextMenu = args.Menu; var graphComponent = (GraphControl)args.Context.CanvasControl; var item = args.Item as INode; if (algorithmType == PathsMode.ShortestPaths) { if (item != null) { UpdateSelection(item, graphComponent); } var selectedNodes = graphComponent.Selection.SelectedNodes; if (selectedNodes.Count > 0) { var markAsSource = new MenuItem { Header = "Mark as Source" }; markAsSource.Click += (sender, eventArgs) => { markedSources = selectedNodes.ToList(); RunAlgorithm(graph); }; contextMenu.Items.Add(markAsSource); var markAsTarget = new MenuItem { Header = "Mark as Target" }; markAsTarget.Click += (sender, eventArgs) => { markedTargets = selectedNodes.ToList(); RunAlgorithm(graph); }; contextMenu.Items.Add(markAsTarget); } } else if (algorithmType != PathsMode.AllChains) { if (item != null) { var markAsSource = new MenuItem { Header = "Mark as Source" }; markAsSource.Click += (sender, eventArgs) => { markedSources = new [] { item }.ToList(); RunAlgorithm(graph); }; contextMenu.Items.Add(markAsSource); if (algorithmType != PathsMode.SingleSource) { var markAsTarget = new MenuItem { Header = "Mark as Target" }; markAsTarget.Click += (sender, eventArgs) => { markedTargets = new[] { item }.ToList(); RunAlgorithm(graph); }; contextMenu.Items.Add(markAsTarget); } } } }
/// <summary> /// Fills the context menu with menu items based on the clicked node. /// </summary> private void OnPopulateItemContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> e) { // first update the selection INode node = e.Item as INode; // if the cursor is over a node select it, else clear selection UpdateSelection(node); // Create the context menu items if (graphControl.Selection.SelectedNodes.Count > 0) { // at least one node is selected e.Menu.Items.Add(Commands.Cut, graphControl); e.Menu.Items.Add(Commands.Copy, graphControl); e.Menu.Items.Add(Commands.Paste, e.QueryLocation, graphControl); e.Menu.Items.Add(Commands.Delete, graphControl); } else { // no node has been hit var selectAllItem = new ToolStripMenuItem("Select all"); selectAllItem.Click += (o, args) => { graphEditorInputMode.SelectAll(); }; e.Menu.Items.Add(selectAllItem); e.Menu.Items.Add(Commands.Paste, e.QueryLocation, graphControl); } // open the menu e.ShowMenu = true; // mark the event as handled e.Handled = true; }
private void ContextMenuInputModePopulateContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> e) { var node = e.Item as INode; // create a menu item to toggle the assistant status bool assistant = assistants[node]; var menuItem = new MenuItem { Header = "Set as " + (assistant ? "normal" : "assistant") }; menuItem.Click += async delegate { //Toggle the value in the map and set the style to indicate an assistant node assistants[node] = !assistant; var shinyPlateNodeStyle = node.Style.Clone() as ShinyPlateNodeStyle; if (shinyPlateNodeStyle != null) { shinyPlateNodeStyle.Pen = !assistant ? new Pen(Brushes.Black, 2) { DashStyle = DashStyles.Dash } : null; graphControl.Graph.SetStyle(node, shinyPlateNodeStyle); } await ApplyLayout(); }; e.Menu.Items.Add(menuItem); e.ShowMenu = true; e.Handled = true; }
/// <summary> /// Event handler for the context menu for stripe header /// </summary> /// <remarks>We show only a simple context menu that demonstrates the <see cref="TableEditorInputMode.InsertChild"/> convenience method.</remarks> private void graphEditorInputMode_PopulateItemContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> e) { if (!e.Handled) { var stripe = GetStripe(e.QueryLocation); if (stripe != null) { var deleteItem = new ToolStripMenuItem { Text = "Delete " + stripe.Stripe }; deleteItem.SetCommand(Commands.Delete, stripe.Stripe, graphControl); e.Menu.Items.Add(deleteItem); var insertBeforeItem = new ToolStripMenuItem { Text = "Insert new stripe before " + stripe.Stripe }; insertBeforeItem.Click += delegate { IStripe parent = stripe.Stripe.GetParentStripe(); int index = stripe.Stripe.GetIndex(); tableEditorInputMode.InsertChild(parent, index); }; e.Menu.Items.Add(insertBeforeItem); var insertAfterItem = new ToolStripMenuItem { Text = "Insert new stripe after " + stripe.Stripe }; insertAfterItem.Click += delegate { IStripe parent = stripe.Stripe.GetParentStripe(); int index = stripe.Stripe.GetIndex(); tableEditorInputMode.InsertChild(parent, index + 1); }; e.Menu.Items.Add(insertAfterItem); e.Handled = true; } } }
/// <summary> /// Opens a context menu to change the type of a node. /// </summary> private void OnPopulateItemContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> args) { if (args.Item is INode) { // Select node if not already selected if (!graphControl.Selection.IsSelected(args.Item)) { graphControl.Selection.Clear(); graphControl.Selection.SetSelected(args.Item, true); } for (int type = 0; type < nodeStyles.Length; type++) { var nodeStyle = nodeStyles[type]; var menuItem = new ToolStripMenuItem { Image = CreateColoredRectangle(nodeStyle.Brush, nodeStyle.Pen), }; var type1 = type; menuItem.Click += async(o, eventArgs) => { foreach (var node in graphControl.Selection.SelectedNodes) { node.Tag = type1; GraphControl.Graph.SetStyle(node, nodeStyle); } await ApplyLayout(true); }; args.Menu.Items.Add(menuItem); } } }
/// <summary> /// Populates the context menu for nodes. /// </summary> private void PopulateNodeContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> e) { var node = e.Item as INode; var selection = graphControl.Selection.SelectedNodes; if (node != null) { if (!selection.IsSelected(node)) { selection.Clear(); selection.SetSelected(node, true); graphControl.CurrentItem = node; } } if (selection.Count > 0) { var markAsSourceItem = new MenuItem { Header = "Mark as Source" }; markAsSourceItem.Click += async(o, args) => await MarkAsSource(selection.ToList()); e.Menu.Items.Add(markAsSourceItem); var markAsTargetItem = new MenuItem { Header = "Mark as Target" }; markAsTargetItem.Click += async(o, args) => await MarkAsTarget(selection.ToList()); e.Menu.Items.Add(markAsTargetItem); // check if one or more of the selected nodes are already marked as source or target bool marked = false; foreach (INode n in selection) { if (sourceNodes.Contains(n) || targetNodes.Contains(n)) { marked = true; break; } } if (marked) { // add the 'Remove Mark' item var removeMarkItem = new MenuItem { Header = "Remove Mark" }; removeMarkItem.Click += async delegate { List <INode> sn = sourceNodes.ToList(); sn.RemoveAll((node1 => selection.IsSelected(node1))); await MarkAsSource(sn); List <INode> tn = targetNodes.ToList(); tn.RemoveAll((node1 => selection.IsSelected(node1))); await MarkAsTarget(tn); }; e.Menu.Items.Add(removeMarkItem); } } e.Handled = true; }
/// <summary> /// Called when the context menu should be populated for a given item. /// </summary> /// <param name="sender">The sender.</param> /// <param name="populateItemContextMenuEventArgs">The event argument instance containing the event data.</param> private void OnPopulateItemContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> populateItemContextMenuEventArgs) { // see if it's a node but not a not empty group node INode node = populateItemContextMenuEventArgs.Item as INode; if (node != null && graphControl.Graph.GetChildren(node).Count == 0) { // see if it's already selected var selectedNodes = graphControl.Selection.SelectedNodes; if (!selectedNodes.IsSelected(node)) { // no - make it the only selected node selectedNodes.Clear(); } // make sure the node is selected selectedNodes.SetSelected(node, true); graphControl.CurrentItem = node; // mark all selected nodes for incremental layout var item = new MenuItem { Header = "Reinsert Incrementally" }; item.Click += delegate(object o, RoutedEventArgs args) { incrementalNodes.AddRange(selectedNodes); UpdateLayout(o, args); }; populateItemContextMenuEventArgs.Menu.Items.Add(item); populateItemContextMenuEventArgs.Handled = true; } // if it's an edge... IEdge edge = populateItemContextMenuEventArgs.Item as IEdge; if (edge != null) { // update selection state var selectedEdges = graphControl.Selection.SelectedEdges; if (!selectedEdges.IsSelected(edge)) { selectedEdges.Clear(); } selectedEdges.SetSelected(edge, true); graphControl.CurrentItem = edge; // and offer option to reroute selected edges var item = new MenuItem { Header = "Reroute" }; item.Click += delegate(object o, RoutedEventArgs args) { incrementalEdges.AddRange(selectedEdges); UpdateLayout(o, args); }; populateItemContextMenuEventArgs.Menu.Items.Add(item); populateItemContextMenuEventArgs.Handled = true; } }
/// <summary> /// Adds a context menu to mark the source node for the reachability algorithm. /// </summary> public override void PopulateContextMenu(PopulateItemContextMenuEventArgs <IModelItem> args) { var item = args.Item as INode; if (item != null) { var menuItem = new ToolStripMenuItem("Mark as Source"); menuItem.Click += (o, e) => { markedSource = item; var graph = args.Context.GetGraph(); ResetGraph(graph); RunAlgorithm(graph); }; args.Menu.Items.Add(menuItem); } }
/// <summary> /// Event handler for the context menu other hits on a node. /// </summary> /// <remarks>We show only a dummy context menu to demonstrate the basic principle.</remarks> private void graphEditorInputMode_PopulateNodeContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> e) { if (!e.Handled) { IModelItem tableNode = graphEditorInputMode.FindItems(e.QueryLocation, new[] { GraphItemTypes.Node }, (item) => item.Lookup <ITable>() != null).FirstOrDefault(); if (tableNode != null) { var cutItem = new ToolStripMenuItem { Text = "ContextMenu for " + tableNode }; e.Menu.Items.Add(cutItem); e.Handled = true; } } }
/// <summary> /// Fills the context menu with menu items based on the clicked node. /// </summary> private void OnPopulateItemContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> e) { // first update the selection INode node = e.Item as INode; // if the cursor is over a node select it, else clear selection UpdateSelection(node); // Create the context menu items if (graphControl.Selection.SelectedNodes.Count > 0) { // at least one node is selected var cutItem = new MenuItem { Command = ApplicationCommands.Cut }; e.Menu.Items.Add(cutItem); var copyItem = new MenuItem { Command = ApplicationCommands.Copy }; e.Menu.Items.Add(copyItem); var deleteItem = new MenuItem { Command = ApplicationCommands.Delete }; e.Menu.Items.Add(deleteItem); } else { // no node has been hit var selectAllItem = new MenuItem { Header = "Select all" }; selectAllItem.Click += (o, args) => { graphEditorInputMode.SelectAll(); }; e.Menu.Items.Add(selectAllItem); var pasteItem = new MenuItem { Command = ApplicationCommands.Paste, CommandParameter = e.QueryLocation }; e.Menu.Items.Add(pasteItem); } // open the menu e.ShowMenu = true; // mark the event as handled e.Handled = true; }
/// <summary> /// Opens a context menu to change the type of a node. /// </summary> private void OnPopulateItemContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> args) { if (args.Item is INode) { // Select node if not already selected if (!graphControl.Selection.IsSelected(args.Item)) { graphControl.Selection.Clear(); graphControl.Selection.SetSelected(args.Item, true); } for (int type = 0; type < nodeStyles.Length; type++) { var nodeStyle = nodeStyles[type]; var menuItem = new MenuItem { Header = new Rectangle { Fill = nodeStyle.Brush, Width = 50, Height = 20, Stroke = nodeStyle.Pen.Brush, Margin = new Thickness(5) } }; var type1 = type; menuItem.Click += async(o, eventArgs) => { foreach (var node in graphControl.Selection.SelectedNodes) { node.Tag = type1; GraphControl.Graph.SetStyle(node, nodeStyle); } await ApplyLayout(true); }; args.Menu.Items.Add(menuItem); } } }
/// <summary> /// Fills the context menu with menu items based on the clicked node. /// </summary> private void OnPopulateItemContextMenu(object sender, PopulateItemContextMenuEventArgs <IModelItem> e) { // first update the selection INode node = e.Item as INode; // if the cursor is over a node select it, else clear selection UpdateSelection(node); // Create the context menu items var selectedNodes = graphControl.Selection.SelectedNodes; if (selectedNodes.Count > 0) { // only allow aggregation operations on nodes that are not aggregation nodes already var aggregateAllowed = selectedNodes.Any(n => !AggregateGraph.IsAggregationItem(n)); var aggregateByShape = new ToolStripMenuItem("Aggregate Nodes with Same Shape") { Enabled = aggregateAllowed }; aggregateByShape.Click += (o, args) => AggregateSame(selectedNodes.ToList(), ShapeSelector, ShapeStyle); e.Menu.Items.Add(aggregateByShape); var aggregateByColor = new ToolStripMenuItem("Aggregate Nodes with Same Color") { Enabled = aggregateAllowed }; aggregateByColor.Click += (o, args) => AggregateSame(selectedNodes.ToList(), ColorSelector, ColorStyle); e.Menu.Items.Add(aggregateByColor); var aggregateByShapeAndColor = new ToolStripMenuItem("Aggregate Nodes with Same Shape and Color") { Enabled = aggregateAllowed }; aggregateByShapeAndColor.Click += (o, args) => AggregateSame(selectedNodes.ToList(), ShapeAndColorSelector, ShapeAndColorStyle); e.Menu.Items.Add(aggregateByShapeAndColor); var separateAllowed = selectedNodes.Any(n => AggregateGraph.IsAggregationItem(n)); var separate = new ToolStripMenuItem("Separate") { Enabled = separateAllowed }; separate.Click += (o, args) => Separate(selectedNodes.ToList()); e.Menu.Items.Add(separate); } else { var aggregateByShape = new ToolStripMenuItem("Aggregate All Nodes by Shape"); aggregateByShape.Click += (o, args) => AggregateAll(ShapeSelector, ShapeStyle); e.Menu.Items.Add(aggregateByShape); var aggregateByColor = new ToolStripMenuItem("Aggregate All Nodes by Color"); aggregateByColor.Click += (o, args) => AggregateAll(ColorSelector, ColorStyle); e.Menu.Items.Add(aggregateByColor); var aggregateByShapeAndColor = new ToolStripMenuItem("Aggregate All Nodes by Shape and Color"); aggregateByShapeAndColor.Click += (o, args) => AggregateAll(ShapeAndColorSelector, ShapeAndColorStyle); e.Menu.Items.Add(aggregateByShapeAndColor); var separateAllowed = Graph.Nodes.Any(n => AggregateGraph.IsAggregationItem(n)); var separateAll = new ToolStripMenuItem("Separate All") { Enabled = separateAllowed }; separateAll.Click += (o, args) => { AggregateGraph.SeparateAll(); RunLayout(); }; e.Menu.Items.Add(separateAll); } e.ShowMenu = true; e.Handled = true; }
/// <summary> /// Populate the context menu specifically for the current algorithm. /// </summary> public virtual void PopulateContextMenu(PopulateItemContextMenuEventArgs <IModelItem> args) { }