Exemple #1
0
        /// <summary>
        /// Fills in the actual mod option fields.
        /// </summary>
        /// <param name="dialog">The dialog to populate.</param>
        private void FillModOptions(PDialog dialog)
        {
            var body   = dialog.Body;
            var margin = new RectOffset(CATEGORY_MARGIN, CATEGORY_MARGIN, CATEGORY_MARGIN,
                                        CATEGORY_MARGIN);

            // For each option, add its UI component to panel
            body.Margin = new RectOffset();
            var scrollBody = new PPanel("ScrollContent")
            {
                Spacing = OUTER_MARGIN, Direction = PanelDirection.Vertical, Alignment =
                    TextAnchor.UpperCenter, FlexSize = Vector2.right
            };
            var allOptions = (options == null) ? optionCategories : OptionsEntry.
                             AddCustomOptions(options, optionCategories);

            // Display all categories
            foreach (var catEntries in allOptions)
            {
                string category = catEntries.Key;
                if (catEntries.Value.Count > 0)
                {
                    string name = string.IsNullOrEmpty(category) ? "Default" : category;
                    int    i    = 0;
                    // Not optimal for layout performance, but the panel is needed to have a
                    // different background color for each category "box"
                    var container = new PGridPanel("Category_" + name)
                    {
                        Margin   = margin, BackColor = PUITuning.Colors.DialogDarkBackground,
                        FlexSize = Vector2.right
                    };
                    // Needs to be a separate panel so that it can be collapsed
                    var contents = new PGridPanel("Entries")
                    {
                        FlexSize = Vector2.right
                    };
                    AddCategoryHeader(container, catEntries.Key, contents);
                    foreach (var entry in catEntries.Value)
                    {
                        contents.AddRow(new GridRowSpec());
                        entry.CreateUIEntry(contents, ref i);
                        i++;
                    }
                    scrollBody.AddChild(container);
                }
            }
            // Manual config button
            scrollBody.AddChild(new PButton("ManualConfig")
            {
                Text    = PUIStrings.BUTTON_MANUAL, ToolTip = PUIStrings.TOOLTIP_MANUAL,
                OnClick = OnManualConfig, TextAlignment = TextAnchor.MiddleCenter, Margin =
                    PDialog.BUTTON_MARGIN
            }.SetKleiBlueStyle());
            body.AddChild(new PScrollPane()
            {
                ScrollHorizontal     = false, ScrollVertical = allOptions.Count > 0,
                Child                = scrollBody, FlexSize = Vector2.right, TrackSize = 8,
                AlwaysShowHorizontal = false, AlwaysShowVertical = false
            });
        }
        /// <summary>
        /// Creates an options entry wrapper for the specified property.
        /// </summary>
        /// <param name="info">The property to wrap.</param>
        /// <param name="oa">The option title and tool tip.</param>
        /// <returns>An options wrapper, or null if none can handle this type.</returns>
        private static OptionsEntry CreateOptions(PropertyInfo info, OptionAttribute oa)
        {
            OptionsEntry entry = null;
            Type         type  = info.PropertyType;
            string       field = info.Name;

            // Enumeration type
            if (type.IsEnum)
            {
                entry = new SelectOneOptionsEntry(field, oa.Title, oa.Tooltip, type);
            }
            else if (type == typeof(bool))
            {
                entry = new CheckboxOptionsEntry(field, oa.Title, oa.Tooltip);
            }
            else if (type == typeof(int))
            {
                entry = new IntOptionsEntry(oa.Title, oa.Tooltip, info);
            }
            else if (type == typeof(float))
            {
                entry = new FloatOptionsEntry(oa.Title, oa.Tooltip, info);
            }
            else if (type == typeof(string))
            {
                entry = new StringOptionsEntry(oa.Title, oa.Tooltip, info);
            }
            return(entry);
        }
        /// <summary>
        /// Builds the options entries from the type.
        /// </summary>
        /// <param name="forType">The type of the options class.</param>
        /// <returns>A list of all public properties annotated for options dialogs.</returns>
        private static IDictionary <string, OptionsList> BuildOptions(Type forType)
        {
            var             entries = new Dictionary <string, OptionsList>(4);
            OptionAttribute oa;

            foreach (var prop in forType.GetProperties())
            {
                // Must have the annotation
                foreach (var attr in prop.GetCustomAttributes(false))
                {
                    if ((oa = OptionsEntry.GetOptionInfo(attr)) != null)
                    {
                        // Attempt to find a class that will represent it
                        var entry = CreateOptions(prop, oa);
                        if (entry != null)
                        {
                            string category = entry.Category ?? "";
                            // Add this category if it does not exist
                            if (!entries.TryGetValue(category, out OptionsList inCat))
                            {
                                inCat = new List <OptionsEntry>(16);
                                entries.Add(category, inCat);
                            }
                            inCat.Add(entry);
                        }
                        break;
                    }
                }
            }
            return(entries);
        }
Exemple #4
0
        internal OptionsDialog(Type optionsType, KMod.Mod modSpec)
        {
            dialog           = null;
            modImage         = null;
            this.modSpec     = modSpec ?? throw new ArgumentNullException("modSpec");
            this.optionsType = optionsType ?? throw new ArgumentNullException("optionsType");
            optionCategories = OptionsEntry.BuildOptions(optionsType);
            options          = null;
            // Determine config location
            infoAttr = POptions.GetModInfoAttribute(optionsType);
            typeAttr = POptions.GetConfigFileAttribute(optionsType);
            var src = modSpec.file_source;

            if (src == null)
            {
                path = null;
            }
            else
            {
                path = Path.Combine(src.GetRoot(), typeAttr?.ConfigFileName ?? POptions.
                                    CONFIG_FILE_NAME);
            }
            // Find mod home page
            string url   = infoAttr?.URL;
            var    label = modSpec.label;

            if (string.IsNullOrEmpty(url) && label.distribution_platform == KMod.Label.
                DistributionPlatform.Steam)
            {
                // Steam mods use their workshop ID as the label
                url = "https://steamcommunity.com/sharedfiles/filedetails/?id=" + label.id;
            }
            modURL = url;
        }
Exemple #5
0
        internal OptionsDialog(Type optionsType, IOptionsHandler handler)
        {
            string root = handler.ConfigPath;

            dialog           = null;
            modImage         = null;
            this.handler     = handler ?? throw new ArgumentNullException("handler");
            this.optionsType = optionsType ?? throw new ArgumentNullException("optionsType");
            optionCategories = OptionsEntry.BuildOptions(optionsType);
            options          = null;
            // Determine config location
            infoAttr = POptions.GetModInfoAttribute(optionsType);
            typeAttr = POptions.GetConfigFileAttribute(optionsType);
            path     = (root == null) ? null : Path.Combine(root, typeAttr?.ConfigFileName ??
                                                            POptions.CONFIG_FILE_NAME);
        }
Exemple #6
0
 /// <summary>
 /// Adds a category header to the dialog.
 /// </summary>
 /// <param name="container">The parent of the header.</param>
 /// <param name="category">The header title.</param>
 /// <param name="contents">The panel containing the options in this category.</param>
 private void AddCategoryHeader(PGridPanel container, string category,
                                PGridPanel contents)
 {
     contents.AddColumn(new GridColumnSpec(flex: 1.0f)).AddColumn(new GridColumnSpec());
     if (!string.IsNullOrEmpty(category))
     {
         bool state   = !(infoAttr?.ForceCollapseCategories ?? false);
         var  handler = new CategoryExpandHandler(state);
         container.AddColumn(new GridColumnSpec()).AddColumn(new GridColumnSpec(
                                                                 flex: 1.0f)).AddRow(new GridRowSpec()).AddRow(new GridRowSpec(flex: 1.0f));
         // Toggle is upper left, header is upper right
         var header = new PLabel("CategoryHeader")
         {
             Text = OptionsEntry.LookInStrings(category), TextStyle =
                 CATEGORY_TITLE_STYLE, TextAlignment = TextAnchor.LowerCenter
         };
         var toggle = new PToggle("CategoryToggle")
         {
             Color          = PUITuning.Colors.ComponentDarkStyle, InitialState = state,
             ToolTip        = PUIStrings.TOOLTIP_TOGGLE, Size = TOGGLE_SIZE,
             OnStateChanged = handler.OnExpandContract
         };
         header.OnRealize += handler.OnRealizeHeader;
         toggle.OnRealize += handler.OnRealizeToggle;
         container.AddChild(header, new GridComponentSpec(0, 1)
         {
             Margin = new RectOffset(OUTER_MARGIN, OUTER_MARGIN, 0, 0)
         }).AddChild(toggle, new GridComponentSpec(0, 0));
         if (contents != null)
         {
             contents.OnRealize += handler.OnRealizePanel;
         }
         container.AddChild(contents, new GridComponentSpec(1, 0)
         {
             ColumnSpan = 2
         });
     }
     else
     {
         // Default of unconstrained fills the whole panel
         container.AddColumn(new GridColumnSpec(flex: 1.0f)).AddRow(new GridRowSpec(
                                                                        flex: 1.0f)).AddChild(contents, new GridComponentSpec(0, 0));
     }
 }
Exemple #7
0
        /// <summary>
        /// Triggered when the Mod Options button is clicked.
        /// </summary>
        public void ShowDialog()
        {
            string title;

            if (string.IsNullOrEmpty(displayInfo.Title))
            {
                title = PLibStrings.BUTTON_OPTIONS;
            }
            else
            {
                title = string.Format(PLibStrings.DIALOG_TITLE, OptionsEntry.LookInStrings(
                                          displayInfo.Title));
            }
            // Close current dialog if open
            CloseDialog();
            // Ensure that it is on top of other screens (which may be +100 modal)
            var pDialog = new PDialog("ModOptions")
            {
                Title              = title, Size = SETTINGS_DIALOG_SIZE, SortKey = 150.0f,
                DialogBackColor    = PUITuning.Colors.OptionsBackground,
                DialogClosed       = OnOptionsSelected, MaxSize = SETTINGS_DIALOG_MAX_SIZE,
                RoundToNearestEven = true
            }.AddButton("ok", STRINGS.UI.CONFIRMDIALOG.OK, PLibStrings.TOOLTIP_OK,
                        PUITuning.Colors.ButtonPinkStyle).AddButton(PDialog.DIALOG_KEY_CLOSE,
                                                                    STRINGS.UI.CONFIRMDIALOG.CANCEL, PLibStrings.TOOLTIP_CANCEL,
                                                                    PUITuning.Colors.ButtonBlueStyle);

            options = POptions.ReadSettings(POptions.GetConfigFilePath(optionsType),
                                            optionsType);
            if (options == null)
            {
                options = CreateOptions(optionsType);
            }
            AddModInfoScreen(pDialog);
            FillModOptions(pDialog);
            // Manually build the dialog so the options can be updated after realization
            var obj = pDialog.Build();

            UpdateOptions();
            dialog = obj.GetComponent <KScreen>();
            dialog.Activate();
        }
Exemple #8
0
 /// <summary>
 /// Triggered when the Mod Options button is clicked.
 /// </summary>
 public void OnModOptions(GameObject _)
 {
     if (path != null)
     {
         string title = handler.GetTitle(OptionsEntry.LookInStrings(infoAttr?.Title));
         if (string.IsNullOrEmpty(title))
         {
             title = PUIStrings.BUTTON_OPTIONS;
         }
         // Close current dialog if open
         CloseDialog();
         // Ensure that it is on top of other screens (which may be +100 modal)
         var pDialog = new PDialog("ModOptions")
         {
             Title              = title, Size = SETTINGS_DIALOG_SIZE, SortKey = 150.0f,
             DialogBackColor    = PUITuning.Colors.OptionsBackground,
             DialogClosed       = OnOptionsSelected, MaxSize = SETTINGS_DIALOG_MAX_SIZE,
             RoundToNearestEven = true
         }.AddButton("ok", STRINGS.UI.CONFIRMDIALOG.OK, PUIStrings.TOOLTIP_OK,
                     PUITuning.Colors.ButtonPinkStyle).AddButton(PDialog.DIALOG_KEY_CLOSE,
                                                                 STRINGS.UI.CONFIRMDIALOG.CANCEL, PUIStrings.TOOLTIP_CANCEL,
                                                                 PUITuning.Colors.ButtonBlueStyle);
         options = POptions.ReadSettings(path, optionsType);
         if (options == null)
         {
             CreateOptions();
         }
         if (infoAttr != null)
         {
             AddModInfoScreen(pDialog);
         }
         FillModOptions(pDialog);
         // Manually build the dialog so the options can be updated after realization
         var obj = pDialog.Build();
         UpdateOptions();
         dialog = obj.GetComponent <KScreen>();
         dialog.Activate();
     }
 }
Exemple #9
0
        internal OptionsDialog(Type optionsType)
        {
            OnClose          = null;
            dialog           = null;
            modImage         = null;
            this.optionsType = optionsType ?? throw new ArgumentNullException(nameof(
                                                                                  optionsType));
            optionCategories = OptionsEntry.BuildOptions(optionsType);
            options          = null;
            // Determine config location
            var infoAttr = optionsType.GetCustomAttribute <ModInfoAttribute>();

            if (infoAttr != null)
            {
                collapseCategories = infoAttr.ForceCollapseCategories;
            }
            else
            {
                collapseCategories = false;
            }
            configAttr  = optionsType.GetCustomAttribute <ConfigFileAttribute>();
            displayInfo = new ModDialogInfo(optionsType, infoAttr?.URL, infoAttr?.Image);
        }
Exemple #10
0
        /// <summary>
        /// Builds the options entries from the type.
        /// </summary>
        /// <param name="forType">The type of the options class.</param>
        /// <returns>A list of all public properties annotated for options dialogs.</returns>
        private static ICollection <OptionsEntry> BuildOptions(Type forType)
        {
            var             entries = new List <OptionsEntry>(16);
            OptionAttribute oa;

            foreach (var prop in forType.GetProperties())
            {
                // Must have the annotation
                foreach (var attr in prop.GetCustomAttributes(false))
                {
                    if ((oa = OptionsEntry.GetTitle(attr)) != null)
                    {
                        // Attempt to find a class that will represent it
                        var entry = CreateOptions(prop, oa);
                        if (entry != null)
                        {
                            entries.Add(entry);
                        }
                        break;
                    }
                }
            }
            return(entries);
        }
		internal RuntimeOptionsHandler(string path, string title) {
			ConfigPath = path;
			this.title = string.IsNullOrEmpty(title) ? null : OptionsEntry.LookInStrings(title);
		}