slint/internal/compiler/widgets/common/slider-base.slint
2025-01-25 21:30:22 +01:00

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);
}
}