79 lines
2.1 KiB
Plaintext
79 lines
2.1 KiB
Plaintext
import { Theme, SpacingSystem } from "../theme/theme.slint";
|
|
import { Animations } from "../utils/animations.slint";
|
|
|
|
export component Switch {
|
|
in property <bool> checked: false;
|
|
in property <bool> enabled: true;
|
|
|
|
callback toggled(bool);
|
|
|
|
private property <bool> pressed: false;
|
|
private property <bool> hovered: false;
|
|
|
|
min-width: 32px;
|
|
min-height: 18px;
|
|
|
|
states [
|
|
disabled when !root.enabled: {
|
|
track.opacity: 0.5;
|
|
thumb.opacity: 0.5;
|
|
}
|
|
checked when root.checked: {
|
|
track.background: Theme.colors.primary;
|
|
thumb.x: root.width - thumb.width - 2px;
|
|
}
|
|
unchecked when !root.checked: {
|
|
track.background: Theme.colors.input;
|
|
thumb.x: 2px;
|
|
}
|
|
]
|
|
|
|
track := Rectangle {
|
|
width: 32px;
|
|
height: 18px;
|
|
border-radius: 9px;
|
|
background: Theme.colors.input;
|
|
border-width: 1px;
|
|
border-color: transparent;
|
|
|
|
animate background { duration: Animations.durations.fast; easing: Animations.ease-out; }
|
|
|
|
thumb := Rectangle {
|
|
width: 14px;
|
|
height: 14px;
|
|
y: (parent.height - self.height) / 2;
|
|
x: 2px;
|
|
border-radius: 7px;
|
|
background: Theme.colors.background;
|
|
|
|
drop-shadow-blur: 2px;
|
|
drop-shadow-color: #00000040;
|
|
drop-shadow-offset-y: 1px;
|
|
|
|
animate x { duration: Animations.durations.fast; easing: Animations.ease-out; }
|
|
}
|
|
}
|
|
|
|
touch := TouchArea {
|
|
enabled: root.enabled;
|
|
|
|
clicked => {
|
|
if (root.enabled) {
|
|
root.toggled(!root.checked);
|
|
}
|
|
}
|
|
|
|
pointer-event(event) => {
|
|
if (event.kind == PointerEventKind.down) {
|
|
root.pressed = true;
|
|
} else if (event.kind == PointerEventKind.up || event.kind == PointerEventKind.cancel) {
|
|
root.pressed = false;
|
|
}
|
|
}
|
|
|
|
moved => {
|
|
root.hovered = self.has-hover;
|
|
}
|
|
}
|
|
}
|