*** empty log message ***

This commit is contained in:
Mark Mine 2001-01-06 01:07:10 +00:00
parent c9ec4a26a2
commit de7bcb0b50
5 changed files with 222 additions and 58 deletions

View File

@ -262,6 +262,7 @@ class LevelEditor(NodePath, PandaObject):
('SGENodePath_Toggle Viz', self.toggleViz),
('SGENodePath_Add Group', self.addGroup),
('SGENodePath_Add Vis Group', self.addVisGroup),
('SGENodePath_Set Color', self.setNPColor),
# Actions in response to Pie Menu interaction
('select_building_style', self.setBuildingStyle),
('select_building_type', self.setBuildingType),
@ -1085,14 +1086,16 @@ class LevelEditor(NodePath, PandaObject):
self.replaceSelected()
def setWindowCount(self, count):
if self.DNATarget:
if count == 0:
# Remove windows and clear out DNATarget
self.removeWindows(self.DNATarget, self.DNATargetParent)
self.DNATarget = None
else:
self.DNATarget.setWindowCount(count)
self.replaceSelected()
if (self.DNATarget != None) & (count != 0):
self.DNATarget.setWindowCount(count)
elif (self.DNATarget != None) & (count == 0):
# Remove windows and clear out DNATarget
self.removeWindows(self.DNATarget, self.DNATargetParent)
self.DNATarget = None
elif (self.DNATarget == None) & (count != 0):
self.DNATarget = self.createWindows()
self.DNATargetParent.add(self.DNATarget)
self.replaceSelected()
def setWallStyle(self, style):
if (self.DNATarget != None) & (style != None):
@ -1100,6 +1103,14 @@ class LevelEditor(NodePath, PandaObject):
self.DNATarget, style,
self.DNATarget.getHeight())
self.replaceSelected()
def setNPColor(self, nodePath):
""" This is used to set color of dnaNode subparts """
def updateDNANodeColor(color, s = self, np = nodePath):
# Update node color in DNASTORE here
# dnaNode = s.findDNANode(np)
pass
esg = EntryScale.setColor(nodePath, updateDNANodeColor)
# SELECTION FUNCTIONS
def select(self, nodePath):
@ -2935,7 +2946,7 @@ class LevelEditorPanel(Pmw.MegaToplevel):
buttonFrame2,
text = 'New Vis Group',
command = self.createNewVisGroup)
self.groupButton.pack(side = 'left', expand = 1, fill = 'x')
self.visGroupButton.pack(side = 'left', expand = 1, fill = 'x')
self.setParentButton = Button(
buttonFrame2,
@ -2949,44 +2960,48 @@ class LevelEditorPanel(Pmw.MegaToplevel):
command = self.levelEditor.reparentSelected)
self.reparentButton.pack(side = 'left', expand = 1, fill = 'x')
buttonFrame2.pack(fill = 'x')
buttonFrame3 = Frame(hull)
self.isolateButton = Button(
buttonFrame2,
buttonFrame3,
text = 'Isolate Selected',
command = self.levelEditor.isolate)
self.isolateButton.pack(side = 'left', expand = 1, fill = 'x')
self.showAllButton = Button(
buttonFrame2,
buttonFrame3,
text = 'Show All',
command = self.levelEditor.showAll)
self.showAllButton.pack(side = 'left', expand = 1, fill = 'x')
buttonFrame2.pack(fill = 'x')
buttonFrame3.pack(fill = 'x')
buttonFrame3 = Frame(hull)
buttonFrame4 = Frame(hull)
self.driveMode = IntVar()
self.driveMode.set(1)
self.driveModeButton = Radiobutton(
buttonFrame3,
buttonFrame4,
text = 'Drive Mode',
value = 0,
variable = self.driveMode,
command = self.levelEditor.useDriveMode)
self.driveModeButton.pack(side = 'left', expand = 1, fill = 'x')
directModeButton = Radiobutton(
buttonFrame3,
buttonFrame4,
text = 'DIRECT Fly',
value = 1,
variable = self.driveMode,
command = self.levelEditor.useDirectFly)
directModeButton.pack(side = 'left', expand = 1, fill = 'x')
buttonFrame3.pack(fill = 'x')
buttonFrame4.pack(fill = 'x')
self.sceneGraphExplorer = SceneGraphExplorer(
parent = sceneGraphPage,
root = self.levelEditor,
menuItems = ['Select', 'Isolate', 'Flash', 'Toggle Viz',
'Set Parent', 'Reparent', 'Add Group',
'Add Vis Group', 'Set Color',
'Set Name'])
self.sceneGraphExplorer.pack(expand = 1, fill = 'both')

View File

@ -9,8 +9,8 @@ import Floater
"""
TODO:
Orbital mode
Task to monitor pose
wrt coa
"""
ZERO_VEC = Vec3(0)
@ -31,6 +31,8 @@ class Placer(Pmw.MegaToplevel):
# Initialize state
self.tempCS = render.attachNewNode(NamedNode('placerTempCS'))
self.orbitFromCS = render.attachNewNode(NamedNode('placerOrbitFromCS'))
self.orbitToCS = render.attachNewNode(NamedNode('placerOrbitToCS'))
self.refCS = self.tempCS
self.undoList = []
self.redoList = []
@ -45,15 +47,16 @@ class Placer(Pmw.MegaToplevel):
self.refNodePathDict['camera'] = camera
self.refNodePathNames = ['self', 'render', 'camera', 'selected', 'coa']
# Get initial state
# Initial state
self.initPos = Vec3(0)
self.initHpr = Vec3(0)
self.initScale = Vec3(1)
self.coaPos = Vec3(0)
self.coaHpr = Vec3(0)
# Offset for orbital mode
self.posOffset = Vec3(0)
# Init movement mode
self.movementMode = 'Absolute'
self.movementMode = 'Relative To:'
# Create panel
# Handle to the toplevels hull
@ -69,14 +72,6 @@ class Placer(Pmw.MegaToplevel):
menuBar = Pmw.MenuBar(menuFrame, hotkeys = 1, balloon = balloon)
menuBar.pack(side = LEFT, expand = 1, fill = X)
menuBar.addmenu('Placer', 'Placer Panel Operations')
menuBar.addmenuitem('Placer', 'command',
'Undo Pos/Hpr/Scale',
label = 'Undo',
command = self.undo)
menuBar.addmenuitem('Placer', 'command',
'Redo Pos/Hpr/Scale',
label = 'Redo',
command = self.redo)
menuBar.addmenuitem('Placer', 'command',
'Reset Node Path',
label = 'Reset All',
@ -88,7 +83,7 @@ class Placer(Pmw.MegaToplevel):
menuBar.addmenuitem('Placer', 'command',
'Exit Placer Panel',
label = 'Exit',
command = self.destroy)
command = self.preDestroy)
menuBar.addmenu('Help', 'Placer Panel Help Operations')
self.toggleBalloonVar = IntVar()
@ -112,7 +107,9 @@ class Placer(Pmw.MegaToplevel):
self.nodePathMenu.pack(side = 'left', expand = 0)
modeMenu = Pmw.OptionMenu(menuFrame,
items = ('Absolute', 'Relative To:'),
items = ('Absolute', 'Relative To:',
'Orbit:'),
initialitem = 'Relative To:',
command = self.setMovementMode,
menubutton_width = 8)
modeMenu.pack(side = 'left', expand = 0)
@ -127,9 +124,11 @@ class Placer(Pmw.MegaToplevel):
self.refNodePathMenu.pack(side = 'left', expand = 0)
self.undoButton = Button(menuFrame, text = 'Undo',
state = 'disabled',
command = self.undo)
self.undoButton.pack(side = 'left', expand = 0)
self.redoButton = Button(menuFrame, text = 'Redo',
state = 'disabled',
command = self.redo)
self.redoButton.pack(side = 'left', expand = 0)
@ -162,6 +161,8 @@ class Placer(Pmw.MegaToplevel):
self.posX['command'] = self.xform
self.posX['commandData'] = ['x']
self.posX['callbackData'] = ['x']
self.posX.onReturn = self.pushUndo
self.posX.onReturnRelease = self.xformStop
self.posX.onPress = self.xformStart
self.posX.onRelease = self.xformStop
self.posX.pack(expand=1,fill='x')
@ -174,6 +175,8 @@ class Placer(Pmw.MegaToplevel):
self.posY['command'] = self.xform
self.posY['commandData'] = ['y']
self.posY['callbackData'] = ['y']
self.posY.onReturn = self.pushUndo
self.posY.onReturnRelease = self.xformStop
self.posY.onPress = self.xformStart
self.posY.onRelease = self.xformStop
self.posY.pack(expand=1,fill='x')
@ -186,6 +189,8 @@ class Placer(Pmw.MegaToplevel):
self.posZ['command'] = self.xform
self.posZ['commandData'] = ['z']
self.posZ['callbackData'] = ['z']
self.posZ.onReturn = self.pushUndo
self.posZ.onReturnRelease = self.xformStop
self.posZ.onPress = self.xformStart
self.posZ.onRelease = self.xformStop
self.posZ.pack(expand=1,fill='x')
@ -215,6 +220,8 @@ class Placer(Pmw.MegaToplevel):
self.hprH['command'] = self.xform
self.hprH['commandData'] = ['h']
self.hprH['callbackData'] = ['h']
self.hprH.onReturn = self.pushUndo
self.hprH.onReturnRelease = self.xformStop
self.hprH.onPress = self.xformStart
self.hprH.onRelease = self.xformStop
self.hprH.pack(expand=1,fill='x')
@ -228,6 +235,8 @@ class Placer(Pmw.MegaToplevel):
self.hprP['command'] = self.xform
self.hprP['commandData'] = ['p']
self.hprP['callbackData'] = ['p']
self.hprP.onReturn = self.pushUndo
self.hprP.onReturnRelease = self.xformStop
self.hprP.onPress = self.xformStart
self.hprP.onRelease = self.xformStop
self.hprP.pack(expand=1,fill='x')
@ -241,6 +250,8 @@ class Placer(Pmw.MegaToplevel):
self.hprR['command'] = self.xform
self.hprR['commandData'] = ['r']
self.hprR['callbackData'] = ['r']
self.hprR.onReturn = self.pushUndo
self.hprR.onReturnRelease = self.xformStop
self.hprR.onPress = self.xformStart
self.hprR.onRelease = self.xformStop
self.hprR.pack(expand=1,fill='x')
@ -285,6 +296,8 @@ class Placer(Pmw.MegaToplevel):
self.scaleX['command'] = self.xform
self.scaleX['commandData'] = ['sx']
self.scaleX['callbackData'] = ['sx']
self.scaleX.onReturn = self.pushUndo
self.scaleX.onReturnRelease = self.xformStop
self.scaleX.onPress = self.xformStart
self.scaleX.onRelease = self.xformStop
self.scaleX.pack(expand=1,fill='x')
@ -297,6 +310,8 @@ class Placer(Pmw.MegaToplevel):
self.scaleY['command'] = self.xform
self.scaleY['commandData'] = ['sy']
self.scaleY['callbackData'] = ['sy']
self.scaleY.onReturn = self.pushUndo
self.scaleY.onReturnRelease = self.xformStop
self.scaleY.onPress = self.xformStart
self.scaleY.onRelease = self.xformStop
self.scaleY.pack(expand=1,fill='x')
@ -309,12 +324,14 @@ class Placer(Pmw.MegaToplevel):
self.scaleZ['command'] = self.xform
self.scaleZ['commandData'] = ['sz']
self.scaleZ['callbackData'] = ['sz']
self.scaleZ.onReturn = self.pushUndo
self.scaleZ.onReturnRelease = self.xformStop
self.scaleZ.onPress = self.xformStart
self.scaleZ.onRelease = self.xformStop
self.scaleZ.pack(expand=1,fill='x')
# Make sure appropriate labels are showing
self.setMovementMode('Absolute')
self.setMovementMode('Relative To:')
# Set up placer for inital node path
self.selectNodePathNamed('init')
@ -325,21 +342,19 @@ class Placer(Pmw.MegaToplevel):
# Set prefix
namePrefix = ''
self.movementMode = movementMode
if (movementMode == 'Drive'):
namePrefix = 'Drive delta '
elif (movementMode == 'Orbit'):
namePrefix = 'Orbit '
elif (movementMode == 'Absolute'):
if (movementMode == 'Absolute'):
namePrefix = 'Absolute '
elif (movementMode == 'Relative To:'):
namePrefix = 'Relative '
elif (movementMode == 'Orbit'):
namePrefix = 'Orbit'
# Enable/disable wrt menu
if(movementMode == 'Relative To:'):
self.refNodePathMenu.configure(entry_foreground = 'Black')
self.refNodePathMenu.configure(entry_background = 'SystemWindow')
else:
if (movementMode == 'Absolute'):
self.refNodePathMenu.configure(entry_foreground = 'gray50')
self.refNodePathMenu.configure(entry_background = '#E0E0E0')
else:
self.refNodePathMenu.configure(entry_foreground = 'Black')
self.refNodePathMenu.configure(entry_background = 'SystemWindow')
# Update pos widgets
self.posX['text'] = namePrefix + 'X'
self.posY['text'] = namePrefix + 'Y'
@ -400,21 +415,15 @@ class Placer(Pmw.MegaToplevel):
nodePath = None
if name == 'self':
nodePath = self.tempCS
self.coaPos.set(0,0,0)
self.coaHpr.set(0,0,0)
elif name == 'selected':
nodePath = direct.selected.last
# Add Combo box entry for this selected object
self.addRefNodePath(nodePath)
elif name == 'coa':
nodePath = self.tempCS
if direct.selected.last:
decomposeMatrix(direct.selected.last.mCoa2Dnp,
VBase3(0), self.coaHpr, self.coaPos,
CSDefault)
nodePath = self.tempCS
else:
self.coaPos.set(0,0,0)
self.coaHpr.set(0,0,0)
nodePath = None
else:
nodePath = self.refNodePathDict.get(name, None)
if (nodePath == None):
@ -480,12 +489,16 @@ class Placer(Pmw.MegaToplevel):
np = self['nodePath']
if (np != None) & isinstance(np, NodePath):
# Update temp CS
self.updateTempCS()
self.updateAuxiliaryCoordinateSystems()
# Update widgets
if self.movementMode == 'Absolute':
pos.assign(np.getPos())
hpr.assign(np.getHpr())
scale.assign(np.getScale())
elif self.movementMode == 'Orbit:':
pos.assign(self.posOffset)
hpr.assign(ZERO_VEC)
scale.assign(np.getScale())
elif self.refCS:
pos.assign(np.getPos(self.refCS))
hpr.assign(np.getHpr(self.refCS))
@ -494,9 +507,26 @@ class Placer(Pmw.MegaToplevel):
self.updateHprWidgets(hpr)
self.updateScaleWidgets(scale)
def updateTempCS(self):
self.tempCS.setPosHpr(self['nodePath'], 0,0,0,0,0,0)
# MRM: How to handle COA here?
def updateAuxiliaryCoordinateSystems(self):
# Temp CS
if ((self.refNodePathMenuEntry.get() == 'coa') &
(direct.selected.last != None)):
pos = Vec3(0)
hpr = Vec3(0)
decomposeMatrix(direct.selected.last.mCoa2Dnp,
VBase3(0), hpr, pos, CSDefault)
self.tempCS.setPosHpr(direct.selected.last, pos, hpr)
else:
self.tempCS.setPosHpr(self['nodePath'], 0,0,0,0,0,0)
# Orbit CS
# At reference
self.orbitFromCS.setPos(self.refCS, 0,0,0)
# But aligned with target
self.orbitFromCS.setHpr(self['nodePath'], 0,0,0)
# Also update to CS
self.orbitToCS.setPosHpr(self.orbitFromCS, 0,0,0,0,0,0)
# Get offset from origin
self.posOffset.assign(self['nodePath'].getPos(self.orbitFromCS))
def xform(self, value, axis):
if axis in ['sx', 'sy', 'sz']:
@ -505,6 +535,8 @@ class Placer(Pmw.MegaToplevel):
self.xformAbsolute(value, axis)
elif self.movementMode == 'Relative To:':
self.xformRelative(value, axis)
elif self.movementMode == 'Orbit:':
self.xformOrbit(value, axis)
def xformStart(self, data):
# Record undo point
@ -514,8 +546,11 @@ class Placer(Pmw.MegaToplevel):
self.updatePlacer()
def xformStop(self, data):
# Throw event to signal manipulation done
messenger.send('manipulateObjectCleanup')
# Update placer to reflect new state
self.updatePlacer()
def xformAbsolute(self, value, axis):
nodePath = self['nodePath']
@ -549,6 +584,24 @@ class Placer(Pmw.MegaToplevel):
elif axis == 'r':
nodePath.setR(self.refCS, value)
def xformOrbit(self, value, axis):
nodePath = self['nodePath']
if ((nodePath != None) & (self.refCS != None) &
(self.orbitFromCS != None) & (self.orbitToCS != None)):
if axis == 'x':
self.posOffset.setX(value)
elif axis == 'y':
self.posOffset.setY(value)
elif axis == 'z':
self.posOffset.setZ(value)
elif axis == 'h':
self.orbitToCS.setH(self.orbitFromCS, value)
elif axis == 'p':
self.orbitToCS.setP(self.orbitFromCS, value)
elif axis == 'r':
self.orbitToCS.setR(self.orbitFromCS, value)
nodePath.setPosHpr(self.orbitToCS, self.posOffset, ZERO_VEC)
def xformScale(self, value, axis):
if self['nodePath']:
mode = self.scalingMode.get()
@ -619,7 +672,7 @@ class Placer(Pmw.MegaToplevel):
self['nodePath'].setScale(self.initScale)
self.updatePlacer()
def pushUndo(self):
def pushUndo(self, fResetRedo = 1):
nodePath = self['nodePath']
if nodePath != None:
name = self.nodePathMenuEntry.get()
@ -627,12 +680,20 @@ class Placer(Pmw.MegaToplevel):
hpr = nodePath.getHpr()
scale = nodePath.getScale()
self.undoList.append([name, pos,hpr,scale])
# Make sure button is reactivated
self.undoButton.configure(state = 'normal')
if fResetRedo:
self.redoList = []
self.redoButton.configure(state = 'disabled')
def popUndo(self):
# Get last item
pose = self.undoList[-1]
# Strip last item off of undo list
self.undoList = self.undoList[:-1]
# Update state of undo button
if not self.undoList:
self.undoButton.configure(state = 'disabled')
# Return last item
return pose
@ -644,12 +705,17 @@ class Placer(Pmw.MegaToplevel):
hpr = nodePath.getHpr()
scale = nodePath.getScale()
self.redoList.append([name, pos,hpr,scale])
# Make sure button is reactivated
self.redoButton.configure(state = 'normal')
def popRedo(self):
# Get last item
pose = self.redoList[-1]
# Strip last item off of redo list
self.redoList = self.redoList[:-1]
# Update state of redo button
if not self.redoList:
self.redoButton.configure(state = 'disabled')
# Return last item
return pose
@ -677,15 +743,35 @@ class Placer(Pmw.MegaToplevel):
# Make sure combo box is showing the right thing
self.nodePathMenu.selectitem(pose[0])
# Record active's current state on redo stack
self.pushUndo()
self.pushUndo(fResetRedo = 0)
# Redo xform
self['nodePath'].setPosHprScale(pose[1], pose[2], pose[3])
# Reflect new changes
self.updatePlacer()
def printNodePathInfo(self):
print 'Print Node Path info here'
np = self['nodePath']
if np:
name = np.getName()
pos = np.getPos()
hpr = np.getHpr()
scale = np.getScale()
posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2])
hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2])
scaleString = '%.2f, %.2f, %.2f' % (scale[0], scale[1], scale[2])
print 'NodePath: %s' % name
print 'Pos: %s' % posString
print 'Hpr: %s' % hprString
print 'Scale: %s' % scaleString
print ('%s.setPosHprScale(%s, %s, %s)' %
(name, posString, hprString, scaleString))
def preDestroy(self):
self.tempCS.removeNode()
self.orbitFromCS.removeNode()
self.orbitToCS.removeNode()
self.destroy()
def toggleBalloon(self):
if self.toggleBalloonVar.get():
self.balloon.configure(state = 'balloon')

View File

@ -281,8 +281,10 @@ class Dial(Pmw.MegaWidget):
input = self._entryVal.get()
try:
newValue = string.atof(input)
apply(self.onReturn, self['callbackData'])
self.set(newValue)
self._entry.configure(background = self._entryBackground)
apply(self.onReturnRelease, self['callbackData'])
except ValueError:
self._entry.configure(background = 'Pink')
@ -440,6 +442,14 @@ class Dial(Pmw.MegaWidget):
# Should we do this?
self.setScaleFactorExp(0, showText = 0)
def onReturn(self, *args):
""" User redefinable callback executed on <Return> in entry """
pass
def onReturnRelease(self, *args):
""" User redefinable callback executed on <Return> release in entry """
pass
def onPress(self, *args):
""" User redefinable callback executed on button press """
pass

View File

@ -1,10 +1,11 @@
"""
EntryScale Class: Scale with a label, and a linked and validated entry
"""
from PandaObject import *
from Tkinter import *
import Pmw
import string
import tkColorChooser
from tkSimpleDialog import askfloat
class EntryScale(Pmw.MegaWidget):
@ -235,6 +236,8 @@ class EntryScaleGroup(Pmw.MegaToplevel):
('command', None, None),
# A tuple of labels, one for each entryScale
('labels', DEFAULT_LABELS, self._updateLabels),
# Destroy or withdraw
('fDestroy', 0, INITOPT)
)
self.defineoptions(kw, optiondefs)
@ -259,9 +262,13 @@ class EntryScaleGroup(Pmw.MegaToplevel):
'EntryScale Group', 'command', 'Reset the EntryScale Group panel',
label = 'Reset',
command = lambda s = self: s.reset())
if self['fDestroy']:
dismissCommand = self.destroy
else:
dismissCommand = self.withdraw
menubar.addmenuitem(
'EntryScale Group', 'command', 'Dismiss EntryScale Group panel',
label = 'Dismiss', command = self.withdraw)
label = 'Dismiss', command = dismissCommand)
menubar.addmenu('Help', 'EntryScale Group Help Operations')
self.toggleBalloonVar = IntVar()
@ -331,6 +338,42 @@ class EntryScaleGroup(Pmw.MegaToplevel):
self.set(self['initialValue'])
def setColor(nodePath, callback = None):
def setNodePathColor(color, np = nodePath, cb = callback):
np.setColor(color[0]/255.0, color[1]/255.0,
color[2]/255.0, color[3]/255.0)
# Execute callback to pass along color info
if cb:
cb(color)
def popupColorPicker():
# Can pass in current color with: color = (255, 0, 0)
color = tkColorChooser.askcolor(
parent = esg.interior(),
# Initialize it to current color
initialcolor = tuple(esg.get()[:3]))[0]
if color:
esg.set((color[0], color[1], color[2], esg.getAt(3)))
if isinstance(nodePath, NodePath):
if nodePath.hasColor():
initColor = nodePath.getColor() * 255.0
else:
initColor = Vec4(255)
esg = EntryScaleGroup(title = 'RGBA Panel',
dim = 4,
labels = ['R','G','B','A'],
initialValue = [int(initColor[0]),
int(initColor[1]),
int(initColor[2]),
int(initColor[3])],
Valuator_max = 255,
Valuator_resolution = 1,
# Destroy not withdraw panel on dismiss
fDestroy = 1,
command = setNodePathColor)
menu = esg.component('menubar').component('EntryScale Group-menu')
menu.insert_command(index = 1, label = 'Popup Color Picker',
command = popupColorPicker)
return esg
## SAMPLE CODE
if __name__ == '__main__':

View File

@ -149,7 +149,9 @@ class Floater(Pmw.MegaWidget):
def _entryCommand(self, event = None):
try:
val = string.atof( self.entryValue.get() )
apply(self.onReturn,self['callbackData'])
self.set( val )
apply(self.onReturnRelease,self['callbackData'])
except ValueError:
pass
@ -187,6 +189,14 @@ class Floater(Pmw.MegaWidget):
def reset(self):
self.set(self['initialValue'])
def onReturn(self, *args):
""" User redefinable callback executed on <Return> in entry """
pass
def onReturnRelease(self, *args):
""" User redefinable callback executed on <Return> release in entry """
pass
def onPress(self, *args):
""" User redefinable callback executed on button press """
pass