|
@@ -7,6 +7,7 @@ from tkSimpleDialog import askfloat
|
|
|
import Pmw
|
|
import Pmw
|
|
|
import string
|
|
import string
|
|
|
import math
|
|
import math
|
|
|
|
|
+import types
|
|
|
|
|
|
|
|
FRAMES = 0
|
|
FRAMES = 0
|
|
|
SECONDS = 1
|
|
SECONDS = 1
|
|
@@ -19,11 +20,16 @@ class AnimPanel(AppShell):
|
|
|
usecommandarea = 0
|
|
usecommandarea = 0
|
|
|
usestatusarea = 0
|
|
usestatusarea = 0
|
|
|
|
|
|
|
|
- def __init__(self, parent = None, **kw):
|
|
|
|
|
|
|
+ def __init__(self, aList = [], parent = None, **kw):
|
|
|
INITOPT = Pmw.INITOPT
|
|
INITOPT = Pmw.INITOPT
|
|
|
|
|
+ if ((type(aList) == types.ListType) or
|
|
|
|
|
+ (type(aList) == types.TupleType)):
|
|
|
|
|
+ kw['actorList'] = aList
|
|
|
|
|
+ else:
|
|
|
|
|
+ kw['actorList'] = [aList]
|
|
|
optiondefs = (
|
|
optiondefs = (
|
|
|
('title', self.appname, None),
|
|
('title', self.appname, None),
|
|
|
- ('actorList', (), None),
|
|
|
|
|
|
|
+ ('actorList', [], None),
|
|
|
('Actor_label_width', 12, None),
|
|
('Actor_label_width', 12, None),
|
|
|
)
|
|
)
|
|
|
self.defineoptions(kw, optiondefs)
|
|
self.defineoptions(kw, optiondefs)
|
|
@@ -63,9 +69,36 @@ class AnimPanel(AppShell):
|
|
|
command = self.displaySeconds)
|
|
command = self.displaySeconds)
|
|
|
# Reset all actor controls
|
|
# Reset all actor controls
|
|
|
menuBar.addmenuitem('AnimPanel', 'command',
|
|
menuBar.addmenuitem('AnimPanel', 'command',
|
|
|
- 'Reset Actor controls',
|
|
|
|
|
- label = 'Reset all',
|
|
|
|
|
- command = self.resetAll)
|
|
|
|
|
|
|
+ 'Reset Actor controls to zero',
|
|
|
|
|
+ label = 'Reset all to zero',
|
|
|
|
|
+ command = self.resetAllToZero)
|
|
|
|
|
+ menuBar.addmenuitem('AnimPanel', 'command',
|
|
|
|
|
+ 'Reset Actor controls to end time',
|
|
|
|
|
+ label = 'Reset all to end time',
|
|
|
|
|
+ command = self.resetAllToEnd)
|
|
|
|
|
+
|
|
|
|
|
+ # Add some buttons to update all Actor Controls
|
|
|
|
|
+ self.fToggleAll = 1
|
|
|
|
|
+ b = self.createcomponent(
|
|
|
|
|
+ 'toggleEnableButton', (), None,
|
|
|
|
|
+ Button, (self.menuFrame,),
|
|
|
|
|
+ text = 'Toggle Enable',
|
|
|
|
|
+ command = self.toggleAllControls)
|
|
|
|
|
+ b.pack(side = RIGHT, expand = 0)
|
|
|
|
|
+
|
|
|
|
|
+ b = self.createcomponent(
|
|
|
|
|
+ 'showSecondsButton', (), None,
|
|
|
|
|
+ Button, (self.menuFrame,),
|
|
|
|
|
+ text = 'Show Seconds',
|
|
|
|
|
+ command = self.displaySeconds)
|
|
|
|
|
+ b.pack(side = RIGHT, expand = 0)
|
|
|
|
|
+
|
|
|
|
|
+ b = self.createcomponent(
|
|
|
|
|
+ 'showFramesButton', (), None,
|
|
|
|
|
+ Button, (self.menuFrame,),
|
|
|
|
|
+ text = 'Show Frames',
|
|
|
|
|
+ command = self.displayFrameCounts)
|
|
|
|
|
+ b.pack(side = RIGHT, expand = 0)
|
|
|
|
|
|
|
|
# Create a frame to hold all the actor controls
|
|
# Create a frame to hold all the actor controls
|
|
|
actorFrame = Frame(interior)
|
|
actorFrame = Frame(interior)
|
|
@@ -76,7 +109,10 @@ class AnimPanel(AppShell):
|
|
|
for actor in self['actorList']:
|
|
for actor in self['actorList']:
|
|
|
ac = self.createcomponent(
|
|
ac = self.createcomponent(
|
|
|
'actorControl%d' % index, (), 'Actor',
|
|
'actorControl%d' % index, (), 'Actor',
|
|
|
- ActorControl, (actorFrame,))
|
|
|
|
|
|
|
+ ActorControl, (actorFrame,),
|
|
|
|
|
+ text = actor.getName(),
|
|
|
|
|
+ animList = actor.getAnimNames(),
|
|
|
|
|
+ actor = actor)
|
|
|
ac.pack(expand = 1, fill = X)
|
|
ac.pack(expand = 1, fill = X)
|
|
|
self.actorControlList.append(ac)
|
|
self.actorControlList.append(ac)
|
|
|
index = index + 1
|
|
index = index + 1
|
|
@@ -86,23 +122,35 @@ class AnimPanel(AppShell):
|
|
|
|
|
|
|
|
# Create a frame to hold the playback controls
|
|
# Create a frame to hold the playback controls
|
|
|
controlFrame = Frame(interior)
|
|
controlFrame = Frame(interior)
|
|
|
- self.playPauseVar = IntVar()
|
|
|
|
|
- self.playPauseVar.set(0)
|
|
|
|
|
- self.playPauseButton = self.createcomponent(
|
|
|
|
|
|
|
+ self.toStartButton = self.createcomponent(
|
|
|
|
|
+ 'toStart', (), None,
|
|
|
|
|
+ Button, (controlFrame,),
|
|
|
|
|
+ text = '<<',
|
|
|
|
|
+ width = 8,
|
|
|
|
|
+ command = self.resetAllToZero)
|
|
|
|
|
+ self.toStartButton.pack(side = LEFT, expand = 1, fill = X)
|
|
|
|
|
+
|
|
|
|
|
+ self.playButton = self.createcomponent(
|
|
|
'playPause', (), None,
|
|
'playPause', (), None,
|
|
|
- Checkbutton, (controlFrame,),
|
|
|
|
|
|
|
+ Button, (controlFrame,),
|
|
|
text = 'Play', width = 8,
|
|
text = 'Play', width = 8,
|
|
|
- variable = self.playPauseVar,
|
|
|
|
|
- indicatoron = FALSE)
|
|
|
|
|
- self.playPauseButton.pack(side = LEFT, expand = 1, fill = X)
|
|
|
|
|
|
|
+ command = self.playActorControls)
|
|
|
|
|
+ self.playButton.pack(side = LEFT, expand = 1, fill = X)
|
|
|
|
|
|
|
|
- self.resetButton = self.createcomponent(
|
|
|
|
|
- 'reset', (), None,
|
|
|
|
|
|
|
+ self.stopButton = self.createcomponent(
|
|
|
|
|
+ 'playPause', (), None,
|
|
|
Button, (controlFrame,),
|
|
Button, (controlFrame,),
|
|
|
- text = 'Reset All',
|
|
|
|
|
|
|
+ text = 'Stop', width = 8,
|
|
|
|
|
+ command = self.stopActorControls)
|
|
|
|
|
+ self.stopButton.pack(side = LEFT, expand = 1, fill = X)
|
|
|
|
|
+
|
|
|
|
|
+ self.toEndButton = self.createcomponent(
|
|
|
|
|
+ 'toEnd', (), None,
|
|
|
|
|
+ Button, (controlFrame,),
|
|
|
|
|
+ text = '>>',
|
|
|
width = 8,
|
|
width = 8,
|
|
|
- command = self.resetAll)
|
|
|
|
|
- self.resetButton.pack(side = LEFT, expand = 1, fill = X)
|
|
|
|
|
|
|
+ command = self.resetAllToEnd)
|
|
|
|
|
+ self.toEndButton.pack(side = LEFT, expand = 1, fill = X)
|
|
|
|
|
|
|
|
self.loopVar = IntVar()
|
|
self.loopVar = IntVar()
|
|
|
self.loopVar.set(0)
|
|
self.loopVar.set(0)
|
|
@@ -115,12 +163,28 @@ class AnimPanel(AppShell):
|
|
|
|
|
|
|
|
controlFrame.pack(fill = X)
|
|
controlFrame.pack(fill = X)
|
|
|
|
|
|
|
|
|
|
+ def playActorControls(self):
|
|
|
|
|
+ fLoop = self.loopVar.get()
|
|
|
|
|
+ for actorControl in self.actorControlList:
|
|
|
|
|
+ actorControl.play(fLoop)
|
|
|
|
|
+
|
|
|
|
|
+ def stopActorControls(self):
|
|
|
|
|
+ for actorControl in self.actorControlList:
|
|
|
|
|
+ actorControl.stop()
|
|
|
|
|
+
|
|
|
def getActorControlAt(self, index):
|
|
def getActorControlAt(self, index):
|
|
|
return self.actorControlList[index]
|
|
return self.actorControlList[index]
|
|
|
|
|
|
|
|
def enableActorControlAt(self,index):
|
|
def enableActorControlAt(self,index):
|
|
|
self.getActorControlAt(index).enableControl()
|
|
self.getActorControlAt(index).enableControl()
|
|
|
|
|
|
|
|
|
|
+ def toggleAllControls(self):
|
|
|
|
|
+ if self.fToggleAll:
|
|
|
|
|
+ self.disableActorControls()
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.enableActorControls()
|
|
|
|
|
+ self.fToggleAll = 1 - self.fToggleAll
|
|
|
|
|
+
|
|
|
def enableActorControls(self):
|
|
def enableActorControls(self):
|
|
|
for actorControl in self.actorControlList:
|
|
for actorControl in self.actorControlList:
|
|
|
actorControl.enableControl()
|
|
actorControl.enableControl()
|
|
@@ -140,9 +204,13 @@ class AnimPanel(AppShell):
|
|
|
for actorControl in self.actorControlList:
|
|
for actorControl in self.actorControlList:
|
|
|
actorControl.displaySeconds()
|
|
actorControl.displaySeconds()
|
|
|
|
|
|
|
|
- def resetAll(self):
|
|
|
|
|
|
|
+ def resetAllToZero(self):
|
|
|
|
|
+ for actorControl in self.actorControlList:
|
|
|
|
|
+ actorControl.resetToZero()
|
|
|
|
|
+
|
|
|
|
|
+ def resetAllToEnd(self):
|
|
|
for actorControl in self.actorControlList:
|
|
for actorControl in self.actorControlList:
|
|
|
- actorControl.reset()
|
|
|
|
|
|
|
+ actorControl.resetToEnd()
|
|
|
|
|
|
|
|
class ActorControl(Pmw.MegaWidget):
|
|
class ActorControl(Pmw.MegaWidget):
|
|
|
def __init__(self, parent = None, **kw):
|
|
def __init__(self, parent = None, **kw):
|
|
@@ -150,17 +218,20 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
INITOPT = Pmw.INITOPT
|
|
INITOPT = Pmw.INITOPT
|
|
|
DEFAULT_FONT = (('MS', 'Sans', 'Serif'), 12, 'bold')
|
|
DEFAULT_FONT = (('MS', 'Sans', 'Serif'), 12, 'bold')
|
|
|
DEFAULT_ANIMS = ('neutral', 'run', 'walk')
|
|
DEFAULT_ANIMS = ('neutral', 'run', 'walk')
|
|
|
|
|
+ animList = kw.get('animList', DEFAULT_ANIMS)
|
|
|
|
|
+ if len(animList) > 0:
|
|
|
|
|
+ initActive = animList[0]
|
|
|
|
|
+ else:
|
|
|
|
|
+ initActive = DEFAULT_ANIMS[0]
|
|
|
optiondefs = (
|
|
optiondefs = (
|
|
|
('text', 'Actor', self._updateLabelText),
|
|
('text', 'Actor', self._updateLabelText),
|
|
|
('actor', None, None),
|
|
('actor', None, None),
|
|
|
('animList', DEFAULT_ANIMS, None),
|
|
('animList', DEFAULT_ANIMS, None),
|
|
|
|
|
+ ('active', initActive, None),
|
|
|
('sLabel_width', 5, None),
|
|
('sLabel_width', 5, None),
|
|
|
('sLabel_font', DEFAULT_FONT, None),
|
|
('sLabel_font', DEFAULT_FONT, None),
|
|
|
)
|
|
)
|
|
|
self.defineoptions(kw, optiondefs)
|
|
self.defineoptions(kw, optiondefs)
|
|
|
- self.addoptions(
|
|
|
|
|
- (('active', self['animList'][0], None),)
|
|
|
|
|
- )
|
|
|
|
|
|
|
|
|
|
# Initialize the superclass
|
|
# Initialize the superclass
|
|
|
Pmw.MegaWidget.__init__(self, parent)
|
|
Pmw.MegaWidget.__init__(self, parent)
|
|
@@ -171,9 +242,7 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
|
|
|
|
|
# Instance variables
|
|
# Instance variables
|
|
|
self.offset = 0.0
|
|
self.offset = 0.0
|
|
|
- self.fps = 24.0
|
|
|
|
|
- self.maxFrame = 120
|
|
|
|
|
- self.maxSeconds = self.maxFrame / self.fps
|
|
|
|
|
|
|
+ self.maxFrame = 1.0
|
|
|
|
|
|
|
|
# Create component widgets
|
|
# Create component widgets
|
|
|
self._label = self.createcomponent(
|
|
self._label = self.createcomponent(
|
|
@@ -201,7 +270,7 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
# Items for top level menu
|
|
# Items for top level menu
|
|
|
labelMenu.add_cascade(label = 'Display Units', menu = displayMenu)
|
|
labelMenu.add_cascade(label = 'Display Units', menu = displayMenu)
|
|
|
labelMenu.add_command(label = 'Set Offset', command = self.setOffset)
|
|
labelMenu.add_command(label = 'Set Offset', command = self.setOffset)
|
|
|
- labelMenu.add_command(label = 'Reset', command = self.reset)
|
|
|
|
|
|
|
+ labelMenu.add_command(label = 'Reset', command = self.resetToZero)
|
|
|
# Now associate menu with menubutton
|
|
# Now associate menu with menubutton
|
|
|
self._label['menu'] = labelMenu
|
|
self._label['menu'] = labelMenu
|
|
|
self._label.pack(side = LEFT, fill = X)
|
|
self._label.pack(side = LEFT, fill = X)
|
|
@@ -217,19 +286,23 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
animMenu.pack(side = 'left', padx = 5, expand = 0)
|
|
animMenu.pack(side = 'left', padx = 5, expand = 0)
|
|
|
|
|
|
|
|
# Combo box to select frame rate
|
|
# Combo box to select frame rate
|
|
|
- fpsList = (1,2,4,8,12,15,24,30)
|
|
|
|
|
- fpsMenu = self.createcomponent(
|
|
|
|
|
- 'fpsMenu', (), None,
|
|
|
|
|
|
|
+ playRateList = [1/24.0, 0.1, 0.5, 1.0, 2.0,5.0,10.0]
|
|
|
|
|
+ playRate = self['actor'].getPlayRate(self['active'])
|
|
|
|
|
+ if playRate not in playRateList:
|
|
|
|
|
+ playRateList.append(playRate)
|
|
|
|
|
+ playRateList.sort
|
|
|
|
|
+ playRateMenu = self.createcomponent(
|
|
|
|
|
+ 'playRateMenu', (), None,
|
|
|
Pmw.ComboBox, (interior,),
|
|
Pmw.ComboBox, (interior,),
|
|
|
- labelpos = W, label_text = 'at:',
|
|
|
|
|
- entry_width = 4, selectioncommand = self.setFrameRate,
|
|
|
|
|
- scrolledlist_items = fpsList)
|
|
|
|
|
- fpsMenu.selectitem('24')
|
|
|
|
|
- fpsMenu.pack(side = LEFT, padx = 5, expand = 0)
|
|
|
|
|
|
|
+ labelpos = W, label_text = 'X',
|
|
|
|
|
+ entry_width = 4, selectioncommand = self.setPlayRate,
|
|
|
|
|
+ scrolledlist_items = playRateList)
|
|
|
|
|
+ playRateMenu.selectitem(`playRate`)
|
|
|
|
|
+ playRateMenu.pack(side = LEFT, padx = 5, expand = 0)
|
|
|
|
|
|
|
|
# A label
|
|
# A label
|
|
|
- fpsLabel = Label(interior, text = "fps")
|
|
|
|
|
- fpsLabel.pack(side = LEFT)
|
|
|
|
|
|
|
+ playRateLabel = Label(interior, text = 'speed')
|
|
|
|
|
+ playRateLabel.pack(side = LEFT)
|
|
|
|
|
|
|
|
# Scale to control animation
|
|
# Scale to control animation
|
|
|
frameFrame = Frame(interior, relief = SUNKEN, bd = 1)
|
|
frameFrame = Frame(interior, relief = SUNKEN, bd = 1)
|
|
@@ -243,6 +316,7 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
'scale', (), None,
|
|
'scale', (), None,
|
|
|
Scale, (frameFrame,),
|
|
Scale, (frameFrame,),
|
|
|
from_ = 0.0, to = self.maxFrame, resolution = 1.0,
|
|
from_ = 0.0, to = self.maxFrame, resolution = 1.0,
|
|
|
|
|
+ command = self.goTo,
|
|
|
orient = HORIZONTAL, showvalue = 1)
|
|
orient = HORIZONTAL, showvalue = 1)
|
|
|
self.frameControl.pack(side = LEFT, expand = 1)
|
|
self.frameControl.pack(side = LEFT, expand = 1)
|
|
|
|
|
|
|
@@ -263,12 +337,18 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
frameActive.pack(side = LEFT, expand = 1)
|
|
frameActive.pack(side = LEFT, expand = 1)
|
|
|
|
|
|
|
|
# Execute option callbacks
|
|
# Execute option callbacks
|
|
|
- self.initialiseoptions(ActorControl)
|
|
|
|
|
|
|
+ self.initialiseoptions(ActorControl)
|
|
|
|
|
+ self.updateDisplay()
|
|
|
|
|
|
|
|
def _updateLabelText(self):
|
|
def _updateLabelText(self):
|
|
|
self._label['text'] = self['text']
|
|
self._label['text'] = self['text']
|
|
|
|
|
|
|
|
def updateDisplay(self):
|
|
def updateDisplay(self):
|
|
|
|
|
+ actor = self['actor']
|
|
|
|
|
+ active = self['active']
|
|
|
|
|
+ self.fps = actor.getFrameRate(active)
|
|
|
|
|
+ self.maxFrame = actor.getNumFrames(active) - 1
|
|
|
|
|
+ self.maxSeconds = self.maxFrame / self.fps
|
|
|
# Switch between showing frame counts and seconds
|
|
# Switch between showing frame counts and seconds
|
|
|
if self.unitsVar.get() == FRAMES:
|
|
if self.unitsVar.get() == FRAMES:
|
|
|
newMin = int(math.floor(self.offset * self.fps))
|
|
newMin = int(math.floor(self.offset * self.fps))
|
|
@@ -281,22 +361,21 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
newMax = self.offset + self.maxSeconds
|
|
newMax = self.offset + self.maxSeconds
|
|
|
self.minLabel['text'] = "%.1f" % newMin
|
|
self.minLabel['text'] = "%.1f" % newMin
|
|
|
self.maxLabel['text'] = "%.1f" % newMax
|
|
self.maxLabel['text'] = "%.1f" % newMax
|
|
|
- print newMin, newMax
|
|
|
|
|
- self.frameControl.configure(to = newMax, resolution = 0.1)
|
|
|
|
|
|
|
+ self.frameControl.configure(to = newMax, resolution = 0.01)
|
|
|
|
|
|
|
|
def selectAnimNamed(self, name):
|
|
def selectAnimNamed(self, name):
|
|
|
- print 'Selected Anim: ' + name
|
|
|
|
|
|
|
+ self['active'] = name
|
|
|
|
|
+ self.updateDisplay()
|
|
|
|
|
|
|
|
- def setFrameRate(self, rate):
|
|
|
|
|
- self.fps = string.atof(rate)
|
|
|
|
|
- self.maxSeconds = self.maxFrame / self.fps
|
|
|
|
|
|
|
+ def setPlayRate(self, rate):
|
|
|
|
|
+ self['actor'].setPlayRate(eval(rate), self['active'])
|
|
|
self.updateDisplay()
|
|
self.updateDisplay()
|
|
|
|
|
|
|
|
def setOffset(self):
|
|
def setOffset(self):
|
|
|
newOffset = askfloat(parent = self.interior(),
|
|
newOffset = askfloat(parent = self.interior(),
|
|
|
title = self['text'],
|
|
title = self['text'],
|
|
|
prompt = 'Start offset (seconds):')
|
|
prompt = 'Start offset (seconds):')
|
|
|
- if newOffset:
|
|
|
|
|
|
|
+ if newOffset != None:
|
|
|
self.offset = newOffset
|
|
self.offset = newOffset
|
|
|
self.updateDisplay()
|
|
self.updateDisplay()
|
|
|
|
|
|
|
@@ -314,13 +393,31 @@ class ActorControl(Pmw.MegaWidget):
|
|
|
self.unitsVar.set(SECONDS)
|
|
self.unitsVar.set(SECONDS)
|
|
|
self.updateDisplay()
|
|
self.updateDisplay()
|
|
|
|
|
|
|
|
- def reset(self):
|
|
|
|
|
- self.offset = 0.0
|
|
|
|
|
- self.frameControl.set(0.0)
|
|
|
|
|
- self.updateDisplay()
|
|
|
|
|
-######################################################################
|
|
|
|
|
|
|
+ def play(self, fLoop):
|
|
|
|
|
+ if self.frameActiveVar.get():
|
|
|
|
|
+ if fLoop:
|
|
|
|
|
+ self['actor'].loop(self['active'])
|
|
|
|
|
+ else:
|
|
|
|
|
+ self['actor'].play(self['active'])
|
|
|
|
|
|
|
|
-# Create demo in root window for testing.
|
|
|
|
|
-if __name__ == '__main__':
|
|
|
|
|
- widget = AnimPanel(actorList = (1,2,3))
|
|
|
|
|
|
|
+ def goTo(self, t):
|
|
|
|
|
+ if self.unitsVar.get() == FRAMES:
|
|
|
|
|
+ self['actor'].pose(self['active'], string.atoi(t))
|
|
|
|
|
+ else:
|
|
|
|
|
+ self['actor'].pose(self['active'], int(string.atof(t) * self.fps))
|
|
|
|
|
+
|
|
|
|
|
+ def stop(self):
|
|
|
|
|
+ if self.frameActiveVar.get():
|
|
|
|
|
+ self['actor'].stop()
|
|
|
|
|
|
|
|
|
|
+ def resetToZero(self):
|
|
|
|
|
+ self.frameControl.set(0.0)
|
|
|
|
|
+
|
|
|
|
|
+ def resetToEnd(self):
|
|
|
|
|
+ if self.unitsVar.get() == FRAMES:
|
|
|
|
|
+ t = self.maxFrame
|
|
|
|
|
+ else:
|
|
|
|
|
+ t = self.maxFrame / self.fps
|
|
|
|
|
+ self.frameControl.set(t)
|
|
|
|
|
+
|
|
|
|
|
+
|