[patch] Record the Hexa vs ktsu widget verdict - #339
Merged
Merged
Conversation
CLAUDE.md said seven widget pairs "both survive on purpose until the comparison tab settles which to keep". The comparison tab shipped; the verdict never got written down. This writes it down. Five of the seven are not duplicates on inspection: - DividerContainer is a retained layout container owning a list of zones with per-zone draw callbacks, persisted sizes and nesting. A Splitter is one stateless drag handle over a ref float. The comparison tab cannot even show them side by side. - Tree is a ScopedAction that draws connector lines around nested content: no label, no collapsing, no ID stack. IconTreeNode is a real collapsible node requiring TreePop(). They compose rather than compete, which is why TreeTests already drives both in one class. - RadialProgressBar / SkeletonLoader / BufferingBar / Spinner are four different widgets, not two pairs. - Alignment.Center builds a container of (ContentRegionAvail.X, contentSize.Y), so its vertical extent is the content's own height and vertical centring is a no-op. TextCentered is therefore equivalent to TextCenteredH alone; TextCenteredV/VH and TextCenteredWithin's ellipsis clipping have no counterpart on the other side. - ImageCentered returns a click where the Hexa three return void, and ImageCenteredWithin / ImageScaleTo are each unique to their side. Two are genuine, with a recommended survivor: - Switch over ToggleSwitch: same signature, but Switch marks itself for probes, animates from ImGui's own delta time rather than Hexa's clock (so it needs none of the TickAnimationClockIfUnpumped machinery), and draws its own label. - Combo over EnumCombo on the enum overload, unless Hexa's display-name handling is wanted -- Combo shows raw Enum.GetNames and marks itself, EnumCombo routes through ComboEnumHelper and does not. The through-line is that only the ktsu originals call ImGuiProbes.MarkItem, so every Hexa-backed widget must be marked by the test itself or reached by geometry. SwitchTests and ComboTests need no Mark call; every Hexa-backed suite does. Nothing is obsoleted here. Retiring public API is a breaking change and that call belongs to the maintainer; this records what the decision is between. Refs #338 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DTHNXgSNEHUSQ5KMLgivno
|
This was referenced Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Refs #338.
CLAUDE.mdsaid seven widget pairs "both survive on purpose until the comparison tab settles which to keep". The comparison tab shipped in #337; the verdict never got written down. This writes it down, and changes no widget code.Nothing is obsoleted here. Retiring public API is a breaking change and that call is yours — this records what the decision is actually between, so it can be made on facts rather than on the pair list.
Five of the seven are not duplicates
DividerContainervsHorizontalSplitter/VerticalSplitterDividerZones with per-zone draw callbacks, persisted sizes (GetSizes/SetSizesFromList), anonResizedcallback and nesting — versus one stateless drag handle mutating aref float. The comparison tab can't even show them side by side; its splitter row points at the Advanced Demos tab for the container.TreevsIconTreeNodeTreeis aScopedActiondrawing connector lines around nested content: no label, no collapsing, no ID-stack interaction.IconTreeNodeis a real collapsible node with an icon glyph and flags, and the caller mustTreePop(). They compose rather than compete — which is whyTreeTestsalready drives both in one class.RadialProgressBar/SkeletonLoadervsBufferingBar/SpinnerRadialCountdown/RadialCountUp), determinate linear, indeterminate spinner, shimmering placeholder. The only overlap is "determinate progress", where radial vs linear is a visual choice.TextCenteredvsTextCenteredV/H/VHAlignment.Centerbuilds a container of(ContentRegionAvail.X, contentSize.Y)— its vertical extent is the content's own height, so vertical centring is a no-op andTextCenteredis horizontal-only. It equalsTextCenteredHand nothing else.TextCenteredV/VHhave no ktsu counterpart;TextCenteredWithin(text, size, clip)with ellipsis clipping has no Hexa counterpart.ImageCenteredvsImageCenteredV/H/VHImageCenteredreturnsboolfor a click, the Hexa three returnvoid.ImageCenteredWithinandImageScaleToare each unique to their side.Two are genuine
SwitchvsToggleSwitch— identical signature. Three differences, all favouringSwitch: it callsImGuiProbes.MarkItem; it animates fromImGui.GetIO().DeltaTimerather than Hexa's clock, so it needs none of theTickAnimationClockIfUnpumpedmachineryToggleSwitchrequires to avoid rendering inverted after its first click in a pumpless app; and it draws the visible label itself.CombovsEnumCombo— onlyCombo<TEnum>overlaps; theISemanticStringandstringcollection overloads are unique. The enum overloads differ in naming (rawEnum.GetNamesvs Hexa'sComboEnumHelper<T>.GetName, which is where a display-name override would come from), probe marking, and constraint (where TEnum : Enumvswhere T : struct, Enum). If nothing depends on Hexa's naming,EnumCombois the one to retire.The through-line
Only the ktsu originals are probe-visible.
SwitchandComboare the only two widgets in either family that callImGuiProbes.MarkItem—SwitchTestsandComboTestsneed zeroMarkcalls, while every Hexa-backed suite marks the widget itself or reaches it by geometry. That is the most consequential difference between the two families and a reason to prefer a ktsu original in an app you intend to UI-test.Changes
CLAUDE.md: replaces the "both survive on purpose" sentence with a link to a new Hexa-backed vs ktsu widgets section carrying the table above.examples/ImGuiWidgetsDemo/HexaWidgetsDemo.cs: one line at the top of the comparison tab noting that most rows are not duplicates, pointing at that section.Verification
dotnet buildclean, 0 warnings.ImGuiWidgetsDemo.UITestsreports 12 of 28 failing both with and without this change — identical counts, so nothing here moved them. The root cause is environmental rather than a defect:examples/ImGuiWidgetsDemo/ktsu.pngis a Git LFS pointer, git-lfs is not installed in this sandbox, so it was never smudged and ImageSharp fails to decode it (UnknownImageFormatException, with PNG absent from the decoder list). Every failing test is one that reaches a tab loading that texture. CI has git-lfs, so this should not reproduce there.Generated by Claude Code