Add deadband distance before initiating drag action on pane grid
This commit is contained in:
parent
dd249a1d11
commit
116fb666b0
2 changed files with 68 additions and 18 deletions
|
|
@ -531,6 +531,8 @@ pub fn update<'a, Message, T: Draggable>(
|
||||||
on_drag: &Option<Box<dyn Fn(DragEvent) -> Message + 'a>>,
|
on_drag: &Option<Box<dyn Fn(DragEvent) -> Message + 'a>>,
|
||||||
on_resize: &Option<(f32, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>,
|
on_resize: &Option<(f32, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
|
const DRAG_DEADBAND_DISTANCE: f32 = 10.0;
|
||||||
|
|
||||||
let mut event_status = event::Status::Ignored;
|
let mut event_status = event::Status::Ignored;
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
|
|
@ -572,7 +574,6 @@ pub fn update<'a, Message, T: Draggable>(
|
||||||
shell,
|
shell,
|
||||||
contents,
|
contents,
|
||||||
on_click,
|
on_click,
|
||||||
on_drag,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -584,7 +585,6 @@ pub fn update<'a, Message, T: Draggable>(
|
||||||
shell,
|
shell,
|
||||||
contents,
|
contents,
|
||||||
on_click,
|
on_click,
|
||||||
on_drag,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -637,7 +637,49 @@ pub fn update<'a, Message, T: Draggable>(
|
||||||
}
|
}
|
||||||
Event::Mouse(mouse::Event::CursorMoved { .. })
|
Event::Mouse(mouse::Event::CursorMoved { .. })
|
||||||
| Event::Touch(touch::Event::FingerMoved { .. }) => {
|
| 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() {
|
if let Some((split, _)) = action.picked_split() {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
||||||
|
|
@ -712,7 +754,6 @@ fn click_pane<'a, Message, T>(
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
contents: impl Iterator<Item = (Pane, T)>,
|
contents: impl Iterator<Item = (Pane, T)>,
|
||||||
on_click: &Option<Box<dyn Fn(Pane) -> Message + 'a>>,
|
on_click: &Option<Box<dyn Fn(Pane) -> Message + 'a>>,
|
||||||
on_drag: &Option<Box<dyn Fn(DragEvent) -> Message + 'a>>,
|
|
||||||
) where
|
) where
|
||||||
T: Draggable,
|
T: Draggable,
|
||||||
{
|
{
|
||||||
|
|
@ -720,23 +761,15 @@ fn click_pane<'a, Message, T>(
|
||||||
.zip(layout.children())
|
.zip(layout.children())
|
||||||
.filter(|(_, layout)| layout.bounds().contains(cursor_position));
|
.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 {
|
if let Some(on_click) = &on_click {
|
||||||
shell.publish(on_click(pane));
|
shell.publish(on_click(pane));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(on_drag) = &on_drag {
|
let pane_position = layout.position();
|
||||||
if content.can_be_dragged_at(layout, cursor_position) {
|
let origin =
|
||||||
let pane_position = layout.position();
|
cursor_position - Vector::new(pane_position.x, pane_position.y);
|
||||||
|
*action = state::Action::Clicking { pane, origin };
|
||||||
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 }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -749,7 +782,7 @@ pub fn mouse_interaction(
|
||||||
spacing: f32,
|
spacing: f32,
|
||||||
resize_leeway: Option<f32>,
|
resize_leeway: Option<f32>,
|
||||||
) -> Option<mouse::Interaction> {
|
) -> 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);
|
return Some(mouse::Interaction::Grabbing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -403,6 +403,15 @@ pub enum Action {
|
||||||
///
|
///
|
||||||
/// [`PaneGrid`]: super::PaneGrid
|
/// [`PaneGrid`]: super::PaneGrid
|
||||||
Idle,
|
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.
|
/// A [`Pane`] in the [`PaneGrid`] is being dragged.
|
||||||
///
|
///
|
||||||
/// [`PaneGrid`]: super::PaneGrid
|
/// [`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.
|
/// Returns the current [`Split`] that is being dragged, if any.
|
||||||
pub fn picked_split(&self) -> Option<(Split, Axis)> {
|
pub fn picked_split(&self) -> Option<(Split, Axis)> {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue