// Sets the resource logger state when toggled,
        // and the filter when entered.
        private void DrawRequestedResourceLogging()
        {
            var tmp = Penumbra.Config.EnableResourceLogging;

            if (ImGui.Checkbox("##resourceLogging", ref tmp))
            {
                _window._penumbra.ResourceLogger.SetState(tmp);
            }

            ImGui.SameLine();
            ImGuiUtil.LabeledHelpMarker("Enable Requested Resource Logging", "Log all game paths FFXIV requests to the plugin log.\n"
                                        + "You can filter the logged paths for those containing the entered string or matching the regex, if the entered string compiles to a valid regex.\n"
                                        + "Red boundary indicates invalid regex.");

            ImGui.SameLine();

            // Red borders if the string is not a valid regex.
            var tmpString = Penumbra.Config.ResourceLoggingFilter;

            using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.RegexWarningBorder, !_window._penumbra.ResourceLogger.ValidRegex);
            using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale,
                                               !_window._penumbra.ResourceLogger.ValidRegex);
            ImGui.SetNextItemWidth(-1);
            if (ImGui.InputTextWithHint("##ResourceLogFilter", "Filter...", ref tmpString, Utf8GamePath.MaxGamePathLength))
            {
                _window._penumbra.ResourceLogger.SetFilter(tmpString);
            }
        }
Пример #2
0
        private bool _dialogOpen;                       // For toggling on/off.

        // Do not change the directory without explicitly pressing enter or this button.
        // Shows up only if the current input does not correspond to the current directory.
        private static bool DrawPressEnterWarning(string newName, string old, float width, bool saved)
        {
            using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.PressEnterWarningBg);
            var w      = new Vector2(width, 0);
            var symbol = '\0';

            var(text, valid) = newName.Length > RootDirectoryMaxLength
                ? ($"Path is too long. The maximum length is {RootDirectoryMaxLength}.", false)
                : newName.Any(c => (symbol = c) > ( char )0x7F)
                    ? ($"Path contains invalid symbol {symbol}. Only ASCII is allowed.", false)
                    : ($"Press Enter or Click Here to Save (Current Directory: {old})", true);

            return((ImGui.Button(text, w) || saved) && valid);
        }
Пример #3
0
        // Draw a big red bar if the current setting is inherited.
        private void DrawInheritedWarning()
        {
            if (!_inherited)
            {
                return;
            }

            using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.PressEnterWarningBg);
            var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);

            if (ImGui.Button($"These settings are inherited from {_collection.Name}.", width))
            {
                Penumbra.CollectionManager.Current.SetModInheritance(_mod.Index, false);
            }

            ImGuiUtil.HoverTooltip("You can click this button to copy the current settings to the current selection.\n"
                                   + "You can also just change any setting, which will copy the settings with the single setting changed to the current selection.");
        }
Пример #4
0
        // If any conflicts exist, show them in this tab.
        private unsafe void DrawConflictsTab()
        {
            using var tab = DrawTab(ConflictTabHeader, Tabs.Conflicts);
            if (!tab)
            {
                return;
            }

            using var box = ImRaii.ListBox("##conflicts", -Vector2.One);
            if (!box)
            {
                return;
            }

            foreach (var conflict in Penumbra.CollectionManager.Current.Conflicts(_mod))
            {
                if (ImGui.Selectable(conflict.Mod2.Name) && conflict.Mod2 is Mod mod)
                {
                    _window._selector.SelectByValue(mod);
                }

                ImGui.SameLine();
                using (var color = ImRaii.PushColor(ImGuiCol.Text,
                                                    conflict.HasPriority ? ColorId.HandledConflictMod.Value() : ColorId.ConflictingMod.Value()))
                {
                    var priority = conflict.Mod2.Index < 0
                        ? conflict.Mod2.Priority
                        : Penumbra.CollectionManager.Current[conflict.Mod2.Index].Settings !.Priority;
                    ImGui.TextUnformatted($"(Priority {priority})");
                }

                using var indent = ImRaii.PushIndent(30f);
                foreach (var data in conflict.Conflicts)
                {
                    var _ = data switch
                    {
                        Utf8GamePath p => ImGuiNative.igSelectable_Bool(p.Path.Path, 0, ImGuiSelectableFlags.None, Vector2.Zero) > 0,
                        MetaManipulation m => ImGui.Selectable(m.Manipulation?.ToString() ?? string.Empty),
                        _ => false,
                    };
                }
            }
        }
        // Draw the mod name in the game font with a 2px border, centered,
        // with at least the width of the version space to each side.
        private float DrawModName()
        {
            var decidingWidth = Math.Max(_secondRowWidth, ImGui.GetWindowWidth());
            var offsetWidth   = (decidingWidth - _modNameWidth) / 2;
            var offsetVersion = _modVersion.Length > 0
                ? _modVersionWidth + ImGui.GetStyle().ItemSpacing.X + ImGui.GetStyle().WindowPadding.X
                : 0;
            var offset = Math.Max(offsetWidth, offsetVersion);

            if (offset > 0)
            {
                ImGui.SetCursorPosX(offset);
            }

            using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.MetaInfoText);
            using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale);
            using var font  = ImRaii.PushFont(_nameFont.ImFont, _nameFont.Available);
            ImGuiUtil.DrawTextButton(_modName, Vector2.Zero, 0);
            return(offset);
        }
Пример #6
0
        public static void DrawDiscordButton(float width)
        {
            const string discord = "Join Discord for Support";
            const string address = @"https://discord.gg/kVva7DHV4r";

            using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.DiscordColor);
            if (ImGui.Button(discord, new Vector2(width, 0)))
            {
                try
                {
                    var process = new ProcessStartInfo(address)
                    {
                        UseShellExecute = true,
                    };
                    Process.Start(process);
                }
                catch
                {
                    // ignored
                }
            }

            ImGuiUtil.HoverTooltip($"Open {address}");
        }
    // Draw a simple clipped table containing all changed items.
    private void DrawChangedItemTab()
    {
        // Functions in here for less pollution.
        bool FilterChangedItem(KeyValuePair <string, (SingleArray <IMod>, object?)> item)
        => (_changedItemFilter.IsEmpty ||
            ChangedItemName(item.Key, item.Value.Item2)
            .Contains(_changedItemFilter.Lower, StringComparison.InvariantCultureIgnoreCase)) &&
        (_changedItemModFilter.IsEmpty || item.Value.Item1.Any(m => m.Name.Contains(_changedItemModFilter)));

        void DrawChangedItemColumn(KeyValuePair <string, (SingleArray <IMod>, object?)> item)
        {
            ImGui.TableNextColumn();
            DrawChangedItem(item.Key, item.Value.Item2, false);
            ImGui.TableNextColumn();
            if (item.Value.Item1.Count > 0)
            {
                ImGui.TextUnformatted(item.Value.Item1[0].Name);
                if (item.Value.Item1.Count > 1)
                {
                    ImGuiUtil.HoverTooltip(string.Join("\n", item.Value.Item1.Skip(1).Select(m => m.Name)));
                }
            }

            ImGui.TableNextColumn();
            if (item.Value.Item2 is Item it)
            {
                using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
                ImGuiUtil.RightAlign($"({( ( Quad )it.ModelMain ).A})");
            }
        }

        using var tab = ImRaii.TabItem("Changed Items");
        if (!tab)
        {
            return;
        }

        // Draw filters.
        var varWidth = ImGui.GetContentRegionAvail().X
                       - 400 * ImGuiHelpers.GlobalScale
                       - ImGui.GetStyle().ItemSpacing.X;

        ImGui.SetNextItemWidth(400 * ImGuiHelpers.GlobalScale);
        LowerString.InputWithHint("##changedItemsFilter", "Filter Item...", ref _changedItemFilter, 128);
        ImGui.SameLine();
        ImGui.SetNextItemWidth(varWidth);
        LowerString.InputWithHint("##changedItemsModFilter", "Filter Mods...", ref _changedItemModFilter, 128);

        using var child = ImRaii.Child("##changedItemsChild", -Vector2.One);
        if (!child)
        {
            return;
        }

        // Draw table of changed items.
        var height = ImGui.GetTextLineHeightWithSpacing() + 2 * ImGui.GetStyle().CellPadding.Y;
        var skips  = ImGuiClip.GetNecessarySkips(height);

        using var list = ImRaii.Table("##changedItems", 3, ImGuiTableFlags.RowBg, -Vector2.One);
        if (!list)
        {
            return;
        }

        const ImGuiTableColumnFlags flags = ImGuiTableColumnFlags.NoResize | ImGuiTableColumnFlags.WidthFixed;

        ImGui.TableSetupColumn("items", flags, 400 * ImGuiHelpers.GlobalScale);
        ImGui.TableSetupColumn("mods", flags, varWidth - 100 * ImGuiHelpers.GlobalScale);
        ImGui.TableSetupColumn("id", flags, 100 * ImGuiHelpers.GlobalScale);

        var items = Penumbra.CollectionManager.Current.ChangedItems;
        var rest  = _changedItemFilter.IsEmpty && _changedItemModFilter.IsEmpty
            ? ImGuiClip.ClippedDraw(items, skips, DrawChangedItemColumn, items.Count)
            : ImGuiClip.FilteredClippedDraw(items, skips, FilterChangedItem, DrawChangedItemColumn);

        ImGuiClip.DrawEndDummy(rest, height);
    }