Exemple #1
0
 /// <summary>
 /// Write member information into <see cref="Option"/>s.
 /// <remarks>
 /// The function basically dispatches between different visitor functions.
 /// </remarks>
 /// </summary>
 /// <param name="optionGroup">The OptionGroup to contain the configuration.</param>
 /// <param name="config">The input configuration.</param>
 private void VisitMembers(OptionGroup optionGroup, object config)
 {
     foreach (var member in toplevelItems)
     {
         VisitMember(member, optionGroup, config);
     }
     foreach (var method in methods)
     {
         VisitMethod(method, optionGroup, config);
     }
 }
Exemple #2
0
        /// <summary>
        /// Convert the input configuration into an <see cref="OptionGroup"/> usable by an option editor.
        /// </summary>
        /// <remarks>
        /// First, all members are *collected* and stored in their respective maps and lists.
        /// Next, members are sorted by the position information contained in the corresponding <see cref="OptionGroupAttribute"/>.
        /// Finally, all members are visited and the extracted data relevant to build ui components are written to
        /// an <see cref="Option"/>.
        /// </remarks>
        /// <param name="config">The input configuration written by the developer.</param>
        /// <returns>The output configuration usable by an option editor.</returns>
        public OptionGroup Convert(object config)
        {
            var type = config.GetType();

            // collect members
            CollectMembers(type, config);

            // sort members
            toplevelItems.Sort(new MemberComparer());
            foreach (KeyValuePair <string, List <MemberInfo> > entry in groupMapping)
            {
                entry.Value.Sort(new MemberComparer());
            }

            // visit members
            var topLevelGroup = new OptionGroup();

            SetLabel(type, topLevelGroup);
            VisitMembers(topLevelGroup, config);
            return(topLevelGroup);
        }
Exemple #3
0
 /// <summary>
 /// Visit a member.
 /// </summary>
 /// <remarks>
 /// The function dispatches between different visit functions based on type of the member.
 /// </remarks>
 /// <param name="member">The member to visit.</param>
 /// <param name="optionGroup">The output data object.</param>
 /// <param name="config">The input configuration.</param>
 private void VisitMember(MemberInfo member, OptionGroup optionGroup, object config)
 {
     if (ShouldIgnoreMember(member))
     {
         return;
     }
     if (IsOptionGroup(member))
     {
         optionGroup.ChildOptions.Add(VisitGroup(member, config));
     }
     else
     {
         if (member is FieldInfo)
         {
             optionGroup.ChildOptions.Add(VisitField((FieldInfo)member, config));
         }
         else if (member is PropertyInfo)
         {
             optionGroup.ChildOptions.Add(VisitProperty((PropertyInfo)member, config));
         }
     }
 }
Exemple #4
0
        /// <summary>
        ///  Creates a group box and it's children
        /// </summary>
        /// <param name="optionGroup"></param>
        /// <returns></returns>
        private Control CreateGroupBox(OptionGroup optionGroup)
        {
            GroupBox box = new GroupBox();

            box.Text  = optionGroup.Label;
            box.Width = rootPanel.Width -
                        (gbPaddingLeft + gbPaddingRight + topLevelGroupPaddingLeft + topLevelGroupPaddingRight);
            var Y = box.Location.Y + gbPaddingTop;

            foreach (var child in optionGroup.ChildOptions)
            {
                Control groupChild = CreateControl(child);
                groupChild.Location = new Point(gbPaddingLeft, Y);
                groupChild.Width    = rootPanel.Width -
                                      (gbPaddingLeft + gbPaddingRight + topLevelGroupPaddingLeft + topLevelGroupPaddingRight);

                box.Controls.Add(groupChild);
                Y += groupChild.Height;
            }
            box.Height = Y + gbPaddingBottom;
            return(box);
        }
Exemple #5
0
        /// <summary>
        /// Visit a group and return an <see cref="OptionGroup"/> with all relevant information to build a component.
        /// </summary>
        /// <remarks>
        /// The following information is written:
        /// - group name
        /// - text label
        /// - custom attributes
        /// <para>
        /// If the <see cref="groupMapping"/> contains child members of this groups, these are <see cref="VisitMember">visited</see> as well.
        /// </para>
        /// </remarks>
        /// <param name="groupMember">The group to process.</param>
        /// <param name="config">The input configuration.</param>
        private OptionGroup VisitGroup(MemberInfo groupMember, object config)
        {
            var g = new OptionGroup();

            g.Name          = groupMember.Name;
            g.ComponentType = ComponentTypes.OptionGroup;
            SetLabel(groupMember, g);
            object[] attrs = groupMember.GetCustomAttributes(false);
            foreach (var attribute in attrs)
            {
                VisitAttribute((Attribute)attribute, g);
            }
            var name = g.Name.ToLower();

            if (groupMapping.ContainsKey(name))
            {
                var memberInfos = groupMapping[name];
                foreach (var memberInfo in memberInfos)
                {
                    VisitMember(memberInfo, g, config);
                }
            }
            return(g);
        }
Exemple #6
0
 private static void VisitMethod(MethodInfo method, OptionGroup optionGroup, object config)
 {
     // methods aren't used right now
 }
Exemple #7
0
        /// <summary>
        /// Creates a foldable top-level grouping and it's children
        /// </summary>
        /// <param name="optionGroup"></param>
        private SplitContainer AddTopLevelOptionGroup(OptionGroup optionGroup)
        {
            SplitContainer splitContainer = new SplitContainer();

            splitContainer.Orientation = Orientation.Horizontal;
            splitContainer.BackColor   = Color.LightGray;
            splitContainer.Width       =
                rootPanel.Width - (rootPanel.Width - (topLevelGroupPaddingLeft + topLevelGroupPaddingRight + 100));
            splitContainer.IsSplitterFixed = true;

            var groupLabelButton =
                new Label()
            {
                Text = "▶ " + optionGroup.Label, BackColor = Color.Gray, ForeColor = Color.White, Dock = DockStyle.Fill, TextAlign = ContentAlignment.MiddleLeft, AutoSize = false
            };

            groupLabelButton.Click += (sender, args) => {
                toggleHeaderCollapse(splitContainer);
            };
            splitContainer.Panel1.Click += (sender, args) => {
                toggleHeaderCollapse(splitContainer);
            };

            splitContainer.Panel1.Controls.Add(groupLabelButton);
            splitContainer.Panel1.BackColor = Color.Gray;
            splitContainer.Panel1.Size      = new Size(rootPanel.Width - (topLevelGroupPaddingLeft + topLevelGroupPaddingRight), 30);
            splitContainer.Panel1.AutoSize  = true;


            var Y = topLevelGroupPaddingTop;

            foreach (var option in (optionGroup).ChildOptions)
            {
                // a group containing more elements
                if (option.ComponentType == ComponentTypes.OptionGroup)
                {
                    var optionControl = CreateGroupBox(option as OptionGroup);
                    optionControl.Location = new Point(topLevelGroupPaddingLeft, Y);
                    splitContainer.Panel2.Controls.Add(optionControl);
                    Y += optionControl.Height;
                }
                else
                {
                    // single elements
                    var optionControl = CreateControl(option);
                    splitContainer.Panel2.Controls.Add(optionControl);
                    optionControl.Location = new Point(topLevelGroupPaddingLeft, Y);
                    Y += optionControl.Height;
                }
            }

            splitContainer.Panel2.BackColor = Color.White;
            splitContainer.Panel1MinSize    = 30;
            splitContainer.Panel2MinSize    = 1;
            splitContainer.Panel2.AutoSize  = true;

            splitContainer.FixedPanel       = FixedPanel.Panel1;
            splitContainer.SplitterDistance = 10;
            splitContainer.MinimumSize      = new Size(rootPanel.Width, 10);
            splitContainer.Size             = new Size(rootPanel.Width, 10);
            splitContainer.Panel2Collapsed  = true;

            if (optionGroup.Label == "Description")
            {
                if (splitContainer.Panel2.Controls[0] is RichTextBox)
                {
                    // rtf boxes can be isolated
                    RichTextBox text = (RichTextBox)splitContainer.Panel2.Controls[0];
                    text.Width       = rootPanel.Width - (topLevelGroupPaddingLeft + topLevelGroupPaddingRight);
                    text.BorderStyle = BorderStyle.None;
                    text.ScrollBars  = RichTextBoxScrollBars.None;
                    var content = text.Rtf;
                    text.Text = String.Empty;
                    ContentsResizedEventHandler text_OnContentsResized = null;
                    text_OnContentsResized = delegate(object o, ContentsResizedEventArgs args) {
                        text.Height           = args.NewRectangle.Height;
                        splitContainer.Height = topLevelGroupPaddingBottom + topLevelGroupPaddingTop + args.NewRectangle.Height;
                        text.ContentsResized -= text_OnContentsResized;
                    };
                    text.ContentsResized += text_OnContentsResized;
                    text.Rtf              = content;

                    toggleHeaderCollapse(splitContainer);
                }
            }
            return(splitContainer);
        }