summaryrefslogtreecommitdiffstats
path: root/widget/src/pane_grid
diff options
context:
space:
mode:
Diffstat (limited to 'widget/src/pane_grid')
-rw-r--r--widget/src/pane_grid/content.rs53
-rw-r--r--widget/src/pane_grid/state.rs83
-rw-r--r--widget/src/pane_grid/title_bar.rs42
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(