1
0
Fork 0
forked from wry/wry

tree: split container drag destinations

This commit is contained in:
kossLAN 2026-05-29 21:13:54 -04:00
parent 795cc7d117
commit 774177390e
No known key found for this signature in database
2 changed files with 136 additions and 125 deletions

View file

@ -1,8 +1,11 @@
mod drag_destination;
mod tasks;
pub use drag_destination::default_tile_drag_destination;
pub use tasks::{container_layout, container_render_positions, container_tab_render_textures};
use {
drag_destination::direction_to_split,
crate::{
backend::ButtonState,
cursor::KnownCursor,
@ -2521,128 +2524,3 @@ impl ToplevelNodeBase for ContainerNode {
}
}
}
fn direction_to_split(dir: Direction) -> (ContainerSplit, bool) {
match dir {
Direction::Left => (ContainerSplit::Horizontal, true),
Direction::Down => (ContainerSplit::Vertical, false),
Direction::Up => (ContainerSplit::Vertical, true),
Direction::Right => (ContainerSplit::Horizontal, false),
Direction::Unspecified => (ContainerSplit::Horizontal, true),
}
}
fn tile_drag_destination_in_mono(
tl: Rc<dyn ToplevelNode>,
abs_bounds: Rect,
abs_x: i32,
abs_y: i32,
) -> TileDragDestination {
let mut x1 = abs_bounds.x1();
let mut x2 = abs_bounds.x2();
let mut y1 = abs_bounds.y1();
let mut y2 = abs_bounds.y2();
let dx = (x2 - x1) / 3;
let dy = (y2 - y1) / 3;
let mut split_before = true;
let mut split = ContainerSplit::Horizontal;
if abs_x < x1 + dx {
x2 = x1 + dx;
} else if abs_x > x2 - dx {
split_before = false;
x1 = x2 - dx;
} else {
split = ContainerSplit::Vertical;
x1 += dx;
x2 -= dx;
if abs_y < y1 + dy {
y2 = y1 + dy;
} else if abs_y > y2 - dy {
split_before = false;
y1 = y2 - dy;
} else {
let rect = Rect::new_saturating(x1, y1 + dy, x2, y2 - dy);
return TileDragDestination {
highlight: rect,
ty: TddType::Replace(tl),
};
}
}
let rect = Rect::new_saturating(x1, y1, x2, y2);
TileDragDestination {
highlight: rect,
ty: TddType::Split {
node: tl,
split,
before: split_before,
},
}
}
fn tile_drag_destination_in_split(
tl: Rc<dyn ToplevelNode>,
split: ContainerSplit,
abs_bounds: Rect,
mut abs_x: i32,
mut abs_y: i32,
) -> TileDragDestination {
let mut x1 = abs_bounds.x1();
let mut x2 = abs_bounds.x2();
let mut y1 = abs_bounds.y1();
let mut y2 = abs_bounds.y2();
macro_rules! swap {
() => {
if split == ContainerSplit::Horizontal {
mem::swap(&mut x1, &mut y1);
mem::swap(&mut x2, &mut y2);
mem::swap(&mut abs_x, &mut abs_y);
}
};
}
swap!();
let mut split_before = false;
let mut split_after = false;
let dx = (x2 - x1) / 3;
if abs_x < x1 + dx {
split_before = true;
x2 = x1 + dx;
} else if abs_x < x2 - dx {
x1 += dx;
x2 -= dx;
} else {
split_after = true;
x1 = x2 - dx;
}
swap!();
let rect = Rect::new_saturating(x1, y1, x2, y2);
let ty = if split_before || split_after {
TddType::Split {
node: tl,
split: split.other(),
before: split_before,
}
} else {
TddType::Replace(tl)
};
TileDragDestination {
highlight: rect,
ty,
}
}
pub fn default_tile_drag_destination(
tl: Rc<dyn ToplevelNode>,
source: NodeId,
split: Option<ContainerSplit>,
abs_bounds: Rect,
abs_x: i32,
abs_y: i32,
) -> Option<TileDragDestination> {
if tl.node_id() == source {
return None;
}
Some(match split {
None => tile_drag_destination_in_mono(tl, abs_bounds, abs_x, abs_y),
Some(s) => tile_drag_destination_in_split(tl, s, abs_bounds, abs_x, abs_y),
})
}

View file

@ -0,0 +1,133 @@
use {
super::ContainerSplit,
crate::{
rect::Rect,
tree::{Direction, NodeId, TddType, TileDragDestination, ToplevelNode},
},
std::{mem, rc::Rc},
};
pub(super) fn direction_to_split(dir: Direction) -> (ContainerSplit, bool) {
match dir {
Direction::Left => (ContainerSplit::Horizontal, true),
Direction::Down => (ContainerSplit::Vertical, false),
Direction::Up => (ContainerSplit::Vertical, true),
Direction::Right => (ContainerSplit::Horizontal, false),
Direction::Unspecified => (ContainerSplit::Horizontal, true),
}
}
fn tile_drag_destination_in_mono(
tl: Rc<dyn ToplevelNode>,
abs_bounds: Rect,
abs_x: i32,
abs_y: i32,
) -> TileDragDestination {
let mut x1 = abs_bounds.x1();
let mut x2 = abs_bounds.x2();
let mut y1 = abs_bounds.y1();
let mut y2 = abs_bounds.y2();
let dx = (x2 - x1) / 3;
let dy = (y2 - y1) / 3;
let mut split_before = true;
let mut split = ContainerSplit::Horizontal;
if abs_x < x1 + dx {
x2 = x1 + dx;
} else if abs_x > x2 - dx {
split_before = false;
x1 = x2 - dx;
} else {
split = ContainerSplit::Vertical;
x1 += dx;
x2 -= dx;
if abs_y < y1 + dy {
y2 = y1 + dy;
} else if abs_y > y2 - dy {
split_before = false;
y1 = y2 - dy;
} else {
let rect = Rect::new_saturating(x1, y1 + dy, x2, y2 - dy);
return TileDragDestination {
highlight: rect,
ty: TddType::Replace(tl),
};
}
}
let rect = Rect::new_saturating(x1, y1, x2, y2);
TileDragDestination {
highlight: rect,
ty: TddType::Split {
node: tl,
split,
before: split_before,
},
}
}
fn tile_drag_destination_in_split(
tl: Rc<dyn ToplevelNode>,
split: ContainerSplit,
abs_bounds: Rect,
mut abs_x: i32,
mut abs_y: i32,
) -> TileDragDestination {
let mut x1 = abs_bounds.x1();
let mut x2 = abs_bounds.x2();
let mut y1 = abs_bounds.y1();
let mut y2 = abs_bounds.y2();
macro_rules! swap {
() => {
if split == ContainerSplit::Horizontal {
mem::swap(&mut x1, &mut y1);
mem::swap(&mut x2, &mut y2);
mem::swap(&mut abs_x, &mut abs_y);
}
};
}
swap!();
let mut split_before = false;
let mut split_after = false;
let dx = (x2 - x1) / 3;
if abs_x < x1 + dx {
split_before = true;
x2 = x1 + dx;
} else if abs_x < x2 - dx {
x1 += dx;
x2 -= dx;
} else {
split_after = true;
x1 = x2 - dx;
}
swap!();
let rect = Rect::new_saturating(x1, y1, x2, y2);
let ty = if split_before || split_after {
TddType::Split {
node: tl,
split: split.other(),
before: split_before,
}
} else {
TddType::Replace(tl)
};
TileDragDestination {
highlight: rect,
ty,
}
}
pub fn default_tile_drag_destination(
tl: Rc<dyn ToplevelNode>,
source: NodeId,
split: Option<ContainerSplit>,
abs_bounds: Rect,
abs_x: i32,
abs_y: i32,
) -> Option<TileDragDestination> {
if tl.node_id() == source {
return None;
}
Some(match split {
None => tile_drag_destination_in_mono(tl, abs_bounds, abs_x, abs_y),
Some(s) => tile_drag_destination_in_split(tl, s, abs_bounds, abs_x, abs_y),
})
}