diff options
Diffstat (limited to 'widget/src/pane_grid')
-rw-r--r-- | widget/src/pane_grid/content.rs | 53 | ||||
-rw-r--r-- | widget/src/pane_grid/state.rs | 83 | ||||
-rw-r--r-- | widget/src/pane_grid/title_bar.rs | 42 |
3 files changed, 105 insertions, 73 deletions
diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index ec0676b1..be5e5066 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -1,12 +1,12 @@ use crate::container; -use crate::core::event::{self, Event}; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; use crate::core::widget::{self, Tree}; use crate::core::{ - self, Clipboard, Element, Layout, Point, Rectangle, Shell, Size, Vector, + self, Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size, + Vector, }; use crate::pane_grid::{Draggable, TitleBar}; @@ -73,7 +73,7 @@ where } } -impl<'a, Message, Theme, Renderer> Content<'a, Message, Theme, Renderer> +impl<Message, Theme, Renderer> Content<'_, Message, Theme, Renderer> where Theme: container::Catalog, Renderer: core::Renderer, @@ -239,7 +239,7 @@ where ); } - pub(crate) fn on_event( + pub(crate) fn update( &mut self, tree: &mut Tree, event: Event, @@ -250,13 +250,11 @@ where shell: &mut Shell<'_, Message>, viewport: &Rectangle, is_picked: bool, - ) -> event::Status { - let mut event_status = event::Status::Ignored; - + ) { let body_layout = if let Some(title_bar) = &mut self.title_bar { let mut children = layout.children(); - event_status = title_bar.on_event( + title_bar.update( &mut tree.children[1], event.clone(), children.next().unwrap(), @@ -272,10 +270,8 @@ where layout }; - let body_status = if is_picked { - event::Status::Ignored - } else { - self.body.as_widget_mut().on_event( + if !is_picked { + self.body.as_widget_mut().update( &mut tree.children[0], event, body_layout, @@ -284,10 +280,33 @@ where clipboard, shell, viewport, - ) - }; + ); + } + } + + pub(crate) fn grid_interaction( + &self, + layout: Layout<'_>, + cursor: mouse::Cursor, + drag_enabled: bool, + ) -> Option<mouse::Interaction> { + let title_bar = self.title_bar.as_ref()?; + + let mut children = layout.children(); + let title_bar_layout = children.next().unwrap(); + + let is_over_pick_area = cursor + .position() + .map(|cursor_position| { + title_bar.is_over_pick_area(title_bar_layout, cursor_position) + }) + .unwrap_or_default(); + + if is_over_pick_area && drag_enabled { + return Some(mouse::Interaction::Grab); + } - event_status.merge(body_status) + None } pub(crate) fn mouse_interaction( @@ -382,8 +401,8 @@ where } } -impl<'a, Message, Theme, Renderer> Draggable - for &Content<'a, Message, Theme, Renderer> +impl<Message, Theme, Renderer> Draggable + for &Content<'_, Message, Theme, Renderer> where Theme: container::Catalog, Renderer: core::Renderer, diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index c20c3b9c..2f8a64ea 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -6,7 +6,8 @@ use crate::pane_grid::{ Axis, Configuration, Direction, Edge, Node, Pane, Region, Split, Target, }; -use rustc_hash::FxHashMap; +use std::borrow::Cow; +use std::collections::BTreeMap; /// The state of a [`PaneGrid`]. /// @@ -25,17 +26,12 @@ pub struct State<T> { /// The panes of the [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid - pub panes: FxHashMap<Pane, T>, + pub panes: BTreeMap<Pane, T>, /// The internal state of the [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid pub internal: Internal, - - /// The maximized [`Pane`] of the [`PaneGrid`]. - /// - /// [`PaneGrid`]: super::PaneGrid - pub(super) maximized: Option<Pane>, } impl<T> State<T> { @@ -52,16 +48,12 @@ impl<T> State<T> { /// Creates a new [`State`] with the given [`Configuration`]. pub fn with_configuration(config: impl Into<Configuration<T>>) -> Self { - let mut panes = FxHashMap::default(); + let mut panes = BTreeMap::default(); 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<T> State<T> { } let _ = self.panes.insert(new_pane, state); - let _ = self.maximized.take(); + let _ = self.internal.maximized.take(); Some((new_pane, new_split)) } @@ -228,8 +220,11 @@ impl<T> State<T> { ) { if let Some((state, _)) = self.close(pane) { if let Some((new_pane, _)) = self.split(axis, target, state) { + // Ensure new node corresponds to original closed `Pane` for state continuity + self.relabel(new_pane, pane); + if swap { - self.swap(target, new_pane); + self.swap(target, pane); } } } @@ -259,13 +254,27 @@ impl<T> State<T> { &mut self, axis: Axis, pane: Pane, - swap: bool, + inverse: 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, inverse) + { + // 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 @@ -303,8 +312,8 @@ impl<T> State<T> { /// 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) { @@ -319,7 +328,7 @@ impl<T> State<T> { /// /// [`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 @@ -327,14 +336,14 @@ impl<T> State<T> { /// /// [`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<Pane> { - self.maximized + self.internal.maximized } } @@ -345,6 +354,7 @@ impl<T> State<T> { pub struct Internal { layout: Node, last_id: usize, + maximized: Option<Pane>, } impl Internal { @@ -353,7 +363,7 @@ impl Internal { /// /// [`PaneGrid`]: super::PaneGrid pub fn from_configuration<T>( - panes: &mut FxHashMap<Pane, T>, + panes: &mut BTreeMap<Pane, T>, content: Configuration<T>, next_id: usize, ) -> Self { @@ -390,18 +400,34 @@ 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<Pane> { + self.maximized } } /// 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. /// @@ -440,10 +466,3 @@ impl Action { } } } - -impl Internal { - /// The layout [`Node`] of the [`Internal`] state - pub fn layout(&self) -> &Node { - &self.layout - } -} diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index 5002b4f7..4bd2c2f6 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -1,13 +1,12 @@ use crate::container; -use crate::core::event::{self, Event}; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; use crate::core::widget::{self, Tree}; use crate::core::{ - self, Clipboard, Element, Layout, Padding, Point, Rectangle, Shell, Size, - Vector, + self, Clipboard, Element, Event, Layout, Padding, Point, Rectangle, Shell, + Size, Vector, }; use crate::pane_grid::controls::Controls; @@ -99,7 +98,7 @@ where } } -impl<'a, Message, Theme, Renderer> TitleBar<'a, Message, Theme, Renderer> +impl<Message, Theme, Renderer> TitleBar<'_, Message, Theme, Renderer> where Theme: container::Catalog, Renderer: core::Renderer, @@ -428,7 +427,7 @@ where } } - pub(crate) fn on_event( + pub(crate) fn update( &mut self, tree: &mut Tree, event: Event, @@ -438,7 +437,7 @@ where clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, viewport: &Rectangle, - ) -> event::Status { + ) { let mut children = layout.children(); let padded = children.next().unwrap(); @@ -446,15 +445,16 @@ where let title_layout = children.next().unwrap(); let mut show_title = true; - let control_status = if let Some(controls) = &mut self.controls { + if let Some(controls) = &mut self.controls { let controls_layout = children.next().unwrap(); + if title_layout.bounds().width + controls_layout.bounds().width > padded.bounds().width { if let Some(compact) = controls.compact.as_mut() { let compact_layout = children.next().unwrap(); - compact.as_widget_mut().on_event( + compact.as_widget_mut().update( &mut tree.children[2], event.clone(), compact_layout, @@ -463,11 +463,11 @@ where clipboard, shell, viewport, - ) + ); } else { show_title = false; - controls.full.as_widget_mut().on_event( + controls.full.as_widget_mut().update( &mut tree.children[1], event.clone(), controls_layout, @@ -476,10 +476,10 @@ where clipboard, shell, viewport, - ) + ); } } else { - controls.full.as_widget_mut().on_event( + controls.full.as_widget_mut().update( &mut tree.children[1], event.clone(), controls_layout, @@ -488,14 +488,12 @@ where clipboard, shell, viewport, - ) + ); } - } else { - event::Status::Ignored - }; + } - let title_status = if show_title { - self.content.as_widget_mut().on_event( + if show_title { + self.content.as_widget_mut().update( &mut tree.children[0], event, title_layout, @@ -504,12 +502,8 @@ where clipboard, shell, viewport, - ) - } else { - event::Status::Ignored - }; - - control_status.merge(title_status) + ); + } } pub(crate) fn mouse_interaction( |