/// <summary> /// Handles when a key is pressed. /// </summary> protected override void OnKeyDown(KeyEventArgs e) { switch (e.KeyCode) { // store when the control key is pressed case (Keys.ControlKey): if (_copiedNode == null && _movedNode == null) { Cursor = Cursors.Default; } break; // store when the shift key is pressed case (Keys.ShiftKey): // update the drawn graph for dragging and duplicating if (_movedNodeGraph != null) { _movedNodeGraph.RenderDepth = int.MaxValue; Invalidate(); } break; // cut to clipboard case (Keys.X): if (KeyCtrlIsDown) { CutSelectedNode(KeyShiftIsDown); } break; // copy to clipboard case (Keys.C): if (KeyCtrlIsDown) { CopySelectedNode(KeyShiftIsDown); } break; // paste from clipboard case (Keys.V): if (!_clipboardPasteMode) { _clipboardPasteMode = KeyCtrlIsDown && _clipboardNode != null; if (_clipboardPasteMode) { // create the layout manager used to draw the graph _movedNodeGraph = new NodeLayoutManager(_clipboardNode.CloneBranch().CreateNodeViewData(null, _rootNodeView.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); _movedNodeGraph.Scale = 0.3f; //_movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _movedNodeGraph.RenderDepth = int.MaxValue; // use the existing node as the node defaults _dragNodeDefaults = _clipboardNode; Invalidate(); } } break; // handle when the delete key is pressed case (Keys.Delete): DeleteSelectedNode(KeyShiftIsDown); break; case (Keys.E): if (e.Control) { CenterNode(_rootNodeView); } break; case (Keys.Oemplus): if (e.Control) { scaleGraph(0.1f * _nodeLayoutManager.Scale, false); } break; case (Keys.OemMinus): if (e.Control) { scaleGraph(-0.1f * _nodeLayoutManager.Scale, false); } break; case (Keys.K): if (e.Control) { CheckErrors(_rootNodeView.RootBehavior, false); } break; case (Keys.F9): if (SelectedNode != null) { if (e.Shift) { SelectedNode.SetBreakpoint(HighlightBreakPoint.kExit); } else if (e.Control) { SelectedNode.SetBreakpoint(HighlightBreakPoint.kPlanning); } else { SelectedNode.SetBreakpoint(HighlightBreakPoint.kEnter); } LayoutChanged(); } break; case (Keys.F8): toggleEnableNode(); break; case (Keys.F1): openDoc(); break; case (Keys.Left): case (Keys.Right): case (Keys.Up): case (Keys.Down): if (e.Control) { switch (e.KeyCode) { case (Keys.Left): _nodeLayoutManager.Offset = new PointF(_nodeLayoutManager.Offset.X - 10, _nodeLayoutManager.Offset.Y); Invalidate(); break; case (Keys.Right): _nodeLayoutManager.Offset = new PointF(_nodeLayoutManager.Offset.X + 10, _nodeLayoutManager.Offset.Y); Invalidate(); break; case (Keys.Up): _nodeLayoutManager.Offset = new PointF(_nodeLayoutManager.Offset.X, _nodeLayoutManager.Offset.Y - 10); Invalidate(); break; case (Keys.Down): _nodeLayoutManager.Offset = new PointF(_nodeLayoutManager.Offset.X, _nodeLayoutManager.Offset.Y + 10); Invalidate(); break; } break; } break; default: base.OnKeyDown(e); break; } }
internal void SaveImage() { if (saveImageDialog.ShowDialog() == DialogResult.OK) { NodeLayoutManager nlm = new NodeLayoutManager(_nodeLayoutManager.RootNodeLayout, _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, false); nlm.Offset = new PointF(1.0f, 1.0f); using(Graphics g = CreateGraphics()) { nlm.UpdateLayout(g); } SizeF totalSize = nlm.RootNodeLayout.GetTotalSize(nlm.Padding.Width, int.MaxValue); Size newimageSize = new Size((int)Math.Ceiling(totalSize.Width) + 2, (int)Math.Ceiling(totalSize.Height) + 2); Graphics formGraphics = null; IntPtr hdc = new IntPtr(); Image img = null; bool needsSave = true; //if (saveImageDialog.FilterIndex == 1) //{ // formGraphics = CreateGraphics(); // hdc = formGraphics.GetHdc(); // img = new Metafile(saveImageDialog.FileName, hdc); // needsSave = false; //} //else if (saveImageDialog.FilterIndex == 2) { img = new Bitmap(newimageSize.Width, newimageSize.Height); } using(Graphics graphics = Graphics.FromImage(img)) { nlm.DrawGraph(graphics, new PointF()); } if (needsSave) { img.Save(saveImageDialog.FileName); } img.Dispose(); if (formGraphics != null) { formGraphics.ReleaseHdc(hdc); formGraphics.Dispose(); } } }
/// <summary> /// Handles when a mouse button was pressed. /// </summary> protected override void OnMouseDown(MouseEventArgs e) { // the graph has not yet been dragged _startMousePosition = e.Location; _lastMousePosition = e.Location; _objectDragType = ObjectDragTypes.kNone; _dragAttachment = null; _dragTargetAttachment = null; _movedSubItem = null; _fsmDragMode = FSMDragModes.kNone; if (!_clipboardPasteMode) { _currentNode = _rootNodeView.GetInsideNode(_lastMousePosition); _dragTargetNode = null; _movedNodeGraph = null; _movedNode = null; if (_currentNode != null) { if (KeyCtrlIsDown || _currentNode.IsFSM || _currentNode.CanBeDragged() && (KeyShiftIsDown || _currentNode.Node.ParentCanAdoptChildren)) { _objectDragType = ObjectDragTypes.kNode; } } } else { if (_currentNode == null) { _currentNode = _rootNodeView.GetInsideNode(_lastMousePosition); } if (_dragTargetNode == null) { _dragTargetNode = _currentNode; } } if (e.Button == MouseButtons.Left && _currentNode != null) { Debug.Check(_nodeLayoutManager != null); NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location)); NodeViewData.SubItemAttachment attach = subItem as NodeViewData.SubItemAttachment; if (attach != null && attach.IsSelected) { _objectDragType = ObjectDragTypes.kAttachment; } PointF graphMousePos = _nodeLayoutManager.ViewToGraph(_lastMousePosition); NodeViewData.RangeType rangeType = _currentNode.CheckFSMArrowRange(graphMousePos, out _fsmSubItem, out _fsmItemBoundingBox); if (rangeType != NodeViewData.RangeType.kNode) { _objectDragType = ObjectDragTypes.kNone; if (Plugin.EditMode == EditModes.Design) { if (rangeType == NodeViewData.RangeType.kFSMLeftArrow) { _fsmDragMode = FSMDragModes.kLeft; } else if (rangeType == NodeViewData.RangeType.kFSMRightArrow) { _fsmDragMode = FSMDragModes.kRight; } } } } if (_currentNode == null) { _objectDragType = ObjectDragTypes.kGraph; } // focus the view if not focused if (!Focused) { // we focus twice to avoid an issue with focusing the view Parent.Focus(); //OnMouseDown will cal OnGotFocus as well //Focus(); } base.OnMouseDown(e); }
/// <summary> /// Handles when a key is released. /// </summary> protected override void OnKeyUp(KeyEventArgs e) { switch (e.KeyCode) { case (Keys.Enter): if (SelectedNode != null) { if (KeyCtrlIsDown) { SelectedNode.ExpandAll(!SelectedNode.IsExpanded); } else { SelectedNode.IsExpanded = !SelectedNode.IsExpanded; } LayoutChanged(); e.Handled = true; } break; // store when the shift key is released case (Keys.ShiftKey): // update the drawn graph for dragging and duplicating if (_movedNodeGraph != null) { _movedNodeGraph.RenderDepth = 0; Invalidate(); } break; // paste from clipboard case (Keys.V): PasteSelectedNode(); _clipboardPasteMode = false; // reset all the drag data _copiedNode = null; _movedNode = null; _dragTargetNode = null; _dragNodeDefaults = null; _movedNodeGraph = null; // redraw the graph Invalidate(); break; case (Keys.Left): case (Keys.Right): case (Keys.Up): case (Keys.Down): if (e.Control) { break; } if (SelectedNode == null) { SelectedNode = this.RootNodeView; if (ClickNode != null) { ClickNode(SelectedNode); } LayoutChanged(); break; } switch (e.KeyCode) { case (Keys.Left): if (SelectedNode != null && SelectedNode.Parent != null) { SelectedNode = SelectedNode.Parent; if (ClickNode != null) { ClickNode(SelectedNode); } LayoutChanged(); } break; case (Keys.Right): if (SelectedNode != null && SelectedNode.Children.Count > 0) { SelectedNode = SelectedNode.Children[0] as NodeViewData; if (ClickNode != null) { ClickNode(SelectedNode); } LayoutChanged(); } break; case (Keys.Up): if (SelectedNode != null) { if (!KeyShiftIsDown || !SwitchSelection()) { // Node if (SelectedNode.SelectedSubItem == null) { if (SelectedNode.PreviousNode != null) { if (KeyCtrlIsDown) { // Move MoveNode(true); } else { // Select SelectedNode = SelectedNode.PreviousNode as NodeViewData; if (ClickNode != null) { ClickNode(SelectedNode); } } } } // Attachment else { NodeViewData.SubItem previousItem = SelectedNode.PreviousSelectedSubItem; if (previousItem != null) { if (KeyCtrlIsDown) { // Move NodeViewData.SubItemAttachment sourceItem = SelectedNode.SelectedSubItem as NodeViewData.SubItemAttachment; NodeViewData.SubItemAttachment targetItem = previousItem as NodeViewData.SubItemAttachment; MoveSubItem(SelectedNode, SelectedNode, sourceItem, targetItem, true, false); SelectedNode.SelectedSubItem = sourceItem; } else { // Select SelectedNode.SelectedSubItem = previousItem; if (ClickEvent != null) { ClickEvent(SelectedNode); } } } } } LayoutChanged(); } break; case (Keys.Down): if (SelectedNode != null) { if (!KeyShiftIsDown || !SwitchSelection()) { // Node if (SelectedNode.SelectedSubItem == null) { if (SelectedNode.NextNode != null) { if (KeyCtrlIsDown) { // Move MoveNode(false); } else { // Select SelectedNode = SelectedNode.NextNode as NodeViewData; if (ClickNode != null) { ClickNode(SelectedNode); } } } } // Attachment else { NodeViewData.SubItem nextItem = SelectedNode.NextSelectedSubItem; if (nextItem != null) { if (KeyCtrlIsDown) { // Move NodeViewData.SubItemAttachment sourceItem = SelectedNode.SelectedSubItem as NodeViewData.SubItemAttachment; NodeViewData.SubItemAttachment targetItem = nextItem as NodeViewData.SubItemAttachment; MoveSubItem(SelectedNode, SelectedNode, sourceItem, targetItem, false, false); SelectedNode.SelectedSubItem = sourceItem; } else { // Select SelectedNode.SelectedSubItem = nextItem; if (ClickEvent != null) { ClickEvent(SelectedNode); } } } } } LayoutChanged(); } break; } break; default: base.OnKeyUp(e); break; } }
/// <summary> /// Handles when a mouse button is let go of. /// </summary> protected override void OnMouseUp(MouseEventArgs e) { _movedSubItem = null; // check if we were dragging a transition for the FSM. if (e.Button == MouseButtons.Left && _currentNode != null && ((_objectDragType == ObjectDragTypes.kNode) && _currentNode.IsFSM || _fsmSubItem != null && _fsmDragMode != FSMDragModes.kNone)) { if (Plugin.EditMode == EditModes.Design && _startMousePosition != e.Location) { // drag and move the fsm node if ((_objectDragType == ObjectDragTypes.kNode) && _currentNode.IsFSM) { UndoManager.Save(this.RootNode); LayoutChanged(); } // drag and connector the target node else { NodeViewData targetNvd = _rootNodeView.GetInsideNode(e.Location); if (targetNvd != null && targetNvd.IsFSM && (targetNvd.Parent != null) && _fsmSubItem is NodeViewData.SubItemAttachment) { NodeViewData.SubItemAttachment subItemAttachment = _fsmSubItem as NodeViewData.SubItemAttachment; if (subItemAttachment.Attachment != null && subItemAttachment.Attachment.TargetFSMNodeId != targetNvd.Node.Id) { subItemAttachment.Attachment.TargetFSMNodeId = targetNvd.Node.Id; UndoManager.Save(this.RootNode); LayoutChanged(); } } } } } // check if we were dragging an existing sub item. else if (e.Button == MouseButtons.Left && _currentNode != null && _dragTargetNode != null && _dragAttachment != null) { NodeViewData.SubItem targetSubItem = _dragTargetNode.GetSubItem(_dragTargetNode, _nodeLayoutManager.ViewToGraph(e.Location)); if (KeyCtrlIsDown || targetSubItem != _dragAttachment) { NodeViewData.SubItemAttachment targetAttachment = targetSubItem as NodeViewData.SubItemAttachment; if ((_currentNode != _dragTargetNode || targetAttachment != null) && this.MoveSubItem(_currentNode, _dragTargetNode, _dragAttachment, targetAttachment, _dragAttachMode == NodeAttachMode.Top, KeyCtrlIsDown)) { _currentNode.ClickEvent(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location)); LayoutChanged(); } } _dragAttachment = null; _dragTargetAttachment = null; _dragAttachMode = NodeAttachMode.None; } // check if we were dragging or copying an existing node. else if (e.Button == MouseButtons.Left && (_movedNode != null || _copiedNode != null || _clipboardPasteMode)) { // if we have a valid target node continue if (_dragTargetNode != null) { Node sourceNode = null; if (_copiedNode != null) { bool cloneBranch = !(_copiedNode is ReferencedBehavior); sourceNode = (KeyShiftIsDown && cloneBranch) ? (Nodes.Node)_copiedNode.CloneBranch() : (Nodes.Node)_copiedNode.Clone(); } else if (_clipboardPasteMode) { bool cloneBranch = !(_clipboardNode is ReferencedBehavior); sourceNode = (/*KeyShiftIsDown && */cloneBranch) ? (Nodes.Node)_clipboardNode.CloneBranch() : (Nodes.Node)_clipboardNode.Clone(); } else if (_movedNode != null) { sourceNode = _movedNode; } Debug.Check(sourceNode != null); Node sourceParent = (Node)sourceNode.Parent; BehaviorNode sourceBehavior = sourceNode.Behavior; if (_dragTargetNode.Node == sourceNode) { _dragAttachMode = NodeAttachMode.None; } if (_dragAttachMode == NodeAttachMode.Top || _dragAttachMode == NodeAttachMode.Bottom || _dragAttachMode == NodeAttachMode.Left || _dragAttachMode == NodeAttachMode.Right || _dragAttachMode == NodeAttachMode.Center) { // set the prefab dirty for its previous parent if (sourceParent != null && !string.IsNullOrEmpty(sourceParent.PrefabName)) { sourceParent.HasOwnPrefabData = true; } if (KeyShiftIsDown) { if (sourceParent != null) { sourceParent.RemoveChild(sourceNode.ParentConnector, sourceNode); } } else { sourceNode.ExtractNode(); } } // move the dragged node to the target node, according to the attach mode switch (_dragAttachMode) { // the node will be placed above the target node case (NodeAttachMode.Top): int n = _dragTargetNode.Node.ParentConnector.GetChildIndex(_dragTargetNode.Node); ((Node)_dragTargetNode.Node.Parent).AddChild(_dragTargetNode.Node.ParentConnector, sourceNode, n); _selectedNodePending = sourceNode; _selectedNodePendingParent = _dragTargetNode.Parent; LayoutChanged(); break; // the node will be placed below the target node case (NodeAttachMode.Bottom): int m = _dragTargetNode.Node.ParentConnector.GetChildIndex(_dragTargetNode.Node); ((Node)_dragTargetNode.Node.Parent).AddChild(_dragTargetNode.Node.ParentConnector, sourceNode, m + 1); _selectedNodePending = sourceNode; _selectedNodePendingParent = _dragTargetNode.Parent; LayoutChanged(); break; // the node will be placed in front of the target node case (NodeAttachMode.Left): Node parent = (Node)_dragTargetNode.Node.Parent; Node.Connector conn = _dragTargetNode.Node.ParentConnector; int o = conn.GetChildIndex(_dragTargetNode.Node); parent.RemoveChild(conn, _dragTargetNode.Node); parent.AddChild(conn, sourceNode, o); BaseNode.Connector sourceConn = sourceNode.GetConnector(conn.Identifier); Debug.Check(sourceConn != null); sourceNode.AddChild(sourceConn, _dragTargetNode.Node); _selectedNodePending = sourceNode; _selectedNodePendingParent = _dragTargetNode.Parent; LayoutChanged(); break; // the node will simply attached to the target node case (NodeAttachMode.Right): _dragTargetNode.Node.AddChild(_dragTargetConnector, sourceNode); _selectedNodePending = sourceNode; _selectedNodePendingParent = _dragTargetNode; LayoutChanged(); break; // the node will replace the target node case (NodeAttachMode.Center): if (replaceNode(_dragTargetNode.Node, sourceNode)) { LayoutChanged(); } break; } if (_dragAttachMode != NodeAttachMode.None) { // If cloning a node, its Id should be reset. if (_copiedNode != null || _clipboardPasteMode) { // Cross two different behavior files if (_clipboardPasteMode && _clipboardRootNode != this.RootNodeView) { try { // Copy the used Pars from the current behavior to the new one. if (_clipboardNode != null && _clipboardRootNode != null && _clipboardRootNode.Node is Behavior) { foreach(ParInfo par in((Behavior)(_clipboardRootNode.Node)).LocalVars) { List<Node.ErrorCheck> result = new List<Node.ErrorCheck>(); Plugin.CheckPar(_clipboardNode, par, ref result); if (result.Count > 0) { bool bExist = false; foreach(ParInfo p in((Behavior)this.RootNode).LocalVars) { if (p.Name == par.Name) { bExist = true; break; } } if (!bExist) { ((Behavior)this.RootNode).LocalVars.Add(par); } } } } // reset its properties and methods sourceNode.ResetMembers(false, this.RootNode.AgentType, true); } catch { } } // reset its Id sourceNode.ResetId(true); } // update the node's label sourceNode.OnPropertyValueChanged(false); // set the prefab dirty for its current parent if (sourceNode.Parent != null) { Node parent = (Node)sourceNode.Parent; if (!string.IsNullOrEmpty(parent.PrefabName)) { parent.HasOwnPrefabData = true; sourceNode.SetPrefab(parent.PrefabName, true); } } UndoManager.Save(this.RootNode); } } // reset all the drag data if (!_clipboardPasteMode) { _copiedNode = null; _movedNode = null; _dragTargetNode = null; _dragNodeDefaults = null; _movedNodeGraph = null; } // redraw the graph Invalidate(); } // popup the menu for the current hit node else if (e.Button == MouseButtons.Right && !KeyAltIsDown && !KeyCtrlIsDown && !KeyShiftIsDown) { bool itemEnabled = (SelectedNode != null && SelectedNode.Node.Parent != null); itemEnabled &= (Plugin.EditMode == EditModes.Design); deleteMenuItem.ShortcutKeys = Keys.Delete; deleteTreeMenuItem.ShortcutKeys = Keys.Shift | Keys.Delete; cutMenuItem.Enabled = SelectedNodeCanBeCut(); cutTreeMenuItem.Enabled = (SelectedNode != null) && !SelectedNode.IsFSM && SelectedTreeCanBeCut(); copyMenuItem.Enabled = itemEnabled; copySubtreeMenuItem.Enabled = (SelectedNode != null) && !SelectedNode.IsFSM; pasteMenuItem.Enabled = SelectedNodeCanBePasted(); deleteMenuItem.Enabled = SelectedNodeCanBeDeleted(); deleteTreeMenuItem.Enabled = (SelectedNode != null) && !SelectedNode.IsFSM && SelectedTreeCanBeDeleted(); bool isReferencedBehavior = SelectedNode != null && SelectedNode.Node is ReferencedBehavior; bool isEvent = SelectedNode != null && SelectedNode.SelectedSubItem != null && SelectedNode.SelectedSubItem.SelectableObject is Attachments.Event; referenceMenuItem.Enabled = itemEnabled || isReferencedBehavior || isEvent; referenceMenuItem.Text = (isReferencedBehavior || isEvent) ? Resources.OpenReference : Resources.SaveReference; disableMenuItem.Enabled = false; if (itemEnabled) { if (SelectedNode.SelectedSubItem != null && SelectedNode.SelectedSubItem.SelectableObject is Attachments.Attachment) { Attachments.Attachment attach = SelectedNode.SelectedSubItem.SelectableObject as Attachments.Attachment; disableMenuItem.Enabled = attach.CanBeDisabled(); disableMenuItem.Text = attach.Enable ? Resources.DisableNode : Resources.EnableNode; } else { disableMenuItem.Enabled = SelectedNode.Node.CanBeDisabled(); disableMenuItem.Text = SelectedNode.Node.Enable ? Resources.DisableNode : Resources.EnableNode; } } expandMenuItem.Enabled = (SelectedNode != null && SelectedNode.CanBeExpanded()); collapseMenuItem.Enabled = expandMenuItem.Enabled; expandAllMenuItem.Enabled = expandMenuItem.Enabled; collapseAllMenuItem.Enabled = expandMenuItem.Enabled; bool isPrefabInstance = SelectedNode != null && !string.IsNullOrEmpty(SelectedNode.Node.PrefabName); breakPrefabMenuItem.Enabled = itemEnabled && isPrefabInstance; if (isPrefabInstance) { string fullpath = FileManagers.FileManager.GetFullPath(SelectedNode.Node.PrefabName); isPrefabInstance = File.Exists(fullpath); } savePrefabMenuItem.Enabled = itemEnabled; savePrefabMenuItem.Text = isPrefabInstance ? Resources.OpenPrefab : Resources.SavePrefab; if (SelectedNode != null) { Node prefabRoot = SelectedNode.Node.GetPrefabRoot(); string relativeFilename = FileManagers.FileManager.GetRelativePath(this.RootNode.Filename); applyMenuItem.Enabled = itemEnabled && isPrefabInstance && SelectedNode.Node.PrefabName != relativeFilename && prefabRoot.IsPrefabDataDirty(); } breakpointMenuItem.Enabled = SelectedNode != null && SelectedNode.Parent != null; if (SelectedNode != null) { enterBreakpointMenuItem.Text = SelectedNode.GetBreakpointOperation(HighlightBreakPoint.kEnter); exitBreakpointMenuItem.Text = SelectedNode.GetBreakpointOperation(HighlightBreakPoint.kExit); this.beakpointPlanning.Visible = false; if (SelectedNode.Node is Task) { this.beakpointPlanning.Visible = true; beakpointPlanning.Text = SelectedNode.GetBreakpointOperation(HighlightBreakPoint.kPlanning); } } contextMenu.Show(this, new Point(e.X, e.Y)); } Cursor = Cursors.Default; _fsmDragMode = FSMDragModes.kNone; // redraw the graph Invalidate(); base.OnMouseUp(e); }
/// <summary> /// Handles when the mouse is moved. /// </summary> protected override void OnMouseMove(MouseEventArgs e) { if (_lostFocus) { _lostFocus = false; // update the last ouse position _lastMousePosition = e.Location; base.OnMouseMove(e); return; } // returns the mouse under the mouse cursor NodeViewData nodeFound = _rootNodeView.GetInsideNode(e.Location); NodeViewData.SubItem subItemFound = null; if (nodeFound != null) { subItemFound = nodeFound.GetSubItem(nodeFound, _nodeLayoutManager.ViewToGraph(e.Location)); } else { this.toolTip.Hide(this); } // clear previously stored node which can cause problems when dragging to another view //_dragTargetNode = null; if (nodeFound != null || _currentExpandNode != null || subItemFound != null) { if (_dragAttachment == null) { _currentNode = nodeFound; } if (Settings.Default.ShowNodeToolTips) { if (nodeFound != null) { _nodeToolTip = (subItemFound != null) ? subItemFound.ToolTip : nodeFound.ToolTip; } if (!string.IsNullOrEmpty(_nodeToolTip)) { this.toolTipTimer.Start(); } } Invalidate(); } // check if we are currently dragging the graph if ((e.Button == MouseButtons.Middle || (e.Button == MouseButtons.Left && _objectDragType == ObjectDragTypes.kGraph)) && _lastMousePosition != e.Location && !this.contextMenu.Visible) { Cursor = Cursors.SizeAll; // move the graph according to the last mouse position _nodeLayoutManager.Offset = new PointF(_nodeLayoutManager.Offset.X - (_lastMousePosition.X - e.X), _nodeLayoutManager.Offset.Y - (_lastMousePosition.Y - e.Y)); Invalidate(); } // check if we start duplicating an existing node step 1 else if (e.Button == MouseButtons.Left && KeyCtrlIsDown && _lastMousePosition != e.Location && _dragNodeDefaults == null && _copiedNode == null && _currentNode != null && !(_currentNode.Node is BehaviorNode)) { if (_objectDragType == ObjectDragTypes.kNode) { // node _movedNode = null; _copiedNode = _currentNode.Node; // create the layout manager used to draw the graph _movedNodeGraph = new NodeLayoutManager(_copiedNode.CloneBranch().CreateNodeViewData(null, _rootNodeView.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); _movedNodeGraph.Scale = 0.3f; _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; // use the existing node as the node defaults _dragNodeDefaults = _copiedNode; } else if (_objectDragType == ObjectDragTypes.kAttachment) { // attachment if (_dragAttachment == null) { NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location)); _dragAttachment = subItem as NodeViewData.SubItemAttachment; } } Invalidate(); } // check if we are duplicating an existing node step 2 else if (e.Button == MouseButtons.Left && KeyCtrlIsDown && (_copiedNode != null || _dragAttachment != null)) { if (_objectDragType == ObjectDragTypes.kNode) { // node _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _dragTargetNode = _currentNode; Cursor = _currentNode == null ? Cursors.No : Cursors.Default; //Point movedGraphGraphPos= new Point(e.Location.X + _movedNodeGraph.Offset.X, e.Location.Y + _movedNodeGraph.Offset.Y /-2); //_movedNodeGraph.Location= movedGraphGraphPos; } else if (_objectDragType == ObjectDragTypes.kAttachment) { // attachment _dragTargetNode = nodeFound; if (_dragTargetNode != null) { NodeViewData.SubItem subItem = _dragTargetNode.GetSubItem(_dragTargetNode, _nodeLayoutManager.ViewToGraph(e.Location)); _dragTargetAttachment = subItem as NodeViewData.SubItemAttachment; } } Invalidate(); } // check if we start dragging an existing node step 1 else if (e.Button == MouseButtons.Left && _lastMousePosition != e.Location && !KeyCtrlIsDown && _movedNode == null && _currentNode != null) { if (_objectDragType == ObjectDragTypes.kNode) { // node if (_currentNode.CanBeDragged()) { if (_currentNode.IsFSM) { PointF currentGraphMousePos = _nodeLayoutManager.ViewToGraph(e.Location); PointF lastGraphMousePos = _nodeLayoutManager.ViewToGraph(_lastMousePosition); _currentNode.ScreenLocation = new PointF(_currentNode.ScreenLocation.X + currentGraphMousePos.X - lastGraphMousePos.X, _currentNode.ScreenLocation.Y + currentGraphMousePos.Y - lastGraphMousePos.Y); LayoutChanged(); } else if ((KeyShiftIsDown || _currentNode.Node.ParentCanAdoptChildren)) { _movedNode = _currentNode.Node; // create the layout manager used to draw the graph if (_movedNodeGraph == null) { _movedNodeGraph = new NodeLayoutManager(_movedNode.CloneBranch().CreateNodeViewData(null, _rootNodeView.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); } _movedNodeGraph.Scale = 0.3f; //_movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _movedNodeGraph.RenderDepth = int.MaxValue; } } } else if (_objectDragType == ObjectDragTypes.kAttachment) { // attachment if (_fsmDragMode == FSMDragModes.kNone && Plugin.EditMode == EditModes.Design) { _movedNodeGraph = null; _dragTargetNode = nodeFound; if (_dragAttachment == null) { NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location)); _dragAttachment = subItem as NodeViewData.SubItemAttachment; if (_dragAttachment != null) { _movedSubItem = _dragAttachment.Clone(_currentNode.Node); } } else if (_dragTargetNode != null) { NodeViewData.SubItem subItem = _dragTargetNode.GetSubItem(_dragTargetNode, _nodeLayoutManager.ViewToGraph(e.Location)); _dragTargetAttachment = subItem as NodeViewData.SubItemAttachment; } } } Invalidate(); } // check if we start dragging an existing node step 2 else if (e.Button == MouseButtons.Left && _movedNode != null && !_clipboardPasteMode) { // create the layout manager used to draw the graph if (_movedNodeGraph == null) { _movedNodeGraph = new NodeLayoutManager(_movedNode.CloneBranch().CreateNodeViewData(null, _rootNodeView.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); } _movedNodeGraph.Scale = 0.3f; _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _dragNodeDefaults = _movedNode; _dragTargetNode = _currentNode; Cursor = _currentNode == null ? Cursors.No : Cursors.Default; Invalidate(); } else if (_clipboardPasteMode) { if (_movedNodeGraph != null) { //_movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _movedNodeGraph.RenderDepth = int.MaxValue; } _dragTargetNode = _currentNode; Cursor = _currentNode == null ? Cursors.No : Cursors.Default; Invalidate(); } else if (_currentNode != null && _dragAttachment == null) { // Highlight the expand/collapse flag PointF graphMousePos = _nodeLayoutManager.ViewToGraph(e.Location); bool isInExandRange = _currentNode.IsInExpandRange(graphMousePos); bool isInExandConnectorRange = _currentNode.IsInExpandConnectorRange(graphMousePos); if (isInExandRange || isInExandConnectorRange) { _currentExpandNode = _currentNode; _nodeToolTip = isInExandRange ? Resources.ExpandAllInfo : Resources.ExpandConnectorInfo; Invalidate(); } else if (_currentExpandNode != null) { _currentExpandNode = null; Invalidate(); } } // update the last ouse position _lastMousePosition = e.Location; base.OnMouseMove(e); }
/// <summary> /// Handles when the mouse is moved. /// </summary> protected override void OnMouseMove(MouseEventArgs e) { if (_lostFocus) { _lostFocus = false; // update the last ouse position _lastMousePosition = e.Location; base.OnMouseMove(e); return; } // returns the mouse under the mouse cursor NodeViewData nodeFound = _rootNode.IsInside(e.Location); // clear previously stored node which can cause problems when dragging to another view //_dragTargetNode = null; // if a different node is the current one, update it if (nodeFound != _currentNode || _currentExpandNode != null) { if (_dragAttachment == null) { _currentNode = nodeFound; } if (nodeFound == null) { this.toolTip.Hide(this); } else if (Settings.Default.ShowNodeToolTips) { if (!string.IsNullOrEmpty(nodeFound.ToolTip)) this.toolTipTimer.Start(); } Invalidate(); } // check if we are currently dragging the graph if ((e.Button == MouseButtons.Middle || e.Button == MouseButtons.Left && IsPanMode) && _lastMousePosition != e.Location && !this.contextMenu.Visible) { _isGraphDragged = true; // move the graph according to the last mouse position _nodeLayoutManager.Offset = new PointF(_nodeLayoutManager.Offset.X - (_lastMousePosition.X - e.X), _nodeLayoutManager.Offset.Y - (_lastMousePosition.Y - e.Y)); Invalidate(); } // check if we start duplicating an existing node step 1 else if (e.Button == MouseButtons.Left && KeyCtrlIsDown && _lastMousePosition != e.Location && _dragNodeDefaults == null && _copiedNode == null && _currentNode != null && !(_currentNode.Node is BehaviorNode)) { _movedNode = null; _copiedNode = _currentNode.Node; // create the layout manager used to draw the graph _movedNodeGraph = new NodeLayoutManager(_copiedNode.CloneBranch().CreateNodeViewData(null, _rootNode.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenHighlight, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); _movedNodeGraph.Scale = 0.3f; _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; // use the existing node as the node defaults _dragNodeDefaults = _copiedNode; Invalidate(); } // check if we are duplicating an existing node step 2 else if (e.Button == MouseButtons.Left && KeyCtrlIsDown && _copiedNode != null) { _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _dragTargetNode = _currentNode; Cursor = _currentNode == null ? Cursors.No : Cursors.Default; //Point movedGraphGraphPos= new Point(e.Location.X + _movedNodeGraph.Offset.X, e.Location.Y + _movedNodeGraph.Offset.Y /-2); //_movedNodeGraph.Location= movedGraphGraphPos; Invalidate(); } // check if we start dragging an existing node step 1 else if (e.Button == MouseButtons.Left && _lastMousePosition != e.Location && !KeyCtrlIsDown && _movedNode == null && _currentNode != null && !(_currentNode.Node is BehaviorNode)) { if (_isNodeDragged) // node { if (KeyShiftIsDown || _currentNode.Node.ParentCanAdoptChildren) { _movedNode = _currentNode.Node; // create the layout manager used to draw the graph if (_movedNodeGraph == null) _movedNodeGraph = new NodeLayoutManager(_movedNode.CloneBranch().CreateNodeViewData(null, _rootNode.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenHighlight, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); _movedNodeGraph.Scale = 0.3f; _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; } } else // attachment { _movedNodeGraph = null; if (_dragAttachment == null) { NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location)); _dragAttachment = subItem as NodeViewData.SubItemAttachment; } else { NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location)); _dragTargetAttachment = subItem as NodeViewData.SubItemAttachment; Invalidate(); } } } // check if we start dragging an existing node step 2 else if (e.Button == MouseButtons.Left && _movedNode != null && !_clipboardPasteMode) { // create the layout manager used to draw the graph if (_movedNodeGraph == null) _movedNodeGraph = new NodeLayoutManager(_movedNode.CloneBranch().CreateNodeViewData(null, _rootNode.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenHighlight, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); _movedNodeGraph.Scale = 0.3f; _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _dragNodeDefaults = _movedNode; _dragTargetNode = _currentNode; Cursor = _currentNode == null ? Cursors.No : Cursors.Default; Invalidate(); } else if (e.Button == MouseButtons.Right && IsPanMode && _panStartMousePosition != e.Location) { int delta = e.X - (int)_panStartMousePosition.X + (int)_panStartMousePosition.Y - e.Y; scaleGraph(delta / 16, false); } else if (_clipboardPasteMode) { if (_movedNodeGraph != null) _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; _dragTargetNode = _currentNode; Cursor = _currentNode == null ? Cursors.No : Cursors.Default; Invalidate(); } else if (_currentNode != null && _dragAttachment == null) { // Highlight the expand/collapse flag PointF graphMousePos = _nodeLayoutManager.ViewToGraph(e.Location); if (_currentNode.IsInExpandRange(graphMousePos)) { _currentExpandNode = _currentNode; Invalidate(); } else if (_currentExpandNode != null) { _currentExpandNode = null; Invalidate(); } } // update the last ouse position _lastMousePosition = e.Location; base.OnMouseMove(e); }
/// <summary> /// Handles when a mouse button was pressed. /// </summary> protected override void OnMouseDown(MouseEventArgs e) { // the graph has not yet been dragged _lastMousePosition = e.Location; _isGraphDragged = false; _isNodeDragged = false; _dragAttachment = null; _dragTargetAttachment = null; if (!_clipboardPasteMode) { _currentNode = _rootNode.IsInside(_lastMousePosition); _dragTargetNode = null; _movedNodeGraph = null; _movedNode = null; if (_currentNode != null) { _isNodeDragged = _currentNode.CanBeDragged() && !KeyCtrlIsDown && (KeyShiftIsDown || _currentNode.Node.ParentCanAdoptChildren); } } else { if (_currentNode == null) { _currentNode = _rootNode.IsInside(e.Location); } if (_dragTargetNode == null) { _dragTargetNode = _currentNode; } } // update the mouse cursor when dragging nodes if (IsPanMode || e.Button == MouseButtons.Middle) { _panStartMousePosition = e.Location; Cursor = (e.Button == MouseButtons.Right) ? Cursors.NoMove2D : Cursors.SizeAll; } else if (e.Button == MouseButtons.Left && _currentNode != null) { Debug.Check(_nodeLayoutManager != null); NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location)); NodeViewData.SubItemAttachment attach = subItem as NodeViewData.SubItemAttachment; if (attach != null && attach.IsSelected) { _isNodeDragged = false; } } // focus the view if not focused if (!Focused) { // we focus twice to avoid an issue with focusing the view Parent.Focus(); //OnMouseDown will cal OnGotFocus as well //Focus(); } base.OnMouseDown(e); }
/// <summary> /// Handles when a key is pressed. /// </summary> protected override void OnKeyDown(KeyEventArgs e) { switch (e.KeyCode) { // store when the alt key is pressed case (Keys.Menu): IsPanMode = true; break; // store when the control key is pressed case (Keys.ControlKey): if (_copiedNode == null && _movedNode == null) { Cursor = Cursors.Default; } break; // store when the shift key is pressed case (Keys.ShiftKey): // update the drawn graph for dragging and duplicating if (_movedNodeGraph != null) { _movedNodeGraph.RenderDepth = int.MaxValue; Invalidate(); } break; // copy to clipboard case (Keys.C): if (KeyCtrlIsDown) { CopySelectedNode(); } break; // paste from clipboard case (Keys.V): if (!_clipboardPasteMode) { _clipboardPasteMode = KeyCtrlIsDown && _clipboardNode != null; if (_clipboardPasteMode) { // create the layout manager used to draw the graph _movedNodeGraph = new NodeLayoutManager(_clipboardNode.CloneBranch().CreateNodeViewData(null, _rootNode.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenHighlight, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true); _movedNodeGraph.Scale = 0.3f; _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0; // use the existing node as the node defaults _dragNodeDefaults = _clipboardNode; Invalidate(); } } break; // cut to clipboard case (Keys.X): if (KeyCtrlIsDown) { CutSelectedNode(KeyShiftIsDown); } break; // handle when the delete key is pressed case (Keys.Delete): DeleteSelectedNode(KeyShiftIsDown); break; case (Keys.E): if (e.Control) { CenterNode(_rootNode); } break; case (Keys.K): if (e.Control) { CheckErrors(_rootNode.RootBehavior, false); } break; case (Keys.F9): if (SelectedNode != null) { if (e.Shift) { SelectedNode.SetBreakpoint(HighlightBreakPoint.kExit); } else { SelectedNode.SetBreakpoint(HighlightBreakPoint.kEnter); } LayoutChanged(); } break; default: base.OnKeyDown(e); break; } }