58 lines
1.7 KiB
Plaintext
58 lines
1.7 KiB
Plaintext
import { Theme, Animations } from "../theme/theme.slint";
|
|
|
|
export enum StatusState {
|
|
stopped,
|
|
starting,
|
|
running,
|
|
}
|
|
|
|
export component StatusIndicator {
|
|
in property <StatusState> state: StatusState.stopped;
|
|
|
|
private property <color> dot-color: state == StatusState.running ? #22c55e :
|
|
state == StatusState.starting ? #eab308 :
|
|
#9ca3af;
|
|
|
|
private property <bool> should-animate: state == StatusState.running || state == StatusState.starting;
|
|
|
|
width: 10px;
|
|
height: 10px;
|
|
|
|
// Breathing animation ring
|
|
if root.should-animate: ping := Rectangle {
|
|
width: parent.width;
|
|
height: parent.height;
|
|
border-radius: 5px;
|
|
background: root.dot-color.transparentize(0.25);
|
|
|
|
// Animate scale and opacity for breathing effect
|
|
states [
|
|
pulse: {
|
|
ping.width: parent.width * 2;
|
|
ping.height: parent.height * 2;
|
|
ping.x: -parent.width / 2;
|
|
ping.y: -parent.height / 2;
|
|
ping.opacity: 0;
|
|
|
|
in {
|
|
animate width, height, x, y, opacity {
|
|
duration: 1500ms;
|
|
easing: cubic-bezier(0, 0, 0.2, 1);
|
|
iteration-count: -1;
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
// Main dot
|
|
dot := Rectangle {
|
|
width: parent.width;
|
|
height: parent.height;
|
|
border-radius: 5px;
|
|
background: root.dot-color;
|
|
|
|
animate background { duration: Animations.durations.normal; }
|
|
}
|
|
}
|