public RadialMenu(uint nodeId, Point worldCoords, double radius, Dictionary <int, string> items, double startAngle, NodePart part) { this.startAngle = startAngle * Math.PI / 180; this.endAngle = (startAngle - 90) * Math.PI / 180; // 90: the radial menu is a quadrant this.nodePart = part; this.worldCoords = worldCoords; this.nodeId = nodeId; this.radius = radius; radialMenuVisual = new DrawingVisual(); radialMenuVisual.Transform = new TranslateTransform(worldCoords.X, worldCoords.Y); SetAnchor(); itemsList = items; reducedList = items; InitializeMenuItems(); UpdateItemsArrangement(-1); InitializeItemWeight(); ValidateScrollers(); Compose(); }
// todo: maybe idendity issues with indexOf private void invalidate(Node node) { for (int i = 0, n = node.parts.Count; i < n; ++i) { NodePart part = node.parts[i]; var bindPose = part.invBoneBindTransforms; if (bindPose != null) { for (int j = 0; j < bindPose.Count; ++j) { // tood: figure out that ordered dic thing, key should be accessable by index //bindPose.Keys[j] = getNode(bindPose.Keys[j].id); } } if (!materials.Contains(part.material)) { int midx = materials.IndexOf(part.material); if (midx < 0) { materials.Add(part.material = part.material.copy()); } else { part.material = materials[midx]; } } } for (int i = 0, n = node.getChildCount(); i < n; ++i) { invalidate(node.getChild(i)); } }
public RadialMenu(uint nodeId, Point worldCoords, double radius, Dictionary<int, string> items, double startAngle, NodePart part) { this.startAngle = startAngle * Math.PI / 180; this.endAngle = (startAngle - 90) * Math.PI / 180; // 90: the radial menu is a quadrant this.nodePart = part; this.worldCoords = worldCoords; this.nodeId = nodeId; this.radius = radius; radialMenuVisual = new DrawingVisual(); radialMenuVisual.Transform = new TranslateTransform(worldCoords.X, worldCoords.Y); SetAnchor(); itemsList = items; reducedList = items; InitializeMenuItems(); UpdateItemsArrangement(-1); InitializeItemWeight(); ValidateScrollers(); Compose(); }
public MenuItemsProvider(GraphController controller, NodePart part, uint id) { this.graphController = controller; this.nodePart = part; this.nodeId = id; this.GenerateMenuItems(); }
private bool HandleBeginHighFrequencyUpdate(GraphCommand command) { uint nodeId = (uint)command.GetArgument(0); NodePart nodePart = ((NodePart)command.GetArgument(1)); nodeSelectedForHighFrequencyUpdate = GetVisualNode(nodeId); if (null == nodeSelectedForHighFrequencyUpdate) { return(false); } // @TODO(Ben): The caller would have to specify NodePart in // the near future, but for now we are making some assumption. // switch (nodeSelectedForHighFrequencyUpdate.VisualType) { case NodeType.Driver: nodePart = NodePart.Text; break; default: throw new InvalidOperationException("Not available for other node type (097D3A07D806)"); } nodeSelectedForHighFrequencyUpdate.EnableEdit(nodePart, -1); return(true); }
public bool DoBeginNodeEdit(uint compId, NodePart nodePart) { GraphCommand command = new GraphCommand(GraphCommand.Name.BeginNodeEdit); command.AppendArgument(compId); command.AppendArgument(nodePart); return(RerouteToHandler(command)); }
public bool DoCreateRadialMenu(NodePart nodePart, uint nodeId) { GraphCommand command = new GraphCommand(GraphCommand.Name.CreateRadialMenu); command.AppendArgument(nodePart); command.AppendArgument(nodeId); return(RerouteToHandler(command)); }
private bool HandleCreateRadialMenu(GraphCommand command) { NodePart part = ((NodePart)command.GetArgument(0)); uint nodeId = (uint)command.GetArgument(1); this.itemsProvider = new MenuItemsProvider(this, part, nodeId); return(true); }
public bool DoBeginHighFrequencyUpdate(uint nodeId, NodePart nodePart) { GraphCommand command = new GraphCommand(GraphCommand.Name.BeginHighFrequencyUpdate); command.AppendArgument(nodeId); command.AppendArgument(nodePart); return(RerouteToHandler(command)); }
private void Node(object obj, string shape = "oval", NodePart propertyCategory = NodePart.All) { NodePart visitedPart = NodePart.None; if (m_visitedNodes.TryGetValue(obj, out visitedPart)) { if ((visitedPart & propertyCategory) != 0) { return; } m_visitedNodes.Remove(obj); } m_visitedNodes.Add(obj, visitedPart | propertyCategory); string propertiesString = ""; var properties = GetProperties(obj); foreach (var property in properties) { var type = GetPropertyType(property); if ((propertyCategory & NodePart.GeneralProperties) != 0 && type.IsPrimitive || type.IsValueType) { propertiesString += String.Format("\\n{0}: {1}", property.Name, property.GetValue(obj)); } var enumerableTypes = GetGenericIEnumerables(type); foreach (var enumerableType in enumerableTypes) { if (enumerableType == typeof(IImageProvider)) { var imageProviders = property.GetValue(obj) as IEnumerable <IImageProvider>; var i = 0; foreach (var imageProvider in imageProviders) { Edge(imageProvider, obj, String.Format("{0}[{1}]", property.Name, i++)); Dot(imageProvider); } } } if ((propertyCategory & NodePart.ImageProviderProperties) != 0 && property.GetValue(obj) is IImageProvider) { Edge(property.GetValue(obj), obj, property.Name); Dot(property.GetValue(obj) as IImageProvider); } } if ((propertyCategory & NodePart.GeneralProperties) != 0) { m_dotString += String.Format("{0} [label=\"{1}{2}\", shape=\"{3}\"]; ", NodeId(obj), obj.GetType().Name, propertiesString, shape); } }
public string GenerateTechId() { if (String.IsNullOrEmpty(NodePart)) { return(""); } var i = NodePart.IndexOf('_'); return(i > 0 && i + 1 < NodePart.Length ? NodePart.Substring(i + 1) : NodePart); }
public bool DoMouseUp(MouseButton button, uint compId, NodePart nodePart, int index, ModifierKeys modifier) { GraphCommand command = new GraphCommand(GraphCommand.Name.MouseUp); command.AppendArgument(button); command.AppendArgument(compId); command.AppendArgument(nodePart); command.AppendArgument(index); command.AppendArgument(modifier); return(RerouteToHandler(command)); }
internal bool DisableEdit() { if (this.partSelectedForEdit == NodePart.Caption || this.partSelectedForEdit == NodePart.Text || this.partSelectedForEdit == NodePart.ReplicationGuide) { this.partSelectedForEdit = NodePart.None; return(true); } else { throw new InvalidOperationException(); } }
public bool DoEndDrag(MouseButton button, uint compId, NodePart nodePart, int index, ModifierKeys modifier, double mouseX, double mouseY) { GraphCommand command = new GraphCommand(GraphCommand.Name.EndDrag); command.AppendArgument(button); command.AppendArgument(compId); command.AppendArgument(nodePart); command.AppendArgument(index); command.AppendArgument(modifier); command.AppendArgument(mouseX); command.AppendArgument(mouseY); return(RerouteToHandler(command)); }
internal void ToggleContextualMenu(NodePart nodePart) { if (this.partDisplayingMenu == nodePart) { this.partDisplayingMenu = NodePart.None; } else { this.partDisplayingMenu = nodePart; } this.Dirty = true; this.Compose(); }
internal bool EnableEdit(NodePart nodePart, int index) { if (this.partSelectedForEdit != NodePart.None) { return(false);//throw exception } // Replication guide index should only be specified for this case. if (nodePart != NodePart.ReplicationGuide && (index != -1)) { throw new ArgumentException("Index should not be specified (34BB6918677B)", "index"); } this.partSelectedForEdit = nodePart; this.replicationIndex = index; return(true); }
public bool HitTestComponent(uint compId, Point mouse, out NodePart nodePart, out int index) { nodePart = NodePart.None; index = -1; //Implement hittest:DONE IVisualNode node = this.GetVisualNode(compId); if (null == node) { return(false); } nodePart = ((VisualNode)node).HitTest(mouse.X, mouse.Y, out index); return(nodePart != NodePart.None); }
private bool HandleBeginNodeEdit(GraphCommand command) { uint nodeId = (uint)command.GetArgument(0); NodePart nodePart = ((NodePart)command.GetArgument(1)); VisualNode node = this.GetVisualNode(nodeId); if (nodePart == NodePart.Text) { this.previousText = node.Text; } else if (nodePart == NodePart.Caption) { this.previousText = node.Caption; } node.EnableEdit(nodePart, -1); return(true); }
public Renderable getRenderable(Renderable @out, Node node, NodePart nodePart) { nodePart.setRenderable(@out); if (nodePart.bones == null && transform != default(Matrix4)) { @out.worldTransform = (transform) * (node.globalTransform); } else if (transform != default(Matrix4)) { @out.worldTransform = (transform); } else { @out.worldTransform = Matrix4.Identity; } @out.userData = userData; return(@out); }
public bool GetNodeText(uint compId, NodePart nodePart, out string text) { text = string.Empty; VisualNode newNode = this.GetVisualNode(compId); if (null == newNode) { return(false); } if (nodePart == NodePart.Caption) { text = newNode.Caption; return(true); } else if (nodePart == NodePart.Text) { text = newNode.Text; return(true); } return(false); }
private bool HandleBeginDrag(GraphCommand command) { MouseButton button = ((MouseButton)command.GetArgument(0)); uint compId = ((uint)command.GetArgument(1)); NodePart nodePart = ((NodePart)command.GetArgument(2)); int slotIndex = ((int)command.GetArgument(3)); ModifierKeys modifiers = ((ModifierKeys)command.GetArgument(4)); double mouseX = ((double)command.GetArgument(5)); double mouseY = ((double)command.GetArgument(6)); switch (nodePart) { case NodePart.None: BeginDragSelectionRegion(modifiers); return(true); case NodePart.InputSlot: case NodePart.OutputSlot: BeginDragInputOutputSlot(compId, nodePart, slotIndex); return(true); case NodePart.Caption: case NodePart.Text: case NodePart.ReplicationGuide: case NodePart.InputLabel: case NodePart.North: case NodePart.NorthEast: case NodePart.NorthWest: case NodePart.South: case NodePart.Preview: case NodePart.PreviewNorthEast: BeginDragSelectedNodes(mouseX, mouseY, this.GetVisualNode(compId)); return(true); } return(false); }
internal void HandleMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { isMouseButtonDown = false; if (panning) { graphControl.SetCursor(CursorSet.Index.HandPan); return; } ModifierKeys modifiers = Keyboard.Modifiers; mousePosition = e.GetPosition(graphCanvas); uint newCompId = uint.MaxValue; int index = -1; NodePart nodePart = NodePart.None; DrawingVisual visual = FindChildren(mousePosition); if (visual != null) { edgeVisuals.TryGetValue(visual, out newCompId); if ((newCompId != uint.MaxValue) && (newCompId != 0) && graphController.CurrentDragState == DragState.None) { ScrollToVisual(visual); return; } nodeVisuals.TryGetValue(visual, out newCompId); graphController.HitTestComponent(newCompId, mousePosition, out nodePart, out index); } if (graphController.CurrentDragState == DragState.RegionSelection) { foreach (uint compId in selectedComponent) graphController.DoSelectComponent(compId, modifiers); } if (graphController.CurrentDragState != DragState.None) { // The graph controller is in a dragging state when mouse button // is released, send a signal for it to get out of dragging mode. bool ignoreEndDrag = false; if (graphController.CurrentDragState == DragState.CurveDrawing || graphController.CurrentDragState == DragState.EdgeReconnection) { if ((lastClickedNodeId == newCompId) && (lastClickedNodeIndex == index) && (lastClickedNodePart == nodePart)) //if release mouse on the same slot ignoreEndDrag = true; } if (!ignoreEndDrag) { graphController.DoEndDrag(MouseButton.Left, newCompId, nodePart, index, modifiers, mousePosition.X, mousePosition.Y); mouseDownPosition = new Point(-1, -1); lastClickedNodeId = uint.MaxValue; // reset lastClickedNodeIndex = int.MaxValue; lastClickedNodePart = NodePart.None; } } graphController.DoMouseUp(MouseButton.Left, newCompId, nodePart, index, modifiers); }
internal void HandleMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { isMouseButtonDown = true; ScrollViewer scrollViewer = graphControl.canvasScrollViewer; mouseDownScreenPosition = e.GetPosition(scrollViewer); // for zoom and pan if (panning) return; if ((graphController.CurrentDragState == DragState.CurveDrawing) || (graphController.CurrentDragState == DragState.EdgeReconnection)) return; if (extendedBubble.Count() > 0) // toggle the exteded bubbles(one with text selected) { List<ExtendedPreview> previewToRemove = new List<ExtendedPreview>(); foreach (ExtendedPreview previewTextBox in extendedBubble) previewToRemove.Add(previewTextbox); foreach (ExtendedPreview previewTextBox in previewToRemove) graphController.TransientExtendPreviewBubble((uint)previewTextbox.Tag, false); } mousePosition = e.GetPosition(graphCanvas); mouseDownPosition = mousePosition; ModifierKeys modifiers = Keyboard.Modifiers; uint newCompId = uint.MaxValue; int index = -1; NodePart nodePart = NodePart.None; string temp = string.Empty; DrawingVisual visual = FindChildren(mousePosition); if (visual != null) { edgeVisuals.TryGetValue(visual, out newCompId); if (!graphController.CheckEdgeType(newCompId))//it is implicit edge newCompId = uint.MaxValue; if ((newCompId != uint.MaxValue) && (newCompId != 0)) { if (!modifiers.HasFlag(ModifierKeys.Control) && !modifiers.HasFlag(ModifierKeys.Shift)) graphController.DoClearSelection(); graphController.DoSelectComponent(newCompId, modifiers); return; } bubbleVisuals.TryGetValue(visual, out newCompId); // toggle bubble visibility if (newCompId != uint.MaxValue && newCompId != 0) { IInfoBubble bubble; graphController.GetInfoBubble(newCompId, out bubble); if (bubble == null || !bubble.IsPreviewBubble || !WithinBubbleToggleVisibilityRegion(mousePosition, visual)) return; if (transientExtendedBubble.Contains(newCompId)) transientExtendedBubble.Remove(newCompId); graphController.DoTogglePreview(newCompId); if (bubble.Collapsed) graphControl.SetCursor(CursorSet.Index.Expand); else graphControl.SetCursor(CursorSet.Index.Condense); return; } nodeVisuals.TryGetValue(visual, out newCompId); graphController.HitTestComponent(newCompId, mousePosition, out nodePart, out index); if (radialMenu != null) { int menuId = 0; if (subRadialMenu != null) { menuId = subRadialMenu.HandleClick(mousePosition); if (menuId > 0) this.graphController.DoSelectMenuItem(menuId, mousePosition.X, mousePosition.Y, radialMenu.GetNodeId(), radialMenu.GetNodePart()); else if (menuId == -1) //first radial Menu clicked { menuId = radialMenu.HandleClick(mousePosition); if (menuId > 0) this.graphController.DoSelectMenuItem(menuId, mousePosition.X, mousePosition.Y, radialMenu.GetNodeId(), radialMenu.GetNodePart()); } } else { menuId = radialMenu.HandleClick(mousePosition); if (menuId > 0) this.graphController.DoSelectMenuItem(menuId, mousePosition.X, mousePosition.Y, radialMenu.GetNodeId(), radialMenu.GetNodePart()); } if (menuId != 0) { RemoveRadialMenu(); RemoveSubRadialMenu(); } return; } } else { RemoveRadialMenu(); RemoveSubRadialMenu(); } if (e.ClickCount == 2) HandleDoubleClick(nodePart, newCompId, index, visual); if (nodePart == NodePart.InputSlot || nodePart == NodePart.OutputSlot)//for click(mouse down and up) and drag to connect edge { if (lastClickedNodeId == newCompId && lastClickedNodeIndex == index && lastClickedNodePart == nodePart) { lastClickedNodeId = uint.MaxValue; // reset lastClickedNodeIndex = int.MaxValue; lastClickedNodePart = NodePart.None; } else { lastClickedNodeId = newCompId; lastClickedNodeIndex = index; lastClickedNodePart = nodePart; } } graphController.DoMouseDown(MouseButton.Left, newCompId, nodePart, index, modifiers); }
internal bool DisableEdit() { if (this.partSelectedForEdit == NodePart.Caption || this.partSelectedForEdit == NodePart.Text || this.partSelectedForEdit == NodePart.ReplicationGuide) { this.partSelectedForEdit = NodePart.None; return true; } else throw new InvalidOperationException(); }
void AddNodePart(NodePart np) { T val = (np as INodePart).SomeValue; //require downcast here.
internal EdgeConnectionFlag AttemptConnectEdge(VisualNode node, NodePart nodePart, int index, out List<IVisualNode> nodeToModify) { nodeToModify = new List<IVisualNode>(); connectNodeId = uint.MaxValue; connectSlotId = uint.MaxValue; connectSlotType = SlotType.None; SlotType startSlotType = SlotType.None; if (node != null) { connectNodeId = node.NodeId; if (graphController.CurrentDragState == DragState.CurveDrawing) { if (currentlySelectedNodeId == connectNodeId) return EdgeConnectionFlag.None; startSlotType = currentlySelectedSlotType; } else { foreach (uint slotId in reconnectingSlots) //try to connect any of the reconnecting node { if (connectNodeId == graphController.GetSlot(slotId).Owners.Last()) return EdgeConnectionFlag.None; } if (graphController.GetSlot(lastConnectedSlotId).SlotType == SlotType.Output) startSlotType = SlotType.Input; else startSlotType = SlotType.Output; } if (nodePart == NodePart.InputSlot || nodePart == NodePart.InputLabel || nodePart == NodePart.ReplicationGuide) { connectSlotType = SlotType.Input; connectSlotId = node.GetInputSlot(index); } else if (nodePart == NodePart.OutputSlot || (nodePart == NodePart.Text && node.VisualType != NodeType.CodeBlock)) // user can only connect to the output slot of the CBN { connectSlotType = SlotType.Output; connectSlotId = node.GetOutputSlot(index); } else if (node.VisualType == NodeType.Identifier && nodePart == NodePart.Caption) { if (startSlotType == SlotType.Output) { connectSlotType = SlotType.Input; connectSlotId = node.GetInputSlot(0); } else if (startSlotType == SlotType.Input) { connectSlotType = SlotType.Output; connectSlotId = node.GetOutputSlot(0); } } } if (graphController.CurrentDragState == DragState.CurveDrawing) { if (connectSlotId == 0 || connectSlotId == uint.MaxValue) return EdgeConnectionFlag.None; if (currentlySelectedSlotType == connectSlotType) return EdgeConnectionFlag.Illegal; // Check if these is a edge between the two slots already if (startSlotType == SlotType.Input) { this.inputSlotId = currentlySelectedSlotId; this.outputSlotId = connectSlotId; } else { this.inputSlotId = connectSlotId; this.outputSlotId = currentlySelectedSlotId; } var entry = edgeCollection.FirstOrDefault(x => IsAdded(x.Value)); if ((edgeCollection.Count() != 0) && (entry.Value != null)) return EdgeConnectionFlag.None; nodeToModify.Add(graphController.GetVisualNode(currentlySelectedNodeId)); nodeToModify.Add(node); //check if it is a edge replace(the input slot is connect to other node already) if (FindEdgeToBeReplaced(out edgeToBeReplaced)) { nodeToModify.Add(graphController.GetVisualNode (graphController.GetSlot(edgeToBeReplaced.StartSlotId).Owners.Last())); nodeToModify.Add(graphController.GetVisualNode (graphController.GetSlot(edgeToBeReplaced.EndSlotId).Owners.Last())); } return EdgeConnectionFlag.NewEdge; } else { nodeToModify.Add(graphController.GetVisualNode (graphController.GetSlot(lastConnectedSlotId).Owners.Last())); foreach (uint slotId in reconnectingSlots) { nodeToModify.Add(graphController.GetVisualNode (graphController.GetSlot(slotId).Owners.Last())); } if (connectSlotId == 0 || connectSlotId == uint.MaxValue) return EdgeConnectionFlag.None; if (connectSlotType != graphController.GetSlot(lastConnectedSlotId).SlotType) return EdgeConnectionFlag.Illegal; if (lastConnectedSlotId == connectSlotId) // node modification is needed only when the it reconnect to different slot { nodeToModify = new List<IVisualNode>(); } else { nodeToModify.Add(node); //check if it is a edge replace(the input slot is connect to other node already) if (FindEdgeToBeReplaced(reconnectingSlots[0], out edgeToBeReplaced)) { if (!reconnectingEdges.Contains(edgeToBeReplaced.EdgeId)) { nodeToModify.Add(graphController.GetVisualNode (graphController.GetSlot(edgeToBeReplaced.StartSlotId).Owners.Last())); nodeToModify.Add(graphController.GetVisualNode (graphController.GetSlot(edgeToBeReplaced.EndSlotId).Owners.Last())); } } } return EdgeConnectionFlag.ReconnectEdge; } }
private bool HandleEndDrag(GraphCommand command) { MouseButton button = ((MouseButton)command.GetArgument(0)); uint compId = ((uint)command.GetArgument(1)); NodePart nodePart = ((NodePart)command.GetArgument(2)); int slotIndex = ((int)command.GetArgument(3)); ModifierKeys modifiers = ((ModifierKeys)command.GetArgument(4)); double mouseX = ((double)command.GetArgument(5)); double mouseY = ((double)command.GetArgument(6)); switch (currentDragState) { case DragState.NodeRepositioning: foreach (DraggedNode draggedNode in dragSet) { ((VisualNode)draggedNode.node).X = mouseX - draggedNode.DeltaX; ((VisualNode)draggedNode.node).Y = mouseY - draggedNode.DeltaY; } // both node that the edge is connected to should be bring to back // foreach (VisualNode connectingNode in edgeController.GetNodesFromSelectedEdges()) { if (!connectingNode.Selected) { RearrangeNodeAndBubbleVisual(connectingNode, false); } } dragSet.Clear(); edgeController.ResetAllEdges(); break; case DragState.CurveDrawing: case DragState.EdgeReconnection: edgeConnection = EdgeConnectionFlag.None; VisualNode node = GetVisualNode(edgeController.GetConnectNodeId()); if (null != node) { node.PreviewSelected = node.Selected; node.Compose(); // Optionally redraw the node. } node = GetVisualNode(edgeController.GetCurrentlySelectedNodeId()); if (null != node) { node.Selected = false; node.Compose(); // reset highlighted node } node = GetVisualNode(compId); List <IVisualNode> modifiedNodes = null; edgeConnection = edgeController.AttemptConnectEdge(node, nodePart, slotIndex, out modifiedNodes); DeltaNodes deltaNodes = new DeltaNodes(); deltaNodes.AppendToModifiedNodes(modifiedNodes.Distinct().ToList()); //reset highlighted node foreach (IVisualNode visualNode in deltaNodes.ModifiedNodes) { ((VisualNode)visualNode).Selected = false; } // Start tracking variables being undefined in this process. { RuntimeStates runtimeStates = graphProperties.RuntimeStates; runtimeStates.BeginDefinitionMonitor(); undoRedoRecorder.BeginGroup(); undoRedoRecorder.RecordRuntimeStatesForUndo(runtimeStates); undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes); edgeController.CreateEdge(); modifiedNodes.Clear(); this.EstablishImplicitConnections(modifiedNodes); undoRedoRecorder.EndGroup(); Dictionary <uint, List <string> > undefinedVariables = null; runtimeStates.EndDefinitionMonitor(out undefinedVariables); deltaNodes.AppendUndefinedVariables(undefinedVariables); } deltaNodes.AppendToModifiedNodes(modifiedNodes); if (deltaNodes.ModifiedNodes.Count > 0) //modification have been done { SynchronizeToLiveRunner(deltaNodes); } else { undoRedoRecorder.PopRecordFromUndoStorage(); } edgeController.ResetParameters(); edgeController.ResetAllEdges(); currentDragState = DragState.None; edgeConnection = EdgeConnectionFlag.None; break; case DragState.RegionSelection: if (visualHost != null) { visualHost.EndDragSelection(); } break; } //currentDragState = DragState.None; selectionBox.UpdateSelectionBox(GetSelectedNodes()); return(true); }
private bool HandleMouseUp(GraphCommand command) { MouseButton button = ((MouseButton)command.GetArgument(0)); uint compId = ((uint)command.GetArgument(1)); NodePart nodePart = ((NodePart)command.GetArgument(2)); int slotIndex = ((int)command.GetArgument(3)); ModifierKeys modifiers = ((ModifierKeys)command.GetArgument(4)); if (currentDragState == DragState.None) { IVisualNode node = null; VisualNode visNode = null; nodeCollection.TryGetValue(compId, out node); if (null != node) { visNode = node as VisualNode; } switch (nodePart) { case NodePart.InputSlot: case NodePart.OutputSlot: case NodePart.NorthWest: case NodePart.South: case NodePart.Caption: case NodePart.Text: case NodePart.North: case NodePart.ReplicationGuide: case NodePart.InputLabel: break; case NodePart.NorthEast: visNode.ToggleContextualMenu(nodePart); break; case NodePart.Preview: //visNode.TogglePreview(); break; case NodePart.PreviewNorthEast: //visNode.ToggleContextualMenu(nodePart); break; default: if (!modifiers.HasFlag(ModifierKeys.Control) && !modifiers.HasFlag(ModifierKeys.Shift)) { ClearSelectionInternal(); } break; } if (visualHost != null && visNode != null && visNode.Selected) { visualHost.ScrollToVisual(visualHost.GetDrawingVisualForNode(visNode.NodeId)); } } else if (currentDragState != DragState.CurveDrawing && currentDragState != DragState.EdgeReconnection) // for click and drag { currentDragState = DragState.None; // it won't end when mouseup on the same slot } // IDE-1371 selectionBox.UpdateSelectionBox(GetSelectedNodes()); return(true); }
internal void HandleMouseRightButtonDown(object sender, MouseButtonEventArgs e) { isMouseButtonDown = true; if (graphController.CurrentDragState == DragState.CurveDrawing || graphController.CurrentDragState == DragState.EdgeReconnection) { graphController.DoEndDrag(MouseButton.Left, 0, NodePart.None, -1, ModifierKeys.None, -1, -1); lastClickedNodeId = uint.MaxValue; // reset lastClickedNodeIndex = int.MaxValue; lastClickedNodePart = NodePart.None; mouseDownPosition = new Point(-1, -1); graphControl.SetCursor(CursorSet.Index.Pointer); return; } ScrollViewer scrollViewer = graphControl.canvasScrollViewer; mouseDownScreenPosition = e.GetPosition(scrollViewer); BeginPan(); //mousePosition = e.GetPosition((UIElement)sender); //ModifierKeys modifiers = Keyboard.Modifiers; //uint newCompId = uint.MaxValue; //int index = -1; //NodePart nodePart = NodePart.None; //string temp = string.Empty; //DrawingVisual visual = FindChildren(mousePosition); //if (visual != null) //{ // nodeVisuals.TryGetValue(visual, out newCompId); // graphController.HitTestComponent(newCompId, mousePosition, out nodePart, out index); //} //if (nodePart != NodePart.None && nodePart != NodePart.Preview && nodePart != NodePart.PreviewNorthEast && nodePart != NodePart.PreviewNorthWest) //{ // graphController.DoSelectComponent(newCompId,modifiers); // return; //} }
protected Node loadNode(ModelNode modelNode) { Node node = new Node(); node.id = modelNode.id; if (modelNode.translation != null) { node.translation = (modelNode.translation); } if (modelNode.rotation != null) { node.rotation = (modelNode.rotation); } if (modelNode.scale != null) { node.scale = (modelNode.scale); } // FIXME create temporary maps for faster lookup? if (modelNode.parts != null) { foreach (ModelNodePart modelNodePart in modelNode.parts) { MeshPart meshPart = null; Material meshMaterial = null; if (modelNodePart.meshPartId != null) { foreach (MeshPart part in meshParts) { if (modelNodePart.meshPartId == (part.id)) { meshPart = part; break; } } } if (modelNodePart.materialId != null) { foreach (Material material in materials) { if (modelNodePart.materialId == (material.id)) { meshMaterial = material; break; } } } if (meshPart == null || meshMaterial == null) { throw new Exception("Invalid node: " + node.id); } if (meshPart != null && meshMaterial != null) { NodePart nodePart = new NodePart(); nodePart.meshPart = meshPart; nodePart.material = meshMaterial; node.parts.Add(nodePart); if (modelNodePart.bones != null) { nodePartBones.Add(nodePart, modelNodePart.bones); } } } } if (modelNode.children != null) { foreach (ModelNode child in modelNode.children) { node.addChild(loadNode(child)); } } return(node); }
public bool GetNodePartRegion(uint compId, NodePart nodePart, Point mousePt, out Rect result, out NodeType type) { result = new Rect(); type = NodeType.None; IVisualNode iNode = GetVisualNode(compId); VisualNode node = ((VisualNode)iNode); if (null == node) { return(false); } type = node.VisualType; double centerLine = 0; double width = node.Width; double height = node.Height; if (nodePart == NodePart.None) { result.X = node.X; result.Y = node.Y; result.Width = node.Width; result.Height = node.Height; return(true); } if (nodePart == NodePart.North || nodePart == NodePart.South) { centerLine = node.CenterLine; result.X = node.X; result.Y = node.Y; result.Width = centerLine; result.Height = node.Height; } switch (node.VisualType) { case NodeType.Function: centerLine = node.CenterLine; if (nodePart == NodePart.Caption) { result = new Rect(new Point(node.X + centerLine, node.Y + 0), new Point(node.X + width, node.Y + height / 2)); return(true); } if (nodePart == NodePart.Text) { result = new Rect(new Point(node.X + centerLine, node.Y + height / 2), new Point(node.X + width, node.Y + height)); return(true); } if (nodePart == NodePart.ReplicationGuide) { FunctionNode fNode = node as FunctionNode; result = new Rect(new Size(Configurations.ReplicationGuideWidth, Configurations.SlotStripeSize)); mousePt.X -= node.X; mousePt.Y -= node.Y; double deltaX = centerLine - mousePt.X; int replicationIndex = (int)(deltaX / (Configurations.ReplicationGuideWidth + Configurations.TriangleHeight)); double slotCount = node.GetInputSlots().Count(); double slotHeight = (node.Height) / slotCount; int slotIndex = (int)((mousePt.Y) / slotHeight); result.Location = new Point(node.X + centerLine - fNode.GetMaxReplicationWidth(), node.Y + slotIndex * Configurations.SlotStripeSize + 1); return(true); } //take inputSlots into consideration break; case NodeType.Driver: centerLine = node.CenterLine; if (nodePart == NodePart.Caption) { result = new Rect(new Point(node.X + 0, node.Y + 0), new Point(node.X + centerLine, node.Y + height)); return(true); } if (nodePart == NodePart.Text) { result = new Rect(new Point(node.X + centerLine, node.Y + 0), new Point(node.X + width, node.Y + height)); return(true); } break; case NodeType.CodeBlock: if (nodePart == NodePart.Text) { result = new Rect(new Point(node.X + 0, node.Y + 0), new Point(node.X + width, node.Y + height)); return(true); } break; case NodeType.Identifier: if (nodePart == NodePart.Caption) { result = new Rect(new Point(node.X + 0, node.Y + 0), new Point(node.X + width, node.Y + height)); return(true); } break; case NodeType.Property: if (nodePart == NodePart.Caption) { result = new Rect(new Point(node.X, node.Y + 0), new Point(node.X + width, node.Y + height / 2)); return(true); } else if (nodePart == NodePart.Text) { result = new Rect(new Point(node.X, node.Y + height / 2), new Point(node.X + width, node.Y + height)); return(true); } break; default: result = new Rect(); return(false); } return(false); }
public void SetMouseCursor(uint nodeId, NodePart nodePart, int index, ModifierKeys modifiers, bool isMouseButtonDown, double x, double y) { if (0 == nodeId) { // When the UI calls this method, we are only expecting two possible // value ranges for 'nodeId': a "uint.MaxValue" when the 'nodeId' is // invalid, or a positive number. This should not be zero, if it is, // do let me know. - Ben. throw new ArgumentException("121B20BE: Invalid argument!", "nodeId"); } if (currentDragState == DragState.NodeRepositioning) { if (!isMouseButtonDown) { return; } foreach (DraggedNode draggedNode in dragSet) { if (visualHost != null) { VisualNode node = (VisualNode)draggedNode.node; DrawingVisual visual = visualHost.GetDrawingVisualForNode(node.NodeId); TranslateTransform transform = visual.Transform as TranslateTransform; transform.X = x - draggedNode.DeltaX; transform.Y = y - draggedNode.DeltaY; node.X = transform.X; node.Y = transform.Y; this.TransformBubble(node, transform); } } edgeController.UpdateSelectedEdges(); selectionBox.UpdateSelectionBox(x, y); } else if ((currentDragState == DragState.CurveDrawing) || (currentDragState == DragState.EdgeReconnection)) { if (nodePart != NodePart.None && nodeId == uint.MaxValue) { throw new InvalidOperationException("Nodepard and NodeId are not in consistent (914C54A64BFD)"); } VisualNode node = null; edgeConnection = EdgeConnectionFlag.None; if (nodePart != NodePart.None) { node = GetVisualNode(nodeId); } else { if (lastHoveredNodeId != uint.MaxValue && lastHoveredNodeId != edgeController.GetCurrentlySelectedNodeId()) { node = GetVisualNode(lastHoveredNodeId); node.PreviewSelected = node.Selected;//reset the original state of the node RearrangeNodeAndBubbleVisual(node, false); } } //verification List <IVisualNode> nodeToModify; edgeConnection = edgeController.AttemptConnectEdge(node, nodePart, index, out nodeToModify); if (nodePart != NodePart.None) { if ((edgeConnection == EdgeConnectionFlag.NewEdge || edgeConnection == EdgeConnectionFlag.ReconnectEdge) && (nodePart == NodePart.InputSlot || nodePart == NodePart.InputLabel || nodePart == NodePart.ReplicationGuide)) { node.SetHoveredIndex(index); } node.PreviewSelected = true; RearrangeNodeAndBubbleVisual(node, true); } if (edgeConnection != EdgeConnectionFlag.None && edgeConnection != EdgeConnectionFlag.Illegal) { edgeController.DrawConnectingEdgeTo(); } else { edgeController.DrawConnectingEdgeTo(new Point(x, y)); } lastHoveredNodeId = nodeId; if (null != node) { node.Compose(); // Optionally redraw the node. } } }
public bool DoSelectMenuItem(int menuItemId, double x, double y, uint nodeId, NodePart nodePart) { GraphCommand command = new GraphCommand(GraphCommand.Name.SelectMenuItem); command.AppendArgument(menuItemId); command.AppendArgument(x); command.AppendArgument(y); command.AppendArgument(nodeId); command.AppendArgument(nodePart); return(RerouteToHandler(command)); }
internal bool EnableEdit(NodePart nodePart, int index) { if (this.partSelectedForEdit != NodePart.None) return false;//throw exception // Replication guide index should only be specified for this case. if (nodePart != NodePart.ReplicationGuide && (index != -1)) throw new ArgumentException("Index should not be specified (34BB6918677B)", "index"); this.partSelectedForEdit = nodePart; this.replicationIndex = index; return true; }
internal void HandleMouseMove(object sender, MouseEventArgs e) { if (animationOn) return; if (editTextbox != null) //prevent the code blocks from moving return; bool cursorSet = false; ModifierKeys modifiers = Keyboard.Modifiers; uint nodeId = uint.MaxValue; uint edgeId = uint.MaxValue; int index = -1; NodePart nodePart = NodePart.None; DrawingVisual drawingVisual; // Pan ScrollViewer scrollViewer = graphControl.canvasScrollViewer; Point mouseScreenPosition = e.GetPosition(scrollViewer); if (panning) { if (!isMouseButtonDown) { graphControl.SetCursor(CursorSet.Index.HandPan); return; } graphControl.SetCursor(CursorSet.Index.HandPanActive); double shiftX = mouseScreenPosition.X - mouseDownScreenPosition.X; double shiftY = mouseScreenPosition.Y - mouseDownScreenPosition.Y; mouseDownScreenPosition = mouseScreenPosition; scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - shiftX); scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - shiftY); return; } //Auto Pan the canvas when mouse near the border of the window AutoPan(mouseScreenPosition); if (graphController.CurrentDragState == DragState.None) { // In the section below for the "BeginDrag", we are using the mouseDownPosition instead current mouse position // The reason is that once we mousedown and move the mouse so fast then the mousePosition is so far away the mouseDownPosition // IDE-1509 // drawingVisual = FindChildren(mouseDownPosition); if (drawingVisual != null) { if (nodeVisuals.TryGetValue(drawingVisual, out nodeId)) graphController.HitTestComponent(nodeId, mouseDownPosition, out nodePart, out index); else { // If the mouse cursor is over an edge, then we'll reset // "nodeId" to indicate there's no node being hit right now. nodeId = uint.MaxValue; } } bool ignorDrag = false; if (!((lastClickedNodeId == nodeId) && (lastClickedNodeIndex == index) && (lastClickedNodePart == nodePart)) //if mouse not on the same slot && (!isMouseButtonDown)) ignorDrag = true; if (!ignorDrag) { MouseButton button = MouseButton.Left; if (e.RightButton == MouseButtonState.Pressed) button = MouseButton.Right; //(TODO:Joy)(? from Vic: is it the correct place for it?) //remove the radial menu when dragging RemoveRadialMenu(); RemoveSubRadialMenu(); // Begin graph controller into a dragging mode since // this is the first mouse move sample after mouse down. graphController.DoBeginDrag(button, nodeId, nodePart, index, modifiers, mouseDownPosition.X, mouseDownPosition.Y); } } nodeId = uint.MaxValue; index = -1; nodePart = NodePart.None; mousePosition = e.GetPosition(graphCanvas); drawingVisual = FindChildren(mousePosition); // remove extended preview, excluding ones that got selected text or got radial menu if (extendedBubble.Count() > 0 && e.LeftButton != MouseButtonState.Pressed) { List<ExtendedPreview> previewToRemove = new List<ExtendedPreview>(); foreach (ExtendedPreview previewTextBox in extendedBubble) { if (!IsMouseInExtendedBubble(mousePosition, previewTextbox) && string.IsNullOrEmpty(previewTextbox.InternalTextBox.SelectedText) && (uint)previewTextbox.Tag != lastHoveredBubbleId) previewToRemove.Add(previewTextbox); } foreach (ExtendedPreview previewTextBox in previewToRemove) graphController.TransientExtendPreviewBubble((uint)previewTextbox.Tag, false); } List<uint> ignoreTransientExtendedBubble = new List<uint>(); if (nodeVisuals.Count > 0 && drawingVisual != null) { if (nodeVisuals.TryGetValue(drawingVisual, out nodeId)) // check for node { graphController.HitTestComponent(nodeId, mousePosition, out nodePart, out index); } else if (edgeVisuals.TryGetValue(drawingVisual, out edgeId)) // check for edge { // If the mouse cursor is over an edge, then we'll reset // "nodeId" to indicate there's no node being hit right now. nodeId = uint.MaxValue; if (!graphController.CheckEdgeType(edgeId))//implecit edge edgeId = uint.MaxValue; } else // check for preview { nodeId = uint.MaxValue; edgeId = uint.MaxValue; if (graphController.CurrentDragState == DragState.None) { uint bubbleId = uint.MaxValue; if ((!FindExtendedBubbleOn(mousePosition)) && (FindBubble(drawingVisual, out bubbleId))) // hover on condensed drawing visual { IInfoBubble bubble = null; graphController.GetInfoBubble(bubbleId, out bubble); //radial menu for bubble Point pt = new Point(); Point anchorPoint = bubble.AnchorPoint; pt.X = mousePosition.X - drawingVisual.Transform.Value.OffsetX; pt.Y = mousePosition.Y - drawingVisual.Transform.Value.OffsetY; anchorPoint.Offset(bubble.Width / 2, 0); if (this.graphController.PreviewBubbleHittest(pt, bubbleId)) { this.CreateRadialMenuForPreview(anchorPoint, bubbleId); return; } if (transientExtendedBubble.Contains(bubbleId)) ignoreTransientExtendedBubble.Add(bubbleId); // condense extended bubbles List<ExtendedPreview> previewToRemove = new List<ExtendedPreview>(); foreach (ExtendedPreview previewTextBox in extendedBubble) previewToRemove.Add(previewTextbox); if (WithinBubbleToggleVisibilityRegion(mousePosition, drawingVisual)) { if (bubble.Collapsed && !bubble.Extended) { graphController.TransientShowPreviewBubble(bubbleId, true); transientExtendedBubble.Add(bubbleId); ignoreTransientExtendedBubble.Add(bubbleId); } else { // if the extended preview box of hovered preview is found, // condense needed // ExtendedPreview hoveredPreviewBox = null; foreach (ExtendedPreview previewTextBox in extendedBubble) { if ((uint)previewTextbox.Tag == bubbleId) { hoveredPreviewBox = previewTextbox; break; } } if (hoveredPreviewBox != null) previewToRemove.Remove(hoveredPreviewBox); } if (!bubble.Collapsed && !transientExtendedBubble.Contains(bubbleId)) graphControl.SetCursor(CursorSet.Index.Condense); else graphControl.SetCursor(CursorSet.Index.Expand); cursorSet = true; } else { graphController.TransientExtendPreviewBubble(bubbleId, true); } foreach (ExtendedPreview previewTextBox in previewToRemove) graphController.TransientExtendPreviewBubble((uint)previewTextbox.Tag, false); } } } } // radial menu hovered bubble if (lastHoveredBubbleId != uint.MaxValue && !ignoreTransientExtendedBubble.Contains(lastHoveredBubbleId)) ignoreTransientExtendedBubble.Add(lastHoveredBubbleId); // toggle to hide all the temprarily showed PreviewBubble but the currently hovered one foreach (uint bubbleId in transientExtendedBubble.Except(ignoreTransientExtendedBubble)) { graphController.TransientShowPreviewBubble(bubbleId, false); } transientExtendedBubble.Clear(); transientExtendedBubble.AddRange(ignoreTransientExtendedBubble); // radial menu if (drawingVisual != null) { if (subRadialMenu != null && radialMenu != null) { if (subRadialMenu.GetRadialVisual() == drawingVisual || radialMenu.GetRadialVisual() == drawingVisual) { Point temp; int tempId; bool result = subRadialMenu.HandleMouseMove(mousePosition, out temp, out tempId); if (result == false) { radialMenu.HandleMouseMove(mousePosition, out temp, out tempId); if (tempId != selectedMenuId && tempId != int.MinValue) { RemoveSubRadialMenu(); radialMenu.UnFade(); selectedMenuId = tempId; ResetSubRadialMenuTimer(); } } } else { ResetSubRadialMenuTimer(); RemoveSubRadialMenu(); } } else if (subRadialMenu == null && radialMenu != null) { if (radialMenu.GetRadialVisual() == drawingVisual) { Point temp; int tempId; bool result = radialMenu.HandleMouseMove(mousePosition, out temp, out tempId); if (tempId != selectedMenuId) { RemoveSubRadialMenu(); if (selectedMenuId != tempId) { selectedMenuId = tempId; ResetSubRadialMenuTimer(); } } if (subRadialMenu == null && result == true) { if (selectedMenuId == tempId && tempId > Configurations.PropertyBase) { CreateSubRadialMenuTimer(); subRadialMenuPoint = temp; } } } else RemoveRadialMenu(); } else if (drawingVisual == selectionBoxVisual && graphController.CurrentDragState == DragState.None) { if (this.graphController.SelectionBoxHittest(mousePosition)) CreateRadialMenuForSelectionBox(); } else { if (nodePart == NodePart.NorthEast || nodePart == NodePart.NorthWest || nodePart == NodePart.North || nodePart == NodePart.South) { if (this.graphController.CurrentDragState == DragState.None) CreateRadialMenu(nodeId, nodePart, new Point()); } } } else { RemoveRadialMenu(); RemoveSubRadialMenu(); ResetSubRadialMenuTimer(); } // window select node if (graphController.CurrentDragState == DragState.RegionSelection) { List<uint> currentSelectedComponent = this.GetComponents(); //update newly add element foreach (uint componentId in currentSelectedComponent.Except(selectedComponent)) graphController.PreviewSelectComponent(componentId, modifiers); //update element that not in the rectangle region anylonger foreach (uint componentId in selectedComponent.Except(currentSelectedComponent)) graphController.ClearPreviewSelection(componentId); selectedComponent = currentSelectedComponent; } if (!(lastClickedNodeId == nodeId && lastClickedNodeIndex == index && lastClickedNodePart == nodePart)) { lastClickedNodeId = uint.MaxValue; lastClickedNodeIndex = int.MaxValue; lastClickedNodePart = NodePart.None; } graphController.SetMouseCursor(nodeId, nodePart, index, modifiers, isMouseButtonDown, mousePosition.X, mousePosition.Y); if (cursorSet) return; else if (edgeId != uint.MaxValue && edgeId != 0) graphControl.SetCursor(CursorSet.Index.ArcSelect); else if (graphController.EdgeConnection == EdgeConnectionFlag.NewEdge) graphControl.SetCursor(CursorSet.Index.ArcAddEnd); else if (graphController.EdgeConnection == EdgeConnectionFlag.ReconnectEdge) graphControl.SetCursor(CursorSet.Index.ArcRemove); else if (graphController.CurrentDragState == DragState.RegionSelection) graphControl.SetCursor(CursorSet.Index.RectangularSelection); else if ((graphController.CurrentDragState == DragState.None) && (nodePart == NodePart.InputSlot || nodePart == NodePart.OutputSlot)) graphControl.SetCursor(CursorSet.Index.ArcAdd); else graphControl.SetCursor(CursorSet.Index.Pointer); }
private bool HandleMouseDown(GraphCommand command) { MouseButton button = ((MouseButton)command.GetArgument(0)); uint compId = ((uint)command.GetArgument(1)); NodePart nodePart = ((NodePart)command.GetArgument(2)); int slotIndex = ((int)command.GetArgument(3)); ModifierKeys modifiers = ((ModifierKeys)command.GetArgument(4)); if (nodePart != NodePart.None) { if (IdGenerator.GetType(compId) != ComponentType.Node) { throw new InvalidOperationException("Component type mismatch!"); } IVisualNode node = null; nodeCollection.TryGetValue(compId, out node); if (null == node) { throw new ArgumentException("Invalid argument!", "compId"); } VisualNode visualNode = node as VisualNode; switch (nodePart) { case NodePart.North: case NodePart.South: case NodePart.NorthEast: case NodePart.NorthWest: case NodePart.PreviewNorthEast: case NodePart.Preview: ClearSelectionInternal(); RearrangeNodeAndBubbleVisual(visualNode, true); visualNode.Selected = true; break; case NodePart.Caption: case NodePart.Text: case NodePart.ReplicationGuide: case NodePart.InputLabel: if (visualNode.Selected) { if (modifiers.HasFlag(ModifierKeys.Control)) //remove the selected node and update the edge { visualNode.Selected = false; } } else { if (!modifiers.HasFlag(ModifierKeys.Control) && !modifiers.HasFlag(ModifierKeys.Shift)) { ClearSelectionInternal(); } RearrangeNodeAndBubbleVisual(visualNode, true); visualNode.Selected = true; } break; case NodePart.InputSlot: case NodePart.OutputSlot: break; } if (null != visualNode) { visualNode.Compose(); // Redraw for selection change. } } selectionBox.UpdateSelectionBox(GetSelectedNodes()); return(true); }
private void CreateRadialMenu(uint nodeId, NodePart part, Point subRadialMenuOffset) { ModifierKeys keys = Keyboard.Modifiers; if (keys.HasFlag(ModifierKeys.Control)) return; Rect result; NodeType type; double startAngle; Point worldCoords; if (this.Controller.GetNodePartRegion(nodeId, NodePart.None, mouseDownPosition, out result, out type) == false) return; worldCoords = result.Location; switch (part) { case NodePart.NorthEast: startAngle = 90; worldCoords.X += result.Width; worldCoords.Offset(-Configurations.CenterOffsetX, Configurations.CenterOffsetY); break; case NodePart.North: startAngle = 180; this.Controller.GetNodePartRegion(nodeId, NodePart.North, mouseDownPosition, out result, out type); worldCoords.X += result.Width; worldCoords.Offset(Configurations.CenterOffsetX, Configurations.CenterOffsetY); break; case NodePart.NorthWest: startAngle = 180; worldCoords.Offset(Configurations.CenterOffsetX, Configurations.CenterOffsetY); break; case NodePart.South: startAngle = 270; this.Controller.GetNodePartRegion(nodeId, NodePart.South, mouseDownPosition, out result, out type); worldCoords.X += result.Width; worldCoords.Y += result.Height; worldCoords.Offset(Configurations.CenterOffsetX, -Configurations.CenterOffsetY); break; default: startAngle = 90; worldCoords.X += result.Width; worldCoords.Offset(-Configurations.CenterOffsetX, Configurations.CenterOffsetY); break; } Dictionary<int, string> menuItems = null; Dictionary<int, string> overloadedItems = null; if (this.lastHoveredNodePart != part || this.lastHoveredNodeId != nodeId) { this.graphController.DoCreateRadialMenu(part, nodeId); lastHoveredNodePart = part; lastHoveredNodeId = nodeId; selectedMenuId = int.MinValue; } this.graphController.GetMenuItems(out menuItems, out overloadedItems); if (null != menuItems && (menuItems.Count > 0)) { radialMenu = new RadialMenu(nodeId, worldCoords, Configurations.CircleRadius, menuItems, startAngle, part); this.children.Add(radialMenu.GetRadialVisual()); ScrollToMenuVisual(radialMenu.GetRadialVisual(), radialMenu.GetMenuWidth()); if (Application.Current != null && (Application.Current.MainWindow != null)) { if (Application.Current.MainWindow.IsFocused == false) { Application.Current.MainWindow.Activate(); Application.Current.MainWindow.Topmost = true; Application.Current.MainWindow.Topmost = false; Application.Current.MainWindow.Focus(); } } Keyboard.Focus(this.graphCanvas.graphCanvas); } }
private void CreateRadialMenuForSelectionBox() { double startAngle = 90; Point worldCoords = this.graphController.GetNorthEastPositionOfSelectionBox(); NodePart part = NodePart.NorthEast; worldCoords.Offset(-Configurations.CenterOffsetX, Configurations.CenterOffsetY); Dictionary<int, string> menuItems = new Dictionary<int, string>(); Dictionary<int, string> overloadedItems = new Dictionary<int, string>(); if (this.lastHoveredNodePart != part || this.lastHoveredNodeId != int.MaxValue) { this.graphController.DoCreateRadialMenu(part, uint.MaxValue); lastHoveredNodePart = part; lastHoveredNodeId = uint.MaxValue; selectedMenuId = int.MinValue; } this.graphController.GetMenuItems(out menuItems, out overloadedItems); if (menuItems != null && menuItems.Count > 0) { radialMenu = new RadialMenu(uint.MaxValue, worldCoords, Configurations.CircleRadius, menuItems, startAngle, part); this.children.Add(radialMenu.GetRadialVisual()); ScrollToMenuVisual(radialMenu.GetRadialVisual(), radialMenu.GetMenuWidth()); if (Application.Current != null && (Application.Current.MainWindow != null)) { if (Application.Current.MainWindow.IsFocused == false) { Application.Current.MainWindow.Activate(); Application.Current.MainWindow.Topmost = true; Application.Current.MainWindow.Topmost = false; Application.Current.MainWindow.Focus(); } } Keyboard.Focus(this.graphCanvas.graphCanvas); } }
private void HandleDoubleClick(NodePart nodePart, uint newCompId, int index, DrawingVisual visual) { graphControl.SetCursor(CursorSet.Index.Pointer); string temp; ModifierKeys modifiers = Keyboard.Modifiers; if (nodePart == NodePart.Caption || nodePart == NodePart.Text) { if (editTextbox == null) { NodeType type = NodeType.None; graphController.GetNodePartRegion(newCompId, nodePart, mousePosition, out currentNodePartRegion, out type); //calc center position of textbox in rect double x = mousePosition.X; double y = mousePosition.Y; x = (currentNodePartRegion.Right - currentNodePartRegion.Left) / 2; y = (currentNodePartRegion.Bottom - currentNodePartRegion.Top) / 2; SolidColorBrush backgroundColor; FontWeight weight; if (type != NodeType.CodeBlock) { double minTextboxWidth = 0; graphController.GetTextboxMinSize(newCompId, out minTextboxWidth); switch (type) { case NodeType.Identifier: backgroundColor = Configurations.RectWhite; weight = FontWeights.Normal; minTextboxWidth = 0; break; case NodeType.Function: if (nodePart == NodePart.Caption) { graphController.DoMouseDown(MouseButton.Left, newCompId, nodePart, index, modifiers); mouseDownPosition = mousePosition; return; } else { backgroundColor = Configurations.RectWhite; weight = FontWeights.SemiBold; } //y -= 2; break; case NodeType.Driver: if (nodePart == NodePart.Caption) backgroundColor = Configurations.RectWhite; else backgroundColor = Configurations.RectGrey; weight = FontWeights.SemiBold; minTextboxWidth = 0; break; case NodeType.Property: if (nodePart == NodePart.Caption) { graphController.DoMouseDown(MouseButton.Left, newCompId, nodePart, index, modifiers); mouseDownPosition = mousePosition; return; } else { backgroundColor = Configurations.RectWhite; weight = FontWeights.SemiBold; } break; default: backgroundColor = Configurations.RectWhite; weight = FontWeights.SemiBold; minTextboxWidth = 0; break; } CreateEditTextbox(false, backgroundColor, Configurations.Font, weight, Configurations.TextSize, minTextboxWidth); editTextbox.Alignment = TextAlignment.Center; editTextbox.SelectAll = true; x += currentNodePartRegion.Left - 3;//-3 y += currentNodePartRegion.Top - 2;//-2 graphController.GetNodeText(newCompId, nodePart, out temp); editTextbox.Text = temp; if (temp.Length > 25) temp = temp.Substring(0, 25); FormattedText newText = new FormattedText(temp, Configurations.culture, FlowDirection.LeftToRight, Configurations.TypeFace, Configurations.TextSize, Configurations.TextNormalColor); //use gettextsize() from utilities double offset = newText.WidthIncludingTrailingWhitespace; if (offset < minTextboxWidth) offset = minTextboxWidth; x -= ((offset) / 2); y -= Configurations.TextSize / 2; } else { CreateEditTextbox(true, Configurations.RectWhite, Configurations.Font, FontWeights.Normal, Configurations.TextSize, 0); graphController.GetNodeText(newCompId, nodePart, out temp); x = currentNodePartRegion.X + Configurations.TextHorizontalOffset; y = currentNodePartRegion.Y + Configurations.TextVerticalOffset; if (temp == Configurations.CodeBlockInitialMessage) editTextbox.Text = ""; else editTextbox.Text = temp; } Point cursorScreenPos = mousePosition; editTextbox.SetCursorScreenPos(cursorScreenPos); editTextbox.SetValue(Canvas.LeftProperty, x); editTextbox.SetValue(Canvas.TopProperty, y); nodeEditFlag = true; nodeEditId = newCompId; graphController.DoBeginNodeEdit(nodeEditId, nodePart); graphController.UpdateNodeText(newCompId, editTextbox.Text); } } else { if (nodeEditFlag == false && nodePart == NodePart.None && visual == null) { //create textbox if (editTextbox == null) { CreateEditTextbox(true, Configurations.RectWhite, Configurations.Font, FontWeights.Normal, Configurations.TextSize, 0); editTextbox.SetValue(Canvas.LeftProperty, mousePosition.X - 3); editTextbox.SetValue(Canvas.TopProperty, mousePosition.Y - Configurations.TextVerticalOffset - 1); editTextbox.UpdateCursor(); } graphController.DoCreateCodeBlockNode(mousePosition.X, mousePosition.Y, editTextbox.Text); editTextbox.Text = Configurations.CodeBlockInitialMessage; graphController.GetLastNodeId(out newCompId); nodeEditFlag = true; nodeEditId = newCompId; graphController.DoBeginNodeEdit(newCompId, NodePart.Text); graphController.UpdateNodeText(newCompId, editTextbox.Text); } } if (nodePart == NodePart.ReplicationGuide) { //replication guide edit Rect rect = new Rect(); NodeType type = NodeType.None; int replicationIndex; int slotIndex; nodeEditFlag = true; replicationEditFlag = true; nodeEditId = newCompId; graphController.GetNodePartRegion(newCompId, nodePart, mousePosition, out rect, out type); CreateEditTextbox(false, Configurations.RectWhite, Configurations.Font, FontWeights.Normal, Configurations.TextSize, 25); graphController.GetReplicationIndex(newCompId, mousePosition, out replicationIndex, out slotIndex); string tempText = string.Empty; if (replicationIndex != -1) { this.editingReplicationIndex = slotIndex; graphController.GetReplicationText(newCompId, slotIndex, out tempText); if (tempText == string.Empty) { tempText = Configurations.ReplicationInitialString; } else editTextbox.SetCursorScreenPos(mouseDownPosition); editTextbox.Text = tempText; editTextbox.SetValue(Canvas.LeftProperty, rect.Location.X - 7); editTextbox.SetValue(Canvas.TopProperty, rect.Location.Y + 1); graphController.DoEditReplicationGuide(newCompId, slotIndex); } } }
private void BeginDragInputOutputSlot(uint compId, NodePart nodePart, int slotIndex) { IVisualNode node = null; nodeCollection.TryGetValue(compId, out node); ((VisualNode)node).Selected = true; uint slotId = uint.MaxValue; if (nodePart == NodePart.OutputSlot) { slotId = node.GetOutputSlot(slotIndex); edgeController.SetCurrentlySelectedSlotType(SlotType.Output); } else if (nodePart == NodePart.InputSlot) { slotId = node.GetInputSlot(slotIndex); edgeController.SetCurrentlySelectedSlotType(SlotType.Input); } else { // 'BeginDragInputOutputSlot' cannot be called for things other than slots. throw new InvalidOperationException("Invalid call ot 'BeginDragInputOutputSlot'!"); } List<VisualEdge> reconnectEdges = edgeController.FindEdgesConnectingToSlot(slotId, true); if (reconnectEdges.Count() > 0) { List<uint> connectingSlots = new List<uint>(); List<uint> connectingEdges = new List<uint>(); edgeController.ResetAllEdges(); if (GetSlot(slotId).SlotType == SlotType.Output) { foreach (VisualEdge edge in reconnectEdges) { edgeController.ClearEdgeVisual(edge.EdgeId); connectingSlots.Add(edge.EndSlotId); connectingEdges.Add(edge.EdgeId); } } else { foreach (VisualEdge edge in reconnectEdges) { edgeController.ClearEdgeVisual(edge.EdgeId); connectingSlots.Add(edge.StartSlotId); connectingEdges.Add(edge.EdgeId); } } edgeController.SetConnectedSlotId(slotId); edgeController.SetReconnectingEdges(connectingEdges); edgeController.SetReconnectingSlots(connectingSlots); this.currentDragState = DragState.EdgeReconnection; foreach (uint connectingSlotId in connectingSlots) { VisualNode visualNode = GetVisualNode(GetSlot(connectingSlotId).Owners.Last()); visualNode.Selected = true; visualNode.Compose(); } ((VisualNode)node).Selected = false; } else // Normal drawing edge { edgeController.SetCurrentlySelectedNodeId(node.NodeId); edgeController.SetCurrentlySelectedSlotId(slotId); edgeController.ResetAllEdges(); this.currentDragState = DragState.CurveDrawing; } }
internal void CreateRadialMenuForPreview(Point pt, uint bubbleId) { if (radialMenu != null) return; ModifierKeys keys = Keyboard.Modifiers; if (keys.HasFlag(ModifierKeys.Control)) return; lastHoveredBubbleId = bubbleId; double startAngle = 90; Point worldCoords = pt; NodePart part = NodePart.NorthEast; worldCoords.Offset(-Configurations.CenterOffsetX, Configurations.CenterOffsetY); Dictionary<int, string> menuItems = new Dictionary<int, string>(); Dictionary<int, string> overloadedItems = new Dictionary<int, string>(); IInfoBubble infoBubble = null; this.graphController.GetInfoBubble(bubbleId, out infoBubble); if (infoBubble != null) { States nodeState; graphController.GetNodeState(infoBubble.OwnerId, out nodeState); bool textualPreviewFlag = nodeState.HasFlag(States.TextualPreview); bool geometryPreviewFlag = nodeState.HasFlag(States.GeometryPreview); if (textualPreviewFlag == false && geometryPreviewFlag == false) { textualPreviewFlag = true; geometryPreviewFlag = true; } if (textualPreviewFlag) menuItems.Add(Configurations.GeometricOutput, "Geometric Preview"); if (geometryPreviewFlag) menuItems.Add(Configurations.TextualOutput, "Textual Preview"); if (nodeState.HasFlag(States.PreviewHidden)) menuItems.Add(Configurations.HidePreview, "Show Preview"); else menuItems.Add(Configurations.HidePreview, "Hide Preview"); } if (this.lastHoveredNodePart != part || this.lastHoveredNodeId != int.MaxValue) { this.graphController.DoCreateRadialMenu(part, bubbleId); lastHoveredNodePart = part; lastHoveredNodeId = uint.MaxValue; selectedMenuId = int.MinValue; } if (menuItems != null && menuItems.Count > 0) { radialMenu = new RadialMenu(bubbleId, worldCoords, Configurations.CircleRadius, menuItems, startAngle, part); this.children.Add(radialMenu.GetRadialVisual()); ScrollToMenuVisual(radialMenu.GetRadialVisual(), radialMenu.GetMenuWidth()); if (Application.Current != null && (Application.Current.MainWindow != null)) { if (Application.Current.MainWindow.IsFocused == false) { Application.Current.MainWindow.Activate(); Application.Current.MainWindow.Topmost = true; Application.Current.MainWindow.Topmost = false; Application.Current.MainWindow.Focus(); } } Keyboard.Focus(this.graphCanvas.graphCanvas); } }
private bool HandleSelectedMenuItem(GraphCommand command) { int menuItemId = (int)command.GetArgument(0); double mouseX = ((double)command.GetArgument(1)); double mouseY = ((double)command.GetArgument(2)); uint nodeId = (uint)command.GetArgument(3); NodePart part = ((NodePart)command.GetArgument(4)); LibraryItem selectedItem = new LibraryItem(); VisualNode node = this.GetVisualNode(nodeId); if (itemsProvider != null) { selectedItem = this.itemsProvider.GetItem(menuItemId); } if (selectedItem == null) //No match in the library { if (part == NodePart.NorthWest) { this.HandleTopLeftSelectedItem(menuItemId, nodeId); } else if (menuItemId == Configurations.ConvertNodeToCode) { HandleConvertSelectionToCode(); return(true); } else if (menuItemId < Configurations.PropertyBase) { // @TODO(Joy): Use switch-case for "menuItemId". ProcessPreviewMenuItems(menuItemId, nodeId); UpdateDirtyNodes(); return(true); } } else //Item found in library { if (selectedItem.Children != null && selectedItem.Children.Count > 0) { selectedItem = selectedItem.Children[0]; } LibraryItem.MemberType itemType = this.GetItemType(menuItemId); DeltaNodes deltaNodes = new DeltaNodes(); VisualNode newNode = null; if (part == NodePart.NorthEast) { if (selectedItem.Type == LibraryItem.MemberType.InstanceProperty) { if (selectedItem.ItemType == NodeType.Function) { newNode = this.CreateMethodNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes); } else { newNode = this.CreatePropertyNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes); } deltaNodes.AppendToAddedNodes(newNode); } else if (selectedItem.Type == LibraryItem.MemberType.InstanceMethod) { newNode = this.CreateMethodNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes); deltaNodes.AppendToAddedNodes(newNode); } if (newNode != null && (null != deltaNodes.AddedNodes) && deltaNodes.AddedNodes.Count > 0) { // @keyu: If we are acessing its member function or // property, there is no reason to mark this node as // dirty. Comment it out to avoid to recreate object. // // deltaNodes.AppendToModifiedNodes(node); Slot inputSlot = this.GetSlot(newNode.GetInputSlot(0)) as Slot; Slot outputSlot = this.GetSlot(node.GetOutputSlot(0)) as Slot; this.undoRedoRecorder.BeginGroup(); this.undoRedoRecorder.RecordRuntimeStatesForUndo(this.graphProperties.RuntimeStates); this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes); this.graphProperties.RuntimeStates.AddVariablesDefinedInNode(newNode, false); this.edgeController.CreateLinkingEdge(outputSlot, inputSlot); this.undoRedoRecorder.RecordNodeCreationForUndo(deltaNodes.AddedNodes); this.undoRedoRecorder.EndGroup(); //After EstablishLinkingConnection() is executed, the nodes in the nodeToModify would already be modified this.SynchronizeToLiveRunner(deltaNodes); } } else if (part == NodePart.North) { if (itemType == LibraryItem.MemberType.Constructor) { deltaNodes.AppendToModifiedNodes(node); deltaNodes.AppendToModifiedNodes(FindAssociatedNodesFromNodes(deltaNodes.ModifiedNodes)); this.undoRedoRecorder.BeginGroup(); this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes); //this.undoRedoRecorder.RecordEdgeModificationForUndo(edgeController.FindEdgeConnectTo(node)); ((FunctionNode)node).ChangeConstructor(selectedItem.QualifiedName, selectedItem.ArgumentTypes, selectedItem.ArgumentNames); this.undoRedoRecorder.EndGroup(); //After ChangeConstructor() is executed, the nodes in the nodeToModify would already be modified this.SynchronizeToLiveRunner(deltaNodes); } else if (itemType == LibraryItem.MemberType.InstanceProperty) { deltaNodes.AppendToRemovedNodes(node); deltaNodes.AppendToModifiedNodes(this.FindAssociatedNodesFromNodes(deltaNodes.RemovedNodes)); newNode = this.CreatePropertyNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes); deltaNodes.AppendToAddedNodes(newNode); this.undoRedoRecorder.BeginGroup(); this.undoRedoRecorder.RecordRuntimeStatesForUndo(this.graphProperties.RuntimeStates); this.undoRedoRecorder.RecordNodeDeletionForUndo(deltaNodes.RemovedNodes); this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes); this.TransferInformationFromMethodToProperty(node, newNode); this.undoRedoRecorder.RecordNodeCreationForUndo(deltaNodes.AddedNodes); this.DeleteNodes(deltaNodes.RemovedNodes); this.undoRedoRecorder.EndGroup(); //After DeleteNodes() is executed, the nodes in the nodeToModify would already be modified this.SynchronizeToLiveRunner(deltaNodes); } else if (itemType == LibraryItem.MemberType.InstanceMethod) { deltaNodes.AppendToModifiedNodes(node); deltaNodes.AppendToModifiedNodes(FindAssociatedNodesFromNodes(deltaNodes.ModifiedNodes)); this.undoRedoRecorder.BeginGroup(); this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes); ((FunctionNode)node).ChangeMethod(selectedItem.QualifiedName, selectedItem.ArgumentTypes); this.undoRedoRecorder.EndGroup(); //After ChangeConstructor() is executed, the nodes in the nodeToModify would already be modified this.SynchronizeToLiveRunner(deltaNodes); } } } this.UpdateDirtyNodes(); edgeController.UpdateEdgeConnectTo(node); return(true); }
internal void HandleKeyUp(object sender, KeyEventArgs e) { if (e.Key == Key.Escape) { if (panning) { EndPan(); return; } if (graphController.CurrentDragState == DragState.CurveDrawing || graphController.CurrentDragState == DragState.EdgeReconnection || graphController.CurrentDragState == DragState.RegionSelection) { graphController.DoEndDrag(MouseButton.Left, 0, NodePart.None, -1, ModifierKeys.None, -1, -1); lastClickedNodeId = uint.MaxValue; // reset lastClickedNodeIndex = int.MaxValue; lastClickedNodePart = NodePart.None; mouseDownPosition = new Point(-1, -1); graphControl.SetCursor(CursorSet.Index.Pointer); } graphController.DoClearSelection(); return; } if (e.Key == Key.Home || e.Key == Key.End || e.Key == Key.Prior || e.Key == Key.PageUp || e.Key == Key.Next || e.Key == Key.PageDown) { e.Handled = true; return; } }
internal void ToggleContextualMenu(NodePart nodePart) { if (this.partDisplayingMenu == nodePart) this.partDisplayingMenu = NodePart.None; else this.partDisplayingMenu = nodePart; this.Dirty = true; this.Compose(); }
private void Node(object obj, string shape = "oval", NodePart propertyCategory = NodePart.All) { NodePart visitedPart = NodePart.None; if (m_visitedNodes.TryGetValue(obj, out visitedPart)) { if ((visitedPart & propertyCategory) != 0) { return; } m_visitedNodes.Remove(obj); } m_visitedNodes.Add(obj, visitedPart | propertyCategory); string propertiesString = ""; var properties = GetProperties(obj); foreach (var property in properties) { var type = GetPropertyType(property); if ((propertyCategory & NodePart.GeneralProperties) != 0 && type.IsPrimitive || type.IsValueType) { propertiesString += String.Format("\\n{0}: {1}", property.Name, property.GetValue(obj)); } var enumerableTypes = GetGenericIEnumerables(type); foreach (var enumerableType in enumerableTypes) { if (enumerableType == typeof(IImageProvider)) { var imageProviders = property.GetValue(obj) as IEnumerable<IImageProvider>; var i = 0; foreach (var imageProvider in imageProviders) { Edge(imageProvider, obj, String.Format("{0}[{1}]", property.Name, i++)); Dot(imageProvider); } } } if ((propertyCategory & NodePart.ImageProviderProperties) != 0 && property.GetValue(obj) is IImageProvider) { Edge(property.GetValue(obj), obj, property.Name); Dot(property.GetValue(obj) as IImageProvider); } } if ((propertyCategory & NodePart.GeneralProperties) != 0) { m_dotString += String.Format("{0} [label=\"{1}{2}\", shape=\"{3}\"]; ", NodeId(obj), obj.GetType().Name, propertiesString, shape); } }