Skip to content

[minor] Add SwatchPalette, a selectable, drag-reorderable grid of colour swatches - #571

Merged
matt-edmondson merged 4 commits into
mainfrom
widget/stack-swatch
Sep 30, 2026
Merged

matt-edmondson merged 4 commits into
mainfrom
widget/stack-swatch

Conversation

@matt-edmondson

@matt-edmondson matt-edmondson commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Matt · project thread

Before: ktsu.ImGui.Widgets had no palette widget. A host that wanted a pickable, reorderable set of colours had to lay out and hit-test swatches itself.

After: ImGuiWidgets.SwatchPalette draws a wrapping grid of swatches over a caller-owned IList<Color>. Clicking a swatch selects it. Dragging one reorders the list in place, and the selection follows the swatch it pointed at. Adding, removing and editing colours stay with the host.

How: SwatchPaletteState holds the layout, hit-testing, drop slot, move and drag tracking, and has no ImGui dependency. The grid and each swatch are probe-marked. This adds a demo section, an isolation suite, a gallery tile, and entries in the image and colour docs group.

Stacked PR. #570 (GradientEditor) has merged, so this now targets main and is the next one to merge. Merge order: this → ImageCompare (#572) → CropOverlay (#573) → PixelLoupe (#574).

Validation, Release build: the solution builds clean, ImGuiWidgetsDemo.UITests passes 44/44, ImGui.Widgets.UITests passes 900/900, and WidgetGallery --check passes.

Closes #530

🤖 Generated with Claude Code

https://claude.ai/code/session_01LXUsRiHnKs6HCgLAbC1L6D

…our swatches

A wrapping grid of swatches over a caller-owned IList<Color>. Clicking a
swatch selects it; dragging one reorders the list in place, with the
selection following the swatch it named. Adding, removing and editing
colours stays with the host. The layout, hit-testing, drop slot, move and
drag tracking live in SwatchPaletteState with no ImGui dependency.

The grid and each swatch are probe-marked. Adds a demo section, an
isolation suite, a gallery tile and the image and colour docs entries.

Closes #530

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LXUsRiHnKs6HCgLAbC1L6D
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HgjMCJ9MQRmUk6c8KABDYH
SonarCloud's S2184 flags int.MinValue / 2 and int.MaxValue / 2 passed where
floats are expected, since an integer division feeding a float usually means
a lost fraction. Nothing was lost here, but a named float bound says what the
clamp is for: keeping the cast back to int from overflowing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LXUsRiHnKs6HCgLAbC1L6D
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Domain widgets Tier 3: add SwatchPalette (colour swatch grid with drag-reorder)

2 participants