Add ability to drag pane to the pane grid edges & optional style for dragged pane
This commit is contained in:
parent
7f805bc5dd
commit
e5c9dd54b3
5 changed files with 293 additions and 106 deletions
|
|
@ -108,10 +108,15 @@ impl Application for Example {
|
||||||
Message::Dragged(pane_grid::DragEvent::Dropped {
|
Message::Dragged(pane_grid::DragEvent::Dropped {
|
||||||
pane,
|
pane,
|
||||||
target,
|
target,
|
||||||
region,
|
}) => match target {
|
||||||
}) => {
|
pane_grid::Target::PaneGrid(edge) => {
|
||||||
self.panes.split_with(&target, &pane, region);
|
self.panes.move_to_edge(&pane, edge)
|
||||||
}
|
}
|
||||||
|
pane_grid::Target::Pane {
|
||||||
|
pane: target,
|
||||||
|
region,
|
||||||
|
} => self.panes.split_with(&target, &pane, region),
|
||||||
|
},
|
||||||
Message::Dragged(_) => {}
|
Message::Dragged(_) => {}
|
||||||
Message::TogglePin(pane) => {
|
Message::TogglePin(pane) => {
|
||||||
if let Some(Pane { is_pinned, .. }) = self.panes.get_mut(&pane)
|
if let Some(Pane { is_pinned, .. }) = self.panes.get_mut(&pane)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ pub trait StyleSheet {
|
||||||
/// The supported style of the [`StyleSheet`].
|
/// The supported style of the [`StyleSheet`].
|
||||||
type Style: Default;
|
type Style: Default;
|
||||||
|
|
||||||
/// The [`Region`] to draw when a pane is hovered.
|
/// The [`Appearance`] to draw when a pane is hovered.
|
||||||
fn hovered_region(&self, style: &Self::Style) -> Appearance;
|
fn hovered_region(&self, style: &Self::Style) -> Appearance;
|
||||||
|
|
||||||
/// The [`Line`] to draw when a split is picked.
|
/// The [`Line`] to draw when a split is picked.
|
||||||
|
|
|
||||||
|
|
@ -581,39 +581,49 @@ pub fn update<'a, Message, T: Draggable>(
|
||||||
| Event::Touch(touch::Event::FingerLost { .. }) => {
|
| Event::Touch(touch::Event::FingerLost { .. }) => {
|
||||||
if let Some((pane, _)) = action.picked_pane() {
|
if let Some((pane, _)) = action.picked_pane() {
|
||||||
if let Some(on_drag) = on_drag {
|
if let Some(on_drag) = on_drag {
|
||||||
let dropped_region =
|
if let Some(cursor_position) = cursor.position() {
|
||||||
cursor.position().and_then(|cursor_position| {
|
let event = if let Some(edge) =
|
||||||
contents
|
in_edge(layout, cursor_position)
|
||||||
|
{
|
||||||
|
DragEvent::Dropped {
|
||||||
|
pane,
|
||||||
|
target: Target::PaneGrid(edge),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let dropped_region = contents
|
||||||
.zip(layout.children())
|
.zip(layout.children())
|
||||||
.filter_map(|(target, layout)| {
|
.filter_map(|(target, layout)| {
|
||||||
layout_region(layout, cursor_position)
|
layout_region(layout, cursor_position)
|
||||||
.map(|region| (target, region))
|
.map(|region| (target, region))
|
||||||
})
|
})
|
||||||
.next()
|
.next();
|
||||||
});
|
|
||||||
|
|
||||||
let event = match dropped_region {
|
match dropped_region {
|
||||||
Some(((target, _), region)) if pane != target => {
|
Some(((target, _), region))
|
||||||
DragEvent::Dropped {
|
if pane != target =>
|
||||||
pane,
|
{
|
||||||
target,
|
DragEvent::Dropped {
|
||||||
region,
|
pane,
|
||||||
|
target: Target::Pane {
|
||||||
|
pane: target,
|
||||||
|
region,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => DragEvent::Canceled { pane },
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
_ => DragEvent::Canceled { pane },
|
|
||||||
};
|
|
||||||
|
|
||||||
shell.publish(on_drag(event));
|
shell.publish(on_drag(event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*action = state::Action::Idle;
|
|
||||||
|
|
||||||
event_status = event::Status::Captured;
|
event_status = event::Status::Captured;
|
||||||
} else if action.picked_split().is_some() {
|
} else if action.picked_split().is_some() {
|
||||||
*action = state::Action::Idle;
|
|
||||||
|
|
||||||
event_status = event::Status::Captured;
|
event_status = event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*action = state::Action::Idle;
|
||||||
}
|
}
|
||||||
Event::Mouse(mouse::Event::CursorMoved { .. })
|
Event::Mouse(mouse::Event::CursorMoved { .. })
|
||||||
| Event::Touch(touch::Event::FingerMoved { .. }) => {
|
| Event::Touch(touch::Event::FingerMoved { .. }) => {
|
||||||
|
|
@ -671,13 +681,13 @@ fn layout_region(layout: Layout<'_>, cursor_position: Point) -> Option<Region> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let region = if cursor_position.x < (bounds.x + bounds.width / 3.0) {
|
let region = if cursor_position.x < (bounds.x + bounds.width / 3.0) {
|
||||||
Region::Left
|
Region::Edge(Edge::Left)
|
||||||
} else if cursor_position.x > (bounds.x + 2.0 * bounds.width / 3.0) {
|
} else if cursor_position.x > (bounds.x + 2.0 * bounds.width / 3.0) {
|
||||||
Region::Right
|
Region::Edge(Edge::Right)
|
||||||
} else if cursor_position.y < (bounds.y + bounds.height / 3.0) {
|
} else if cursor_position.y < (bounds.y + bounds.height / 3.0) {
|
||||||
Region::Top
|
Region::Edge(Edge::Top)
|
||||||
} else if cursor_position.y > (bounds.y + 2.0 * bounds.height / 3.0) {
|
} else if cursor_position.y > (bounds.y + 2.0 * bounds.height / 3.0) {
|
||||||
Region::Bottom
|
Region::Edge(Edge::Bottom)
|
||||||
} else {
|
} else {
|
||||||
Region::Center
|
Region::Center
|
||||||
};
|
};
|
||||||
|
|
@ -833,28 +843,32 @@ pub fn draw<Renderer, T>(
|
||||||
|
|
||||||
let mut render_picked_pane = None;
|
let mut render_picked_pane = None;
|
||||||
|
|
||||||
for ((id, pane), layout) in contents.zip(layout.children()) {
|
let cursor_in_edge = cursor
|
||||||
|
.position()
|
||||||
|
.and_then(|cursor_position| in_edge(layout, cursor_position));
|
||||||
|
|
||||||
|
for ((id, pane), pane_layout) in contents.zip(layout.children()) {
|
||||||
match picked_pane {
|
match picked_pane {
|
||||||
Some((dragging, origin)) if id == dragging => {
|
Some((dragging, origin)) if id == dragging => {
|
||||||
render_picked_pane = Some((pane, origin, layout));
|
render_picked_pane = Some((pane, origin, pane_layout));
|
||||||
}
|
}
|
||||||
Some((dragging, _)) if id != dragging => {
|
Some((dragging, _)) if id != dragging => {
|
||||||
draw_pane(
|
draw_pane(
|
||||||
pane,
|
pane,
|
||||||
renderer,
|
renderer,
|
||||||
default_style,
|
default_style,
|
||||||
layout,
|
pane_layout,
|
||||||
pane_cursor,
|
pane_cursor,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
||||||
if picked_pane.is_some() {
|
if picked_pane.is_some() && cursor_in_edge.is_none() {
|
||||||
if let Some(region) =
|
if let Some(region) =
|
||||||
cursor.position().and_then(|cursor_position| {
|
cursor.position().and_then(|cursor_position| {
|
||||||
layout_region(layout, cursor_position)
|
layout_region(pane_layout, cursor_position)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let bounds = layout_region_bounds(layout, region);
|
let bounds = layout_region_bounds(pane_layout, region);
|
||||||
let hovered_region_style = theme.hovered_region(style);
|
let hovered_region_style = theme.hovered_region(style);
|
||||||
|
|
||||||
renderer.fill_quad(
|
renderer.fill_quad(
|
||||||
|
|
@ -875,7 +889,7 @@ pub fn draw<Renderer, T>(
|
||||||
pane,
|
pane,
|
||||||
renderer,
|
renderer,
|
||||||
default_style,
|
default_style,
|
||||||
layout,
|
pane_layout,
|
||||||
pane_cursor,
|
pane_cursor,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -883,6 +897,23 @@ pub fn draw<Renderer, T>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if picked_pane.is_some() {
|
||||||
|
if let Some(edge) = cursor_in_edge {
|
||||||
|
let hovered_region_style = theme.hovered_region(style);
|
||||||
|
let bounds = edge_bounds(layout, edge);
|
||||||
|
|
||||||
|
renderer.fill_quad(
|
||||||
|
renderer::Quad {
|
||||||
|
bounds,
|
||||||
|
border_radius: hovered_region_style.border_radius.into(),
|
||||||
|
border_width: hovered_region_style.border_width,
|
||||||
|
border_color: hovered_region_style.border_color,
|
||||||
|
},
|
||||||
|
theme.hovered_region(style).background,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Render picked pane last
|
// Render picked pane last
|
||||||
if let Some((pane, origin, layout)) = render_picked_pane {
|
if let Some((pane, origin, layout)) = render_picked_pane {
|
||||||
if let Some(cursor_position) = cursor.position() {
|
if let Some(cursor_position) = cursor.position() {
|
||||||
|
|
@ -907,67 +938,127 @@ pub fn draw<Renderer, T>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((axis, split_region, is_picked)) = picked_split {
|
if picked_pane.is_none() {
|
||||||
let highlight = if is_picked {
|
if let Some((axis, split_region, is_picked)) = picked_split {
|
||||||
theme.picked_split(style)
|
let highlight = if is_picked {
|
||||||
} else {
|
theme.picked_split(style)
|
||||||
theme.hovered_split(style)
|
} else {
|
||||||
};
|
theme.hovered_split(style)
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(highlight) = highlight {
|
if let Some(highlight) = highlight {
|
||||||
renderer.fill_quad(
|
renderer.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds: match axis {
|
bounds: match axis {
|
||||||
Axis::Horizontal => Rectangle {
|
Axis::Horizontal => Rectangle {
|
||||||
x: split_region.x,
|
x: split_region.x,
|
||||||
y: (split_region.y
|
y: (split_region.y
|
||||||
+ (split_region.height - highlight.width)
|
+ (split_region.height - highlight.width)
|
||||||
/ 2.0)
|
/ 2.0)
|
||||||
.round(),
|
.round(),
|
||||||
width: split_region.width,
|
width: split_region.width,
|
||||||
height: highlight.width,
|
height: highlight.width,
|
||||||
},
|
},
|
||||||
Axis::Vertical => Rectangle {
|
Axis::Vertical => Rectangle {
|
||||||
x: (split_region.x
|
x: (split_region.x
|
||||||
+ (split_region.width - highlight.width) / 2.0)
|
+ (split_region.width - highlight.width)
|
||||||
.round(),
|
/ 2.0)
|
||||||
y: split_region.y,
|
.round(),
|
||||||
width: highlight.width,
|
y: split_region.y,
|
||||||
height: split_region.height,
|
width: highlight.width,
|
||||||
|
height: split_region.height,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
border_radius: 0.0.into(),
|
||||||
|
border_width: 0.0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
},
|
},
|
||||||
border_radius: 0.0.into(),
|
highlight.color,
|
||||||
border_width: 0.0,
|
);
|
||||||
border_color: Color::TRANSPARENT,
|
}
|
||||||
},
|
|
||||||
highlight.color,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const THICKNESS_RATIO: f32 = 25.0;
|
||||||
|
|
||||||
|
fn in_edge(layout: Layout<'_>, cursor: Point) -> Option<Edge> {
|
||||||
|
let bounds = layout.bounds();
|
||||||
|
|
||||||
|
let height_thickness = bounds.height / THICKNESS_RATIO;
|
||||||
|
let width_thickness = bounds.width / THICKNESS_RATIO;
|
||||||
|
let thickness = height_thickness.min(width_thickness);
|
||||||
|
|
||||||
|
if cursor.x > bounds.x && cursor.x < bounds.x + thickness {
|
||||||
|
Some(Edge::Left)
|
||||||
|
} else if cursor.x > bounds.x + bounds.width - thickness
|
||||||
|
&& cursor.x < bounds.x + bounds.width
|
||||||
|
{
|
||||||
|
Some(Edge::Right)
|
||||||
|
} else if cursor.y > bounds.y && cursor.y < bounds.y + thickness {
|
||||||
|
Some(Edge::Top)
|
||||||
|
} else if cursor.y > bounds.y + bounds.height - thickness
|
||||||
|
&& cursor.y < bounds.y + bounds.height
|
||||||
|
{
|
||||||
|
Some(Edge::Bottom)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn edge_bounds(layout: Layout<'_>, edge: Edge) -> Rectangle {
|
||||||
|
let bounds = layout.bounds();
|
||||||
|
|
||||||
|
let height_thickness = bounds.height / THICKNESS_RATIO;
|
||||||
|
let width_thickness = bounds.width / THICKNESS_RATIO;
|
||||||
|
let thickness = height_thickness.min(width_thickness);
|
||||||
|
|
||||||
|
match edge {
|
||||||
|
Edge::Top => Rectangle {
|
||||||
|
height: thickness,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
|
Edge::Left => Rectangle {
|
||||||
|
width: thickness,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
|
Edge::Right => Rectangle {
|
||||||
|
x: bounds.x + bounds.width - thickness,
|
||||||
|
width: thickness,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
|
Edge::Bottom => Rectangle {
|
||||||
|
y: bounds.y + bounds.height - thickness,
|
||||||
|
height: thickness,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn layout_region_bounds(layout: Layout<'_>, region: Region) -> Rectangle {
|
fn layout_region_bounds(layout: Layout<'_>, region: Region) -> Rectangle {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
||||||
match region {
|
match region {
|
||||||
Region::Center => bounds,
|
Region::Center => bounds,
|
||||||
Region::Top => Rectangle {
|
Region::Edge(edge) => match edge {
|
||||||
height: bounds.height / 2.0,
|
Edge::Top => Rectangle {
|
||||||
..bounds
|
height: bounds.height / 2.0,
|
||||||
},
|
..bounds
|
||||||
Region::Left => Rectangle {
|
},
|
||||||
width: bounds.width / 2.0,
|
Edge::Left => Rectangle {
|
||||||
..bounds
|
width: bounds.width / 2.0,
|
||||||
},
|
..bounds
|
||||||
Region::Right => Rectangle {
|
},
|
||||||
x: bounds.x + bounds.width / 2.0,
|
Edge::Right => Rectangle {
|
||||||
width: bounds.width / 2.0,
|
x: bounds.x + bounds.width / 2.0,
|
||||||
..bounds
|
width: bounds.width / 2.0,
|
||||||
},
|
..bounds
|
||||||
Region::Bottom => Rectangle {
|
},
|
||||||
y: bounds.y + bounds.height / 2.0,
|
Edge::Bottom => Rectangle {
|
||||||
height: bounds.height / 2.0,
|
y: bounds.y + bounds.height / 2.0,
|
||||||
..bounds
|
height: bounds.height / 2.0,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -986,11 +1077,8 @@ pub enum DragEvent {
|
||||||
/// The picked [`Pane`].
|
/// The picked [`Pane`].
|
||||||
pane: Pane,
|
pane: Pane,
|
||||||
|
|
||||||
/// The [`Pane`] where the picked one was dropped on.
|
/// The [`Target`] where the picked [`Pane`] was dropped on.
|
||||||
target: Pane,
|
target: Target,
|
||||||
|
|
||||||
/// The [`Region`] of the target [`Pane`] where the picked one was dropped on.
|
|
||||||
region: Region,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A [`Pane`] was picked and then dropped outside of other [`Pane`]
|
/// A [`Pane`] was picked and then dropped outside of other [`Pane`]
|
||||||
|
|
@ -1001,19 +1089,40 @@ pub enum DragEvent {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The [`Target`] area a pane can be dropped on.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum Target {
|
||||||
|
/// The [`Edge`} of the full [`PaneGrid`].
|
||||||
|
PaneGrid(Edge),
|
||||||
|
/// A single [`Pane`] of the [`PaneGrid`].
|
||||||
|
Pane {
|
||||||
|
/// The targetted [`Pane`].
|
||||||
|
pane: Pane,
|
||||||
|
/// The targetted area of the [`Pane`].
|
||||||
|
region: Region,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
/// The region of a [`Pane`].
|
/// The region of a [`Pane`].
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub enum Region {
|
pub enum Region {
|
||||||
/// Center region.
|
/// Center region.
|
||||||
#[default]
|
#[default]
|
||||||
Center,
|
Center,
|
||||||
/// Top region.
|
/// Edge region.
|
||||||
|
Edge(Edge),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The edges of an area.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum Edge {
|
||||||
|
/// Top edge.
|
||||||
Top,
|
Top,
|
||||||
/// Left region.
|
/// Left edge.
|
||||||
Left,
|
Left,
|
||||||
/// Right region.
|
/// Right edge.
|
||||||
Right,
|
Right,
|
||||||
/// Bottom region.
|
/// Bottom edge.
|
||||||
Bottom,
|
Bottom,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,16 @@ impl Node {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn split_inverse(&mut self, id: Split, axis: Axis, pane: Pane) {
|
||||||
|
*self = Node::Split {
|
||||||
|
id,
|
||||||
|
axis,
|
||||||
|
ratio: 0.5,
|
||||||
|
a: Box::new(Node::Pane(pane)),
|
||||||
|
b: Box::new(self.clone()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn update(&mut self, f: &impl Fn(&mut Node)) {
|
pub(crate) fn update(&mut self, f: &impl Fn(&mut Node)) {
|
||||||
if let Node::Split { a, b, .. } = self {
|
if let Node::Split { a, b, .. } = self {
|
||||||
a.update(f);
|
a.update(f);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
//! [`PaneGrid`]: crate::widget::PaneGrid
|
//! [`PaneGrid`]: crate::widget::PaneGrid
|
||||||
use crate::core::{Point, Size};
|
use crate::core::{Point, Size};
|
||||||
use crate::pane_grid::{
|
use crate::pane_grid::{
|
||||||
Axis, Configuration, Direction, Node, Pane, Region, Split,
|
Axis, Configuration, Direction, Edge, Node, Pane, Region, Split,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
@ -173,18 +173,20 @@ impl<T> State<T> {
|
||||||
pub fn split_with(&mut self, target: &Pane, pane: &Pane, region: Region) {
|
pub fn split_with(&mut self, target: &Pane, pane: &Pane, region: Region) {
|
||||||
match region {
|
match region {
|
||||||
Region::Center => self.swap(pane, target),
|
Region::Center => self.swap(pane, target),
|
||||||
Region::Top => {
|
Region::Edge(edge) => match edge {
|
||||||
self.split_and_swap(Axis::Horizontal, target, pane, true)
|
Edge::Top => {
|
||||||
}
|
self.split_and_swap(Axis::Horizontal, target, pane, true)
|
||||||
Region::Bottom => {
|
}
|
||||||
self.split_and_swap(Axis::Horizontal, target, pane, false)
|
Edge::Bottom => {
|
||||||
}
|
self.split_and_swap(Axis::Horizontal, target, pane, false)
|
||||||
Region::Left => {
|
}
|
||||||
self.split_and_swap(Axis::Vertical, target, pane, true)
|
Edge::Left => {
|
||||||
}
|
self.split_and_swap(Axis::Vertical, target, pane, true)
|
||||||
Region::Right => {
|
}
|
||||||
self.split_and_swap(Axis::Vertical, target, pane, false)
|
Edge::Right => {
|
||||||
}
|
self.split_and_swap(Axis::Vertical, target, pane, false)
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,6 +206,67 @@ impl<T> State<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Move [`Pane`] to an [`Edge`] of the [`PaneGrid`].
|
||||||
|
pub fn move_to_edge(&mut self, pane: &Pane, edge: Edge) {
|
||||||
|
match edge {
|
||||||
|
Edge::Top => {
|
||||||
|
self.split_major_node_and_swap(Axis::Horizontal, pane, true)
|
||||||
|
}
|
||||||
|
Edge::Bottom => {
|
||||||
|
self.split_major_node_and_swap(Axis::Horizontal, pane, false)
|
||||||
|
}
|
||||||
|
Edge::Left => {
|
||||||
|
self.split_major_node_and_swap(Axis::Vertical, pane, true)
|
||||||
|
}
|
||||||
|
Edge::Right => {
|
||||||
|
self.split_major_node_and_swap(Axis::Vertical, pane, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_major_node_and_swap(
|
||||||
|
&mut self,
|
||||||
|
axis: Axis,
|
||||||
|
pane: &Pane,
|
||||||
|
swap: bool,
|
||||||
|
) {
|
||||||
|
if let Some((state, _)) = self.close(pane) {
|
||||||
|
let _ = self.split_major_node(axis, state, swap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_major_node(
|
||||||
|
&mut self,
|
||||||
|
axis: Axis,
|
||||||
|
state: T,
|
||||||
|
swap: bool,
|
||||||
|
) -> Option<(Pane, Split)> {
|
||||||
|
let major_node = &mut self.internal.layout;
|
||||||
|
|
||||||
|
let new_pane = {
|
||||||
|
self.internal.last_id = self.internal.last_id.checked_add(1)?;
|
||||||
|
|
||||||
|
Pane(self.internal.last_id)
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_split = {
|
||||||
|
self.internal.last_id = self.internal.last_id.checked_add(1)?;
|
||||||
|
|
||||||
|
Split(self.internal.last_id)
|
||||||
|
};
|
||||||
|
|
||||||
|
if swap {
|
||||||
|
major_node.split_inverse(new_split, axis, new_pane)
|
||||||
|
} else {
|
||||||
|
major_node.split(new_split, axis, new_pane)
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = self.panes.insert(new_pane, state);
|
||||||
|
let _ = self.maximized.take();
|
||||||
|
|
||||||
|
Some((new_pane, new_split))
|
||||||
|
}
|
||||||
|
|
||||||
/// Swaps the position of the provided panes in the [`State`].
|
/// Swaps the position of the provided panes in the [`State`].
|
||||||
///
|
///
|
||||||
/// If you want to swap panes on drag and drop in your [`PaneGrid`], you
|
/// If you want to swap panes on drag and drop in your [`PaneGrid`], you
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue