slint/tests/cases/elements/swipegesturehandler.slint
Olivier Goffart 2faae11b6b
Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / tree-sitter (push) Blocked by required conditions
CI / updater_test (0.3.0) (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.85) (push) Blocked by required conditions
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.85) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, macos-14, stable) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, beta) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly) (push) Blocked by required conditions
CI / node_test (macos-14) (push) Blocked by required conditions
CI / node_test (ubuntu-22.04) (push) Blocked by required conditions
CI / node_test (windows-2022) (push) Blocked by required conditions
CI / python_test (macos-14) (push) Blocked by required conditions
CI / python_test (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (macos-13) (push) Blocked by required conditions
CI / cpp_test_driver (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (macos-14, 1.85) (push) Blocked by required conditions
CI / cpp_cmake (ubuntu-22.04, stable) (push) Blocked by required conditions
CI / cpp_cmake (windows-2022, nightly) (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / wasm (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions
CI / wasm_demo (push) Blocked by required conditions
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / mcu (pico2-st7789, thumbv8m.main-none-eabihf) (push) Blocked by required conditions
CI / mcu (stm32h735g, thumbv7em-none-eabihf) (push) Blocked by required conditions
CI / mcu-embassy (push) Blocked by required conditions
CI / ffi_32bit_build (push) Blocked by required conditions
CI / docs (push) Blocked by required conditions
SwipeGestureHandler: better support of embedded SwipeGestureHandler's
- When checking the threshold, make sure that the change in the
   interrested dirrection is much more significant that the delta in the
   orthogonal direction (hence the `/ 2`)

 - Accept all mouse move event as we otherwise don't get them further if
   the event was delayed by another SwipeGestureHandler or flickable
2025-09-07 10:03:06 +02:00

301 lines
13 KiB
Text

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
export component TestCase inherits Window {
width: 600px;
height: 600px;
in-out property <string> r;
in property <bool> enabled <=> right-gesture.enabled;
out property ta_hover <=> ta.has-hover;
out property ta_pressed <=> ta.pressed;
out property down-swiping <=> down-gesture.swiping;
out property left-swiping <=> left-gesture.swiping;
out property right-swiping <=> right-gesture.swiping;
function distance(a: Point, b: Point) -> float {
return sqrt((a.x / 1px - b.x / 1px).pow(2) + (a.y / 1px - b.y / 1px).pow(2));
}
public function invoke_cancel() {
left-gesture.cancel()
}
down-gesture := SwipeGestureHandler {
handle-swipe-down: true;
handle-swipe-left: false;
swiped => {
r += "S1(" + distance(self.current-position, self.pressed-position) + ")";
}
cancelled => {
r += "C1(" + distance(self.current-position, self.pressed-position) + ")";
}
VerticalLayout {
left-gesture := SwipeGestureHandler {
handle-swipe-left: true;
swiped => {
r += "S2(" + distance(self.current-position, self.pressed-position) + ")";
}
moved => {
r += "M2(" + distance(self.current-position, self.pressed-position) + ")";
}
cancelled => {
r += "C2(" + distance(self.current-position, self.pressed-position) + ")";
}
}
right-gesture := SwipeGestureHandler {
handle-swipe-right: true;
ta := TouchArea {
clicked => {
r += "clicked()"
}
}
swiped => {
r += "S3(" + distance(self.current-position, self.pressed-position) + ")";
}
}
}
}
init => {
// Just make sure it doesn't crash the interpreter
left-gesture.cancel();
}
}
/*
```rust
let instance = TestCase::new().unwrap();
assert_eq!(instance.get_enabled(), true);
assert_eq!(instance.get_r(), "");
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
use slint::{platform::WindowEvent, LogicalPosition, platform::PointerEventButton};
// click
slint_testing::send_mouse_click(&instance, 500., 500.);
assert_eq!(instance.get_r(), "clicked()");
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
instance.set_r("".into());
// Down
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(4.0, 4.0) });
assert_eq!(instance.get_ta_hover(), false);
slint_testing::mock_elapsed_time(20);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(300.0, 400.0) });
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(300.0, 400.0), button: PointerEventButton::Left });
slint_testing::mock_elapsed_time(20);
assert_eq!(instance.get_ta_pressed(), false); // because we might recognize it as a gesture
assert_eq!(instance.get_ta_hover(), true, "must be hover");
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(299.0, 402.0) });
slint_testing::mock_elapsed_time(20);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(298.0, 452.0) });
slint_testing::mock_elapsed_time(20);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_down_swiping(), true);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
slint_testing::mock_elapsed_time(220);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(350.0, 482.0) });
slint_testing::mock_elapsed_time(20);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_down_swiping(), true);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_r(), "");
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(316.0, 463.0) });
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(316.0, 463.0), button: PointerEventButton::Left });
assert_eq!(instance.get_r(), "S1(65)");
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
instance.set_r("".into());
// FIXME: this shouldn't be necessary, but otherwise we don't send exit event to the toucharea
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(316.0, 463.0) });
// Left
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(100.0, 100.0) });
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
slint_testing::mock_elapsed_time(20);
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(100.0, 100.0), button: PointerEventButton::Left });
slint_testing::mock_elapsed_time(20);
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_r(), "");
slint_testing::mock_elapsed_time(20);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(80.0, 100.0) });
slint_testing::mock_elapsed_time(80);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(65.0, 112.0) });
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_left_swiping(), true);
assert_eq!(instance.get_r(), "M2(37)");
instance.window().dispatch_event(WindowEvent::PointerExited);
assert_eq!(instance.get_r(), "M2(37)C2(37)");
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_ta_hover(), false);
// Left again but cancel in the middle
instance.set_r("".into());
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(100.0, 100.0) });
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
slint_testing::mock_elapsed_time(20);
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(100.0, 100.0), button: PointerEventButton::Left });
slint_testing::mock_elapsed_time(120);
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_r(), "");
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(80.0, 100.0) });
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_left_swiping(), true);
assert_eq!(instance.get_r(), "M2(20)");
instance.invoke_invoke_cancel();
assert_eq!(instance.get_r(), "M2(20)C2(20)");
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_ta_hover(), false);
slint_testing::mock_elapsed_time(120);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(60.0, 100.0) });
slint_testing::mock_elapsed_time(120);
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(100.0, 100.0), button: PointerEventButton::Left });
slint_testing::mock_elapsed_time(120);
assert_eq!(instance.get_r(), "M2(20)C2(20)");
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
assert_eq!(instance.get_ta_hover(), false);
```
```rust
use slint::{platform::WindowEvent, LogicalPosition, platform::PointerEventButton};
// swipe two swipe area at the same time
let instance = TestCase::new().unwrap();
assert_eq!(instance.get_enabled(), true);
assert_eq!(instance.get_r(), "");
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(100.0, 400.0) });
assert_eq!(instance.get_ta_hover(), true);
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(100.0, 400.0), button: PointerEventButton::Left });
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_ta_pressed(), false);
// wait a very long time
slint_testing::mock_elapsed_time(1300);
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_ta_pressed(), true);
// up right
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(130.0, 380.0) });
assert_eq!(instance.get_r(), "");
assert_eq!(instance.get_ta_hover(), false, "hover was cancelled");
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), true);
// now down right: this cancel the previous swipe
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(110.0, 519.0) });
assert_eq!(instance.get_r(), "");
assert_eq!(instance.get_ta_hover(), false);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_down_swiping(), true);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false, "got cancelled");
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(220.0, 519.0), button: PointerEventButton::Left });
assert_eq!(instance.get_r(), "S1(169)");
assert_eq!(instance.get_ta_hover(), true);
assert_eq!(instance.get_ta_pressed(), false);
assert_eq!(instance.get_down_swiping(), false);
assert_eq!(instance.get_left_swiping(), false);
assert_eq!(instance.get_right_swiping(), false);
```
```cpp
using slint::PointerEventButton;
auto handle = TestCase::create();
const TestCase &instance = *handle;
// Left and cancel in the middle
instance.window().dispatch_pointer_press_event(slint::LogicalPosition({100.0, 100.0}), PointerEventButton::Left);
assert_eq(instance.get_ta_hover(), false);
assert_eq(instance.get_down_swiping(), false);
assert_eq(instance.get_left_swiping(), false);
assert_eq(instance.get_right_swiping(), false);
slint_testing::mock_elapsed_time(120);
instance.window().dispatch_pointer_move_event(slint::LogicalPosition({ 80.0, 100.0 }));
assert_eq(instance.get_ta_hover(), false);
assert_eq(instance.get_down_swiping(), false);
assert_eq(instance.get_right_swiping(), false);
assert_eq(instance.get_left_swiping(), true);
assert_eq(instance.get_r(), "M2(20)");
instance.invoke_invoke_cancel();
assert_eq(instance.get_r(), "M2(20)C2(20)");
assert_eq(instance.get_down_swiping(), false);
assert_eq(instance.get_left_swiping(), false);
assert_eq(instance.get_right_swiping(), false);
assert_eq(instance.get_ta_hover(), false);
slint_testing::mock_elapsed_time(120);
instance.window().dispatch_pointer_move_event(slint::LogicalPosition({ 60.0, 100.0 }));
slint_testing::mock_elapsed_time(120);
instance.window().dispatch_pointer_release_event(slint::LogicalPosition({40.0, 100.0}), PointerEventButton::Left);
slint_testing::mock_elapsed_time(120);
assert_eq(instance.get_r(), "M2(20)C2(20)");
assert_eq(instance.get_down_swiping(), false);
assert_eq(instance.get_left_swiping(), false);
assert_eq(instance.get_right_swiping(), false);
assert_eq(instance.get_ta_hover(), false);
```
*/