Skip to content

feat: collapsible, reorderable categories with draggable actions#2

Merged
PalmarHealer merged 1 commit into
mainfrom
feat/category-reorder
May 31, 2026
Merged

feat: collapsible, reorderable categories with draggable actions#2
PalmarHealer merged 1 commit into
mainfrom
feat/category-reorder

Conversation

@PalmarHealer

Copy link
Copy Markdown
Contributor

Summary

Three requested enhancements to the categories view (sliders & buttons):

  1. Collapsible categories — a chevron per card collapses/expands it; the state is persisted in the profile.
  2. Reorderable category cards — drag the ⠿ grip on a card header to reorder (cosmetic, but saved via list order).
  3. Draggable actions — drag the ⠿ grip on an action row to reorder within a category, or move it to another category of the same kind (drop onto a collapsed/empty card appends).

What changed

  • model: collapsed flag added to SliderCategory/ButtonCategory (serde default, so existing profiles load fine). Card order is the Vec order, so reordering persists automatically; assignments key off id, not position, so reordering is purely cosmetic.
  • glue: handlers for toggle-category-collapse, reorder-category (move a card to an insertion index), and move-line (relocate an action/stream within or between categories), each with the index-shift math, then persist + re-push.
  • UI (Slint): collapse chevron; ⠿ grip handles drive a hand-rolled drag-and-drop (Slint 1.16 has no native DnD). Drop targets are hit-tested from the global pointer vs each element's absolute-position, shown with an accent drop-line and a dimmed source row/card.

Implementation note

absolute-position reads are ternary-guarded so they only execute during an active drag. Reading absolute-position in a binding evaluated at init recurses through text layout (Recursion detected panic) — and Slint's && does not short-circuit the operand away, so the guard must be a ? :, not &&.

Known limitations (hand-rolled DnD)

  • No auto-scroll near list edges while dragging.
  • No floating drag "ghost" — feedback is the dimmed source + the accent drop-line.
  • Dropping on an expanded card's header area (above the first row) may not register a slot; aim for an actual row.

Testing

  • cargo build clean; cargo test passes.
  • Manually verified on Windows: collapse persists across restart; cards and actions reorder; actions move between categories.

🤖 Generated with Claude Code

Categories view gains drag-and-drop and persistent collapse:

- model: add `collapsed` to Slider/ButtonCategory (serde default), saved
  in the profile. Card order is the Vec order, so reordering persists.
- glue: handlers for toggle-collapse, reorder-category (move card to an
  insertion index), and move-line (relocate an action/stream within or
  between categories of the same kind), each with the index-shift math.
- UI: a collapse chevron per card; ⠿ grip handles on category headers and
  action rows drive a hand-rolled drag (Slint has no native DnD). Drop
  targets are hit-tested from the global pointer vs each element's
  absolute-position, with an accent drop-line indicator and a dimmed
  source. Geometry reads are ternary-guarded so absolute-position is only
  touched during an active drag — reading it at init recurses through
  text layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds collapsible/reorderable category cards and draggable action/stream rows to the categories view. State is persisted in the profile via a new collapsed flag and the existing Vec order. Hand-rolled drag-and-drop is implemented in Slint using absolute-position hit-testing guarded by ternaries to avoid recursion during initial layout.

Changes:

  • Adds collapsed: bool (serde default) to SliderCategory/ButtonCategory and propagates it through CategorySummary to the UI.
  • Adds three new callbacks (toggle-category-collapse, reorder-category, move-line) with Rust handlers (reorder_by_id, move_line) that handle index-shift math and persist the preset.
  • Rewrites the category card layout to include a chevron toggle, drag grips for cards and rows, drop-mark indicators, and ternary-guarded absolute-position reads.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/model.rs Adds collapsed field to both category structs and updates a test constructor.
src/main.rs Updates seed CategorySummary literals with collapsed: false.
src/glue.rs Wires three new callbacks; adds reorder_by_id and move_line helpers; includes collapsed in pushed summaries.
ui/app.slint Adds collapsed to CategorySummary, introduces DropMark, drag state, grips, hit-test logic, and forwards new callbacks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@PalmarHealer PalmarHealer merged commit 2146340 into main May 31, 2026
1 check passed
@PalmarHealer PalmarHealer deleted the feat/category-reorder branch May 31, 2026 17:41
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.

2 participants