fix(inpaint): editor reset-all resets brush tool; wrap onConnectionsChange; load-race guard
- Reset all to default now returns the tool to Brush (it stayed on Erase). - node.onConnectionsChange is wrapped instead of assigned, so a prototype / other-extension handler is chained, not clobbered (forward-safety). - _loadImageFromURL / _loadImageFromDataURL / _loadMaskFromURL carry a load generation token: a late image/mask onload from a prior open no longer overwrites the current image, and a saved mask won't clobber fresh strokes (bails if painting / has undo history / a painted bbox). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2ef7cd6cde
commit
754e0177d2
@@ -336,6 +336,7 @@ export class InpaintCropEditor {
|
||||
_setTool(v) { this.tool = v; }
|
||||
|
||||
_resetAll() {
|
||||
this._setTool("add"); // back to Brush (was left on Erase after a reset)
|
||||
this.brushSize = DEFAULT_BRUSH_SIZE;
|
||||
this.maskOpacity = 0.5;
|
||||
this.params.blend = 16;
|
||||
@@ -352,6 +353,7 @@ export class InpaintCropEditor {
|
||||
this.el.growSlider?.setValue(4);
|
||||
this.el.ctxSlider?.setValue(24);
|
||||
this.el.targetSlider?.setValue(1024);
|
||||
this._toolGrid?.setActive?.("add");
|
||||
this._blendModeGrid?.setActive?.("mask");
|
||||
this._sizeModeGrid?.setActive?.("keep");
|
||||
this._multipleGrid?.setActive?.(8);
|
||||
|
||||
@@ -325,14 +325,18 @@ app.registerExtension({
|
||||
};
|
||||
api.addEventListener("executed", onExec);
|
||||
|
||||
node.onConnectionsChange = (type, slotIndex, connected) => {
|
||||
if (type !== LiteGraph.INPUT) return;
|
||||
if (node.inputs?.[slotIndex]?.name !== "image") return;
|
||||
if (isGraphLoading()) return;
|
||||
node._pixInpaintSourceURL = null;
|
||||
if (node.properties) delete node.properties.pixInpaintSource;
|
||||
if (connected) refreshSourcePreview();
|
||||
else restoreNodePreview(parts, "{}", node);
|
||||
// wrap (don't clobber) any existing handler from the prototype / another ext;
|
||||
// forward all args, then run our image-input source-preview logic.
|
||||
const origConnChange = node.onConnectionsChange;
|
||||
node.onConnectionsChange = function (type, slotIndex, connected) {
|
||||
const r = origConnChange?.apply(this, arguments);
|
||||
if (type === LiteGraph.INPUT && node.inputs?.[slotIndex]?.name === "image" && !isGraphLoading()) {
|
||||
node._pixInpaintSourceURL = null;
|
||||
if (node.properties) delete node.properties.pixInpaintSource;
|
||||
if (connected) refreshSourcePreview();
|
||||
else restoreNodePreview(parts, "{}", node);
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
const origRemoved = node.onRemoved;
|
||||
|
||||
@@ -205,9 +205,14 @@ proto._invertMask = function () {
|
||||
};
|
||||
|
||||
proto._loadMaskFromURL = function (url) {
|
||||
const token = this._loadToken; // tie to the image-load generation that requested it
|
||||
const img = new Image();
|
||||
img.crossOrigin = "anonymous";
|
||||
img.onload = () => {
|
||||
// bail if a newer open/load superseded this, OR the user already started working
|
||||
// (painting / has undo history / a painted bbox) - don't clobber fresh strokes.
|
||||
if (token !== this._loadToken) return;
|
||||
if (this._painting || this._undo?.length || this._bbox) return;
|
||||
this._ensureMaskCanvas();
|
||||
const tmp = document.createElement("canvas");
|
||||
tmp.width = this.imgW; tmp.height = this.imgH;
|
||||
|
||||
@@ -8,9 +8,11 @@ const proto = InpaintCropEditor.prototype;
|
||||
|
||||
// ── image load ──────────────────────────────────────────────────────────────
|
||||
proto._loadImageFromURL = function (url, onDone) {
|
||||
const token = (this._loadToken = (this._loadToken || 0) + 1); // newest load wins
|
||||
const img = new Image();
|
||||
img.crossOrigin = "anonymous";
|
||||
img.onload = () => {
|
||||
if (token !== this._loadToken) return; // a newer open/load superseded this one
|
||||
this.img = img;
|
||||
this.imgW = img.naturalWidth;
|
||||
this.imgH = img.naturalHeight;
|
||||
@@ -27,8 +29,10 @@ proto._loadImageFromURL = function (url, onDone) {
|
||||
};
|
||||
|
||||
proto._loadImageFromDataURL = function (dataURL) {
|
||||
const token = (this._loadToken = (this._loadToken || 0) + 1); // newest load wins
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
if (token !== this._loadToken) return; // a newer open/load superseded this one
|
||||
this.img = img;
|
||||
this.imgW = img.naturalWidth;
|
||||
this.imgH = img.naturalHeight;
|
||||
|
||||
Reference in New Issue
Block a user