feat(ui): add header quick-picker for themes and tabs
Palette button left of the cog opens a two-section popup. The themes section enumerates AllBuiltIns + AllCustom; the tabs section enumerates Config.Tabs. The active entry gets a leading check-glyph, inactive rows a same-width blank so labels stay aligned. Click selects without closing the popup (DontClosePopups). Theme click triggers the PM-1 crossfade via ThemeRegistry.Switch; tab click routes through ChangeTab so LastActivityTime stays consistent with the sidebar and top-bar click paths. The header input-width reservation now counts the new button plus the per-button SameLine spacing -- the old formula dropped the spacing term and overflowed the row once a third button appeared.
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user