aboutsummaryrefslogtreecommitdiff
path: root/linux/home/.config/ags/widget/osd/Progress.ts
blob: bcf27da33c4ecb89a5b7b5beb2c075a7b6546d87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import type Gtk from "gi://Gtk?version=3.0"
import GLib from "gi://GLib?version=2.0"
import { range } from "lib/utils"
import options from "options"

type ProgressProps = {
    height?: number
    width?: number
    vertical?: boolean
    child: Gtk.Widget
}

export default ({
    height = 18,
    width = 180,
    vertical = false,
    child,
}: ProgressProps) => {
    const fill = Widget.Box({
        class_name: "fill",
        hexpand: vertical,
        vexpand: !vertical,
        hpack: vertical ? "fill" : "start",
        vpack: vertical ? "end" : "fill",
        child,
    })

    const container = Widget.Box({
        class_name: "progress",
        child: fill,
        css: `
            min-width: ${width}px;
            min-height: ${height}px;
        `,
    })

    let fill_size = 0
    let animations: number[] = []

    return Object.assign(container, {
        setValue(value: number) {
            if (value < 0)
                return

            if (animations.length > 0) {
                for (const id of animations)
                    GLib.source_remove(id)

                animations = []
            }

            const axis = vertical ? "height" : "width"
            const axisv = vertical ? height : width
            const min = vertical ? width : height
            const preferred = (axisv - min) * value + min

            if (!fill_size) {
                fill_size = preferred
                fill.css = `min-${axis}: ${preferred}px;`
                return
            }

            const frames = options.transition.value / 10
            const goal = preferred - fill_size
            const step = goal / frames

            animations = range(frames, 0).map(i => Utils.timeout(5 * i, () => {
                fill_size += step
                fill.css = `min-${axis}: ${fill_size}px`
                animations.shift()
            }))
        },
    })
}