2022-12-16 18:40:57 -06:00
from panda3d . core import Point3 , Vec3 , VBase3
2019-11-02 17:27:54 -05:00
from direct . tkwidgets . AppShell import *
from direct . showbase . TkGlobal import *
from direct . tkwidgets . Tree import *
from direct . tkwidgets import Slider , Floater
2019-12-30 00:07:56 -06:00
from tkinter . simpledialog import askstring
from tkinter . messagebox import showwarning , askyesno
from tkinter import *
2019-11-02 17:27:54 -05:00
from direct . showbase . PythonUtil import Functor , list2dict
from direct . gui . DirectGui import DGG
2019-12-30 00:07:56 -06:00
import tkinter . filedialog
2019-11-02 17:27:54 -05:00
from direct . showbase import DirectObject
import math
import operator
from direct . tkwidgets import Valuator
from direct . tkwidgets import VectorWidgets
from otp . level import LevelConstants
from direct . directtools import DirectSession
import Pmw
class InGameEditor ( AppShell ) :
appname = ' In-Game Editor '
frameWidth = 900
frameHeight = 475
usecommandarea = 1
usestatusarea = 1
contactname = ' Darren Ranalli '
contactphone = ' (818) 623-3904 '
contactemail = ' darren.ranalli@disney.com '
WantUndo = False
def __init__ ( self , level , doneEvent , requestSaveEvent , saveAsEvent , undoEvent , redoEvent , wireframeEvent , oobeEvent , csEvent , runEvent , texEvent , * * kw ) :
DGG . INITOPT = Pmw . INITOPT
optiondefs = ( ( ' title ' , ' In-Game ' + level . getName ( ) + ' Editor ' , None ) , )
self . defineoptions ( kw , optiondefs )
self . level = level
self . doneEvent = doneEvent
self . requestSaveEvent = requestSaveEvent
self . saveAsEvent = saveAsEvent
self . undoEvent = undoEvent
self . redoEvent = redoEvent
self . wireframeEvent = wireframeEvent
self . oobeEvent = oobeEvent
self . csEvent = csEvent
self . runEvent = runEvent
self . texEvent = texEvent
self . entityCopy = None
self . curEntId = None
self . curEntWidgets = { }
self . visZonesEditor = None
AppShell . __init__ ( self )
self . initialiseoptions ( self . __class__ )
self . accept ( self . level . getAttribChangeEventName ( ) , self . handleAttribChange )
self . accept ( ' DIRECT_selectedNodePath ' , self . selectedNodePathHook )
self . accept ( ' DIRECT_manipulateObjectCleanup ' , self . manipCleanupHook )
self . accept ( ' DIRECT_undo ' , self . manipCleanupHook )
self . accept ( ' DIRECT_redo ' , self . manipCleanupHook )
return
def getEventMsgName ( self , event ) :
return ' InGameEditor %s _ %s ' % ( self . level . getLevelId ( ) , event )
def getEntityName ( self , entId ) :
return self . level . levelSpec . getEntitySpec ( entId ) [ ' name ' ]
def appInit ( self ) :
from direct . directtools import DirectSession
direct . enableLight ( )
direct . disable ( )
bboard . post ( DirectSession . DirectSession . DIRECTdisablePost )
def createMenuBar ( self ) :
menuBar = self . menuBar
menuBar . addmenuitem ( ' File ' , ' command ' , ' Save the level spec on the AI ' , label = ' Save on AI ' , command = self . handleRequestSave )
menuBar . addmenuitem ( ' File ' , ' command ' , ' Save the level spec locally ' , label = ' Save Locally As... ' , command = self . handleSaveAs )
menuBar . addmenuitem ( ' File ' , ' separator ' )
menuBar . addmenuitem ( ' File ' , ' command ' , ' Export a single entity ' , label = ' Export Entity... ' , command = self . level . handleExportEntity )
menuBar . addmenuitem ( ' File ' , ' command ' , ' Export a tree of entities ' , label = ' Export Entity Tree... ' , command = self . level . handleExportEntityTree )
menuBar . addmenuitem ( ' File ' , ' separator ' )
menuBar . addmenuitem ( ' File ' , ' command ' , ' Import a tree of entities ' , label = ' Import Entities... ' , command = self . level . handleImportEntities )
menuBar . addmenuitem ( ' File ' , ' separator ' )
if InGameEditor . WantUndo :
menuBar . addmenu ( ' Edit ' , ' Edit Operations ' )
menuBar . addmenuitem ( ' Edit ' , ' command ' , ' Undo the last edit ' , label = ' Undo ' , command = self . doUndo )
menuBar . addmenuitem ( ' Edit ' , ' command ' , ' Redo the last undo ' , label = ' Redo ' , command = self . doRedo )
menuBar . addmenu ( ' Entity ' , ' Entity Operations ' )
menuBar . addmenuitem ( ' Entity ' , ' command ' , ' Duplicate Selected Entity ' , label = ' Duplicate Selected Entity ' , command = self . level . duplicateSelectedEntity )
menuBar . addmenuitem ( ' Entity ' , ' separator ' )
permanentTypes = self . level . entTypeReg . getPermanentTypeNames ( )
entTypes = list ( self . level . entTypes )
2019-12-30 20:38:26 -06:00
for permanentType in permanentTypes :
entTypes . remove ( permanentType )
2019-11-02 17:27:54 -05:00
entTypes . sort ( )
numEntities = len ( entTypes )
cascadeMenu = ' '
for index in range ( numEntities ) :
type = entTypes [ index ]
if index % 10 == 0 :
lastIndex = min ( index + 9 , numEntities - 1 )
cascadeMenu = ' %s -> %s ' % ( entTypes [ index ] , entTypes [ lastIndex ] )
menuBar . addcascademenu ( ' Entity ' , cascadeMenu )
def doInsert ( self = self , type = type ) :
self . level . insertEntity ( type )
self . explorer . update ( fUseCachedChildren = 0 )
menuBar . addmenuitem ( cascadeMenu , ' command ' , ' Insert %s ' % type , label = ' Insert %s ' % type , command = doInsert )
menuBar . addmenuitem ( ' Entity ' , ' separator ' )
menuBar . addmenuitem ( ' Entity ' , ' command ' , ' Remove Selected Entity ' , label = ' Remove Selected Entity ' , command = self . removeSelectedEntity )
menuBar . addmenuitem ( ' Entity ' , ' command ' , ' Remove Selected EntityTree ' , label = ' Remove Selected Entity Tree ' , command = self . removeSelectedEntityTree )
menuBar . addmenuitem ( ' Entity ' , ' separator ' )
menuBar . addmenuitem ( ' Entity ' , ' command ' , ' Go To Selected Entity ' , label = ' Go To Selected Entity ' , command = self . level . moveAvToSelected )
menuBar . addmenuitem ( ' Entity ' , ' command ' , ' Refresh Entity Explorer ' , label = ' Refresh Entity Explorer ' , command = self . refreshExplorer )
self . menuBar . addmenu ( ' DIRECT ' , ' Direct Session Panel Operations ' )
self . menuBar . addmenuitem ( ' DIRECT ' , ' checkbutton ' , ' DIRECT Enabled ' , label = ' Enable ' , variable = direct . panel . directEnabled , command = direct . panel . toggleDirect )
self . menuBar . addmenuitem ( ' DIRECT ' , ' checkbutton ' , ' DIRECT Grid Enabled ' , label = ' Enable Grid ' , variable = direct . panel . directGridEnabled , command = direct . panel . toggleDirectGrid )
self . menuBar . addmenuitem ( ' DIRECT ' , ' command ' , ' Toggle Object Handles Visability ' , label = ' Toggle Widget Viz ' , command = direct . toggleWidgetVis )
self . menuBar . addmenuitem ( ' DIRECT ' , ' command ' , ' Toggle Widget Move/COA Mode ' , label = ' Toggle Widget Mode ' , command = direct . manipulationControl . toggleObjectHandlesMode )
self . menuBar . addmenuitem ( ' DIRECT ' , ' checkbutton ' , ' DIRECT Widget On Top ' , label = ' Widget On Top ' , variable = direct . panel . directWidgetOnTop , command = direct . panel . toggleWidgetOnTop )
self . menuBar . addmenuitem ( ' DIRECT ' , ' command ' , ' Deselect All ' , label = ' Deselect All ' , command = direct . deselectAll )
if InGameEditor . WantUndo :
undoFrame = Frame ( self . menuFrame )
self . redoButton = Button ( undoFrame , text = ' Redo ' , command = self . doRedo )
self . redoButton . pack ( side = RIGHT , expand = 0 )
self . undoButton = Button ( undoFrame , text = ' Undo ' , command = self . doUndo )
self . undoButton . pack ( side = RIGHT , expand = 0 )
undoFrame . pack ( side = RIGHT , expand = 0 )
toggleFrame = Frame ( self . menuFrame )
self . wireframeButton = Button ( toggleFrame , text = ' Wire ' , command = self . doWireframe )
self . wireframeButton . pack ( side = RIGHT , expand = 0 )
self . texButton = Button ( toggleFrame , text = ' Tex ' , command = self . doTex )
self . texButton . pack ( side = RIGHT , expand = 0 )
self . csButton = Button ( toggleFrame , text = ' Cs ' , command = self . doCs )
self . csButton . pack ( side = RIGHT , expand = 0 )
self . runButton = Button ( toggleFrame , text = ' Run ' , command = self . doRun )
self . runButton . pack ( side = RIGHT , expand = 0 )
self . oobeButton = Button ( toggleFrame , text = ' Oobe ' , command = self . doOobe )
self . oobeButton . pack ( side = RIGHT , expand = 0 )
toggleFrame . pack ( side = RIGHT , expand = 0 , padx = 5 )
AppShell . createMenuBar ( self )
def createInterface ( self ) :
interior = self . interior ( )
mainFrame = Frame ( interior )
self . framePane = Pmw . PanedWidget ( mainFrame , orient = DGG . HORIZONTAL )
self . explorerFrame = self . framePane . add ( ' left ' , min = 250 )
self . widgetFrame = self . framePane . add ( ' right ' , min = 300 )
self . explorer = LevelExplorer ( parent = self . explorerFrame , editor = self )
self . explorer . pack ( fill = BOTH , expand = 1 )
self . explorerFrame . pack ( fill = BOTH , expand = 1 )
self . pageOneFrame = Pmw . ScrolledFrame ( self . widgetFrame , borderframe_relief = GROOVE , horizflex = ' elastic ' )
self . pageOneFrame . pack ( expand = 1 , fill = BOTH )
self . widgetFrame . pack ( fill = BOTH , expand = 1 )
self . framePane . pack ( fill = BOTH , expand = 1 )
mainFrame . pack ( fill = BOTH , expand = 1 )
self . createButtons ( )
self . initialiseoptions ( self . __class__ )
self . attribWidgets = [ ]
def selectedNodePathHook ( self , nodePath ) :
np = nodePath . findNetTag ( ' entity ' )
if not np . isEmpty ( ) :
if np . id ( ) != nodePath . id ( ) :
np . select ( )
else :
self . findEntityFromNP ( np )
def findEntityFromNP ( self , nodePath ) :
entId = self . level . nodePathId2EntId . get ( nodePath . id ( ) )
if entId :
self . selectEntity ( entId )
else :
for entId in self . level . levelSpec . getAllEntIds ( ) :
np = self . level . getEntInstanceNP ( entId )
if np :
if np . id ( ) == nodePath . id ( ) :
self . selectEntity ( entId )
return
def manipCleanupHook ( self , nodePathList ) :
if not nodePathList :
return
entId = self . level . nodePathId2EntId . get ( nodePathList [ 0 ] . id ( ) )
if entId :
t = nodePathList [ 0 ] . getTransform ( )
entSpec = self . level . levelSpec . getEntitySpec ( entId )
entPos = entSpec . get ( ' pos ' )
if entPos and t . getPos ( ) != entPos :
self . level . setAttribEdit ( entId , ' pos ' , Point3 ( t . getPos ( ) ) )
entHpr = entSpec . get ( ' hpr ' )
if entHpr and t . getHpr ( ) != entHpr :
self . level . setAttribEdit ( entId , ' hpr ' , Vec3 ( t . getHpr ( ) ) )
entScale = entSpec . get ( ' scale ' )
if entScale and t . getScale ( ) != entScale :
self . level . setAttribEdit ( entId , ' scale ' , Vec3 ( t . getScale ( ) ) )
def refreshExplorer ( self ) :
self . explorer . update ( )
def selectEntity ( self , entId ) :
node = self . explorer . _node . find ( entId )
if node :
node . reveal ( )
self . explorer . _node . deselecttree ( )
node . select ( )
def removeSelectedEntity ( self ) :
if self . level . selectedEntity :
parentEntId = self . level . selectedEntity . parentEntId
else :
parentEntId = None
if self . level . removeSelectedEntity ( ) != - 1 :
self . explorer . update ( fUseCachedChildren = 0 )
if parentEntId :
self . selectEntity ( parentEntId )
return
def removeSelectedEntityTree ( self ) :
if self . level . selectedEntity :
parentEntId = self . level . selectedEntity . parentEntId
else :
parentEntId = None
if self . level . removeSelectedEntityTree ( ) != - 1 :
self . explorer . update ( fUseCachedChildren = 0 )
if parentEntId :
self . selectEntity ( parentEntId )
return
def clearAttribEditPane ( self ) :
for widg in self . attribWidgets :
widg . destroy ( )
if self . visZonesEditor :
self . visZonesEditor . destroy ( )
self . attribWidgets = [ ]
self . curEntId = None
self . curEntWidgets = { }
self . cbDict = { }
return
def updateEntityCopy ( self , entId ) :
if self . entityCopy == None :
self . entityCopy = self . level . getEntInstanceNPCopy ( entId )
if self . entityCopy is not None :
self . entityCopy . setRenderModeWireframe ( )
self . entityCopy . setTextureOff ( 1 )
self . entityCopy . setColor ( 1 , 0 , 0 )
return
def updateAttribEditPane ( self , entId , levelSpec , entTypeReg ) :
self . clearAttribEditPane ( )
self . curEntId = entId
widgetSetter = None
entSpec = levelSpec . getEntitySpec ( entId )
typeDesc = entTypeReg . getTypeDesc ( entSpec [ ' type ' ] )
attribNames = typeDesc . getAttribNames ( )
attribDescs = typeDesc . getAttribDescDict ( )
for attribName in attribNames :
desc = attribDescs [ attribName ]
params = desc . getParams ( )
datatype = desc . getDatatype ( )
if datatype == ' int ' :
self . addIntWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' float ' :
self . addFloatWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' bool ' :
self . addBoolWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' choice ' :
self . addChoiceWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' multiChoice ' :
self . addMultiChoiceWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype in [ ' pos ' , ' hpr ' , ' scale ' ] :
self . addVec3Widget ( levelSpec , entSpec , entId , attribName , params , datatype )
elif datatype == ' color ' :
self . addColorWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' bamfilename ' :
self . addFileWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' visZoneList ' :
self . addVisZoneWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' entId ' :
self . addEntIdWidget ( levelSpec , entSpec , entId , attribName , params , entTypeReg )
elif datatype == ' string ' :
self . addStringWidget ( levelSpec , entSpec , entId , attribName , params )
elif datatype == ' const ' :
self . addConstWidget ( levelSpec , entSpec , entId , attribName , params )
else :
self . addPythonWidget ( levelSpec , entSpec , entId , attribName , params )
return
def addIntWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
minVal = params . get ( ' min ' , None )
maxVal = params . get ( ' max ' , None )
if minVal is not None and maxVal is not None :
widgClass = Slider . Slider
else :
widgClass = Floater . Floater
widg = widgClass ( self . pageOneFrame . interior ( ) , text = attribName , value = entSpec [ attribName ] , numDigits = 0 , label_width = 15 , label_anchor = W , label_justify = LEFT , label_font = None , min = minVal , max = maxVal , resolution = 1.0 )
def clientIntCommand ( val ) :
entity = self . level . getEntInstance ( entId )
if entity :
entity . handleAttribChange ( attribName , int ( val ) )
def finalIntCommand ( ) :
self . level . setAttribEdit ( entId , attribName , int ( widg . get ( ) ) )
widg [ ' command ' ] = clientIntCommand
widg [ ' postCallback ' ] = finalIntCommand
widg . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( widg )
self . curEntWidgets [ attribName ] = lambda x : widg . set ( x , 0 )
return
def addFloatWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
minVal = params . get ( ' min ' , None )
maxVal = params . get ( ' max ' , None )
widg = Floater . Floater ( self . pageOneFrame . interior ( ) , text = attribName , value = entSpec [ attribName ] , label_width = 15 , label_anchor = W , label_justify = LEFT , label_font = None , min = minVal , max = maxVal )
def clientFloatCommand ( val ) :
entity = self . level . getEntInstance ( entId )
if entity :
entity . handleAttribChange ( attribName , val )
def finalFloatCommand ( ) :
self . level . setAttribEdit ( entId , attribName , widg . get ( ) )
widg [ ' command ' ] = clientFloatCommand
widg [ ' postCallback ' ] = finalFloatCommand
widg . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( widg )
self . curEntWidgets [ attribName ] = lambda x : widg . set ( x , 0 )
return
def addBoolWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
flag = BooleanVar ( )
flag . set ( entSpec [ attribName ] )
def booleanCommand ( booleanVar = flag ) :
self . level . setAttribEdit ( entId , attribName , flag . get ( ) )
frame = Frame ( self . pageOneFrame . interior ( ) )
label = Label ( frame , text = attribName , width = 15 , anchor = W , justify = LEFT )
label . pack ( side = LEFT , expand = 0 )
trueButton = Radiobutton ( frame , text = ' True ' , value = 1 , variable = flag , command = booleanCommand )
trueButton . pack ( side = LEFT , expand = 0 )
falseButton = Radiobutton ( frame , text = ' False ' , value = 0 , variable = flag , command = booleanCommand )
falseButton . pack ( side = LEFT , expand = 0 )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
self . curEntWidgets [ attribName ] = flag . set
def addChoiceWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
if attribName in entSpec :
attributeValue = entSpec . get ( attribName )
else :
typeDesc = self . level . entTypeReg . getTypeDesc ( entSpec [ ' type ' ] )
attribDesc = typeDesc . getAttribDescDict ( ) [ attribName ]
attributeValue = attribDesc . getDefaultValue ( )
valueDict = params . get ( ' valueDict ' , { } )
2019-12-30 00:07:56 -06:00
for key , value in list ( valueDict . items ( ) ) :
2019-11-02 17:27:54 -05:00
if value == attributeValue :
attributeValue = key
break
radioVar = StringVar ( )
radioVar . set ( attributeValue )
def radioCommand ( radioVar = radioVar ) :
value = valueDict . get ( radioVar . get ( ) , radioVar . get ( ) )
self . level . setAttribEdit ( entId , attribName , value )
frame = Frame ( self . pageOneFrame . interior ( ) , relief = GROOVE , borderwidth = 2 )
label = Label ( frame , text = attribName , width = 15 , anchor = W , justify = LEFT )
label . pack ( side = LEFT , expand = 0 )
for choice in params . get ( ' choiceSet ' , [ ] ) :
2020-01-08 20:22:39 -06:00
if type ( choice ) is str :
2019-11-02 17:27:54 -05:00
choiceStr = choice
else :
2019-12-30 00:07:56 -06:00
choiceStr = repr ( choice )
2019-11-02 17:27:54 -05:00
if choiceStr not in valueDict :
valueDict [ choiceStr ] = choice
choiceButton = Radiobutton ( frame , text = choiceStr , value = choiceStr , variable = radioVar , command = radioCommand )
choiceButton . pack ( side = LEFT , expand = 0 )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
def setRadioVar ( attributeValue ) :
2019-12-30 00:07:56 -06:00
for key , value in list ( valueDict . items ( ) ) :
2019-11-02 17:27:54 -05:00
if value == attributeValue :
attributeValue = key
break
radioVar . set ( attributeValue )
self . curEntWidgets [ attribName ] = setRadioVar
def addMultiChoiceWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
frame = Frame ( self . pageOneFrame . interior ( ) , relief = GROOVE , borderwidth = 2 )
label = Label ( frame , text = attribName , width = 15 , anchor = W , justify = LEFT )
label . pack ( side = LEFT , expand = 0 )
valueDict = params . get ( ' valueDict ' , { } )
self . cbDict [ attribName ] = list2dict ( entSpec [ attribName ] , value = 1 )
checkbuttonDict = { }
base . cbButtons = [ ]
base . checkbuttonDict = checkbuttonDict
for choice in params . get ( ' choiceSet ' , [ ] ) :
trueValue = valueDict . get ( choice , choice )
cbVar = IntVar ( )
cbVar . set ( trueValue in self . cbDict [ attribName ] )
checkbuttonDict [ trueValue ] = cbVar
def cbCommand ( var , trueValue = trueValue ) :
vd = self . cbDict [ attribName ]
2019-12-30 00:07:56 -06:00
print ( vd )
2019-11-02 17:27:54 -05:00
if var . get ( ) :
2019-12-30 00:07:56 -06:00
print ( ' got it ' , trueValue , vd )
2019-11-02 17:27:54 -05:00
vd [ trueValue ] = 1
else :
2019-12-30 00:07:56 -06:00
print ( ' not it ' , trueValue , vd )
2019-11-02 17:27:54 -05:00
if trueValue in vd :
del vd [ trueValue ]
2019-12-30 00:07:56 -06:00
value = list ( vd . keys ( ) )
print ( ' SENDING ' , value )
2019-11-02 17:27:54 -05:00
self . level . setAttribEdit ( entId , attribName , value )
2020-01-08 20:22:39 -06:00
if type ( choice ) is str :
2019-11-02 17:27:54 -05:00
labelStr = choice
else :
2019-12-30 00:07:56 -06:00
labelStr = repr ( choice )
2019-11-02 17:27:54 -05:00
func = Functor ( cbCommand , cbVar )
choiceButton = Checkbutton ( frame , text = labelStr , variable = cbVar , command = lambda : func ( ) )
choiceButton . pack ( side = LEFT , expand = 0 )
base . cbButtons . append ( choiceButton )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
def setCheckbuttonVar ( attributeValueList ) :
2019-12-30 00:07:56 -06:00
print ( ' COMING BACK ' , attributeValueList )
for attributeValue , cb in list ( checkbuttonDict . items ( ) ) :
2019-11-02 17:27:54 -05:00
if attributeValue in attributeValueList :
cb . set ( 1 )
else :
cb . set ( 0 )
self . curEntWidgets [ attribName ] = setCheckbuttonVar
def addVec3Widget ( self , levelSpec , entSpec , entId , attribName , params , datatype ) :
def veCommand ( poslist ) :
self . level . setAttribEdit ( entId , attribName , Point3 ( * poslist ) )
vec = entSpec [ attribName ]
if not isinstance ( vec , VBase3 ) :
vec = Vec3 ( vec )
value = [ vec [ 0 ] , vec [ 1 ] , vec [ 2 ] ]
minVal = maxVal = None
if datatype == ' pos ' :
floaterLabels = [ ' x ' , ' y ' , ' z ' ]
floaterType = ' floater '
elif datatype == ' hpr ' :
floaterLabels = [ ' h ' , ' p ' , ' r ' ]
floaterType = ' angledial '
else :
floaterLabels = [ ' sx ' , ' sy ' , ' sz ' ]
floaterType = ' slider '
minVal = 0
maxVal = 1000
widg = VectorWidgets . VectorEntry ( self . pageOneFrame . interior ( ) , text = attribName , value = value , type = floaterType , bd = 0 , relief = None , min = minVal , max = maxVal , label_justify = LEFT , label_anchor = W , label_width = 14 , label_bd = 0 , labelIpadx = 0 , floaterGroup_labels = floaterLabels )
widg [ ' command ' ] = veCommand
widg . pack ( fill = X , expand = 1 )
if attribName in ( ' pos ' , ' hpr ' , ' scale ' ) :
def placeEntity ( ) :
selectedEntityNP = self . level . getEntInstanceNP ( entId )
if selectedEntityNP is not None :
selectedEntityNP . place ( )
return
widg . menu . add_command ( label = ' Place... ' , command = placeEntity )
def adjustCopy ( vec ) :
self . updateEntityCopy ( entId )
if self . entityCopy is not None :
if datatype == ' pos ' :
self . entityCopy . setPos ( vec [ 0 ] , vec [ 1 ] , vec [ 2 ] )
elif datatype == ' hpr ' :
self . entityCopy . setHpr ( vec [ 0 ] , vec [ 1 ] , vec [ 2 ] )
elif datatype == ' scale ' :
self . entityCopy . setScale ( vec [ 0 ] , vec [ 1 ] , vec [ 2 ] )
widg . set ( vec , 0 )
return
widg . _floaters [ ' command ' ] = adjustCopy
widg . _floaters . component ( ' valuatorGroup ' ) [ ' postCallback ' ] = lambda x , y , z : veCommand ( [ x , y , z ] )
self . attribWidgets . append ( widg )
self . curEntWidgets [ attribName ] = lambda x : widg . set ( x , 0 )
return
def addColorWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
def veCommand ( colorlist ) :
self . level . setAttribEdit ( entId , attribName , Vec4 ( * colorlist ) / 255.0 )
vec = entSpec [ attribName ]
value = [ vec [ 0 ] * 255.0 ,
vec [ 1 ] * 255.0 ,
vec [ 2 ] * 255.0 ,
vec [ 3 ] * 255.0 ]
floaterLabels = [ ' r ' ,
' g ' ,
' b ' ,
' a ' ]
widg = VectorWidgets . ColorEntry ( self . pageOneFrame . interior ( ) , text = attribName , type = ' slider ' , relief = None , bd = 0 , label_justify = LEFT , label_anchor = W , label_width = 14 , label_bd = 0 , labelIpadx = 0 , floaterGroup_labels = floaterLabels , value = value , floaterGroup_value = value )
widg [ ' command ' ] = veCommand
widg . pack ( fill = X , expand = 1 )
def adjustEntity ( vec ) :
entity = self . level . getEntInstance ( entId )
if entity is not None :
entity . setColor ( vec [ 0 ] / 255.0 , vec [ 1 ] / 255.0 , vec [ 2 ] / 255.0 , vec [ 3 ] / 255.0 )
widg . set ( vec , 0 )
return
widg . _floaters [ ' command ' ] = adjustEntity
widg . _floaters . component ( ' valuatorGroup ' ) [ ' postCallback ' ] = lambda x , y , z , a : veCommand ( [ x ,
y ,
z ,
a ] )
self . attribWidgets . append ( widg )
self . curEntWidgets [ attribName ] = lambda x : widg . set ( x * 255.0 , 0 )
return
def addFileWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
text = StringVar ( )
text . set ( repr ( entSpec [ attribName ] ) )
def handleReturn ( event ) :
self . handleAttributeChangeSubmit ( attribName , text , entId , levelSpec )
def askFilename ( callback = handleReturn ) :
if text . get ( ) == ' None ' :
initialDir = Filename . expandFrom ( ' $TTMODELS/built/ ' ) . toOsSpecific ( )
else :
initialDir = Filename . expandFrom ( ' $TTMODELS/built/ %s ' % text . get ( ) [ 1 : - 1 ] ) . toOsSpecific ( )
2019-12-30 00:07:56 -06:00
print ( text , text . get ( ) [ 1 : - 1 ] , initialDir )
2019-11-02 17:27:54 -05:00
rawFilename = askopenfilename ( defaultextension = ' * ' , initialdir = initialDir , filetypes = ( ( ' Bam Files ' , ' *.bam ' ) ,
( ' Egg Files ' , ' *.egg ' ) ,
( ' Maya Binaries ' , ' *.mb ' ) ,
( ' All files ' , ' * ' ) ) , title = ' Load Model File ' , parent = self . interior ( ) )
if rawFilename != ' ' :
filename = Filename . fromOsSpecific ( rawFilename )
filename . findOnSearchpath ( getModelPath ( ) . getValue ( ) )
2019-12-30 00:07:56 -06:00
text . set ( " ' %s ' " % repr ( filename ) )
2019-11-02 17:27:54 -05:00
handleReturn ( None )
return
frame = Frame ( self . pageOneFrame . interior ( ) )
label = Button ( frame , text = attribName , width = 14 , borderwidth = 0 , anchor = W , justify = LEFT )
label [ ' command ' ] = askFilename
label . pack ( side = LEFT , expand = 0 )
def enterWidget ( event , widg = label ) :
widg [ ' background ' ] = ' #909090 '
def leaveWidget ( event , widg = label ) :
widg [ ' background ' ] = ' SystemButtonFace '
label . bind ( ' <Enter> ' , enterWidget )
label . bind ( ' <Leave> ' , leaveWidget )
widg = Entry ( frame , textvariable = text )
widg . bind ( ' <Return> ' , handleReturn )
widg . pack ( side = LEFT , fill = X , expand = 1 )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
self . curEntWidgets [ attribName ] = lambda x : text . set ( repr ( x ) )
def addVisZoneWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
text = StringVar ( )
text . set ( repr ( entSpec [ attribName ] ) )
def handleReturn ( event ) :
self . handleAttributeChangeSubmit ( attribName , text , entId , levelSpec )
def handleUpdate ( visZoneList ) :
self . level . setAttribEdit ( entId , attribName , visZoneList )
def getZoneList ( callback = handleReturn ) :
zoneEntIds = list ( self . level . entType2ids [ ' zone ' ] )
zoneEntIds . remove ( LevelConstants . UberZoneEntId )
zoneEntIds . sort ( )
self . visZonesEditor = LevelVisZonesEditor ( self , entId , entSpec [ attribName ] , modelZones = zoneEntIds , updateCommand = handleUpdate )
frame = Frame ( self . pageOneFrame . interior ( ) )
label = Button ( frame , text = attribName , width = 14 , borderwidth = 0 , anchor = W , justify = LEFT )
label [ ' command ' ] = getZoneList
label . pack ( side = LEFT , expand = 0 )
def enterWidget ( event , widg = label ) :
widg [ ' background ' ] = ' #909090 '
def leaveWidget ( event , widg = label ) :
widg [ ' background ' ] = ' SystemButtonFace '
label . bind ( ' <Enter> ' , enterWidget )
label . bind ( ' <Leave> ' , leaveWidget )
widg = Entry ( frame , textvariable = text )
widg . bind ( ' <Return> ' , handleReturn )
widg . pack ( side = LEFT , fill = X , expand = 1 )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
def refreshWidget ( visZoneList ) :
text . set ( repr ( visZoneList ) )
if self . visZonesEditor :
self . visZonesEditor . setVisible ( visZoneList )
self . curEntWidgets [ attribName ] = refreshWidget
def addEntIdWidget ( self , levelSpec , entSpec , entId , attribName , params , entTypeReg ) :
text = StringVar ( )
text . set ( repr ( entSpec [ attribName ] ) )
def handleReturn ( event ) :
self . handleAttributeChangeSubmit ( attribName , text , entId , levelSpec )
def handleMenu ( id ) :
text . set ( id )
self . level . setAttribEdit ( entId , attribName , id )
frame = Frame ( self . pageOneFrame . interior ( ) )
label = Label ( frame , text = attribName , width = 15 , anchor = W , justify = LEFT )
label . pack ( side = LEFT , expand = 0 )
widg = Entry ( frame , textvariable = text )
widg . bind ( ' <Return> ' , handleReturn )
widg . pack ( side = LEFT , fill = X , expand = 1 )
if attribName is ' parentEntId ' :
buttonText = ' Reparent To '
else :
buttonText = ' Select Entity '
entButton = Menubutton ( frame , width = 8 , text = buttonText , relief = RAISED , borderwidth = 2 )
entMenu = Menu ( entButton , tearoff = 0 )
entButton [ ' menu ' ] = entMenu
entButton . pack ( side = LEFT , fill = ' x ' , expand = 1 )
entType = params . get ( ' type ' )
entOutput = params . get ( ' output ' )
idDict = { }
if entType == ' grid ' :
for eType in entTypeReg . getDerivedTypeNames ( ' grid ' ) :
idDict [ eType ] = self . level . entType2ids . get ( eType , [ ] )
elif entType == ' nodepath ' :
for eType in entTypeReg . getDerivedTypeNames ( ' nodepath ' ) :
idDict [ eType ] = self . level . entType2ids . get ( eType , [ ] )
elif entOutput == ' bool ' :
for eType in entTypeReg . getTypeNamesFromOutputType ( ' bool ' ) :
idDict [ eType ] = self . level . entType2ids . get ( eType , [ ] )
else :
2019-12-30 00:07:56 -06:00
for eType in list ( self . level . entType2ids . keys ( ) ) :
2019-11-02 17:27:54 -05:00
idDict [ eType ] = self . level . entType2ids . get ( eType , [ ] )
2019-12-30 00:07:56 -06:00
typeKeys = list ( idDict . keys ( ) )
2019-11-02 17:27:54 -05:00
typeKeys . sort ( )
def getChildEntIds ( entity ) :
entIds = [ ]
for child in entity . getChildren ( ) :
entIds . append ( child . entId )
entIds . extend ( getChildEntIds ( child ) )
return entIds
thisEntity = self . level . getEntity ( entId )
forbiddenEntIds = [ entId , thisEntity . parentEntId ]
forbiddenEntIds . extend ( getChildEntIds ( thisEntity ) )
for eType in typeKeys :
idList = list ( idDict [ eType ] )
for forbiddenId in forbiddenEntIds :
if forbiddenId in idList :
idList . remove ( forbiddenId )
if len ( idList ) == 0 :
continue
subMenu = Menu ( entMenu , tearoff = 0 )
entMenu . add_cascade ( label = eType , menu = subMenu )
idList . sort ( )
numIds = len ( idList )
idIndex = 0
for id in idList :
if idIndex % 10 == 0 :
if numIds > 10 :
m = Menu ( subMenu , tearoff = 0 )
firstId = idList [ idIndex ]
lastIndex = min ( idIndex + 9 , numIds - 1 )
lastId = idList [ lastIndex ]
subMenu . add_cascade ( label = ' Ids %d - %d ' % ( firstId , lastId ) , menu = m )
else :
m = subMenu
m . add_command ( label = ' %d : %s ' % ( id , self . getEntityName ( id ) ) , command = lambda id = id , h = handleMenu : h ( id ) )
idIndex + = 1
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
self . curEntWidgets [ attribName ] = text . set
def addStringWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
text = StringVar ( )
text . set ( str ( entSpec [ attribName ] ) )
def handleReturn ( event ) :
self . level . setAttribEdit ( entId , attribName , text . get ( ) )
frame = Frame ( self . pageOneFrame . interior ( ) )
label = Label ( frame , text = attribName , width = 15 , anchor = W , justify = LEFT )
label . pack ( side = LEFT , expand = 0 )
widg = Entry ( frame , textvariable = text )
widg . bind ( ' <Return> ' , handleReturn )
widg . pack ( side = LEFT , fill = X , expand = 1 )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
self . curEntWidgets [ attribName ] = text . set
def addConstWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
frame = Frame ( self . pageOneFrame . interior ( ) )
label = Label ( frame , text = attribName , width = 15 , anchor = W , justify = LEFT )
label . pack ( side = LEFT , expand = 0 )
text = str ( entSpec [ attribName ] )
valueLabel = Label ( frame , text = text , anchor = W , justify = LEFT , relief = GROOVE )
valueLabel . pack ( side = LEFT , fill = X , expand = 1 )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
def addPythonWidget ( self , levelSpec , entSpec , entId , attribName , params ) :
text = StringVar ( )
text . set ( repr ( entSpec [ attribName ] ) )
def handleReturn ( event ) :
self . handleAttributeChangeSubmit ( attribName , text , entId , levelSpec )
frame = Frame ( self . pageOneFrame . interior ( ) )
label = Label ( frame , text = attribName , width = 15 , anchor = W , justify = LEFT )
label . pack ( side = LEFT , expand = 0 )
widg = Entry ( frame , textvariable = text )
widg . bind ( ' <Return> ' , handleReturn )
widg . pack ( side = LEFT , fill = X , expand = 1 )
frame . pack ( fill = X , expand = 1 )
self . attribWidgets . append ( frame )
self . curEntWidgets [ attribName ] = lambda x : text . set ( repr ( x ) )
def handleAttributeChangeSubmit ( self , attribName , textObj , entId , levelSpec ) :
newText = textObj . get ( )
try :
value = eval ( newText )
except :
showwarning ( ' ERROR ' , ' that is not a valid Python object ' , parent = self . parent )
return
self . level . setAttribEdit ( entId , attribName , value )
def handleAttribChange ( self , entId , attribName , value , username ) :
if username == self . level . editUsername :
if self . entityCopy :
self . entityCopy . removeNode ( )
self . entityCopy = None
if entId == self . curEntId :
widgetSetter = self . curEntWidgets [ attribName ]
if widgetSetter is not None :
widgetSetter ( value )
return
def createButtons ( self ) :
pass
def toggleBalloon ( self ) :
if self . toggleBalloonVar . get ( ) :
self . balloon ( ) . configure ( state = ' both ' )
else :
self . balloon ( ) . configure ( state = ' none ' )
def onDestroy ( self , event ) :
from direct . directtools import DirectSession
direct . disable ( )
bboard . remove ( DirectSession . DirectSession . DIRECTdisablePost )
self . ignore ( self . level . getAttribChangeEventName ( ) )
self . ignore ( ' DIRECT_selectedNodePath ' )
self . ignore ( ' DIRECT_manipulateObjectCleanup ' )
self . ignore ( ' DIRECT_undo ' )
self . ignore ( ' DIRECT_redo ' )
2019-12-30 00:07:56 -06:00
print ( ' InGameEditor.onDestroy() ' )
2019-11-02 17:27:54 -05:00
if self . visZonesEditor :
self . visZonesEditor . destroy ( )
self . explorer . _node . destroy ( )
del self . level
messenger . send ( self . doneEvent )
def handleRequestSave ( self ) :
messenger . send ( self . requestSaveEvent )
def handleSaveAs ( self ) :
2019-12-30 00:07:56 -06:00
filename = tkinter . filedialog . asksaveasfilename ( parent = self . parent , defaultextension = ' .py ' , filetypes = [ ( ' Python Source Files ' , ' .py ' ) , ( ' All Files ' , ' * ' ) ] )
2019-11-02 17:27:54 -05:00
if len ( filename ) > 0 :
messenger . send ( self . saveAsEvent , [ filename ] )
def doUndo ( self ) :
messenger . send ( self . undoEvent )
def doRedo ( self ) :
messenger . send ( self . redoEvent )
def doWireframe ( self ) :
messenger . send ( self . wireframeEvent )
def doOobe ( self ) :
messenger . send ( self . oobeEvent )
def doCs ( self ) :
messenger . send ( self . csEvent )
def doRun ( self ) :
messenger . send ( self . runEvent )
def doTex ( self ) :
messenger . send ( self . texEvent )
def resetLevel ( self ) :
self . showTodo ( what = ' resetLevel ' )
def showTodo ( self , what = ' ' ) :
self . showWarning ( ' %s \n This is not yet implemented. ' % what , ' TODO ' )
def showWarning ( self , msg , title = ' Warning ' ) :
showwarning ( title , msg , parent = self . parent )
def askYesNo ( self , msg , title = ' Query ' ) :
return askyesno ( title , msg , parent = self . parent )
def popupLevelDialog ( self ) :
data = askstring ( ' Input Level Data ' , ' Level Data: ' , parent = self )
if data :
self . messageBar ( ) . helpmessage ( data )
class LevelVisZonesEditor ( Pmw . MegaToplevel ) :
def __init__ ( self , editor , entId , visible , modelZones = [ ] , updateCommand = None , parent = None , * * kw ) :
DGG . INITOPT = Pmw_INITOPT
optiondefs = ( ( ' title ' , ' Level Vis-Zone Editor ' , None ) , )
self . defineoptions ( kw , optiondefs )
Pmw . MegaToplevel . __init__ ( self , parent , title = self [ ' title ' ] )
self . editor = editor
self . entId = entId
self . modelZones = modelZones
self . modelZones . sort ( )
self . updateCommand = updateCommand
hull = self . component ( ' hull ' )
balloon = self . balloon = Pmw . Balloon ( hull )
self . balloon . configure ( state = ' none ' )
menuFrame = Frame ( hull , relief = GROOVE , bd = 2 )
menuFrame . pack ( fill = X , expand = 1 )
menuBar = Pmw . MenuBar ( menuFrame , hotkeys = 1 , balloon = balloon )
menuBar . pack ( side = LEFT , expand = 1 , fill = X )
menuBar . addmenu ( ' Vis Zones Editor ' , ' Visability Zones Editor Operations ' )
menuBar . addmenuitem ( ' Vis Zones Editor ' , ' command ' , ' Exit Visability Zones Editor ' , label = ' Exit ' , command = self . destroy )
menuBar . addmenu ( ' Help ' , ' Visibility Zones Editor Help Operations ' )
self . toggleBalloonVar = IntVar ( )
self . toggleBalloonVar . set ( 0 )
menuBar . addmenuitem ( ' Help ' , ' checkbutton ' , ' Toggle balloon help ' , label = ' Balloon Help ' , variable = self . toggleBalloonVar , command = self . toggleBalloon )
sf = Pmw . ScrolledFrame ( hull , horizflex = ' elastic ' , usehullsize = 1 , hull_width = 200 , hull_height = 400 )
frame = sf . interior ( )
sf . pack ( padx = 5 , pady = 3 , fill = BOTH , expand = 1 )
self . radioSelect = Pmw . RadioSelect ( frame , selectmode = MULTIPLE , orient = DGG . VERTICAL , pady = 0 , command = self . toggleVisZone )
self . buttons = [ ]
for modelZoneNum in self . modelZones :
buttonStr = ' %d - %s ' % ( modelZoneNum , self . editor . getEntityName ( modelZoneNum ) )
button = self . radioSelect . add ( buttonStr , width = 12 )
button . configure ( anchor = W , justify = LEFT )
self . buttons . append ( button )
self . radioSelect . pack ( expand = 1 , fill = X )
sf . reposition ( )
buttonFrame = Frame ( hull )
self . showMode = IntVar ( )
self . showMode . set ( self . editor . level . level . getColorZones ( ) )
self . showActiveButton = Radiobutton ( buttonFrame , text = ' Stash Invisible ' , value = 0 , indicatoron = 1 , variable = self . showMode , command = self . setVisRenderMode )
self . showActiveButton . pack ( side = LEFT , fill = X , expand = 1 )
self . showAllButton = Radiobutton ( buttonFrame , text = ' Color Invisible ' , value = 1 , indicatoron = 1 , variable = self . showMode , command = self . setVisRenderMode )
self . showAllButton . pack ( side = LEFT , fill = X , expand = 1 )
buttonFrame . pack ( fill = X , expand = 1 )
self . initialiseoptions ( LevelVisZonesEditor )
self . setVisible ( visible )
return None
def toggleVisZone ( self , zoneStr , state ) :
zoneNum = int ( zoneStr . split ( ' - ' ) [ 0 ] )
if state == 0 :
if zoneNum in self . visible :
self . visible . remove ( zoneNum )
elif zoneNum not in self . visible :
self . visible . append ( zoneNum )
self . visible . sort ( )
if self . updateCommand :
self . updateCommand ( self . visible )
def setVisible ( self , visible ) :
self . visible = visible
self . refreshVisibility ( )
def setVisRenderMode ( self ) :
self . editor . level . level . setColorZones ( self . showMode . get ( ) )
def refreshVisibility ( self ) :
self . radioSelect . selection = [ ]
for button in self . buttons :
componentName = button [ ' text ' ]
modelZone = int ( componentName . split ( ' - ' ) [ 0 ] )
if modelZone in self . visible :
button . configure ( relief = ' sunken ' )
self . radioSelect . selection . append ( componentName )
else :
button . configure ( relief = ' raised ' )
def destroy ( self ) :
self . editor . visZonesEditor = None
Pmw . MegaToplevel . destroy ( self )
return
def toggleBalloon ( self ) :
if self . toggleBalloonVar . get ( ) :
self . balloon . configure ( state = ' balloon ' )
else :
self . balloon . configure ( state = ' none ' )
DEFAULT_MENU_ITEMS = [ ' Update Explorer ' ,
' Separator ' ,
' Select ' ,
' Deselect ' ,
' Separator ' ,
' Delete ' ,
' Separator ' ,
' Fit ' ,
' Flash ' ,
' Isolate ' ,
' Toggle Vis ' ,
' Show All ' ,
' Separator ' ,
' Set Reparent Target ' ,
' Reparent ' ,
' WRT Reparent ' ,
' Separator ' ,
' Place ' ,
' Set Name ' ,
' Set Color ' ,
' Explore ' ,
' Separator ' ]
class LevelExplorer ( Pmw . MegaWidget , DirectObject . DirectObject ) :
def __init__ ( self , parent = None , editor = None , * * kw ) :
optiondefs = ( ( ' menuItems ' , [ ] , Pmw . INITOPT ) , )
self . defineoptions ( kw , optiondefs )
Pmw . MegaWidget . __init__ ( self , parent )
self . editor = editor
interior = self . interior ( )
interior . configure ( relief = GROOVE , borderwidth = 2 )
self . _scrolledCanvas = self . createcomponent ( ' scrolledCanvas ' , ( ) , None , Pmw . ScrolledCanvas , ( interior , ) , hull_width = 300 , hull_height = 80 , usehullsize = 1 )
self . _canvas = self . _scrolledCanvas . component ( ' canvas ' )
self . _canvas [ ' scrollregion ' ] = ( ' 0i ' , ' 0i ' , ' 2i ' , ' 4i ' )
self . _scrolledCanvas . resizescrollregion ( )
self . _scrolledCanvas . pack ( padx = 3 , pady = 3 , expand = 1 , fill = BOTH )
self . _canvas . bind ( ' <ButtonPress-2> ' , self . mouse2Down )
self . _canvas . bind ( ' <B2-Motion> ' , self . mouse2Motion )
self . _canvas . bind ( ' <Configure> ' , lambda e , sc = self . _scrolledCanvas : sc . resizescrollregion ( ) )
self . interior ( ) . bind ( ' <Destroy> ' , self . onDestroy )
self . _treeItem = LevelExplorerItem ( self . editor . level , self . editor )
self . _node = TreeNode ( self . _canvas , None , self . _treeItem , DEFAULT_MENU_ITEMS + self [ ' menuItems ' ] )
self . _node . expand ( )
self . _parentFrame = Frame ( interior )
self . accept ( ' Level_Update Explorer ' , lambda f , s = self : s . update ( ) )
self . initialiseoptions ( LevelExplorer )
return
def update ( self , fUseCachedChildren = 1 ) :
self . _node . update ( fUseCachedChildren )
self . _node . expand ( )
def mouse2Down ( self , event ) :
self . _width = 1.0 * self . _canvas . winfo_width ( )
self . _height = 1.0 * self . _canvas . winfo_height ( )
xview = self . _canvas . xview ( )
yview = self . _canvas . yview ( )
self . _left = xview [ 0 ]
self . _top = yview [ 0 ]
self . _dxview = xview [ 1 ] - xview [ 0 ]
self . _dyview = yview [ 1 ] - yview [ 0 ]
self . _2lx = event . x
self . _2ly = event . y
def mouse2Motion ( self , event ) :
newx = self . _left - ( event . x - self . _2lx ) / self . _width * self . _dxview
self . _canvas . xview_moveto ( newx )
newy = self . _top - ( event . y - self . _2ly ) / self . _height * self . _dyview
self . _canvas . yview_moveto ( newy )
self . _2lx = event . x
self . _2ly = event . y
self . _left = self . _canvas . xview ( ) [ 0 ]
self . _top = self . _canvas . yview ( ) [ 0 ]
def onDestroy ( self , event ) :
self . ignore ( ' Level_Update Explorer ' )
class LevelExplorerItem ( TreeItem ) :
def __init__ ( self , levelElement , editor ) :
self . levelElement = levelElement
self . editor = editor
def GetText ( self ) :
return self . levelElement . getName ( )
def GetKey ( self ) :
return self . levelElement . id ( )
def IsEditable ( self ) :
return 1
def SetText ( self , text ) :
self . levelElement . setNewName ( text )
def GetIconName ( self ) :
return ' sphere2 '
def IsExpandable ( self ) :
return self . levelElement . getNumChildren ( ) != 0
def GetSubList ( self ) :
sublist = [ ]
for element in self . levelElement . getChildren ( ) :
item = LevelExplorerItem ( element , self . editor )
sublist . append ( item )
return sublist
def OnSelect ( self ) :
messenger . send ( self . editor . getEventMsgName ( ' Select ' ) , [ self . levelElement ] )
def MenuCommand ( self , command ) :
messenger . send ( self . editor . getEventMsgName ( command ) , [ self . levelElement ] )