diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs index 7800315..30b5c10 100644 --- a/HellionChat/Ui/ChatLogWindow.cs +++ b/HellionChat/Ui/ChatLogWindow.cs @@ -472,6 +472,107 @@ public sealed class ChatLogWindow : Window ChangeTab(newIndex); } + // PM-2b v1.5.4 header quick-picker. Two scrollable sections -- every + // built-in plus custom theme, and every tab. Clicking a theme arms + // the PM-1 crossfade via ThemeRegistry.Switch; clicking a tab routes + // through ChangeTab so LastActivityTime stays consistent with the + // sidebar and top-bar click paths. DontClosePopups keeps the popup + // open so the user can hop between entries without re-opening it. + private void DrawQuickPickerPopup() + { + using var popup = ImRaii.Popup("##hellion-quick-picker"); + if (!popup.Success) + return; + + ImGui.TextUnformatted(HellionStrings.Settings_QuickPicker_Themes_Header); + ImGui.Separator(); + + var activeSlug = Plugin.ThemeRegistry.Active.Slug; + var allThemes = Plugin + .ThemeRegistry.AllBuiltIns() + .Concat(Plugin.ThemeRegistry.AllCustom()) + .ToList(); + + using ( + var scroll = ImRaii.Child( + "##hellion-quick-picker-themes", + new Vector2(220f, Math.Min(allThemes.Count * 22f, 200f)) + ) + ) + { + if (scroll.Success) + { + foreach (var theme in allThemes) + { + var isActive = string.Equals( + theme.Slug, + activeSlug, + StringComparison.OrdinalIgnoreCase + ); + DrawQuickPickerGlyph(isActive); + if ( + ImGui.Selectable( + $"{theme.Name}##quick-theme-{theme.Slug}", + isActive, + ImGuiSelectableFlags.DontClosePopups + ) + && !isActive + ) + Plugin.ThemeRegistry.Switch(theme.Slug); + } + } + } + + ImGui.Spacing(); + ImGui.TextUnformatted(HellionStrings.Settings_QuickPicker_Tabs_Header); + ImGui.Separator(); + + var tabs = Plugin.Config.Tabs; + var activeTabIndex = Plugin.LastTab; + using ( + var scroll = ImRaii.Child( + "##hellion-quick-picker-tabs", + new Vector2(220f, Math.Min(tabs.Count * 22f, 200f)) + ) + ) + { + if (scroll.Success) + { + for (var i = 0; i < tabs.Count; i++) + { + var isActive = i == activeTabIndex; + DrawQuickPickerGlyph(isActive); + if ( + ImGui.Selectable( + $"{tabs[i].Name}##quick-tab-{i}", + isActive, + ImGuiSelectableFlags.DontClosePopups + ) + && !isActive + ) + ChangeTab(i); + } + } + } + } + + // Leading check-glyph slot for a quick-picker row. Active rows get a + // FontAwesome check; inactive rows get a same-width blank so the + // labels stay aligned. The glyph font push stays on its own line so + // it never bleeds into the body-font Selectable label. + private void DrawQuickPickerGlyph(bool isActive) + { + using (Plugin.FontManager.FontAwesome.Push()) + { + var check = FontAwesomeIcon.Check.ToIconString(); + if (isActive) + ImGui.TextUnformatted(check); + else + ImGui.Dummy(new Vector2(ImGui.CalcTextSize(check).X, ImGui.GetTextLineHeight())); + } + ImGui.SameLine(); + } + private void TabSwitched(Tab newTab, Tab previousTab) { // Use the fixed channel if set by the user. Otherwise, if the new tab @@ -903,7 +1004,15 @@ public sealed class ChatLogWindow : Window var buttonWidth = afterIcon.X - beforeIcon.X; var showNovice = Plugin.Config.ShowNoviceNetwork && GameFunctions.GameFunctions.IsMentor(); var buttonsRight = (showNovice ? 1 : 0) + (Plugin.Config.ShowHideButton ? 1 : 0); - var inputWidth = ImGui.GetContentRegionAvail().X - buttonWidth * (1 + buttonsRight); + // Right-side buttons: quick-picker palette + cog (always present) + // plus the optional hide / novice buttons. Each slot costs the + // measured button width AND one ItemSpacing for the SameLine gap + // in front of it -- leaving the spacing term out overflows the + // header row by one gap per button (v1.5.4 quick-picker fix). + var rightButtonCount = 2 + buttonsRight; + var inputWidth = + ImGui.GetContentRegionAvail().X + - rightButtonCount * (buttonWidth + ImGui.GetStyle().ItemSpacing.X); var normalColor = ImGui.GetColorU32(ImGuiCol.Text); var push = inputColour != null; @@ -1013,6 +1122,19 @@ public sealed class ChatLogWindow : Window ImGui.SameLine(); + if ( + ImGuiUtil.IconButton( + FontAwesomeIcon.Palette, + tooltip: HellionStrings.Settings_QuickPicker_Tooltip, + width: (int)buttonWidth + ) + ) + ImGui.OpenPopup("##hellion-quick-picker"); + + DrawQuickPickerPopup(); + + ImGui.SameLine(); + if (ImGuiUtil.IconButton(FontAwesomeIcon.Cog, width: (int)buttonWidth)) Plugin.SettingsWindow.Toggle();