//widgets (function(global) { var LiteGraph = global.LiteGraph; /* Button ****************/ function WidgetButton() { this.addOutput("", LiteGraph.EVENT); this.addOutput("", "boolean"); this.addProperty("text", "click me"); this.addProperty("font_size", 30); this.addProperty("message", ""); this.size = [164, 84]; this.clicked = false; } WidgetButton.title = "Button"; WidgetButton.desc = "Triggers an event"; WidgetButton.font = "Arial"; WidgetButton.prototype.onDrawForeground = function(ctx) { if (this.flags.collapsed) { return; } var margin = 10; ctx.fillStyle = "black"; ctx.fillRect( margin + 1, margin + 1, this.size[0] - margin * 2, this.size[1] - margin * 2 ); ctx.fillStyle = "#AAF"; ctx.fillRect( margin - 1, margin - 1, this.size[0] - margin * 2, this.size[1] - margin * 2 ); ctx.fillStyle = this.clicked ? "white" : this.mouseOver ? "#668" : "#334"; ctx.fillRect( margin, margin, this.size[0] - margin * 2, this.size[1] - margin * 2 ); if (this.properties.text || this.properties.text === 0) { var font_size = this.properties.font_size || 30; ctx.textAlign = "center"; ctx.fillStyle = this.clicked ? "black" : "white"; ctx.font = font_size + "px " + WidgetButton.font; ctx.fillText( this.properties.text, this.size[0] * 0.5, this.size[1] * 0.5 + font_size * 0.3 ); ctx.textAlign = "left"; } }; WidgetButton.prototype.onMouseDown = function(e, local_pos) { if ( local_pos[0] > 1 && local_pos[1] > 1 && local_pos[0] < this.size[0] - 2 && local_pos[1] < this.size[1] - 2 ) { this.clicked = true; this.setOutputData(1, this.clicked); this.triggerSlot(0, this.properties.message); return true; } }; WidgetButton.prototype.onExecute = function() { this.setOutputData(1, this.clicked); }; WidgetButton.prototype.onMouseUp = function(e) { this.clicked = false; }; LiteGraph.registerNodeType("widget/button", WidgetButton); function WidgetToggle() { this.addInput("", "boolean"); this.addInput("e", LiteGraph.ACTION); this.addOutput("v", "boolean"); this.addOutput("e", LiteGraph.EVENT); this.properties = { font: "", value: false }; this.size = [160, 44]; } WidgetToggle.title = "Toggle"; WidgetToggle.desc = "Toggles between true or false"; WidgetToggle.prototype.onDrawForeground = function(ctx) { if (this.flags.collapsed) { return; } var size = this.size[1] * 0.5; var margin = 0.25; var h = this.size[1] * 0.8; ctx.font = this.properties.font || (size * 0.8).toFixed(0) + "px Arial"; var w = ctx.measureText(this.title).width; var x = (this.size[0] - (w + size)) * 0.5; ctx.fillStyle = "#AAA"; ctx.fillRect(x, h - size, size, size); ctx.fillStyle = this.properties.value ? "#AEF" : "#000"; ctx.fillRect( x + size * margin, h - size + size * margin, size * (1 - margin * 2), size * (1 - margin * 2) ); ctx.textAlign = "left"; ctx.fillStyle = "#AAA"; ctx.fillText(this.title, size * 1.2 + x, h * 0.85); ctx.textAlign = "left"; }; WidgetToggle.prototype.onAction = function(action) { this.properties.value = !this.properties.value; this.trigger("e", this.properties.value); }; WidgetToggle.prototype.onExecute = function() { var v = this.getInputData(0); if (v != null) { this.properties.value = v; } this.setOutputData(0, this.properties.value); }; WidgetToggle.prototype.onMouseDown = function(e, local_pos) { if ( local_pos[0] > 1 && local_pos[1] > 1 && local_pos[0] < this.size[0] - 2 && local_pos[1] < this.size[1] - 2 ) { this.properties.value = !this.properties.value; this.graph._version++; this.trigger("e", this.properties.value); return true; } }; LiteGraph.registerNodeType("widget/toggle", WidgetToggle); /* Number ****************/ function WidgetNumber() { this.addOutput("", "number"); this.size = [80, 60]; this.properties = { min: -1000, max: 1000, value: 1, step: 1 }; this.old_y = -1; this._remainder = 0; this._precision = 0; this.mouse_captured = false; } WidgetNumber.title = "Number"; WidgetNumber.desc = "Widget to select number value"; WidgetNumber.pixels_threshold = 10; WidgetNumber.markers_color = "#666"; WidgetNumber.prototype.onDrawForeground = function(ctx) { var x = this.size[0] * 0.5; var h = this.size[1]; if (h > 30) { ctx.fillStyle = WidgetNumber.markers_color; ctx.beginPath(); ctx.moveTo(x, h * 0.1); ctx.lineTo(x + h * 0.1, h * 0.2); ctx.lineTo(x + h * -0.1, h * 0.2); ctx.fill(); ctx.beginPath(); ctx.moveTo(x, h * 0.9); ctx.lineTo(x + h * 0.1, h * 0.8); ctx.lineTo(x + h * -0.1, h * 0.8); ctx.fill(); ctx.font = (h * 0.7).toFixed(1) + "px Arial"; } else { ctx.font = (h * 0.8).toFixed(1) + "px Arial"; } ctx.textAlign = "center"; ctx.font = (h * 0.7).toFixed(1) + "px Arial"; ctx.fillStyle = "#EEE"; ctx.fillText( this.properties.value.toFixed(this._precision), x, h * 0.75 ); }; WidgetNumber.prototype.onExecute = function() { this.setOutputData(0, this.properties.value); }; WidgetNumber.prototype.onPropertyChanged = function(name, value) { var t = (this.properties.step + "").split("."); this._precision = t.length > 1 ? t[1].length : 0; }; WidgetNumber.prototype.onMouseDown = function(e, pos) { if (pos[1] < 0) { return; } this.old_y = e.canvasY; this.captureInput(true); this.mouse_captured = true; return true; }; WidgetNumber.prototype.onMouseMove = function(e) { if (!this.mouse_captured) { return; } var delta = this.old_y - e.canvasY; if (e.shiftKey) { delta *= 10; } if (e.metaKey || e.altKey) { delta *= 0.1; } this.old_y = e.canvasY; var steps = this._remainder + delta / WidgetNumber.pixels_threshold; this._remainder = steps % 1; steps = steps | 0; var v = clamp( this.properties.value + steps * this.properties.step, this.properties.min, this.properties.max ); this.properties.value = v; this.graph._version++; this.setDirtyCanvas(true); }; WidgetNumber.prototype.onMouseUp = function(e, pos) { if (e.click_time < 200) { var steps = pos[1] > this.size[1] * 0.5 ? -1 : 1; this.properties.value = clamp( this.properties.value + steps * this.properties.step, this.properties.min, this.properties.max ); this.graph._version++; this.setDirtyCanvas(true); } if (this.mouse_captured) { this.mouse_captured = false; this.captureInput(false); } }; LiteGraph.registerNodeType("widget/number", WidgetNumber); /* Combo ****************/ function WidgetCombo() { this.addOutput("", "string"); this.addOutput("change", LiteGraph.EVENT); this.size = [80, 60]; this.properties = { value: "A", values:"A;B;C" }; this.old_y = -1; this.mouse_captured = false; this._values = this.properties.values.split(";"); var that = this; this.widgets_up = true; this.widget = this.addWidget("combo","", this.properties.value, function(v){ that.properties.value = v; that.triggerSlot(1, v); }, { property: "value", values: this._values } ); } WidgetCombo.title = "Combo"; WidgetCombo.desc = "Widget to select from a list"; WidgetCombo.prototype.onExecute = function() { this.setOutputData( 0, this.properties.value ); }; WidgetCombo.prototype.onPropertyChanged = function(name, value) { if(name == "values") { this._values = value.split(";"); this.widget.options.values = this._values; } else if(name == "value") { this.widget.value = value; } }; LiteGraph.registerNodeType("widget/combo", WidgetCombo); /* Knob ****************/ function WidgetKnob() { this.addOutput("", "number"); this.size = [64, 84]; this.properties = { min: 0, max: 1, value: 0.5, color: "#7AF", precision: 2 }; this.value = -1; } WidgetKnob.title = "Knob"; WidgetKnob.desc = "Circular controller"; WidgetKnob.size = [80, 100]; WidgetKnob.prototype.onDrawForeground = function(ctx) { if (this.flags.collapsed) { return; } if (this.value == -1) { this.value = (this.properties.value - this.properties.min) / (this.properties.max - this.properties.min); } var center_x = this.size[0] * 0.5; var center_y = this.size[1] * 0.5; var radius = Math.min(this.size[0], this.size[1]) * 0.5 - 5; var w = Math.floor(radius * 0.05); ctx.globalAlpha = 1; ctx.save(); ctx.translate(center_x, center_y); ctx.rotate(Math.PI * 0.75); //bg ctx.fillStyle = "rgba(0,0,0,0.5)"; ctx.beginPath(); ctx.moveTo(0, 0); ctx.arc(0, 0, radius, 0, Math.PI * 1.5); ctx.fill(); //value ctx.strokeStyle = "black"; ctx.fillStyle = this.properties.color; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(0, 0); ctx.arc( 0, 0, radius - 4, 0, Math.PI * 1.5 * Math.max(0.01, this.value) ); ctx.closePath(); ctx.fill(); //ctx.stroke(); ctx.lineWidth = 1; ctx.globalAlpha = 1; ctx.restore(); //inner ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(center_x, center_y, radius * 0.75, 0, Math.PI * 2, true); ctx.fill(); //miniball ctx.fillStyle = this.mouseOver ? "white" : this.properties.color; ctx.beginPath(); var angle = this.value * Math.PI * 1.5 + Math.PI * 0.75; ctx.arc( center_x + Math.cos(angle) * radius * 0.65, center_y + Math.sin(angle) * radius * 0.65, radius * 0.05, 0, Math.PI * 2, true ); ctx.fill(); //text ctx.fillStyle = this.mouseOver ? "white" : "#AAA"; ctx.font = Math.floor(radius * 0.5) + "px Arial"; ctx.textAlign = "center"; ctx.fillText( this.properties.value.toFixed(this.properties.precision), center_x, center_y + radius * 0.15 ); }; WidgetKnob.prototype.onExecute = function() { this.setOutputData(0, this.properties.value); this.boxcolor = LiteGraph.colorToString([ this.value, this.value, this.value ]); }; WidgetKnob.prototype.onMouseDown = function(e) { this.center = [this.size[0] * 0.5, this.size[1] * 0.5 + 20]; this.radius = this.size[0] * 0.5; if ( e.canvasY - this.pos[1] < 20 || LiteGraph.distance( [e.canvasX, e.canvasY], [this.pos[0] + this.center[0], this.pos[1] + this.center[1]] ) > this.radius ) { return false; } this.oldmouse = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]]; this.captureInput(true); return true; }; WidgetKnob.prototype.onMouseMove = function(e) { if (!this.oldmouse) { return; } var m = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]]; var v = this.value; v -= (m[1] - this.oldmouse[1]) * 0.01; if (v > 1.0) { v = 1.0; } else if (v < 0.0) { v = 0.0; } this.value = v; this.properties.value = this.properties.min + (this.properties.max - this.properties.min) * this.value; this.oldmouse = m; this.setDirtyCanvas(true); }; WidgetKnob.prototype.onMouseUp = function(e) { if (this.oldmouse) { this.oldmouse = null; this.captureInput(false); } }; WidgetKnob.prototype.onPropertyChanged = function(name, value) { if (name == "min" || name == "max" || name == "value") { this.properties[name] = parseFloat(value); return true; //block } }; LiteGraph.registerNodeType("widget/knob", WidgetKnob); //Show value inside the debug console function WidgetSliderGUI() { this.addOutput("", "number"); this.properties = { value: 0.5, min: 0, max: 1, text: "V" }; var that = this; this.size = [140, 40]; this.slider = this.addWidget( "slider", "V", this.properties.value, function(v) { that.properties.value = v; }, this.properties ); this.widgets_up = true; } WidgetSliderGUI.title = "Inner Slider"; WidgetSliderGUI.prototype.onPropertyChanged = function(name, value) { if (name == "value") { this.slider.value = value; } }; WidgetSliderGUI.prototype.onExecute = function() { this.setOutputData(0, this.properties.value); }; LiteGraph.registerNodeType("widget/internal_slider", WidgetSliderGUI); //Widget H SLIDER function WidgetHSlider() { this.size = [160, 26]; this.addOutput("", "number"); this.properties = { color: "#7AF", min: 0, max: 1, value: 0.5 }; this.value = -1; } WidgetHSlider.title = "H.Slider"; WidgetHSlider.desc = "Linear slider controller"; WidgetHSlider.prototype.onDrawForeground = function(ctx) { if (this.value == -1) { this.value = (this.properties.value - this.properties.min) / (this.properties.max - this.properties.min); } //border ctx.globalAlpha = 1; ctx.lineWidth = 1; ctx.fillStyle = "#000"; ctx.fillRect(2, 2, this.size[0] - 4, this.size[1] - 4); ctx.fillStyle = this.properties.color; ctx.beginPath(); ctx.rect(4, 4, (this.size[0] - 8) * this.value, this.size[1] - 8); ctx.fill(); }; WidgetHSlider.prototype.onExecute = function() { this.properties.value = this.properties.min + (this.properties.max - this.properties.min) * this.value; this.setOutputData(0, this.properties.value); this.boxcolor = LiteGraph.colorToString([ this.value, this.value, this.value ]); }; WidgetHSlider.prototype.onMouseDown = function(e) { if (e.canvasY - this.pos[1] < 0) { return false; } this.oldmouse = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]]; this.captureInput(true); return true; }; WidgetHSlider.prototype.onMouseMove = function(e) { if (!this.oldmouse) { return; } var m = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]]; var v = this.value; var delta = m[0] - this.oldmouse[0]; v += delta / this.size[0]; if (v > 1.0) { v = 1.0; } else if (v < 0.0) { v = 0.0; } this.value = v; this.oldmouse = m; this.setDirtyCanvas(true); }; WidgetHSlider.prototype.onMouseUp = function(e) { this.oldmouse = null; this.captureInput(false); }; WidgetHSlider.prototype.onMouseLeave = function(e) { //this.oldmouse = null; }; LiteGraph.registerNodeType("widget/hslider", WidgetHSlider); function WidgetProgress() { this.size = [160, 26]; this.addInput("", "number"); this.properties = { min: 0, max: 1, value: 0, color: "#AAF" }; } WidgetProgress.title = "Progress"; WidgetProgress.desc = "Shows data in linear progress"; WidgetProgress.prototype.onExecute = function() { var v = this.getInputData(0); if (v != undefined) { this.properties["value"] = v; } }; WidgetProgress.prototype.onDrawForeground = function(ctx) { //border ctx.lineWidth = 1; ctx.fillStyle = this.properties.color; var v = (this.properties.value - this.properties.min) / (this.properties.max - this.properties.min); v = Math.min(1, v); v = Math.max(0, v); ctx.fillRect(2, 2, (this.size[0] - 4) * v, this.size[1] - 4); }; LiteGraph.registerNodeType("widget/progress", WidgetProgress); function WidgetText() { this.addInputs("", 0); this.properties = { value: "...", font: "Arial", fontsize: 18, color: "#AAA", align: "left", glowSize: 0, decimals: 1 }; } WidgetText.title = "Text"; WidgetText.desc = "Shows the input value"; WidgetText.widgets = [ { name: "resize", text: "Resize box", type: "button" }, { name: "led_text", text: "LED", type: "minibutton" }, { name: "normal_text", text: "Normal", type: "minibutton" } ]; WidgetText.prototype.onDrawForeground = function(ctx) { //ctx.fillStyle="#000"; //ctx.fillRect(0,0,100,60); ctx.fillStyle = this.properties["color"]; var v = this.properties["value"]; if (this.properties["glowSize"]) { ctx.shadowColor = this.properties.color; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowBlur = this.properties["glowSize"]; } else { ctx.shadowColor = "transparent"; } var fontsize = this.properties["fontsize"]; ctx.textAlign = this.properties["align"]; ctx.font = fontsize.toString() + "px " + this.properties["font"]; this.str = typeof v == "number" ? v.toFixed(this.properties["decimals"]) : v; if (typeof this.str == "string") { var lines = this.str.replace(/[\r\n]/g, "\\n").split("\\n"); for (var i=0; i < lines.length; i++) { ctx.fillText( lines[i], this.properties["align"] == "left" ? 15 : this.size[0] - 15, fontsize * -0.15 + fontsize * (parseInt(i) + 1) ); } } ctx.shadowColor = "transparent"; this.last_ctx = ctx; ctx.textAlign = "left"; }; WidgetText.prototype.onExecute = function() { var v = this.getInputData(0); if (v != null) { this.properties["value"] = v; } //this.setDirtyCanvas(true); }; WidgetText.prototype.resize = function() { if (!this.last_ctx) { return; } var lines = this.str.split("\\n"); this.last_ctx.font = this.properties["fontsize"] + "px " + this.properties["font"]; var max = 0; for (var i=0; i < lines.length; i++) { var w = this.last_ctx.measureText(lines[i]).width; if (max < w) { max = w; } } this.size[0] = max + 20; this.size[1] = 4 + lines.length * this.properties["fontsize"]; this.setDirtyCanvas(true); }; WidgetText.prototype.onPropertyChanged = function(name, value) { this.properties[name] = value; this.str = typeof value == "number" ? value.toFixed(3) : value; //this.resize(); return true; }; LiteGraph.registerNodeType("widget/text", WidgetText); function WidgetPanel() { this.size = [200, 100]; this.properties = { borderColor: "#ffffff", bgcolorTop: "#f0f0f0", bgcolorBottom: "#e0e0e0", shadowSize: 2, borderRadius: 3 }; } WidgetPanel.title = "Panel"; WidgetPanel.desc = "Non interactive panel"; WidgetPanel.widgets = [{ name: "update", text: "Update", type: "button" }]; WidgetPanel.prototype.createGradient = function(ctx) { if ( this.properties["bgcolorTop"] == "" || this.properties["bgcolorBottom"] == "" ) { this.lineargradient = 0; return; } this.lineargradient = ctx.createLinearGradient(0, 0, 0, this.size[1]); this.lineargradient.addColorStop(0, this.properties["bgcolorTop"]); this.lineargradient.addColorStop(1, this.properties["bgcolorBottom"]); }; WidgetPanel.prototype.onDrawForeground = function(ctx) { if (this.flags.collapsed) { return; } if (this.lineargradient == null) { this.createGradient(ctx); } if (!this.lineargradient) { return; } ctx.lineWidth = 1; ctx.strokeStyle = this.properties["borderColor"]; //ctx.fillStyle = "#ebebeb"; ctx.fillStyle = this.lineargradient; if (this.properties["shadowSize"]) { ctx.shadowColor = "#000"; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowBlur = this.properties["shadowSize"]; } else { ctx.shadowColor = "transparent"; } ctx.roundRect( 0, 0, this.size[0] - 1, this.size[1] - 1, this.properties["shadowSize"] ); ctx.fill(); ctx.shadowColor = "transparent"; ctx.stroke(); }; LiteGraph.registerNodeType("widget/panel", WidgetPanel); })(this);