Skip to content

pallets: steadier docking and floating, and a much faster Blocks palette - #2074

Merged
HakanSeven12 merged 12 commits into
HakanSeven12:mainfrom
MarcelP102:pallet-fixes
Oct 23, 2026
Merged

HakanSeven12 merged 12 commits into
HakanSeven12:mainfrom
MarcelP102:pallet-fixes

Conversation

@MarcelP102

@MarcelP102 MarcelP102 commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Makes docked and floating pallets steadier (the title bar keeps its side, every edge resizes, and the drawing no longer jumps), and makes the Blocks palette fast with many blocks.

Floating pallets (src/ui/dock.rs, src/app/dock)

  • The vertical title bar keeps its side, saved with the layout. A layout saved before this change starts with the bar on the left.
    • It starts on the side the pallet was docked on.
    • While dragging, it only flips when the frame touches the docked pallets of an edge, the screen edge, or an edge showing the blue drop preview.
    • With docking off for the pallet, only the screen edge counts.
  • The corner resize grip and its resize_left.svg icon are gone.
    • Every side and corner of a floating pallet resizes it, with the matching cursor.
    • Dragging the left or top side keeps the opposite side in place.
    • A pallet collapsed to its title bar resizes from the top and bottom only.
  • Dragging a pallet that already floats moves the pallet itself, drawn where it will land. A layer above it takes the pointer, so the moving window doesn't react.
  • A pallet dragged out of a dock still shows the plain drop ghost.

Drawing stays in place (dock_keep_view)

  • Docking or undocking a pallet, switching an edge to auto-hide and resizing a docked group all keep the drawing where it is: the view pans by however far the viewport's centre moved.
  • A revealed auto-hide group draws over the drawing instead of squeezing it.
  • The viewport's new size is set as soon as the docked edges or the window change. The ViewCube's controls, the UCS picker and icon, the grid and the crosshair no longer trail the drawing by a frame while resizing.
  • Split model viewports are not panned.

Blocks palette (src/ui/window/block_palette.rs, src/app/update/blocks_palette.rs)

  • Thumbnails draw through a canvas cache, so they aren't tessellated again every frame.
  • Block names are looked up through an index instead of a scan per card.
  • Clicking a block that's already in the drawing no longer rebuilds every preview first. This removes about a second before the card turned blue.
  • All six views build only the rows in view, with spaces of the same height for the rest:
    • names in Small Icons, Details and List stay on one line, cut with "…";
    • every row is the same height, which makes this possible;
    • List rows are about 1.7 px taller, as tall as Details rows.
  • Previews are worked out once the palette is about to show them. The ribbon gallery, which shows every block, works them all out when it opens.
  • Saving or defining a block (Block Editor save, Save As, BLOCK, block properties) redraws only that block and the blocks holding it. Every other change still rebuilds all previews.
  • Library folders list at once, and their thumbnails, as well as those of Recent / Favorites drawings, are read on a background thread.

Testing

  • cargo test --lib: 3,013 passed, 0 failed, 31 ignored, with upstream main merged in.
  • New tests:
    • the title bar side: docked side, docked pallets, screen edge, drop preview, docking off;
    • resizing from every edge and the cursors;
    • the drawing keeping its place, and the viewport size following dock and window changes;
    • the moving window in the real view;
    • the palette's visible rows in every view, against the real iced layout;
    • on-demand previews, partial refreshes after a block save, the case-insensitive index and background thumbnails.
  • cargo clippy --lib --tests shows no warnings in the new code.
  • Measured with 500 blocks in a 300×1000 px palette (debug build), per frame:
    • name lookups: 21 ms → 1 ms;
    • drawing the visible thumbnails: 8 ms → 0.1 ms;
    • building and laying out the list: 9 ms → 0.7 ms.

claude added 12 commits October 22, 2026 14:24
…keep the drawing still

- A floating pallet's vertical title bar now keeps its side (saved in the
  layout). It starts on the side the pallet was docked on and only moves
  when a drag brings the frame against the docked pallets of an edge, when
  the drop preview shows on an edge without docked pallets, or, with
  docking off, against the screen edge.
- The corner resize grip is gone: every side and corner of a floating
  pallet resizes it (top and bottom only while it is hidden to its bar).
- The drawing stays put on screen when pallets dock or undock, an edge
  switches to auto-hide, or a docked group is resized: the view pans by
  however far the viewport's centre moved. A revealed auto-hide group now
  draws over the drawing instead of squeezing it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
…n edge

While dragging a floating pallet, its title bar now also moves to a side
as soon as the frame reaches that edge of the screen, not only once the
pointer shows the drop preview there. The floating drop ghost now shows
the title bar on the side it will land on, so the flip is visible mid-drag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
Dragging a pallet that already floats now moves the pallet itself instead
of a ghost: it draws where it would land, with its title bar on the side
it would land on, and hides while a dock zone shows its preview. A layer
over everything takes the pointer during the drag, so the moving window
doesn't react to it and the cursor stays a closed hand. A pallet dragged
out of a dock still shows the ghost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
…sizes

- A pallet dragged out of a dock to float shows the plain drop ghost again:
  its title along the top, no vertical title bar.
- The viewport's new size is set as soon as the docked edges or the window
  change, instead of only once layout measures it after the overlays were
  built. The ViewCube's controls, the UCS picker and icon, the grid and the
  crosshair no longer trail the drawing by a frame while a docked pallet or
  the window is resized.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
Dragging any pallet redraws the window on every pointer move. With a large
Block palette open each frame redrew every visible thumbnail from scratch
and looked each block up by name with a linear scan, several times per card.

- Thumbnails draw through a canvas cache kept with the block's preview, so
  they are only tessellated again when their size changes or the palette
  refreshes.
- Block names are looked up through an index built when the list is set.
- The previews kept for Recent / Favorites share the Current Drawing ones
  instead of copying every block's wires on each refresh.

With 500 blocks this takes about 30 ms off each frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
- Clicking a block rebuilt every block's preview first, even for a block
  already in the drawing: that took about a second before the card turned
  blue with many blocks. The palette now only rebuilds when the click had
  to import or redefine the block. Switching tabs and opening the ribbon's
  block gallery rebuild only when the drawing's blocks changed, and adding
  a favorite only reads the drawing thumbnail it may need.
- The icon views build only the rows in view (plus two spare at each end),
  with spaces of the same height for the rest, so the list keeps its height
  and scroll position. With 500 blocks this takes building the palette from
  about 9 ms to under 1 ms per frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
Saving or defining a block changes the drawing's block marker, and the
palette then rebuilt the preview of every block. A message that saves a
block now tells the palette which blocks it changed: the refresh after it
redraws those and the blocks holding them (directly or nested) and keeps
the other previews with their drawn thumbnails.

- Block Editor save: the edited block plus whatever the save itself
  rewrote (a dynamic block's references), found by comparing definitions.
- Block Editor Save As: the definitions that differ from before.
- BLOCK and the Block Editor's block properties: that block.

The hint only counts when the palette was up to date before the change and
lives for the message that made it; every other change still rebuilds all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
…ackground

- A refresh no longer works out every block's preview. Previews are made
  once the palette is about to show them: the rows in view of the icon
  views (the first screenful before the list reports its viewport), every
  row of Small Icons and Details, none for List. The ribbon gallery, which
  shows every block, makes all of them when it opens; placing a block and
  the drawing's blocks in Recent / Favorites make theirs right away.
- Drawing thumbnails for library folders and for Recent / Favorites are
  read on a background thread, a few at a time, instead of on the UI
  thread: a library folder lists at once and its thumbnails appear as they
  are read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
…d List too

Their rows weren't all equally tall: Details and List names wrapped when
long or in a narrow pallet. Names in these views now stay on one line and
are cut with "…" where they run out of room, every row (and the Details
header) is a fixed 16 px, and all six views share one layout, so these
views also build only the rows in view and work out only the previews
shown. List rows are about 1.7 px taller, as tall as Details rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
- Finding the blocks a save changed, and the blocks holding them, skips
  model space, paper space and layouts: their contents are the drawing
  itself, which was compared or scanned on every block save.
- The palette only works out which previews are shown when the scroll
  position, view, tab, filter, Recent / Favorites or the blocks changed,
  instead of after every message.
- The room the docked edges take looks the shown group up once per edge.
- BlockPreview::new was only used by a test, which now uses pending().
- Two comments now mention that dock and window changes also set the
  viewport's size.
- blockpalette_refresh_shares_previews_and_makes_new_ones is folded into
  blockpalette_refresh_keeps_previews_of_blocks_a_change_did_not_touch:
  its other checks were already covered elsewhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
Brings pallet-fixes up to date with HakanSeven12/OpenCADStudio main. The
only conflict was in src/app/block_editor_tests.rs, where both sides added
tests at the same place; both are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
Clippy's field_reassign_with_default flagged the view test setting `view`
right after `Default::default()`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li8vASn3zodEpXndUDTgyM
@HakanSeven12
HakanSeven12 merged commit 4c4140a into HakanSeven12:main Oct 23, 2026
4 of 8 checks passed
HakanSeven12 added a commit that referenced this pull request Oct 23, 2026
#2074 builds previews only for rows on screen, so a block noted in Recent
or Favorites from an off-screen row showed an empty box in other drawings,
and an unbuilt kept preview hid the fallback to this drawing's block.
Build the preview when the entry is noted, fall back when it is unbuilt,
and clear the block change hint also when a message returns early.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HakanSeven12 added a commit that referenced this pull request Oct 23, 2026
The dock tests serialized their headless renderers among themselves, but
#2074's block palette test builds one too, and two made in parallel crash
the test process. Share one crate-wide lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

3 participants