Add support for sending folder layer
Photoshop plugin will first clone and merge the selected folder layer, send, then delete the cloned and merged layer, all in one modal execution.
This commit is contained in:
+14
-13
@@ -127,19 +127,20 @@ class PhotoshopInstance:
|
||||
def update_comfyui_last_value(self, layer, use_layer_bounds, value):
|
||||
layer_bounds_combo = f"{layer}{use_layer_bounds}"
|
||||
self.comfyui_last_value_tracker[layer_bounds_combo] = value
|
||||
|
||||
|
||||
# need to update history id after internal operation otherwise it might cause infinite change loop
|
||||
async def update_history_state_id_after_internal_change(self, history_state_id=None):
|
||||
if history_state_id is None: # need to get new id after operation, it causes history change
|
||||
history_state_id = await self.get_active_history_state_id()
|
||||
if self.get_img_state_id is not None: # udpate all the change trackers with the new history state id
|
||||
self.change_tracker = {k: history_state_id for k, v in self.change_tracker.items() if v == self.get_img_state_id}
|
||||
self.get_img_state_id = history_state_id # it gets into a loop if get img state is not updated
|
||||
|
||||
async def update_layer_bounds_history_state_id(self, layer, use_layer_bounds):
|
||||
layer_bounds_combo = f"{layer}{use_layer_bounds}"
|
||||
latest_state_id = self.get_push_history_state_id() or await self.get_active_history_state_id()
|
||||
latest_state_id = await self.get_active_history_state_id()
|
||||
self.change_tracker[layer_bounds_combo] = latest_state_id
|
||||
return latest_state_id
|
||||
|
||||
async def update_history_state_id_after_send(self):
|
||||
old_history_state_id = self.get_img_state_id
|
||||
history_state_id = await self.get_active_history_state_id() # need to get new id after operation, it causes history change
|
||||
self.get_img_state_id = history_state_id # it gets into a loop if get img state is not updated
|
||||
if old_history_state_id is not None: # udpate all the change trackers with the new history state id
|
||||
self.change_tracker = {k: history_state_id for k, v in self.change_tracker.items() if v == old_history_state_id}
|
||||
|
||||
async def get_layers(self):
|
||||
result = await self.wsCallsManager.call('get_layers', {})
|
||||
@@ -151,10 +152,10 @@ class PhotoshopInstance:
|
||||
if not is_changed and self.last_get_img_id is not None:
|
||||
return self.last_get_img_id
|
||||
result = await self.wsCallsManager.call('get_image', {'layer_id': layer_id, 'use_layer_bounds': bounds_id}, timeout=60)
|
||||
id = result['upload_name']
|
||||
layer_opacity = result['layer_opacity']
|
||||
history_state_id = await self.update_layer_bounds_history_state_id(layer_id, bounds_id)
|
||||
self.get_img_state_id = history_state_id
|
||||
await self.update_history_state_id_after_internal_change(history_state_id)
|
||||
layer_opacity = result['layer_opacity']
|
||||
id = result['upload_name']
|
||||
self.last_get_img_id = id
|
||||
return id, layer_opacity
|
||||
|
||||
@@ -167,7 +168,7 @@ class PhotoshopInstance:
|
||||
|
||||
async def send_images(self, image_ids, layer_name=""):
|
||||
result = await self.wsCallsManager.call('send_images', {'image_ids': image_ids, 'layer_name': layer_name})
|
||||
await self.update_history_state_id_after_send()
|
||||
await self.update_history_state_id_after_internal_change()
|
||||
return result
|
||||
|
||||
def get_push_history_state_id(self):
|
||||
|
||||
Vendored
+41
-8
@@ -267,7 +267,7 @@ async function getPixelsData(layer, desireBounds) {
|
||||
return await getPixelsDataHelper(null, desireBounds);
|
||||
}
|
||||
// normal layer
|
||||
return getPixelsDataHelper(layer, desireBounds);
|
||||
return await getPixelsDataHelper(layer, desireBounds);
|
||||
}
|
||||
|
||||
// ps returns trimmed data so need padding
|
||||
@@ -286,6 +286,22 @@ function padAndTrimLayerDataToDesireBounds(layer, pixelDataFromAPI, desireBounds
|
||||
(0,_util__WEBPACK_IMPORTED_MODULE_2__.unTrimImageData)(pixelDataFromAPI, pixelDataForReturn, bounds, desireBounds);
|
||||
return pixelDataForReturn;
|
||||
}
|
||||
function isLayerFolder(layer) {
|
||||
return layer.layers && layer.layers.length > 0;
|
||||
}
|
||||
async function findLayer(layerID) {
|
||||
let layer;
|
||||
let isFolder = false;
|
||||
if (layerID <= 0) return [layer, isFolder];
|
||||
layer = (0,_util__WEBPACK_IMPORTED_MODULE_2__.findInAllSubLayer)(photoshop__WEBPACK_IMPORTED_MODULE_0__.app.activeDocument, layerID);
|
||||
if (!layer) throw new Error(`Layer(id: ${layerID}) not found`);
|
||||
if (!isLayerFolder(layer)) return [layer, isFolder];
|
||||
// layer is folder
|
||||
const dupLayer = await layer.duplicate();
|
||||
const mergedLayer = await dupLayer.merge();
|
||||
isFolder = true;
|
||||
return [mergedLayer, isFolder];
|
||||
}
|
||||
class ComfyConnection {
|
||||
static instance = null;
|
||||
static _connectStateCallbacks = [];
|
||||
@@ -423,15 +439,23 @@ class ComfyConnection {
|
||||
} else if (payload.action == 'get_image') {
|
||||
const layerID = payload.params.layer_id;
|
||||
const boundsLayerID = payload.params.use_layer_bounds;
|
||||
await executeAsModalUntilSuccess(async () => {
|
||||
await executeAsModalUntilSuccess(async executionContext => {
|
||||
let hostControl;
|
||||
let suspensionID;
|
||||
const startTime = Date.now();
|
||||
let uploadName = 0;
|
||||
let layer;
|
||||
let layerOpacity = 100;
|
||||
let isFolder = false;
|
||||
const activeLayers = photoshop__WEBPACK_IMPORTED_MODULE_0__.app.activeDocument.activeLayers;
|
||||
try {
|
||||
let layer;
|
||||
if (layerID > 0) {
|
||||
layer = (0,_util__WEBPACK_IMPORTED_MODULE_2__.findInAllSubLayer)(photoshop__WEBPACK_IMPORTED_MODULE_0__.app.activeDocument, layerID);
|
||||
if (!layer) throw new Error(`Layer(id: ${layerID}) not found`);
|
||||
}
|
||||
hostControl = executionContext.hostControl;
|
||||
suspensionID = await hostControl.suspendHistory({
|
||||
"documentID": photoshop__WEBPACK_IMPORTED_MODULE_0__.app.activeDocument.id,
|
||||
"name": "Image To ComfyUI"
|
||||
});
|
||||
[layer, isFolder] = await findLayer(layerID);
|
||||
layerOpacity = layer?.opacity ?? 100;
|
||||
const desireBounds = getDesiredBounds(boundsLayerID);
|
||||
const pixelDataFromAPI = await getPixelsData(layer, desireBounds);
|
||||
const pixelDataForReturn = padAndTrimLayerDataToDesireBounds(layer, pixelDataFromAPI, desireBounds);
|
||||
@@ -476,11 +500,20 @@ class ComfyConnection {
|
||||
error: e.message
|
||||
}));
|
||||
throw e;
|
||||
} finally {
|
||||
if (layer && isFolder) layer.delete();
|
||||
if (activeLayers && activeLayers.length > 0) {
|
||||
for (let i = 0; i < activeLayers.length; i++) {
|
||||
activeLayers[i].selected = true;
|
||||
}
|
||||
}
|
||||
if (hostControl && suspensionID) await hostControl.resumeHistory(suspensionID);
|
||||
}
|
||||
this.socket.send(JSON.stringify({
|
||||
call_id: payload.call_id,
|
||||
result: {
|
||||
upload_name: uploadName
|
||||
upload_name: uploadName,
|
||||
layer_opacity: layerOpacity
|
||||
}
|
||||
}));
|
||||
}, {
|
||||
|
||||
@@ -93,7 +93,7 @@ async function getPixelsData(layer, desireBounds) {
|
||||
return await getPixelsDataHelper(null, desireBounds);
|
||||
}
|
||||
// normal layer
|
||||
return getPixelsDataHelper(layer, desireBounds);
|
||||
return await getPixelsDataHelper(layer, desireBounds);
|
||||
}
|
||||
|
||||
// ps returns trimmed data so need padding
|
||||
@@ -118,6 +118,24 @@ function padAndTrimLayerDataToDesireBounds(layer, pixelDataFromAPI, desireBounds
|
||||
return pixelDataForReturn;
|
||||
}
|
||||
|
||||
function isLayerFolder(layer){
|
||||
return layer.layers && layer.layers.length > 0;
|
||||
}
|
||||
|
||||
async function findLayer(layerID) {
|
||||
let layer;
|
||||
let isFolder = false;
|
||||
if (layerID <= 0) return [layer, isFolder];
|
||||
layer = findInAllSubLayer(app.activeDocument, layerID)
|
||||
if (!layer) throw new Error(`Layer(id: ${layerID}) not found`);
|
||||
if (!isLayerFolder(layer)) return [layer, isFolder];
|
||||
// layer is folder
|
||||
const dupLayer = await layer.duplicate();
|
||||
const mergedLayer = await dupLayer.merge()
|
||||
isFolder = true;
|
||||
return [mergedLayer, isFolder];
|
||||
}
|
||||
|
||||
class ComfyConnection {
|
||||
static instance = null;
|
||||
|
||||
@@ -272,15 +290,23 @@ class ComfyConnection {
|
||||
const layerID = payload.params.layer_id
|
||||
const boundsLayerID = payload.params.use_layer_bounds
|
||||
|
||||
await executeAsModalUntilSuccess(async () => {
|
||||
await executeAsModalUntilSuccess(async (executionContext) => {
|
||||
let hostControl;
|
||||
let suspensionID;
|
||||
const startTime = Date.now();
|
||||
let uploadName = 0;
|
||||
let layer;
|
||||
let layerOpacity = 100;
|
||||
let isFolder = false;
|
||||
const activeLayers = app.activeDocument.activeLayers;
|
||||
try {
|
||||
if (layerID > 0) {
|
||||
layer = findInAllSubLayer(app.activeDocument, layerID)
|
||||
if (!layer) throw new Error(`Layer(id: ${layerID}) not found`);
|
||||
}
|
||||
hostControl = executionContext.hostControl;
|
||||
suspensionID = await hostControl.suspendHistory({
|
||||
"documentID": app.activeDocument.id,
|
||||
"name": "Image To ComfyUI"
|
||||
});
|
||||
[layer, isFolder] = await findLayer(layerID);
|
||||
layerOpacity = layer?.opacity ?? 100;
|
||||
const desireBounds = getDesiredBounds(boundsLayerID);
|
||||
const pixelDataFromAPI = await getPixelsData(layer, desireBounds)
|
||||
const pixelDataForReturn = padAndTrimLayerDataToDesireBounds(layer, pixelDataFromAPI, desireBounds)
|
||||
@@ -329,6 +355,14 @@ class ComfyConnection {
|
||||
})
|
||||
)
|
||||
throw e
|
||||
} finally {
|
||||
if (layer && isFolder) layer.delete();
|
||||
if (activeLayers && activeLayers.length > 0) {
|
||||
for (let i = 0; i < activeLayers.length; i++) {
|
||||
activeLayers[i].selected = true;
|
||||
}
|
||||
}
|
||||
if (hostControl && suspensionID) await hostControl.resumeHistory(suspensionID);
|
||||
}
|
||||
|
||||
this.socket.send(
|
||||
@@ -336,7 +370,7 @@ class ComfyConnection {
|
||||
call_id: payload.call_id,
|
||||
result: {
|
||||
upload_name: uploadName,
|
||||
layer_opacity: layer?.opacity ?? 100
|
||||
layer_opacity: layerOpacity,
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user