Reputation: 1
I am trying to create a slider setup for an Attribute Editor view. I know I have to setup a callback but have been stumpt. The goal is to have a parent slider with two children. The purpose is for pose control is when you have, ie, both arms going up for the parent and individual controls to each arm being the children. I have been able to do this if I create a UI window but have not been able to get it to work as an AE template. This is the code that works for the UI window.
class frGUI(object):
def add_sliders(self, *_):
# The test sliders
self.parentval[0] = 0
self.slider[0] = pm.floatSliderGrp(l='Up-Down', p=self.frame1111, f=True, min=-100.0, max=100.0,
v=0.0, cc=lambda *_: self.update_children(0, 1, 2),
dc=lambda *_: self.update_children(0, 1, 2))
self.offsetval[1] = 0
self.slider[1] = pm.floatSliderGrp(l='Up-Down Left', p=self.frame1111, f=True, min=-100.0, max=100.0,
v=0.0, cc=lambda *_: self.update_child_offset(0, 1),
dc=lambda *_: self._up_down_left())
self.offsetval[2] = 0
self.slider[2] = pm.floatSliderGrp(l='Up-Down Right', p=self.frame1111, f=True, min=-100.0, max=100.0,
v=0.0, cc=lambda *_: self.update_child_offset(0, 2),
dc=lambda *_: self._up_down_right())
def __init__(self):
self.parentval = {}
self.offsetval = {}
self.slider = {}
if pm.window('mainwindow', exists=True):
pm.deleteUI('mainwindow')
self.window = pm.window('mainwindow', title='Test Rig', w=425, h=600, mxb=False, mnb=True)
pm.scrollLayout()
# First-level tabs
tab1 = pm.tabLayout(w=405, h=600, imw=5, imh=5)
# First second-level tab
form111 = pm.formLayout()
pm.frameLayout(w=385, lv=False)
self.frame1111 = pm.frameLayout(lv=False, bv=True)
pm.setParent('..')
pm.setParent('..')
pm.setParent('..')
pm.tabLayout(tab1, edit=True, tabLabel=((form111, 'Test')))
self.add_sliders(self)
pm.showWindow(self.window)
def _up_down(self, *_):
self._up_down_left()
self._up_down_right()
def _up_down_left(self, *_):
self.update_lShldrBend()
def _up_down_right(self, *_):
self.update_rShldrBend()
def update_lShldrBend(self, *_):
value = pm.floatSliderGrp(self.slider[1], q=True, v=True)
pm.setAttr('lShldrBend.rotateZ', value)
def update_rShldrBend(self, *_):
value = pm.floatSliderGrp(self.slider[2], q=True, v=True)*(-1)
pm.setAttr('rShldrBend.rotateZ', value)
def update_children(self, parent, child1, child2, *_):
child1lab = pm.floatSliderGrp(self.slider[child1], q=True, l=True)
child2lab = pm.floatSliderGrp(self.slider[child2], q=True, l=True)
child1par = pm.floatSliderGrp(self.slider[child1], q=True, p=True)
child2par = pm.floatSliderGrp(self.slider[child2], q=True, p=True)
child1min = pm.floatSliderGrp(self.slider[child1], q=True, min=True)
child2min = pm.floatSliderGrp(self.slider[child2], q=True, min=True)
pm.deleteUI(self.slider[child1])
pm.deleteUI(self.slider[child2])
self.parentval[parent] = pm.floatSliderGrp(self.slider[parent], q=True, v=True)
child1val = self.offsetval[child1] + self.parentval[parent]
child2val = self.offsetval[child2] + self.parentval[parent]
self.slider[child1] = pm.floatSliderGrp(l=child1lab, p=child1par, f=True, min=child1min, max=100.0,
v=child1val, cc=lambda *_: self.update_child_offset(0, 1),
dc=lambda *_: self._up_down_left(1))
self.slider[child2] = pm.floatSliderGrp(l=child2lab, p=child2par, f=True, min=child2min, max=100.0,
v=child2val, cc=lambda *_: self.update_child_offset(0, 2),
dc=lambda *_: self._up_down_right(2))
if parent == 0:
self._up_down()
def update_child_offset(self, parent, child, *_):
childval = pm.floatSliderGrp(self.slider[child], q=True, v=True)
self.offsetval[child] = childval - self.parentval[parent]
if child == 1:
self._up_down_left()
elif child == 2:
self._up_down_right()
import maya.cmds as cmds
import pymel.core as pm
example = frGUI()
I'm new to MAYA coding on this level but have done a fare bit elsewhere.
Upvotes: 0
Views: 385
Reputation: 1978
You can use a node template with pymel like this:
import pymel.core as pm
class BaseTemplate(pm.ui.AETemplate):
def addControl(self, control, label=None, **kwargs):
pm.ui.AETemplate.addControl(self, control, label=label, **kwargs)
def beginLayout(self, name, collapse=True):
pm.ui.AETemplate.beginLayout(self, name, collapse=collapse)
class AEmyownNodeTemplate(BaseTemplate):
def __init__(self, nodeName):
BaseTemplate.__init__(self,nodeName)
self.thisNode = None
self.ksrType = None
self.node = pm.PyNode(self.nodeName)
self.buildBody(nodeName)
def buildMyOwnTemplates(self, nodeName):
self.thisNode = pm.PyNode(nodeName)
if self.thisNode.type() in ['mesh']:
self.beginLayout("MyOwnLayout" ,collapse=1)
self.endLayout()
def buildBody(self, nodeName):
self.buildMyOwnTemplates(nodeName)
Let's say it it saved somewhere in the pythonpath as aeNodeTemplate.py then you can use it together with a callback in userSetup:
import pymel.core as pm
import aeNodeTemplate
pm.callbacks(addCallback=aeNodeTemplate.AEmyownNodeTemplate, hook='AETemplateCustomContent', owner="me")
This should work for all mesh nodes where a new layout named MyOwnLayout
should appear.
Upvotes: 1