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)
}
}
} |