Skip to content

feat(donut): mark group slices with an outward chevron - #1111

Merged
KnifeLemon merged 1 commit into
KnifeLemon:mainfrom
lightscape-jm:feat/donut-group-chevron
Nov 4, 2026
Merged

KnifeLemon merged 1 commit into
KnifeLemon:mainfrom
lightscape-jm:feat/donut-group-chevron

Conversation

@lightscape-jm

Copy link
Copy Markdown
Contributor

What does this change?

Closes #868, the first of the donut visuals chain planned in #856. A group slice now has a small chevron by its outer edge, pointing to where its ring fans out, so a group can be told from a preset at a glance, in any language, even where "Group of N" has no room. No setting, and no new strings.

  • On group slices only, by the outer edge, pointing away from the centre. It's drawn in the slice's own transform, so it opens, pops out, flips and collapses into the progress ring with its slice.
  • Colours: the secondary text colour, the highlight's text colour when the slice is lit, half strength when the group is disabled. It follows the theme and custom themes.
  • Size follows the donut: it scales with Settings → Donut toolbar → Size (OuterRadius).
  • The name moves in by 3 px at the default size, so it clears the chevron on the top and bottom slices. Its size, wrapping and whether "Group of N" shows stay as they were.
  • The Donut toolbar page marks groups too: its slices, and the translucent slice shown while dragging a group, from the donut or from the palette. DonutItem.Children = [] is the documented "group with nothing to fan out"; everything that fans a group out, or reserves room for its ring, already skips edit mode, so the preview's size doesn't change.

How it's built: DonutMenu.DrawSliceLabel draws a slice's text and mark. The ring, the old face during a flip, the collapse and the drop preview all use it, so they can't drift apart. SetDropPreview has a new optional group, fixed when the drag starts (DragState.IsGroup, PaletteChip.IsGroup), like CanAdd.

Known limit: the name moves in along the slice, so it clears the chevron at the top and bottom. On a side slice, a long name on a donut of 4 to 6 slices can still touch it. #870, next but one in the chain, keeps every label inside its slice and clear of the chevron, as that issue says.

Type of change

  • Bug fix
  • New feature or improvement
  • New format or engine
  • Translation
  • Documentation
  • Build, CI or dependencies

How was it tested?

  • dotnet format --verify-no-changes
  • dotnet test: on macOS, the App tests that fail do so on unmodified main too (the engine-page renders, and the flaky A_lost_animation_frame…). The Donut, Radial and Toolbar tests pass on Windows 11 ARM64. In an Ubuntu 24.04 container the whole App suite fails only the two UpdateAsync_on_linux… tests, which fail there on unmodified main too; after the last changes to the tests, the Donut, Radial and Toolbar tests pass there apart from BrowserDropTests.Other_text…, which also fails now and then on unmodified main on my Mac.
  • Tried it in the app (macOS, a build of this branch on current main, dark): the Images donut's front and back faces, Tab to flip, the Rotate group opened and lit, the chevron on its slice with the ring beside it; in Settings → Donut toolbar, the PDF donut's back face, the Edit group dragged one place along, its chevron going with it. No errors in the log.
  • Overlap with text measured pixel by pixel across three sizes and hole sizes, 2 to 12 slices, Latin, Arabic, Hindi and Korean names, and every built-in group name in all 20 languages. That's what the name's move, and the known limit above, come from.

New tests, DonutGroupMarkTests (12, one of them with two cases); each was checked by removing what it covers and seeing it fail:

Test Checks
Only a group slice chevron on the group's outer edge and nowhere else
Size grows with the donut
Name moves in by 3 px
Lit / disabled the highlight's text colour; half strength with one blended path, no brighter tip
Side slice turns with its slice, pops out with it
Collapse / flip moves in towards the centre with its slice; narrows on the old face as it turns
Editor marked at a preset's size; a dragged slice and the palette's chips know they're groups, on a real drag
Profile change during a drag no crash, and a release off the donut changes nothing

Screenshots (UI changes)

The Images donut's back face, and Rotate lit with its ring open:

The Images donut's back face, a chevron on the Rotate group The Rotate group lit, its ring open beside it

Settings → Donut toolbar, the PDF donut's back face:

The Donut toolbar page, a chevron on the Edit group

Checklist

  • New UI strings are in all src/Filee.App/Assets/i18n/*.json files (none needed)
  • New third-party code or binaries are listed in THIRD-PARTY-NOTICES.md (none)
  • The PR does one thing (unrelated changes go in a separate PR)

🤖 Generated with Claude Code

A group slice draws a small chevron by its outer edge, pointing to where its ring fans out, so a group can be told from
a preset at a glance, even where "Group of N" has no room.

- DonutMenu.DrawSliceLabel draws a slice's text and mark for the ring, the old face, the collapse and the drop preview;
  a group's name moves in to leave the mark room.
- The mark's size follows the donut's. It takes the secondary text colour, the highlight's text colour when lit, and half
  strength when the group is disabled.
- The Donut toolbar page marks its group slices and the slice of a group being dragged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the feature New features label Nov 4, 2026

@KnifeLemon KnifeLemon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @lightscape-jm. This does all five things #868 asks. The mark stays on the slice's own radius, so hit-testing is unchanged, and at radius 110–220 with the hole at 42% and 65% and long names and captions, it didn't overlap the top slice's text. The side-slice overlap you disclosed belongs to #870, so I'm fine leaving it. The 13 test cases pass locally and CI is green. Merging.

Two small things for a follow-up, neither blocks this:

  • DonutMenu.cs:1111: DrawGroupMark builds a new StreamGeometry for each group slice on every frame while the donut animates. The comment at DonutMenu.cs:1279 says slice shapes are kept and reused to avoid exactly that, so the mark could be cached like _wedges.
  • ToolbarPage.axaml.cs:251: the tests check the chip's IsGroup property, but the real drags in the file all start from slices. So the table's "on a real drag" isn't quite covered for chips, and a chip drag asserting PreviewIsGroup would close that.

@KnifeLemon
KnifeLemon merged commit 5d51c2f into KnifeLemon:main Nov 4, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Donut: mark group slices with a small outward chevron

2 participants