From 415fd4f643d385dad39bd0ee5a47de384643dcf3 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Fri, 4 Oct 2024 11:27:02 -0700 Subject: Use BTreeMap for Ord iteration of panes This ensures continuity in how panes are iterated on when building widget state --- widget/src/pane_grid/state.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'widget/src/pane_grid/state.rs') diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index c20c3b9c..f5d2bb02 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -6,7 +6,7 @@ use crate::pane_grid::{ Axis, Configuration, Direction, Edge, Node, Pane, Region, Split, Target, }; -use rustc_hash::FxHashMap; +use std::collections::BTreeMap; /// The state of a [`PaneGrid`]. /// @@ -25,7 +25,7 @@ pub struct State { /// The panes of the [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid - pub panes: FxHashMap, + pub panes: BTreeMap, /// The internal state of the [`PaneGrid`]. /// @@ -52,7 +52,7 @@ impl State { /// Creates a new [`State`] with the given [`Configuration`]. pub fn with_configuration(config: impl Into>) -> Self { - let mut panes = FxHashMap::default(); + let mut panes = BTreeMap::default(); let internal = Internal::from_configuration(&mut panes, config.into(), 0); @@ -353,7 +353,7 @@ impl Internal { /// /// [`PaneGrid`]: super::PaneGrid pub fn from_configuration( - panes: &mut FxHashMap, + panes: &mut BTreeMap, content: Configuration, next_id: usize, ) -> Self { -- cgit From 9ac3318357d636cde22ae34f7b2cdeddd3f55cdb Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Fri, 4 Oct 2024 11:31:14 -0700 Subject: Retain widget state against incoming panes We can associate each state with a `Pane` and compare that against the new panes to remove states w/ respective panes which no longer exist. Because we always increment `Pane`, new states are always added to the end, so this retain + add new state approach will ensure continuity when panes are added & removed --- widget/src/pane_grid/state.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'widget/src/pane_grid/state.rs') diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index f5d2bb02..e1934930 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -343,7 +343,7 @@ impl State { /// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone)] pub struct Internal { - layout: Node, + pub(super) layout: Node, last_id: usize, } @@ -397,11 +397,12 @@ impl Internal { /// The current action of a [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Default)] pub enum Action { /// The [`PaneGrid`] is idle. /// /// [`PaneGrid`]: super::PaneGrid + #[default] Idle, /// A [`Pane`] in the [`PaneGrid`] is being dragged. /// @@ -441,9 +442,8 @@ impl Action { } } -impl Internal { - /// The layout [`Node`] of the [`Internal`] state - pub fn layout(&self) -> &Node { - &self.layout - } +#[derive(Default)] +pub(super) struct Widget { + pub action: Action, + pub panes: Vec, } -- cgit From 5ebd8ac83f6c173bd24de146bf582f049663a330 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Fri, 4 Oct 2024 11:34:14 -0700 Subject: Keep `Pane` associated to state / layout after swap State continuity is dependent on keeping a node associated to it's original `Pane` id. When splitting -> swapping nodes, we need to assign it back to the original `Pane` to enforce continuity. --- widget/src/pane_grid/state.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'widget/src/pane_grid/state.rs') diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index e1934930..b7aef67d 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -228,8 +228,15 @@ impl State { ) { if let Some((state, _)) = self.close(pane) { if let Some((new_pane, _)) = self.split(axis, target, state) { + // Ensure new node corresponds to original `Pane` for state continuity + self.swap(pane, new_pane); + let _ = self + .panes + .remove(&new_pane) + .and_then(|state| self.panes.insert(pane, state)); + if swap { - self.swap(target, new_pane); + self.swap(target, pane); } } } @@ -262,7 +269,16 @@ impl State { swap: bool, ) { if let Some((state, _)) = self.close(pane) { - let _ = self.split_node(axis, None, state, swap); + if let Some((new_pane, _)) = + self.split_node(axis, None, state, swap) + { + // Ensure new node corresponds to original `Pane` for state continuity + self.swap(pane, new_pane); + let _ = self + .panes + .remove(&new_pane) + .and_then(|state| self.panes.insert(pane, state)); + } } } -- cgit From 659669dd5810d470d51f528495cab2f676eb58ed Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 24 Oct 2024 13:47:28 +0200 Subject: Remove duplicated `maximized` state in `pane_grid` --- widget/src/pane_grid/state.rs | 44 +++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'widget/src/pane_grid/state.rs') diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index b7aef67d..f7e8f750 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -6,6 +6,7 @@ use crate::pane_grid::{ Axis, Configuration, Direction, Edge, Node, Pane, Region, Split, Target, }; +use std::borrow::Cow; use std::collections::BTreeMap; /// The state of a [`PaneGrid`]. @@ -31,11 +32,6 @@ pub struct State { /// /// [`PaneGrid`]: super::PaneGrid pub internal: Internal, - - /// The maximized [`Pane`] of the [`PaneGrid`]. - /// - /// [`PaneGrid`]: super::PaneGrid - pub(super) maximized: Option, } impl State { @@ -57,11 +53,7 @@ impl State { let internal = Internal::from_configuration(&mut panes, config.into(), 0); - State { - panes, - internal, - maximized: None, - } + State { panes, internal } } /// Returns the total amount of panes in the [`State`]. @@ -214,7 +206,7 @@ impl State { } let _ = self.panes.insert(new_pane, state); - let _ = self.maximized.take(); + let _ = self.internal.maximized.take(); Some((new_pane, new_split)) } @@ -319,8 +311,8 @@ impl State { /// Closes the given [`Pane`] and returns its internal state and its closest /// sibling, if it exists. pub fn close(&mut self, pane: Pane) -> Option<(T, Pane)> { - if self.maximized == Some(pane) { - let _ = self.maximized.take(); + if self.internal.maximized == Some(pane) { + let _ = self.internal.maximized.take(); } if let Some(sibling) = self.internal.layout.remove(pane) { @@ -335,7 +327,7 @@ impl State { /// /// [`PaneGrid`]: super::PaneGrid pub fn maximize(&mut self, pane: Pane) { - self.maximized = Some(pane); + self.internal.maximized = Some(pane); } /// Restore the currently maximized [`Pane`] to it's normal size. All panes @@ -343,14 +335,14 @@ impl State { /// /// [`PaneGrid`]: super::PaneGrid pub fn restore(&mut self) { - let _ = self.maximized.take(); + let _ = self.internal.maximized.take(); } /// Returns the maximized [`Pane`] of the [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid pub fn maximized(&self) -> Option { - self.maximized + self.internal.maximized } } @@ -359,8 +351,9 @@ impl State { /// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone)] pub struct Internal { - pub(super) layout: Node, + layout: Node, last_id: usize, + maximized: Option, } impl Internal { @@ -406,7 +399,22 @@ impl Internal { } }; - Self { layout, last_id } + Self { + layout, + last_id, + maximized: None, + } + } + + pub(super) fn layout(&self) -> Cow<'_, Node> { + match self.maximized { + Some(pane) => Cow::Owned(Node::Pane(pane)), + None => Cow::Borrowed(&self.layout), + } + } + + pub(super) fn maximized(&self) -> Option { + self.maximized } } -- cgit From 55504ffcd41a5f1c8c35889501337a729b6aac28 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 24 Oct 2024 13:55:04 +0200 Subject: Rename `state::Widget` to `pane_grid::Memory` --- widget/src/pane_grid/state.rs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'widget/src/pane_grid/state.rs') diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index f7e8f750..67cd3bf2 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -465,9 +465,3 @@ impl Action { } } } - -#[derive(Default)] -pub(super) struct Widget { - pub action: Action, - pub panes: Vec, -} -- cgit From d08bc6e45d12c7a5e4037c20673ff832eb7802ec Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 24 Oct 2024 14:17:38 +0200 Subject: Add `relabel` helper to `pane_grid::State` --- widget/src/pane_grid/state.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'widget/src/pane_grid/state.rs') diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index 67cd3bf2..2f8a64ea 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -220,12 +220,8 @@ impl State { ) { if let Some((state, _)) = self.close(pane) { if let Some((new_pane, _)) = self.split(axis, target, state) { - // Ensure new node corresponds to original `Pane` for state continuity - self.swap(pane, new_pane); - let _ = self - .panes - .remove(&new_pane) - .and_then(|state| self.panes.insert(pane, state)); + // Ensure new node corresponds to original closed `Pane` for state continuity + self.relabel(new_pane, pane); if swap { self.swap(target, pane); @@ -258,22 +254,27 @@ impl State { &mut self, axis: Axis, pane: Pane, - swap: bool, + inverse: bool, ) { if let Some((state, _)) = self.close(pane) { if let Some((new_pane, _)) = - self.split_node(axis, None, state, swap) + self.split_node(axis, None, state, inverse) { - // Ensure new node corresponds to original `Pane` for state continuity - self.swap(pane, new_pane); - let _ = self - .panes - .remove(&new_pane) - .and_then(|state| self.panes.insert(pane, state)); + // Ensure new node corresponds to original closed `Pane` for state continuity + self.relabel(new_pane, pane); } } } + fn relabel(&mut self, target: Pane, label: Pane) { + self.swap(target, label); + + let _ = self + .panes + .remove(&target) + .and_then(|state| self.panes.insert(label, 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 -- cgit