File size: 2,813 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
import {BaseSteppedWidget} from "./BaseSteppedWidget.js"
import {getWidgetStep} from "../utils/widget.js"

export class NumberWidget extends BaseSteppedWidget {
    constructor(widget, node) {
        super(widget, node);
        this.type = "number";
    }

    get _displayValue() {
        return Number(this.value).toFixed(
            this.options.precision !== undefined
                ? this.options.precision
                : 3,
        )
    }

    canIncrement() {
        const {max} = this.options
        return max == null || this.value < max
    }

    canDecrement() {
        const {min} = this.options
        return min == null || this.value > min
    }

    incrementValue(options) {
        this.setValue(this.value + getWidgetStep(this.options), options)
    }

    decrementValue(options) {
        this.setValue(this.value - getWidgetStep(this.options), options)
    }

    setValue(value, options) {
        let newValue = value
        if (this.options.min != null && newValue < this.options.min) {
            newValue = this.options.min
        }
        if (this.options.max != null && newValue > this.options.max) {
            newValue = this.options.max
        }
        super.setValue(newValue, options)
    }

    onClick({e, node, canvas}) {
        const x = e.canvasX - node.pos[0]
        const width = this.width || node.size[0]

        // Determine if clicked on left/right arrows
        const delta = x < 40
            ? -1
            : (x > width - 40
                ? 1
                : 0)

        if (delta) {
            // Handle left/right arrow clicks
            this.setValue(this.value + delta * getWidgetStep(this.options), {e, node, canvas})
            return
        }

        // Handle center click - show prompt
        canvas.prompt("Value", this.value, (v) => {
            // Check if v is a valid equation or a number
            if (/^[\d\s()*+/-]+|\d+\.\d+$/.test(v)) {
                // Solve the equation if possible
                try {
                    v = eval(v)
                } catch {
                }
            }
            const newValue = Number(v)
            if (!isNaN(newValue)) {
                this.setValue(newValue, {e, node, canvas})
            }
        }, e)
    }

    /**
     * Handles drag events for the number widget
     * @param {object} options The options for handling the drag event
     */
    onDrag({e, node, canvas}) {
        const width = this.width || node.width
        const x = e.canvasX - node.pos[0]
        const delta = x < 40
            ? -1
            : (x > width - 40
                ? 1
                : 0)

        if (delta && (x > -3 && x < width + 3)) return
        this.setValue(this.value + (e.deltaX ?? 0) * getWidgetStep(this.options), {e, node, canvas})
    }
}