touch-area: Trigger pointer-evnet on mouse move

Trigger the `pointer-event` callback on mouse move. This is of "kind"
Move and the mouse button will always be `Other`, but at least the mappings
will be correct:-)

Closes: #2770
This commit is contained in:
Tobias Hunger 2023-12-04 16:38:26 +01:00 committed by Tobias Hunger
parent b12c35d877
commit 9737720cf2
7 changed files with 40 additions and 26 deletions

View file

@ -11,6 +11,8 @@ All notable changes to this project are documented in this file.
- Added focus state to `StandardListView`
- Added a `double-clicked` callback in `TouchArea`, which is triggered when a `TouchArea`
is clicked twice in rapid succession.
- The `pointer-event` callback in `TouchArea` is now triggered on mouse move
as well.
## [1.3.2] - 2023-12-01

View file

@ -756,8 +756,12 @@ When not part of a layout, its width or height default to 100% of the parent ele
period of time. Assigning this callback will cause the `clicked` callback to get delayed, so that Slint can
detect whether the first click was a click or the first half of a double click.
- **`moved()`**: The mouse has been moved. This will only be called if the mouse is also pressed.
- **`pointer-event(PointerEvent)`**: Invoked when a button was pressed or released. The [_`PointerEvent`_](structs.md#pointerevent)
argument contains information such which button was pressed and any active keyboard modifiers.
See also **pointer-event(PointerEvent)**.
- **`pointer-event(PointerEvent)`**: Invoked when a button was pressed or released or the pointer moved.
The [_`PointerEvent`_](structs.md#pointerevent) argument contains information such which button was pressed
and any active keyboard modifiers.
In the [_`PointerEventKind::Move`_](structs.md#pointereventkind) case the `buttons` field will always
be set to `PointerEventButton::Other`, independent of whether any button is pressed or not.
- **`scroll-event(PointerScrollEvent) -> EventResult`**: Invoked when the mouse wheel was rotated or another scroll gesture was made.
The [_`PointerScrollEvent`_](structs.md#pointerscrollevent) argument contains information about how much to scroll in what direction.
The returned [`EventResult`](enums.md#eventresult) indicates whether to accept or ignore the event. Ignored events are

View file

@ -129,6 +129,8 @@ macro_rules! for_each_enums {
Down,
/// The button was released.
Up,
/// The pointer has moved,
Move,
}
/// This enum describes the different types of buttons for a pointer event,

View file

@ -592,14 +592,14 @@ pub(crate) fn handle_mouse_grab(
if input_result != InputEventResult::GrabMouse {
mouse_input_state.grabbed = false;
// Return a move event so that the new position can be registered properly
return Some(
Some(
mouse_event
.position()
.map_or(MouseEvent::Exit, |position| MouseEvent::Moved { position }),
);
}
)
} else {
None
}
}
pub(crate) fn send_exit_events(

View file

@ -595,12 +595,17 @@ impl Item for TouchArea {
InputEventResult::EventAccepted
}
MouseEvent::Moved { .. } => {
if self.grabbed.get() {
Self::FIELD_OFFSETS.pointer_event.apply_pin(self).call(&(PointerEvent {
button: PointerEventButton::Other,
kind: PointerEventKind::Move,
modifiers: window_adapter.window().0.modifiers.get().into(),
},));
return if self.grabbed.get() {
Self::FIELD_OFFSETS.moved.apply_pin(self).call(&());
InputEventResult::GrabMouse
} else {
InputEventResult::EventAccepted
}
};
}
MouseEvent::Wheel { delta_x, delta_y, .. } => {
let modifiers = window_adapter.window().0.modifiers.get().into();

View file

@ -41,6 +41,8 @@ export component TestCase {
pointer-event-test += "up";
} else if (e.kind == PointerEventKind.down) {
pointer-event-test += "down";
} else if (e.kind == PointerEventKind.move) {
pointer-event-test += "move";
} else {
pointer-event-test += "err";
}
@ -102,27 +104,24 @@ assert_eq(instance.get_touch1(), 1);
assert_eq(instance.get_touch2(), 1);
assert_eq(instance.get_touch3(), 1);
assert_eq(instance.get_pointer_event_test(), "downleftclickupleft");
// The final moveother is added by the grab handler!
assert_eq(instance.get_pointer_event_test(), "moveotherdownleftclickupleftmoveother");
instance.set_pointer_event_test("");
// issue #2918: press anywhere, release on a toucharea
instance.window().dispatch_pointer_press_event(slint::LogicalPosition({70.0, 6.0}), PointerEventButton::Left);
instance.window().dispatch_pointer_move_event(slint::LogicalPosition({ 102.0, 103.0 }));
instance.window().dispatch_pointer_release_event(slint::LogicalPosition({101.0, 104.0}), PointerEventButton::Left);
assert_eq(instance.get_pointer_event_test(), "upleft"); // no "clicked"
assert_eq(instance.get_pointer_event_test(), "moveotherupleft"); // no "clicked"
assert_eq(instance.get_touch1(), 1);
assert_eq(instance.get_touch2(), 1);
assert_eq(instance.get_touch3(), 1);
```
```rust
use slint::{platform::WindowEvent, platform::PointerEventButton, platform::Key, LogicalPosition};
use slint::private_unstable_api::re_exports::MouseCursor;
let instance = TestCase::new().unwrap();
assert_eq!(slint_testing::access_testing_window(instance.window(), |window| window.mouse_cursor.get()), MouseCursor::Default);
@ -154,14 +153,15 @@ assert_eq!(instance.get_touch2(), 1);
assert_eq!(instance.get_touch3(), 1);
assert_eq!(slint_testing::access_testing_window(instance.window(), |window| window.mouse_cursor.get()), MouseCursor::Default);
assert_eq!(instance.get_pointer_event_test().as_str(), "downleftclickupleft");
// The final moveother is added by the grab handler!
assert_eq!(instance.get_pointer_event_test().as_str(), "moveotherdownleftclickupleftmoveother");
instance.set_pointer_event_test("".into());
// issue #2918: press anywhere, release on a toucharea
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(70.0, 6.0), button: PointerEventButton::Left });
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(102.0, 103.0) });
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(101.0, 104.0), button: PointerEventButton::Left });
assert_eq!(instance.get_pointer_event_test().as_str(), "upleft"); // no "clicked"
assert_eq!(instance.get_pointer_event_test().as_str(), "moveotherupleft"); // no "clicked"
assert_eq!(instance.get_touch1(), 1);
assert_eq!(instance.get_touch2(), 1);
assert_eq!(instance.get_touch3(), 1);
@ -172,8 +172,7 @@ instance.window().dispatch_event(WindowEvent::PointerPressed { position: Logical
slint_testing::send_keyboard_char(&instance, Key::Control.into(), false);
slint_testing::send_keyboard_char(&instance, Key::Shift.into(), true);
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(101.0, 104.0), button: PointerEventButton::Left });
assert_eq!(instance.get_pointer_event_test().as_str(), "downleft(ctrl)clickupleft(shift)");
assert_eq!(instance.get_pointer_event_test().as_str(), "downleft(ctrl)clickupleft(shift)moveother(shift)");
```
```js
@ -202,6 +201,6 @@ assert.equal(instance.touch1, 1);
assert.equal(instance.touch2, 1);
assert.equal(instance.touch3, 1);
assert.equal(instance.pointer_event_test, "downleftclickupleft");
assert.equal(instance.pointer_event_test, "moveotherdownleftclickupleftmoveother");
```
*/

View file

@ -50,6 +50,8 @@ export component TestCase {
pointer-event-test += "up";
} else if (e.kind == PointerEventKind.down) {
pointer-event-test += "down";
} else if (e.kind == PointerEventKind.move) {
pointer-event-test += "move";
} else {
pointer-event-test += "err";
}
@ -127,7 +129,7 @@ assert_eq(instance.get_touch_double1(), 0);
assert_eq(instance.get_touch_double2(), 0);
assert_eq(instance.get_touch_double3(), 0);
assert_eq(instance.get_pointer_event_test(), "downleftupleftclick");
assert_eq(instance.get_pointer_event_test(), "moveotherdownleftupleftmoveotherclick");
instance.set_pointer_event_test("");
// issue #2918: press anywhere, release on a toucharea
@ -135,7 +137,7 @@ instance.window().dispatch_pointer_press_event(slint::LogicalPosition({70.0, 6.0
instance.window().dispatch_pointer_move_event(slint::LogicalPosition({ 102.0, 103.0 }));
instance.window().dispatch_pointer_release_event(slint::LogicalPosition({101.0, 104.0}), PointerEventButton::Left);
slint_testing::mock_elapsed_time(1000);
assert_eq(instance.get_pointer_event_test(), "upleft"); // no "clicked"
assert_eq(instance.get_pointer_event_test(), "moveotherupleft"); // no "clicked"
assert_eq(instance.get_touch1(), 1);
assert_eq(instance.get_touch2(), 1);
assert_eq(instance.get_touch3(), 1);
@ -243,7 +245,7 @@ assert_eq!(instance.get_touch_double2(), 0);
assert_eq!(instance.get_touch_double3(), 0);
assert_eq!(slint_testing::access_testing_window(instance.window(), |window| window.mouse_cursor.get()), MouseCursor::Default);
assert_eq!(instance.get_pointer_event_test().as_str(), "downleftupleftclick");
assert_eq!(instance.get_pointer_event_test().as_str(), "moveotherdownleftupleftmoveotherclick");
instance.set_pointer_event_test("".into());
// issue #2918: press anywhere, release on a toucharea
@ -251,7 +253,7 @@ instance.window().dispatch_event(WindowEvent::PointerPressed { position: Logical
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(102.0, 103.0) });
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(101.0, 104.0), button: PointerEventButton::Left });
slint_testing::mock_elapsed_time(1000);
assert_eq!(instance.get_pointer_event_test().as_str(), "upleft"); // no "clicked"
assert_eq!(instance.get_pointer_event_test().as_str(), "moveotherupleft"); // no "clicked", no trailing moveother as not grabbed
assert_eq!(instance.get_touch1(), 1);
assert_eq!(instance.get_touch2(), 1);
assert_eq!(instance.get_touch3(), 1);
@ -266,7 +268,7 @@ slint_testing::send_keyboard_char(&instance, Key::Control.into(), false);
slint_testing::send_keyboard_char(&instance, Key::Shift.into(), true);
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(101.0, 104.0), button: PointerEventButton::Left });
slint_testing::mock_elapsed_time(1000);
assert_eq!(instance.get_pointer_event_test().as_str(), "downleft(ctrl)upleft(shift)click");
assert_eq!(instance.get_pointer_event_test().as_str(), "downleft(ctrl)upleft(shift)moveother(shift)click");
// clean up:
slint_testing::send_keyboard_char(&instance, Key::Shift.into(), false);
instance.set_pointer_event_test("".into());
@ -334,7 +336,7 @@ assert_eq!(instance.get_touch_double2(), 1);
assert_eq!(instance.get_touch_double3(), 3);
assert_eq!(slint_testing::access_testing_window(instance.window(), |window| window.mouse_cursor.get()), MouseCursor::Default);
assert_eq!(instance.get_pointer_event_test().as_str(), "downleftupleftdownleftdouble_clickupleft");
assert_eq!(instance.get_pointer_event_test().as_str(), "moveotherdownleftupleftmoveothermoveotherdownleftdouble_clickupleftmoveother");
```
```js
@ -379,7 +381,7 @@ assert.equal(instance.touch_double1, 0);
assert.equal(instance.touch_double2, 0);
assert.equal(instance.touch_double3, 0);
assert.equal(instance.pointer_event_test, "downleftupleftclick");
assert.equal(instance.pointer_event_test, "moveotherdownleftupleftmoveotherclick");
// does not double-click on anything
slintlib.private_api.send_mouse_double_click(instance, 5., 5.);