Skip to content

Commit 7f0ec0e

Browse files
committed
feat: add node tooltips and fix canvas layout in ResolutionMaster
- aztoolkit.py: add tooltip annotations to every input field (width, height, auto_detect, rescale_mode, rescale_value, input_image, latent_type); add OUTPUT_TOOLTIPS tuple and DESCRIPTION constant for builder metadata. - js/ResolutionMaster.js: correct collapsed-extra-controls padding (16→4) and compute bottom-content height separately when extra controls are active so the canvas no longer collapses when toggled; track lastCanvasBounds and draw info text below the canvas bounds rather than the default position; simplify input_image label/name management by assigning displayName directly instead of storing/restoring pre-mutation state; fully override getInputLabel in deactivateNodeExtensions so slot 0 always returns 'input_image' without side-effects.
1 parent 7053b78 commit 7f0ec0e

2 files changed

Lines changed: 35 additions & 38 deletions

File tree

aztoolkit.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,21 @@ def INPUT_TYPES(cls):
2828
"required": {
2929
"mode": (
3030
["Manual", "Manual Sliders", "Common Resolutions", "Aspect Ratios"],
31+
{"tooltip": "Frontend control mode for choosing the output resolution. Resolution Master currently uses Manual mode for the custom 2D canvas interface."}
3132
),
3233
"latent_type": (
3334
["latent_4x8", "latent_128x16"],
34-
{"default": "latent_4x8"}
35+
{"default": "latent_4x8", "tooltip": "Latent tensor format to create: latent_4x8 for SD/SDXL/Flux-style latents, or latent_128x16 for Flux.2-style latents."}
3536
),
36-
"width": ("INT", {"default": 512, "min": 0, "max": 32768, "step": 64}),
37-
"height": ("INT", {"default": 512, "min": 0, "max": 32768, "step": 64}),
38-
"auto_detect": ("BOOLEAN", {"default": False, "label_on": "Auto-detect from input", "label_off": "Manual"}),
39-
"rescale_mode": ("STRING", {"default": "resolution"}),
40-
"rescale_value": ("FLOAT", {"default": 1.0, "step": 0.001, "min": 0.0, "max": 100.0}),
37+
"width": ("INT", {"default": 512, "min": 0, "max": 32768, "step": 64, "tooltip": "Output width in pixels. This value is controlled by the Resolution Master canvas and preset tools."}),
38+
"height": ("INT", {"default": 512, "min": 0, "max": 32768, "step": 64, "tooltip": "Output height in pixels. This value is controlled by the Resolution Master canvas and preset tools."}),
39+
"auto_detect": ("BOOLEAN", {"default": False, "label_on": "Auto-detect from input", "label_off": "Manual", "tooltip": "When enabled, reads the connected input image dimensions for auto-detect and auto-fit workflows."}),
40+
"rescale_mode": ("STRING", {"default": "resolution", "tooltip": "Frontend-selected scaling intent used for the rescale_factor output: manual, resolution, or megapixels."}),
41+
"rescale_value": ("FLOAT", {"default": 1.0, "step": 0.001, "min": 0.0, "max": 100.0, "tooltip": "Calculated scale factor passed from the frontend. This becomes the rescale_factor output."}),
4142
"batch_size": ("INT", {"default": 1, "min": 1, "max": 4096, "tooltip": "The number of latent images in the batch."}),
4243
},
4344
"optional": {
44-
"input_image": ("IMAGE",),
45+
"input_image": ("IMAGE", {"tooltip": "Optional image used for auto-detecting source width and height when auto_detect is enabled."}),
4546
},
4647
"hidden": {
4748
"unique_id": "UNIQUE_ID",
@@ -50,6 +51,14 @@ def INPUT_TYPES(cls):
5051

5152
RETURN_TYPES = ("INT", "INT", "FLOAT", "INT", "LATENT")
5253
RETURN_NAMES = ("width", "height", "rescale_factor", "batch_size", "latent")
54+
OUTPUT_TOOLTIPS = (
55+
"Final output width in pixels.",
56+
"Final output height in pixels.",
57+
"Scale factor needed to reach the selected scaling target.",
58+
"Batch size forwarded from the node input.",
59+
"Empty latent tensor created at the selected resolution, batch size, and latent type.",
60+
)
61+
DESCRIPTION = "Interactive resolution, scaling, preset, and latent-size helper with optional input-image auto-detection."
5362
FUNCTION = "main"
5463
CATEGORY = "utils/azToolkit"
5564

js/ResolutionMaster.js

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ class ResolutionMasterCanvas {
210210
}
211211

212212
getCanvasInfoGap() {
213-
return this.collapsedSections?.extraControls ? 16 : this.getManualSpacing();
213+
return this.collapsedSections?.extraControls ? 4 : this.getManualSpacing();
214214
}
215215

216216
getManualBottomPadding() {
@@ -227,7 +227,9 @@ class ResolutionMasterCanvas {
227227
}
228228

229229
const spacing = this.getManualSpacing();
230-
const bottomContentHeight = this.getCanvasInfoGap() + 15 + spacing + this.getManualBottomPadding();
230+
const bottomContentHeight = this.collapsedSections?.extraControls
231+
? 15 + this.getManualBottomPadding()
232+
: this.getCanvasInfoGap() + 15 + spacing + this.getManualBottomPadding();
231233
const availableHeight = this.node.size[1] - currentY - bottomContentHeight;
232234
return Math.max(200, availableHeight);
233235
}
@@ -249,16 +251,6 @@ class ResolutionMasterCanvas {
249251
const isCompact = this.collapsedSections?.extraControls || false;
250252

251253
this.node.inputs?.forEach(input => {
252-
if (!input._resolutionMasterStoredVisualNames) {
253-
input._resolutionMasterStoredVisualNames = {
254-
labelExists: Object.prototype.hasOwnProperty.call(input, "label"),
255-
label: input.label,
256-
localizedName: input.localized_name,
257-
displayName: input.displayName,
258-
displayNameExists: Object.prototype.hasOwnProperty.call(input, "displayName")
259-
};
260-
}
261-
262254
input.name = "input_image";
263255
input.hidden = false;
264256

@@ -267,18 +259,9 @@ class ResolutionMasterCanvas {
267259
input.localized_name = " ";
268260
input.displayName = " ";
269261
} else {
270-
const stored = input._resolutionMasterStoredVisualNames;
271-
input.localized_name = stored.localizedName ?? input.name;
272-
if (stored.labelExists) {
273-
input.label = stored.label;
274-
} else {
275-
delete input.label;
276-
}
277-
if (stored.displayNameExists) {
278-
input.displayName = stored.displayName;
279-
} else {
280-
delete input.displayName;
281-
}
262+
input.label = "input_image";
263+
input.localized_name = "input_image";
264+
input.displayName = "input_image";
282265
}
283266
});
284267

@@ -294,11 +277,12 @@ class ResolutionMasterCanvas {
294277
: this.inputs?.[slot]?.localized_name || this.inputs?.[slot]?.name || " ";
295278
};
296279
} else if (this.node._resolutionMasterHasStoredGetInputLabel) {
297-
if (this.node._resolutionMasterOriginalGetInputLabel) {
298-
this.node.getInputLabel = this.node._resolutionMasterOriginalGetInputLabel;
299-
} else {
300-
delete this.node.getInputLabel;
301-
}
280+
this.node.getInputLabel = function(slot) {
281+
if (slot === 0) return "input_image";
282+
return this._resolutionMasterOriginalGetInputLabel
283+
? this._resolutionMasterOriginalGetInputLabel.call(this, slot)
284+
: this.inputs?.[slot]?.localized_name || this.inputs?.[slot]?.name || "";
285+
};
302286
}
303287

304288
this.node.outputs?.forEach(output => {
@@ -469,8 +453,11 @@ class ResolutionMasterCanvas {
469453
const canvasPadding = this.collapsedSections.extraControls ? 8 : 20;
470454
this.draw2DCanvas(ctx, margin, currentY, node.size[0] - margin * 2, canvasHeight, canvasPadding);
471455
currentY += canvasHeight + this.getCanvasInfoGap();
472-
473-
this.drawInfoText(ctx, currentY);
456+
457+
const infoY = this.collapsedSections.extraControls && this.lastCanvasBounds
458+
? this.lastCanvasBounds.y + this.lastCanvasBounds.h + 18
459+
: currentY;
460+
this.drawInfoText(ctx, infoY);
474461
currentY += 15 + spacing;
475462

476463
if (this.collapsedSections.extraControls) {
@@ -733,6 +720,7 @@ class ResolutionMasterCanvas {
733720
const offsetY = y + (h - canvasH) / 2;
734721

735722
this.controls.canvas2d = { x: offsetX, y: offsetY, w: canvasW, h: canvasH };
723+
this.lastCanvasBounds = this.controls.canvas2d;
736724

737725
ctx.fillStyle = "rgba(20,20,20,0.8)";
738726
ctx.strokeStyle = "rgba(0,0,0,0.5)";

0 commit comments

Comments
 (0)