From d41cea00314c34eec7108e424393b9d21b1e5066 Mon Sep 17 00:00:00 2001 From: JonKazama-Hellion Date: Tue, 5 May 2026 14:28:24 +0200 Subject: [PATCH] fix(settings): card grid wraps correctly, detail view drops legacy tab list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SettingsOverview now wraps each card in BeginGroup/EndGroup so SameLine in the loop can wrap rows. The card content is drawn directly into the DrawList (icon, title, subtext) without cursor hopping that broke the flow. DrawDetail no longer renders the second-column tab list — the user has already picked a section from the overview, the redundant column made the detail view feel like the old vanilla settings layout. Section content now uses the full width. --- HellionChat/Ui/Settings.cs | 39 +++++++-------------------- HellionChat/Ui/SettingsOverview.cs | 43 ++++++++++++++---------------- 2 files changed, 30 insertions(+), 52 deletions(-) diff --git a/HellionChat/Ui/Settings.cs b/HellionChat/Ui/Settings.cs index 62cf690..2a61094 100755 --- a/HellionChat/Ui/Settings.cs +++ b/HellionChat/Ui/Settings.cs @@ -143,36 +143,17 @@ public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window ImGui.Separator(); ImGui.Spacing(); - // Tab-Liste + Content (wie vorher) - using (var table = ImRaii.Table("##chat2-settings-table", 2)) - { - if (table.Success) - { - ImGui.TableSetupColumn("tab", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("settings", ImGuiTableColumnFlags.WidthStretch); + // Section-Content in voller Breite. Die Tab-Liste links ist überholt: + // der User ist bereits über die Card-Übersicht navigiert, eine zweite + // Tab-Liste daneben würde nur den Vanilla-Look zurückbringen. Falls + // der User in eine andere Section will, geht er zurück zur Overview + // (Breadcrumb / ESC). + var style = ImGui.GetStyle(); + var height = ImGui.GetContentRegionAvail().Y - style.FramePadding.Y * 2 - style.ItemSpacing.Y - style.ItemInnerSpacing.Y * 2 - ImGui.CalcTextSize("A").Y; - ImGui.TableNextColumn(); - - var changed = false; - for (var i = 0; i < Tabs.Count; i++) - { - if (!ImGui.Selectable($"{Tabs[i].Name}###tab-{i}", CurrentTab == i)) - continue; - - CurrentTab = i; - changed = true; - } - - ImGui.TableNextColumn(); - - var style = ImGui.GetStyle(); - var height = ImGui.GetContentRegionAvail().Y - style.FramePadding.Y * 2 - style.ItemSpacing.Y - style.ItemInnerSpacing.Y * 2 - ImGui.CalcTextSize("A").Y; - - using var child = ImRaii.Child("##chat2-settings", new Vector2(-1, height)); - if (child.Success) - Tabs[CurrentTab].Draw(changed); - } - } + using var child = ImRaii.Child("##chat2-settings-detail", new Vector2(-1, height)); + if (child.Success) + Tabs[CurrentTab].Draw(false); } private void DrawSaveButtons() diff --git a/HellionChat/Ui/SettingsOverview.cs b/HellionChat/Ui/SettingsOverview.cs index 9837b53..b0f8a96 100644 --- a/HellionChat/Ui/SettingsOverview.cs +++ b/HellionChat/Ui/SettingsOverview.cs @@ -52,6 +52,11 @@ internal sealed class SettingsOverview private void DrawCard(int index, FontAwesomeIcon icon, string title, string subtext, float w, float h) { + // BeginGroup macht den Card-Bereich zu einem einzelnen ImGui-Layout-Item. + // Damit funktioniert SameLine() im Caller-Loop — sonst tracked ImGui die + // einzelnen InvisibleButton/Text-Items separat und das Wrapping bricht. + ImGui.BeginGroup(); + var cursorBefore = ImGui.GetCursorScreenPos(); var clicked = ImGui.InvisibleButton($"##settings-card-{index}", new Vector2(w, h)); var hovered = ImGui.IsItemHovered(); @@ -60,35 +65,27 @@ internal sealed class SettingsOverview var draw = ImGui.GetWindowDrawList(); draw.AddRectFilled(cursorBefore, cursorBefore + new Vector2(w, h), bgColor, 4f); - // ImGui hat den Cursor nach dem InvisibleButton bereits korrekt - // weitergesetzt (für die Layout-Engine). Wir merken uns die Position, - // verschieben den Cursor temporär für die Inhalts-Beschriftung und - // restoren ihn am Ende — sonst kollidieren manuelle Cursor-Sets mit - // SameLine im Caller und die Cards stapeln sich diagonal. - var cursorAfterButton = ImGui.GetCursorScreenPos(); + // Inhalts-Overlay: Icon + Title + Subtext direkt mit DrawList in den + // Card-Bereich zeichnen, statt Cursor-Hopping mit SetCursorScreenPos. + // DrawList-Overlays ändern den Cursor nicht, BeginGroup/EndGroup + // hält den Layout-Anker stabil für SameLine. + var iconPos = cursorBefore + new Vector2(16f, 12f); + var titlePos = cursorBefore + new Vector2(16f, 40f); + var subtextPos = cursorBefore + new Vector2(16f, 62f); - 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). + var titleColor = ColourUtil.RgbaToAbgr(0xE6F4F1FFu); + var subtextColor = ColourUtil.RgbaToAbgr(0x8FA3B5FFu); + + // Icon via FontAwesome — temporär den Font pushen, mit DrawList zeichnen using (_window.Plugin.FontManager.FontAwesome.Push()) { - ImGui.Text(icon.ToIconString()); + draw.AddText(iconPos, titleColor, icon.ToIconString()); } - ImGui.SetCursorScreenPos(textPos + new Vector2(0f, 28f)); - ImGui.TextUnformatted(title); + draw.AddText(titlePos, titleColor, title); + draw.AddText(subtextPos, subtextColor, subtext); - ImGui.SetCursorScreenPos(textPos + new Vector2(0f, 50f)); - using (ImRaii.PushColor(ImGuiCol.Text, 0xFF8FA3B5u)) - { - ImGui.TextUnformatted(subtext); - } - - // Restore cursor to post-button position, so SameLine + Wrap im Caller - // wieder mit dem ImGui-Layout-Flow arbeiten. - ImGui.SetCursorScreenPos(cursorAfterButton); + ImGui.EndGroup(); if (clicked) {