*** empty log message ***
This commit is contained in:
parent
b02e0c91fb
commit
ff9b9bcf4c
|
|
@ -21,8 +21,8 @@ class DirectCameraControl(PandaObject):
|
|||
self.camManipRef = direct.group.attachNewNode('camManipRef')
|
||||
t = CAM_MOVE_DURATION
|
||||
self.actionEvents = [
|
||||
['handleMouse2', self.mouseFlyStart],
|
||||
['handleMouse2Up', self.mouseFlyStop],
|
||||
['DIRECT_mouse2', self.mouseFlyStart],
|
||||
['DIRECT_mouse2Up', self.mouseFlyStop],
|
||||
['c', self.centerCamIn, 0.5],
|
||||
['f', self.fitOnWidget],
|
||||
['h', self.homeCam],
|
||||
|
|
@ -259,7 +259,10 @@ class DirectCameraControl(PandaObject):
|
|||
angle = getCrankAngle(state.coaCenter)
|
||||
deltaAngle = angle - state.lastAngle
|
||||
state.lastAngle = angle
|
||||
self.camManipRef.setHpr(self.camManipRef, 0, 0, -deltaAngle)
|
||||
if base.config.GetBool('temp-hpr-fix',0):
|
||||
self.camManipRef.setHpr(self.camManipRef, 0, 0, deltaAngle)
|
||||
else:
|
||||
self.camManipRef.setHpr(self.camManipRef, 0, 0, -deltaAngle)
|
||||
direct.camera.setMat(self.camManipRef, wrtMat)
|
||||
return Task.cont
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class DirectLights(NodePath):
|
|||
# Turn it on as a default
|
||||
self.setOn(directLight)
|
||||
# Send an event to all watching objects
|
||||
messenger.send('DirectLights_addLight', [directLight])
|
||||
messenger.send('DIRECT_addLight', [directLight])
|
||||
# Return the new light
|
||||
return directLight
|
||||
|
||||
|
|
@ -101,6 +101,8 @@ class DirectLights(NodePath):
|
|||
""" Turn on all DIRECT lights """
|
||||
base.initialState.setAttribute(LightTransition.getClassType(),
|
||||
self.la)
|
||||
# Make sure there is a default material
|
||||
render.setMaterial(Material())
|
||||
|
||||
def allOff(self):
|
||||
""" Turn off all DIRECT lights """
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class DirectManipulationControl(PandaObject):
|
|||
self.fScaling = 0
|
||||
self.mode = None
|
||||
self.actionEvents = [
|
||||
['handleMouse1', self.manipulationStart],
|
||||
['handleMouse1Up', self.manipulationStop],
|
||||
['DIRECT_mouse1', self.manipulationStart],
|
||||
['DIRECT_mouse1Up', self.manipulationStop],
|
||||
['tab', self.toggleObjectHandlesMode],
|
||||
['.', self.objectHandles.multiplyScalingFactorBy, 2.0],
|
||||
['>', self.objectHandles.multiplyScalingFactorBy, 2.0],
|
||||
|
|
@ -111,7 +111,7 @@ class DirectManipulationControl(PandaObject):
|
|||
self.objectHandles.hideGuides()
|
||||
# Restart followSelectedNodePath task
|
||||
self.spawnFollowSelectedNodePathTask()
|
||||
messenger.send('manipulateObjectCleanup')
|
||||
messenger.send('DIRECT_manipulateObjectCleanup')
|
||||
|
||||
def spawnFollowSelectedNodePathTask(self):
|
||||
# If nothing selected, just return
|
||||
|
|
@ -177,7 +177,7 @@ class DirectManipulationControl(PandaObject):
|
|||
# hide the bbox of the selected objects during interaction
|
||||
direct.selected.dehighlightAll()
|
||||
# Send event to signal start of manipulation
|
||||
messenger.send('manipulateObjectStart')
|
||||
messenger.send('DIRECT_manipulateObjectStart')
|
||||
# Manipulate the real object with the constraint
|
||||
# The constraint is passed as the name of the node
|
||||
self.spawnManipulateObjectTask()
|
||||
|
|
@ -304,7 +304,10 @@ class DirectManipulationControl(PandaObject):
|
|||
elif self.rotateAxis == 'y':
|
||||
direct.widget.setR(direct.widget, -deltaAngle)
|
||||
elif self.rotateAxis == 'z':
|
||||
direct.widget.setH(direct.widget, deltaAngle)
|
||||
if base.config.GetBool('temp-hpr-fix',0):
|
||||
direct.widget.setH(direct.widget, -deltaAngle)
|
||||
else:
|
||||
direct.widget.setH(direct.widget, deltaAngle)
|
||||
# Record crank angle for next time around
|
||||
self.lastCrankAngle = newAngle
|
||||
|
||||
|
|
@ -416,7 +419,10 @@ class DirectManipulationControl(PandaObject):
|
|||
deltaAngle = angle - state.lastAngle
|
||||
state.lastAngle = angle
|
||||
# Mouse motion edge to edge of display region results in one full turn
|
||||
relHpr(direct.widget, direct.camera, 0, 0, deltaAngle)
|
||||
if base.config.GetBool('temp-hpr-fix',0):
|
||||
relHpr(direct.widget, direct.camera, 0, 0, -deltaAngle)
|
||||
else:
|
||||
relHpr(direct.widget, direct.camera, 0, 0, deltaAngle)
|
||||
|
||||
def scale3D(self, state):
|
||||
# Scale the selected node based upon up down mouse motion
|
||||
|
|
@ -461,7 +467,7 @@ class DirectManipulationControl(PandaObject):
|
|||
# Move the objects with the widget
|
||||
direct.selected.moveWrtWidgetAll()
|
||||
# Let everyone know that something was moved
|
||||
messenger.send('manipulateObjectCleanup')
|
||||
messenger.send('DIRECT_manipulateObjectCleanup')
|
||||
|
||||
class ObjectHandles(NodePath,PandaObject):
|
||||
def __init__(self):
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class SelectedNodePaths(PandaObject):
|
|||
# And keep track of it in the deselected dictionary
|
||||
self.deselectedDict[id] = dnp
|
||||
# Send a message
|
||||
messenger.send('deselectedNodePath', [dnp])
|
||||
messenger.send('DIRECT_deselectedNodePath', [dnp])
|
||||
return dnp
|
||||
|
||||
def getSelectedAsList(self):
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ from DirectGrid import *
|
|||
from DirectGeometry import *
|
||||
from DirectLights import *
|
||||
from DirectSessionPanel import *
|
||||
from tkSimpleDialog import askstring
|
||||
import Placer
|
||||
import EntryScale
|
||||
import OnscreenText
|
||||
import types
|
||||
import __builtin__
|
||||
|
|
@ -44,6 +46,7 @@ class DirectSession(PandaObject):
|
|||
# Ancestry of currently selected object
|
||||
self.ancestry = []
|
||||
self.ancestryIndex = 0
|
||||
self.activeParent = None
|
||||
|
||||
self.readout = OnscreenText.OnscreenText( pos = (0.1, -0.95), bg=Vec4(1,1,1,1))
|
||||
# Make sure readout is never lit or drawn in wireframe
|
||||
|
|
@ -90,15 +93,19 @@ class DirectSession(PandaObject):
|
|||
['highlightAll', self.selected.highlightAll],
|
||||
['preRemoveNodePath', self.deselect],
|
||||
# Scene graph explorer functions
|
||||
['SGENodePath_Select', self.select],
|
||||
['SGENodePath_Deselect', self.deselect],
|
||||
['SGENodePath_Flash', self.flash],
|
||||
['SGENodePath_Isolate', self.isolate],
|
||||
['SGENodePath_Toggle Vis', self.toggleVis],
|
||||
['SGENodePath_Show All', self.showAllDescendants],
|
||||
['SGENodePath_Fit', self.fitOnNodePath],
|
||||
['SGENodePath_Place', Placer.place],
|
||||
['SGENodePath_Delete', self.removeNodePath],
|
||||
['SGE_Select', self.select],
|
||||
['SGE_Deselect', self.deselect],
|
||||
['SGE_Set Parent', self.setActiveParent],
|
||||
['SGE_Reparent', self.reparent],
|
||||
['SGE_Flash', self.flash],
|
||||
['SGE_Isolate', self.isolate],
|
||||
['SGE_Toggle Vis', self.toggleVis],
|
||||
['SGE_Show All', self.showAllDescendants],
|
||||
['SGE_Fit', self.fitOnNodePath],
|
||||
['SGE_Place', Placer.place],
|
||||
['SGE_Set Color', EntryScale.rgbPanel],
|
||||
['SGE_Delete', self.removeNodePath],
|
||||
['SGE_Set Name', self.getAndSetName],
|
||||
]
|
||||
self.keyEvents = ['escape', 'delete', 'control', 'control-up',
|
||||
'shift', 'shift-up', 'alt', 'alt-up',
|
||||
|
|
@ -195,17 +202,17 @@ class DirectSession(PandaObject):
|
|||
def inputHandler(self, input):
|
||||
# Deal with keyboard and mouse input
|
||||
if input == 'mouse1':
|
||||
messenger.send('handleMouse1')
|
||||
messenger.send('DIRECT_mouse1')
|
||||
elif input == 'mouse1-up':
|
||||
messenger.send('handleMouse1Up')
|
||||
messenger.send('DIRECT_mouse1Up')
|
||||
elif input == 'mouse2':
|
||||
messenger.send('handleMouse2')
|
||||
messenger.send('DIRECT_mouse2')
|
||||
elif input == 'mouse2-up':
|
||||
messenger.send('handleMouse2Up')
|
||||
messenger.send('DIRECT_mouse2Up')
|
||||
elif input == 'mouse3':
|
||||
messenger.send('handleMouse3')
|
||||
messenger.send('DIRECT_mouse3')
|
||||
elif input == 'mouse3-up':
|
||||
messenger.send('handleMouse3Up')
|
||||
messenger.send('DIRECT_mouse3Up')
|
||||
elif input == 'shift':
|
||||
self.fShift = 1
|
||||
elif input == 'shift-up':
|
||||
|
|
@ -249,7 +256,7 @@ class DirectSession(PandaObject):
|
|||
def select(self, nodePath, fMultiSelect = 0, fResetAncestry = 1):
|
||||
dnp = self.selected.select(nodePath, fMultiSelect)
|
||||
if dnp:
|
||||
messenger.send('preSelectNodePath', [dnp])
|
||||
messenger.send('DIRECT_preSelectNodePath', [dnp])
|
||||
if fResetAncestry:
|
||||
# Update ancestry
|
||||
self.ancestry = dnp.getAncestry()
|
||||
|
|
@ -276,7 +283,7 @@ class DirectSession(PandaObject):
|
|||
t.dnp = dnp
|
||||
taskMgr.spawnTaskNamed(t, 'followSelectedNodePath')
|
||||
# Send an message marking the event
|
||||
messenger.send('selectedNodePath', [dnp])
|
||||
messenger.send('DIRECT_selectedNodePath', [dnp])
|
||||
|
||||
def followSelectedNodePathTask(self, state):
|
||||
mCoa2Render = state.dnp.mCoa2Dnp * state.dnp.getMat(render)
|
||||
|
|
@ -296,7 +303,7 @@ class DirectSession(PandaObject):
|
|||
taskMgr.removeTasksNamed('followSelectedNodePath')
|
||||
self.ancestry = []
|
||||
# Send an message marking the event
|
||||
messenger.send('deselectedNodePath', [dnp])
|
||||
messenger.send('DIRECT_deselectedNodePath', [dnp])
|
||||
|
||||
def deselectAll(self):
|
||||
self.selected.deselectAll()
|
||||
|
|
@ -306,6 +313,20 @@ class DirectSession(PandaObject):
|
|||
self.readout.setText(' ')
|
||||
taskMgr.removeTasksNamed('followSelectedNodePath')
|
||||
|
||||
def setActiveParent(self, nodePath = None):
|
||||
# Record new parent
|
||||
self.activeParent = nodePath
|
||||
# Alert everyone else
|
||||
messenger.send('DIRECT_activeParent', [self.activeParent])
|
||||
|
||||
def reparent(self, nodePath = None):
|
||||
if nodePath and self.activeParent:
|
||||
oldParent = nodePath.getParent()
|
||||
nodePath.reparentTo(self.activeParent)
|
||||
# Alert everyone else
|
||||
messenger.send('DIRECT_reparent',
|
||||
[nodePath, oldParent, self.activeParent])
|
||||
|
||||
def flash(self, nodePath = 'None Given'):
|
||||
""" Highlight an object by setting it red for a few seconds """
|
||||
# Clean up any existing task
|
||||
|
|
@ -421,6 +442,14 @@ class DirectSession(PandaObject):
|
|||
self.select(np, 0, 0)
|
||||
self.flash(np)
|
||||
|
||||
def getAndSetName(self, nodePath):
|
||||
""" Prompt user for new node path name """
|
||||
newName = askstring('Node Path: ' + nodePath.getName(),
|
||||
'Enter new name:')
|
||||
if newName:
|
||||
nodePath.setName(newName)
|
||||
messenger.send('DIRECT_nodePathSetName', [nodePath, newName])
|
||||
|
||||
# UNDO REDO FUNCTIONS
|
||||
def pushUndo(self, nodePathList, fResetRedo = 1):
|
||||
# Assemble group of changes
|
||||
|
|
@ -435,10 +464,10 @@ class DirectSession(PandaObject):
|
|||
# Truncate list
|
||||
self.undoList = self.undoList[-25:]
|
||||
# Alert anyone who cares
|
||||
messenger.send('pushUndo')
|
||||
messenger.send('DIRECT_pushUndo')
|
||||
if fResetRedo and (nodePathList != []):
|
||||
self.redoList = []
|
||||
messenger.send('redoListEmpty')
|
||||
messenger.send('DIRECT_redoListEmpty')
|
||||
|
||||
def popUndoGroup(self):
|
||||
# Get last item
|
||||
|
|
@ -447,7 +476,7 @@ class DirectSession(PandaObject):
|
|||
self.undoList = self.undoList[:-1]
|
||||
# Update state of undo button
|
||||
if not self.undoList:
|
||||
messenger.send('undoListEmpty')
|
||||
messenger.send('DIRECT_undoListEmpty')
|
||||
# Return last item
|
||||
return undoGroup
|
||||
|
||||
|
|
@ -464,7 +493,7 @@ class DirectSession(PandaObject):
|
|||
# Truncate list
|
||||
self.redoList = self.redoList[-25:]
|
||||
# Alert anyone who cares
|
||||
messenger.send('pushRedo')
|
||||
messenger.send('DIRECT_pushRedo')
|
||||
|
||||
def popRedoGroup(self):
|
||||
# Get last item
|
||||
|
|
@ -473,7 +502,7 @@ class DirectSession(PandaObject):
|
|||
self.redoList = self.redoList[:-1]
|
||||
# Update state of redo button
|
||||
if not self.redoList:
|
||||
messenger.send('redoListEmpty')
|
||||
messenger.send('DIRECT_redoListEmpty')
|
||||
# Return last item
|
||||
return redoGroup
|
||||
|
||||
|
|
@ -489,7 +518,7 @@ class DirectSession(PandaObject):
|
|||
# Undo xform
|
||||
pose[0].setPosHprScale(pose[1], pose[2], pose[3])
|
||||
# Alert anyone who cares
|
||||
messenger.send('undo')
|
||||
messenger.send('DIRECT_undo')
|
||||
|
||||
def redo(self):
|
||||
if self.redoList:
|
||||
|
|
@ -502,7 +531,7 @@ class DirectSession(PandaObject):
|
|||
for pose in redoGroup:
|
||||
pose[0].setPosHprScale(pose[1], pose[2], pose[3])
|
||||
# Alert anyone who cares
|
||||
messenger.send('redo')
|
||||
messenger.send('DIRECT_redo')
|
||||
|
||||
# UTILITY FUNCTIONS
|
||||
def useObjectHandles(self):
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
from ShowBaseGlobal import *
|
||||
import __builtin__
|
||||
|
||||
# If specified in the user's Configrc, create the direct session
|
||||
if base.wantDIRECT:
|
||||
from DirectSession import *
|
||||
__builtin__.direct = base.direct = DirectSession()
|
||||
direct.enable()
|
||||
else:
|
||||
# Otherwise set the values to None
|
||||
__builtin__.direct = base.direct = None
|
||||
|
||||
|
|
@ -1,4 +1,11 @@
|
|||
from PandaObject import *
|
||||
from EntryScale import EntryScale
|
||||
|
||||
def adjust(command = None, min = 0.0, max = 1.0, text = 'Adjust'):
|
||||
tl = Toplevel()
|
||||
tl.title('Parameter Adjust')
|
||||
es = EntryScale(tl, command = command, min = min, max = max, text = text)
|
||||
es.pack(expand = 1, fill = X)
|
||||
|
||||
## Background Color ##
|
||||
def setBackgroundColor(r,g,b):
|
||||
|
|
|
|||
|
|
@ -776,11 +776,40 @@
|
|||
def place(self):
|
||||
base.wantDIRECT = 1
|
||||
base.wantTk = 1
|
||||
from TkGlobal import *
|
||||
from DirectSessionGlobal import *
|
||||
from ShowBaseGlobal import *
|
||||
import TkGlobal
|
||||
import Placer
|
||||
Placer.place(self)
|
||||
|
||||
def explore(self):
|
||||
base.wantDIRECT = 1
|
||||
base.wantTk = 1
|
||||
from ShowBaseGlobal import *
|
||||
import TkGlobal
|
||||
import SceneGraphExplorer
|
||||
SceneGraphExplorer.explore(self)
|
||||
|
||||
def rgbPanel(self, cb = None):
|
||||
base.wantDIRECT = 1
|
||||
base.wantTk = 1
|
||||
from ShowBaseGlobal import *
|
||||
import TkGlobal
|
||||
import EntryScale
|
||||
EntryScale.rgbPanel(self, cb)
|
||||
|
||||
def select(self):
|
||||
base.wantDIRECT = 1
|
||||
base.wantTk = 1
|
||||
from ShowBaseGlobal import *
|
||||
import TkGlobal
|
||||
direct.select(self)
|
||||
|
||||
def deselect(self):
|
||||
base.wantDIRECT = 1
|
||||
base.wantTk = 1
|
||||
from ShowBaseGlobal import *
|
||||
import TkGlobal
|
||||
direct.deselect(self)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from PandaModules import *
|
||||
from DirectSessionGlobal import *
|
||||
from ShowBaseGlobal import *
|
||||
from IntervalGlobal import *
|
||||
from Actor import *
|
||||
|
||||
|
|
|
|||
|
|
@ -20,14 +20,13 @@ else:
|
|||
|
||||
print "Loading LevelEditor for hoods: ", hoods
|
||||
|
||||
from DirectSessionGlobal import *
|
||||
from ShowBaseGlobal import *
|
||||
from PandaObject import *
|
||||
from PieMenu import *
|
||||
from GuiGlobals import *
|
||||
from Tkinter import *
|
||||
from DirectGeometry import *
|
||||
from SceneGraphExplorer import *
|
||||
from tkSimpleDialog import askstring
|
||||
from tkMessageBox import showinfo
|
||||
from tkFileDialog import *
|
||||
from whrandom import *
|
||||
|
|
@ -39,7 +38,6 @@ import os
|
|||
import __builtin__
|
||||
import whrandom
|
||||
import Floater
|
||||
import EntryScale
|
||||
|
||||
# Colors used by all color menus
|
||||
DEFAULT_COLORS = [
|
||||
|
|
@ -418,19 +416,19 @@ class LevelEditor(NodePath, PandaObject):
|
|||
|
||||
# The list of events the level editor responds to
|
||||
self.actionEvents = [
|
||||
# Actions in response to DIRECT operations
|
||||
('selectedNodePath', self.selectedNodePathHook),
|
||||
('deselectedNodePath', self.deselectedNodePathHook),
|
||||
# Node path events
|
||||
('preRemoveNodePath', self.removeNodePathHook),
|
||||
('manipulateObjectCleanup', self.updateSelectedPose),
|
||||
|
||||
# Actions in response to DIRECT operations
|
||||
('DIRECT_selectedNodePath', self.selectedNodePathHook),
|
||||
('DIRECT_deselectedNodePath', self.deselectedNodePathHook),
|
||||
('DIRECT_manipulateObjectCleanup', self.updateSelectedPose),
|
||||
('DIRECT_nodePathSetName', self.setName),
|
||||
('DIRECT_activeParent', self.setActiveParent),
|
||||
('DIRECT_reparent', self.reparent),
|
||||
('RGBPanel_setColor', self.setColor),
|
||||
# Actions in response to Level Editor Panel operations
|
||||
('SGENodePath_Set Name', self.getAndSetName),
|
||||
('SGENodePath_Set Parent', self.setActiveParent),
|
||||
('SGENodePath_Reparent', self.reparent),
|
||||
('SGENodePath_Add Group', self.addGroup),
|
||||
('SGENodePath_Add Vis Group', self.addVisGroup),
|
||||
('SGENodePath_Set Color', self.setNPColor),
|
||||
('SGE_Add Group', self.addGroup),
|
||||
('SGE_Add Vis Group', self.addVisGroup),
|
||||
# Actions in response to Pie Menu interaction
|
||||
('select_building_style', self.setBuildingStyle),
|
||||
('select_building_type', self.setBuildingType),
|
||||
|
|
@ -515,6 +513,7 @@ class LevelEditor(NodePath, PandaObject):
|
|||
|
||||
# BATTLE CELLS
|
||||
self.battleCellMarker = loader.loadModel('models/misc/sphere')
|
||||
self.battleCellMarker.setName('battleCellMarker')
|
||||
self.battleCellMarker.setScale(1)
|
||||
self.currentBattleCellType = "20w 20l"
|
||||
|
||||
|
|
@ -676,19 +675,22 @@ class LevelEditor(NodePath, PandaObject):
|
|||
# Turn off player camera control
|
||||
base.disableMouse()
|
||||
# Handle mouse events for pie menus
|
||||
self.accept('handleMouse3',self.levelHandleMouse3)
|
||||
self.accept('handleMouse3Up',self.levelHandleMouse3Up)
|
||||
self.accept('DIRECT_mouse3',self.levelHandleMouse3)
|
||||
self.accept('DIRECT_mouse3Up',self.levelHandleMouse3Up)
|
||||
|
||||
def disableMouse(self):
|
||||
""" Disable Pie Menu interaction """
|
||||
# Disable handling of mouse events
|
||||
self.ignore('handleMouse3')
|
||||
self.ignore('handleMouse3Up')
|
||||
self.ignore('DIRECT_mouse3')
|
||||
self.ignore('DIRECT_mouse3Up')
|
||||
|
||||
# LEVEL OBJECT MANAGEMENT FUNCTIONS
|
||||
def findDNANode(self, nodePath):
|
||||
""" Find node path's DNA Object in DNAStorage (if any) """
|
||||
return DNASTORE.findDNAGroup(nodePath.id())
|
||||
if nodePath:
|
||||
return DNASTORE.findDNAGroup(nodePath.id())
|
||||
else:
|
||||
return None
|
||||
|
||||
def replaceSelected(self):
|
||||
if self.replaceSelectedEnabled:
|
||||
|
|
@ -735,40 +737,35 @@ class LevelEditor(NodePath, PandaObject):
|
|||
nodePath.removeNode()
|
||||
|
||||
def removeNodePathHook(self, nodePath):
|
||||
if nodePath:
|
||||
dnaNode = self.findDNANode(nodePath)
|
||||
# Does the node path correspond to a DNA Object
|
||||
if dnaNode:
|
||||
for i in self.removeHookList:
|
||||
i(dnaNode, nodePath)
|
||||
# Get DNANode's parent
|
||||
parentDNANode = dnaNode.getParent()
|
||||
if parentDNANode:
|
||||
# Remove DNANode from its parent
|
||||
parentDNANode.remove(dnaNode)
|
||||
# Delete DNA and associated Node Relations from DNA Store
|
||||
DNASTORE.removeDNAGroup(dnaNode)
|
||||
dnaNode = self.findDNANode(nodePath)
|
||||
# Does the node path correspond to a DNA Object
|
||||
if dnaNode:
|
||||
for i in self.removeHookList:
|
||||
i(dnaNode, nodePath)
|
||||
# Get DNANode's parent
|
||||
parentDNANode = dnaNode.getParent()
|
||||
if parentDNANode:
|
||||
# Remove DNANode from its parent
|
||||
parentDNANode.remove(dnaNode)
|
||||
# Delete DNA and associated Node Relations from DNA Store
|
||||
DNASTORE.removeDNAGroup(dnaNode)
|
||||
|
||||
def reparent(self, nodePath):
|
||||
def reparent(self, nodePath, oldParent, newParent):
|
||||
""" Move node path (and its DNA) to active parent """
|
||||
# Do we have a node path?
|
||||
if nodePath:
|
||||
dnaNode = self.findDNANode(nodePath)
|
||||
# Does the node path correspond to a DNA Object
|
||||
if dnaNode:
|
||||
# Yes, get its parent and see if it has a DNA Object
|
||||
parent = nodePath.getParent()
|
||||
parentDNAObject = self.findDNANode(parent)
|
||||
if parentDNAObject:
|
||||
# Yes it does, move node path (and DNA)
|
||||
# to new parent (if active parent set)
|
||||
if ((self.NPParent != None) and
|
||||
(self.DNAParent != None)):
|
||||
nodePath.reparentTo(self.NPParent)
|
||||
parentDNAObject.remove(dnaNode)
|
||||
self.DNAParent.add(dnaNode)
|
||||
# Update scene graph explorer to reflect change
|
||||
# self.panel.sceneGraphExplorer.update()
|
||||
# Does the node path correspond to a DNA Object
|
||||
dnaNode = self.findDNANode(nodePath)
|
||||
if dnaNode:
|
||||
# Find old parent DNA
|
||||
oldParentDNANode = self.findDNANode(oldParent)
|
||||
# Remove DNA from old parent
|
||||
if oldParentDNANode:
|
||||
oldParentDNANode.remove(dnaNode)
|
||||
if newParent:
|
||||
# Update active parent just to be safe
|
||||
self.setActiveParent(newParent)
|
||||
# Move DNA to new parent (if active parent set)
|
||||
if self.DNAParent != None:
|
||||
self.DNAParent.add(dnaNode)
|
||||
|
||||
def reparentSelected(self):
|
||||
for nodePath in direct.selected:
|
||||
|
|
@ -776,9 +773,6 @@ class LevelEditor(NodePath, PandaObject):
|
|||
|
||||
def setActiveParent(self, nodePath = None):
|
||||
""" Set NPParent and DNAParent to node path and its DNA """
|
||||
# If nothing passed in, try currently selected node path
|
||||
if not nodePath:
|
||||
nodePath = direct.selected.last
|
||||
# If we've got a valid node path
|
||||
if nodePath:
|
||||
# See if this is in the DNA database
|
||||
|
|
@ -791,17 +785,9 @@ class LevelEditor(NodePath, PandaObject):
|
|||
else:
|
||||
print 'LevelEditor.setActiveParent: nodePath == None'
|
||||
|
||||
def getAndSetName(self, nodePath):
|
||||
""" Prompt user for new node path name """
|
||||
newName = askstring('Node Path', 'Enter new name:')
|
||||
if newName:
|
||||
self.setName(nodePath, newName)
|
||||
|
||||
def setName(self, nodePath, newName):
|
||||
""" Set name of a node path and its DNA (if it exists) """
|
||||
# First, set name of the node path
|
||||
nodePath.setName(newName)
|
||||
# Now find the DNA that corresponds to this node path
|
||||
""" Set name of nodePath's DNA (if it exists) """
|
||||
# Find the DNA that corresponds to this node path
|
||||
dnaNode = self.findDNANode(nodePath)
|
||||
if dnaNode:
|
||||
# If it exists, set the name of the DNA Node
|
||||
|
|
@ -834,30 +820,34 @@ class LevelEditor(NodePath, PandaObject):
|
|||
# Update DNA
|
||||
self.updatePose(dnaObject, selectedNode)
|
||||
else:
|
||||
possiblePoint = self.findSuitPointMarker(selectedNode)
|
||||
if possiblePoint:
|
||||
point = self.getSuitPointFromNodePath(possiblePoint)
|
||||
if point:
|
||||
print "Found suit point!", point
|
||||
# First snap selected node path to grid
|
||||
pos = selectedNode.getPos(direct.grid)
|
||||
snapPos = direct.grid.computeSnapPoint(pos)
|
||||
if self.panel.fPlaneSnap.get():
|
||||
zheight = 0
|
||||
else:
|
||||
zheight = snapPos[2]
|
||||
selectedNode.setPos(direct.grid,
|
||||
snapPos[0], snapPos[1], zheight)
|
||||
newPos = selectedNode.getPos(self.NPToplevel)
|
||||
point.setPos(newPos)
|
||||
pointOrCell, type = self.findPointOrCell(selectedNode)
|
||||
if pointOrCell and type:
|
||||
# First snap selected node path to grid
|
||||
pos = selectedNode.getPos(direct.grid)
|
||||
snapPos = direct.grid.computeSnapPoint(pos)
|
||||
if self.panel.fPlaneSnap.get():
|
||||
zheight = 0
|
||||
else:
|
||||
zheight = snapPos[2]
|
||||
selectedNode.setPos(
|
||||
direct.grid,
|
||||
snapPos[0], snapPos[1], zheight)
|
||||
newPos = selectedNode.getPos(self.NPToplevel)
|
||||
# Update DNA
|
||||
pointOrCell.setPos(newPos)
|
||||
if (type == 'suitPointMarker'):
|
||||
print "Found suit point!", pointOrCell
|
||||
# Ok, now update all the lines into that node
|
||||
for edge in self.point2edgeDict[point]:
|
||||
for edge in self.point2edgeDict[pointOrCell]:
|
||||
oldEdgeLine = self.edgeDict[edge]
|
||||
del self.edgeDict[edge]
|
||||
oldEdgeLine.reset()
|
||||
del oldEdgeLine
|
||||
newEdgeLine = self.drawSuitEdge(edge, self.NPParent)
|
||||
newEdgeLine = self.drawSuitEdge(
|
||||
edge, self.NPParent)
|
||||
self.edgeDict[edge] = newEdgeLine
|
||||
elif (type == 'battleCellMarker'):
|
||||
print "Found battle cell!", pointOrCell
|
||||
|
||||
def updatePose(self, dnaObject, nodePath):
|
||||
"""
|
||||
|
|
@ -1013,14 +1003,14 @@ class LevelEditor(NodePath, PandaObject):
|
|||
def addGroup(self, nodePath):
|
||||
""" Add a new DNA Node Group to the specified Node Path """
|
||||
# Set the node path as the current parent
|
||||
self.setActiveParent(nodePath)
|
||||
direct.setActiveParent(nodePath)
|
||||
# Add a new group to the selected parent
|
||||
self.createNewGroup()
|
||||
|
||||
def addVisGroup(self, nodePath):
|
||||
""" Add a new DNA Group to the specified Node Path """
|
||||
# Set the node path as the current parent
|
||||
self.setActiveParent(nodePath)
|
||||
direct.setActiveParent(nodePath)
|
||||
# Add a new group to the selected parent
|
||||
self.createNewGroup(type = 'vis')
|
||||
|
||||
|
|
@ -1473,13 +1463,23 @@ class LevelEditor(NodePath, PandaObject):
|
|||
self.DNATarget.getHeight())
|
||||
self.replaceSelected()
|
||||
|
||||
def setNPColor(self, nodePath):
|
||||
def setColor(self, nodePath, r,g,b,a):
|
||||
""" 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)
|
||||
dnaNode = self.findDNANode(nodePath)
|
||||
if dnaNode:
|
||||
objClass = DNAGetClassType(dnaNode)
|
||||
if ((objClass.eq(DNA_WALL)) or
|
||||
(objClass.eq(DNA_WINDOWS)) or
|
||||
(objClass.eq(DNA_DOOR)) or
|
||||
(objClass.eq(DNA_CORNICE)) or
|
||||
(objClass.eq(DNA_PROP)) or
|
||||
(objClass.eq(DNA_SIGN)) or
|
||||
(objClass.eq(DNA_SIGN_BASELINE)) or
|
||||
(objClass.eq(DNA_SIGN_TEXT)) or
|
||||
(objClass.eq(DNA_SIGN_GRAPHIC))
|
||||
):
|
||||
# Update dna information
|
||||
dnaNode.setColor(VBase4(r/255.0, g/255.0, b/255.0, a/255.0))
|
||||
|
||||
# SELECTION FUNCTIONS
|
||||
def selectedNodePathHook(self, nodePath):
|
||||
|
|
@ -1527,15 +1527,12 @@ class LevelEditor(NodePath, PandaObject):
|
|||
if DNAClassEqual(dnaNode, DNA_STREET):
|
||||
self.snapList = OBJECT_SNAP_POINTS[dnaNode.getCode()]
|
||||
else:
|
||||
possiblePoint = self.findSuitPointMarker(nodePath)
|
||||
if possiblePoint:
|
||||
point = self.getSuitPointFromNodePath(possiblePoint)
|
||||
if point:
|
||||
print "Found suit point!", point
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
pointOrCell, type = self.findPointOrCell(nodePath)
|
||||
if pointOrCell and (type == 'suitPointMarker'):
|
||||
print "Found suit point!", pointOrCell
|
||||
if pointOrCell and (type == 'battleCellMarker'):
|
||||
print "Found battle cell!", pointOrCell
|
||||
|
||||
# Let others know that something new may be selected:
|
||||
for i in self.selectedNodePathHookHooks:
|
||||
i()
|
||||
|
|
@ -1577,20 +1574,29 @@ class LevelEditor(NodePath, PandaObject):
|
|||
return self.findDNARoot(nodePath.getParent())
|
||||
|
||||
|
||||
def findSuitPointMarker(self, nodePath):
|
||||
""" Walk up a node path's ancestry looking for its DNA Root """
|
||||
def findPointOrCell(self, nodePath):
|
||||
"""
|
||||
Walk up a node path's ancestry to see if its a suit point marker
|
||||
or a battle cell marker
|
||||
"""
|
||||
# Check current node's name for root marker
|
||||
if (nodePath.getName() == 'suitPointMarker'):
|
||||
# Its a root!
|
||||
return nodePath
|
||||
# Its a suit point marker!
|
||||
# See if point is in pointDict
|
||||
point = self.getSuitPointFromNodePath(nodePath)
|
||||
return point, 'suitPointMarker'
|
||||
elif (nodePath.getName() == 'battleCellMarker'):
|
||||
# Its a battle cell marker
|
||||
# See if cell is in cell Dict
|
||||
cell = self.getBattleCellFromNodePath(nodePath)
|
||||
return cell, 'battleCellMarker'
|
||||
else:
|
||||
# If reached the top: fail
|
||||
if not nodePath.hasParent():
|
||||
return None
|
||||
return None, None
|
||||
else:
|
||||
# Try parent
|
||||
return self.findSuitPointMarker(nodePath.getParent())
|
||||
|
||||
return self.findPointOrCell(nodePath.getParent())
|
||||
|
||||
# MANIPULATION FUNCTIONS
|
||||
def keyboardRotateSelected(self, arrowDirection):
|
||||
|
|
@ -2252,15 +2258,17 @@ class LevelEditor(NodePath, PandaObject):
|
|||
|
||||
def placeSuitPoint(self):
|
||||
v = self.getGridSnapIntersectionPoint()
|
||||
# get the absolute pos relative to the top level. That is what gets stored in the point
|
||||
# get the absolute pos relative to the top level.
|
||||
# That is what gets stored in the point
|
||||
mat = direct.grid.getMat(self.NPToplevel)
|
||||
absPos = Point3(mat.xformPoint(v))
|
||||
print 'Suit point: ' + `absPos`
|
||||
# Store the point in the DNA. If this point is already in there, it returns
|
||||
# the existing point
|
||||
# Store the point in the DNA. If this point is already in there,
|
||||
# it returns the existing point
|
||||
suitPoint = DNASTORE.storeSuitPoint(self.currentSuitPointType, absPos)
|
||||
if not self.pointDict.has_key(suitPoint):
|
||||
marker = self.drawSuitPoint(absPos, self.currentSuitPointType, self.NPToplevel)
|
||||
marker = self.drawSuitPoint(
|
||||
absPos, self.currentSuitPointType, self.NPToplevel)
|
||||
self.pointDict[suitPoint] = marker
|
||||
self.currentSuitPointIndex = suitPoint.getIndex()
|
||||
|
||||
|
|
@ -2269,9 +2277,10 @@ class LevelEditor(NodePath, PandaObject):
|
|||
# Make a new dna edge
|
||||
if DNAClassEqual(self.DNAParent, DNA_VIS_GROUP):
|
||||
zoneId = self.DNAParent.getName()
|
||||
suitEdge = DNASuitEdge(self.startSuitPoint, self.endSuitPoint, zoneId)
|
||||
suitEdge = DNASuitEdge(
|
||||
self.startSuitPoint, self.endSuitPoint, zoneId)
|
||||
DNASTORE.storeSuitEdge(suitEdge)
|
||||
# Add the edge to the current vis group so it can be written out
|
||||
# Add edge to the current vis group so it can be written out
|
||||
self.DNAParent.addSuitEdge(suitEdge)
|
||||
# Draw a line to represent the edge
|
||||
edgeLine = self.drawSuitEdge(suitEdge, self.NPParent)
|
||||
|
|
@ -2338,7 +2347,8 @@ class LevelEditor(NodePath, PandaObject):
|
|||
numPoints = DNASTORE.getNumSuitPoints()
|
||||
for i in range(numPoints):
|
||||
point = DNASTORE.getSuitPoint(i)
|
||||
marker = self.drawSuitPoint(point.getPos(), point.getPointType(), self.NPToplevel)
|
||||
marker = self.drawSuitPoint(
|
||||
point.getPos(), point.getPointType(), self.NPToplevel)
|
||||
self.pointDict[point] = marker
|
||||
|
||||
# Edges
|
||||
|
|
@ -2359,7 +2369,6 @@ class LevelEditor(NodePath, PandaObject):
|
|||
else:
|
||||
self.point2edgeDict[point] = [edge]
|
||||
|
||||
|
||||
def getSuitPointFromNodePath(self, nodePath):
|
||||
"""
|
||||
Given a node path, attempt to find the point,nodePath pair
|
||||
|
|
@ -2421,6 +2430,18 @@ class LevelEditor(NodePath, PandaObject):
|
|||
for cell, marker in self.cellDict.items():
|
||||
marker.show()
|
||||
|
||||
def getBattleCellFromNodePath(self, nodePath):
|
||||
"""
|
||||
Given a node path, attempt to find the battle cell, nodePath pair
|
||||
in the cellDict. If it is there, return the cell. If we
|
||||
cannot find it, return None.
|
||||
TODO: a reverse lookup cellDict would speed this up quite a bit
|
||||
"""
|
||||
for cell, marker in self.cellDict.items():
|
||||
if marker.eq(nodePath):
|
||||
return cell
|
||||
return None
|
||||
|
||||
def colorZones(self):
|
||||
# Give each zone a random color to see them better
|
||||
visGroups = self.getDNAVisGroups(self.NPToplevel)
|
||||
|
|
@ -3728,13 +3749,14 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
self.fUpdateSelected = 1
|
||||
# Handle to the toplevels hull
|
||||
hull = self.component('hull')
|
||||
|
||||
hull.geometry('400x575')
|
||||
|
||||
balloon = self.balloon = Pmw.Balloon(hull)
|
||||
# Start with balloon help disabled
|
||||
self.balloon.configure(state = 'none')
|
||||
|
||||
menuFrame = Frame(hull, relief = GROOVE, bd = 2)
|
||||
menuFrame.pack(fill = X, expand = 1)
|
||||
menuFrame.pack(fill = X)
|
||||
|
||||
menuBar = Pmw.MenuBar(menuFrame, hotkeys = 1, balloon = balloon)
|
||||
menuBar.pack(side = LEFT, expand = 1, fill = X)
|
||||
|
|
@ -3809,7 +3831,7 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
|
||||
self.editMenu = Pmw.ComboBox(
|
||||
menuFrame, labelpos = W,
|
||||
label_text = 'Edit Mode:', entry_width = 12,
|
||||
label_text = 'Edit Mode:', entry_width = 18,
|
||||
selectioncommand = self.levelEditor.setEditMode, history = 0,
|
||||
scrolledlist_items = NEIGHBORHOODS)
|
||||
self.editMenu.selectitem(NEIGHBORHOODS[0])
|
||||
|
|
@ -4181,50 +4203,7 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
variable = self.fGrid,
|
||||
command = self.toggleGrid)
|
||||
direct.gridButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
buttonFrame.pack(expand = 1, fill = 'x')
|
||||
|
||||
buttonFrame2 = Frame(hull)
|
||||
self.groupButton = Button(
|
||||
buttonFrame2,
|
||||
text = 'New Group',
|
||||
command = self.levelEditor.createNewGroup)
|
||||
self.groupButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
self.visGroupButton = Button(
|
||||
buttonFrame2,
|
||||
text = 'New Vis Group',
|
||||
command = self.createNewVisGroup)
|
||||
self.visGroupButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
self.setParentButton = Button(
|
||||
buttonFrame2,
|
||||
text = 'Set Parent',
|
||||
command = self.levelEditor.setActiveParent)
|
||||
self.setParentButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
self.reparentButton = Button(
|
||||
buttonFrame2,
|
||||
text = 'Re Parent',
|
||||
command = self.levelEditor.reparentSelected)
|
||||
self.reparentButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
buttonFrame2.pack(fill = 'x')
|
||||
|
||||
buttonFrame3 = Frame(hull)
|
||||
self.isolateButton = Button(
|
||||
buttonFrame3,
|
||||
text = 'Isolate Selected',
|
||||
command = direct.isolate)
|
||||
self.isolateButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
self.showAllButton = Button(
|
||||
buttonFrame3,
|
||||
text = 'Show All',
|
||||
command = self.showAll)
|
||||
self.showAllButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
buttonFrame3.pack(fill = 'x')
|
||||
buttonFrame.pack(fill = X)
|
||||
|
||||
buttonFrame4 = Frame(hull)
|
||||
self.driveMode = IntVar()
|
||||
|
|
@ -4243,14 +4222,13 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
variable = self.driveMode,
|
||||
command = self.levelEditor.useDirectFly)
|
||||
directModeButton.pack(side = 'left', expand = 1, fill = 'x')
|
||||
buttonFrame4.pack(fill = 'x')
|
||||
buttonFrame4.pack(fill = X)
|
||||
|
||||
self.sceneGraphExplorer = SceneGraphExplorer(
|
||||
parent = sceneGraphPage,
|
||||
menuItems = ['Set Parent', 'Reparent', 'Add Group',
|
||||
'Add Vis Group', 'Set Color',
|
||||
'Set Name'])
|
||||
self.sceneGraphExplorer.pack(expand = 1, fill = 'both')
|
||||
nodePath = self.levelEditor,
|
||||
menuItems = ['Add Group', 'Add Vis Group', 'Set Color'])
|
||||
self.sceneGraphExplorer.pack(expand = 1, fill = BOTH)
|
||||
|
||||
# Make sure input variables processed
|
||||
self.initialiseoptions(LevelEditorPanel)
|
||||
|
|
@ -4286,12 +4264,6 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
def toggleMapVis(self):
|
||||
self.levelEditor.toggleMapVis(self.fMapVis.get())
|
||||
|
||||
def showAll(self):
|
||||
direct.showAll(self.levelEditor.NPToplevel)
|
||||
|
||||
def createNewVisGroup(self):
|
||||
self.levelEditor.createNewGroup(type = 'vis')
|
||||
|
||||
def setStreetModuleType(self,name):
|
||||
self.streetModuleType = 'street_' + name
|
||||
self.levelEditor.setCurrent('street_texture', self.streetModuleType)
|
||||
|
|
@ -4699,8 +4671,8 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
(objClass.eq(DNA_PROP)) or
|
||||
(objClass.eq(DNA_SIGN)) or
|
||||
(objClass.eq(DNA_SIGN_BASELINE)) or
|
||||
(objClass.eq(DNA_SIGN_BASELINE_TEXT)) or
|
||||
(objClass.eq(DNA_SIGN_BASELINE_GRAPHIC))
|
||||
(objClass.eq(DNA_SIGN_TEXT)) or
|
||||
(objClass.eq(DNA_SIGN_GRAPHIC))
|
||||
):
|
||||
self.levelEditor.setDNATargetColor(
|
||||
VBase4((color[0]/255.0),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
from DirectSessionGlobal import *
|
||||
from ShowBaseGlobal import *
|
||||
import LevelEditor
|
||||
l = LevelEditor.LevelEditor()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from DirectSessionGlobal import *
|
||||
from ShowBaseGlobal import *
|
||||
|
||||
import ParticleEffect
|
||||
import ParticlePanel
|
||||
|
|
|
|||
|
|
@ -179,6 +179,9 @@ class Particles(ParticleSystem.ParticleSystem):
|
|||
else:
|
||||
self.removeAngularForce(force)
|
||||
|
||||
def setRenderNodePath(self, nodePath):
|
||||
self.setRenderParent(nodePath.node())
|
||||
|
||||
## Getters ##
|
||||
def getName(self):
|
||||
"""getName()"""
|
||||
|
|
|
|||
|
|
@ -20,6 +20,15 @@ __builtin__.messenger = base.messenger
|
|||
__builtin__.config = base.config
|
||||
__builtin__.directNotify = directNotify
|
||||
|
||||
# Initialize DIRECT
|
||||
if base.wantDIRECT:
|
||||
from DirectSession import *
|
||||
__builtin__.direct = base.direct = DirectSession()
|
||||
direct.enable()
|
||||
else:
|
||||
# Otherwise set the values to None
|
||||
__builtin__.direct = base.direct = None
|
||||
|
||||
# Set direct notify categories now that we have config
|
||||
directNotify.setDconfigLevels()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ taskMgr page
|
|||
class DirectSessionPanel(AppShell):
|
||||
# Override class variables here
|
||||
appname = 'Direct Session Panel'
|
||||
frameWidth = 550
|
||||
frameWidth = 600
|
||||
frameHeight = 502
|
||||
usecommandarea = 1
|
||||
usestatusarea = 0
|
||||
|
|
@ -67,15 +67,16 @@ class DirectSessionPanel(AppShell):
|
|||
self.jbNodePathNames = ['camera', 'selected', 'none']
|
||||
|
||||
# Set up event hooks
|
||||
self.actionEvents = [('undo', self.undoHook),
|
||||
('pushUndo', self.pushUndoHook),
|
||||
('undoListEmpty', self.undoListEmptyHook),
|
||||
('redo', self.redoHook),
|
||||
('pushRedo', self.pushRedoHook),
|
||||
('redoListEmpty', self.redoListEmptyHook),
|
||||
('selectedNodePath', self.selectedNodePathHook),
|
||||
('DirectLights_addLight', self.addLight),
|
||||
]
|
||||
self.actionEvents = [
|
||||
('DIRECT_undo', self.undoHook),
|
||||
('DIRECT_pushUndo', self.pushUndoHook),
|
||||
('DIRECT_undoListEmpty', self.undoListEmptyHook),
|
||||
('DIRECT_redo', self.redoHook),
|
||||
('DIRECT_pushRedo', self.pushRedoHook),
|
||||
('DIRECT_redoListEmpty', self.redoListEmptyHook),
|
||||
('DIRECT_selectedNodePath',self.selectedNodePathHook),
|
||||
('DIRECT_addLight', self.addLight),
|
||||
]
|
||||
for event, method in self.actionEvents:
|
||||
self.accept(event, method)
|
||||
|
||||
|
|
@ -139,20 +140,21 @@ class DirectSessionPanel(AppShell):
|
|||
# The master frame for the dials
|
||||
mainFrame = Frame(interior)
|
||||
|
||||
# Paned widget for dividing two halves
|
||||
framePane = Pmw.PanedWidget(mainFrame, orient = HORIZONTAL)
|
||||
sgeFrame = framePane.add('left', min = 250)
|
||||
notebookFrame = framePane.add('right', min = 300)
|
||||
|
||||
# Scene Graph Explorer
|
||||
sgeFrame = Frame(mainFrame)
|
||||
self.sgeUpdate = Button(sgeFrame, text = 'Update Explorer')
|
||||
self.sgeUpdate.pack(fill = X, expand = 0)
|
||||
self.SGE = SceneGraphExplorer.SceneGraphExplorer(
|
||||
sgeFrame, nodePath = render,
|
||||
scrolledCanvas_hull_width = 200,
|
||||
scrolledCanvas_hull_width = 250,
|
||||
scrolledCanvas_hull_height = 400)
|
||||
self.SGE.pack(fill = BOTH, expand = 0)
|
||||
self.sgeUpdate['command'] = self.SGE.update
|
||||
sgeFrame.pack(side = LEFT, fill = 'both', expand = 0)
|
||||
|
||||
# Create the notebook pages
|
||||
notebook = Pmw.NoteBook(mainFrame)
|
||||
notebook = Pmw.NoteBook(notebookFrame)
|
||||
notebook.pack(fill = BOTH, expand = 1)
|
||||
envPage = notebook.add('Environment')
|
||||
lightsPage = notebook.add('Lights')
|
||||
|
|
@ -562,9 +564,9 @@ class DirectSessionPanel(AppShell):
|
|||
self.jbHprSF.pack(fill = X, expand = 0)
|
||||
self.bind(self.jbHprSF, 'Set joybox HPR speed multiplier')
|
||||
|
||||
|
||||
notebook.setnaturalsize()
|
||||
|
||||
|
||||
framePane.pack(expand = 1, fill = BOTH)
|
||||
mainFrame.pack(fill = 'both', expand = 1)
|
||||
|
||||
# Create some buttons in the bottom tray
|
||||
|
|
|
|||
|
|
@ -153,16 +153,17 @@ class MopathRecorder(AppShell, PandaObject):
|
|||
self.iRay = SelectionRay(self.iRayCS)
|
||||
# Set up event hooks
|
||||
self.actionEvents = [
|
||||
('undo', self.undoHook),
|
||||
('pushUndo', self.pushUndoHook),
|
||||
('undoListEmpty', self.undoListEmptyHook),
|
||||
('redo', self.redoHook),
|
||||
('pushRedo', self.pushRedoHook),
|
||||
('redoListEmpty', self.redoListEmptyHook),
|
||||
('selectedNodePath', self.selectedNodePathHook),
|
||||
('deselectedNodePath', self.deselectedNodePathHook),
|
||||
('manipulateObjectStart', self.manipulateObjectStartHook),
|
||||
('manipulateObjectCleanup', self.manipulateObjectCleanupHook),
|
||||
('DIRECT_undo', self.undoHook),
|
||||
('DIRECT_pushUndo', self.pushUndoHook),
|
||||
('DIRECT_undoListEmpty', self.undoListEmptyHook),
|
||||
('DIRECT_redo', self.redoHook),
|
||||
('DIRECT_pushRedo', self.pushRedoHook),
|
||||
('DIRECT_redoListEmpty', self.redoListEmptyHook),
|
||||
('DIRECT_selectedNodePath', self.selectedNodePathHook),
|
||||
('DIRECT_deselectedNodePath', self.deselectedNodePathHook),
|
||||
('DIRECT_manipulateObjectStart', self.manipulateObjectStartHook),
|
||||
('DIRECT_manipulateObjectCleanup',
|
||||
self.manipulateObjectCleanupHook),
|
||||
]
|
||||
for event, method in self.actionEvents:
|
||||
self.accept(event, method)
|
||||
|
|
|
|||
|
|
@ -67,12 +67,12 @@ class Placer(AppShell):
|
|||
self.posOffset = Vec3(0)
|
||||
|
||||
# Set up event hooks
|
||||
self.undoEvents = [('undo', self.undoHook),
|
||||
('pushUndo', self.pushUndoHook),
|
||||
('undoListEmpty', self.undoListEmptyHook),
|
||||
('redo', self.redoHook),
|
||||
('pushRedo', self.pushRedoHook),
|
||||
('redoListEmpty', self.redoListEmptyHook)]
|
||||
self.undoEvents = [('DIRECT_undo', self.undoHook),
|
||||
('DIRECT_pushUndo', self.pushUndoHook),
|
||||
('DIRECT_undoListEmpty', self.undoListEmptyHook),
|
||||
('DIRECT_redo', self.redoHook),
|
||||
('DIRECT_pushRedo', self.pushRedoHook),
|
||||
('DIRECT_redoListEmpty', self.redoListEmptyHook)]
|
||||
for event, method in self.undoEvents:
|
||||
self.accept(event, method)
|
||||
|
||||
|
|
@ -610,7 +610,7 @@ class Placer(AppShell):
|
|||
|
||||
def xformStop(self, data):
|
||||
# Throw event to signal manipulation done
|
||||
messenger.send('manipulateObjectCleanup')
|
||||
messenger.send('DIRECT_manipulateObjectCleanup')
|
||||
# Update placer to reflect new state
|
||||
self.updatePlacer()
|
||||
# If moving widget restart follow task
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class EntryScale(Pmw.MegaWidget):
|
|||
('initialValue', 0.0, Pmw.INITOPT),
|
||||
('resolution', 0.001, None),
|
||||
('command', None, None),
|
||||
('callbackData', [], None),
|
||||
('callbackData', [], None),
|
||||
('min', 0.0, self._updateValidate),
|
||||
('max', 100.0, self._updateValidate),
|
||||
('text', 'EntryScale', self._updateLabelText),
|
||||
|
|
@ -328,6 +328,12 @@ class EntryScaleGroup(Pmw.MegaToplevel):
|
|||
text = self['labels'][index])
|
||||
# Do this separately so command doesn't get executed during construction
|
||||
f['command'] = lambda val, s=self, i=index: s._entryScaleSetAt(i, val)
|
||||
f['callbackData'] = [self]
|
||||
# Callbacks
|
||||
f.onReturn = self.__onReturn
|
||||
f.onReturnRelease = self.__onReturnRelease
|
||||
f.onPress = self.__onPress
|
||||
f.onRelease = self.__onRelease
|
||||
f.pack(side = self['side'], expand = 1, fill = X)
|
||||
self.entryScaleList.append(f)
|
||||
|
||||
|
|
@ -376,15 +382,80 @@ class EntryScaleGroup(Pmw.MegaToplevel):
|
|||
def reset(self):
|
||||
self.set(self['initialValue'])
|
||||
|
||||
def __onReturn(self, esg):
|
||||
# Execute onReturn callback
|
||||
apply(self.onReturn, esg.get())
|
||||
|
||||
def setColor(nodePath, callback = None):
|
||||
def onReturn(self, *args):
|
||||
""" User redefinable callback executed on button press """
|
||||
pass
|
||||
|
||||
def __onReturnRelease(self, esg):
|
||||
# Execute onReturnRelease callback
|
||||
apply(self.onReturnRelease, esg.get())
|
||||
|
||||
def onReturnRelease(self, *args):
|
||||
""" User redefinable callback executed on button press """
|
||||
pass
|
||||
|
||||
def __onPress(self, esg):
|
||||
# Execute onPress callback
|
||||
apply(self.onPress, esg.get())
|
||||
|
||||
def onPress(self, *args):
|
||||
""" User redefinable callback executed on button press """
|
||||
pass
|
||||
|
||||
def __onRelease(self, esg):
|
||||
# Execute onRelease callback
|
||||
apply(self.onRelease, esg.get())
|
||||
|
||||
def onRelease(self, *args):
|
||||
""" User redefinable callback executed on button release """
|
||||
pass
|
||||
|
||||
def rgbPanel(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():
|
||||
# Check init color
|
||||
if nodePath.hasColor():
|
||||
initColor = nodePath.getColor() * 255.0
|
||||
else:
|
||||
initColor = Vec4(255)
|
||||
# Create entry scale group
|
||||
esg = EntryScaleGroup(title = 'RGBA Panel: ' + nodePath.getName(),
|
||||
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)
|
||||
# Update menu button
|
||||
esg.component('menubar').component('EntryScale Group-button')['text'] = (
|
||||
'RGBA Panel')
|
||||
# Update menu
|
||||
menu = esg.component('menubar').component('EntryScale Group-menu')
|
||||
# Some helper functions
|
||||
# Clear color
|
||||
menu.insert_command(index = 1, label = 'Clear Color',
|
||||
command = lambda np = nodePath: np.clearColor())
|
||||
# Set Clear Transparency
|
||||
menu.insert_command(index = 2, label = 'Set Transparency',
|
||||
command = lambda np = nodePath: np.setTransparency(1))
|
||||
menu.insert_command(
|
||||
index = 3, label = 'Clear Transparency',
|
||||
command = lambda np = nodePath: np.clearTransparency())
|
||||
# System color picker
|
||||
def popupColorPicker(esg = esg):
|
||||
# Can pass in current color with: color = (255, 0, 0)
|
||||
color = tkColorChooser.askcolor(
|
||||
parent = esg.interior(),
|
||||
|
|
@ -392,26 +463,13 @@ def setColor(nodePath, callback = None):
|
|||
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)
|
||||
menu.insert_command(index = 4, label = 'Popup Color Picker',
|
||||
command = popupColorPicker)
|
||||
|
||||
# Set callback
|
||||
def onRelease(r,g,b,a, nodePath = nodePath):
|
||||
messenger.send('RGBPanel_setColor', [nodePath, r,g,b,a])
|
||||
esg.onRelease = onRelease
|
||||
return esg
|
||||
|
||||
## SAMPLE CODE
|
||||
|
|
|
|||
|
|
@ -3,11 +3,19 @@ from Tkinter import *
|
|||
from Tree import *
|
||||
import Pmw
|
||||
|
||||
DEFAULT_MENU_ITEMS = ['Select', 'Deselect', 'Flash',
|
||||
'Isolate', 'Toggle Vis', 'Show All',
|
||||
'Fit', 'Place', 'Delete']
|
||||
DEFAULT_MENU_ITEMS = [
|
||||
'Update Explorer',
|
||||
'Separator',
|
||||
'Select', 'Deselect', 'Set Parent', 'Reparent', 'Set Name',
|
||||
'Separator',
|
||||
'Delete',
|
||||
'Separator',
|
||||
'Fit', 'Flash', 'Isolate', 'Toggle Vis', 'Show All',
|
||||
'Separator',
|
||||
'Place', 'Set Color',
|
||||
'Separator']
|
||||
|
||||
class SceneGraphExplorer(Pmw.MegaWidget):
|
||||
class SceneGraphExplorer(Pmw.MegaWidget, PandaObject):
|
||||
"Graphical display of a scene graph"
|
||||
def __init__(self, parent = None, nodePath = render, **kw):
|
||||
# Define the megawidget options.
|
||||
|
|
@ -53,6 +61,24 @@ class SceneGraphExplorer(Pmw.MegaWidget):
|
|||
DEFAULT_MENU_ITEMS + self['menuItems'])
|
||||
self._node.expand()
|
||||
|
||||
self._parentFrame = Frame(interior)
|
||||
self._label = self.createcomponent(
|
||||
'parentLabel',
|
||||
(), None,
|
||||
Label, (interior,),
|
||||
text = 'Active Parent: ',
|
||||
anchor = W, justify = LEFT)
|
||||
self._label.pack(expand = 1, fill = X)
|
||||
|
||||
# Add update parent label
|
||||
def updateLabel(nodePath = None, s = self):
|
||||
s._label['text'] = 'Active Parent: ' + nodePath.getName()
|
||||
self.accept('DIRECT_activeParent', updateLabel)
|
||||
|
||||
# Add update hook
|
||||
self.accept('SGE_Update Explorer',
|
||||
lambda np, s = self: s.update())
|
||||
|
||||
# Check keywords and initialise options based on input values.
|
||||
self.initialiseoptions(SceneGraphExplorer)
|
||||
|
||||
|
|
@ -118,10 +144,10 @@ class SceneGraphExplorerItem(TreeItem):
|
|||
return sublist
|
||||
|
||||
def OnSelect(self):
|
||||
messenger.send('SGENodePath_Flash', [self.nodePath])
|
||||
messenger.send('SGE_Flash', [self.nodePath])
|
||||
|
||||
def MenuCommand(self, command):
|
||||
messenger.send('SGENodePath_' + command, [self.nodePath])
|
||||
messenger.send('SGE_' + command, [self.nodePath])
|
||||
|
||||
|
||||
def explore(nodePath = render):
|
||||
|
|
|
|||
|
|
@ -45,16 +45,21 @@ class TreeNode:
|
|||
self.menuVar.set(0)
|
||||
self._popupMenu = None
|
||||
if self.menuList:
|
||||
if self.menuList[-1] == 'Separator':
|
||||
self.menuList = self.menuList[:-1]
|
||||
self._popupMenu = Menu(self.canvas, tearoff = 0)
|
||||
for i in range(len(self.menuList)):
|
||||
item = self.menuList[i]
|
||||
self._popupMenu.add_radiobutton(
|
||||
label = item,
|
||||
variable = self.menuVar,
|
||||
value = i,
|
||||
indicatoron = 0,
|
||||
command = self.popupMenuCommand)
|
||||
|
||||
if item == 'Separator':
|
||||
self._popupMenu.add_separator()
|
||||
else:
|
||||
self._popupMenu.add_radiobutton(
|
||||
label = item,
|
||||
variable = self.menuVar,
|
||||
value = i,
|
||||
indicatoron = 0,
|
||||
command = self.popupMenuCommand)
|
||||
|
||||
def destroy(self):
|
||||
for key in self.kidKeys:
|
||||
c = self.children[key]
|
||||
|
|
@ -120,8 +125,11 @@ class TreeNode:
|
|||
return "break"
|
||||
|
||||
def popupMenuCommand(self):
|
||||
self.item.MenuCommand(self.menuList[self.menuVar.get()])
|
||||
self.parent.update()
|
||||
command = self.menuList[self.menuVar.get()]
|
||||
self.item.MenuCommand(command)
|
||||
if self.parent and (command != 'Update Explorer'):
|
||||
# Update parent to try to keep explorer up to date
|
||||
self.parent.update()
|
||||
|
||||
def expand(self, event=None):
|
||||
if not self.item.IsExpandable():
|
||||
|
|
|
|||
Loading…
Reference in New Issue