From 2ee6bac4962abb10a0d010a04dc322860897fe0c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 2 Nov 2017 18:41:28 +0100 Subject: [PATCH 1/3] Implement ANM-9 --- colorbleed/maya/__init__.py | 19 +++++++++++ colorbleed/maya/customize.py | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 colorbleed/maya/customize.py diff --git a/colorbleed/maya/__init__.py b/colorbleed/maya/__init__.py index 01929eb9e3..d96fbfed08 100644 --- a/colorbleed/maya/__init__.py +++ b/colorbleed/maya/__init__.py @@ -55,10 +55,29 @@ def on_init(_): log.warning("Can't load plug-in: " "{0} - {1}".format(plugin, e)) + def safe_deferred(fn): + """Execute deferred the function in a try-except""" + + def _fn(): + """safely call in deferred callback""" + try: + fn() + except Exception as exc: + print(exc) + + try: + utils.executeDeferred(_fn) + except Exception as exc: + print(exc) + + cmds.loadPlugin("AbcImport", quiet=True) cmds.loadPlugin("AbcExport", quiet=True) force_load_deferred("mtoa") + from .customize import override_component_mask_commands + safe_deferred(override_component_mask_commands) + def on_save(_): """Automatically add IDs to new nodes diff --git a/colorbleed/maya/customize.py b/colorbleed/maya/customize.py new file mode 100644 index 0000000000..7363874fb1 --- /dev/null +++ b/colorbleed/maya/customize.py @@ -0,0 +1,66 @@ +"""A set of commands that install overrides to Maya's UI""" + +import maya.cmds as mc +import maya.mel as mel +from functools import partial +import logging + + +log = logging.getLogger(__name__) + +COMPONENT_MASK_ORIGINAL = {} + + +def override_component_mask_commands(): + """Override component mask ctrl+click behavior. + + This implements special behavior for Maya's component + mask menu items where a ctrl+click will instantly make + it a isolated behavior disabling all others. + + Tested in Maya 2016 and 2018.1 + + """ + log.info("Installing override_component_mask_commands..") + + BUTTONS = mc.formLayout("objectMaskIcons", + query=True, + childArray=True) + # Skip the triangle list item + BUTTONS = [btn for btn in BUTTONS if btn != "objPickMenuLayout"] + + def _on_changed_callback(original, state): + """New callback""" + + # If "control" is held force the toggled one to on and + # toggle the others based on whether any of the buttons + # was remaining active after the toggle, if not then + # enable all + if mc.getModifiers() == 4: # = CTRL + state = True + active = [mc.iconTextCheckBox(btn, query=True, value=True) for btn + in BUTTONS] + if any(active): + mc.selectType(allObjects=False) + else: + mc.selectType(allObjects=True) + + # Replace #1 with the current button state + cmd = original.replace(" #1", " {}".format(int(state))) + mel.eval(cmd) + + # Get all component mask buttons + for btn in BUTTONS: + + # Store a reference to the original command so that if + # we rerun this override command it doesn't recursively + # try to implement the fix. (This also allows us to + # "uninstall" the behavior later) + if btn not in COMPONENT_MASK_ORIGINAL: + original = mc.iconTextCheckBox(btn, query=True, cc=True) + COMPONENT_MASK_ORIGINAL[btn] = original + + # Assign the special callback + original = COMPONENT_MASK_ORIGINAL[btn] + new_fn = partial(_on_changed_callback, original) + mc.iconTextCheckBox(btn, edit=True, cc=new_fn) From 9681c427cfa07dd1eaf84dc9ea08b2c521af6397 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 3 Nov 2017 09:50:43 +0100 Subject: [PATCH 2/3] Cleanup some code --- colorbleed/maya/customize.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/colorbleed/maya/customize.py b/colorbleed/maya/customize.py index 7363874fb1..cb0e47dc27 100644 --- a/colorbleed/maya/customize.py +++ b/colorbleed/maya/customize.py @@ -16,20 +16,21 @@ def override_component_mask_commands(): This implements special behavior for Maya's component mask menu items where a ctrl+click will instantly make - it a isolated behavior disabling all others. + it an isolated behavior disabling all others. - Tested in Maya 2016 and 2018.1 + Tested in Maya 2016 and 2018 """ log.info("Installing override_component_mask_commands..") - BUTTONS = mc.formLayout("objectMaskIcons", + # Get all object mask buttons + buttons = mc.formLayout("objectMaskIcons", query=True, childArray=True) # Skip the triangle list item - BUTTONS = [btn for btn in BUTTONS if btn != "objPickMenuLayout"] + buttons = [btn for btn in buttons if btn != "objPickMenuLayout"] - def _on_changed_callback(original, state): + def _on_changed_callback(raw_command, state): """New callback""" # If "control" is held force the toggled one to on and @@ -39,18 +40,17 @@ def override_component_mask_commands(): if mc.getModifiers() == 4: # = CTRL state = True active = [mc.iconTextCheckBox(btn, query=True, value=True) for btn - in BUTTONS] + in buttons] if any(active): mc.selectType(allObjects=False) else: mc.selectType(allObjects=True) # Replace #1 with the current button state - cmd = original.replace(" #1", " {}".format(int(state))) + cmd = raw_command.replace(" #1", " {}".format(int(state))) mel.eval(cmd) - # Get all component mask buttons - for btn in BUTTONS: + for btn in buttons: # Store a reference to the original command so that if # we rerun this override command it doesn't recursively From 8c472a9594e7abe8d47946a37b52ea41e9b77f3e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 3 Nov 2017 14:14:32 +0100 Subject: [PATCH 3/3] Remove underscore from inner function, make it look less private. --- colorbleed/maya/customize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/colorbleed/maya/customize.py b/colorbleed/maya/customize.py index cb0e47dc27..64f33d5aae 100644 --- a/colorbleed/maya/customize.py +++ b/colorbleed/maya/customize.py @@ -30,7 +30,7 @@ def override_component_mask_commands(): # Skip the triangle list item buttons = [btn for btn in buttons if btn != "objPickMenuLayout"] - def _on_changed_callback(raw_command, state): + def on_changed_callback(raw_command, state): """New callback""" # If "control" is held force the toggled one to on and @@ -62,5 +62,5 @@ def override_component_mask_commands(): # Assign the special callback original = COMPONENT_MASK_ORIGINAL[btn] - new_fn = partial(_on_changed_callback, original) + new_fn = partial(on_changed_callback, original) mc.iconTextCheckBox(btn, edit=True, cc=new_fn)