| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- """
- UI for object property control
- """
- import wx
- import os
- import math
- from wx.lib.embeddedimage import PyEmbeddedImage
- from wx.lib.scrolledpanel import ScrolledPanel
- from wx.lib.agw.cubecolourdialog import CCD_SHOW_ALPHA, CubeColourDialog
- from direct.wxwidgets.WxSlider import WxSlider
- from panda3d.core import BitMask32, Filename
- from . import ObjectGlobals as OG
- from . import AnimGlobals as AG
- #----------------------------------------------------------------------
- Key = PyEmbeddedImage(
- "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAIAAACQKrqGAAAAA3NCSVQICAjb4U/gAAABIElE"
- "QVQokZWSMW7CQBBFZ2Z3sQ02Ni4sOS6QiLgO5yBXIMcJ1KENje8QLESH7F3FVFQIIS3eTWGJ"
- "VE7Iq6Z4+tL8GVRSwmPQg94fKiIOBoNer2et/U1FRER8X6+LonBdFwB4l+p53mq1qqRUUsZx"
- "nKYpBwDOuRACEQGgaRoAYETn8/l4PL4uFkqp/X6fZRlnjO12u7KqENEa43keADDGvuo6Go0A"
- "wPd9YkxrzY0x4/FYKlXX9eVymc1mjIiIgiD43G4BwFprmgYRubU2DMPnySTw/ev1+pSmRISI"
- "SZJ8bDan06ksSyLiQmDXCfr9fp7nb8vldDp9mc9d1/1R27XaClscxzkcDlEUhcOhvt06U1uE"
- "EMaYtpbOXlu01vf5Hz/wDRuDdIDl5WtQAAAAAElFTkSuQmCC")
- #----------------------------------------------------------------------
- class AnimFileDrop(wx.FileDropTarget):
- def __init__(self, editor):
- wx.FileDropTarget.__init__(self)
- self.editor = editor
- def OnDropFiles(self, x, y, filenames):
- obj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
- if obj is None:
- return
- objDef = obj[OG.OBJ_DEF]
- if not objDef.actor:
- return
- objNP = obj[OG.OBJ_NP]
- for filename in filenames:
- name = os.path.basename(filename)
- animName = Filename.fromOsSpecific(filename).getFullpath()
- if name.endswith('.mb') or\
- name.endswith('.ma'):
- self.editor.convertMaya(animName, self.editor.ui.protoPaletteUI.addNewItem, obj, isAnim=True)
- return
- if animName not in objDef.anims:
- objDef.anims.append(animName)
- objNP.loadAnims({name:animName})
- objNP.loop(name)
- obj[OG.OBJ_ANIM] = animName
- self.editor.ui.objectPropertyUI.updateProps(obj)
- class ObjectPropUI(wx.Panel):
- """
- Base class for ObjectPropUIs,
- It consists of label area and ui area.
- """
- def __init__(self, parent, label):
- wx.Panel.__init__(self, parent)
- self.parent = parent
- self.labelPane = wx.Panel(self)
- self.label = wx.StaticText(self.labelPane, label=label)
- self.labelSizer = wx.BoxSizer(wx.HORIZONTAL)
- self.labelSizer.Add(self.label)
- bmpKey = Key.GetBitmap()
- self.setKeyButton = wx.BitmapButton(self.labelPane, -1, bmpKey, size = (15,15),style = wx.BU_AUTODRAW)
- self.labelSizer.Add(self.setKeyButton)
- self.labelPane.SetSizer(self.labelSizer)
- self.uiPane = wx.Panel(self)
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(self.labelPane)
- sizer.Add(self.uiPane, 1, wx.EXPAND, 0)
- self.SetSizer(sizer)
- self.setKeyButton.Bind(wx.EVT_BUTTON, self.onKey)
- def onKey(self, evt):
- self.parent = wx.GetTopLevelParent(self)
- if self.parent.editor.mode == self.parent.editor.ANIM_MODE:
- obj = self.parent.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
- value = self.getValue()
- frame = self.parent.editor.ui.animUI.curFrame
- if property in self.parent.editor.animMgr.keyFramesInfo:
- for i in range(len(self.parent.editor.animMgr.keyFramesInfo[property])):
- if self.parent.editor.animMgr.keyFramesInfo[property][i][AG.FRAME] == frame:
- del self.parent.editor.animMgr.keyFramesInfo[property][i]
- self.parent.editor.animMgr.keyFramesInfo[property].append([frame, value, [], []])
- #sort keyFrameInfo list by the order of frame number
- sortKeyList = self.parent.editor.animMgr.keyFramesInfo[property]
- for i in range(0, len(sortKeyList)-1):
- for j in range(i+1, len(sortKeyList)):
- if sortKeyList[i][AG.FRAME]>sortKeyList[j][AG.FRAME]:
- temp = sortKeyList[i]
- sortKeyList[i] = sortKeyList[j]
- sortKeyList[j] = temp
- self.parent.editor.animMgr.generateSlope(self.parent.editor.animMgr.keyFramesInfo[property])
- else:
- self.parent.editor.animMgr.keyFramesInfo[property] = [[frame, value, [], []]]
- exist = False
- for keyFrame in self.parent.editor.animMgr.keyFrames:
- if frame == keyFrame:
- exist = True
- break
- if not exist:
- self.parent.editor.animMgr.keyFrames.append(frame)
- self.parent.editor.ui.animUI.OnPropKey()
- else:
- evt.Skip()
- def setValue(self, value):
- self.ui.SetValue(value)
- def getValue(self):
- return self.ui.GetValue()
- def bindFunc(self, inFunc, outFunc, valFunc = None):
- self.ui.Bind(wx.EVT_ENTER_WINDOW, inFunc)
- self.ui.Bind(wx.EVT_LEAVE_WINDOW, outFunc)
- if valFunc:
- self.ui.Bind(self.eventType, valFunc)
- class ObjectPropUIEntry(ObjectPropUI):
- """ UI for string value properties """
- def __init__(self, parent, label):
- ObjectPropUI.__init__(self, parent, label)
- self.ui = wx.TextCtrl(self.uiPane, -1)
- self.eventType = wx.EVT_TEXT_ENTER
- self.Layout()
- def setValue(self, value):
- self.ui.SetValue(str(value))
- class ObjectPropUISlider(ObjectPropUI):
- """ UI for float value properties """
- def __init__(self, parent, label, value, minValue, maxValue):
- ObjectPropUI.__init__(self, parent, label)
- self.ui = WxSlider(self.uiPane, -1, value, minValue, maxValue,
- pos = (0,0), size=(140, -1),
- style=wx.SL_HORIZONTAL | wx.SL_LABELS)
- self.ui.Enable()
- self.Layout()
- def bindFunc(self, inFunc, outFunc, valFunc = None):
- self.ui.Bind(wx.EVT_ENTER_WINDOW, inFunc)
- self.ui.Bind(wx.EVT_LEAVE_WINDOW, outFunc)
- self.ui.textValue.Bind(wx.EVT_ENTER_WINDOW, inFunc)
- self.ui.textValue.Bind(wx.EVT_LEAVE_WINDOW, outFunc)
- if valFunc:
- self.ui.bindFunc(valFunc)
- class ObjectPropUISpinner(ObjectPropUI):
- """ UI for int value properties """
- def __init__(self, parent, label, value, minValue, maxValue):
- ObjectPropUI.__init__(self, parent, label)
- self.ui = wx.SpinCtrl(self.uiPane, -1, "", min=minValue, max=maxValue, initial=value)
- self.eventType = wx.EVT_SPIN
- self.Layout()
- class ObjectPropUICheck(ObjectPropUI):
- def __init__(self, parent, label, value):
- ObjectPropUI.__init__(self, parent, label)
- self.ui = wx.CheckBox(self.uiPane, -1, "", size=(50, 30))
- self.setValue(value)
- self.eventType = wx.EVT_CHECKBOX
- self.Layout()
- class ObjectPropUIRadio(ObjectPropUI):
- def __init__(self, parent, label, value, valueList):
- ObjectPropUI.__init__(self, parent, label)
- self.ui = wx.RadioBox(self.uiPane, -1, "", choices=valueList, majorDimension=1, style=wx.RA_SPECIFY_COLS)
- self.setValue(value)
- self.eventType = wx.EVT_RADIOBOX
- self.Layout()
- def setValue(self, value):
- self.ui.SetStringSelection(value)
- def getValue(self):
- return self.ui.GetStringSelection()
- class ObjectPropUICombo(ObjectPropUI):
- def __init__(self, parent, label, value, valueList, obj=None, callBack=None):
- ObjectPropUI.__init__(self, parent, label)
- self.ui = wx.Choice(self.uiPane, -1, choices=valueList)
- if callBack is not None:
- button = wx.Button(self.labelPane, -1, 'Update', size = (100, 18))
- button.Bind(wx.EVT_BUTTON, lambda p0=None, p1=obj, p2=self: callBack(p0, p1, p2))
- self.labelSizer.Add(button)
- self.setValue(value)
- self.eventType = wx.EVT_CHOICE
- self.Layout()
- def setValue(self, value):
- self.ui.SetStringSelection(value)
- def getValue(self):
- return self.ui.GetStringSelection()
- def setItems(self, valueList):
- self.ui.SetItems(valueList)
- class ObjectPropUITime(wx.Panel):
- def __init__(self, parent, label, value):
- wx.Panel.__init__(self, parent)
- self.parent = parent
- self.labelPane = wx.Panel(self)
- self.label = wx.StaticText(self.labelPane, label=label)
- self.labelSizer = wx.BoxSizer(wx.HORIZONTAL)
- self.labelSizer.Add(self.label)
- self.labelPane.SetSizer(self.labelSizer)
- self.uiPane = wx.Panel(self)
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(self.labelPane)
- sizer.Add(self.uiPane, 1, wx.EXPAND, 0)
- self.SetSizer(sizer)
- hSizer = wx.BoxSizer(wx.HORIZONTAL)
- self.uiAmPm = wx.Choice(self.uiPane, -1, choices=['AM', 'PM'])
- self.uiHour = wx.Choice(self.uiPane, -1, choices=[str(x) for x in range(1, 13)])
- self.uiMin = wx.Choice(self.uiPane, -1, choices=[str(x) for x in range(0, 60, 15)])
- hSizer.Add(self.uiAmPm)
- hSizer.Add(self.uiHour)
- hSizer.Add(self.uiMin)
- self.uiPane.SetSizer(hSizer)
- self.setValue(value)
- self.eventType = wx.EVT_CHOICE
- self.Layout()
- def setValue(self, value):
- hourVal = int(math.floor(value))
- minVal = [0, 15, 30, 45][int((value - hourVal) * 4)]
- if hourVal > 11:
- ampmStr = 'PM'
- hourVal = hourVal - 12
- else:
- ampmStr = 'AM'
- if hourVal == 0:
- hourVal = 12
- self.uiAmPm.SetStringSelection(ampmStr)
- self.uiHour.SetStringSelection(str(hourVal))
- self.uiMin.SetStringSelection(str(minVal))
- def getValue(self):
- ampmStr = self.uiAmPm.GetStringSelection()
- hourVal = int(self.uiHour.GetStringSelection())
- if hourVal == 12:
- hourVal = 0
- if ampmStr == 'PM':
- hourVal += 12
- minVal = float(self.uiMin.GetStringSelection())
- value = float(hourVal) + minVal / 60.0
- return value
- def bindFunc(self, inFunc, outFunc, valFunc = None):
- self.uiAmPm.Bind(wx.EVT_ENTER_WINDOW, inFunc)
- self.uiAmPm.Bind(wx.EVT_LEAVE_WINDOW, outFunc)
- self.uiHour.Bind(wx.EVT_ENTER_WINDOW, inFunc)
- self.uiHour.Bind(wx.EVT_LEAVE_WINDOW, outFunc)
- self.uiMin.Bind(wx.EVT_ENTER_WINDOW, inFunc)
- self.uiMin.Bind(wx.EVT_LEAVE_WINDOW, outFunc)
- if valFunc:
- self.uiAmPm.Bind(self.eventType, valFunc)
- self.uiHour.Bind(self.eventType, valFunc)
- self.uiMin.Bind(self.eventType, valFunc)
- class ColorPicker(CubeColourDialog):
- def __init__(self, parent, colourData=None, style=CCD_SHOW_ALPHA,
- alpha=255, updateCB=None, exitCB=None):
- self.updateCB = updateCB
- CubeColourDialog.__init__(self, parent, colourData, style)
- self.okButton.Hide()
- self.cancelButton.Hide()
- self._colour.alpha = alpha
- self.alphaSpin.SetValue(self._colour.alpha)
- self.DrawAlpha()
- if exitCB:
- self.Bind(wx.EVT_CLOSE, exitCB)
- def SetPanelColours(self):
- self.oldColourPanel.RefreshColour(self._oldColour)
- self.newColourPanel.RefreshColour(self._colour)
- if self.updateCB:
- self.updateCB(self._colour.r, self._colour.g, self._colour.b, self._colour.alpha)
- class ObjectPropertyUI(ScrolledPanel):
- def __init__(self, parent, editor):
- self.editor = editor
- self.colorPicker = None
- self.lastColorPickerPos = None
- self.lastPropTab = None
- ScrolledPanel.__init__(self, parent)
- parentSizer = wx.BoxSizer(wx.VERTICAL)
- parentSizer.Add(self, 1, wx.EXPAND, 0)
- parent.SetSizer(parentSizer)
- parent.Layout()
- self.SetDropTarget(AnimFileDrop(self.editor))
- def clearPropUI(self):
- sizer = self.GetSizer()
- if sizer is not None:
- self.lastPropTab = self.nb.GetCurrentPage().GetName()
- sizer.Remove(self.propPane)
- self.propPane.Destroy()
- self.SetSizer(None)
- self.Layout()
- self.SetupScrolling(self, scroll_y=True, rate_y=20)
- def colorPickerExitCB(self, evt=None):
- self.lastColorPickerPos = self.colorPicker.GetPosition()
- self.colorPicker.Destroy()
- self.colorPicker = None
- def colorPickerUpdateCB(self, rr, gg, bb, aa):
- r = rr / 255.0
- g = gg / 255.0
- b = bb / 255.0
- a = aa / 255.0
- self.propCR.setValue(r)
- self.propCG.setValue(g)
- self.propCB.setValue(b)
- self.propCA.setValue(a)
- self.editor.objectMgr.updateObjectColor(r, g, b, a)
- def onColorSlider(self, evt):
- r = float(self.editor.ui.objectPropertyUI.propCR.getValue())
- g = float(self.editor.ui.objectPropertyUI.propCG.getValue())
- b = float(self.editor.ui.objectPropertyUI.propCB.getValue())
- a = float(self.editor.ui.objectPropertyUI.propCA.getValue())
- if self.colorPicker:
- evtObj = evt.GetEventObject()
- if evtObj == self.propCR.ui or\
- evtObj == self.propCR.ui.textValue:
- self.colorPicker.redSpin.SetValue(r * 255)
- self.colorPicker.AssignColourValue('r', r * 255, 255, 0)
- elif evtObj == self.propCG.ui or\
- evtObj == self.propCG.ui.textValue:
- self.colorPicker.greenSpin.SetValue(g * 255)
- self.colorPicker.AssignColourValue('g', g * 255, 255, 0)
- elif evtObj == self.propCB.ui or\
- evtObj == self.propCB.ui.textValue:
- self.colorPicker.blueSpin.SetValue(b * 255)
- self.colorPicker.AssignColourValue('b', b * 255, 255, 0)
- else:
- self.colorPicker._colour.alpha = a * 255
- self.colorPicker.alphaSpin.SetValue(self.colorPicker._colour.alpha)
- self.colorPicker.DrawAlpha()
- self.editor.objectMgr.updateObjectColor(r, g, b, a)
- def openColorPicker(self, evt, colourData, alpha):
- if self.colorPicker:
- self.lastColorPickerPos = self.colorPicker.GetPosition()
- self.colorPicker.Destroy()
- self.colorPicker = ColorPicker(self, colourData, alpha=alpha, updateCB=self.colorPickerUpdateCB, exitCB=self.colorPickerExitCB)
- self.colorPicker.GetColourData().SetChooseFull(True)
- self.colorPicker.Show()
- if self.lastColorPickerPos:
- self.colorPicker.SetPosition(self.lastColorPickerPos)
- def updateProps(self, obj, movable=True):
- self.clearPropUI()
- self.propPane = wx.Panel(self)
- mainSizer = wx.BoxSizer(wx.VERTICAL)
- mainSizer.Add(self.propPane, 1, wx.EXPAND, 0)
- self.SetSizer(mainSizer)
- self.nb = wx.Notebook(self.propPane, style=wx.NB_BOTTOM)
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(self.nb, 1, wx.EXPAND)
- self.propPane.SetSizer(sizer)
- self.transformPane = wx.Panel(self.nb, -1, name='Transform')
- self.nb.AddPage(self.transformPane, 'Transform')
- self.propX = ObjectPropUIEntry(self.transformPane, 'X')
- self.propY = ObjectPropUIEntry(self.transformPane, 'Y')
- self.propZ = ObjectPropUIEntry(self.transformPane, 'Z')
- self.propH = ObjectPropUISlider(self.transformPane, 'H', 0, 0, 360)
- self.propP = ObjectPropUISlider(self.transformPane, 'P', 0, 0, 360)
- self.propR = ObjectPropUISlider(self.transformPane, 'R', 0, 0, 360)
- self.propSX = ObjectPropUIEntry(self.transformPane, 'SX')
- self.propSY = ObjectPropUIEntry(self.transformPane, 'SY')
- self.propSZ = ObjectPropUIEntry(self.transformPane, 'SZ')
- transformProps = [
- self.propX, self.propY, self.propZ,
- self.propH, self.propP, self.propR,
- self.propSX, self.propSY, self.propSZ,
- ]
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.AddMany(transformProps)
- self.transformPane.SetSizer(sizer)
- for transformProp in transformProps:
- transformProp.bindFunc(self.editor.objectMgr.onEnterObjectPropUI,
- self.editor.objectMgr.onLeaveObjectPropUI,
- self.editor.objectMgr.updateObjectTransform)
- if not movable:
- for transformProp in transformProps:
- transformProp.ui.Disable()
- self.lookPane = wx.Panel(self.nb, -1, name='Look')
- self.nb.AddPage(self.lookPane, 'Look')
- objNP = obj[OG.OBJ_NP]
- objRGBA = obj[OG.OBJ_RGBA]
- self.propCR = ObjectPropUISlider(self.lookPane, 'CR', objRGBA[0], 0, 1)
- self.propCG = ObjectPropUISlider(self.lookPane, 'CG', objRGBA[1], 0, 1)
- self.propCB = ObjectPropUISlider(self.lookPane, 'CB', objRGBA[2], 0, 1)
- self.propCA = ObjectPropUISlider(self.lookPane, 'CA', objRGBA[3], 0, 1)
- colorProps = [self.propCR, self.propCG, self.propCB, self.propCA]
- for colorProp in colorProps:
- colorProp.ui.bindFunc(self.onColorSlider)
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.AddMany(colorProps)
- button = wx.Button(self.lookPane, -1, 'Color Picker', (0,0), (140, 20))
- _colourData = wx.ColourData()
- _colourData.SetColour(wx.Colour(objRGBA[0] * 255, objRGBA[1] * 255, objRGBA[2] * 255))
- button.Bind(wx.EVT_BUTTON, lambda p0=None, p1=_colourData, p2=objRGBA[3] * 255: self.openColorPicker(p0, p1, p2))
- sizer.Add(button)
- if self.colorPicker:
- self.openColorPicker(None, _colourData, objRGBA[3] * 255)
- objDef = obj[OG.OBJ_DEF]
- if objDef.updateModelFunction is not None or (objDef.model is not None and len(objDef.models) > 0):
- defaultModel = obj[OG.OBJ_MODEL]
- if defaultModel is None:
- defaultModel = ''
- if len(objDef.models) == 0:
- modelList = ''
- else:
- modelList = objDef.models
- propUI = ObjectPropUICombo(self.lookPane, 'model', defaultModel, modelList, obj, callBack=objDef.updateModelFunction)
- sizer.Add(propUI)
- propUI.bindFunc(self.editor.objectMgr.onEnterObjectPropUI,
- self.editor.objectMgr.onLeaveObjectPropUI,
- lambda p0=None, p1=obj: self.editor.objectMgr.updateObjectModelFromUI(p0, p1))
- animList = objDef.animDict.get(obj[OG.OBJ_MODEL])
- if len(objDef.anims) > 0 or animList:
- if animList is None:
- animList = objDef.anims
- propUI = ObjectPropUICombo(self.lookPane, 'anim', obj[OG.OBJ_ANIM], animList)
- sizer.Add(propUI)
- propUI.bindFunc(self.editor.objectMgr.onEnterObjectPropUI,
- self.editor.objectMgr.onLeaveObjectPropUI,
- lambda p0=None, p1=obj: self.editor.objectMgr.updateObjectAnimFromUI(p0, p1))
- self.lookPane.SetSizer(sizer)
- self.propsPane = wx.Panel(self.nb, -1, name='Properties')
- self.nb.AddPage(self.propsPane, 'Properties')
- sizer = wx.BoxSizer(wx.VERTICAL)
- propNames = objDef.orderedProperties[:]
- for key in list(objDef.properties.keys()):
- if key not in propNames:
- propNames.append(key)
- for key in propNames:
- # handling properties mask
- propMask = BitMask32()
- for modeKey in list(objDef.propertiesMask.keys()):
- if key in objDef.propertiesMask[modeKey]:
- propMask |= modeKey
- if not propMask.isZero():
- if (self.editor.mode & propMask).isZero():
- continue
- propDef = objDef.properties[key]
- propType = propDef[OG.PROP_TYPE]
- propDataType = propDef[OG.PROP_DATATYPE]
- value = obj[OG.OBJ_PROP].get(key)
- if propType == OG.PROP_UI_ENTRY:
- propUI = ObjectPropUIEntry(self.propsPane, key)
- propUI.setValue(value)
- sizer.Add(propUI)
- elif propType == OG.PROP_UI_SLIDE:
- if len(propDef) <= OG.PROP_RANGE:
- continue
- propRange = propDef[OG.PROP_RANGE]
- if value is None:
- continue
- if propDataType != OG.PROP_FLOAT:
- value = float(value)
- propUI = ObjectPropUISlider(self.propsPane, key, value, propRange[OG.RANGE_MIN], propRange[OG.RANGE_MAX])
- sizer.Add(propUI)
- elif propType == OG.PROP_UI_SPIN:
- if len(propDef) <= OG.PROP_RANGE:
- continue
- propRange = propDef[OG.PROP_RANGE]
- if value is None:
- continue
- propUI = ObjectPropUISpinner(self.propsPane, key, value, propRange[OG.RANGE_MIN], propRange[OG.RANGE_MAX])
- sizer.Add(propUI)
- elif propType == OG.PROP_UI_CHECK:
- if value is None:
- continue
- propUI = ObjectPropUICheck(self.propsPane, key, value)
- sizer.Add(propUI)
- elif propType == OG.PROP_UI_RADIO:
- if len(propDef) <= OG.PROP_RANGE:
- continue
- propRange = propDef[OG.PROP_RANGE]
- if value is None:
- continue
- if propDataType != OG.PROP_STR:
- for i in range(len(propRange)):
- propRange[i] = str(propRange[i])
- value = str(value)
- propUI = ObjectPropUIRadio(self.propsPane, key, value, propRange)
- sizer.Add(propUI)
- elif propType == OG.PROP_UI_COMBO:
- if len(propDef) <= OG.PROP_RANGE:
- continue
- propRange = propDef[OG.PROP_RANGE]
- if value is None:
- continue
- if propDataType != OG.PROP_STR:
- for i in range(len(propRange)):
- propRange[i] = str(propRange[i])
- value = str(value)
- propUI = ObjectPropUICombo(self.propsPane, key, value, propRange)
- sizer.Add(propUI)
- elif propType == OG.PROP_UI_COMBO_DYNAMIC:
- if len(propDef) <= OG.PROP_DYNAMIC_KEY:
- continue
- propDynamicKey = propDef[OG.PROP_DYNAMIC_KEY]
- if propDynamicKey == OG.PROP_MODEL:
- dynamicRangeKey = obj[OG.OBJ_MODEL]
- else:
- dynamicRangeKey = obj[OG.OBJ_PROP].get(propDynamicKey)
- if dynamicRangeKey is None:
- self.editor.objectMgr.updateObjectPropValue(obj, key, propDef[OG.PROP_DEFAULT], fUndo=False)
- continue
- propRange = propDef[OG.PROP_RANGE].get(dynamicRangeKey)
- if propRange is None:
- self.editor.objectMgr.updateObjectPropValue(obj, key, propDef[OG.PROP_DEFAULT], fUndo=False)
- continue
- if value is None:
- continue
- if propDataType != OG.PROP_STR:
- for i in range(len(propRange)):
- propRange[i] = str(propRange[i])
- value = str(value)
- if value not in propRange:
- value = propRange[0]
- self.editor.objectMgr.updateObjectPropValue(obj, key, value, fUndo=False)
- propUI = ObjectPropUICombo(self.propsPane, key, value, propRange)
- sizer.Add(propUI)
- elif propType == OG.PROP_UI_TIME:
- if value is None:
- continue
- propUI = ObjectPropUITime(self.propsPane, key, value)
- sizer.Add(propUI)
- else:
- # unspported property type
- continue
- propUI.bindFunc(self.editor.objectMgr.onEnterObjectPropUI,
- self.editor.objectMgr.onLeaveObjectPropUI,
- lambda p0=None, p1=obj, p2=key: self.editor.objectMgr.updateObjectProperty(p0, p1, p2))
- self.propsPane.SetSizer(sizer)
- self.Layout()
- self.SetupScrolling(self, scroll_y = True, rate_y = 20)
- if self.lastPropTab == 'Transform':
- self.nb.SetSelection(0)
- elif self.lastPropTab == 'Look':
- self.nb.SetSelection(1)
- elif self.lastPropTab == 'Properties':
- self.nb.SetSelection(2)
|