163 lines
4.4 KiB
Python
163 lines
4.4 KiB
Python
"""
|
|
UI session is running as long as any of the ngSkinTools UI windows are open.
|
|
|
|
"""
|
|
import functools
|
|
|
|
from ngSkinTools2 import cleanup, signal
|
|
from ngSkinTools2.api import Layers, PaintTool, events, mirror, plugin
|
|
from ngSkinTools2.api.log import getLogger
|
|
from ngSkinTools2.api.python_compatibility import Object
|
|
from ngSkinTools2.observableValue import ObservableValue
|
|
from ngSkinTools2.signal import SignalHub
|
|
|
|
log = getLogger("events")
|
|
|
|
|
|
class CurrentLayerState(Object):
|
|
def __init__(self):
|
|
self.selectedSkinCluster = None
|
|
|
|
# will be None, when no current layer is available
|
|
self.layer = None # type: ngSkinTools2.api.Layer
|
|
|
|
|
|
class CurrentPaintTargetState(Object):
|
|
def __init__(self):
|
|
self.skinCluster = None
|
|
self.layerId = None
|
|
self.targets = None
|
|
|
|
|
|
class State(Object):
|
|
def __init__(self):
|
|
self.layersAvailable = False
|
|
self.selection = []
|
|
self.selectedSkinCluster = None
|
|
self.skin_cluster_dq_channel_used = False
|
|
|
|
self.all_layers = [] # type: List[ngSkinTools2.api.Layer]
|
|
self.currentLayer = CurrentLayerState()
|
|
self.currentInfluence = CurrentPaintTargetState()
|
|
|
|
def set_skin_cluster(self, cluster):
|
|
self.selectedSkinCluster = cluster
|
|
self.layers = None if cluster is None else Layers(cluster)
|
|
|
|
def mirror(self):
|
|
# type: () -> mirror.Mirror
|
|
return mirror.Mirror(self.selectedSkinCluster)
|
|
|
|
|
|
class Context(Object):
|
|
def __init__(self):
|
|
self.selected_layers = ObservableValue() # [] layerId
|
|
|
|
|
|
class Session(Object):
|
|
def __init__(self):
|
|
# reference objects that are keeping the session
|
|
self.references = set()
|
|
self.state = None # type: State
|
|
self.events = None # type: events.Events
|
|
self.signal_hub = None # type: SignalHub
|
|
self.context = None # type: Context
|
|
|
|
self.referenceId = 0
|
|
|
|
def active(self):
|
|
return len(self.references) > 0
|
|
|
|
def start(self):
|
|
log.info("STARTING SESSION")
|
|
plugin.load_plugin()
|
|
|
|
self.paint_tool = PaintTool()
|
|
|
|
self.state = State()
|
|
self.events = events.Events(self.state)
|
|
self.signal_hub = SignalHub()
|
|
self.signal_hub.activate()
|
|
cleanup.registerCleanupHandler(self.signal_hub.deactivate)
|
|
self.context = Context()
|
|
|
|
@signal.on(self.events.targetChanged)
|
|
def on_target_change():
|
|
log.info("target changed: clearing target context")
|
|
self.context.selected_layers.set([])
|
|
|
|
self.events.nodeSelectionChanged.emit()
|
|
|
|
def end(self):
|
|
log.info("ENDING SESSION")
|
|
cleanup.cleanup()
|
|
self.state = None
|
|
self.events = None
|
|
self.context = None
|
|
self.signal_hub = None
|
|
pass
|
|
|
|
def addReference(self):
|
|
"""
|
|
returns unique ID for this added reference; this value needs to be passed into removeReference();
|
|
this ensures that reference holder does not remove other references rather than his own.
|
|
:return:
|
|
"""
|
|
self.referenceId += 1
|
|
if not self.active():
|
|
self.start()
|
|
|
|
self.references.add(self.referenceId)
|
|
return self.referenceId
|
|
|
|
def removeReference(self, referenceId):
|
|
try:
|
|
self.references.remove(referenceId)
|
|
except KeyError:
|
|
pass
|
|
|
|
if not self.active():
|
|
self.end()
|
|
|
|
def addQtWidgetReference(self, widget):
|
|
ref = self.addReference()
|
|
|
|
widget.destroyed.connect(lambda: self.removeReference(ref))
|
|
|
|
def reference(self):
|
|
class Context(Object):
|
|
def __init__(self, session):
|
|
"""
|
|
:type session: Session
|
|
:type refObj: object
|
|
"""
|
|
|
|
self.session = session
|
|
|
|
def __enter__(self):
|
|
self.ref = self.session.addReference()
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
self.session.removeReference(self.ref)
|
|
|
|
return Context(self)
|
|
|
|
|
|
session = Session()
|
|
|
|
|
|
def withSession(func):
|
|
"""
|
|
decorator makes sure that single session is running throughout function's lifetime
|
|
"""
|
|
|
|
@functools.wraps(func)
|
|
def result(*args, **kwargs):
|
|
ref = session.addReference()
|
|
try:
|
|
return func(*args, **kwargs)
|
|
finally:
|
|
session.removeReference(ref)
|
|
|
|
return result
|