mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-28 06:14:10 +00:00

The origin of this proposal is the name of the `swipe-left`, etc. directional, boolean properties. They're missing another verb in their name. In principle the right choice would be "recognize". That is what the type name suggests, that's the term the documentation uses, so the code should read `recognize-swipe-left: true;`. However that is a long word. "Handle" is a verb that's simpler. It's also more generic (that's a downside), but it's otherwise short enough to make things look "right": ``` SwipeGestureHandler { handle-swipe-left: true; swiped => { something.naviate-left(); } } ``` Therefore this patch proposes to rename the type to SwipeGestureHandler and prefixes the boolean directional properties with "handle".
101 lines
2.9 KiB
Text
101 lines
2.9 KiB
Text
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
import { Theme } from "theme.slint";
|
|
|
|
export component Carousel {
|
|
in-out property <int> selected-index;
|
|
in property <length> spacing;
|
|
in property <length> itemWidth;
|
|
in property <int> count: 0;
|
|
|
|
callback move-right();
|
|
callback move-left();
|
|
callback move-focus-up();
|
|
|
|
move-right => {
|
|
root.selected-index = min(root.selected-index + 1, root.count - 1);
|
|
}
|
|
|
|
move-left => {
|
|
root.selected-index = max(root.selected-index - 1, 0);
|
|
}
|
|
|
|
private property <length> center-x: (root.width - Theme.size-big) / 2;
|
|
private property <duration> duration: Theme.duration-regular;
|
|
|
|
forward-focus: focus-scope;
|
|
height: Theme.size-big;
|
|
preferred-width: 100%;
|
|
|
|
focus-scope := FocusScope {
|
|
key-pressed(event) => {
|
|
if (event.text == Key.UpArrow) {
|
|
root.move-focus-up();
|
|
return accept;
|
|
}
|
|
if (event.text == Key.RightArrow) {
|
|
root.move-right();
|
|
return accept;
|
|
}
|
|
if (event.text == Key.LeftArrow) {
|
|
root.move-left();
|
|
return accept;
|
|
}
|
|
return accept;
|
|
}
|
|
}
|
|
|
|
swipe := SwipeGestureHandler {
|
|
handle-swipe-left: true;
|
|
handle-swipe-right: true;
|
|
|
|
swiped => {
|
|
if self.current-position.x > self.pressed-position.x + root.itemWidth / 2 {
|
|
root.move-left();
|
|
} else if self.current-position.x < self.pressed-position.x - root.itemWidth / 2 {
|
|
root.move-right();
|
|
}
|
|
}
|
|
|
|
TouchArea {
|
|
clicked => {
|
|
focus-scope.focus()
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
clip: true;
|
|
|
|
Rectangle {
|
|
property <length> viewport-x: root.center-x - root.selected-index * (root.itemWidth + root.spacing);
|
|
animate viewport-x {
|
|
duration: root.duration;
|
|
easing: ease-in;
|
|
}
|
|
property <length> swipe-offset: 0;
|
|
x: self.viewport-x + swipe-offset;
|
|
width: inner-layout.preferred-width;
|
|
|
|
states [
|
|
swipping when swipe.swiping: {
|
|
//x: self.viewport-x + swipe-offset;
|
|
swipe-offset: (swipe.current-position.x - swipe.pressed-position.x).clamp(-root.itemWidth, root.itemWidth);
|
|
out {
|
|
animate swipe-offset {
|
|
duration: root.duration;
|
|
easing: ease-in;
|
|
}
|
|
}
|
|
}
|
|
]
|
|
|
|
inner-layout := HorizontalLayout {
|
|
spacing <=> root.spacing;
|
|
|
|
@children
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|