mirror of
https://github.com/storytold/craft-libs.git
synced 2026-10-31 07:39:23 +00:00
docking: a column's first tab docks beside its own column
A dock target named by the dragged panel itself anchors on another panel of the same group or column, or leaves the panel in place when it is alone there, instead of failing with InvalidPlacement.
This commit is contained in:
1 parent
ceb75f965e
commit
cef258a356
2 files changed
+34
-1
No files matched your search
@@ -481,3 +481,26 @@ fn right_to_left_mirrors_docks_their_edges_and_new_docks() {
|
||||
d.settle();
|
||||
assert_eq!(d.rect("column-collapse", 5).left(), 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_column_s_first_tab_dropped_on_its_own_column_edge_anchors_on_another_panel() {
|
||||
// Two columns, 0..240 and 240..480; the dragged tab is the first panel of the last one.
|
||||
let wide = |columns: &[&[&[u32]]]| {
|
||||
let mut layout = docked(Side::Start, columns);
|
||||
if let Some(Node::Split { size, .. }) = &mut layout.root {
|
||||
*size = SplitSize::FixedFirst(480.0);
|
||||
}
|
||||
layout
|
||||
};
|
||||
let mut d = Driver::new(wide(&[&[&[2]], &[&[3, 4]]]));
|
||||
let out = d.drag(d.tab(3).center(), pos2(484.0, 300.0));
|
||||
assert_eq!(out.actions, vec![Action::Move { panel: 3, anchor: 4, placement: Placement::Column { after: true } }]);
|
||||
assert_eq!(columns(&d.layout, Side::Start), vec![vec![vec![2]], vec![vec![4]], vec![vec![3]]]);
|
||||
|
||||
// Alone in its column, the panel stays where it is.
|
||||
let layout = wide(&[&[&[2]], &[&[3]]]);
|
||||
let mut d = Driver::new(layout.clone());
|
||||
let out = d.drag(d.tab(3).center(), pos2(484.0, 300.0));
|
||||
assert_eq!(out.actions, vec![]);
|
||||
assert_eq!(d.layout, layout);
|
||||
}
|
||||
@@ -10,7 +10,8 @@ use egui::{Context, Key, Pos2, Rect, Sense, Stroke, StrokeKind, Ui, UiBuilder, p
|
||||
|
||||
use super::{GroupKind, Renderer};
|
||||
use crate::docking::{
|
||||
Action, Column, DockEvent, DockStyle, Group, GroupDrag, GroupGesture, Node, Profile, Side, Target,
|
||||
Action, Column, DockEvent, DockStyle, Group, GroupDrag, GroupGesture, Node, Placement, Profile, Side, Target,
|
||||
dock_model::Unit,
|
||||
targets::{DockDrop, DockTarget, column_edge, horizontal_line, resolve_dock, usable, vertical_line},
|
||||
};
|
||||
use crate::layout::{ResizeHandle, ResizeHandleStyle, SplitAxis};
|
||||
@@ -471,6 +472,15 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {
|
||||
let candidates = self.dock_candidates();
|
||||
let drop = resolve_dock(pointer, &candidates)?;
|
||||
let action = match drop.target.to() {
|
||||
// A target named by the dragged panel is its own group or column: another panel
|
||||
// there names the same one. With none, the drop leaves the panel where it is.
|
||||
Target::At { anchor, placement } if &anchor == panel => {
|
||||
let unit = if matches!(placement, Placement::Column { .. }) { Unit::Column } else { Unit::Group };
|
||||
match self.layout.members(panel, unit).ok()?.into_iter().find(|p| p != panel) {
|
||||
Some(anchor) => Action::Move { panel: panel.clone(), anchor, placement },
|
||||
None => return Some((None, drop.line)),
|
||||
}
|
||||
}
|
||||
Target::At { anchor, placement } => Action::Move { panel: panel.clone(), anchor, placement },
|
||||
to @ Target::NewDock { .. }
|
||||
if self.layout.place(panel).and_then(|place| self.layout.group(&place)).is_some_and(|g| g.panels.len() == 1) =>
|
||||
|
||||
Reference in new issue
Block a user