Henkey9

improved power lora loader

Aug 15th, 2025
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 30.25 KB | Source Code | 0 0
  1. var _a;
  2. import { app } from "../../scripts/app.js";
  3. import { RgthreeBaseServerNode } from "./base_node.js";
  4. import { rgthree } from "./rgthree.js";
  5. import { addConnectionLayoutSupport } from "./utils.js";
  6. import { NodeTypesString } from "./constants.js";
  7. import { drawInfoIcon, drawNumberWidgetPart, drawRoundedRectangle, drawTogglePart, fitString, isLowQuality, } from "./utils_canvas.js";
  8. import { RgthreeBaseWidget, RgthreeBetterButtonWidget, RgthreeDividerWidget, } from "./utils_widgets.js";
  9. import { rgthreeApi } from "../../rgthree/common/rgthree_api.js";
  10. import { showLoraChooser } from "./utils_menu.js";
  11. import { moveArrayItem, removeArrayItem } from "../../rgthree/common/shared_utils.js";
  12. import { RgthreeLoraInfoDialog } from "./dialog_info.js";
  13. import { LORA_INFO_SERVICE } from "../../rgthree/common/model_info_service.js";
  14. const PROP_LABEL_SHOW_STRENGTHS = "Show Strengths";
  15. const PROP_LABEL_SHOW_STRENGTHS_STATIC = `@${PROP_LABEL_SHOW_STRENGTHS}`;
  16. const PROP_VALUE_SHOW_STRENGTHS_SINGLE = "Single Strength";
  17. const PROP_VALUE_SHOW_STRENGTHS_SEPARATE = "Separate Model & Clip";
  18. class RgthreePowerLoraLoader extends RgthreeBaseServerNode {
  19.     constructor(title = NODE_CLASS.title) {
  20.         super(title);
  21.         this.serialize_widgets = true;
  22.         this.logger = rgthree.newLogSession(`[Power Lora Stack]`);
  23.         this.loraWidgetsCounter = 0;
  24.         this.widgetButtonSpacer = null;
  25.         this.properties[PROP_LABEL_SHOW_STRENGTHS] = PROP_VALUE_SHOW_STRENGTHS_SINGLE;
  26.         rgthreeApi.getLoras();
  27.     }
  28.     configure(info) {
  29.         var _b;
  30.         while ((_b = this.widgets) === null || _b === void 0 ? void 0 : _b.length)
  31.             this.removeWidget(0);
  32.         this.widgetButtonSpacer = null;
  33.         super.configure(info);
  34.         this._tempWidth = this.size[0];
  35.         this._tempHeight = this.size[1];
  36.         for (const widgetValue of info.widgets_values || []) {
  37.             if ((widgetValue === null || widgetValue === void 0 ? void 0 : widgetValue.lora) !== undefined) {
  38.                 const widget = this.addNewLoraWidget();
  39.                 widget.value = { ...widgetValue };
  40.             }
  41.         }
  42.         this.addNonLoraWidgets();
  43.         this.size[0] = this._tempWidth;
  44.         this.size[1] = Math.max(this._tempHeight, this.computeSize()[1]);
  45.     }
  46.     onNodeCreated() {
  47.         var _b;
  48.         (_b = super.onNodeCreated) === null || _b === void 0 ? void 0 : _b.call(this);
  49.         this.addNonLoraWidgets();
  50.         const computed = this.computeSize();
  51.         this.size = this.size || [0, 0];
  52.         this.size[0] = Math.max(this.size[0], computed[0]);
  53.         this.size[1] = Math.max(this.size[1], computed[1]);
  54.         this.setDirtyCanvas(true, true);
  55.     }
  56.     addNewLoraWidget(lora) {
  57.         this.loraWidgetsCounter++;
  58.         const widget = this.addCustomWidget(new PowerLoraLoaderWidget("lora_" + this.loraWidgetsCounter));
  59.         if (lora)
  60.             widget.setLora(lora);
  61.         if (this.widgetButtonSpacer) {
  62.             moveArrayItem(this.widgets, widget, this.widgets.indexOf(this.widgetButtonSpacer));
  63.         }
  64.         return widget;
  65.     }
  66.     addNonLoraWidgets() {
  67.         moveArrayItem(this.widgets, this.addCustomWidget(new RgthreeDividerWidget({ marginTop: 4, marginBottom: 0, thickness: 0 })), 0);
  68.         moveArrayItem(this.widgets, this.addCustomWidget(new PowerLoraLoaderHeaderWidget()), 1);
  69.         this.widgetButtonSpacer = this.addCustomWidget(new RgthreeDividerWidget({ marginTop: 4, marginBottom: 0, thickness: 0 }));
  70.         this.addCustomWidget(new RgthreeBetterButtonWidget("➕ Add Lora", (event, pos, node) => {
  71.             rgthreeApi.getLoras().then((lorasDetails) => {
  72.                 const loras = lorasDetails.map((l) => l.file);
  73.                 showLoraChooser(event, (value) => {
  74.                     var _b;
  75.                     if (typeof value === "string") {
  76.                         if (value.includes("Power Lora Chooser")) {
  77.                         }
  78.                         else if (value !== "NONE") {
  79.                             this.addNewLoraWidget(value);
  80.                             const computed = this.computeSize();
  81.                             const tempHeight = (_b = this._tempHeight) !== null && _b !== void 0 ? _b : 15;
  82.                             this.size[1] = Math.max(tempHeight, computed[1]);
  83.                             this.setDirtyCanvas(true, true);
  84.                         }
  85.                     }
  86.                 }, null, [...loras]);
  87.             });
  88.             return true;
  89.         }));
  90.         this.addCustomWidget(new RgthreeBetterButtonWidget("💾 Save Template", (_event, _pos, node) => {
  91.             // The ComfyUI prompt is asynchronous and returns the value via the callback (3rd arg).
  92.             // We therefore need to do the work that depends on the name inside that callback.
  93.             app.canvas.prompt(
  94.                 "Template name",
  95.                 "My Lora Set",
  96.                 (name) => {
  97.                     if (!name)
  98.                         return;
  99.                     const items = this.widgets
  100.                         .filter((w) => { var _b; return (_b = w.name) === null || _b === void 0 ? void 0 : _b.startsWith("lora_"); })
  101.                         .map((w) => ({ ...w.value }))
  102.                         .filter((v) => v && v.lora && v.lora !== "None");
  103.                     rgthreeApi.savePowerLoraTemplate(name, items);
  104.                 }
  105.             );
  106.             return true;
  107.         }));
  108.         this.addCustomWidget(new RgthreeBetterButtonWidget("📂 Load Template", (event, _pos, node) => {
  109.             rgthreeApi.getPowerLoraTemplates().then((templates) => {
  110.                 const names = (templates || []).map((t) => t.name);
  111.                 showLoraChooser(event, (value) => {
  112.                     if (typeof value === "string" && value !== "NONE") {
  113.                         rgthreeApi.getPowerLoraTemplates(value).then((resp) => {
  114.                             const tpl = (resp === null || resp === void 0 ? void 0 : resp.items) ? resp : null;
  115.                             if (!tpl)
  116.                                 return;
  117.                             const current = [...this.widgets];
  118.                             for (const w of current) {
  119.                                 var _b;
  120.                                 if ((_b = w.name) === null || _b === void 0 ? void 0 : _b.startsWith("lora_")) {
  121.                                     removeArrayItem(this.widgets, w);
  122.                                 }
  123.                             }
  124.                             for (const it of tpl.items) {
  125.                                 const w = this.addNewLoraWidget();
  126.                                 w.value = { ...it };
  127.                             }
  128.                             const computed = this.computeSize();
  129.                             const tempHeight = (_b = this._tempHeight) !== null && _b !== void 0 ? _b : 15;
  130.                             this.size[1] = Math.max(tempHeight, computed[1]);
  131.                             this.setDirtyCanvas(true, true);
  132.                         });
  133.                     }
  134.                 }, null, names.length ? names : ["NONE"]);
  135.             });
  136.             return true;
  137.         }));
  138.     }
  139.     getSlotInPosition(canvasX, canvasY) {
  140.         var _b;
  141.         const slot = super.getSlotInPosition(canvasX, canvasY);
  142.         if (!slot) {
  143.             let lastWidget = null;
  144.             for (const widget of this.widgets) {
  145.                 if (!widget.last_y)
  146.                     return;
  147.                 if (canvasY > this.pos[1] + widget.last_y) {
  148.                     lastWidget = widget;
  149.                     continue;
  150.                 }
  151.                 break;
  152.             }
  153.             if ((_b = lastWidget === null || lastWidget === void 0 ? void 0 : lastWidget.name) === null || _b === void 0 ? void 0 : _b.startsWith("lora_")) {
  154.                 return { widget: lastWidget, output: { type: "LORA WIDGET" } };
  155.             }
  156.         }
  157.         return slot;
  158.     }
  159.     getSlotMenuOptions(slot) {
  160.         var _b, _c, _d, _e, _f, _g;
  161.         if ((_c = (_b = slot === null || slot === void 0 ? void 0 : slot.widget) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.startsWith("lora_")) {
  162.             const widget = slot.widget;
  163.             const index = this.widgets.indexOf(widget);
  164.             const canMoveUp = !!((_e = (_d = this.widgets[index - 1]) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.startsWith("lora_"));
  165.             const canMoveDown = !!((_g = (_f = this.widgets[index + 1]) === null || _f === void 0 ? void 0 : _f.name) === null || _g === void 0 ? void 0 : _g.startsWith("lora_"));
  166.             const menuItems = [
  167.                 {
  168.                     content: `ℹ️ Show Info`,
  169.                     callback: () => {
  170.                         widget.showLoraInfoDialog();
  171.                     },
  172.                 },
  173.                 null,
  174.                 {
  175.                     content: `${widget.value.on ? "⚫" : "🟢"} Toggle ${widget.value.on ? "Off" : "On"}`,
  176.                     callback: () => {
  177.                         widget.value.on = !widget.value.on;
  178.                     },
  179.                 },
  180.                 {
  181.                     content: `⬆️ Move Up`,
  182.                     disabled: !canMoveUp,
  183.                     callback: () => {
  184.                         moveArrayItem(this.widgets, widget, index - 1);
  185.                     },
  186.                 },
  187.                 {
  188.                     content: `⬇️ Move Down`,
  189.                     disabled: !canMoveDown,
  190.                     callback: () => {
  191.                         moveArrayItem(this.widgets, widget, index + 1);
  192.                     },
  193.                 },
  194.                 {
  195.                     content: `🗑️ Remove`,
  196.                     callback: () => {
  197.                         removeArrayItem(this.widgets, widget);
  198.                     },
  199.                 },
  200.             ];
  201.             new LiteGraph.ContextMenu(menuItems, {
  202.                 title: "LORA WIDGET",
  203.                 event: rgthree.lastCanvasMouseEvent,
  204.             });
  205.             return undefined;
  206.         }
  207.         return this.defaultGetSlotMenuOptions(slot);
  208.     }
  209.     refreshComboInNode(defs) {
  210.         rgthreeApi.getLoras(true);
  211.     }
  212.     hasLoraWidgets() {
  213.         var _b;
  214.         return !!((_b = this.widgets) === null || _b === void 0 ? void 0 : _b.find((w) => { var _b; return (_b = w.name) === null || _b === void 0 ? void 0 : _b.startsWith("lora_"); }));
  215.     }
  216.     allLorasState() {
  217.         var _b, _c, _d;
  218.         let allOn = true;
  219.         let allOff = true;
  220.         for (const widget of this.widgets) {
  221.             if ((_b = widget.name) === null || _b === void 0 ? void 0 : _b.startsWith("lora_")) {
  222.                 const on = (_c = widget.value) === null || _c === void 0 ? void 0 : _c.on;
  223.                 allOn = allOn && on === true;
  224.                 allOff = allOff && on === false;
  225.                 if (!allOn && !allOff) {
  226.                     return null;
  227.                 }
  228.             }
  229.         }
  230.         return allOn && ((_d = this.widgets) === null || _d === void 0 ? void 0 : _d.length) ? true : false;
  231.     }
  232.     toggleAllLoras() {
  233.         var _b, _c;
  234.         const allOn = this.allLorasState();
  235.         const toggledTo = !allOn ? true : false;
  236.         for (const widget of this.widgets) {
  237.             if (((_b = widget.name) === null || _b === void 0 ? void 0 : _b.startsWith("lora_")) && ((_c = widget.value) === null || _c === void 0 ? void 0 : _c.on) != null) {
  238.                 widget.value.on = toggledTo;
  239.             }
  240.         }
  241.     }
  242.     static setUp(comfyClass, nodeData) {
  243.         RgthreeBaseServerNode.registerForOverride(comfyClass, nodeData, NODE_CLASS);
  244.     }
  245.     static onRegisteredForOverride(comfyClass, ctxClass) {
  246.         addConnectionLayoutSupport(NODE_CLASS, app, [
  247.             ["Left", "Right"],
  248.             ["Right", "Left"],
  249.         ]);
  250.         setTimeout(() => {
  251.             NODE_CLASS.category = comfyClass.category;
  252.         });
  253.     }
  254.     getHelp() {
  255.         return `
  256.       <p>
  257.         The ${this.type.replace("(rgthree)", "")} is a powerful node that condenses 100s of pixels
  258.         of functionality in a single, dynamic node that allows you to add loras, change strengths,
  259.         and quickly toggle on/off all without taking up half your screen.
  260.       </p>
  261.       <ul>
  262.         <li><p>
  263.           Add as many Lora's as you would like by clicking the "+ Add Lora" button.
  264.          There's no real limit!
  265.         </p></li>
  266.         <li><p>
  267.           Right-click on a Lora widget for special options to move the lora up or down
  268.           (no image affect, only presentational), toggle it on/off, or delete the row all together.
  269.         </p></li>
  270.         <li>
  271.           <p>
  272.             <strong>Properties.</strong> You can change the following properties (by right-clicking
  273.             on the node, and select "Properties" or "Properties Panel" from the menu):
  274.           </p>
  275.           <ul>
  276.             <li><p>
  277.               <code>${PROP_LABEL_SHOW_STRENGTHS}</code> - Change between showing a single, simple
  278.               strength (which will be used for both model and clip), or a more advanced view with
  279.               both model and clip strengths being modifiable.
  280.             </p></li>
  281.           </ul>
  282.         </li>
  283.       </ul>`;
  284.     }
  285. }
  286. _a = PROP_LABEL_SHOW_STRENGTHS_STATIC;
  287. RgthreePowerLoraLoader.title = NodeTypesString.POWER_LORA_LOADER;
  288. RgthreePowerLoraLoader.type = NodeTypesString.POWER_LORA_LOADER;
  289. RgthreePowerLoraLoader.comfyClass = NodeTypesString.POWER_LORA_LOADER;
  290. RgthreePowerLoraLoader[_a] = {
  291.     type: "combo",
  292.     values: [PROP_VALUE_SHOW_STRENGTHS_SINGLE, PROP_VALUE_SHOW_STRENGTHS_SEPARATE],
  293. };
  294. class PowerLoraLoaderHeaderWidget extends RgthreeBaseWidget {
  295.     constructor(name = "PowerLoraLoaderHeaderWidget") {
  296.         super(name);
  297.         this.value = { type: "PowerLoraLoaderHeaderWidget" };
  298.         this.type = "custom";
  299.         this.hitAreas = {
  300.             toggle: { bounds: [0, 0], onDown: this.onToggleDown },
  301.         };
  302.         this.showModelAndClip = null;
  303.     }
  304.     draw(ctx, node, w, posY, height) {
  305.         if (!node.hasLoraWidgets()) {
  306.             return;
  307.         }
  308.         this.showModelAndClip =
  309.             node.properties[PROP_LABEL_SHOW_STRENGTHS] === PROP_VALUE_SHOW_STRENGTHS_SEPARATE;
  310.         const margin = 10;
  311.         const innerMargin = margin * 0.33;
  312.         const lowQuality = isLowQuality();
  313.         const allLoraState = node.allLorasState();
  314.         posY += 2;
  315.         const midY = posY + height * 0.5;
  316.         let posX = 10;
  317.         ctx.save();
  318.         this.hitAreas.toggle.bounds = drawTogglePart(ctx, { posX, posY, height, value: allLoraState });
  319.         if (!lowQuality) {
  320.             posX += this.hitAreas.toggle.bounds[1] + innerMargin;
  321.             ctx.globalAlpha = app.canvas.editor_alpha * 0.55;
  322.             ctx.fillStyle = LiteGraph.WIDGET_TEXT_COLOR;
  323.             ctx.textAlign = "left";
  324.             ctx.textBaseline = "middle";
  325.             ctx.fillText("Toggle All", posX, midY);
  326.             let rposX = node.size[0] - margin - innerMargin - innerMargin;
  327.             ctx.textAlign = "center";
  328.             ctx.fillText(this.showModelAndClip ? "Clip" : "Strength", rposX - drawNumberWidgetPart.WIDTH_TOTAL / 2, midY);
  329.             if (this.showModelAndClip) {
  330.                 rposX = rposX - drawNumberWidgetPart.WIDTH_TOTAL - innerMargin * 2;
  331.                 ctx.fillText("Model", rposX - drawNumberWidgetPart.WIDTH_TOTAL / 2, midY);
  332.             }
  333.         }
  334.         ctx.restore();
  335.     }
  336.     onToggleDown(event, pos, node) {
  337.         node.toggleAllLoras();
  338.         this.cancelMouseDown();
  339.         return true;
  340.     }
  341. }
  342. const DEFAULT_LORA_WIDGET_DATA = {
  343.     on: true,
  344.     lora: null,
  345.     strength: 1,
  346.     strengthTwo: null,
  347. };
  348. class PowerLoraLoaderWidget extends RgthreeBaseWidget {
  349.     constructor(name) {
  350.         super(name);
  351.         this.type = "custom";
  352.         this.haveMouseMovedStrength = false;
  353.         this.loraInfoPromise = null;
  354.         this.loraInfo = null;
  355.         this.showModelAndClip = null;
  356.         this.hitAreas = {
  357.             toggle: { bounds: [0, 0], onDown: this.onToggleDown },
  358.             lora: { bounds: [0, 0], onClick: this.onLoraClick },
  359.             remove: { bounds: [0, 0], onClick: this.onRemoveClick },
  360.             moveUp: { bounds: [0, 0], onClick: this.onMoveUpClick },
  361.             moveDown: { bounds: [0, 0], onClick: this.onMoveDownClick },
  362.             strengthDec: { bounds: [0, 0], onClick: this.onStrengthDecDown },
  363.             strengthVal: { bounds: [0, 0], onClick: this.onStrengthValUp },
  364.             strengthInc: { bounds: [0, 0], onClick: this.onStrengthIncDown },
  365.             strengthAny: { bounds: [0, 0], onMove: this.onStrengthAnyMove },
  366.             strengthTwoDec: { bounds: [0, 0], onClick: this.onStrengthTwoDecDown },
  367.             strengthTwoVal: { bounds: [0, 0], onClick: this.onStrengthTwoValUp },
  368.             strengthTwoInc: { bounds: [0, 0], onClick: this.onStrengthTwoIncDown },
  369.             strengthTwoAny: { bounds: [0, 0], onMove: this.onStrengthTwoAnyMove },
  370.         };
  371.         this._value = {
  372.             on: true,
  373.             lora: null,
  374.             strength: 1,
  375.             strengthTwo: null,
  376.         };
  377.     }
  378.     set value(v) {
  379.         this._value = v;
  380.         if (typeof this._value !== "object") {
  381.             this._value = { ...DEFAULT_LORA_WIDGET_DATA };
  382.             if (this.showModelAndClip) {
  383.                 this._value.strengthTwo = this._value.strength;
  384.             }
  385.         }
  386.         this.getLoraInfo();
  387.     }
  388.     get value() {
  389.         return this._value;
  390.     }
  391.     setLora(lora) {
  392.         this._value.lora = lora;
  393.         this.getLoraInfo();
  394.     }
  395.     draw(ctx, node, w, posY, height) {
  396.         var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
  397.         let currentShowModelAndClip = node.properties[PROP_LABEL_SHOW_STRENGTHS] === PROP_VALUE_SHOW_STRENGTHS_SEPARATE;
  398.         if (this.showModelAndClip !== currentShowModelAndClip) {
  399.             let oldShowModelAndClip = this.showModelAndClip;
  400.             this.showModelAndClip = currentShowModelAndClip;
  401.             if (this.showModelAndClip) {
  402.                 if (oldShowModelAndClip != null) {
  403.                     this.value.strengthTwo = (_b = this.value.strength) !== null && _b !== void 0 ? _b : 1;
  404.                 }
  405.             }
  406.             else {
  407.                 this.value.strengthTwo = null;
  408.                 this.hitAreas.strengthTwoDec.bounds = [0, -1];
  409.                 this.hitAreas.strengthTwoVal.bounds = [0, -1];
  410.                 this.hitAreas.strengthTwoInc.bounds = [0, -1];
  411.                 this.hitAreas.strengthTwoAny.bounds = [0, -1];
  412.             }
  413.         }
  414.         ctx.save();
  415.         const margin = 10;
  416.         const innerMargin = margin * 0.33;
  417.         const lowQuality = isLowQuality();
  418.         const midY = posY + height * 0.5;
  419.         let posX = margin;
  420.         drawRoundedRectangle(ctx, { pos: [posX, posY], size: [node.size[0] - margin * 2, height] });
  421.         this.hitAreas.toggle.bounds = drawTogglePart(ctx, { posX, posY, height, value: this.value.on });
  422.         posX += this.hitAreas.toggle.bounds[1] + innerMargin;
  423.         if (lowQuality) {
  424.             ctx.restore();
  425.             return;
  426.         }
  427.         if (!this.value.on) {
  428.             ctx.globalAlpha = app.canvas.editor_alpha * 0.4;
  429.         }
  430.         ctx.fillStyle = LiteGraph.WIDGET_TEXT_COLOR;
  431.         let rposX = node.size[0] - margin - innerMargin - innerMargin;
  432.         const removeIconSize = height * 0.66;
  433.         const removeWidth = removeIconSize + innerMargin;
  434.         ctx.textAlign = "right";
  435.         ctx.textBaseline = "middle";
  436.         ctx.fillStyle = LiteGraph.WIDGET_TEXT_COLOR;
  437.         ctx.fillText("✖", node.size[0] - margin - innerMargin, midY);
  438.         this.hitAreas.remove.bounds = [node.size[0] - margin - innerMargin - removeIconSize, removeWidth];
  439.         // Draw move up/down arrows to reorder
  440.         const moveIconSize = height * 0.66;
  441.         const moveWidth = moveIconSize * 2 + innerMargin;
  442.         const arrowsRightEdge = node.size[0] - margin - innerMargin - removeWidth - innerMargin;
  443.         ctx.textAlign = "center";
  444.         // Compute centers for up and down icons
  445.         const downCenterX = arrowsRightEdge - moveIconSize * 0.5;
  446.         const upCenterX = downCenterX - moveIconSize - innerMargin;
  447.         // Determine if we can move up/down (only within contiguous lora widgets)
  448.         const widgets = node.widgets;
  449.         const index = widgets.indexOf(this);
  450.         const canMoveUp = !!(widgets[index - 1] && widgets[index - 1].name && widgets[index - 1].name.startsWith("lora_"));
  451.         const canMoveDown = !!(widgets[index + 1] && widgets[index + 1].name && widgets[index + 1].name.startsWith("lora_"));
  452.         const previousAlpha = ctx.globalAlpha;
  453.         ctx.globalAlpha = previousAlpha * (canMoveUp ? 1 : 0.35);
  454.         ctx.fillText("▲", upCenterX, midY);
  455.         ctx.globalAlpha = previousAlpha * (canMoveDown ? 1 : 0.35);
  456.         ctx.fillText("▼", downCenterX, midY);
  457.         ctx.globalAlpha = previousAlpha;
  458.         // Set hit areas
  459.         this.hitAreas.moveUp.bounds = [upCenterX - moveIconSize * 0.5, moveIconSize];
  460.         this.hitAreas.moveDown.bounds = [downCenterX - moveIconSize * 0.5, moveIconSize];
  461.         const strengthValue = this.showModelAndClip
  462.             ? ((_c = this.value.strengthTwo) !== null && _c !== void 0 ? _c : 1)
  463.             : ((_d = this.value.strength) !== null && _d !== void 0 ? _d : 1);
  464.         let textColor = undefined;
  465.         if (((_e = this.loraInfo) === null || _e === void 0 ? void 0 : _e.strengthMax) != null && strengthValue > ((_f = this.loraInfo) === null || _f === void 0 ? void 0 : _f.strengthMax)) {
  466.             textColor = "#c66";
  467.         }
  468.         else if (((_g = this.loraInfo) === null || _g === void 0 ? void 0 : _g.strengthMin) != null && strengthValue < ((_h = this.loraInfo) === null || _h === void 0 ? void 0 : _h.strengthMin)) {
  469.             textColor = "#c66";
  470.         }
  471.         const [leftArrow, text, rightArrow] = drawNumberWidgetPart(ctx, {
  472.             posX: node.size[0] - margin - innerMargin - innerMargin - removeWidth - innerMargin - moveWidth - innerMargin,
  473.             posY,
  474.             height,
  475.             value: strengthValue,
  476.             direction: -1,
  477.             textColor,
  478.         });
  479.         this.hitAreas.strengthDec.bounds = leftArrow;
  480.         this.hitAreas.strengthVal.bounds = text;
  481.         this.hitAreas.strengthInc.bounds = rightArrow;
  482.         this.hitAreas.strengthAny.bounds = [leftArrow[0], rightArrow[0] + rightArrow[1] - leftArrow[0]];
  483.         rposX = leftArrow[0] - innerMargin;
  484.         if (this.showModelAndClip) {
  485.             rposX -= innerMargin;
  486.             this.hitAreas.strengthTwoDec.bounds = this.hitAreas.strengthDec.bounds;
  487.             this.hitAreas.strengthTwoVal.bounds = this.hitAreas.strengthVal.bounds;
  488.             this.hitAreas.strengthTwoInc.bounds = this.hitAreas.strengthInc.bounds;
  489.             this.hitAreas.strengthTwoAny.bounds = this.hitAreas.strengthAny.bounds;
  490.             let textColor = undefined;
  491.             if (((_j = this.loraInfo) === null || _j === void 0 ? void 0 : _j.strengthMax) != null && this.value.strength > ((_k = this.loraInfo) === null || _k === void 0 ? void 0 : _k.strengthMax)) {
  492.                 textColor = "#c66";
  493.             }
  494.             else if (((_l = this.loraInfo) === null || _l === void 0 ? void 0 : _l.strengthMin) != null &&
  495.                 this.value.strength < ((_m = this.loraInfo) === null || _m === void 0 ? void 0 : _m.strengthMin)) {
  496.                 textColor = "#c66";
  497.             }
  498.             const [leftArrow, text, rightArrow] = drawNumberWidgetPart(ctx, {
  499.                 posX: rposX,
  500.                 posY,
  501.                 height,
  502.                 value: (_o = this.value.strength) !== null && _o !== void 0 ? _o : 1,
  503.                 direction: -1,
  504.                 textColor,
  505.             });
  506.             this.hitAreas.strengthDec.bounds = leftArrow;
  507.             this.hitAreas.strengthVal.bounds = text;
  508.             this.hitAreas.strengthInc.bounds = rightArrow;
  509.             this.hitAreas.strengthAny.bounds = [
  510.                 leftArrow[0],
  511.                 rightArrow[0] + rightArrow[1] - leftArrow[0],
  512.             ];
  513.             rposX = leftArrow[0] - innerMargin;
  514.         }
  515.         const infoIconSize = height * 0.66;
  516.         const infoWidth = infoIconSize + innerMargin + innerMargin;
  517.         if (this.hitAreas["info"]) {
  518.             rposX -= innerMargin;
  519.             drawInfoIcon(ctx, rposX - infoIconSize, posY + (height - infoIconSize) / 2, infoIconSize);
  520.             this.hitAreas.info.bounds = [rposX - infoIconSize, infoWidth];
  521.             rposX = rposX - infoIconSize - innerMargin;
  522.         }
  523.         const loraWidth = rposX - posX;
  524.         ctx.textAlign = "left";
  525.         ctx.textBaseline = "middle";
  526.         const loraLabel = String(((_p = this.value) === null || _p === void 0 ? void 0 : _p.lora) || "None");
  527.         ctx.fillText(fitString(ctx, loraLabel, loraWidth), posX, midY);
  528.         this.hitAreas.lora.bounds = [posX, loraWidth];
  529.         posX += loraWidth + innerMargin;
  530.         ctx.globalAlpha = app.canvas.editor_alpha;
  531.         ctx.restore();
  532.     }
  533.     serializeValue(node, index) {
  534.         var _b;
  535.         const v = { ...this.value };
  536.         if (!this.showModelAndClip) {
  537.             delete v.strengthTwo;
  538.         }
  539.         else {
  540.             this.value.strengthTwo = (_b = this.value.strengthTwo) !== null && _b !== void 0 ? _b : 1;
  541.             v.strengthTwo = this.value.strengthTwo;
  542.         }
  543.         return v;
  544.     }
  545.     onToggleDown(event, pos, node) {
  546.         this.value.on = !this.value.on;
  547.         this.cancelMouseDown();
  548.         return true;
  549.     }
  550.     onMoveUpClick(event, pos, node) {
  551.         const widgets = node.widgets;
  552.         const index = widgets.indexOf(this);
  553.         const canMoveUp = !!(widgets[index - 1] && widgets[index - 1].name && widgets[index - 1].name.startsWith("lora_"));
  554.         if (canMoveUp) {
  555.             moveArrayItem(widgets, this, index - 1);
  556.             node.setDirtyCanvas(true, true);
  557.         }
  558.         this.cancelMouseDown();
  559.         return true;
  560.     }
  561.     onMoveDownClick(event, pos, node) {
  562.         const widgets = node.widgets;
  563.         const index = widgets.indexOf(this);
  564.         const canMoveDown = !!(widgets[index + 1] && widgets[index + 1].name && widgets[index + 1].name.startsWith("lora_"));
  565.         if (canMoveDown) {
  566.             moveArrayItem(widgets, this, index + 1);
  567.             node.setDirtyCanvas(true, true);
  568.         }
  569.         this.cancelMouseDown();
  570.         return true;
  571.     }
  572.     onRemoveClick(event, pos, node) {
  573.         const widgets = node.widgets;
  574.         removeArrayItem(widgets, this);
  575.         const computed = node.computeSize && node.computeSize();
  576.         if (computed) {
  577.             node.size[1] = Math.max((node._tempHeight !== null && node._tempHeight !== void 0 ? node._tempHeight : 15), computed[1]);
  578.         }
  579.         node.setDirtyCanvas(true, true);
  580.         this.cancelMouseDown();
  581.         return true;
  582.     }
  583.     onInfoDown(event, pos, node) {
  584.         this.showLoraInfoDialog();
  585.     }
  586.     onLoraClick(event, pos, node) {
  587.         showLoraChooser(event, (value) => {
  588.             if (typeof value === "string") {
  589.                 this.value.lora = value;
  590.                 this.loraInfo = null;
  591.                 this.getLoraInfo();
  592.             }
  593.             node.setDirtyCanvas(true, true);
  594.         });
  595.         this.cancelMouseDown();
  596.     }
  597.     onStrengthDecDown(event, pos, node) {
  598.         this.stepStrength(-1, false);
  599.     }
  600.     onStrengthIncDown(event, pos, node) {
  601.         this.stepStrength(1, false);
  602.     }
  603.     onStrengthTwoDecDown(event, pos, node) {
  604.         this.stepStrength(-1, true);
  605.     }
  606.     onStrengthTwoIncDown(event, pos, node) {
  607.         this.stepStrength(1, true);
  608.     }
  609.     onStrengthAnyMove(event, pos, node) {
  610.         this.doOnStrengthAnyMove(event, false);
  611.     }
  612.     onStrengthTwoAnyMove(event, pos, node) {
  613.         this.doOnStrengthAnyMove(event, true);
  614.     }
  615.     doOnStrengthAnyMove(event, isTwo = false) {
  616.         var _b;
  617.         if (event.deltaX) {
  618.             let prop = isTwo ? "strengthTwo" : "strength";
  619.             this.haveMouseMovedStrength = true;
  620.             this.value[prop] = ((_b = this.value[prop]) !== null && _b !== void 0 ? _b : 1) + event.deltaX * 0.05;
  621.         }
  622.     }
  623.     onStrengthValUp(event, pos, node) {
  624.         this.doOnStrengthValUp(event, false);
  625.     }
  626.     onStrengthTwoValUp(event, pos, node) {
  627.         this.doOnStrengthValUp(event, true);
  628.     }
  629.     doOnStrengthValUp(event, isTwo = false) {
  630.         if (this.haveMouseMovedStrength)
  631.             return;
  632.         let prop = isTwo ? "strengthTwo" : "strength";
  633.         const canvas = app.canvas;
  634.         canvas.prompt("Value", this.value[prop], (v) => (this.value[prop] = Number(v)), event);
  635.     }
  636.     onMouseUp(event, pos, node) {
  637.         super.onMouseUp(event, pos, node);
  638.         this.haveMouseMovedStrength = false;
  639.     }
  640.     showLoraInfoDialog() {
  641.         if (!this.value.lora || this.value.lora === "None") {
  642.             return;
  643.         }
  644.         const infoDialog = new RgthreeLoraInfoDialog(this.value.lora).show();
  645.         infoDialog.addEventListener("close", ((e) => {
  646.             if (e.detail.dirty) {
  647.                 this.getLoraInfo(true);
  648.             }
  649.         }));
  650.     }
  651.     stepStrength(direction, isTwo = false) {
  652.         var _b;
  653.         let step = 0.05;
  654.         let prop = isTwo ? "strengthTwo" : "strength";
  655.         let strength = ((_b = this.value[prop]) !== null && _b !== void 0 ? _b : 1) + step * direction;
  656.         this.value[prop] = Math.round(strength * 100) / 100;
  657.     }
  658.     getLoraInfo(force = false) {
  659.         if (!this.loraInfoPromise || force == true) {
  660.             let promise;
  661.             if (this.value.lora && this.value.lora != "None") {
  662.                 promise = LORA_INFO_SERVICE.getInfo(this.value.lora, force, true);
  663.             }
  664.             else {
  665.                 promise = Promise.resolve(null);
  666.             }
  667.             this.loraInfoPromise = promise.then((v) => (this.loraInfo = v));
  668.         }
  669.         return this.loraInfoPromise;
  670.     }
  671. }
  672. const NODE_CLASS = RgthreePowerLoraLoader;
  673. app.registerExtension({
  674.     name: "rgthree.PowerLoraLoader",
  675.     async beforeRegisterNodeDef(nodeType, nodeData) {
  676.         if (nodeData.name === NODE_CLASS.type) {
  677.             NODE_CLASS.setUp(nodeType, nodeData);
  678.         }
  679.     },
  680. });
  681.  
Advertisement
Add Comment
Please, Sign In to add comment