tree: split container drag destinations
This commit is contained in:
parent
795cc7d117
commit
774177390e
2 changed files with 136 additions and 125 deletions
|
|
@ -1,8 +1,11 @@
|
||||||
|
mod drag_destination;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
|
|
||||||
|
pub use drag_destination::default_tile_drag_destination;
|
||||||
pub use tasks::{container_layout, container_render_positions, container_tab_render_textures};
|
pub use tasks::{container_layout, container_render_positions, container_tab_render_textures};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
drag_destination::direction_to_split,
|
||||||
crate::{
|
crate::{
|
||||||
backend::ButtonState,
|
backend::ButtonState,
|
||||||
cursor::KnownCursor,
|
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),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
133
src/tree/container/drag_destination.rs
Normal file
133
src/tree/container/drag_destination.rs
Normal 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),
|
||||||
|
})
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue