summaryrefslogtreecommitdiffstats
path: root/widget/src/pane_grid
diff options
context:
space:
mode:
authorLibravatar Joao Freitas <51237625+jhff@users.noreply.github.com>2023-05-19 11:24:52 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-07-06 07:55:49 +0200
commite5c9dd54b3f51e913f39b38e8907c321c8bfd040 (patch)
tree69c0dc7aa682bec3f00d91b16fecb4bb38bdc8db /widget/src/pane_grid
parent7f805bc5dd9ed38c904d83f9ea931eed6f3234bf (diff)
downloadiced-e5c9dd54b3f51e913f39b38e8907c321c8bfd040.tar.gz
iced-e5c9dd54b3f51e913f39b38e8907c321c8bfd040.tar.bz2
iced-e5c9dd54b3f51e913f39b38e8907c321c8bfd040.zip
Add ability to drag pane to the pane grid edges & optional style for dragged pane
Diffstat (limited to 'widget/src/pane_grid')
-rw-r--r--widget/src/pane_grid/node.rs10
-rw-r--r--widget/src/pane_grid/state.rs89
2 files changed, 86 insertions, 13 deletions
diff --git a/widget/src/pane_grid/node.rs b/widget/src/pane_grid/node.rs
index 3976acd8..6de5920f 100644
--- a/widget/src/pane_grid/node.rs
+++ b/widget/src/pane_grid/node.rs
@@ -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)) {
if let Node::Split { a, b, .. } = self {
a.update(f);
diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs
index 1f034ca3..34781a90 100644
--- a/widget/src/pane_grid/state.rs
+++ b/widget/src/pane_grid/state.rs
@@ -3,7 +3,7 @@
//! [`PaneGrid`]: crate::widget::PaneGrid
use crate::core::{Point, Size};
use crate::pane_grid::{
- Axis, Configuration, Direction, Node, Pane, Region, Split,
+ Axis, Configuration, Direction, Edge, Node, Pane, Region, Split,
};
use std::collections::HashMap;
@@ -173,18 +173,20 @@ impl<T> State<T> {
pub fn split_with(&mut self, target: &Pane, pane: &Pane, region: Region) {
match region {
Region::Center => self.swap(pane, target),
- Region::Top => {
- self.split_and_swap(Axis::Horizontal, target, pane, true)
- }
- Region::Bottom => {
- self.split_and_swap(Axis::Horizontal, target, pane, false)
- }
- Region::Left => {
- self.split_and_swap(Axis::Vertical, target, pane, true)
- }
- Region::Right => {
- self.split_and_swap(Axis::Vertical, target, pane, false)
- }
+ Region::Edge(edge) => match edge {
+ Edge::Top => {
+ self.split_and_swap(Axis::Horizontal, target, pane, true)
+ }
+ Edge::Bottom => {
+ self.split_and_swap(Axis::Horizontal, target, pane, false)
+ }
+ Edge::Left => {
+ self.split_and_swap(Axis::Vertical, target, pane, true)
+ }
+ 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`].
///
/// If you want to swap panes on drag and drop in your [`PaneGrid`], you