Files
Nexus/2023/scripts/rigging_tools/ngskintools2/ui/options.py
2025-11-24 08:27:50 +08:00

202 lines
5.6 KiB
Python

import json
from maya import cmds
from ngSkinTools2 import signal
from ngSkinTools2.api.log import getLogger
from ngSkinTools2.api.python_compatibility import Object, is_string
from ngSkinTools2.observableValue import ObservableValue
log = getLogger("plugin")
class Value(Object):
def __init__(self, value=None):
self.value = value
def get(self):
return self.value
def set(self, value):
self.value = value
def getInt(self):
try:
return int(self.get())
except:
return 0
class PersistentValue(Value):
"""
persistent value can store itself into Maya's "option vars" array
"""
def __init__(self, name, default_value=None, prefix=None):
Value.__init__(self)
if prefix is None:
prefix = VAR_OPTION_PREFIX
self.name = prefix + name
self.default_value = default_value
self.value = load_option(self.name, self.default_value)
def set(self, value):
Value.set(self, value)
save_option(self.name, self.value)
class PersistentDict(Object):
def __init__(self, name, default_values=None):
if default_values is None:
default_values = {}
self.persistence = PersistentValue(name=name, default_value=json.dumps(default_values))
def __get_values(self):
# type: () -> dict
return json.loads(self.persistence.get())
def __getitem__(self, item):
return self.__get_values().get(item, None)
def __setitem__(self, key, value):
v = self.__get_values()
v[key] = value
self.persistence.set(json.dumps(v))
def load_option(var_name, default_value):
"""
loads value from optionVar
"""
from ngSkinTools2 import BATCH_MODE
if BATCH_MODE:
return default_value
if cmds.optionVar(exists=var_name):
return cmds.optionVar(q=var_name)
return default_value
def save_option(varName, value):
"""
saves option via optionVar
"""
from ngSkinTools2 import BATCH_MODE
if BATCH_MODE:
return
# variable does not exist, attempt to save it
key = None
if isinstance(value, float):
key = 'fv'
elif isinstance(value, int):
key = 'iv'
elif is_string(value):
key = 'sv'
else:
raise ValueError("could not save option %s: invalid value %r" % (varName, value))
kvargs = {key: (varName, value)}
log.info("saving optionvar: %r", kvargs)
cmds.optionVar(**kvargs)
VAR_OPTION_PREFIX = 'ngSkinTools2_'
def delete_custom_options():
for varName in cmds.optionVar(list=True):
if varName.startswith(VAR_OPTION_PREFIX):
cmds.optionVar(remove=varName)
cmds.windowPref('MirrorWeightsWindow', ra=True)
def build_config_property(name, default_value, doc=''):
return property(lambda self: self.__get_value__(name, default_value), lambda self, val: self.__set_value__(name, val), doc=doc)
class Config(Object):
"""
Maya-wide settings for ngSkinTools2
"""
mirrorInfluencesDefaults = build_config_property('mirrorInfluencesDefaults', "{}") # type: string
InfluencesSortUnsorted = 'unsorted'
InfluencesSortDescending = 'descending'
def __init__(self):
from ngSkinTools2.api.mirror import MirrorOptions
self.__storage__ = PersistentValue("config", "{}")
self.__state__ = self.load()
self.unique_client_id = PersistentValue('updateCheckUniqueClientId')
self.checkForUpdatesAtStartup = self.build_observable_value('checkForUpdatesAtStartup', True)
self.influences_show_used_influences_only = self.build_observable_value("influencesViewShowUsedInfluencesOnly", False)
# influences sort is not a simple "true/false" flag to allow different sorting methods in the future.
self.influences_sort = self.build_observable_value("influencesSort", Config.InfluencesSortUnsorted)
default_mirror_options = MirrorOptions()
self.mirror_direction = self.build_observable_value("mirrorDirection", default_mirror_options.direction)
self.mirror_dq = self.build_observable_value("mirrorDq", default_mirror_options.mirrorDq)
self.mirror_mask = self.build_observable_value("mirrorMask", default_mirror_options.mirrorMask)
self.mirror_weights = self.build_observable_value("mirrorWeights", default_mirror_options.mirrorWeights)
def __get_value__(self, name, default_value):
result = self.__state__.get(name, default_value)
log.info("config: return %s=%r", name, result)
return result
def __set_value__(self, name, value):
log.info("config: save %s=%r", name, value)
self.__state__[name] = value
self.save()
def build_observable_value(self, name, default_value):
"""
builds ObservableValue that is loaded and persisted into config when changed
:type name: str
:rtype: ngSkinTools2.observableValue.ObservableValue
"""
result = ObservableValue(self.__get_value__(name=name, default_value=default_value))
@signal.on(result.changed)
def save():
self.__set_value__(name, result())
return result
def load(self):
# noinspection PyBroadException
try:
return json.loads(self.__storage__.get())
except:
return {}
def save(self):
self.__storage__.set(json.dumps(self.__state__))
config = Config()
def bind_checkbox(cb, option):
from ngSkinTools2.ui import qt
cb.setChecked(option())
@qt.on(cb.toggled)
def update():
option.set(cb.isChecked())
return cb