Dock: floating panels, tab groups and adjustable slot heights

Panels can now float over the workspace, share a docked slot as tabs,
and split an edge at heights the user picks.

- Dropping a panel away from the edges floats it at the pointer. Floating
  panels move by their title bar, resize from a corner grip, and come to
  the front when clicked.
- Dropping in the top or bottom quarter of a docked slot docks the panel
  above or below it, as before. Dropping in the middle adds the panel as
  a tab of that slot. Pressing a tab shows that panel; dragging a tab
  pulls the panel out again.
- While dragging, a blue ghost previews the result: the new slot, the
  slot with its future tab row, or the floating window.
- A splitter between stacked slots sets their heights; double-click it
  to make the slots equal again. Heights persist.
- A press only becomes a drag after 5 px of movement, so clicking a title
  bar or tab never moves the panel.

The persisted layout now stores each edge as tab groups with a height
weight, plus a list of floating panels. Configs with the old
bare-panel-id stacks still load as single-panel slots.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RyGiMXcsf9HTKfqDxaQGt
This commit is contained in:
Claude committed 2026-10-08 19:10:36 +00:00
1 parent 1bf584a1c1
commit 76883695c3
11 files changed
+1452 -417

No files matched your search

+17 -2
View File
@@ -852,8 +852,19 @@ pub(super) struct OpenCADStudio {
pub(crate) dock_resizing: Option<crate::ui::dock::PanelId>,
/// Last pointer position during a drag / resize.
pub(crate) dock_drag_last: Option<iced::Point>,
/// Live drag target (side + index), shown as a highlight while dragging.
pub(crate) dock_drag_target: Option<(crate::app::config::DockSide, usize)>,
/// Live drop target, shown as a preview while dragging. `None` until the
/// pointer has moved far enough to count as a drag, so a click on a title
/// bar or tab never moves the panel.
pub(crate) dock_drag_target: Option<crate::ui::dock::DropTarget>,
/// First pointer position of the current panel drag.
pub(crate) dock_drag_origin: Option<iced::Point>,
/// Pointer offset from a dragged panel's top-left corner, so a floated
/// panel lands where it is held rather than jumping to the pointer.
pub(crate) dock_grab_offset: iced::Vector,
/// Splitter being dragged between two slots on a side (upper, lower).
pub(crate) dock_split_drag: Option<(crate::app::config::DockSide, usize, usize)>,
/// Floating panel being resized from its corner grip.
pub(crate) dock_float_resizing: Option<crate::ui::dock::PanelId>,
/// Reference-table column currently being width-resized (column index),
/// with the last pointer position. Mirrors the Layers Name-column drag.
pub(crate) xref_col_drag: Option<usize>,
@@ -4289,6 +4300,10 @@ impl OpenCADStudio {
dock_resizing: None,
dock_drag_last: None,
dock_drag_target: None,
dock_drag_origin: None,
dock_grab_offset: iced::Vector::new(0.0, 0.0),
dock_split_drag: None,
dock_float_resizing: None,
xref_col_drag: None,
xref_col_last: None,
xref_split_drag: false,