File size: 4,590 Bytes
c6535db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import { BaseWidget } from "./BaseWidget.js"
import { clamp } from "../utils/widget.js"
import { THEME_COLOR } from "@/constants";

export class SliderWidget extends BaseWidget {
    constructor(widget, node) {
        super(widget, node);
        this.type = "slider";
    }

    /**
     * Draws the widget
     * @param {CanvasRenderingContext2D} ctx The canvas context
     * @param {Object} options The options for drawing the widget
     * @param {number} options.width
     * @param {boolean} [options.showText=true]
     */
    drawWidget(ctx, {
        width,
        showText = true,
        isEasyUseTheme = false,
    }) {
        // Store original context attributes
        const { fillStyle, strokeStyle, textAlign } = ctx

        const { height, y } = this
        const { margin } = BaseWidget

        // Draw background
        ctx.fillStyle = this.background_color
        if(isEasyUseTheme){
            ctx.strokeStyle = this.outline_color
            ctx.beginPath();
            ctx.roundRect(margin, y, width - margin * 2, height, [height * 0.25]);
            ctx.fill();
            ctx.stroke();
        }else{
            ctx.fillRect(margin, y, width - margin * 2, height)
        }

        // Calculate normalized value
        const range = this.options.max - this.options.min
        let nvalue = (this.value - this.options.min) / range
        nvalue = clamp(nvalue, 0, 1)

        // Draw slider bar
        ctx.fillStyle = this.options.slider_color ?? THEME_COLOR
        if(isEasyUseTheme){
            ctx.beginPath();
            ctx.roundRect(margin, y, nvalue * (width - margin * 2), height, [height * 0.25]);
            ctx.fill();
        }
        else{
            ctx.fillRect(margin, y, nvalue * (width - margin * 2), height)
        }

        // Draw outline if not disabled
        if (showText && !this.computedDisabled) {
            ctx.strokeStyle = this.outline_color
            if(!isEasyUseTheme){
                ctx.strokeRect(margin, y, width - margin * 2, height)
            }
        }

        // Draw marker if present
        if (this.marker != null) {
            let marker_nvalue = (this.marker - this.options.min) / range
            marker_nvalue = clamp(marker_nvalue, 0, 1)
            ctx.fillStyle = this.options.marker_color ?? "#AA9"
            if(isEasyUseTheme){
                ctx.roundRect(
                    margin + marker_nvalue * (width - margin * 2),
                    y,
                    2,
                    height,
                    [height * 0.25]);
            }else{
                ctx.fillRect(
                    margin + marker_nvalue * (width - margin * 2),
                    y,
                    2,
                    height,
                )
            }

        }

        // Draw text
        if (showText) {
            ctx.textAlign = "center"
            ctx.fillStyle = this.text_color
            const fixedValue = Number(this.value).toFixed(this.options.precision ?? 3)
            ctx.fillText(
                `${this.label || this.name}  ${fixedValue}`,
                width * 0.5,
                y + height * 0.7,
            )
        }

        // Restore original context attributes
        Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
    }

    /**
     * Handles click events for the slider widget
     * @param {Object} options Widget event options
     */
    onClick(options) {
        if (this.options.read_only) return

        const { e, node } = options
        const width = this.width || node.size[0]
        const x = e.canvasX - node.pos[0]

        // Calculate new value based on click position
        const slideFactor = clamp((x - 15) / (width - 30), 0, 1)
        const newValue = this.options.min + (this.options.max - this.options.min) * slideFactor

        if (newValue !== this.value) {
            this.setValue(newValue, options)
        }
    }

    /**
     * Handles drag events for the slider widget
     * @param {Object} options Widget event options
     * @returns {boolean}
     */
    onDrag(options) {
        if (this.options.read_only) return false

        const { e, node } = options
        const width = this.width || node.size[0]
        const x = e.canvasX - node.pos[0]

        // Calculate new value based on drag position
        const slideFactor = clamp((x - 15) / (width - 30), 0, 1)
        const newValue = this.options.min + (this.options.max - this.options.min) * slideFactor

        if (newValue !== this.value) {
            this.setValue(newValue, options)
        }
    }
}