feat(dock): stacked edge rendering and drag-to-reorder preview

This commit is contained in:
Karim Jerbi committed 2026-08-11 23:13:05 +01:00
1 parent 10a1d89f19
commit 7bfb617745
8 files changed
+326 -448

No files matched your search

+15 -5
View File
@@ -599,7 +599,10 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
self.show_block_palette = false;
self.block_palette.placing = None;
}
PanelId::Properties => self.show_properties = false,
PanelId::Properties => {
self.show_properties = false;
self.ribbon.set_properties(false);
}
}
if self.dock_expanded == Some(id) {
self.dock_expanded = None;
@@ -613,13 +616,20 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
iced::Task::none()
}
DockMsg::Hover(id) => {
self.dock_expanded = Some(id);
// Ignored while dragging/resizing: the pointer is over the
// drag preview, not a rail, so a hover must not collapse the
// panel being dragged or repoint the resize target.
if self.dock_dragging.is_none() && self.dock_resizing.is_none() {
self.dock_expanded = Some(id);
}
iced::Task::none()
}
DockMsg::HoverExit => {
if let Some(id) = self.dock_expanded {
if self.dock.auto_collapse(id) {
self.dock_expanded = None;
if self.dock_dragging.is_none() && self.dock_resizing.is_none() {
if let Some(id) = self.dock_expanded {
if self.dock.auto_collapse(id) {
self.dock_expanded = None;
}
}
}
iced::Task::none()
-12
View File
@@ -553,11 +553,6 @@ impl OpenCADStudio {
section: self.start_section,
},
statusbar: self.statusbar_config.clone(),
properties: crate::app::config::PropertiesDockConfig {
side: self.properties_side,
width: self.properties_width,
auto_collapse: self.properties_auto_collapse,
},
dock: {
let mut dock = self.dock.clone();
dock.ensure_settings();
@@ -600,13 +595,6 @@ impl OpenCADStudio {
// (`refresh_recent_thumbs`) — never here on the boot path.
self.start_section = cfg.start.section;
self.statusbar_config = cfg.statusbar;
self.properties_side = cfg.properties.side;
self.properties_width = if cfg.properties.width.is_finite() {
cfg.properties.width.clamp(220.0, 600.0)
} else {
250.0
};
self.properties_auto_collapse = cfg.properties.auto_collapse;
let mut dock = cfg.dock;
dock.ensure_settings();
self.dock = dock;
-109
View File
@@ -377,115 +377,6 @@ impl OpenCADStudio {
Task::none()
}
Message::TogglePropertiesBar => {
self.props_expanded = !self.props_expanded;
Task::none()
}
Message::PropertiesClose => {
self.show_properties = false;
self.properties_hovered = false;
self.properties_dragging = false;
self.properties_resizing = false;
self.properties_drag_last = None;
self.properties_dock_preview = None;
self.ribbon.set_properties(false);
Task::none()
}
Message::PropertiesAutoCollapseToggle => {
self.properties_auto_collapse ^= true;
// Keep the panel open while the pointer is still over the
// button; leaving the panel performs the first collapse.
self.properties_hovered = self.properties_auto_collapse;
self.save_config();
Task::none()
}
Message::PropertiesHover(hovered) => {
if self.properties_auto_collapse
&& !self.properties_dragging
&& !self.properties_resizing
{
self.properties_hovered = hovered;
}
Task::none()
}
Message::PropertiesDockGrab => {
self.properties_dragging = true;
self.properties_resizing = false;
self.properties_drag_last = None;
self.properties_dock_preview = Some(self.properties_side);
self.properties_hovered = true;
Task::none()
}
Message::PropertiesResizeGrab => {
self.properties_resizing = true;
self.properties_dragging = false;
self.properties_drag_last = None;
self.properties_dock_preview = None;
self.properties_hovered = true;
Task::none()
}
Message::PropertiesWidthReset => {
self.properties_width = 250.0;
self.save_config();
Task::none()
}
Message::PropertiesDragMove(point) => {
if self.properties_dragging {
self.properties_dock_preview = Some(if point.x < self.win_size.0 * 0.5 {
crate::app::config::DockSide::Left
} else {
crate::app::config::DockSide::Right
});
} else if self.properties_resizing {
if let Some(last) = self.properties_drag_last {
let dx = point.x - last.x;
let delta = match self.properties_side {
crate::app::config::DockSide::Left => dx,
crate::app::config::DockSide::Right => -dx,
};
let max_width = (self.win_size.0 * 0.45).clamp(220.0, 600.0);
self.properties_width =
(self.properties_width + delta).clamp(220.0, max_width);
}
}
if self.properties_dragging || self.properties_resizing {
self.properties_drag_last = Some(point);
}
Task::none()
}
Message::PropertiesDragRelease => {
let changed = if self.properties_dragging {
if let Some(side) = self.properties_dock_preview {
let changed = side != self.properties_side;
self.properties_side = side;
changed
} else {
false
}
} else {
self.properties_resizing
};
self.properties_dragging = false;
self.properties_resizing = false;
self.properties_drag_last = None;
self.properties_dock_preview = None;
if self.properties_auto_collapse {
self.properties_hovered = false;
}
if changed {
self.save_config();
}
Task::none()
}
Message::ScrollLayoutTabs(dx) => iced::widget::operation::scroll_by(
iced::advanced::widget::Id::new(crate::ui::statusbar::LAYOUT_TABS_SCROLL_ID),
iced::widget::scrollable::AbsoluteOffset { x: dx, y: 0.0 },