| import { app } from "../../scripts/app.js"; |
| import { drawNodeWidget, drawWidgetButton, fitString, isLowQuality } from "./utils_canvas.js"; |
| export function drawLabelAndValue(ctx, label, value, width, posY, height, options) { |
| var _a; |
| const outerMargin = 15; |
| const innerMargin = 10; |
| const midY = posY + height / 2; |
| ctx.save(); |
| ctx.textAlign = "left"; |
| ctx.textBaseline = "middle"; |
| ctx.fillStyle = LiteGraph.WIDGET_SECONDARY_TEXT_COLOR; |
| const labelX = outerMargin + innerMargin + ((_a = options === null || options === void 0 ? void 0 : options.offsetLeft) !== null && _a !== void 0 ? _a : 0); |
| ctx.fillText(label, labelX, midY); |
| const valueXLeft = labelX + ctx.measureText(label).width + 7; |
| const valueXRight = width - (outerMargin + innerMargin); |
| ctx.fillStyle = LiteGraph.WIDGET_TEXT_COLOR; |
| ctx.textAlign = "right"; |
| ctx.fillText(fitString(ctx, value, valueXRight - valueXLeft), valueXRight, midY); |
| ctx.restore(); |
| } |
| export class RgthreeBaseWidget { |
| constructor(name) { |
| this.type = "custom"; |
| this.options = {}; |
| this.y = 0; |
| this.last_y = 0; |
| this.disabled = false; |
| this.mouseDowned = null; |
| this.isMouseDownedAndOver = false; |
| this.hitAreas = {}; |
| this.downedHitAreasForMove = []; |
| this.downedHitAreasForClick = []; |
| this.name = name; |
| } |
| serializeValue(node, index) { |
| return this.value; |
| } |
| clickWasWithinBounds(pos, bounds) { |
| let xStart = bounds[0]; |
| let xEnd = xStart + (bounds.length > 2 ? bounds[2] : bounds[1]); |
| const clickedX = pos[0] >= xStart && pos[0] <= xEnd; |
| if (bounds.length === 2) { |
| return clickedX; |
| } |
| return clickedX && pos[1] >= bounds[1] && pos[1] <= bounds[1] + bounds[3]; |
| } |
| mouse(event, pos, node) { |
| var _a, _b, _c; |
| const canvas = app.canvas; |
| if (event.type == "pointerdown") { |
| this.mouseDowned = [...pos]; |
| this.isMouseDownedAndOver = true; |
| this.downedHitAreasForMove.length = 0; |
| this.downedHitAreasForClick.length = 0; |
| let anyHandled = false; |
| for (const part of Object.values(this.hitAreas)) { |
| if (this.clickWasWithinBounds(pos, part.bounds)) { |
| if (part.onMove) { |
| this.downedHitAreasForMove.push(part); |
| } |
| if (part.onClick) { |
| this.downedHitAreasForClick.push(part); |
| } |
| if (part.onDown) { |
| const thisHandled = part.onDown.apply(this, [event, pos, node, part]); |
| anyHandled = anyHandled || thisHandled == true; |
| } |
| part.wasMouseClickedAndIsOver = true; |
| } |
| } |
| return (_a = this.onMouseDown(event, pos, node)) !== null && _a !== void 0 ? _a : anyHandled; |
| } |
| if (event.type == "pointerup") { |
| if (!this.mouseDowned) |
| return true; |
| this.downedHitAreasForMove.length = 0; |
| const wasMouseDownedAndOver = this.isMouseDownedAndOver; |
| this.cancelMouseDown(); |
| let anyHandled = false; |
| for (const part of Object.values(this.hitAreas)) { |
| if (part.onUp && this.clickWasWithinBounds(pos, part.bounds)) { |
| const thisHandled = part.onUp.apply(this, [event, pos, node, part]); |
| anyHandled = anyHandled || thisHandled == true; |
| } |
| part.wasMouseClickedAndIsOver = false; |
| } |
| for (const part of this.downedHitAreasForClick) { |
| if (this.clickWasWithinBounds(pos, part.bounds)) { |
| const thisHandled = part.onClick.apply(this, [event, pos, node, part]); |
| anyHandled = anyHandled || thisHandled == true; |
| } |
| } |
| this.downedHitAreasForClick.length = 0; |
| if (wasMouseDownedAndOver) { |
| const thisHandled = this.onMouseClick(event, pos, node); |
| anyHandled = anyHandled || thisHandled == true; |
| } |
| return (_b = this.onMouseUp(event, pos, node)) !== null && _b !== void 0 ? _b : anyHandled; |
| } |
| if (event.type == "pointermove") { |
| this.isMouseDownedAndOver = !!this.mouseDowned; |
| if (this.mouseDowned && |
| (pos[0] < 15 || |
| pos[0] > node.size[0] - 15 || |
| pos[1] < this.last_y || |
| pos[1] > this.last_y + LiteGraph.NODE_WIDGET_HEIGHT)) { |
| this.isMouseDownedAndOver = false; |
| } |
| for (const part of Object.values(this.hitAreas)) { |
| if (this.downedHitAreasForMove.includes(part)) { |
| part.onMove.apply(this, [event, pos, node, part]); |
| } |
| if (this.downedHitAreasForClick.includes(part)) { |
| part.wasMouseClickedAndIsOver = this.clickWasWithinBounds(pos, part.bounds); |
| } |
| } |
| return (_c = this.onMouseMove(event, pos, node)) !== null && _c !== void 0 ? _c : true; |
| } |
| return false; |
| } |
| cancelMouseDown() { |
| this.mouseDowned = null; |
| this.isMouseDownedAndOver = false; |
| this.downedHitAreasForMove.length = 0; |
| } |
| onMouseDown(event, pos, node) { |
| return; |
| } |
| onMouseUp(event, pos, node) { |
| return; |
| } |
| onMouseClick(event, pos, node) { |
| return; |
| } |
| onMouseMove(event, pos, node) { |
| return; |
| } |
| } |
| export class RgthreeBetterButtonWidget extends RgthreeBaseWidget { |
| constructor(name, mouseClickCallback, label) { |
| super(name); |
| this.type = "custom"; |
| this.value = ""; |
| this.label = ""; |
| this.mouseClickCallback = mouseClickCallback; |
| this.label = label || name; |
| } |
| draw(ctx, node, width, y, height) { |
| drawWidgetButton(ctx, { size: [width - 30, height], pos: [15, y] }, this.label, this.isMouseDownedAndOver); |
| } |
| onMouseClick(event, pos, node) { |
| return this.mouseClickCallback(event, pos, node); |
| } |
| } |
| export class RgthreeBetterTextWidget extends RgthreeBaseWidget { |
| constructor(name, value) { |
| super(name); |
| this.name = name; |
| this.value = value; |
| } |
| draw(ctx, node, width, y, height) { |
| const widgetData = drawNodeWidget(ctx, { size: [width, height], pos: [15, y] }); |
| if (!widgetData.lowQuality) { |
| drawLabelAndValue(ctx, this.name, this.value, width, y, height); |
| } |
| } |
| mouse(event, pos, node) { |
| const canvas = app.canvas; |
| if (event.type == "pointerdown") { |
| canvas.prompt("Label", this.value, (v) => (this.value = v), event); |
| return true; |
| } |
| return false; |
| } |
| } |
| export class RgthreeDividerWidget extends RgthreeBaseWidget { |
| constructor(widgetOptions) { |
| super("divider"); |
| this.value = {}; |
| this.options = { serialize: false }; |
| this.type = "custom"; |
| this.widgetOptions = { |
| marginTop: 7, |
| marginBottom: 7, |
| marginLeft: 15, |
| marginRight: 15, |
| color: LiteGraph.WIDGET_OUTLINE_COLOR, |
| thickness: 1, |
| }; |
| Object.assign(this.widgetOptions, widgetOptions || {}); |
| } |
| draw(ctx, node, width, posY, h) { |
| if (this.widgetOptions.thickness) { |
| ctx.strokeStyle = this.widgetOptions.color; |
| const x = this.widgetOptions.marginLeft; |
| const y = posY + this.widgetOptions.marginTop; |
| const w = width - this.widgetOptions.marginLeft - this.widgetOptions.marginRight; |
| ctx.stroke(new Path2D(`M ${x} ${y} h ${w}`)); |
| } |
| } |
| computeSize(width) { |
| return [ |
| width, |
| this.widgetOptions.marginTop + this.widgetOptions.marginBottom + this.widgetOptions.thickness, |
| ]; |
| } |
| } |
| export class RgthreeLabelWidget extends RgthreeBaseWidget { |
| constructor(name, widgetOptions) { |
| super(name); |
| this.type = "custom"; |
| this.options = { serialize: false }; |
| this.value = ""; |
| this.widgetOptions = {}; |
| this.posY = 0; |
| Object.assign(this.widgetOptions, widgetOptions); |
| } |
| update(widgetOptions) { |
| Object.assign(this.widgetOptions, widgetOptions); |
| } |
| draw(ctx, node, width, posY, height) { |
| var _a; |
| this.posY = posY; |
| ctx.save(); |
| let text = (_a = this.widgetOptions.text) !== null && _a !== void 0 ? _a : this.name; |
| if (typeof text === "function") { |
| text = text(); |
| } |
| ctx.textAlign = this.widgetOptions.align || "left"; |
| ctx.fillStyle = this.widgetOptions.color || LiteGraph.WIDGET_TEXT_COLOR; |
| const oldFont = ctx.font; |
| if (this.widgetOptions.italic) { |
| ctx.font = "italic " + ctx.font; |
| } |
| if (this.widgetOptions.size) { |
| ctx.font = ctx.font.replace(/\d+px/, `${this.widgetOptions.size}px`); |
| } |
| const midY = posY + height / 2; |
| ctx.textBaseline = "middle"; |
| if (this.widgetOptions.align === "center") { |
| ctx.fillText(text, node.size[0] / 2, midY); |
| } |
| else { |
| ctx.fillText(text, 15, midY); |
| } |
| ctx.font = oldFont; |
| if (this.widgetOptions.actionLabel === "__PLUS_ICON__") { |
| const plus = new Path2D(`M${node.size[0] - 15 - 2} ${posY + 7} v4 h-4 v4 h-4 v-4 h-4 v-4 h4 v-4 h4 v4 h4 z`); |
| ctx.lineJoin = "round"; |
| ctx.lineCap = "round"; |
| ctx.fillStyle = "#3a3"; |
| ctx.strokeStyle = "#383"; |
| ctx.fill(plus); |
| ctx.stroke(plus); |
| } |
| ctx.restore(); |
| } |
| mouse(event, nodePos, node) { |
| if (event.type !== "pointerdown" || |
| isLowQuality() || |
| !this.widgetOptions.actionLabel || |
| !this.widgetOptions.actionCallback) { |
| return false; |
| } |
| const pos = [nodePos[0], nodePos[1] - this.posY]; |
| const rightX = node.size[0] - 15; |
| if (pos[0] > rightX || pos[0] < rightX - 16) { |
| return false; |
| } |
| this.widgetOptions.actionCallback(event); |
| return true; |
| } |
| } |
| export class RgthreeInvisibleWidget extends RgthreeBaseWidget { |
| constructor(name, type, value, serializeValueFn) { |
| super(name); |
| this.type = "custom"; |
| this.value = value; |
| this.serializeValueFn = serializeValueFn; |
| } |
| draw() { |
| return; |
| } |
| computeSize(width) { |
| return [0, 0]; |
| } |
| serializeValue(node, index) { |
| return this.serializeValueFn != null |
| ? this.serializeValueFn(node, index) |
| : super.serializeValue(node, index); |
| } |
| } |
|
|