summaryrefslogtreecommitdiffstats
path: root/widget
diff options
context:
space:
mode:
Diffstat (limited to 'widget')
-rw-r--r--widget/src/pane_grid.rs141
-rw-r--r--widget/src/pane_grid/state.rs17
2 files changed, 59 insertions, 99 deletions
diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs
index 37562504..478a7024 100644
--- a/widget/src/pane_grid.rs
+++ b/widget/src/pane_grid.rs
@@ -46,6 +46,9 @@ use crate::core::{
Vector, Widget,
};
+const DRAG_DEADBAND_DISTANCE: f32 = 10.0;
+const THICKNESS_RATIO: f32 = 25.0;
+
/// A collection of panes distributed using either vertical or horizontal splits
/// to completely fill the space available.
///
@@ -532,8 +535,6 @@ 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 {
@@ -575,6 +576,7 @@ pub fn update<'a, Message, T: Draggable>(
shell,
contents,
on_click,
+ on_drag,
);
}
}
@@ -586,6 +588,7 @@ pub fn update<'a, Message, T: Draggable>(
shell,
contents,
on_click,
+ on_drag,
);
}
}
@@ -594,38 +597,44 @@ pub fn update<'a, Message, T: Draggable>(
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
| Event::Touch(touch::Event::FingerLifted { .. })
| Event::Touch(touch::Event::FingerLost { .. }) => {
- if let Some((pane, _)) = action.picked_pane() {
+ if let Some((pane, origin)) = action.picked_pane() {
if let Some(on_drag) = on_drag {
if let Some(cursor_position) = cursor.position() {
- let event = if let Some(edge) =
- in_edge(layout, cursor_position)
+ if cursor_position.distance(origin)
+ > DRAG_DEADBAND_DISTANCE
{
- DragEvent::Dropped {
- pane,
- target: Target::Edge(edge),
- }
- } else {
- let dropped_region = contents
- .zip(layout.children())
- .find_map(|(target, layout)| {
- layout_region(layout, cursor_position)
- .map(|region| (target, region))
- });
-
- match dropped_region {
- Some(((target, _), region))
- if pane != target =>
- {
- DragEvent::Dropped {
- pane,
- target: Target::Pane(target, region),
+ let event = if let Some(edge) =
+ in_edge(layout, cursor_position)
+ {
+ DragEvent::Dropped {
+ pane,
+ target: Target::Edge(edge),
+ }
+ } else {
+ let dropped_region = contents
+ .zip(layout.children())
+ .find_map(|(target, layout)| {
+ layout_region(layout, cursor_position)
+ .map(|region| (target, region))
+ });
+
+ match dropped_region {
+ Some(((target, _), region))
+ if pane != target =>
+ {
+ DragEvent::Dropped {
+ pane,
+ target: Target::Pane(
+ target, region,
+ ),
+ }
}
+ _ => DragEvent::Canceled { pane },
}
- _ => DragEvent::Canceled { pane },
- }
- };
+ };
- shell.publish(on_drag(event));
+ shell.publish(on_drag(event));
+ }
}
}
@@ -638,49 +647,7 @@ pub fn update<'a, Message, T: Draggable>(
}
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(touch::Event::FingerMoved { .. }) => {
- 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((_, on_resize)) = on_resize {
if let Some((split, _)) = action.picked_split() {
let bounds = layout.bounds();
@@ -755,6 +722,7 @@ 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,
{
@@ -762,15 +730,21 @@ fn click_pane<'a, Message, T>(
.zip(layout.children())
.filter(|(_, layout)| layout.bounds().contains(cursor_position));
- if let Some(((pane, _), layout)) = clicked_region.next() {
+ if let Some(((pane, content), layout)) = clicked_region.next() {
if let Some(on_click) = &on_click {
shell.publish(on_click(pane));
}
- let pane_position = layout.position();
- let origin =
- cursor_position - Vector::new(pane_position.x, pane_position.y);
- *action = state::Action::Clicking { pane, origin };
+ if let Some(on_drag) = &on_drag {
+ if content.can_be_dragged_at(layout, cursor_position) {
+ *action = state::Action::Dragging {
+ pane,
+ origin: cursor_position,
+ };
+
+ shell.publish(on_drag(DragEvent::Picked { pane }));
+ }
+ }
}
}
@@ -783,7 +757,7 @@ pub fn mouse_interaction(
spacing: f32,
resize_leeway: Option<f32>,
) -> Option<mouse::Interaction> {
- if action.clicked_pane().is_some() || action.picked_pane().is_some() {
+ if action.picked_pane().is_some() {
return Some(mouse::Interaction::Grabbing);
}
@@ -841,7 +815,13 @@ pub fn draw<Theme, Renderer, T>(
Theme: StyleSheet,
Renderer: crate::core::Renderer,
{
- let picked_pane = action.picked_pane();
+ let picked_pane = action.picked_pane().filter(|(_, origin)| {
+ cursor
+ .position()
+ .map(|position| position.distance(*origin))
+ .unwrap_or_default()
+ > DRAG_DEADBAND_DISTANCE
+ });
let picked_split = action
.picked_split()
@@ -962,8 +942,7 @@ pub fn draw<Theme, Renderer, T>(
if let Some(cursor_position) = cursor.position() {
let bounds = layout.bounds();
- let translation = cursor_position
- - Point::new(bounds.x + origin.x, bounds.y + origin.y);
+ let translation = cursor_position - Point::new(origin.x, origin.y);
renderer.with_translation(translation, |renderer| {
renderer.with_layer(bounds, |renderer| {
@@ -1020,8 +999,6 @@ pub fn draw<Theme, Renderer, T>(
}
}
-const THICKNESS_RATIO: f32 = 25.0;
-
fn in_edge(layout: Layout<'_>, cursor: Point) -> Option<Edge> {
let bounds = layout.bounds();
diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs
index 5d1fe254..481cd770 100644
--- a/widget/src/pane_grid/state.rs
+++ b/widget/src/pane_grid/state.rs
@@ -403,15 +403,6 @@ 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
@@ -441,14 +432,6 @@ 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 {