mirror of
https://github.com/slint-ui/slint.git
synced 2025-07-31 00:44:23 +00:00
125 lines
4.3 KiB
Text
125 lines
4.3 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 SliderBase {
|
|
in property <bool> enabled <=> touch-area.enabled;
|
|
in property <float> minimum: 0;
|
|
in property <float> maximum: 100;
|
|
in property <float> step: 1;
|
|
in property <Orientation> orientation;
|
|
in property <length> handle-x;
|
|
in property <length> handle-y;
|
|
in property <length> handle-width;
|
|
in property <length> handle-height;
|
|
out property <bool> pressed <=> touch-area.enabled;
|
|
out property <bool> has-hover <=> touch-area.has-hover;
|
|
out property <bool> vertical: root.orientation == Orientation.vertical;
|
|
out property <bool> has-focus <=> focus-scope.has-focus;
|
|
out property <bool> handle-has-hover: touch-area.mouse-x >= root.handle-x && touch-area.mouse-x <= root.handle-x + root.handle-width &&
|
|
touch-area.mouse-y >= root.handle-y && touch-area.mouse-y <= root.handle-y + root.handle-height;
|
|
out property <bool> handle-pressed;
|
|
in-out property <float> value: minimum;
|
|
|
|
callback changed(value: float);
|
|
callback released(value: float);
|
|
|
|
private property <length> ref-size: !root.vertical ? root.handle-width : root.handle-height;
|
|
|
|
forward-focus: focus-scope;
|
|
|
|
touch-area := TouchArea {
|
|
property <float> pressed-value;
|
|
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
pointer-event(event) => {
|
|
if (event.button != PointerEventButton.left) {
|
|
return;
|
|
}
|
|
|
|
if (event.kind == PointerEventKind.up) {
|
|
if (root.handle-pressed) {
|
|
root.released(root.value);
|
|
}
|
|
root.handle-pressed = false;
|
|
return;
|
|
}
|
|
|
|
|
|
if (!root.handle-has-hover) {
|
|
root.set-value((!root.vertical ? root.size-to-value(touch-area.mouse-x, root.width) :
|
|
root.size-to-value(touch-area.mouse-y, root.height)) + root.minimum);
|
|
}
|
|
|
|
self.pressed-value = value;
|
|
focus-scope.focus();
|
|
root.handle-pressed = true;
|
|
}
|
|
|
|
moved => {
|
|
if (!self.enabled) {
|
|
return;
|
|
}
|
|
|
|
root.set-value(self.pressed-value + (!vertical ? root.size-to-value(touch-area.mouse-x - touch-area.pressed-x, root.width - root.ref-size) :
|
|
root.size-to-value(touch-area.mouse-y - touch-area.pressed-y, root.height - root.ref-size))
|
|
);
|
|
}
|
|
}
|
|
|
|
focus-scope := FocusScope {
|
|
x: 0;
|
|
y: 0;
|
|
width: 0;
|
|
height: 0;
|
|
enabled: root.enabled;
|
|
|
|
key-pressed(event) => {
|
|
if (!self.enabled || root.step <= 0) {
|
|
return reject;
|
|
}
|
|
|
|
if ((!vertical && event.text == Key.RightArrow) || (vertical && event.text == Key.DownArrow)) {
|
|
root.set-value(root.value + root.step);
|
|
return accept;
|
|
} else if ((!vertical && event.text == Key.LeftArrow) || (vertical && event.text == Key.UpArrow)) {
|
|
root.set-value(root.value - root.step);
|
|
return accept;
|
|
} else if (event.text == Key.Home) {
|
|
root.set-value(root.minimum);
|
|
return accept;
|
|
} else if (event.text == Key.End) {
|
|
root.set-value(root.maximum);
|
|
return accept;
|
|
}
|
|
|
|
reject
|
|
}
|
|
|
|
key-released(event) => {
|
|
if (!self.enabled) {
|
|
return reject;
|
|
}
|
|
if (!vertical && event.text == Key.RightArrow) || (vertical && event.text == Key.DownArrow)
|
|
|| (!vertical && event.text == Key.LeftArrow) || (vertical && event.text == Key.UpArrow)
|
|
|| event.text == Key.Home || event.text == Key.End {
|
|
root.released(root.value);
|
|
}
|
|
return accept;
|
|
}
|
|
}
|
|
|
|
pure function size-to-value(size: length, range: length) -> float {
|
|
size * (root.maximum - root.minimum) / range;
|
|
}
|
|
|
|
function set-value(value: float) {
|
|
if (root.value == value) {
|
|
return;
|
|
}
|
|
|
|
root.value = max(root.minimum, min(root.maximum, value));
|
|
root.changed(root.value);
|
|
}
|
|
}
|