fix(scrollable): allow scrolling when children capture touch presses
This commit is contained in:
parent
7918b2826e
commit
87c0358985
3 changed files with 71 additions and 5 deletions
|
|
@ -9,6 +9,8 @@ pub use iced_renderer::graphics;
|
||||||
|
|
||||||
pub use core::widget::Id;
|
pub use core::widget::Id;
|
||||||
|
|
||||||
|
pub(crate) const DRAG_DEADBAND_DISTANCE: f32 = 10.0;
|
||||||
|
|
||||||
mod action;
|
mod action;
|
||||||
mod mouse_area;
|
mod mouse_area;
|
||||||
mod pin;
|
mod pin;
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,8 @@ use crate::core::{
|
||||||
};
|
};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
const DRAG_DEADBAND_DISTANCE: f32 = 10.0;
|
use crate::DRAG_DEADBAND_DISTANCE;
|
||||||
|
|
||||||
const THICKNESS_RATIO: f32 = 25.0;
|
const THICKNESS_RATIO: f32 = 25.0;
|
||||||
|
|
||||||
/// A collection of panes distributed using either vertical or horizontal splits
|
/// A collection of panes distributed using either vertical or horizontal splits
|
||||||
|
|
|
||||||
|
|
@ -961,6 +961,16 @@ where
|
||||||
y: y + translation.y as f64,
|
y: y + translation.y as f64,
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
Event::Touch(touch::Event::FingerLifted {
|
||||||
|
id,
|
||||||
|
position,
|
||||||
|
}) if matches!(
|
||||||
|
state.interaction,
|
||||||
|
Interaction::TouchScrolling(_)
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
Event::Touch(touch::Event::FingerLost { id, position })
|
||||||
|
}
|
||||||
e => e,
|
e => e,
|
||||||
};
|
};
|
||||||
self.content.as_widget_mut().update(
|
self.content.as_widget_mut().update(
|
||||||
|
|
@ -988,6 +998,14 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if matches!(
|
||||||
|
event,
|
||||||
|
Event::Mouse(mouse::Event::CursorMoved { .. })
|
||||||
|
| Event::Touch(touch::Event::FingerPressed { .. })
|
||||||
|
) {
|
||||||
|
state.suppress_touch_hover = false;
|
||||||
|
}
|
||||||
|
|
||||||
if matches!(
|
if matches!(
|
||||||
event,
|
event,
|
||||||
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
|
||||||
|
|
@ -996,10 +1014,18 @@ where
|
||||||
| touch::Event::FingerLost { .. }
|
| touch::Event::FingerLost { .. }
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
if matches!(state.interaction, Interaction::TouchScrolling(_)) {
|
||||||
|
state.suppress_touch_hover = true;
|
||||||
|
}
|
||||||
state.interaction = Interaction::None;
|
state.interaction = Interaction::None;
|
||||||
|
state.touch_press_start = None;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Event::Touch(touch::Event::FingerPressed { .. }) = event {
|
||||||
|
state.touch_press_start = cursor_over_scrollable;
|
||||||
|
}
|
||||||
|
|
||||||
if shell.is_event_captured() {
|
if shell.is_event_captured() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1093,14 +1119,31 @@ where
|
||||||
Interaction::TouchScrolling(position);
|
Interaction::TouchScrolling(position);
|
||||||
}
|
}
|
||||||
touch::Event::FingerMoved { .. } => {
|
touch::Event::FingerMoved { .. } => {
|
||||||
let Interaction::TouchScrolling(
|
let Some(cursor_position) = cursor.position()
|
||||||
scroll_box_touched_at,
|
|
||||||
) = state.interaction
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(cursor_position) = cursor.position()
|
if !matches!(
|
||||||
|
state.interaction,
|
||||||
|
Interaction::TouchScrolling(_)
|
||||||
|
) {
|
||||||
|
let Some(start) = state.touch_press_start
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if start.distance(cursor_position)
|
||||||
|
< crate::DRAG_DEADBAND_DISTANCE
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.interaction =
|
||||||
|
Interaction::TouchScrolling(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
let Interaction::TouchScrolling(
|
||||||
|
scroll_box_touched_at,
|
||||||
|
) = state.interaction
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -1322,6 +1365,14 @@ where
|
||||||
state.translation(self.direction, bounds, content_bounds);
|
state.translation(self.direction, bounds, content_bounds);
|
||||||
|
|
||||||
let cursor = match cursor_over_scrollable {
|
let cursor = match cursor_over_scrollable {
|
||||||
|
_ if state.suppress_touch_hover
|
||||||
|
|| matches!(
|
||||||
|
state.interaction,
|
||||||
|
Interaction::TouchScrolling(_)
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
mouse::Cursor::Unavailable
|
||||||
|
}
|
||||||
Some(cursor_position)
|
Some(cursor_position)
|
||||||
if !(mouse_over_x_scrollbar || mouse_over_y_scrollbar) =>
|
if !(mouse_over_x_scrollbar || mouse_over_y_scrollbar) =>
|
||||||
{
|
{
|
||||||
|
|
@ -1497,6 +1548,14 @@ where
|
||||||
state.translation(self.direction, bounds, content_bounds);
|
state.translation(self.direction, bounds, content_bounds);
|
||||||
|
|
||||||
let cursor = match cursor_over_scrollable {
|
let cursor = match cursor_over_scrollable {
|
||||||
|
_ if state.suppress_touch_hover
|
||||||
|
|| matches!(
|
||||||
|
state.interaction,
|
||||||
|
Interaction::TouchScrolling(_)
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
cursor.levitate() + translation
|
||||||
|
}
|
||||||
Some(cursor_position)
|
Some(cursor_position)
|
||||||
if !(mouse_over_x_scrollbar || mouse_over_y_scrollbar) =>
|
if !(mouse_over_x_scrollbar || mouse_over_y_scrollbar) =>
|
||||||
{
|
{
|
||||||
|
|
@ -2022,6 +2081,8 @@ struct State {
|
||||||
last_notified: Option<Viewport>,
|
last_notified: Option<Viewport>,
|
||||||
last_scrolled: Option<Instant>,
|
last_scrolled: Option<Instant>,
|
||||||
is_scrollbar_visible: bool,
|
is_scrollbar_visible: bool,
|
||||||
|
touch_press_start: Option<Point>,
|
||||||
|
suppress_touch_hover: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
@ -2047,6 +2108,8 @@ impl Default for State {
|
||||||
last_notified: None,
|
last_notified: None,
|
||||||
last_scrolled: None,
|
last_scrolled: None,
|
||||||
is_scrollbar_visible: true,
|
is_scrollbar_visible: true,
|
||||||
|
touch_press_start: None,
|
||||||
|
suppress_touch_hover: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue