/// <summary> /// Creates the node. /// </summary> /// <param name="groups">The group archetypes.</param> /// <param name="id">The node id.</param> /// <param name="context">The context.</param> /// <param name="groupID">The group identifier.</param> /// <param name="typeID">The type identifier.</param> /// <returns>Created node or null if failed.</returns> public static SurfaceNode CreateNode(List <GroupArchetype> groups, uint id, VisjectSurfaceContext context, ushort groupID, ushort typeID) { // Find archetype for that node for (var i = 0; i < groups.Count; i++) { var groupArchetype = groups[i]; if (groupArchetype.GroupID == groupID && groupArchetype.Archetypes != null) { for (var j = 0; j < groupArchetype.Archetypes.Length; j++) { var nodeArchetype = groupArchetype.Archetypes[j]; if (nodeArchetype.TypeID == typeID) { // Create SurfaceNode node; if (nodeArchetype.Create != null) { node = nodeArchetype.Create(id, context, nodeArchetype, groupArchetype); } else { node = new SurfaceNode(id, context, nodeArchetype, groupArchetype); } return(node); } } } } // Error Editor.LogError($"Failed to create Visject Surface node with id: {groupID}:{typeID}"); return(null); }
/// <summary> /// Creates the node. /// </summary> /// <param name="groups">The group archetypes.</param> /// <param name="id">The node id.</param> /// <param name="context">The context.</param> /// <param name="groupID">The group identifier.</param> /// <param name="typeID">The type identifier.</param> /// <returns>Created node or null if failed.</returns> public static SurfaceNode CreateNode(List <GroupArchetype> groups, uint id, VisjectSurfaceContext context, ushort groupID, ushort typeID) { for (var i = 0; i < groups.Count; i++) { var groupArchetype = groups[i]; if (groupArchetype.GroupID == groupID && groupArchetype.Archetypes != null) { foreach (var nodeArchetype in groupArchetype.Archetypes) { if (nodeArchetype.TypeID == typeID) { SurfaceNode node; if (nodeArchetype.Create != null) { node = nodeArchetype.Create(id, context, nodeArchetype, groupArchetype); } else { node = new SurfaceNode(id, context, nodeArchetype, groupArchetype); } return(node); } } } } return(null); }
/// <inheritdoc /> protected override void HandleDragDropAssets(List <AssetItem> objects, DragDropEventArgs args) { for (int i = 0; i < objects.Count; i++) { var assetItem = objects[i]; SurfaceNode node = null; if (assetItem.IsOfType <Texture>()) { node = Context.SpawnNode(5, 11, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType <CubeTexture>()) { node = Context.SpawnNode(5, 12, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType <ParticleEmitterFunction>()) { node = Context.SpawnNode(14, 300, args.SurfaceLocation, new object[] { assetItem.ID }); } if (node != null) { args.SurfaceLocation.X += node.Width + 10; } } base.HandleDragDropAssets(objects, args); }
/// <summary> /// Creates the node. /// </summary> /// <param name="groups">The group archetypes.</param> /// <param name="id">The node id.</param> /// <param name="surface">The surface.</param> /// <param name="groupID">The group identifier.</param> /// <param name="typeID">The type identifier.</param> /// <returns>Created node or null if failed.</returns> public static SurfaceNode CreateNode(List <GroupArchetype> groups, uint id, VisjectSurface surface, ushort groupID, ushort typeID) { // Find archetype for that node foreach (var groupArchetype in groups) { if (groupArchetype.GroupID == groupID && groupArchetype.Archetypes != null) { foreach (var nodeArchetype in groupArchetype.Archetypes) { if (nodeArchetype.TypeID == typeID) { // Create SurfaceNode node; if (nodeArchetype.Create != null) { node = nodeArchetype.Create(id, surface, nodeArchetype, groupArchetype); } else { node = new SurfaceNode(id, surface, nodeArchetype, groupArchetype); } return(node); } } } } // Error Editor.LogError($"Failed to create Visject Surface node with id: {groupID}:{typeID}"); return(null); }
/// <inheritdoc /> protected override void HandleDragDropAssets(List <AssetItem> objects, DragDropEventArgs args) { for (int i = 0; i < objects.Count; i++) { var item = objects[i]; SurfaceNode node = null; switch (item.ItemDomain) { case ContentDomain.Texture: { node = Context.SpawnNode(5, 11, args.SurfaceLocation, new object[] { item.ID }); break; } case ContentDomain.CubeTexture: { node = Context.SpawnNode(5, 12, args.SurfaceLocation, new object[] { item.ID }); break; } } if (node != null) { args.SurfaceLocation.X += node.Width + 10; } } base.HandleDragDropAssets(objects, args); }
/// <summary> /// Initializes a new instance of the <see cref="SurfaceNodeElementControl"/> class. /// </summary> /// <param name="parentNode">The parent node.</param> /// <param name="archetype">The element archetype.</param> /// <param name="location">The location.</param> /// <param name="size">The size.</param> /// <param name="canFocus">if set to <c>true</c> can focus this control.</param> protected SurfaceNodeElementControl(SurfaceNode parentNode, NodeElementArchetype archetype, Vector2 location, Vector2 size, bool canFocus) : base(location, size) { CanFocus = canFocus; ParentNode = parentNode; Archetype = archetype; }
/// <summary> /// Initializes a new instance of the <see cref="SurfaceNodeElementControl"/> class. /// </summary> /// <param name="parentNode">The parent node.</param> /// <param name="archetype">The element archetype.</param> /// <param name="location">The location.</param> /// <param name="size">The size.</param> /// <param name="autoFocus">if set to <c>true</c> can focus this control.</param> protected SurfaceNodeElementControl(SurfaceNode parentNode, NodeElementArchetype archetype, Vector2 location, Vector2 size, bool autoFocus) : base(location, size) { AutoFocus = autoFocus; TooltipText = archetype.Tooltip; ParentNode = parentNode; Archetype = archetype; }
/// <inheritdoc /> protected override void HandleDragDropAssets(List <AssetItem> objects, DragDropEventArgs args) { for (int i = 0; i < objects.Count; i++) { var assetItem = objects[i]; SurfaceNode node = null; if (assetItem.IsOfType <Texture>()) { // Check if it's a normal map bool isNormalMap = false; var obj = FlaxEngine.Content.LoadAsync <Texture>(assetItem.ID); if (obj) { Thread.Sleep(50); if (!obj.WaitForLoaded()) { isNormalMap = obj.IsNormalMap; } } node = Context.SpawnNode(5, (ushort)(isNormalMap ? 4 : 1), args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType <CubeTexture>()) { node = Context.SpawnNode(5, 3, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType <MaterialBase>()) { node = Context.SpawnNode(8, 1, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType <MaterialFunction>()) { node = Context.SpawnNode(1, 24, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType <GameplayGlobals>()) { node = Context.SpawnNode(7, 16, args.SurfaceLocation, new object[] { assetItem.ID, string.Empty, }); } if (node != null) { args.SurfaceLocation.X += node.Width + 10; } } base.HandleDragDropAssets(objects, args); }
/// <inheritdoc /> public override void OnNodeBreakpointEdited(SurfaceNode node) { base.OnNodeBreakpointEdited(node); if (node.Breakpoint.Set && node.Breakpoint.Enabled) { Breakpoints.Add(node); } else { Breakpoints.Remove(node); } }
/// <inheritdoc /> protected override void HandleDragDropAssets(List <AssetItem> objects, DragDropEventArgs args) { for (int i = 0; i < objects.Count; i++) { var item = objects[i]; SurfaceNode node = null; switch (item.ItemDomain) { case ContentDomain.Texture: { // Check if it's a normal map bool isNormalMap = false; var obj = FlaxEngine.Content.LoadAsync <Texture>(item.ID); if (obj) { Thread.Sleep(50); if (!obj.WaitForLoaded()) { isNormalMap = obj.IsNormalMap; } } node = SpawnNode(5, (ushort)(isNormalMap ? 4 : 1), args.SurfaceLocation, new object[] { item.ID }); break; } case ContentDomain.CubeTexture: { node = SpawnNode(5, 3, args.SurfaceLocation, new object[] { item.ID }); break; } case ContentDomain.Material: { node = SpawnNode(8, 1, args.SurfaceLocation, new object[] { item.ID }); break; } } if (node != null) { args.SurfaceLocation.X += node.Width + 10; } } base.HandleDragDropAssets(objects, args); }
/// <summary> /// Finds the node with the given ID. /// </summary> /// <param name="id">The identifier.</param> /// <returns>Found node or null if cannot.</returns> public SurfaceNode FindNode(uint id) { SurfaceNode result = null; for (int i = 0; i < Nodes.Count; i++) { var node = Nodes[i]; if (node.ID == id) { result = node; break; } } return(result); }
/// <summary> /// Creates the node. /// </summary> /// <param name="id">The node id.</param> /// <param name="context">The context.</param> /// <param name="groupArchetype">The group archetype.</param> /// <param name="nodeArchetype">The node archetype.</param> /// <returns>Created node or null if failed.</returns> public static SurfaceNode CreateNode(uint id, VisjectSurfaceContext context, GroupArchetype groupArchetype, NodeArchetype nodeArchetype) { Assert.IsTrue(groupArchetype.Archetypes.Contains(nodeArchetype)); SurfaceNode node; if (nodeArchetype.Create != null) { node = nodeArchetype.Create(id, context, nodeArchetype, groupArchetype); } else { node = new SurfaceNode(id, context, nodeArchetype, groupArchetype); } return(node); }
/// <summary> /// Finds the node of the given type. /// </summary> /// <param name="groupId">The group identifier.</param> /// <param name="typeId">The type identifier.</param> /// <returns>Found node or null if cannot.</returns> public SurfaceNode FindNode(ushort groupId, ushort typeId) { SurfaceNode result = null; uint type = ((uint)groupId << 16) | typeId; for (int i = 0; i < Nodes.Count; i++) { var node = Nodes[i]; if (node.Type == type) { result = node; break; } } return(result); }
/// <inheritdoc /> protected override void HandleDragDropAssets(List <AssetItem> objects, DragDropEventArgs args) { for (int i = 0; i < objects.Count; i++) { var assetItem = objects[i]; SurfaceNode node = null; if (assetItem.IsOfType <FlaxEngine.Animation>()) { node = Context.SpawnNode(9, 2, args.SurfaceLocation, new object[] { assetItem.ID, 1.0f, true, 0.0f, }); } else if (assetItem.IsOfType <SkeletonMask>()) { node = Context.SpawnNode(9, 11, args.SurfaceLocation, new object[] { 0.0f, assetItem.ID, }); } else if (assetItem.IsOfType <AnimationGraphFunction>()) { node = Context.SpawnNode(9, 24, args.SurfaceLocation, new object[] { assetItem.ID, }); } else if (assetItem.IsOfType <GameplayGlobals>()) { node = Context.SpawnNode(7, 16, args.SurfaceLocation, new object[] { assetItem.ID, string.Empty, }); } if (node != null) { args.SurfaceLocation.X += node.Width + 10; } } base.HandleDragDropAssets(objects, args); }
/// <summary> /// Shows the secondary context menu for the given node. /// </summary> /// <param name="node">The node.</param> /// <param name="location">The location in the Surface Space.</param> public void ShowSecondaryCM(SurfaceNode node, Vector2 location) { // Select that node Select(node); // Update context menu buttons _cmDeleteNodeButton.Enabled = (node.Archetype.Flags & NodeFlags.NoRemove) == 0; // var boxUnderMouse = GetChildAtRecursive(location) as Box; _cmRemoveBoxConnectionsButton.Enabled = boxUnderMouse != null && boxUnderMouse.HasAnyConnection; _cmRemoveBoxConnectionsButton.Tag = boxUnderMouse; // Show secondary context menu _cmStartPos = location; _cmSecondaryMenu.Tag = node; _cmSecondaryMenu.Show(this, location); }
/// <summary> /// Called when node gets loaded and should be added to the surface. Creates node elements from the archetype. /// </summary> /// <param name="node">The node.</param> public virtual void OnNodeLoaded(SurfaceNode node) { // Create child elements of the node based on it's archetype int elementsCount = node.Archetype.Elements?.Length ?? 0; for (int i = 0; i < elementsCount; i++) { // ReSharper disable once PossibleNullReferenceException node.AddElement(node.Archetype.Elements[i]); } // Load metadata var meta = node.Meta.GetEntry(11); if (meta.Data != null) { var meta11 = Utils.ByteArrayToStructure <VisjectSurface.Meta11>(meta.Data); node.Location = meta11.Position; //node.IsSelected = meta11.Selected; } }
/// <inheritdoc /> protected override void HandleDragDropAssets(List <AssetItem> objects, DragDropEventArgs args) { for (int i = 0; i < objects.Count; i++) { var item = objects[i]; SurfaceNode node = null; switch (item.ItemDomain) { case ContentDomain.Animation: { node = SpawnNode(9, 2, args.SurfaceLocation, new object[] { item.ID, 1.0f, true, 0.0f, }); break; } case ContentDomain.SkeletonMask: { node = SpawnNode(9, 11, args.SurfaceLocation, new object[] { 0.0f, item.ID, }); break; } } if (node != null) { args.SurfaceLocation.X += node.Width + 10; } } base.HandleDragDropAssets(objects, args); }
/// <inheritdoc /> public override DragDropEffect OnDragDrop(ref Vector2 location, DragData data) { var result = base.OnDragDrop(ref location, data); if (result != DragDropEffect.None) { return(result); } if (_dragOverItems.HasValidDrag) { result = _dragOverItems.Effect; var surfaceLocation = _surface.PointFromParent(location); switch (Type) { case SurfaceType.Material: { for (int i = 0; i < _dragOverItems.Objects.Count; i++) { var item = _dragOverItems.Objects[i]; SurfaceNode node = null; switch (item.ItemDomain) { case ContentDomain.Texture: { // Check if it's a normal map bool isNormalMap = false; var obj = FlaxEngine.Content.LoadAsync <Texture>(item.ID); if (obj) { Thread.Sleep(50); if (!obj.WaitForLoaded()) { isNormalMap = obj.IsNormalMap; } } node = SpawnNode(5, (ushort)(isNormalMap ? 4 : 1), surfaceLocation, new object[] { item.ID }); break; } case ContentDomain.CubeTexture: { node = SpawnNode(5, 3, surfaceLocation, new object[] { item.ID }); break; } case ContentDomain.Material: { node = SpawnNode(8, 1, surfaceLocation, new object[] { item.ID }); break; } } if (node != null) { surfaceLocation.X += node.Width + 10; } } break; } case SurfaceType.AnimationGraph: { for (int i = 0; i < _dragOverItems.Objects.Count; i++) { var item = _dragOverItems.Objects[i]; SurfaceNode node = null; switch (item.ItemDomain) { case ContentDomain.Animation: { node = SpawnNode(9, 2, surfaceLocation, new object[] { item.ID, 1.0f, true, 0.0f, }); break; } case ContentDomain.SkeletonMask: { node = SpawnNode(9, 11, surfaceLocation, new object[] { 0.0f, item.ID, }); break; } } if (node != null) { surfaceLocation.X += node.Width + 10; } } break; } } _dragOverItems.OnDragDrop(); } else if (_dragOverParameter.HasValidDrag) { result = _dragOverParameter.Effect; var surfaceLocation = _surface.PointFromParent(location); var parameter = GetParameter(_dragOverParameter.Parameter); if (parameter == null) { throw new InvalidDataException(); } var node = SpawnNode(6, 1, surfaceLocation, new object[] { parameter.ID }); _dragOverParameter.OnDragDrop(); } return(result); }
/// <inheritdoc /> public override bool OnMouseUp(Vector2 location, MouseButton buttons) { // Cache mouse location _mousePos = location; // Check if any node is under the mouse SurfaceNode nodeAtMouse = GetNodeUnderMouse(); if (nodeAtMouse == null) { // Check if no move has been made at all if (_mouseMoveAmount < 5.0f) { ClearSelection(); } } // Cache flags and state if (_leftMouseDown && buttons == MouseButton.Left) { _leftMouseDown = false; EndMouseCapture(); Cursor = CursorType.Default; if (!_isMovingSelection && _startBox == null) { UpdateSelectionRectangle(); } } if (_rightMouseDown && buttons == MouseButton.Right) { _rightMouseDown = false; EndMouseCapture(); Cursor = CursorType.Default; // Check if no move has been made at all if (_mouseMoveAmount < 3.0f) { // Check if any node is under the mouse _cmStartPos = location; if (nodeAtMouse != null) { if (!HasSelection) { Select(nodeAtMouse); } // Show secondary context menu ShowSecondaryCM(_cmStartPos); } else { // Show primary context menu ShowPrimaryMenu(_cmStartPos); } } _mouseMoveAmount = 0; } // Base if (base.OnMouseUp(location, buttons)) { return(true); } if (buttons == MouseButton.Left) { ConnectingEnd(null); EndMouseCapture(); } return(true); }
/// <inheritdoc /> public override bool OnMouseDown(Vector2 location, MouseButton buttons) { // Check if user is connecting boxes if (_startBox != null) { return(true); } // Cache data _isMovingSelection = false; _mousePos = location; if (buttons == MouseButton.Left) { _leftMouseDown = true; _leftMouseDownPos = location; } if (buttons == MouseButton.Right) { _rightMouseDown = true; _rightMouseDownPos = location; } // Check if any node is under the mouse SurfaceNode nodeAtMouse = GetNodeUnderMouse(); Vector2 cLocation = _surface.PointFromParent(location); if (nodeAtMouse != null) { // Check if mouse is over header and user is pressing mouse left button if (_leftMouseDown && nodeAtMouse.HitsHeader(ref cLocation)) { // Check if user is pressing control if (Root.GetKey(Keys.Control)) { // Add to selection AddToSelection(nodeAtMouse); } // Check if node isn't selected else if (!nodeAtMouse.IsSelected) { // Select node Select(nodeAtMouse); } // Start moving selected nodes StartMouseCapture(); _isMovingSelection = true; _movingSelectionViewPos = _surface.Location; Focus(); return(true); } } else { // Cache flags and state if (_leftMouseDown) { // Start selecting StartMouseCapture(); ClearSelection(); Focus(); return(true); } if (_rightMouseDown) { // Start navigating StartMouseCapture(); Focus(); return(true); } } // Base if (base.OnMouseDown(location, buttons)) { // Clear flags to disable handling mouse events by itself (children should do) _leftMouseDown = _rightMouseDown = false; return(true); } Focus(); return(true); }
/// <summary> /// Called when node gets loaded and should be added to the surface. Creates node elements from the archetype. /// </summary> /// <param name="node">The node.</param> public virtual void OnNodeLoaded(SurfaceNode node) { // Create child elements of the node based on it's archetype int elementsCount = node.Archetype.Elements?.Length ?? 0; for (int i = 0; i < elementsCount; i++) { // ReSharper disable once PossibleNullReferenceException var arch = node.Archetype.Elements[i]; ISurfaceNodeElement element = null; switch (arch.Type) { case NodeElementType.Input: element = new InputBox(node, arch); break; case NodeElementType.Output: element = new OutputBox(node, arch); break; case NodeElementType.BoolValue: element = new BoolValue(node, arch); break; case NodeElementType.FloatValue: element = new FloatValue(node, arch); break; case NodeElementType.IntegerValue: element = new IntegerValue(node, arch); break; case NodeElementType.ColorValue: element = new ColorValue(node, arch); break; case NodeElementType.ComboBox: element = new ComboBoxElement(node, arch); break; case NodeElementType.Asset: element = new AssetSelect(node, arch); break; case NodeElementType.Text: element = new TextView(node, arch); break; case NodeElementType.TextBox: element = new TextBoxView(node, arch); break; case NodeElementType.SkeletonNodeSelect: element = new SkeletonNodeSelectElement(node, arch); break; } if (element != null) { // Link element node.AddElement(element); } } // Load metadata var meta = node.Meta.GetEntry(11); if (meta.Data != null) { var meta11 = Utils.ByteArrayToStructure <VisjectSurface.Meta11>(meta.Data); node.Location = meta11.Position; //node.IsSelected = meta11.Selected; } }
/// <summary> /// Initializes a new instance of the <see cref="SurfaceNodeElementControl"/> class. /// </summary> /// <param name="parentNode">The parent node.</param> /// <param name="archetype">The element archetype.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="canFocus">if set to <c>true</c> can focus this control.</param> protected SurfaceNodeElementControl(SurfaceNode parentNode, NodeElementArchetype archetype, float width, float height, bool canFocus) : base(archetype.ActualPositionX, archetype.ActualPositionY, width, height) { ParentNode = parentNode; Archetype = archetype; }