UI: preserve window-edge Tools redocking across vertical layouts

This commit is contained in:
dotCooCoo
2026-11-08 23:51:39 +07:00
committed by bflatastic
parent a8f21ac0f6
commit 27c292669f
3 changed files with 42 additions and 3 deletions
+3
View File
@@ -542,6 +542,9 @@ impl VectorcraftApp {
// Control bar docked at the bottom has set it to the bar's top.
widgets::set_menu_floor(&ctx, ctx.content_rect().bottom());
}
if self.ui.toolbar && self.ui.screen_mode < 3 {
tools_float::set_window_dock_zone(&ctx, ui.available_rect_before_wrap());
}
if self.ui.toolbar && self.ui.screen_mode < 3 && self.ui.toolbar_pos.is_some() {
toolbar::show(self, ui);
} else if !self.ui.toolbar && self.ui.screen_mode < 3 && self.ui.tab_hid.is_none() {
+32
View File
@@ -344,6 +344,38 @@ fn tools_follow_left_panels_when_resized_hidden_and_restored() {
}
}
#[test]
fn tools_redock_at_window_edge_above_and_below_canvas() {
for above in [true, false] {
let mut h = Harness::new();
let tabs = |panel: &str| Box::new(Node::Tabs { panels: vec![panel.to_string()], active: 0 });
h.app.ui.docking = Some(Layout {
root: Some(Node::Split {
axis: craft_ui::layout::SplitAxis::Vertical,
size: craft_ui::layout::SplitSize::FixedFirst(180.0),
first: tabs("layers"),
second: Box::new(Node::Split {
axis: craft_ui::layout::SplitAxis::Vertical,
size: craft_ui::layout::SplitSize::FixedSecond(180.0),
first: tabs(CANVAS),
second: tabs("properties"),
}),
}),
floating: vec![],
});
assert!(valid(&h.layout()));
h.app.run("window.panel.float", json!({"panel": "tools", "x": 600, "y": 300})).unwrap();
for _ in 0..3 {
h.frame(vec![]);
}
let panel = h.tab(if above { "layers" } else { "properties" }).unwrap();
let canvas = h.app.canvas_rect.unwrap();
assert!(panel.center().y < canvas.top() || panel.center().y > canvas.bottom());
h.drag(pos2(620.0, 307.0), pos2(12.0, panel.center().y));
assert_eq!(h.app.ui.toolbar_pos, None, "window-edge drop above canvas: {above}");
}
}
#[test]
#[ignore = "manual visual check; set LEFT_TOOLS_SCREENSHOTS to an existing harness directory"]
fn capture_tools_beside_left_panels() {
+7 -3
View File
@@ -51,15 +51,19 @@ fn window_zone_id() -> Id {
Id::unique("tools-float-window-zone")
}
/// Keep the window-edge gesture while also accepting a drop next to panels docked left.
/// Accept a drop next to panels docked left, independently of the window-edge gesture.
pub(crate) fn set_dock_zones(ctx: &egui::Context, canvas: Rect, width: f32) {
let window = pos2(ctx.content_rect().left(), canvas.top());
ctx.data_mut(|d| {
d.insert_temp(tools_zone_id(), Rect::from_min_size(canvas.min, vec2(width, canvas.height())));
d.insert_temp(window_zone_id(), Rect::from_min_size(window, vec2(width, canvas.height())));
});
}
/// The legacy 48-point window-edge target spans the full layout below the bars, including
/// panels above and below the canvas. Its width does not follow the toolbar's column count.
pub(crate) fn set_window_dock_zone(ctx: &egui::Context, window: Rect) {
ctx.data_mut(|d| d.insert_temp(window_zone_id(), Rect::from_min_size(window.min, vec2(48.0, window.height()))));
}
/// `pos` moved so a panel of `size` stays inside `screen` (a position saved on a bigger window).
pub fn clamp(pos: [f32; 2], size: Vec2, screen: Rect) -> Pos2 {
let [x, y] = pos;