diff --git a/HellionChat/Ui/Settings.cs b/HellionChat/Ui/Settings.cs index 6abf6a6..538fc9f 100755 --- a/HellionChat/Ui/Settings.cs +++ b/HellionChat/Ui/Settings.cs @@ -9,13 +9,21 @@ using Dalamud.Bindings.ImGui; namespace HellionChat.Ui; +internal enum SettingsView +{ + Overview, + Detail, +} + public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window { - private readonly Plugin Plugin; + internal readonly Plugin Plugin; private Configuration Mutable { get; } private List Tabs { get; } private int CurrentTab; + private SettingsView View = SettingsView.Overview; + private readonly SettingsOverview Overview; internal SettingsWindow(Plugin plugin) : base($"{Language.Settings_Title.Format(Plugin.PluginName)}###chat2-settings") { @@ -31,6 +39,8 @@ public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window Plugin = plugin; Mutable = new Configuration(); + Overview = new SettingsOverview(this); + Tabs = [ new General(Plugin, Mutable), @@ -72,8 +82,33 @@ public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window public override void Draw() { if (ImGui.IsWindowAppearing()) + { Initialise(); + View = SettingsView.Overview; + } + if (View == SettingsView.Overview) + Overview.Draw(); + else + DrawDetail(); + + ImGui.Separator(); + DrawSaveButtons(); + } + + internal void OpenSection(int tabIndex) + { + CurrentTab = tabIndex; + View = SettingsView.Detail; + } + + internal void OpenOverview() + { + View = SettingsView.Overview; + } + + private void DrawDetail() + { using (var table = ImRaii.Table("##chat2-settings-table", 2)) { if (table.Success) @@ -103,9 +138,10 @@ public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window Tabs[CurrentTab].Draw(changed); } } + } - ImGui.Separator(); - + private void DrawSaveButtons() + { var save = ImGui.Button(Language.Settings_Save); ImGui.SameLine(); diff --git a/HellionChat/Ui/SettingsOverview.cs b/HellionChat/Ui/SettingsOverview.cs new file mode 100644 index 0000000..0574021 --- /dev/null +++ b/HellionChat/Ui/SettingsOverview.cs @@ -0,0 +1,90 @@ +using System.Numerics; +using Dalamud.Bindings.ImGui; +using Dalamud.Interface; +using Dalamud.Interface.Utility.Raii; +using HellionChat.Resources; +using HellionChat.Util; + +namespace HellionChat.Ui; + +internal sealed class SettingsOverview +{ + private readonly SettingsWindow _window; + + // Card-Reihenfolge entspricht 1:1 dem Tabs-Index in SettingsWindow. + // Themes (Phase J) wird später als Card 2 zwischen Appearance und Window + // eingeschoben — dabei muss diese Liste neu gemappt werden. + private static readonly (FontAwesomeIcon Icon, string TitleKey, string SubtextKey)[] CardDefs = + [ + (FontAwesomeIcon.SlidersH, "Settings_Card_General_Title", "Settings_Card_General_Subtext"), + (FontAwesomeIcon.Palette, "Settings_Card_Appearance_Title", "Settings_Card_Appearance_Subtext"), + (FontAwesomeIcon.WindowMaximize, "Settings_Card_Window_Title", "Settings_Card_Window_Subtext"), + (FontAwesomeIcon.Comments, "Settings_Card_Chat_Title", "Settings_Card_Chat_Subtext"), + (FontAwesomeIcon.FolderTree, "Settings_Card_Tabs_Title", "Settings_Card_Tabs_Subtext"), + (FontAwesomeIcon.ShieldAlt, "Settings_Card_Privacy_Title", "Settings_Card_Privacy_Subtext"), + (FontAwesomeIcon.Database, "Settings_Card_Database_Title", "Settings_Card_Database_Subtext"), + (FontAwesomeIcon.InfoCircle, "Settings_Card_Information_Title", "Settings_Card_Information_Subtext"), + ]; + + public SettingsOverview(SettingsWindow window) + { + _window = window; + } + + public void Draw() + { + var avail = ImGui.GetContentRegionAvail(); + var columns = avail.X >= 700f ? 3 : 2; + var cardWidth = (avail.X - (columns - 1) * 8f) / columns; + var cardHeight = 96f; + + for (var i = 0; i < CardDefs.Length; i++) + { + var (icon, titleKey, subtextKey) = CardDefs[i]; + var title = HellionStrings.ResourceManager.GetString(titleKey) ?? titleKey; + var subtext = HellionStrings.ResourceManager.GetString(subtextKey) ?? subtextKey; + DrawCard(i, icon, title, subtext, cardWidth, cardHeight); + + if ((i + 1) % columns != 0 && i != CardDefs.Length - 1) + ImGui.SameLine(); + } + } + + private void DrawCard(int index, FontAwesomeIcon icon, string title, string subtext, float w, float h) + { + var cursorBefore = ImGui.GetCursorScreenPos(); + var clicked = ImGui.InvisibleButton($"##settings-card-{index}", new Vector2(w, h)); + var hovered = ImGui.IsItemHovered(); + var bgColor = hovered ? 0xFF22303Fu : 0xFF1A2538u; + + var draw = ImGui.GetWindowDrawList(); + draw.AddRectFilled(cursorBefore, cursorBefore + new Vector2(w, h), bgColor, 4f); + + var textPos = cursorBefore + new Vector2(16f, 12f); + ImGui.SetCursorScreenPos(textPos); + // Plugin ist hier Instanz, nicht Static-Type — daher über _window + // referenzieren (Codebase-Konvention, siehe ImGuiUtil.cs:22 für die + // alternative Static-Init-Pattern, das wir hier nicht nutzen). + using (_window.Plugin.FontManager.FontAwesome.Push()) + { + ImGui.Text(icon.ToIconString()); + } + + ImGui.SetCursorScreenPos(textPos + new Vector2(0f, 28f)); + ImGui.TextUnformatted(title); + + ImGui.SetCursorScreenPos(textPos + new Vector2(0f, 50f)); + using (ImRaii.PushColor(ImGuiCol.Text, 0xFF8FA3B5u)) + { + ImGui.TextUnformatted(subtext); + } + + // Cursor unter die Card setzen für nächsten Item-Pass + ImGui.SetCursorScreenPos(cursorBefore + new Vector2(0f, h + 8f)); + + if (clicked) + { + _window.OpenSection(index); + } + } +}