mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-12 05:22:24 +00:00
docking: drop_edges defaults to all sides; the docking profile's outer band takes only its top and bottom
This commit is contained in:
1 parent
889f0367f2
commit
876d2539f9
4 files changed
+50
-47
No files matched your search
@@ -133,13 +133,8 @@ fn a_group_that_takes_no_tabs_maps_its_whole_body_to_its_edges() {
|
||||
let canvas = Permissions { accepts_tabs: false, ..Permissions::default() };
|
||||
let d = driver(&[(1, canvas)]);
|
||||
let (body, rect) = group(&d, 1);
|
||||
// By default only its top and bottom: left of center goes to the nearer of those.
|
||||
for (zone, at, edges) in [
|
||||
(Zone::Left, body.center() - vec2(10.0, 2.0), Sides::ALL),
|
||||
(Zone::Top, body.center() - vec2(10.0, 2.0), DockStyle::default().drop_edges),
|
||||
(Zone::Bottom, body.center() + vec2(-10.0, 2.0), DockStyle::default().drop_edges),
|
||||
] {
|
||||
let mut d = driver(&[(1, canvas)]).with_style(move |style| style.drop_edges = edges);
|
||||
for (zone, at) in [(Zone::Left, body.center() - vec2(10.0, 0.0)), (Zone::Top, body.center() - vec2(0.0, 10.0))] {
|
||||
let mut d = driver(&[(1, canvas)]);
|
||||
d.hold(tab(&d, 3), at);
|
||||
assert!(d.filled(line(rect, zone)), "{zone:?}");
|
||||
let out = d.release(at);
|
||||
@@ -171,7 +166,7 @@ fn a_side_without_room_joins_as_a_tab_or_offers_nothing() {
|
||||
let out = d.drag(tab(&d, 3), top);
|
||||
assert_eq!(out.actions, vec![Action::Move { panel: 3, anchor: 1, placement: Placement::Split(Zone::Top) }]);
|
||||
// A group that takes no tabs offers nothing there.
|
||||
let mut d = narrow(&[(1, Permissions { accepts_tabs: false, ..Permissions::default() })]).with_style(|style| style.drop_edges = Sides::ALL);
|
||||
let mut d = narrow(&[(1, Permissions { accepts_tabs: false, ..Permissions::default() })]);
|
||||
d.hold(tab(&d, 3), left);
|
||||
assert!(!d.outlined(rect.shrink(1.0)));
|
||||
let out = d.release(left);
|
||||
@@ -275,22 +270,14 @@ fn drop_edges_limit_the_outer_edges_and_the_canvas_sides() {
|
||||
// The canvas has no tab strip: its body is its frame.
|
||||
let (canvas, _) = group(&d, 0);
|
||||
let (side, _) = group(&d, 1);
|
||||
// The bottom edge takes nothing.
|
||||
let at = pos2(canvas.center().x, 590.0);
|
||||
let mut d = canvas_driver(Permissions::PROTECTED, left_right);
|
||||
d.hold(tab(&d, 3), at);
|
||||
assert!(!d.filled(line(canvas, Zone::Bottom)));
|
||||
assert!(!moves(&d.release(at)));
|
||||
// The left edge splits around the canvas column.
|
||||
let at = pos2(canvas.left() + 5.0, canvas.center().y);
|
||||
let mut d = canvas_driver(Permissions::PROTECTED, left_right);
|
||||
d.hold(tab(&d, 3), at);
|
||||
assert!(d.filled(line(canvas, Zone::Left)), "a line along the canvas column's left edge");
|
||||
let out = d.release(at);
|
||||
assert_eq!(out.actions, vec![Action::Move { panel: 3, anchor: 0, placement: Placement::Edge(Zone::Left) }]);
|
||||
let column = split(SplitAxis::Horizontal, SplitSize::Ratio(0.25), tabs(&[3]), tabs(&[0]));
|
||||
let sides = split(SplitAxis::Horizontal, SplitSize::FixedSecond(200.0), column, tabs(&[2]));
|
||||
assert_eq!(d.layout.root, Some(split(SplitAxis::Horizontal, SplitSize::FixedFirst(200.0), tabs(&[1]), sides)));
|
||||
// Without top and bottom, no outer edge takes a drop: left and right are docks here.
|
||||
for at in [pos2(canvas.center().x, 590.0), pos2(canvas.left() + 5.0, 300.0), pos2(canvas.right() - 5.0, 300.0)] {
|
||||
let mut d = canvas_driver(Permissions::PROTECTED, left_right);
|
||||
d.hold(tab(&d, 3), at);
|
||||
assert!(!d.filled(line(canvas, Zone::Bottom)), "{at:?}");
|
||||
let out = d.release(at);
|
||||
assert!(!moves(&out), "{at:?}: {:?}", out.actions);
|
||||
}
|
||||
// A side frame keeps all four sides.
|
||||
for (zone, y) in [(Zone::Bottom, 590.0), (Zone::Top, side.top() + side.height() * 0.2)] {
|
||||
let mut d = canvas_driver(Permissions::PROTECTED, left_right);
|
||||
@@ -310,13 +297,21 @@ fn a_canvas_that_takes_splits_takes_them_only_on_its_drop_edges() {
|
||||
let beside = Permissions { accepts_splits: true, ..Permissions::PROTECTED };
|
||||
let d = canvas_driver(beside, |_| {});
|
||||
let (body, _) = group(&d, 0);
|
||||
let at = pos2(body.left() + body.width() * 0.3, body.bottom() - 40.0);
|
||||
for (edges, zone) in [(DockStyle::default().drop_edges, Some(Zone::Bottom)), (Sides::LEFT_RIGHT, Some(Zone::Left)), (Sides::NONE, None)] {
|
||||
let mut d = canvas_driver(beside, move |style| style.drop_edges = edges);
|
||||
let out = d.drag(tab(&d, 3), at);
|
||||
match zone {
|
||||
Some(zone) => assert_eq!(out.actions, vec![Action::Move { panel: 3, anchor: 0, placement: Placement::Split(zone) }], "{edges:?}"),
|
||||
None => assert!(!moves(&out), "{:?}", out.actions),
|
||||
// Nearer the bottom than the left, and right of center nearer the right than the top.
|
||||
let low = pos2(body.left() + body.width() * 0.3, body.bottom() - 40.0);
|
||||
let high = pos2(body.right() - body.width() * 0.3, body.top() + 40.0);
|
||||
for (edges, zones) in [
|
||||
(DockStyle::default().drop_edges, [Some(Zone::Bottom), Some(Zone::Top)]),
|
||||
(Sides::LEFT_RIGHT, [Some(Zone::Left), Some(Zone::Right)]),
|
||||
(Sides::NONE, [None, None]),
|
||||
] {
|
||||
for (at, zone) in [low, high].into_iter().zip(zones) {
|
||||
let mut d = canvas_driver(beside, move |style| style.drop_edges = edges);
|
||||
let out = d.drag(tab(&d, 3), at);
|
||||
match zone {
|
||||
Some(zone) => assert_eq!(out.actions, vec![Action::Move { panel: 3, anchor: 0, placement: Placement::Split(zone) }], "{edges:?}"),
|
||||
None => assert!(!moves(&out), "{edges:?}: {:?}", out.actions),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {
|
||||
paths.and_then(|paths| paths.get(path).cloned()).unwrap_or_else(|| path.to_vec())
|
||||
}
|
||||
|
||||
/// The outer edge band under the pointer (P8): the sides of
|
||||
/// The outer edge band under the pointer (P8): the top and bottom of
|
||||
/// [`crate::docking::DockStyle::drop_edges`], all four with
|
||||
/// [`crate::docking::DockStyle::side_edge_zones`]. Returns a docked anchor that is not
|
||||
/// moving, the zone and the preview: a line along the edge area's whole edge, or with side
|
||||
@@ -181,7 +181,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {
|
||||
let band = if self.style.side_edge_zones { crate::docking::targets::SIDE_EDGE_BAND } else { self.style.edge_band };
|
||||
let band = band.min(area.width() / 4.0).min(area.height() / 4.0);
|
||||
let line = |zone| crate::docking::targets::edge_line(area, zone, self.style.drop_line_width);
|
||||
let sides = self.style.drop_sides();
|
||||
let sides = self.style.outer_edges();
|
||||
let edges = [
|
||||
(pointer.y - area.top(), Zone::Top),
|
||||
(area.bottom() - pointer.y, Zone::Bottom),
|
||||
|
||||
@@ -64,11 +64,11 @@ pub struct DockStyle {
|
||||
/// bottom edges add a full-width row, a group's zones are [`Self::side_zone_fraction`] of its
|
||||
/// body, and every preview is a line or a tab outline.
|
||||
pub side_edge_zones: bool,
|
||||
/// The layout's outer edges that take a drop, a new frame along that edge, and the sides of
|
||||
/// a group that takes no tabs (a canvas) that take a split (top and bottom; the left and
|
||||
/// right window edges are new docks). With [`crate::docking::Sides::NONE`], palettes dock
|
||||
/// only through the dock bands. Not used with [`Self::side_edge_zones`], which takes all
|
||||
/// four. Groups that take tabs keep all four sides.
|
||||
/// Which sides of a group that takes no tabs (a canvas), and of the layout's outer edge, take
|
||||
/// a drop (all four). Without [`Self::side_edge_zones`] the outer left and right edges are
|
||||
/// new docks, so only top and bottom apply there. A dock-column app whose palettes dock only
|
||||
/// at the left and right sets [`crate::docking::Sides::NONE`] with [`Self::new_dock_zones`]
|
||||
/// on. Not used with [`Self::side_edge_zones`]. Groups that take tabs keep all four sides.
|
||||
pub drop_edges: super::Sides,
|
||||
/// The share of a group's body, below the tab strip, that means "beside" on each side: of
|
||||
/// its width from the left and right edges, of its height from the top and bottom edges
|
||||
@@ -196,7 +196,7 @@ impl DockStyle {
|
||||
title_height: super::chrome::TITLE_HEIGHT,
|
||||
edge_band: 28.0,
|
||||
side_edge_zones: false,
|
||||
drop_edges: super::Sides::TOP_BOTTOM,
|
||||
drop_edges: super::Sides::ALL,
|
||||
side_zone_fraction: 1.0 / 3.0,
|
||||
drop_line_width: 4.0,
|
||||
new_dock_zones: true,
|
||||
@@ -234,12 +234,19 @@ impl DockStyle {
|
||||
}
|
||||
}
|
||||
|
||||
/// The sides [`Self::drop_edges`] gives in this profile: all four with
|
||||
/// The canvas sides [`Self::drop_edges`] gives in this profile: all four with
|
||||
/// [`Self::side_edge_zones`].
|
||||
pub(super) fn drop_sides(&self) -> super::Sides {
|
||||
if self.side_edge_zones { super::Sides::ALL } else { self.drop_edges }
|
||||
}
|
||||
|
||||
/// The outer edges that take a drop: all four with [`Self::side_edge_zones`], else the top
|
||||
/// and bottom of [`Self::drop_edges`].
|
||||
pub(super) fn outer_edges(&self) -> super::Sides {
|
||||
let sides = self.drop_sides();
|
||||
if self.side_edge_zones { sides } else { super::Sides { left: false, right: false, ..sides } }
|
||||
}
|
||||
|
||||
/// How a group's body divides into drop zones: [`crate::docking::SIDE_EDGE_ZONE_DEPTH`] deep
|
||||
/// with [`Self::side_edge_zones`], else [`Self::side_zone_fraction`] of it, with
|
||||
/// [`Self::drop_line_width`] previews. Pass it to [`crate::docking::resolve_drop_by`].
|
||||
|
||||
+8
-7
@@ -250,7 +250,7 @@ A flyout fits its content the same way, without the title bar.
|
||||
| The seam between two stacked groups of a dock column | A new group between them | `seam_band` (28 pt) |
|
||||
| Each edge of a dock column | A new column on that side | `column_edge_band` (28 pt) |
|
||||
| The docked area's left or right edge without a dock, and an empty dock | A new dock | `new_dock_band` (28 pt) |
|
||||
| The edge area's sides in `drop_edges` (top and bottom; all four with `side_edge_zones`) | A new frame along that whole side, a quarter of the edge area | `edge_band` (28 pt, 8 pt with `side_edge_zones`; at most a quarter of the edge area) |
|
||||
| The edge area's top and bottom in `drop_edges` (all four sides with `side_edge_zones`) | A new frame along that whole side, a quarter of the edge area | `edge_band` (28 pt, 8 pt with `side_edge_zones`; at most a quarter of the edge area) |
|
||||
|
||||
Where a band overlaps a group's outer third, both mean the same side. Without
|
||||
`side_edge_zones`, a band reaches only 4 pt past its line into a tab strip that takes tabs;
|
||||
@@ -261,12 +261,13 @@ A flyout fits its content the same way, without the title bar.
|
||||
one side holds a protected panel, that side. Side panels in split frames then get no band
|
||||
across the whole window, and the drop wraps only the canvas column. A drop on the band
|
||||
anchors on the canvas, so `Placement::Edge` narrows the same way when applied.
|
||||
- `DockStyle::drop_edges` (a `Sides`) lists the edge area's sides that take a drop, and the
|
||||
sides of a group that takes no tabs (a canvas) that take a split; there, the whole body goes
|
||||
to the nearest listed side, and with none listed the canvas takes nothing. Groups that take
|
||||
tabs keep all four sides. The default is top and bottom. An app whose palettes dock only
|
||||
through the dock bands sets `Sides::NONE`; one whose palettes sit left and right of the
|
||||
canvas sets `Sides::LEFT_RIGHT`. `side_edge_zones` uses all four and ignores it.
|
||||
- `DockStyle::drop_edges` (a `Sides`, all four by default) lists which sides of a group that
|
||||
takes no tabs (a canvas), and of the layout's outer edge, take a drop. A canvas's whole body
|
||||
goes to the nearest listed side; with none listed it takes nothing. In the docking profile
|
||||
the outer left and right edges are new docks, so only top and bottom apply there. Groups
|
||||
that take tabs keep all four sides. A dock-column app whose palettes dock only at the left
|
||||
and right, as in AutoCAD, sets `Sides::NONE` with `new_dock_zones` on. Not used with
|
||||
`side_edge_zones`.
|
||||
- With `side_edge_zones` (the split-tree arrangement), a frame's zones are a picture frame
|
||||
instead: trapezoids along the four edges of the body below the tab strip, all four the same
|
||||
depth, `docking::SIDE_EDGE_ZONE_DEPTH` (40 pt), or a quarter of the body's smaller side when
|
||||
|
||||
Reference in new issue
Block a user