feat(style): add the setting-row and toggle-switch widgets
Two composites for the settings window, both built on the primitives from v1.10.0 rather than beside them. SettingRow puts the label left and the control right-aligned. ImGui does it the other way round, control first and label trailing, which is a large part of why the settings window reads as a form dump rather than a settings page. The control arrives as a callback so one row covers toggles, sliders, combos and buttons. The cursor advance in SettingRow is the part that needed care. It has to happen after the callback, because ItemSize overwrites CursorPos outright when the control is submitted -- advancing first would simply be undone. But it must not be an ImGui.Dummy: that submits an item and would replace the control as g.LastItemData, silently disabling every IsItemDeactivatedAfterEdit save throttle in the window. SetCursorScreenPos moves the cursor without touching last-item state. ToggleSwitch is a capsule with a gliding knob, driven by HoverState so it animates instead of snapping. Unlike a slider there is no throttle to preserve: a checkbox commits on the click itself. The caller owns the hit area, so a settings row can make the whole row clickable, label included. Named ToggleSwitch, not Toggle: Dalamud's Window base class already has a Toggle() method, and the plain name collides in every window that uses the widget. Geometry lives in WidgetGeometry as usual, with nine new cases pinning the right-alignment split, the narrow-row fallback (the label yields before the control does), and that the knob stays inside its capsule at both ends. ColourUtil gains a two-colour Lerp for the track crossfade.
This commit is contained in:
@@ -24,6 +24,8 @@ internal sealed class WidgetGalleryWindow : Window
|
||||
|
||||
private int _badgeCount = 3;
|
||||
private bool _rowActive = true;
|
||||
private bool _toggleA = true;
|
||||
private bool _toggleB;
|
||||
|
||||
internal WidgetGalleryWindow(Plugin plugin, TokenResolver resolver)
|
||||
: base("Widget Gallery###hellion-widget-gallery")
|
||||
@@ -44,6 +46,8 @@ internal sealed class WidgetGalleryWindow : Window
|
||||
ImGui.Separator();
|
||||
|
||||
DrawRowSection(c);
|
||||
DrawToggleSection(c);
|
||||
DrawSettingRowSection(c);
|
||||
DrawBadgeSection(c);
|
||||
DrawPillSection(c);
|
||||
DrawIconButtonSection(c);
|
||||
@@ -97,6 +101,79 @@ internal sealed class WidgetGalleryWindow : Window
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
private void DrawToggleSection(ThemeColors c)
|
||||
{
|
||||
ImGui.TextUnformatted("Toggle");
|
||||
|
||||
var colors = new ToggleSwitchColors
|
||||
{
|
||||
TrackOffAbgr = _palette.Abgr(Token.SurfaceRaised, c),
|
||||
TrackOnAbgr = _palette.Abgr(Token.AccentPrimary, c),
|
||||
KnobAbgr = _palette.Abgr(Token.Text, c),
|
||||
};
|
||||
|
||||
var size = ToggleSwitch.CalcSize();
|
||||
var gap = 10f * Metrics.Scale;
|
||||
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var origin = ImGui.GetCursorScreenPos();
|
||||
var id = ImGui.GetID($"gallery.toggle.{i}");
|
||||
if (ImGui.InvisibleButton($"##gallery-toggle-{i}", size))
|
||||
{
|
||||
if (i == 0)
|
||||
_toggleA = !_toggleA;
|
||||
else
|
||||
_toggleB = !_toggleB;
|
||||
}
|
||||
|
||||
ToggleSwitch.Draw(id, origin, i == 0 ? _toggleA : _toggleB, colors);
|
||||
if (i == 0)
|
||||
ImGui.SameLine(0f, gap);
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
private void DrawSettingRowSection(ThemeColors c)
|
||||
{
|
||||
ImGui.TextUnformatted("SettingRow");
|
||||
|
||||
var colors = new SettingRowColors
|
||||
{
|
||||
LabelAbgr = _palette.Abgr(Token.Text, c),
|
||||
DescriptionAbgr = _palette.Abgr(Token.TextMuted, c),
|
||||
SurfaceHoverAbgr = _palette.Abgr(Token.SurfaceHover, c),
|
||||
BorderAbgr = _palette.Abgr(Token.Border, c),
|
||||
};
|
||||
|
||||
SettingRow.Draw(
|
||||
ImGui.GetID("gallery.settingrow.plain"),
|
||||
"A plain option",
|
||||
null,
|
||||
colors,
|
||||
() => ImGui.Checkbox("##gallery-sr-a", ref _toggleA)
|
||||
);
|
||||
|
||||
SettingRow.Draw(
|
||||
ImGui.GetID("gallery.settingrow.described"),
|
||||
"With a description",
|
||||
"The second line explains what the control above actually does.",
|
||||
colors,
|
||||
() => ImGui.Checkbox("##gallery-sr-b", ref _toggleB)
|
||||
);
|
||||
|
||||
SettingRow.Draw(
|
||||
ImGui.GetID("gallery.settingrow.long"),
|
||||
"A deliberately very long label that has to be clipped somewhere",
|
||||
null,
|
||||
colors,
|
||||
() => ImGui.SliderInt("##gallery-sr-c", ref _badgeCount, 0, 150)
|
||||
);
|
||||
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
private void DrawBadgeSection(ThemeColors c)
|
||||
{
|
||||
ImGui.TextUnformatted("Badge");
|
||||
|
||||
Reference in New Issue
Block a user