feat(settings): card-grid overview router

This commit is contained in:
2026-05-05 14:02:13 +02:00
parent dd3a0ea069
commit cb5c940a84
2 changed files with 129 additions and 3 deletions
+39 -3
View File
@@ -9,13 +9,21 @@ using Dalamud.Bindings.ImGui;
namespace HellionChat.Ui; namespace HellionChat.Ui;
internal enum SettingsView
{
Overview,
Detail,
}
public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window
{ {
private readonly Plugin Plugin; internal readonly Plugin Plugin;
private Configuration Mutable { get; } private Configuration Mutable { get; }
private List<ISettingsTab> Tabs { get; } private List<ISettingsTab> Tabs { get; }
private int CurrentTab; 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") 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; Plugin = plugin;
Mutable = new Configuration(); Mutable = new Configuration();
Overview = new SettingsOverview(this);
Tabs = Tabs =
[ [
new General(Plugin, Mutable), new General(Plugin, Mutable),
@@ -72,8 +82,33 @@ public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window
public override void Draw() public override void Draw()
{ {
if (ImGui.IsWindowAppearing()) if (ImGui.IsWindowAppearing())
{
Initialise(); 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)) using (var table = ImRaii.Table("##chat2-settings-table", 2))
{ {
if (table.Success) if (table.Success)
@@ -103,9 +138,10 @@ public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window
Tabs[CurrentTab].Draw(changed); Tabs[CurrentTab].Draw(changed);
} }
} }
}
ImGui.Separator(); private void DrawSaveButtons()
{
var save = ImGui.Button(Language.Settings_Save); var save = ImGui.Button(Language.Settings_Save);
ImGui.SameLine(); ImGui.SameLine();
+90
View File
@@ -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);
}
}
}