Skip to content

Commit

Permalink
Merge pull request #2168 from jhff/fix/pane_grid_top_edge_click
Browse files Browse the repository at this point in the history
[Fix] `PaneGrid` click interaction on the top edge
  • Loading branch information
hecrj authored Jan 4, 2024
2 parents 0172cac + 116fb66 commit 68c0484
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 18 deletions.
69 changes: 51 additions & 18 deletions widget/src/pane_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,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 {
Expand Down Expand Up @@ -572,7 +574,6 @@ pub fn update<'a, Message, T: Draggable>(
shell,
contents,
on_click,
on_drag,
);
}
}
Expand All @@ -584,7 +585,6 @@ pub fn update<'a, Message, T: Draggable>(
shell,
contents,
on_click,
on_drag,
);
}
}
Expand Down Expand Up @@ -637,7 +637,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();

Expand Down Expand Up @@ -712,31 +754,22 @@ 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,
{
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 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 };
}
}

Expand All @@ -749,7 +782,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);
}

Expand Down
17 changes: 17 additions & 0 deletions widget/src/pane_grid/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 68c0484

Please sign in to comment.