// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; using System.Linq; using FlaxEditor.Content; using FlaxEditor.Scripting; using FlaxEditor.Surface.Archetypes; using FlaxEngine; namespace FlaxEditor.Surface { /// /// The Visject Surface implementation for the particle emitter graph editor. /// /// [HideInEditor] public class ParticleEmitterSurface : VisjectSurface { internal FlaxEditor.Surface.Archetypes.Particles.ParticleEmitterNode _rootNode; /// /// Gets the root node of the emitter graph. /// public FlaxEditor.Surface.Archetypes.Particles.ParticleEmitterNode RootNode => _rootNode; /// public ParticleEmitterSurface(IVisjectSurfaceOwner owner, Action onSave, FlaxEditor.Undo undo) : base(owner, onSave, undo) { } /// public override string GetTypeName(ScriptType type) { if (type.Type == typeof(FlaxEngine.Object)) return "Texture"; return base.GetTypeName(type); } /// /// Arranges the particle modules nodes. /// public void ArrangeModulesNodes() { if (IsLayoutLocked) return; if (_rootNode == null) throw new InvalidOperationException("Missing root node."); IsLayoutLocked = true; var modulesGroups = Nodes.OfType().GroupBy(x => x.ModuleType).ToList(); modulesGroups.Sort((a, b) => a.Key.CompareTo(b.Key)); var width = _rootNode.Width; var rootPos = _rootNode.Location; var pos = rootPos; pos.Y += Constants.NodeHeaderSize + 1.0f + 7 * Constants.LayoutOffsetY + 6.0f + 4.0f; for (int i = 0; i < _rootNode.Headers.Length; i++) { var header = _rootNode.Headers[i]; var modulesStart = pos - rootPos; var modules = modulesGroups.FirstOrDefault(x => x.Key == header.ModuleType); pos.Y += Constants.NodeHeaderSize + 2.0f; if (modules != null) { foreach (var module in modules) { var height = module.Height; module.Bounds = new Rectangle(pos.X, pos.Y, width, height); pos.Y += height; } } pos.Y += 20.0f; var modulesEnd = pos - rootPos; header.Bounds = new Rectangle(modulesStart.X, modulesStart.Y, width, modulesEnd.Y - modulesStart.Y); } _rootNode.Height = pos.Y - _rootNode.Location.Y; IsLayoutLocked = false; PerformLayout(); } /// public override bool CanUseNodeType(NodeArchetype nodeArchetype) { return (nodeArchetype.Flags & NodeFlags.ParticleEmitterGraph) != 0 && base.CanUseNodeType(nodeArchetype); } /// protected override NodeArchetype GetParameterGetterNodeArchetype(out ushort groupId) { groupId = 6; return Archetypes.Parameters.Nodes[1]; } /// protected override bool ValidateDragItem(AssetItem assetItem) { if (assetItem.IsOfType()) return true; if (assetItem.IsOfType()) return true; if (assetItem.IsOfType()) return true; if (assetItem.IsOfType()) return true; return base.ValidateDragItem(assetItem); } /// protected override void HandleDragDropAssets(List objects, DragDropEventArgs args) { for (int i = 0; i < objects.Count; i++) { var assetItem = objects[i]; SurfaceNode node = null; if (assetItem.IsOfType()) { node = Context.SpawnNode(5, 11, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType()) { node = Context.SpawnNode(5, 12, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType()) { node = Context.SpawnNode(14, 300, args.SurfaceLocation, new object[] { assetItem.ID }); } else if (assetItem.IsOfType()) { 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); } } }