forked from 1b-agent/opencadstudio-upstream
Dock: drop dead pallet-width setters, split on_dock, share span maths
- Only docked pallets have a width divider, so the Width drag and WidthReset no longer carry a branch for an undocked pallet; remove the then unused DockState::set_width / reset_width. Per-pallet widths are still read (older configs, floating size). Tests now size groups. - on_dock hands hover messages to dock_hover and the release to dock_drag_release. - dock_slot_spans and dock_landing share dock_open_spans. No behaviour change. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013RyGiMXcsf9HTKfqDxaQGt
This commit is contained in:
4 files changed
+111
-107
No files matched your search
@@ -186,7 +186,7 @@ fn dock_icon_press_switches_the_shown_group() {
|
||||
assert_eq!(app.dock_shown_group(DockSide::Left), Some(1));
|
||||
assert_eq!(app.dock_slot_spans(DockSide::Left), vec![(0, 0.0, 900.0)]);
|
||||
// Each group keeps its own width.
|
||||
app.dock.set_width(PanelId::Browser, 400.0);
|
||||
app.dock.set_group_width(DockSide::Left, 1, 400.0);
|
||||
assert_eq!(app.dock_column_width(DockSide::Left), 400.0);
|
||||
let _ = app.on_dock(DockMsg::IconPress(PanelId::BlockPalette));
|
||||
let _ = app.on_dock(DockMsg::DragRelease);
|
||||
|
||||
+90
-65
@@ -30,7 +30,7 @@ impl OpenCADStudio {
|
||||
/// whichever panel the message names.
|
||||
pub(crate) fn on_dock(&mut self, m: crate::ui::dock::DockMsg) -> iced::Task<Message> {
|
||||
use crate::app::config::DockSide;
|
||||
use crate::ui::dock::{DockDrag, DockMsg, DropTarget, FloatPanel, HoverPending};
|
||||
use crate::ui::dock::{DockDrag, DockMsg, FloatPanel};
|
||||
match m {
|
||||
DockMsg::DockGrab(id) => self.dock_begin(DockDrag::moving(id, None), Some(id)),
|
||||
DockMsg::IconPress(id) => {
|
||||
@@ -66,12 +66,11 @@ impl OpenCADStudio {
|
||||
self.save_config();
|
||||
}
|
||||
DockMsg::WidthReset(id) => {
|
||||
// Only docked pallets have the divider that sends this.
|
||||
if let Some((side, gi)) = self.dock.location(id) {
|
||||
self.dock.reset_group_width(side, gi);
|
||||
} else {
|
||||
self.dock.reset_width(id);
|
||||
self.save_config();
|
||||
}
|
||||
self.save_config();
|
||||
}
|
||||
DockMsg::TitleHover(id) => self.dock_title_hover = Some(id),
|
||||
DockMsg::TitleHoverEnd(id) => {
|
||||
@@ -150,6 +149,22 @@ impl OpenCADStudio {
|
||||
self.save_config();
|
||||
}
|
||||
DockMsg::Close(id) => return self.dock_set_open(id, false),
|
||||
DockMsg::Hover(_)
|
||||
| DockMsg::HoverEnd(_)
|
||||
| DockMsg::HoverExit
|
||||
| DockMsg::HoverStay
|
||||
| DockMsg::HoverSettled(_) => return self.dock_hover(m),
|
||||
DockMsg::DragMove(point) => self.dock_drag_move(point),
|
||||
DockMsg::DragRelease => self.dock_drag_release(),
|
||||
}
|
||||
iced::Task::none()
|
||||
}
|
||||
|
||||
/// Pointer entering / leaving strip icons, edge columns and floating
|
||||
/// frames, and the delayed auto-hide reveal / hide that follows.
|
||||
fn dock_hover(&mut self, m: crate::ui::dock::DockMsg) -> iced::Task<Message> {
|
||||
use crate::ui::dock::{DockMsg, HoverPending};
|
||||
match m {
|
||||
DockMsg::Hover(id) => {
|
||||
self.dock_icon_hover = Some(id);
|
||||
// Only an auto-hiding edge (or floating pallet) reacts to
|
||||
@@ -198,54 +213,57 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
}
|
||||
DockMsg::DragMove(point) => self.dock_drag_move(point),
|
||||
DockMsg::DragRelease => {
|
||||
let mut changed = false;
|
||||
match self.dock_drag.take() {
|
||||
Some(DockDrag::Move {
|
||||
group: Some((side, gi)),
|
||||
target: Some(DropTarget::Edge { side: to, index }),
|
||||
..
|
||||
}) => changed = self.dock.move_group(side, gi, to, index),
|
||||
Some(DockDrag::Move {
|
||||
panel,
|
||||
group: None,
|
||||
target: Some(target),
|
||||
..
|
||||
}) => {
|
||||
changed = match target {
|
||||
DropTarget::Edge { side, index } => self.dock.dock(panel, side, index),
|
||||
DropTarget::Join { side, group, index } => {
|
||||
self.dock.join_group(panel, side, group, index)
|
||||
}
|
||||
DropTarget::Float { x, y } => {
|
||||
let (w, h) = self.dock_float_size(panel);
|
||||
// A floating panel keeps its docking choice.
|
||||
let docking = self.dock.float_rect(panel).is_none_or(|f| f.docking);
|
||||
self.dock.float(FloatPanel {
|
||||
docking,
|
||||
..FloatPanel::new(panel, x, y, w, h)
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
Some(DockDrag::Move { .. } | DockDrag::LayerColumn) | None => {}
|
||||
Some(DockDrag::Width(_) | DockDrag::Split { .. } | DockDrag::FloatSize { .. }) => {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
self.save_config();
|
||||
}
|
||||
self.dock_drag_last = None;
|
||||
self.xref_col_drag = None;
|
||||
self.xref_col_last = None;
|
||||
self.xref_split_drag = false;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
iced::Task::none()
|
||||
}
|
||||
|
||||
/// Pointer released: land what was dragged and save a changed layout.
|
||||
fn dock_drag_release(&mut self) {
|
||||
use crate::ui::dock::{DockDrag, DropTarget, FloatPanel};
|
||||
let mut changed = false;
|
||||
match self.dock_drag.take() {
|
||||
Some(DockDrag::Move {
|
||||
group: Some((side, gi)),
|
||||
target: Some(DropTarget::Edge { side: to, index }),
|
||||
..
|
||||
}) => changed = self.dock.move_group(side, gi, to, index),
|
||||
Some(DockDrag::Move {
|
||||
panel,
|
||||
group: None,
|
||||
target: Some(target),
|
||||
..
|
||||
}) => {
|
||||
changed = match target {
|
||||
DropTarget::Edge { side, index } => self.dock.dock(panel, side, index),
|
||||
DropTarget::Join { side, group, index } => {
|
||||
self.dock.join_group(panel, side, group, index)
|
||||
}
|
||||
DropTarget::Float { x, y } => {
|
||||
let (w, h) = self.dock_float_size(panel);
|
||||
// A floating panel keeps its docking choice.
|
||||
let docking = self.dock.float_rect(panel).is_none_or(|f| f.docking);
|
||||
self.dock.float(FloatPanel {
|
||||
docking,
|
||||
..FloatPanel::new(panel, x, y, w, h)
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
Some(DockDrag::Move { .. } | DockDrag::LayerColumn) | None => {}
|
||||
Some(DockDrag::Width(_) | DockDrag::Split { .. } | DockDrag::FloatSize { .. }) => {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
self.save_config();
|
||||
}
|
||||
self.dock_drag_last = None;
|
||||
self.xref_col_drag = None;
|
||||
self.xref_col_last = None;
|
||||
self.xref_split_drag = false;
|
||||
}
|
||||
|
||||
/// Pointer motion while something in the dock is dragged.
|
||||
fn dock_drag_move(&mut self, point: iced::Point) {
|
||||
// NOTE: xref column drags intentionally do NOT ride this path: its
|
||||
@@ -353,18 +371,12 @@ impl OpenCADStudio {
|
||||
}
|
||||
DockDrag::Width(id) => {
|
||||
let Some(last) = last else { return };
|
||||
let dx = point.x - last.x;
|
||||
match self.dock.location(id) {
|
||||
// The divider sizes the panel's group.
|
||||
Some((side, gi)) => {
|
||||
let delta = if side == DockSide::Left { dx } else { -dx };
|
||||
let cur = self.dock_group_width(side, gi) + delta;
|
||||
self.dock.set_group_width(side, gi, cur);
|
||||
}
|
||||
None => {
|
||||
let cur = self.dock.settings(id).width + dx;
|
||||
self.dock.set_width(id, cur);
|
||||
}
|
||||
// The divider sizes the docked pallet's group.
|
||||
if let Some((side, gi)) = self.dock.location(id) {
|
||||
let dx = point.x - last.x;
|
||||
let delta = if side == DockSide::Left { dx } else { -dx };
|
||||
let cur = self.dock_group_width(side, gi) + delta;
|
||||
self.dock.set_group_width(side, gi, cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,13 +646,26 @@ impl OpenCADStudio {
|
||||
&self,
|
||||
side: crate::app::config::DockSide,
|
||||
) -> Vec<(usize, f32, f32)> {
|
||||
let Some(gi) = self.dock_shown_group(side) else {
|
||||
return Vec::new();
|
||||
};
|
||||
match self.dock_shown_group(side) {
|
||||
Some(gi) => self.dock_open_spans(&self.dock.groups(side)[gi], None),
|
||||
None => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// The open pallets of `group` (plus `extra`, a pallet about to land
|
||||
/// there), each as (position in the group, top, bottom) down the
|
||||
/// workspace height.
|
||||
pub(crate) fn dock_open_spans(
|
||||
&self,
|
||||
group: &crate::ui::dock::DockGroup,
|
||||
extra: Option<crate::ui::dock::PanelId>,
|
||||
) -> Vec<(usize, f32, f32)> {
|
||||
let (_, avail) = self.dock_workspace_size();
|
||||
let group = &self.dock.groups(side)[gi];
|
||||
let open: Vec<usize> = (0..group.panels.len())
|
||||
.filter(|i| self.dock_panel_visible(group.panels[*i]))
|
||||
.filter(|i| {
|
||||
let id = group.panels[*i];
|
||||
Some(id) == extra || self.dock_panel_visible(id)
|
||||
})
|
||||
.collect();
|
||||
let weights: Vec<f32> = open.iter().map(|i| group.weights[*i]).collect();
|
||||
open.into_iter()
|
||||
|
||||
@@ -690,13 +690,10 @@ impl OpenCADStudio {
|
||||
}
|
||||
let (side, gi) = after.location(id)?;
|
||||
let group = &after.groups(side)[gi];
|
||||
let open: Vec<usize> = (0..group.panels.len())
|
||||
.filter(|i| group.panels[*i] == id || self.dock_panel_visible(group.panels[*i]))
|
||||
.collect();
|
||||
let weights: Vec<f32> = open.iter().map(|i| group.weights[*i]).collect();
|
||||
let at = open.iter().position(|i| group.panels[*i] == id)?;
|
||||
let (_, avail) = self.dock_workspace_size();
|
||||
let (top, bottom) = *crate::ui::dock::slot_spans(&weights, avail).get(at)?;
|
||||
let (_, top, bottom) = self
|
||||
.dock_open_spans(group, Some(id))
|
||||
.into_iter()
|
||||
.find(|(i, _, _)| group.panels[*i] == id)?;
|
||||
Some((top, bottom, after.group_width_px(side, gi, self.win_size.0)))
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user