instara-models / custom-nodes /Comfyui_LG_Tools /web /multi_button_widget.js
parlorsky's picture
Upload folder using huggingface_hub
3a4bb96 verified
Raw
History Blame Contribute Delete
4.84 kB
// 通用多按钮组件定义
const MultiButtonWidget = (app, inputName, options, buttons) => {
const widget = {
name: inputName,
type: "multi_button",
y: 0,
value: null,
options: options || {},
clicked_button: null,
click_time: 0
};
// 使用 ComfyUI 原生样式常量
const margin = 15;
const button_height = LiteGraph.NODE_WIDGET_HEIGHT || 20;
const label_width = options.labelWidth !== undefined ? options.labelWidth : 80;
const button_spacing = options.buttonSpacing || 4;
const button_count = buttons.length;
// 原生 ComfyUI 按钮颜色
const BUTTON_BGCOLOR = "#222";
const BUTTON_OUTLINE_COLOR = "#666";
const BUTTON_TEXT_COLOR = "#DDD";
const BUTTON_CLICKED_COLOR = "#AAA";
widget.draw = function(ctx, node, width, Y, height) {
if (app.canvas.ds.scale < 0.50) return;
ctx.save();
ctx.lineWidth = 1;
// 绘制标签(仅当有标签时)
if (label_width > 0 && inputName) {
ctx.fillStyle = LiteGraph.WIDGET_SECONDARY_TEXT_COLOR;
ctx.textAlign = "left";
ctx.fillText(inputName, margin, Y + height * 0.7);
}
// 计算按钮区域
const label_space = label_width > 0 ? label_width : 0;
const left_margin = label_width > 0 ? margin : 10; // 没有标签时使用小边距避免超出节点
const right_margin = label_width > 0 ? margin : 10; // 右边也保持小边距
const available_width = width - label_space - left_margin - right_margin;
const total_spacing = button_spacing * (button_count - 1);
const button_width = (available_width - total_spacing) / button_count;
const start_x = label_space + left_margin;
// 检查点击高亮是否需要清除
const now = Date.now();
if (widget.click_time && now - widget.click_time > 150) {
widget.clicked_button = null;
widget.click_time = 0;
}
// 循环绘制所有按钮
for (let i = 0; i < button_count; i++) {
const button = buttons[i];
const button_x = start_x + i * (button_width + button_spacing);
// 确定按钮颜色(点击高亮或默认)
const is_clicked = (widget.clicked_button === i);
const button_color = is_clicked ? BUTTON_CLICKED_COLOR :
(button.color || BUTTON_BGCOLOR);
// 绘制按钮背景
ctx.fillStyle = button_color;
ctx.fillRect(button_x, Y, button_width, button_height);
// 绘制按钮边框
ctx.strokeStyle = BUTTON_OUTLINE_COLOR;
ctx.strokeRect(button_x, Y, button_width, button_height);
// 绘制按钮文字
ctx.fillStyle = BUTTON_TEXT_COLOR;
ctx.textAlign = "center";
ctx.fillText(button.text, button_x + button_width / 2, Y + button_height * 0.7);
}
ctx.restore();
};
widget.onPointerDown = function(pointer, node) {
const e = pointer.eDown;
const label_space = label_width > 0 ? label_width : 0;
const left_margin = label_width > 0 ? margin : 10;
const right_margin = label_width > 0 ? margin : 10;
const x = e.canvasX - node.pos[0] - label_space - left_margin;
const available_width = node.size[0] - label_space - left_margin - right_margin;
const total_spacing = button_spacing * (button_count - 1);
const button_width = (available_width - total_spacing) / button_count;
pointer.onClick = () => {
// 计算点击了哪个按钮
for (let i = 0; i < button_count; i++) {
const button_start = i * (button_width + button_spacing);
const button_end = button_start + button_width;
if (x >= button_start && x <= button_end) {
// 点击了第 i 个按钮
widget.clicked_button = i;
widget.click_time = Date.now();
// 执行回调函数
if (buttons[i] && buttons[i].callback) {
buttons[i].callback();
}
// 触发重绘以显示点击效果
app.graph.setDirtyCanvas(true);
break;
}
}
};
};
widget.computeSize = function() {
return [0, button_height];
};
widget.serializeValue = async () => {
return null;
};
return widget;
};
// 导出组件
export { MultiButtonWidget };