/// <summary>
        /// Adds the group archetype to add to the menu.
        /// </summary>
        /// <param name="groupArchetype">The group.</param>
        public void AddGroup(GroupArchetype groupArchetype)
        {
            // Get valid nodes
            var nodes = new List <NodeArchetype>();

            foreach (var nodeArchetype in groupArchetype.Archetypes)
            {
                if ((nodeArchetype.Flags & NodeFlags.NoSpawnViaGUI) != 0)
                {
                    continue;
                }

                nodes.Add(nodeArchetype);
            }

            // Check if can create group for them
            if (nodes.Count > 0)
            {
                var group = new VisjectCMGroup(this, groupArchetype);
                group.HeaderText = groupArchetype.Name;
                group.Close(false);
                for (int i = 0; i < nodes.Count; i++)
                {
                    var item = new VisjectCMItem(group, groupArchetype, nodes[i]);
                    item.Parent = group;
                }
                group.SortChildren();
                group.Parent       = _groupsPanel;
                group.DefaultIndex = _groups.Count;
                _groups.Add(group);
            }
        }
        private void OnSearchFilterChanged()
        {
            // Skip events during setup or init stuff
            if (IsLayoutLocked)
            {
                return;
            }

            // Update groups
            for (int i = 0; i < _groups.Count; i++)
            {
                _groups[i].UpdateFilter(_searchBox.Text);
                _groups[i].UpdateItemSort(_selectedBox);
            }

            SortGroups();

            // If no item is selected (or it's not visible anymore), select the top one
            if (SelectedItem == null || !SelectedItem.VisibleInHierarchy)
            {
                SelectedItem = _groups.Find(g => g.Visible)?.Children.Find(c => c.Visible && c is VisjectCMItem) as VisjectCMItem;
            }
            if (SelectedItem != null)
            {
                _panel1.ScrollViewTo(SelectedItem);
            }
            PerformLayout();
            _searchBox.Focus();
        }
Example #3
0
        /// <summary>
        /// Adds the group archetype to add to the menu.
        /// </summary>
        /// <param name="groupArchetype">The group.</param>
        public void AddGroup(GroupArchetype groupArchetype)
        {
            // Check if can create group for them to be spawned via GUI
            if (groupArchetype.Archetypes.Any(x => (x.Flags & NodeFlags.NoSpawnViaGUI) == 0))
            {
                Profiler.BeginEvent("VisjectCM.AddGroup");

                var group = new VisjectCMGroup(this, groupArchetype);
                group.HeaderText = groupArchetype.Name;
                group.Close(false);
                foreach (var nodeArchetype in groupArchetype.Archetypes)
                {
                    var item = new VisjectCMItem(group, groupArchetype, nodeArchetype);
                    item.Parent = group;
                }
                group.SortChildren();
                group.Parent = _groupsPanel;
                _groups.Add(group);

                if (!IsLayoutLocked)
                {
                    group.UnlockChildrenRecursive();
                    SortGroups();
                    group.PerformLayout();
                    if (_searchBox.TextLength != 0)
                    {
                        OnSearchFilterChanged();
                    }
                }

                Profiler.EndEvent();
            }
        }
Example #4
0
        /// <summary>
        /// Adds the group archetypes to add to the menu.
        /// </summary>
        /// <param name="groupArchetypes">The groups.</param>
        public void AddGroups(IEnumerable <GroupArchetype> groupArchetypes)
        {
            // Check if can create group for them to be spawned via GUI
            if (groupArchetypes.Any(g => g.Archetypes.Any(x => (x.Flags & NodeFlags.NoSpawnViaGUI) == 0)))
            {
                Profiler.BeginEvent("VisjectCM.AddGroups");
                var isLayoutLocked = IsLayoutLocked;
                LockChildrenRecursive();

                Profiler.BeginEvent("Create Groups");
                var groups = new List <VisjectCMGroup>();
                foreach (var groupArchetype in groupArchetypes)
                {
                    var group = new VisjectCMGroup(this, groupArchetype)
                    {
                        HeaderText = groupArchetype.Name
                    };

                    group.Close(false);

                    foreach (var nodeArchetype in groupArchetype.Archetypes)
                    {
                        var item = new VisjectCMItem(group, groupArchetype, nodeArchetype)
                        {
                            Parent = group
                        };
                    }
                    group.SortChildren();
                    group.Parent = _groupsPanel;
                    _groups.Add(group);

                    groups.Add(group);
                }
                Profiler.EndEvent();

                if (!isLayoutLocked)
                {
                    SortGroups();
                    Profiler.BeginEvent("Perform Layout");
                    UnlockChildrenRecursive();
                    foreach (var group in groups)
                    {
                        group.PerformLayout();
                    }
                    PerformLayout();
                    Profiler.EndEvent();

                    if (_searchBox.TextLength != 0)
                    {
                        OnSearchFilterChanged();
                    }
                }

                Profiler.EndEvent();
            }
        }
Example #5
0
        /// <summary>
        /// Resets the view.
        /// </summary>
        public void ResetView()
        {
            bool wasLayoutLocked = IsLayoutLocked;

            IsLayoutLocked = true;

            for (int i = 0; i < _groups.Count; i++)
            {
                _groups[i].ResetView();
            }

            _searchBox.Clear();
            SelectedItem   = null;
            IsLayoutLocked = wasLayoutLocked;
            PerformLayout();
        }
Example #6
0
        /// <summary>
        /// Resets the view.
        /// </summary>
        public void ResetView()
        {
            Profiler.BeginEvent("VisjectCM.ResetView");

            LockChildrenRecursive();
            _searchBox.Clear();
            SelectedItem = null;
            for (int i = 0; i < _groups.Count; i++)
            {
                _groups[i].ResetView();
            }
            UnlockChildrenRecursive();

            SortGroups();
            PerformLayout();

            Profiler.EndEvent();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="VisjectCM"/> class.
        /// </summary>
        /// <param name="info">The initialization info data.</param>
        public VisjectCM(InitInfo info)
        {
            if (info.Groups == null)
            {
                throw new ArgumentNullException(nameof(info.Groups));
            }
            if (info.CanSpawnNode == null)
            {
                throw new ArgumentNullException(nameof(info.CanSpawnNode));
            }
            _parametersGetter          = info.ParametersGetter;
            _parameterGetNodeArchetype = info.ParameterGetNodeArchetype ?? Archetypes.Parameters.Nodes[0];

            // Context menu dimensions
            Size = new Vector2(320, 220);

            // Search box
            _searchBox = new TextBox(false, 1, 1)
            {
                Width         = Width - 3,
                WatermarkText = "Search...",
                Parent        = this
            };
            _searchBox.TextChanged += OnSearchFilterChanged;

            // Create first panel (for scrollbar)
            var panel1 = new Panel(ScrollBars.Vertical)
            {
                Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2),
                Parent = this
            };

            _panel1 = panel1;

            // Create second panel (for groups arrangement)
            var panel2 = new VerticalPanel
            {
                AnchorPreset = AnchorPresets.HorizontalStretchTop,
                IsScrollable = true,
                Parent       = panel1
            };

            _groupsPanel = panel2;

            // Init groups
            int index = 0;
            var nodes = new List <NodeArchetype>();

            foreach (var groupArchetype in info.Groups)
            {
                // Get valid nodes
                nodes.Clear();
                foreach (var nodeArchetype in groupArchetype.Archetypes)
                {
                    if (info.CanSpawnNode(nodeArchetype))
                    {
                        nodes.Add(nodeArchetype);
                    }
                }

                // Check if can create group for them
                if (nodes.Count > 0)
                {
                    var group = new VisjectCMGroup(this, groupArchetype);
                    group.HeaderText = groupArchetype.Name;
                    group.Close(false);
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        var item = new VisjectCMItem(group, groupArchetype, nodes[i]);
                        item.Parent = group;
                    }
                    group.SortChildren();
                    group.Parent       = panel2;
                    group.DefaultIndex = index++;
                    _groups.Add(group);
                }
            }

            // Add custom nodes (special handling)
            if (info.CustomNodesGroup?.Archetypes != null)
            {
                for (int i = 0; i < info.CustomNodesGroup.Archetypes.Length; i++)
                {
                    var nodeArchetype = info.CustomNodesGroup.Archetypes[i];

                    if ((nodeArchetype.Flags & NodeFlags.NoSpawnViaGUI) != 0)
                    {
                        continue;
                    }

                    var groupName = Archetypes.Custom.GetNodeGroup(nodeArchetype);

                    // Find group to reuse
                    VisjectCMGroup group = null;
                    for (int j = 0; j < _groups.Count; j++)
                    {
                        if (string.Equals(_groups[j].Archetype.Name, groupName, StringComparison.OrdinalIgnoreCase))
                        {
                            group = _groups[j];
                            break;
                        }
                    }

                    // Create new group if name is unique
                    if (group == null)
                    {
                        group            = new VisjectCMGroup(this, info.CustomNodesGroup);
                        group.HeaderText = groupName;
                        group.Close(false);
                        group.Parent       = _groupsPanel;
                        group.DefaultIndex = _groups.Count;
                        _groups.Add(group);
                    }

                    // Add new item
                    var item = new VisjectCMItem(group, info.CustomNodesGroup, nodeArchetype);
                    item.Parent = group;

                    // Order items
                    group.SortChildren();
                }
            }
        }
        /// <inheritdoc />
        public override bool OnKeyDown(KeyboardKeys key)
        {
            if (key == KeyboardKeys.Escape)
            {
                Hide();
                return(true);
            }
            else if (key == KeyboardKeys.Return)
            {
                if (SelectedItem != null)
                {
                    OnClickItem(SelectedItem);
                }
                else
                {
                    Hide();
                }
                return(true);
            }
            else if (key == KeyboardKeys.ArrowUp)
            {
                if (SelectedItem == null)
                {
                    return(true);
                }

                var previousSelectedItem = GetPreviousSiblings <VisjectCMItem>(SelectedItem).FirstOrDefault(c => c.Visible) ??
                                           (GetPreviousSiblings <VisjectCMGroup>(SelectedItem.Group).FirstOrDefault(c => c.Visible)?.Children
                                            .FindLast(c => c.Visible && c is VisjectCMItem) as VisjectCMItem);

                if (previousSelectedItem != null)
                {
                    SelectedItem = previousSelectedItem;

                    // Scroll into view (without smoothing)
                    _panel1.VScrollBar.SmoothingScale = 0;
                    _panel1.ScrollViewTo(SelectedItem);
                    _panel1.VScrollBar.SmoothingScale = 1;
                }
                return(true);
            }
            else if (key == KeyboardKeys.ArrowDown)
            {
                if (SelectedItem == null)
                {
                    return(true);
                }

                var nextSelectedItem = GetNextSiblings <VisjectCMItem>(SelectedItem).FirstOrDefault(c => c.Visible) ??
                                       (GetNextSiblings <VisjectCMGroup>(SelectedItem.Group).FirstOrDefault(c => c.Visible)?.Children
                                        .OfType <VisjectCMItem>().FirstOrDefault(c => c.Visible));

                if (nextSelectedItem != null)
                {
                    SelectedItem = nextSelectedItem;
                    _panel1.ScrollViewTo(SelectedItem);
                }
                return(true);
            }

            if (_waitingForInput)
            {
                _waitingForInput = false;
                _searchBox.Focus();
                return(_searchBox.OnKeyDown(key));
            }

            return(base.OnKeyDown(key));
        }
        /// <summary>
        /// Updates the surface parameters group.
        /// </summary>
        private void UpdateSurfaceParametersGroup()
        {
            // Remove the old one
            if (_surfaceParametersGroup != null)
            {
                _groups.Remove(_surfaceParametersGroup);
                _surfaceParametersGroup.Dispose();
                _surfaceParametersGroup = null;
            }

            // Check if surface has any parameters
            var parameters = _parametersGetter != null?_parametersGetter() : null;

            int count = parameters?.Count(x => x.IsPublic) ?? 0;

            if (count > 0)
            {
                // TODO: cache the allocated memory to reduce dynamic allocations
                var archetypes     = new NodeArchetype[count];
                int archetypeIndex = 0;

                // ReSharper disable once PossibleNullReferenceException
                for (int i = 0; i < parameters.Count; i++)
                {
                    if (!parameters[i].IsPublic)
                    {
                        continue;
                    }

                    var node = (NodeArchetype)_parameterGetNodeArchetype.Clone();
                    node.Title                   = "Get " + parameters[i].Name;
                    node.DefaultValues[0]        = parameters[i].ID;
                    archetypes[archetypeIndex++] = node;
                }

                var groupArchetype = new GroupArchetype
                {
                    GroupID    = 6,
                    Name       = "Surface Parameters",
                    Color      = new Color(52, 73, 94),
                    Archetypes = archetypes
                };

                var group = new VisjectCMGroup(this, groupArchetype);
                group.HeaderText = groupArchetype.Name;
                group.Close(false);
                archetypeIndex = 0;
                for (int i = 0; i < parameters.Count; i++)
                {
                    if (!parameters[i].IsPublic)
                    {
                        continue;
                    }

                    var item = new VisjectCMItem(group, groupArchetype, archetypes[archetypeIndex++]);
                    item.Parent = group;
                }
                group.SortChildren();
                group.UnlockChildrenRecursive();
                group.Parent = _groupsPanel;
                _groups.Add(group);
                _surfaceParametersGroup = group;
            }
        }
Example #10
0
 /// <summary>
 /// Called when user clicks on an item.
 /// </summary>
 /// <param name="item">The item.</param>
 public void OnClickItem(VisjectCMItem item)
 {
     Hide();
     OnItemClicked?.Invoke(item, _selectedBox);
 }
Example #11
0
        /// <summary>
        /// Updates the surface parameters group.
        /// </summary>
        private void UpdateSurfaceParametersGroup()
        {
            // Remove the old one
            if (_surfaceParametersGroup != null)
            {
                _groups.Remove(_surfaceParametersGroup);
                _surfaceParametersGroup.Dispose();
                _surfaceParametersGroup = null;
            }

            // Check if surface has any parameters
            var parameters = _parametersGetter != null?_parametersGetter() : null;

            int count = parameters?.Count(x => x.IsPublic) ?? 0;

            if (count > 0)
            {
                // TODO: cache the allocated memory to reduce dynamic allocations
                var archetypes     = new NodeArchetype[count];
                int archetypeIndex = 0;

                // ReSharper disable once PossibleNullReferenceException
                for (int i = 0; i < parameters.Count; i++)
                {
                    if (!parameters[i].IsPublic)
                    {
                        continue;
                    }

                    archetypes[archetypeIndex++] = new NodeArchetype
                    {
                        TypeID        = 1,
                        Create        = Archetypes.Parameters.CreateGetNode,
                        Title         = "Get " + parameters[i].Name,
                        Description   = "Parameter value getter",
                        Size          = new Vector2(140, 60),
                        DefaultValues = new object[]
                        {
                            parameters[i].ID
                        },
                        Elements = new[]
                        {
                            NodeElementArchetype.Factory.ComboBox(2, 0, 116)
                        }
                    };
                }

                var groupArchetype = new GroupArchetype
                {
                    GroupID    = 6,
                    Name       = "Surface Parameters",
                    Color      = new Color(52, 73, 94),
                    Archetypes = archetypes
                };

                var group = new VisjectCMGroup(this, groupArchetype);
                group.HeaderText = groupArchetype.Name;
                group.Close(false);
                archetypeIndex = 0;
                for (int i = 0; i < parameters.Count; i++)
                {
                    if (!parameters[i].IsPublic)
                    {
                        continue;
                    }

                    var item = new VisjectCMItem(group, groupArchetype, archetypes[archetypeIndex++]);
                    item.Parent = group;
                }
                group.SortChildren();
                group.UnlockChildrenRecursive();
                group.Parent = _groupsPanel;
                _groups.Add(group);
                _surfaceParametersGroup = group;
            }
        }
Example #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VisjectCM"/> class.
        /// </summary>
        /// <param name="groups">The group archetypes. Cannot be null.</param>
        /// <param name="canSpawnNodeType">The surface node type validation helper. Cannot be null.</param>
        /// <param name="parametersGetter">The surface parameters getter callback. Can be null.</param>
        public VisjectCM(List <GroupArchetype> groups, Func <NodeArchetype, bool> canSpawnNodeType, Func <List <SurfaceParameter> > parametersGetter = null)
        {
            if (groups == null)
            {
                throw new ArgumentNullException(nameof(groups));
            }
            if (canSpawnNodeType == null)
            {
                throw new ArgumentNullException(nameof(canSpawnNodeType));
            }
            _parametersGetter = parametersGetter;

            // Context menu dimensions
            Size = new Vector2(320, 220);

            // Search box
            _searchBox = new TextBox(false, 1, 1)
            {
                Width         = Width - 3,
                WatermarkText = "Search...",
                Parent        = this
            };
            _searchBox.TextChanged += OnSearchFilterChanged;

            // Create first panel (for scrollbar)
            var panel1 = new Panel(ScrollBars.Vertical)
            {
                Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2),
                Parent = this
            };

            _panel1 = panel1;

            // Create second panel (for groups arrangement)
            var panel2 = new VerticalPanel
            {
                DockStyle    = DockStyle.Top,
                IsScrollable = true,
                Parent       = panel1
            };

            _groupsPanel = panel2;

            // Init groups
            int index = 0;
            var nodes = new List <NodeArchetype>();

            foreach (var groupArchetype in groups)
            {
                // Get valid nodes
                nodes.Clear();
                foreach (var nodeArchetype in groupArchetype.Archetypes)
                {
                    if ((nodeArchetype.Flags & NodeFlags.NoSpawnViaGUI) != 0 || !canSpawnNodeType(nodeArchetype))
                    {
                        continue;
                    }

                    nodes.Add(nodeArchetype);
                }

                // Check if can create group for them
                if (nodes.Count > 0)
                {
                    var group = new VisjectCMGroup(this, groupArchetype);
                    group.Close(false);
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        var item = new VisjectCMItem(group, nodes[i]);
                        item.Parent = group;
                    }
                    group.SortChildren();
                    group.Parent       = panel2;
                    group.DefaultIndex = index++;
                    _groups.Add(group);
                }
            }
        }
Example #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VisjectCM"/> class.
        /// </summary>
        /// <param name="type">The surface type.</param>
        public VisjectCM(SurfaceType type)
        {
            Type = type;

            // Context menu dimensions
            Size = new Vector2(320, 220);

            // Search box
            _searchBox = new TextBox(false, 1, 1)
            {
                Width         = Width - 3,
                WatermarkText = "Search...",
                Parent        = this
            };
            _searchBox.TextChanged += OnSearchFilterChanged;

            // Create first panel (for scrollbar)
            var panel1 = new Panel(ScrollBars.Vertical)
            {
                Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2),
                Parent = this
            };

            // Create second panel (for groups arrangement)
            var panel2 = new VerticalPanel
            {
                DockStyle    = DockStyle.Top,
                IsScrollable = true,
                Parent       = panel1
            };

            // Init groups
            var groups = NodeFactory.Groups;
            var nodes  = new List <NodeArchetype>();

            foreach (var groupArchetype in groups)
            {
                // Get valid nodes
                nodes.Clear();
                foreach (var nodeArchetype in groupArchetype.Archetypes)
                {
                    if ((nodeArchetype.Flags & NodeFlags.NoSpawnViaGUI) != 0)
                    {
                        continue;
                    }
                    if (type == SurfaceType.Material)
                    {
                        if ((nodeArchetype.Flags & NodeFlags.VisjectOnly) != 0)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if ((nodeArchetype.Flags & NodeFlags.MaterialOnly) != 0)
                        {
                            continue;
                        }
                    }

                    nodes.Add(nodeArchetype);
                }

                // Check if can create group for them
                if (nodes.Count > 0)
                {
                    var group = new VisjectCMGroup(this, groupArchetype);
                    group.Close(false);
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        var item = new VisjectCMItem(group, nodes[i]);
                        item.Parent = group;
                    }
                    group.SortChildren();
                    group.Parent = panel2;
                    _groups.Add(group);
                }
            }
        }