private void InitializeInputMode() { GraphEditorInputMode mode = new GraphEditorInputMode(); // add a label to each created node mode.NodeCreated += (sender, args) => { var graph = mode.GraphControl.Graph; graph.AddLabel(args.Item, "Node " + graph.Nodes.Count); }; // customize hit test order to simplify click selecting labels mode.ClickHitTestOrder = new[] { GraphItemTypes.EdgeLabel, GraphItemTypes.NodeLabel, GraphItemTypes.Bend, GraphItemTypes.Edge, GraphItemTypes.Node, GraphItemTypes.Port, GraphItemTypes.All }; graphControl.InputMode = mode; }
private void InitializeInputModes() { // Create a GraphEditorInputMode instance var editMode = new GraphEditorInputMode(); // and install the edit mode into the canvas. graphControl.InputMode = editMode; // create the model for the export rectangle exportRect = new MutableRectangle(0, 0, 100, 100); // visualize it new RectangleIndicatorInstaller(exportRect, RectangleIndicatorInstaller.SelectionTemplateKey) .AddCanvasObject(graphControl.CanvasContext, graphControl.BackgroundGroup, exportRect); AddExportRectInputModes(editMode); }
/// <summary> /// Registers the <see cref="GraphEditorInputMode"/> as the <see cref="CanvasControl.InputMode"/> /// and initializes an <see cref="IPositionHandler"/> that moves a node and its subtree. /// </summary> private void InitializeInputModes() { // create a GraphEditorInputMode instance var editMode = new GraphEditorInputMode { MoveUnselectedInputMode = { Enabled = true }, MovableItems = GraphItemTypes.Node, SelectableItems = GraphItemTypes.None, AllowCreateBend = false, }; // use special position handler to moves a node and its subtree Graph.GetDecorator().NodeDecorator.PositionHandlerDecorator .SetImplementationWrapper((node, handler) => new SubtreePositionHandler(node, handler)); // and install the edit mode into the canvas GraphControl.InputMode = editMode; }
/// <summary> /// Registers the <see cref="GraphEditorInputMode"/> as the <see cref="CanvasControl.InputMode"/> /// and initializes the rectangular area so that it is drawn and can be moved and resized. /// </summary> private void InitializeInputModes() { // create a GraphEditorInputMode instance var editMode = new GraphEditorInputMode(); // and install the edit mode into the canvas. GraphControl.InputMode = editMode; // create the model for the rectangular area clearRect = new MutableRectangle(0, 0, 100, 100); // visualize it new RectangleIndicatorInstaller(clearRect, ClearRectTemplateKey) .AddCanvasObject(GraphControl.CanvasContext, GraphControl.HighlightGroup, clearRect); AddClearRectInputModes(editMode); }
private void InitializeSnapping() { // Initialize snapping state SnappingEnabled = snappingButton.IsChecked ?? false; // Initialize SnapContext GraphEditorInputMode geim = graphControl.InputMode as GraphEditorInputMode; if (geim != null) { snapContext = new GraphSnapContext { Enabled = SnappingEnabled, }; geim.SnapContext = snapContext; } }
/// <summary> /// Initializes the edit mode and the context menu. /// </summary> private void InitializeInputModes() { var editMode = new GraphEditorInputMode { SelectableItems = GraphItemTypes.Node | GraphItemTypes.Edge, ContextMenuItems = GraphItemTypes.Node, NodeCreator = (context, graph, location, parent) => { var node = graph.CreateNode(location); node.Tag = 0; graph.SetStyle(node, GetNodeStyle(node)); return(node); } }; editMode.PopulateItemContextMenu += OnPopulateItemContextMenu; GraphControl.InputMode = editMode; }
/// <summary> /// Adds a context menu for nodes /// </summary> private void SetupContextMenu() { GraphEditorInputMode mode = graphControl.InputMode as GraphEditorInputMode; if (mode != null) { mode.ContextMenuItems = GraphItemTypes.Node; mode.PopulateItemContextMenu += (sender, e) => { var node = e.Item as INode; if (node != null) { // add a context menu entry e.Menu.Items.Add("Set to now", null, (o, args) => SetToNow(node)); } }; } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); graphControl.Graph.NodeDefaults.Style = new ShinyPlateNodeStyle { Brush = Brushes.Orange }; var graphEditorInputMode = new GraphEditorInputMode(); graphControl.InputMode = graphEditorInputMode; oldPasteItems = graphEditorInputMode.PasteSelectableItems; EnableSingleSelection(true); LoadGraph(); graphControl.FitGraphBounds(); }
public ContextMenuForm() { InitializeComponent(); // initialize input mode graphEditorInputMode = new GraphEditorInputMode(); graphControl.InputMode = graphEditorInputMode; RegisterContextMenuCallback(); // load description description.LoadFile(new MemoryStream(Resources.description), RichTextBoxStreamType.RichText); // Set a nicer node style and create the sample graph graphControl.Graph.NodeDefaults.Style = new ShinyPlateNodeStyle { Brush = Brushes.Orange }; CreateSampleGraph(graphControl.Graph); }
public void InitializeInputModes() { // Create a default editor input mode GraphEditorInputMode editMode = new GraphEditorInputMode(); // then customize it to suit our needs // orthogonal edges editMode.OrthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext(); // snapping editMode.SnapContext = new GraphSnapContext() { CollectEdgeSnapLines = false, CollectNodePairSegmentSnapLines = false, CollectNodePairSnapLines = false, CollectPortSnapLines = false, SnapBendAdjacentSegments = false, SnapPortAdjacentSegments = false, SnapBendsToSnapLines = false, SnapSegmentsToSnapLines = false, GridSnapType = GridSnapTypes.All, NodeGridConstraintProvider = new GridConstraintProvider <INode>(20), GridSnapDistance = double.MaxValue, VisualizeSnapResults = false, }; // tweak the CreateEdgeInputMode editMode.CreateEdgeInputMode.ShowPortCandidates = ShowPortCandidates.None; editMode.CreateEdgeInputMode.SnapToTargetCandidate = false; //Enable label editing only for edges and edge labels editMode.LabelEditableItems = GraphItemTypes.Edge | GraphItemTypes.EdgeLabel; // customize the node creation editMode.NodeCreator = CreateNode; // disable default behavior for auto resize editMode.AvailableCommands.Remove(NodeControl.UpdateNodeSizeCommand); // and finally register our input mode with the control. graphControl.InputMode = editMode; }
/// <summary> /// Setup tooltips that return the value that is stored in the mapper. /// </summary> /// <remarks> /// Dynamic tooltips are implemented by adding a tooltip provider as an event handler for the /// <see cref="GraphEditorInputMode.QueryItemToolTip" /> event of the GraphEditorInputMode using the /// <see cref="QueryItemToolTipEventArgs{T}" /> parameter. This parameter provides three relevant /// properties: /// <list type="bullet"> /// <item> /// <description> /// The <see cref="ToolTipQueryEventArgs.Handled" /> property is a flag which indicates /// whether the tooltip was already set by one of possibly several tooltip providers. /// </description> /// </item> /// <item> /// <description> /// The <see cref="QueryItemToolTipEventArgs{T}.Item" /> property contains the <see cref="IModelItem" /> /// the mouse hovers over. /// </description> /// </item> /// <item> /// <description> /// The tooltip is set by setting the <see cref="ToolTipQueryEventArgs.ToolTip" /> /// property. /// </description> /// </item> /// </list> /// </remarks> private void SetupTooltips() { GraphEditorInputMode geim = graphControl.InputMode as GraphEditorInputMode; if (geim != null) { geim.ToolTipItems = GraphItemTypes.Node; geim.QueryItemToolTip += delegate(object src, QueryItemToolTipEventArgs <IModelItem> eventArgs) { if (eventArgs.Handled) { // A tooltip has already been assigned -> nothing to do. return; } INode hitNode = eventArgs.Item as INode; if (hitNode == null) { return; } // Since the node the user interacts with is an instance on the managed view, // rather than on the master graph to which we've bound our data, // we retrieve the mapper indirectly through its symbolic name. // The folding framework automagically returns an IMapper instance that translates // to the original elements. If we were not using folding, this step would be unnecessary // and we could use the mapper instance directly on the original nodes. IMapperRegistry registry = Graph.MapperRegistry; IMapper <INode, DateTime> dateMapper = registry.GetMapper <INode, DateTime>(DateTimeMapperKey); if (dateMapper != null) { // Found a suitable mapper. // Finds out if a node is under the current location. // Set the tooltip. eventArgs.ToolTip = dateMapper[hitNode].ToString(); // Indicate that the tooltip has been set. eventArgs.Handled = true; } }; // Add a little offset to the tooltip such that it is not obscured by the mouse pointer. geim.MouseHoverInputMode.ToolTipLocationOffset = new PointD(20, 20); } }
private void OnWindowLoaded(object sender, RoutedEventArgs e) { // Create a default editor input mode GraphEditorInputMode graphEditorInputMode = new GraphEditorInputMode(); // Enable orthogonal edge editing graphEditorInputMode.OrthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext(); // Just for user convenience: disable node and edge creation, graphEditorInputMode.AllowCreateEdge = false; graphEditorInputMode.AllowCreateNode = false; graphEditorInputMode.AllowClipboardOperations = false; // disable deleting items graphEditorInputMode.DeletableItems = GraphItemTypes.None; // disable grouping operations graphEditorInputMode.AllowGroupingOperations = false; graphEditorInputMode.AllowReparentNodes = false; // enable snapping for edges only, graphEditorInputMode.SnapContext = new GraphSnapContext() { CollectNodeSnapLines = false, CollectNodePairCenterSnapLines = false, CollectNodePairSnapLines = false, CollectNodePairSegmentSnapLines = false, CollectNodeSizes = false, SnapNodesToSnapLines = false, SnapOrthogonalMovement = false }; graphControl.Graph.SetUndoEngineEnabled(true); // Finally, set the input mode to the graph control. graphControl.InputMode = graphEditorInputMode; // Disable auto-cleanup of ports since the purple nodes have explicit ports graphControl.Graph.NodeDefaults.Ports.AutoCleanUp = false; // Create and register the edge decorations RegisterOrthogonalEdgeHelperDecorators(); CreateSampleGraph(graphControl.Graph); }
public SnapLinesForm() { InitializeComponent(); description.LoadFile(new MemoryStream(Resources.description), RichTextBoxStreamType.RichText); SetupOptions(); snapContext = new GraphSnapContext(); // intialize input mode graphEditorInputMode = new GraphEditorInputMode() { AllowGroupingOperations = true, OrthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext(), SnapContext = snapContext }; GraphControl.InputMode = graphEditorInputMode; GraphControl.Graph.GetDecorator().EdgeDecorator.EdgeReconnectionPortCandidateProviderDecorator.SetImplementation( edge => true, EdgeReconnectionPortCandidateProviders.AllNodeCandidates); // initialize grid this.gridInfo = new GridInfo { HorizontalSpacing = 30, VerticalSpacing = 30 }; grid = new GridVisualCreator(gridInfo); GraphControl.BackgroundGroup.AddChild(grid); snapContext.NodeGridConstraintProvider = new GridConstraintProvider <INode>(gridInfo); snapContext.BendGridConstraintProvider = new GridConstraintProvider <IBend>(gridInfo); // initialize current values OnSnappingChanged(this, null); OnGridHorizontalWidthChanged(this, null); OnGridVerticalWidthChanged(this, null); GraphControl.Invalidate(); GraphControl.ZoomChanged += delegate { UpdateGrid(); }; GraphControl.ViewportChanged += delegate { UpdateGrid(); }; InitializeGraph(); }
private void ResizeNodeExecuted(object sender, ExecutedRoutedEventArgs e) { NodeControl nodeControl = e.OriginalSource as NodeControl; if (nodeControl != null) { // parameter is desired size var desiredSize = (Size?)e.Parameter; if (desiredSize.HasValue) { INode node = nodeControl.Item; GraphEditorInputMode mode = (GraphEditorInputMode)graphControl.InputMode; IRectangle layout = node.Layout; // adjust only height mode.SetNodeLayout(node, new RectD(layout.X, layout.Y, layout.Width, desiredSize.Value.Height)); e.Handled = true; } } }
public EdgeReconnectionForm() { InitializeComponent(); description.LoadFile(new MemoryStream(Resources.description), RichTextBoxStreamType.RichText); IGraph graph = graphControl.Graph; // Disable automatic cleanup of unconnected ports since some nodes have a predfined set of ports graph.NodeDefaults.Ports.AutoCleanUp = false; // Create a default editor input mode var graphEditorInputMode = new GraphEditorInputMode(); // Just for user convenience: disable node and edge creation, graphEditorInputMode.AllowCreateEdge = false; graphEditorInputMode.AllowCreateNode = false; // disable deleting items graphEditorInputMode.DeletableItems = GraphItemTypes.None; // disable the clipboard graphEditorInputMode.AllowClipboardOperations = false; // and enable the undo feature. graph.SetUndoEngineEnabled(true); // Finally, set the input mode to the graph control. graphControl.InputMode = graphEditorInputMode; // Set a port style that makes the pre-defined ports visible graph.NodeDefaults.Ports.Style = new NodeStylePortStyleAdapter(new ShapeNodeStyle { Shape = ShapeNodeShape.Ellipse, Brush = Brushes.Black, Pen = null }) { RenderSize = new SizeD(3, 3) }; RegisterEdgeReconnectionPortCandidateProvider(); CreateSampleGraph(graphControl); }
/// <summary> /// Creates the default input mode for the GraphControl, /// a <see cref="GraphEditorInputMode"/>. /// </summary> /// <returns>a specializes new GraphEditorInputMode instance</returns> protected virtual IInputMode CreateEditorMode() { GraphEditorInputMode mode = new GraphEditorInputMode { AllowGroupingOperations = true }; // creating bends does not make sense because the routing is calculated // immediately after the creation. mode.CreateEdgeInputMode.AllowCreateBend = false; // register hooks whenever something is dragged or resized mode.HandleInputMode.DragFinished += UpdateLayout; mode.MoveInputMode.DragFinished += UpdateLayout; // ... and when new nodes are created interactively mode.NodeCreated += OnNodeCreated; // ... or edges mode.CreateEdgeInputMode.EdgeCreated += OnEdgeCreated; mode.PopulateItemContextMenu += OnPopulateItemContextMenu; return(mode); }
/// <summary> /// Adds a context menu for nodes /// </summary> private void SetupContextMenu() { GraphEditorInputMode mode = graphControl.InputMode as GraphEditorInputMode; if (mode != null) { mode.ContextMenuItems = GraphItemTypes.Node; mode.PopulateItemContextMenu += (sender, e) => { // the events' Menu property carries the Context Menu instance that we instantiate during initialization // depending on the exact menu implementation, adding items needs to be done differently. var node = e.Item as INode; if (node != null) { // add a context menu entry e.Menu.Items.Add("Set [" + node.ToString() + "] to now", null, (o, args) => SetToNow(node)); } }; } }
/// <summary> /// Creates the default input mode for the GraphControl, a <see cref="GraphEditorInputMode" />. /// </summary> /// <returns>a new GraphEditorInputMode instance and configures snapping and orthogonal edge editing</returns> private IInputMode CreateEditorMode() { var mode = new GraphEditorInputMode { AllowGroupingOperations = true, SnapContext = CreateGraphSnapContext(), LabelSnapContext = CreateLabelSnapContext(), OrthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext { Enabled = false }, }; // make bend creation more important than moving of selected edges // this has the effect that dragging a selected edge (not its bends) // will create a new bend instead of moving all bends // This is especially nicer in conjunction with orthogonal // edge editing because this creates additional bends every time // the edge is moved otherwise mode.CreateBendInputMode.Priority = mode.MoveInputMode.Priority - 1; return(mode); }
/// <summary> /// Creates the default input mode for the GraphControl, /// a <see cref="GraphEditorInputMode"/>. /// </summary> /// <remarks> /// The control uses a custom node creation callback that creates business objects for newly /// created nodes. /// </remarks> /// <returns>a new GraphEditorInputMode instance</returns> protected virtual IInputMode CreateEditorMode() { var mode = new GraphEditorInputMode { // don't allow nodes to be created using a mouse click NodeCreator = (context, graph, location, parent) => graphControl.Graph.CreateNode( new RectD(location, new SizeD(50, 50)), BusRouterNodeStyles.GetRandomStyle()), // disable node resizing ShowHandleItems = GraphItemTypes.Bend | GraphItemTypes.Edge, // don't allow edges to be created by the user AllowCreateEdge = false, // enable orthogonal edge editing OrthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext(), // enable marquee selection for nodes only MarqueeSelectableItems = GraphItemTypes.Node, // enable context snapping SnapContext = new GraphSnapContext() }; return(mode); }
private static void CommitValuesToForm(OptionHandler handler, GraphEditorForm form) { GraphControl gc = form.GraphControl; IGraph g = form.Graph; GraphEditorInputMode geim = form.GraphEditorInputMode; OptionGroup controlGroup = handler.GetGroupByName(UI_DEFAULTS); OptionGroup graphGroup = handler.GetGroupByName(GRAPH_SETTINGS); OptionGroup sharingGroup = graphGroup.GetGroupByName(SHARING_SETTINGS); OptionGroup miscGroup = handler.GetGroupByName(MISC_SETTINGS); gc.HitTestRadius = (double)controlGroup[HitTestRadius].Value; geim.AutoRemoveEmptyLabels = (bool)controlGroup[AutoRemoveEmptyLabels].Value; form.GridWidth = (int)controlGroup[GridWidth].Value; form.GridSnapType = (GridSnapTypes)controlGroup[GridSnapeType].Value; form.GridVisible = (bool)controlGroup[GridVisible].Value; if (g != null) { g.NodeDefaults.Labels.AutoAdjustPreferredSize = g.EdgeDefaults.Labels.AutoAdjustPreferredSize = (bool)graphGroup[AutoAdjustPreferredLabelSize].Value; g.NodeDefaults.Ports.AutoCleanUp = g.EdgeDefaults.Ports.AutoCleanUp = (bool)graphGroup[AutoCleanupPorts].Value; g.NodeDefaults.ShareStyleInstance = (bool)sharingGroup[ShareDefaultNodeStyleInstance].Value; g.EdgeDefaults.ShareStyleInstance = (bool)sharingGroup[ShareDefaultEdgeStyleInstance].Value; g.NodeDefaults.Labels.ShareStyleInstance = (bool)sharingGroup[ShareDefaultNodeLabelStyleInstance].Value; g.EdgeDefaults.Labels.ShareStyleInstance = (bool)sharingGroup[ShareDefaultEdgeLabelStyleInstance].Value; g.NodeDefaults.Ports.ShareStyleInstance = g.EdgeDefaults.Ports.ShareStyleInstance = (bool)sharingGroup[ShareDefaultPortStyleInstance].Value; g.NodeDefaults.Labels.ShareLayoutParameterInstance = (bool)sharingGroup[ShareDefaultNodeLabelModelParameter].Value; g.EdgeDefaults.Labels.ShareLayoutParameterInstance = (bool)sharingGroup[ShareDefaultEdgeLabelModelParameter].Value; } UndoEngine undoEngine = form.Graph.GetUndoEngine(); if (undoEngine != null) { undoEngine.Size = (int)miscGroup[UndoEngine_Size].Value; } }
/// <summary> /// Creates the default input mode for the GraphControl, a <see cref="GraphEditorInputMode" />. /// </summary> /// <returns>a new GraphEditorInputMode instance with added event listeners and demo-specific settings such as no labels</returns> protected virtual IInputMode CreateEditorInputMode() { // disable labels because they are not needed in this demo var mode = new GraphEditorInputMode { AllowEditLabel = false, AllowAddLabel = false }; // add the required event listeners that are called when edges might need to be re-routed mode.CreateEdgeInputMode.EdgeCreated += EdgeCreatedListener; mode.MoveInputMode.DragFinished += DragFinishedListenerMove; mode.HandleInputMode.DragFinished += DragFinishedListenerHandle; // make bend creation more important than moving of selected edges // this has the effect that dragging a selected edge (not its bends) // will create a new bend instead of moving all bends mode.CreateBendInputMode.Priority = mode.MoveInputMode.Priority - 1; // set the input mode graphControl.InputMode = mode; return(mode); }
private void InitializeSnapping() { // Initializes snapping state SnappingEnabled = snappingButton.Checked; // Initializes SnapContext GraphEditorInputMode geim = graphControl.InputMode as GraphEditorInputMode; if (geim != null) { graphSnapContext = new GraphSnapContext { Enabled = SnappingEnabled, }; labelSnapContext = new LabelSnapContext { Enabled = SnappingEnabled, }; geim.SnapContext = graphSnapContext; geim.LabelSnapContext = labelSnapContext; } }
private void FormLoaded(object sender, EventArgs e) { IGraph graph = graphControl.Graph; // Create a default editor input mode GraphEditorInputMode graphEditorInputMode = new GraphEditorInputMode(); // Just for user convenience: disable node and edge creation, graphEditorInputMode.AllowCreateEdge = false; graphEditorInputMode.AllowCreateNode = false; // disable deleting items graphEditorInputMode.DeletableItems = GraphItemTypes.None; // don't show resize handles, graphEditorInputMode.ShowHandleItems = GraphItemTypes.None; // disable clipboard, graphEditorInputMode.AllowClipboardOperations = false; // and enable the undo feature. graph.SetUndoEngineEnabled(true); // Finally, set the input mode to the graph control. graphControl.InputMode = graphEditorInputMode; // Create the rectangle that limits the movement of some nodes // and add it to the GraphControl. var boundaryRectangle = new MutableRectangle(20, 20, 480, 400); var rectangle = new RectangleVisual(boundaryRectangle) { Pen = Pens.Black }; graphControl.RootGroup.AddChild(rectangle, CanvasObjectDescriptors.Visual); RegisterPositionHandler(boundaryRectangle); CreateSampleGraph(graph); // reset the Undo queue so the initial graph creation cannot be undone graph.GetUndoEngine().Clear(); }
/// <summary> /// Called upon loading of the form. /// This method initializes the graph and the input mode. /// </summary> protected override void OnLoad(EventArgs e) { base.OnLoad(e); description.LoadFile(new MemoryStream(Resources.description), RichTextBoxStreamType.RichText); // initialize default graph styles var graph = graphControl.Graph; graph.NodeDefaults.Style = new ShinyPlateNodeStyle { Brush = Brushes.DarkOrange }; graph.NodeDefaults.Size = new SizeD(50, 30); graph.NodeDefaults.Labels.Style = new MySimpleLabelStyle(); graph.NodeDefaults.Labels.LayoutParameter = new ExteriorLabelModel { Insets = new InsetsD(15) }.CreateParameter(ExteriorLabelModel.Position.North); graph.EdgeDefaults.Labels.Style = new MySimpleLabelStyle(); // initialize the graph graphControl.ImportFromGraphML("Resources\\SelectionStyling.graphml"); // initialize the input mode // disable label editing, since this would be really confusing in combination with our style. var graphEditorInputMode = new GraphEditorInputMode { AllowEditLabel = true, SnapContext = new GraphSnapContext() }; graphControl.InputMode = graphEditorInputMode; InitializeDecoration(); UpdateDecoration(); SelectAllNodes(graphEditorInputMode); SelectAllLabels(graphEditorInputMode); }
/// <summary> /// Adds a context menu for nodes /// </summary> private void SetupContextMenu() { GraphEditorInputMode mode = graphControl.InputMode as GraphEditorInputMode; if (mode != null) { mode.ContextMenuItems = GraphItemTypes.Node; mode.PopulateItemContextMenu += (sender, e) => { var node = e.Item as INode; if (node != null) { // add a context menu entry var menuItem = new MenuItem() { Header = "Set to now" }; menuItem.Click += (o, args) => SetToNow(node); e.Menu.Items.Add(menuItem); } }; } }
/// <summary> /// Creates and registers the input modes. /// </summary> protected virtual void InitializeInputModes() { var mode = new GraphEditorInputMode(); // Always add a label to the newly created nodes mode.NodeCreator = (context, graph, location, parent) => { var node = graph.CreateNode(location); graph.AddLabel(node, "Node"); return(node); }; // The original MoveInputMode is only active when the 'Classic Mode' toggle button is checked mode.MoveInputMode.Enabled = btnClassic.Checked; // Enable the MoveUnselectedInputMode: mode.MoveUnselectedInputMode.Enabled = true; // configure the recognizer to also respect the IsRecognized method mode.MoveUnselectedInputMode.PressedRecognizer = mode.MoveUnselectedInputMode.PressedRecognizer.And(IsRecognized); mode.MoveUnselectedInputMode.HoverRecognizer = mode.MoveUnselectedInputMode.HoverRecognizer.And(IsRecognized); graphControl.InputMode = mode; }
private void OnLoaded(object source, EventArgs args) { snapContext = new GraphSnapContext(); // intialize input mode graphEditorInputMode = new GraphEditorInputMode() { AllowGroupingOperations = true, OrthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext(), SnapContext = snapContext }; GraphControl.InputMode = graphEditorInputMode; GraphControl.Graph.GetDecorator().EdgeDecorator.EdgeReconnectionPortCandidateProviderDecorator.SetImplementation( edge => true, EdgeReconnectionPortCandidateProviders.AllNodeCandidates); // initialize grid this.gridInfo = new GridInfo { HorizontalSpacing = 30, VerticalSpacing = 30 }; grid = new GridVisualCreator(gridInfo); GraphControl.BackgroundGroup.AddChild(grid); snapContext.NodeGridConstraintProvider = new GridConstraintProvider <INode>(gridInfo); snapContext.BendGridConstraintProvider = new GridConstraintProvider <IBend>(gridInfo); // initialize current values OnSnappingChanged(this, null); OnGridHorizontalWidthChanged(this, null); OnGridVerticalWidthChanged(this, null); GraphControl.Invalidate(); GraphControl.ZoomChanged += delegate { UpdateGrid(); }; GraphControl.ViewportChanged += delegate { UpdateGrid(); }; InitializeGraph(); }
/// <summary> /// Creates the default input mode for the GraphControl, /// a <see cref="GraphEditorInputMode"/>. /// </summary> /// <returns>a new GraphEditorInputMode instance</returns> protected virtual IInputMode CreateEditorMode() { // create default interaction with a number of disabled input modes. GraphEditorInputMode mode = new GraphEditorInputMode { // no bend creation CreateBendInputMode = { Enabled = false }, // only nodes can be selected SelectableItems = GraphItemTypes.Node | GraphItemTypes.Edge, // only nodes may be marquee selected MarqueeSelectableItems = GraphItemTypes.Node, // only nodes and edges can be selected via clicks ClickSelectableItems = GraphItemTypes.Node | GraphItemTypes.Edge, // clicks will be reported for nodes, only ClickableItems = GraphItemTypes.Node, // handles won't be shown for any items ShowHandleItems = GraphItemTypes.None, // when creating new edges, bends and self-loops are not allowed CreateEdgeInputMode = { AllowCreateBend = false, AllowSelfloops = false }, }; // prepare the move input mode for interacting with the layout algorithm InitMoveMode(mode.MoveInputMode); // We could also allow direct moving of nodes, without requiring selection of the nodes, first. // However by default this conflicts with the edge creation gesture, which we will simply disable, here. // uncomment the following lines to be able to move nodes without selecting them first // // var unselected = mode.CreateMoveUnselectedInputMode(EventRecognizers.Create(EventRecognizers.Always)); // unselected.Priority = mode.MoveInputMode.Priority + 1; // mode.Add(unselected); // mode.CreateEdgeInputMode.Enabled = false; // InitMoveMode(unselected); return(mode); }
private void OnWindowLoaded(object sender, RoutedEventArgs e) { IGraph graph = graphControl.Graph; // Disable automatic cleanup of unconnected ports since some nodes have a predefined set of ports graph.NodeDefaults.Ports.AutoCleanUp = false; // Create a default editor input mode and configure it GraphEditorInputMode graphEditorInputMode = new GraphEditorInputMode(); // Just for user convenience: disable node creation, graphEditorInputMode.AllowCreateNode = false; // allow edge deletion only graphEditorInputMode.DeletableItems = GraphItemTypes.Edge; // and enable the undo feature. graph.SetUndoEngineEnabled(true); // Finally, set the input mode to the graph control. graphControl.InputMode = graphEditorInputMode; RegisterPortCandidateProvider(); CreateSampleGraph(); }
/// <summary> /// Configures input modes to interact with the graph structure. /// </summary> private void InitializeInputModes() { var graphEditorInputMode = new GraphEditorInputMode(); graphEditorInputMode.ClickInputMode.DoubleClicked += ClickInputModeDoubleClicked; // add a label to newly created nodes and mark the node as non-fixed graphEditorInputMode.NodeCreated += delegate(object sender, ItemEventArgs <INode> args) { var node = args.Item; if (graphControl.Graph.IsGroupNode(node)) { graphControl.Graph.AddLabel(node, "Group"); } else { graphControl.Graph.AddLabel(node, graphControl.Graph.Nodes.Count.ToString()); } SetFixed(node, false); }; graphEditorInputMode.CreateEdgeInputMode.EdgeCreated += (sender, args) => SetFixed(args.Item, false); graphControl.InputMode = graphEditorInputMode; }