Example #1
0
        private void CreateNodes()
        {
            EditorTreeView.Nodes.Clear();
            foreach (PropertyInfo propertyInfo in SelectedObjectType.GetProperties())
            {
                TreeViewPropertyAttribute tvpa = propertyInfo.GetCustomAttribute <TreeViewPropertyAttribute>();
                if (tvpa == null)
                {
                    continue;
                }

                TreeNodeCollection nodeCollection = EditorTreeView.Nodes;

                if (tvpa.ParentNode != null) // Property belongs to a category/folder
                {
                    string parentNodeKey = $"*{tvpa.ParentNode}";
                    if (!EditorTreeView.Nodes.ContainsKey(parentNodeKey)) // Folder does not exist, create it
                    {
                        TreeNode parentNode = new TreeNode(tvpa.ParentNode)
                        {
                            Name = parentNodeKey, ImageKey = "folder0", SelectedImageKey = "folder0"
                        };
                        EditorTreeView.Nodes.Add(parentNode);
                    }

                    nodeCollection = EditorTreeView.Nodes[parentNodeKey].Nodes;
                }

                TreeNode node = new TreeNode
                {
                    Text        = tvpa.DisplayName,
                    Name        = propertyInfo.Name,
                    ToolTipText = tvpa.Description
                };
                GUITools.SetTreeNodeImage(node, "Setting");

                nodeCollection.Add(node);

                if (propertyInfo.PropertyType.IsArray)
                {
                    GUITools.SetTreeNodeImage(node, "folder0");

                    if (tvpa.DataSourceType.IsEnum)
                    {
                        foreach (object enumValue in Enum.GetValues(tvpa.DataSourceType))
                        {
                            GUITools.GetDisplayStrings(tvpa.DataSourceType, enumValue, out string enumDisplayName, out string enumDescription);
                            node.Nodes.Add($"#{enumValue}", enumDisplayName, "checkbox0", "checkbox0").ToolTipText = enumDescription;
                        }
                    }
                    else if (tvpa.DataSourceType.IsSubclassOf(typeof(DBEntry)))
                    {
                        foreach (DBEntry entry in Database.Instance.GetAllEntries(tvpa.DataSourceType))
                        {
                            node.Nodes.Add($"#{entry.ID}", entry.UIDisplayName, "checkbox0", "checkbox0").ToolTipText = entry.UIDescription;
                        }
                    }
                }
            }

            EditorTreeView.Sort();
        }
Example #2
0
        private void UpdateNode(TreeNode node)
        {
            Array arrayValues;

            if (!string.IsNullOrEmpty(node.Name))
            {
                switch (node.Name[0])
                {
                case '*':     // Node is a folder
                    break;

                case '#':     // Node is a checkbox
                    arrayValues = (Array)GetPropertyValue(node.Parent.Name);
                    string checkImage = "checkbox0";
                    for (int i = 0; i < arrayValues.Length; i++)
                    {
                        if (arrayValues.GetValue(i).ToString() == node.Name.Substring(1))
                        {
                            checkImage = "checkbox1";
                            break;
                        }
                    }
                    node.ImageKey         = checkImage;
                    node.SelectedImageKey = checkImage;
                    break;

                default:                                                 // Node is a property
                    if (GetPropertyInfo(node.Name).PropertyType.IsArray) // Property is an array
                    {
                        if (GetTreeViewPropertyAttribute(node.Name).DataSourceType.IsSubclassOf(typeof(ContextMenuExpandable)))
                        {
                            node.Nodes.Clear();
                            arrayValues = (Array)GetPropertyValue(node.Name);

                            for (int i = 0; i < arrayValues.Length; i++)
                            {
                                TreeNode elementNode = node.Nodes.Add($"#{i}", arrayValues.GetValue(i).ToString());
                                elementNode.Tag         = i;
                                elementNode.ToolTipText = elementNode.Text.Replace(", ", "\r\n- ");
                            }

                            return;     // Do not update subnodes
                        }
                    }
                    else
                    {
                        TreeViewPropertyAttribute tvpa = GetTreeViewPropertyAttribute(node.Name);

                        string valueText = GUITools.GetDisplayName(tvpa.DataSourceType, GetPropertyValue(node.Name));
                        if (tvpa.DataSourceType == typeof(int))
                        {
                            TreeViewPropertyIntAttribute tvpia = GetPropertyAttribute <TreeViewPropertyIntAttribute>(node.Name);
                            if (tvpia != null)
                            {
                                valueText = tvpia.FormatIntValue((int)GetPropertyValue(node.Name));
                            }
                        }
                        else if (string.IsNullOrEmpty(valueText) && tvpa.Flags.HasFlag(TreeViewPropertyAttributeFlags.EmptyIsRandom))
                        {
                            valueText = "Random";
                        }

                        node.Text = $"{tvpa.DisplayName}: {valueText}";
                    }
                    break;
                }
            }

            foreach (TreeNode childNode in node.Nodes)
            {
                UpdateNode(childNode);
            }
        }
Example #3
0
        private void OnNodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node == null)
            {
                return;
            }
            EditorTreeView.SelectedNode = e.Node;

            if (e.Node.Nodes.Count > 0)
            {
                if (e.Node.IsExpanded)
                {
                    e.Node.Collapse();
                }
                else
                {
                    e.Node.Expand();
                }
                return;
            }

            if (string.IsNullOrEmpty(e.Node.Name))
            {
                return;                                    // Node has no name, nothing to do
            }
            if (e.Node.Name.StartsWith("*"))
            {
                return;                      // Node is a folder, nothing to do
            }
            if (e.Node.Name.StartsWith("#")) // Node is an array element
            {
                // Array of enums or DBEntries, treat as a checkbox
                if (GetTreeViewPropertyAttribute(e.Node.Parent.Name).DataSourceType.IsEnum ||
                    GetTreeViewPropertyAttribute(e.Node.Parent.Name).DataSourceType.IsSubclassOf(typeof(DBEntry)))
                {
                    if (e.Button != MouseButtons.Left)
                    {
                        return;                                // Only left clicks can toggle checkboxes
                    }
                    string checkImage = (e.Node.ImageKey == "checkbox0") ? "checkbox1" : "checkbox0";
                    e.Node.ImageKey         = checkImage;
                    e.Node.SelectedImageKey = checkImage;

                    object       selectedValues = null;
                    PropertyInfo propertyInfo   = GetPropertyInfo(e.Node.Parent.Name);
                    Type         elementType    = propertyInfo.PropertyType.GetElementType();
                    if (elementType == typeof(string))
                    {
                        selectedValues = (from TreeNode n in e.Node.Parent.Nodes where n.ImageKey == "checkbox1" select n.Name.Substring(1)).ToArray();
                    }
                    else if (elementType == typeof(RealismOption))
                    {
                        selectedValues = (from TreeNode n in e.Node.Parent.Nodes where n.ImageKey == "checkbox1" select(RealismOption) Enum.Parse(elementType, n.Name.Substring(1))).ToArray();
                    }

                    if (selectedValues != null)
                    {
                        propertyInfo.SetValue(SelectedObject, selectedValues);
                    }

                    UpdateNode(e.Node.Parent); // Update parent because sometimes enabling an option will disable others
                    OnPropertyValueChanged?.Invoke(EditorTreeView, new EventArgs());
                }
                else if (GetTreeViewPropertyAttribute(e.Node.Parent.Name).DataSourceType.
                         IsSubclassOf(typeof(ContextMenuExpandable))) // Array of ContextMenuExpandables
                {
                    ContextMenu.Items.Clear();
                    Array arrayValues = (Array)GetPropertyValue(e.Node.Parent.Name);
                    int   arrayIndex  = (int)e.Node.Tag;
                    ((ContextMenuExpandable)arrayValues.GetValue(arrayIndex)).CreateContextMenu(ContextMenu, OnContextMenuItemClicked);
                    ContextMenu.Items.Add(new ToolStripSeparator());

                    if (GetTreeViewPropertyAttribute(e.Node.Parent.Name).DataSourceType == typeof(MissionTemplateFlightGroup))
                    {
                        ContextMenu.Items.Add("Add another flight group").Tag = "*add";
                        if (e.Node.Parent.Nodes.Count > 1)
                        {
                            ContextMenu.Items.Add("Remove flight group").Tag = "*remove";
                        }
                    }

                    foreach (ToolStripItem item in ContextMenu.Items)
                    {
                        if ((item is ToolStripMenuItem) && (((ToolStripMenuItem)item).DropDownItems.Count > 0))
                        {
                            ((ToolStripMenuItem)item).DropDownItemClicked += OnContextMenuItemClicked;
                        }
                    }

                    ContextMenu.Show(EditorTreeView, e.Location);
                }

                return;
            }

            if (GetPropertyInfo(e.Node.Name).PropertyType.IsArray)
            {
                return;
            }

            ContextMenu.Items.Clear();
            TreeViewPropertyAttribute tvpa = GetTreeViewPropertyAttribute(e.Node.Name);

            if (tvpa.DataSourceType.IsEnum)
            {
                foreach (object enumValue in Enum.GetValues(tvpa.DataSourceType))
                {
                    GUITools.GetDisplayStrings(tvpa.DataSourceType, enumValue, out string enumDisplayName, out string enumDescription);
                    ToolStripMenuItem enumMenuItem = new ToolStripMenuItem {
                        Tag = enumValue, Text = enumDisplayName, ToolTipText = enumDescription
                    };
                    ContextMenu.Items.Add(enumMenuItem);
                }
            }
            else if (tvpa.DataSourceType == typeof(int))
            {
                TreeViewPropertyIntAttribute tvpia = GetPropertyAttribute <TreeViewPropertyIntAttribute>(e.Node.Name);

                if (tvpia != null)
                {
                    for (int i = tvpia.IntValueMin; i <= tvpia.IntValueMax; i += tvpia.IntValueIncrement)
                    {
                        ContextMenu.Items.Add(tvpia.FormatIntValue(i)).Tag = i;
                    }
                }
            }
            else if (tvpa.DataSourceType.IsSubclassOf(typeof(DBEntry)))
            {
                GUITools.PopulateToolStripMenuWithDBEntries(
                    ContextMenu.Items, tvpa.DataSourceType,
                    OnContextMenuItemClicked, tvpa.Flags.HasFlag(TreeViewPropertyAttributeFlags.EmptyIsRandom));
            }

            ContextMenu.Show(EditorTreeView, e.Location);
        }