Пример #1
0
    // Create a file for an option group from given data.
    internal static void CreateOptionGroup(DirectoryInfo baseFolder, SelectType type, string name,
                                           int priority, int index, string desc, IEnumerable <ISubMod> subMods)
    {
        switch (type)
        {
        case SelectType.Multi:
        {
            var group = new MultiModGroup()
            {
                Name        = name,
                Description = desc,
                Priority    = priority,
            };
            group.PrioritizedOptions.AddRange(subMods.OfType <SubMod>().Select((s, idx) => (s, idx)));
            IModGroup.Save(group, baseFolder, index);
            break;
        }

        case SelectType.Single:
        {
            var group = new SingleModGroup()
            {
                Name        = name,
                Description = desc,
                Priority    = priority,
            };
            group.OptionData.AddRange(subMods.OfType <SubMod>());
            IModGroup.Save(group, baseFolder, index);
            break;
        }
        }
    }
Пример #2
0
        // Draw a single group selector as a combo box.
        // If a description is provided, add a help marker besides it.
        private void DrawSingleGroup(IModGroup group, int groupIdx)
        {
            if (group.Type != SelectType.Single || !group.IsOption)
            {
                return;
            }

            using var id = ImRaii.PushId(groupIdx);
            var selectedOption = _emptySetting ? 0 : ( int )_settings.Settings[groupIdx];

            ImGui.SetNextItemWidth(_window._inputTextWidth.X * 3 / 4);
            using var combo = ImRaii.Combo(string.Empty, group[selectedOption].Name);
            if (combo)
            {
                for (var idx2 = 0; idx2 < group.Count; ++idx2)
                {
                    if (ImGui.Selectable(group[idx2].Name, idx2 == selectedOption))
                    {
                        Penumbra.CollectionManager.Current.SetModSetting(_mod.Index, groupIdx, ( uint )idx2);
                    }
                }
            }

            combo.Dispose();
            ImGui.SameLine();
            if (group.Description.Length > 0)
            {
                ImGuiUtil.LabeledHelpMarker(group.Name, group.Description);
            }
            else
            {
                ImGui.TextUnformatted(group.Name);
            }
        }
Пример #3
0
            private static void Target(ModPanel panel, IModGroup group, int groupIdx, int optionIdx)
            {
                // TODO drag options to other groups without options.
                using var target = ImRaii.DragDropTarget();
                if (!target.Success || !ImGuiUtil.IsDropping(DragDropLabel))
                {
                    return;
                }

                if (_dragDropGroupIdx >= 0 && _dragDropOptionIdx >= 0)
                {
                    if (_dragDropGroupIdx == groupIdx)
                    {
                        var sourceOption = _dragDropOptionIdx;
                        panel._delayedActions.Enqueue(() => Penumbra.ModManager.MoveOption(panel._mod, groupIdx, sourceOption, optionIdx));
                    }
                    else
                    {
                        // Move from one group to another by deleting, then adding the option.
                        var sourceGroup  = _dragDropGroupIdx;
                        var sourceOption = _dragDropOptionIdx;
                        var option       = @group[_dragDropOptionIdx];
                        var priority     = @group.OptionPriority(_dragDropGroupIdx);
                        panel._delayedActions.Enqueue(() =>
                        {
                            Penumbra.ModManager.DeleteOption(panel._mod, sourceGroup, sourceOption);
                            Penumbra.ModManager.AddOption(panel._mod, groupIdx, option, priority);
                        });
                    }
                }

                _dragDropGroupIdx  = -1;
                _dragDropOptionIdx = -1;
            }
Пример #4
0
            // Handle drag and drop to move options inside a group or into another group.
            private static void Source(IModGroup group, int groupIdx, int optionIdx)
            {
                using var source = ImRaii.DragDropSource();
                if (!source)
                {
                    return;
                }

                if (ImGui.SetDragDropPayload(DragDropLabel, IntPtr.Zero, 0))
                {
                    _dragDropGroupIdx  = groupIdx;
                    _dragDropOptionIdx = optionIdx;
                }

                ImGui.TextUnformatted($"Dragging option {group[ optionIdx ].Name} from group {group.Name}...");
            }
Пример #5
0
        // Draw a multi group selector as a bordered set of checkboxes.
        // If a description is provided, add a help marker in the title.
        private void DrawMultiGroup(IModGroup group, int groupIdx)
        {
            if (group.Type != SelectType.Multi || !group.IsOption)
            {
                return;
            }

            using var id = ImRaii.PushId(groupIdx);
            var flags = _emptySetting ? 0u : _settings.Settings[groupIdx];

            Widget.BeginFramedGroup(group.Name, group.Description);
            for (var idx2 = 0; idx2 < group.Count; ++idx2)
            {
                var flag    = 1u << idx2;
                var setting = (flags & flag) != 0;
                if (ImGui.Checkbox(group[idx2].Name, ref setting))
                {
                    flags = setting ? flags | flag : flags & ~flag;
                    Penumbra.CollectionManager.Current.SetModSetting(_mod.Index, groupIdx, flags);
                }
            }

            Widget.EndFramedGroup();
        }
Пример #6
0
            // Draw a line for a single option.
            private static void EditOption(ModPanel panel, IModGroup group, int groupIdx, int optionIdx)
            {
                var option = group[optionIdx];

                using var id = ImRaii.PushId(optionIdx);
                ImGui.TableNextColumn();
                ImGui.AlignTextToFramePadding();
                ImGui.Selectable($"Option #{optionIdx + 1}");
                Source(group, groupIdx, optionIdx);
                Target(panel, group, groupIdx, optionIdx);

                ImGui.TableNextColumn();
                if (Input.Text("##Name", groupIdx, optionIdx, option.Name, out var newOptionName, 256, -1))
                {
                    Penumbra.ModManager.RenameOption(panel._mod, groupIdx, optionIdx, newOptionName);
                }

                ImGui.TableNextColumn();
                if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), panel._window._iconButtonSize,
                                                 "Delete this option.\nHold Control while clicking to delete.", !ImGui.GetIO().KeyCtrl, true))
                {
                    panel._delayedActions.Enqueue(() => Penumbra.ModManager.DeleteOption(panel._mod, groupIdx, optionIdx));
                }

                ImGui.TableNextColumn();
                if (group.Type == SelectType.Multi)
                {
                    if (Input.Priority("##Priority", groupIdx, optionIdx, group.OptionPriority(optionIdx), out var priority,
                                       50 * ImGuiHelpers.GlobalScale))
                    {
                        Penumbra.ModManager.ChangeOptionPriority(panel._mod, groupIdx, optionIdx, priority);
                    }

                    ImGuiUtil.HoverTooltip("Option priority.");
                }
            }
Пример #7
0
 // Draw a combo to select single or multi group and switch between them.
 private void DrawGroupCombo(IModGroup group, int groupIdx)
 {
Пример #8
0
        private static bool MigrateV0ToV1(Mod mod, JObject json)
        {
            if (mod.FileVersion > 0)
            {
                return(false);
            }

            var swaps = json["FileSwaps"]?.ToObject <Dictionary <Utf8GamePath, FullPath> >()
                        ?? new Dictionary <Utf8GamePath, FullPath>();
            var groups        = json["Groups"]?.ToObject <Dictionary <string, OptionGroupV0> >() ?? new Dictionary <string, OptionGroupV0>();
            var priority      = 1;
            var seenMetaFiles = new HashSet <FullPath>();

            foreach (var group in groups.Values)
            {
                ConvertGroup(mod, group, ref priority, seenMetaFiles);
            }

            foreach (var unusedFile in mod.FindUnusedFiles().Where(f => !seenMetaFiles.Contains(f)))
            {
                if (unusedFile.ToGamePath(mod.ModPath, out var gamePath) &&
                    !mod._default.FileData.TryAdd(gamePath, unusedFile))
                {
                    PluginLog.Error($"Could not add {gamePath} because it already points to {mod._default.FileData[ gamePath ]}.");
                }
            }

            mod._default.FileSwapData.Clear();
            mod._default.FileSwapData.EnsureCapacity(swaps.Count);
            foreach (var(gamePath, swapPath) in swaps)
            {
                mod._default.FileSwapData.Add(gamePath, swapPath);
            }

            mod._default.IncorporateMetaChanges(mod.ModPath, true);
            foreach (var(group, index) in mod.Groups.WithIndex())
            {
                IModGroup.Save(group, mod.ModPath, index);
            }

            // Delete meta files.
            foreach (var file in seenMetaFiles.Where(f => f.Exists))
            {
                try
                {
                    File.Delete(file.FullName);
                }
                catch (Exception e)
                {
                    PluginLog.Warning($"Could not delete meta file {file.FullName} during migration:\n{e}");
                }
            }

            // Delete old meta files.
            var oldMetaFile = Path.Combine(mod.ModPath.FullName, "metadata_manipulations.json");

            if (File.Exists(oldMetaFile))
            {
                try
                {
                    File.Delete(oldMetaFile);
                }
                catch (Exception e)
                {
                    PluginLog.Warning($"Could not delete old meta file {oldMetaFile} during migration:\n{e}");
                }
            }

            mod.FileVersion = 1;
            mod.SaveDefaultMod();
            mod.SaveMeta();

            return(true);
        }