Improve transparency mask handling
- Collapse transparency mask by default - Add transparency mask: option to add or flatten mask - Removed Use selection as mask - Mask adding logic sets top paintlayer as active - Fixes #91 - FIxes #85pull/112/head
parent
c25c8130a8
commit
f35706776a
|
|
@ -1,5 +1,11 @@
|
|||
# UI Changelog
|
||||
|
||||
## 2023-01-20
|
||||
|
||||
- Removed "Use selection as mask" option; Using the selection to mask generated images is now default behaviour.
|
||||
- Added "Add transparency mask" option; Choose to mask generated images by adding transparency mask, or directly flatten/crop image.
|
||||
- Top paintlayer will now be set as active layer when generation is complete.
|
||||
|
||||
## 2022-12-28
|
||||
|
||||
- Added "Alt Dock Behaviour" under "SD Plugin Config".
|
||||
|
|
|
|||
|
|
@ -103,6 +103,12 @@ A: Unfortunately no, all plugins so far have different APIs. The official API is
|
|||
|
||||
See [CHANGELOG.md](./CHANGELOG.md) for the full changelog.
|
||||
|
||||
### 2023-01-20
|
||||
|
||||
- Removed "Use selection as mask" option; Using the selection to mask generated images is now default behaviour.
|
||||
- Added "Add transparency mask" option; Choose to mask generated images by adding transparency mask, or directly flatten/crop image.
|
||||
- Top paintlayer will now be set as active layer when generation is complete.
|
||||
|
||||
### 2022-12-28
|
||||
|
||||
- Added "Alt Dock Behaviour" under "SD Plugin Config".
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ ETA_REFRESH_INTERVAL = 1000 # 1 second between eta refresh
|
|||
CFG_FOLDER = "krita" # which folder in ~/.config to store config
|
||||
CFG_NAME = "krita_diff_plugin" # name of config file
|
||||
EXT_CFG_NAME = "krita_diff_plugin_scripts" # name of config file
|
||||
# selection mask can only be added after image is added, so timeout is needed
|
||||
ADD_MASK_TIMEOUT = 200
|
||||
ADD_MASK_TIMEOUT = 50
|
||||
THREADED = True
|
||||
ROUTE_PREFIX = "/sdapi/interpause/"
|
||||
OFFICIAL_ROUTE_PREFIX = "/sdapi/v1/"
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class ConfigPage(QWidget):
|
|||
script.cfg, "just_use_yaml", "(unrecommended) Ignore settings"
|
||||
)
|
||||
self.create_mask_layer = QCheckBox(
|
||||
script.cfg, "create_mask_layer", "Use selection as mask"
|
||||
script.cfg, "create_mask_layer", "Add transparency mask"
|
||||
)
|
||||
self.save_temp_images = QCheckBox(
|
||||
script.cfg, "save_temp_images", "Save images for debug"
|
||||
|
|
|
|||
|
|
@ -335,22 +335,54 @@ class Script(QObject):
|
|||
def transparency_mask_inserter(self):
|
||||
"""Mask out extra regions due to adjust_selection()."""
|
||||
orig_selection = self.selection.duplicate() if self.selection else None
|
||||
create_mask = self.cfg("create_mask_layer", bool)
|
||||
|
||||
def add_mask(layers):
|
||||
self.doc.waitForDone()
|
||||
cur_selection = self.selection
|
||||
cur_layer = self.doc.activeNode()
|
||||
for layer in layers:
|
||||
self.doc.setActiveNode(layer)
|
||||
self.doc.setSelection(orig_selection)
|
||||
self.app.action("add_new_transparency_mask").trigger()
|
||||
self.doc.setSelection(cur_selection) # reset to current selection
|
||||
self.doc.setActiveNode(cur_layer) # reset to current layer
|
||||
add_mask_action = self.app.action("add_new_transparency_mask")
|
||||
merge_mask_action = self.app.action("flatten_layer")
|
||||
|
||||
def trigger_mask_adding(layers):
|
||||
if self.cfg("create_mask_layer", bool):
|
||||
# need timeout to ensure layer exists first else crash
|
||||
QTimer.singleShot(ADD_MASK_TIMEOUT, lambda: add_mask(layers))
|
||||
# This function is recursive to workaround race conditions when calling Krita's actions
|
||||
def add_mask(layers: list, cur_selection):
|
||||
if len(layers) < 1:
|
||||
self.doc.setSelection(cur_selection) # reset to current selection
|
||||
return
|
||||
layer = layers.pop()
|
||||
|
||||
orig_visible = layer.visible()
|
||||
orig_name = layer.name()
|
||||
|
||||
def restore():
|
||||
# assume newly flattened layer is active
|
||||
result = self.doc.activeNode()
|
||||
result.setVisible(orig_visible)
|
||||
result.setName(orig_name)
|
||||
|
||||
add_mask(layers, cur_selection)
|
||||
|
||||
layer.setVisible(True)
|
||||
self.doc.setActiveNode(layer)
|
||||
self.doc.setSelection(orig_selection)
|
||||
add_mask_action.trigger()
|
||||
|
||||
if create_mask:
|
||||
# collapse transparency mask by default
|
||||
layer.setCollapsed(True)
|
||||
layer.setVisible(orig_visible)
|
||||
QTimer.singleShot(
|
||||
ADD_MASK_TIMEOUT, lambda: add_mask(layers, cur_selection)
|
||||
)
|
||||
else:
|
||||
# flatten transparency mask into layer
|
||||
merge_mask_action.trigger()
|
||||
QTimer.singleShot(ADD_MASK_TIMEOUT, lambda: restore())
|
||||
|
||||
def trigger_mask_adding(layers: list):
|
||||
layers = layers[::-1] # causes final active layer to be the top one
|
||||
|
||||
def handle_mask():
|
||||
cur_selection = self.selection.duplicate() if self.selection else None
|
||||
add_mask(layers, cur_selection)
|
||||
|
||||
QTimer.singleShot(ADD_MASK_TIMEOUT, lambda: handle_mask())
|
||||
|
||||
return trigger_mask_adding
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue