summaryrefslogtreecommitdiffstats
path: root/widget/src/pane_grid
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/src/pane_grid.rs89
-rw-r--r--widget/src/pane_grid/content.rs9
-rw-r--r--widget/src/pane_grid/state.rs17
-rw-r--r--widget/src/pane_grid/title_bar.rs18
4 files changed, 90 insertions, 43 deletions
diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs
index 2d25a543..cf1f0455 100644
--- a/widget/src/pane_grid.rs
+++ b/widget/src/pane_grid.rs
@@ -265,12 +265,11 @@ where
}
}
- fn width(&self) -> Length {
- self.width
- }
-
- fn height(&self) -> Length {
- self.height
+ fn size(&self) -> Size<Length> {
+ Size {
+ width: self.width,
+ height: self.height,
+ }
}
fn layout(
@@ -490,8 +489,7 @@ pub fn layout<Renderer, T>(
&layout::Limits,
) -> layout::Node,
) -> layout::Node {
- let limits = limits.width(width).height(height);
- let size = limits.resolve(Size::ZERO);
+ let size = limits.resolve(width, height, Size::ZERO);
let regions = node.pane_regions(spacing, size);
let children = contents
@@ -500,16 +498,14 @@ pub fn layout<Renderer, T>(
let region = regions.get(&pane)?;
let size = Size::new(region.width, region.height);
- let mut node = layout_content(
+ let node = layout_content(
content,
tree,
renderer,
&layout::Limits::new(size, size),
);
- node.move_to(Point::new(region.x, region.y));
-
- Some(node)
+ Some(node.move_to(Point::new(region.x, region.y)))
})
.collect();
@@ -531,6 +527,8 @@ pub fn update<'a, Message, T: Draggable>(
on_drag: &Option<Box<dyn Fn(DragEvent) -> Message + 'a>>,
on_resize: &Option<(f32, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>,
) -> event::Status {
+ const DRAG_DEADBAND_DISTANCE: f32 = 10.0;
+
let mut event_status = event::Status::Ignored;
match event {
@@ -572,7 +570,6 @@ pub fn update<'a, Message, T: Draggable>(
shell,
contents,
on_click,
- on_drag,
);
}
}
@@ -584,7 +581,6 @@ pub fn update<'a, Message, T: Draggable>(
shell,
contents,
on_click,
- on_drag,
);
}
}
@@ -637,7 +633,49 @@ pub fn update<'a, Message, T: Draggable>(
}
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(touch::Event::FingerMoved { .. }) => {
- if let Some((_, on_resize)) = on_resize {
+ if let Some((_, origin)) = action.clicked_pane() {
+ if let Some(on_drag) = &on_drag {
+ let bounds = layout.bounds();
+
+ if let Some(cursor_position) = cursor.position_over(bounds)
+ {
+ let mut clicked_region = contents
+ .zip(layout.children())
+ .filter(|(_, layout)| {
+ layout.bounds().contains(cursor_position)
+ });
+
+ if let Some(((pane, content), layout)) =
+ clicked_region.next()
+ {
+ if content
+ .can_be_dragged_at(layout, cursor_position)
+ {
+ let pane_position = layout.position();
+
+ let new_origin = cursor_position
+ - Vector::new(
+ pane_position.x,
+ pane_position.y,
+ );
+
+ if new_origin.distance(origin)
+ > DRAG_DEADBAND_DISTANCE
+ {
+ *action = state::Action::Dragging {
+ pane,
+ origin,
+ };
+
+ shell.publish(on_drag(DragEvent::Picked {
+ pane,
+ }));
+ }
+ }
+ }
+ }
+ }
+ } else if let Some((_, on_resize)) = on_resize {
if let Some((split, _)) = action.picked_split() {
let bounds = layout.bounds();
@@ -712,7 +750,6 @@ fn click_pane<'a, Message, T>(
shell: &mut Shell<'_, Message>,
contents: impl Iterator<Item = (Pane, T)>,
on_click: &Option<Box<dyn Fn(Pane) -> Message + 'a>>,
- on_drag: &Option<Box<dyn Fn(DragEvent) -> Message + 'a>>,
) where
T: Draggable,
{
@@ -720,23 +757,15 @@ fn click_pane<'a, Message, T>(
.zip(layout.children())
.filter(|(_, layout)| layout.bounds().contains(cursor_position));
- if let Some(((pane, content), layout)) = clicked_region.next() {
+ if let Some(((pane, _), layout)) = clicked_region.next() {
if let Some(on_click) = &on_click {
shell.publish(on_click(pane));
}
- if let Some(on_drag) = &on_drag {
- if content.can_be_dragged_at(layout, cursor_position) {
- let pane_position = layout.position();
-
- let origin = cursor_position
- - Vector::new(pane_position.x, pane_position.y);
-
- *action = state::Action::Dragging { pane, origin };
-
- shell.publish(on_drag(DragEvent::Picked { pane }));
- }
- }
+ let pane_position = layout.position();
+ let origin =
+ cursor_position - Vector::new(pane_position.x, pane_position.y);
+ *action = state::Action::Clicking { pane, origin };
}
}
@@ -749,7 +778,7 @@ pub fn mouse_interaction(
spacing: f32,
resize_leeway: Option<f32>,
) -> Option<mouse::Interaction> {
- if action.picked_pane().is_some() {
+ if action.clicked_pane().is_some() || action.picked_pane().is_some() {
return Some(mouse::Interaction::Grabbing);
}
diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs
index 826ea663..ee00f186 100644
--- a/widget/src/pane_grid/content.rs
+++ b/widget/src/pane_grid/content.rs
@@ -165,7 +165,7 @@ where
let title_bar_size = title_bar_layout.size();
- let mut body_layout = self.body.as_widget().layout(
+ let body_layout = self.body.as_widget().layout(
&mut tree.children[0],
renderer,
&layout::Limits::new(
@@ -177,11 +177,12 @@ where
),
);
- body_layout.move_to(Point::new(0.0, title_bar_size.height));
-
layout::Node::with_children(
max_size,
- vec![title_bar_layout, body_layout],
+ vec![
+ title_bar_layout,
+ body_layout.move_to(Point::new(0.0, title_bar_size.height)),
+ ],
)
} else {
self.body.as_widget().layout(
diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs
index 481cd770..5d1fe254 100644
--- a/widget/src/pane_grid/state.rs
+++ b/widget/src/pane_grid/state.rs
@@ -403,6 +403,15 @@ pub enum Action {
///
/// [`PaneGrid`]: super::PaneGrid
Idle,
+ /// A [`Pane`] in the [`PaneGrid`] is being clicked.
+ ///
+ /// [`PaneGrid`]: super::PaneGrid
+ Clicking {
+ /// The [`Pane`] being clicked.
+ pane: Pane,
+ /// The starting [`Point`] of the click interaction.
+ origin: Point,
+ },
/// A [`Pane`] in the [`PaneGrid`] is being dragged.
///
/// [`PaneGrid`]: super::PaneGrid
@@ -432,6 +441,14 @@ impl Action {
}
}
+ /// Returns the current [`Pane`] that is being clicked, if any.
+ pub fn clicked_pane(&self) -> Option<(Pane, Point)> {
+ match *self {
+ Action::Clicking { pane, origin, .. } => Some((pane, origin)),
+ _ => None,
+ }
+ }
+
/// Returns the current [`Split`] that is being dragged, if any.
pub fn picked_split(&self) -> Option<(Split, Axis)> {
match *self {
diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs
index f4dbb6b1..eb21b743 100644
--- a/widget/src/pane_grid/title_bar.rs
+++ b/widget/src/pane_grid/title_bar.rs
@@ -217,7 +217,7 @@ where
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
- let limits = limits.pad(self.padding);
+ let limits = limits.shrink(self.padding);
let max_size = limits.max();
let title_layout = self.content.as_widget().layout(
@@ -228,8 +228,8 @@ where
let title_size = title_layout.size();
- let mut node = if let Some(controls) = &self.controls {
- let mut controls_layout = controls.as_widget().layout(
+ let node = if let Some(controls) = &self.controls {
+ let controls_layout = controls.as_widget().layout(
&mut tree.children[1],
renderer,
&layout::Limits::new(Size::ZERO, max_size),
@@ -240,11 +240,13 @@ where
let height = title_size.height.max(controls_size.height);
- controls_layout.move_to(Point::new(space_before_controls, 0.0));
-
layout::Node::with_children(
Size::new(max_size.width, height),
- vec![title_layout, controls_layout],
+ vec![
+ title_layout,
+ controls_layout
+ .move_to(Point::new(space_before_controls, 0.0)),
+ ],
)
} else {
layout::Node::with_children(
@@ -253,9 +255,7 @@ where
)
};
- node.move_to(Point::new(self.padding.left, self.padding.top));
-
- layout::Node::with_children(node.size().pad(self.padding), vec![node])
+ layout::Node::container(node, self.padding)
}
pub(crate) fn operate(