panes: a bottom pane dragged to a side previews the width it docks at

This commit is contained in:
aiongg committed 2026-10-24 13:12:49 +00:00
1 parent 3ddbb0b181
commit 5bbf45a20a
2 files changed
+30 -4

No files matched your search

+11 -4
View File
@@ -534,13 +534,19 @@ impl PaneHost {
}
if content.movable(&s.pane) {
self.drag_out(ui.ctx(), &bar, s, edge, rect, bounds, memory, preview, style, requests);
// Docked at the host's left or right edge, the pane gets the width the side limits
// give its size: a bottom pane's height, not its width.
let (side_min, side_max) = self.limits(content, &s.pane, bounds.width());
let side_width =
s.state.size.filter(|v| v.is_finite()).or(default.filter(|v| v.is_finite())).unwrap_or(side_min).clamp(side_min, side_max);
self.drag_out(ui.ctx(), &bar, s, edge, rect, side_width, bounds, memory, preview, style, requests);
}
rect
}
/// A docked pane's title dragged beyond [`DOCK_SNAP`] of the pane: dropped near the host's
/// left or right edge it docks there, elsewhere it floats under the pointer.
/// left or right edge it docks there `side_width` wide, elsewhere it floats under the
/// pointer.
#[allow(clippy::too_many_arguments)]
fn drag_out<P: Clone>(
&self,
@@ -549,6 +555,7 @@ impl PaneHost {
s: &Shown<P>,
edge: Edge,
rect: Rect,
side_width: f32,
bounds: Rect,
memory: &mut Memory,
preview: &egui::Painter,
@@ -592,8 +599,8 @@ impl PaneHost {
return;
}
let shape = match target.map(|t| self.side(t)) {
Some(Side::Left) => Rect::from_x_y_ranges(bounds.left()..=bounds.left() + rect.width(), bounds.y_range()),
Some(_) => Rect::from_x_y_ranges(bounds.right() - rect.width()..=bounds.right(), bounds.y_range()),
Some(Side::Left) => Rect::from_x_y_ranges(bounds.left()..=bounds.left() + side_width, bounds.y_range()),
Some(_) => Rect::from_x_y_ranges(bounds.right() - side_width..=bounds.right(), bounds.y_range()),
None => float,
};
chrome::drop_preview(preview, shape.shrink(1.0), style.accent, true);
+19
View File
@@ -174,6 +174,25 @@ fn columns_sit_side_by_side_resize_and_move_to_end() {
assert_eq!(edge(&h, Pane::Styles), L + 250.0);
}
#[test]
fn a_bottom_pane_dragged_to_a_side_previews_the_width_it_docks_at() {
let mut app = App::new(&[Pane::Comments]);
app.states.insert(Pane::Comments, PaneState::docked(Edge::Bottom, 300.0));
let mut h = harness(app);
let from = title(&h, Pane::Comments).center();
let to = pos2(L + 10.0, 200.0);
hold(&mut h, from, to);
let previewed = h.output().shapes.iter().any(|clipped| match &clipped.shape {
egui::Shape::Rect(shape) => shape.rect.left() == L + 1.0 && shape.rect.width() == 298.0,
_ => false,
});
assert!(previewed, "a 300 pt side pane");
send(&mut h, vec![button(to, false)]);
h.run_steps(2);
assert_eq!(h.state().place(Pane::Comments), Place::Docked(Edge::Start));
assert_eq!(edge(&h, Pane::Comments), L + 300.0);
}
#[test]
fn title_dragged_out_floats_and_a_drop_near_an_edge_docks() {
// Drag-out-to-float and the 32 pt edge snap follow wordcraft#2584.