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;
|
||||
|
||||
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),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
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