feat(style): let a setting row render disabled
Six settings across the window only apply while another one is on. Today they sit at full contrast and simply do nothing when clicked. BeginDisabled cannot carry this: it pushes an alpha that ImGui applies inside its own widgets, and every part of a setting row that a user reads -- label, description, separator, hover fill -- is draw-list output that never sees it. So the row fades itself, drops its click, and stops tracking hover. The flag is passed through to the control callback as well. A draw-list control handed into the row has exactly the same problem and no other way to learn about it. Note the parameter sits before styleOverride, so the one existing positional call site had to name its argument.
This commit is contained in:
@@ -34,6 +34,10 @@ internal readonly record struct SettingRowContext
|
||||
public float ControlHeight { get; init; }
|
||||
public float HoverAmount { get; init; }
|
||||
|
||||
// Passed through so a draw-list control can fade itself. BeginDisabled only
|
||||
// reaches ImGui's own widgets, so the row cannot dim its control for it.
|
||||
public bool Disabled { get; init; }
|
||||
|
||||
// Right edge of the control column, vertically centred.
|
||||
public Vector2 AlignRight(Vector2 size) =>
|
||||
new(
|
||||
@@ -56,10 +60,12 @@ internal static class SettingRow
|
||||
string? description,
|
||||
SettingRowColors colors,
|
||||
Action<SettingRowContext> drawControl,
|
||||
bool disabled = false,
|
||||
SettingRowStyle? styleOverride = null
|
||||
)
|
||||
{
|
||||
var style = styleOverride ?? new SettingRowStyle();
|
||||
var alpha = disabled ? 0.5f : 1f;
|
||||
var scale = Metrics.Scale;
|
||||
var padY = style.PadY * scale;
|
||||
var gap = style.Gap * scale;
|
||||
@@ -78,11 +84,13 @@ internal static class SettingRow
|
||||
// The label half is the hit area: the control column submits its own
|
||||
// item and would fight with a button underneath it.
|
||||
ImGui.SetCursorScreenPos(origin);
|
||||
var labelClicked = ImGui.InvisibleButton(
|
||||
$"##hellion-srow-{id}",
|
||||
new Vector2(labelWidth, size.Y)
|
||||
);
|
||||
var hovered = ImGui.IsMouseHoveringRect(origin, origin + size) && ImGui.IsWindowHovered();
|
||||
var labelClicked =
|
||||
ImGui.InvisibleButton($"##hellion-srow-{id}", new Vector2(labelWidth, size.Y))
|
||||
&& !disabled;
|
||||
var hovered =
|
||||
!disabled
|
||||
&& ImGui.IsMouseHoveringRect(origin, origin + size)
|
||||
&& ImGui.IsWindowHovered();
|
||||
var hoverAmount = HoverState.Query(id, hovered);
|
||||
|
||||
// Chrome first, all of it draw-list only: nothing between here and the
|
||||
@@ -98,7 +106,7 @@ internal static class SettingRow
|
||||
SurfaceHoverAbgr = colors.SurfaceHoverAbgr,
|
||||
SurfaceActiveAbgr = colors.SurfaceHoverAbgr,
|
||||
AccentAbgr = colors.BorderAbgr,
|
||||
BorderAbgr = colors.BorderAbgr,
|
||||
BorderAbgr = ColourUtil.ApplyAlpha(colors.BorderAbgr, alpha),
|
||||
},
|
||||
new RowStyle { AccentBarWidth = 0f, DrawSeparator = style.DrawSeparator }
|
||||
);
|
||||
@@ -107,13 +115,17 @@ internal static class SettingRow
|
||||
// control. The description wraps instead of being cut.
|
||||
var dl = ImGui.GetWindowDrawList();
|
||||
dl.PushClipRect(origin, new Vector2(origin.X + labelWidth, origin.Y + size.Y), true);
|
||||
dl.AddText(new Vector2(origin.X, origin.Y + padY), colors.LabelAbgr, label);
|
||||
dl.AddText(
|
||||
new Vector2(origin.X, origin.Y + padY),
|
||||
ColourUtil.ApplyAlpha(colors.LabelAbgr, alpha),
|
||||
label
|
||||
);
|
||||
if (description is not null)
|
||||
dl.AddText(
|
||||
ImGui.GetFont(),
|
||||
ImGui.GetFontSize(),
|
||||
new Vector2(origin.X, origin.Y + padY + lineHeight),
|
||||
colors.DescriptionAbgr,
|
||||
ColourUtil.ApplyAlpha(colors.DescriptionAbgr, alpha),
|
||||
description,
|
||||
labelWidth
|
||||
);
|
||||
@@ -129,6 +141,7 @@ internal static class SettingRow
|
||||
ControlWidth = controlWidth,
|
||||
ControlHeight = lineHeight,
|
||||
HoverAmount = hoverAmount,
|
||||
Disabled = disabled,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ internal sealed class WidgetGalleryWindow : Window
|
||||
DrawSectionHeaderSection(c);
|
||||
DrawRowSection(c);
|
||||
DrawToggleSection(c);
|
||||
DrawSegmentedSection(c);
|
||||
DrawSettingRowSection(c);
|
||||
DrawBadgeSection(c);
|
||||
DrawPillSection(c);
|
||||
@@ -250,9 +251,84 @@ internal sealed class WidgetGalleryWindow : Window
|
||||
null,
|
||||
colors,
|
||||
_ => ImGui.SliderInt("##gallery-sr-d", ref _badgeCount, 0, 150),
|
||||
new SettingRowStyle { DrawSeparator = false, PreferredControlWidth = 90f }
|
||||
styleOverride: new SettingRowStyle
|
||||
{
|
||||
DrawSeparator = false,
|
||||
PreferredControlWidth = 90f,
|
||||
}
|
||||
);
|
||||
|
||||
// Disabled: the label fades, the row stops lighting up, and the click
|
||||
// does not reach the setting.
|
||||
using (ImRaii.Disabled())
|
||||
{
|
||||
SettingRow.Draw(
|
||||
ImGui.GetID("gallery.settingrow.disabled"),
|
||||
"Disabled row",
|
||||
"Neither the row nor its control may respond.",
|
||||
colors,
|
||||
_ => ImGui.SliderInt("##gallery-sr-e", ref _badgeCount, 0, 150),
|
||||
disabled: true
|
||||
);
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
// Segment labels are held rather than built per frame: a collection
|
||||
// expression in the draw call would allocate a fresh array every frame.
|
||||
private static readonly string[] SegmentLabelsTwo = ["Sidebar", "Top tabs"];
|
||||
private static readonly string[] SegmentLabelsThree = ["Off", "Compact", "Full"];
|
||||
private int _segmentTwo;
|
||||
private int _segmentThree = 1;
|
||||
|
||||
private void DrawSegmentedSection(ThemeColors c)
|
||||
{
|
||||
var colors = new SegmentedControlColors
|
||||
{
|
||||
TrackAbgr = _palette.Abgr(Token.SurfaceBase, c),
|
||||
SelectedAbgr = _palette.Abgr(Token.AccentPrimary, c),
|
||||
HoverAbgr = _palette.Abgr(Token.SurfaceHover, c),
|
||||
LabelAbgr = _palette.Abgr(Token.TextMuted, c),
|
||||
SelectedLabelAbgr = _palette.Abgr(Token.Text, c),
|
||||
BorderAbgr = _palette.Abgr(Token.Border, c),
|
||||
};
|
||||
|
||||
var width = MathF.Min(260f * Metrics.Scale, ImGui.GetContentRegionAvail().X);
|
||||
|
||||
_segmentTwo = SegmentedControl.Draw(
|
||||
ImGui.GetID("gallery.segmented.two"),
|
||||
ImGui.GetCursorScreenPos(),
|
||||
width,
|
||||
SegmentLabelsTwo,
|
||||
_segmentTwo,
|
||||
colors
|
||||
);
|
||||
ImGui.Dummy(SegmentedControl.CalcSize(width));
|
||||
|
||||
_segmentThree = SegmentedControl.Draw(
|
||||
ImGui.GetID("gallery.segmented.three"),
|
||||
ImGui.GetCursorScreenPos(),
|
||||
width,
|
||||
SegmentLabelsThree,
|
||||
_segmentThree,
|
||||
colors
|
||||
);
|
||||
ImGui.Dummy(SegmentedControl.CalcSize(width));
|
||||
|
||||
// Odd width over three segments: the edges must stay flush with no seam
|
||||
// and no overhang on the right.
|
||||
SegmentedControl.Draw(
|
||||
ImGui.GetID("gallery.segmented.odd"),
|
||||
ImGui.GetCursorScreenPos(),
|
||||
201f,
|
||||
SegmentLabelsThree,
|
||||
0,
|
||||
colors,
|
||||
disabled: true
|
||||
);
|
||||
ImGui.Dummy(SegmentedControl.CalcSize(201f));
|
||||
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user