mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
*** empty log message ***
This commit is contained in:
parent
f3068ee1bc
commit
98eda01daa
@ -82,5 +82,7 @@ def planeIntersect (lineOrigin, lineDir, planeOrigin, normal):
|
|||||||
hitPt = lineDir * t
|
hitPt = lineDir * t
|
||||||
return hitPt + lineOrigin
|
return hitPt + lineOrigin
|
||||||
|
|
||||||
def roundTo(value, divisor):
|
def ROUND_TO(value, divisor):
|
||||||
return round(value/float(divisor)) * divisor
|
return round(value/float(divisor)) * divisor
|
||||||
|
def ROUND_INT(val):
|
||||||
|
return int(round(val))
|
||||||
|
@ -114,9 +114,9 @@ class DirectGrid(NodePath,PandaObject):
|
|||||||
# Snap if necessary
|
# Snap if necessary
|
||||||
if self.fXyzSnap:
|
if self.fXyzSnap:
|
||||||
self.snapPos.set(
|
self.snapPos.set(
|
||||||
roundTo(self.snapPos[0], self.gridSpacing),
|
ROUND_TO(self.snapPos[0], self.gridSpacing),
|
||||||
roundTo(self.snapPos[1], self.gridSpacing),
|
ROUND_TO(self.snapPos[1], self.gridSpacing),
|
||||||
roundTo(self.snapPos[2], self.gridSpacing))
|
ROUND_TO(self.snapPos[2], self.gridSpacing))
|
||||||
|
|
||||||
# Move snap marker to this point
|
# Move snap marker to this point
|
||||||
self.snapMarker.setPos(self.snapPos)
|
self.snapMarker.setPos(self.snapPos)
|
||||||
@ -125,7 +125,7 @@ class DirectGrid(NodePath,PandaObject):
|
|||||||
return self.snapPos
|
return self.snapPos
|
||||||
|
|
||||||
def computeSnapAngle(self, angle):
|
def computeSnapAngle(self, angle):
|
||||||
return roundTo(angle, self.snapAngle)
|
return ROUND_TO(angle, self.snapAngle)
|
||||||
|
|
||||||
def setSnapAngle(self, angle):
|
def setSnapAngle(self, angle):
|
||||||
self.snapAngle = angle
|
self.snapAngle = angle
|
||||||
|
@ -2,7 +2,8 @@ from PandaObject import *
|
|||||||
from DirectGeometry import *
|
from DirectGeometry import *
|
||||||
|
|
||||||
MANIPULATION_MOVE_DELAY = 0.65
|
MANIPULATION_MOVE_DELAY = 0.65
|
||||||
VISIBLE_DISCS = ['x-disc-visible', 'y-disc-visible', 'z-disc-visible']
|
UNPICKABLE = ['x-disc-visible', 'y-disc-visible', 'z-disc-visible',
|
||||||
|
'GridBack']
|
||||||
|
|
||||||
class DirectManipulationControl(PandaObject):
|
class DirectManipulationControl(PandaObject):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -24,6 +25,7 @@ class DirectManipulationControl(PandaObject):
|
|||||||
self.fWidgetTop = 0
|
self.fWidgetTop = 0
|
||||||
self.fFreeManip = 1
|
self.fFreeManip = 1
|
||||||
self.fScaling = 1
|
self.fScaling = 1
|
||||||
|
self.unpickable = UNPICKABLE
|
||||||
self.mode = None
|
self.mode = None
|
||||||
|
|
||||||
def manipulationStart(self, chan):
|
def manipulationStart(self, chan):
|
||||||
@ -102,7 +104,7 @@ class DirectManipulationControl(PandaObject):
|
|||||||
# Is it a named node?, If so, see if it has a name
|
# Is it a named node?, If so, see if it has a name
|
||||||
elif issubclass(node.__class__, NamedNode):
|
elif issubclass(node.__class__, NamedNode):
|
||||||
name = node.getName()
|
name = node.getName()
|
||||||
if name in VISIBLE_DISCS:
|
if name in self.unpickable:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
index = i
|
index = i
|
||||||
@ -119,7 +121,7 @@ class DirectManipulationControl(PandaObject):
|
|||||||
# Find the node path from the node found above
|
# Find the node path from the node found above
|
||||||
nodePath = render.findPathDownTo(node)
|
nodePath = render.findPathDownTo(node)
|
||||||
# Select it
|
# Select it
|
||||||
direct.select(nodePath)
|
direct.select(nodePath, direct.fShift)
|
||||||
else:
|
else:
|
||||||
direct.deselectAll()
|
direct.deselectAll()
|
||||||
else:
|
else:
|
||||||
@ -136,11 +138,15 @@ class DirectManipulationControl(PandaObject):
|
|||||||
self.objectHandles.showAllHandles()
|
self.objectHandles.showAllHandles()
|
||||||
self.objectHandles.hideGuides()
|
self.objectHandles.hideGuides()
|
||||||
# Restart followSelectedNodePath task
|
# Restart followSelectedNodePath task
|
||||||
if direct.selected.last:
|
|
||||||
self.spawnFollowSelectedNodePathTask()
|
self.spawnFollowSelectedNodePathTask()
|
||||||
messenger.send('manipulateObjectCleanup')
|
messenger.send('manipulateObjectCleanup')
|
||||||
|
|
||||||
def spawnFollowSelectedNodePathTask(self):
|
def spawnFollowSelectedNodePathTask(self):
|
||||||
|
# If nothing selected, just return
|
||||||
|
if not direct.selected.last:
|
||||||
|
return
|
||||||
|
# Clear out old task to make sure
|
||||||
|
taskMgr.removeTasksNamed('followSelectedNodePath')
|
||||||
# Where are the object handles relative to the selected object
|
# Where are the object handles relative to the selected object
|
||||||
pos = VBase3(0)
|
pos = VBase3(0)
|
||||||
hpr = VBase3(0)
|
hpr = VBase3(0)
|
||||||
@ -183,6 +189,14 @@ class DirectManipulationControl(PandaObject):
|
|||||||
self.ignore(',')
|
self.ignore(',')
|
||||||
self.ignore('F')
|
self.ignore('F')
|
||||||
|
|
||||||
|
def addUnpickable(self, item):
|
||||||
|
if item not in self.unpickable:
|
||||||
|
self.unpickable.append(item)
|
||||||
|
|
||||||
|
def removeUnpickable(self, item):
|
||||||
|
if item in self.unpickable:
|
||||||
|
self.unpickable.remove(item)
|
||||||
|
|
||||||
def removeManipulateObjectTask(self):
|
def removeManipulateObjectTask(self):
|
||||||
taskMgr.removeTasksNamed('manipulateObject')
|
taskMgr.removeTasksNamed('manipulateObject')
|
||||||
|
|
||||||
@ -435,8 +449,7 @@ class DirectManipulationControl(PandaObject):
|
|||||||
# Compute widget2newWidget relative to base coordinate system
|
# Compute widget2newWidget relative to base coordinate system
|
||||||
mWidget2Base = direct.widget.getMat(base)
|
mWidget2Base = direct.widget.getMat(base)
|
||||||
mBase2NewBase = Mat4()
|
mBase2NewBase = Mat4()
|
||||||
mBase2NewBase.composeMatrix(
|
composeMatrix(mBase2NewBase, UNIT_VEC, VBase3(h,p,r), ZERO_VEC,
|
||||||
UNIT_VEC, VBase3(h,p,r), ZERO_VEC,
|
|
||||||
CSDefault)
|
CSDefault)
|
||||||
mBase2Widget = base.getMat(direct.widget)
|
mBase2Widget = base.getMat(direct.widget)
|
||||||
mWidget2Parent = direct.widget.getMat()
|
mWidget2Parent = direct.widget.getMat()
|
||||||
|
@ -2,7 +2,7 @@ from PandaObject import *
|
|||||||
from DirectGeometry import *
|
from DirectGeometry import *
|
||||||
from DirectSelection import *
|
from DirectSelection import *
|
||||||
|
|
||||||
|
# MRM: To do: handle broken node paths in selected and deselected dicts
|
||||||
class DirectNodePath(NodePath):
|
class DirectNodePath(NodePath):
|
||||||
# A node path augmented with info, bounding box, and utility methods
|
# A node path augmented with info, bounding box, and utility methods
|
||||||
def __init__(self, nodePath):
|
def __init__(self, nodePath):
|
||||||
@ -47,11 +47,15 @@ class DirectNodePath(NodePath):
|
|||||||
|
|
||||||
class SelectedNodePaths(PandaObject):
|
class SelectedNodePaths(PandaObject):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
self.selectedDict = {}
|
self.selectedDict = {}
|
||||||
self.deselectedDict = {}
|
self.deselectedDict = {}
|
||||||
self.last = None
|
self.last = None
|
||||||
|
|
||||||
def select(self, nodePath, fMultiSelect = 0):
|
def select(self, nodePath, fMultiSelect = 0):
|
||||||
|
""" Select the specified node path. Multiselect as required """
|
||||||
# Do nothing if nothing selected
|
# Do nothing if nothing selected
|
||||||
if not nodePath:
|
if not nodePath:
|
||||||
print 'Nothing selected!!'
|
print 'Nothing selected!!'
|
||||||
@ -64,17 +68,16 @@ class SelectedNodePaths(PandaObject):
|
|||||||
# Get this pointer
|
# Get this pointer
|
||||||
id = nodePath.id()
|
id = nodePath.id()
|
||||||
# First see if its already in the selected dictionary
|
# First see if its already in the selected dictionary
|
||||||
dnp = self.selectedDict.get(id, None)
|
dnp = self.getSelectedDict(id)
|
||||||
# If so, we're done
|
# If so, we're done
|
||||||
if not dnp:
|
if not dnp:
|
||||||
# See if it is in the deselected dictionary
|
# See if it is in the deselected dictionary
|
||||||
dnp = self.deselectedDict.get(id, None)
|
dnp = self.getDeselectedDict(id)
|
||||||
if dnp:
|
if dnp:
|
||||||
# It has been previously selected:
|
|
||||||
# Show its bounding box
|
|
||||||
dnp.highlight()
|
|
||||||
# Remove it from the deselected dictionary
|
# Remove it from the deselected dictionary
|
||||||
del(self.deselectedDict[id])
|
del(self.deselectedDict[id])
|
||||||
|
# Show its bounding box
|
||||||
|
dnp.highlight()
|
||||||
else:
|
else:
|
||||||
# Didn't find it, create a new selectedNodePath instance
|
# Didn't find it, create a new selectedNodePath instance
|
||||||
dnp = DirectNodePath(nodePath)
|
dnp = DirectNodePath(nodePath)
|
||||||
@ -87,10 +90,11 @@ class SelectedNodePaths(PandaObject):
|
|||||||
return dnp
|
return dnp
|
||||||
|
|
||||||
def deselect(self, nodePath):
|
def deselect(self, nodePath):
|
||||||
|
""" Deselect the specified node path """
|
||||||
# Get this pointer
|
# Get this pointer
|
||||||
id = nodePath.id()
|
id = nodePath.id()
|
||||||
# See if it is in the selected dictionary
|
# See if it is in the selected dictionary
|
||||||
dnp = self.selectedDict.get(id, None)
|
dnp = self.getSelectedDict(id)
|
||||||
if dnp:
|
if dnp:
|
||||||
# It was selected:
|
# It was selected:
|
||||||
# Hide its bounding box
|
# Hide its bounding box
|
||||||
@ -101,30 +105,80 @@ class SelectedNodePaths(PandaObject):
|
|||||||
self.deselectedDict[id] = dnp
|
self.deselectedDict[id] = dnp
|
||||||
return dnp
|
return dnp
|
||||||
|
|
||||||
def selectedAsList(self):
|
def getSelectedAsList(self):
|
||||||
list = []
|
"""
|
||||||
for key in self.selectedDict.keys():
|
Return a list of all selected node paths. No verification of
|
||||||
list.append(self.selectedDict[key])
|
connectivity is performed on the members of the list
|
||||||
return list
|
"""
|
||||||
|
return self.selectedDict.values()[:]
|
||||||
|
|
||||||
def __getitem__(self,index):
|
def __getitem__(self,index):
|
||||||
return self.selectedAsList()[index]
|
return self.getSelectedAsList()[index]
|
||||||
|
|
||||||
def deselectedAsList(self):
|
def getSelectedDict(self, id):
|
||||||
list = []
|
"""
|
||||||
for key in self.deselectedDict.keys():
|
Search selectedDict for node path, try to repair broken node paths.
|
||||||
list.append(self.deselectedDict[key])
|
"""
|
||||||
return list
|
dnp = self.selectedDict.get(id, None)
|
||||||
|
if dnp:
|
||||||
|
# Found item in selected Dictionary, is it still valid?
|
||||||
|
if dnp.verifyConnectivity():
|
||||||
|
# Yes
|
||||||
|
return dnp
|
||||||
|
else:
|
||||||
|
# Not valid anymore, try to repair
|
||||||
|
if dnp.repairConnectivity(render):
|
||||||
|
# Fixed, return node path
|
||||||
|
return dnp
|
||||||
|
else:
|
||||||
|
del(self.selectedDict[id])
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
# Not in selected dictionary
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getDeselectedAsList(self):
|
||||||
|
return self.deselectedDict.values()[:]
|
||||||
|
|
||||||
|
def getDeselectedDict(self, id):
|
||||||
|
"""
|
||||||
|
Search deselectedDict for node path, try to repair broken node paths.
|
||||||
|
"""
|
||||||
|
dnp = self.deselectedDict.get(id, None)
|
||||||
|
if dnp:
|
||||||
|
# Found item in deselected Dictionary, is it still valid?
|
||||||
|
if dnp.verifyConnectivity():
|
||||||
|
# Yes
|
||||||
|
return dnp
|
||||||
|
else:
|
||||||
|
# Not valid anymore, try to repair
|
||||||
|
if dnp.repairConnectivity(render):
|
||||||
|
# Fixed, return node path
|
||||||
|
return dnp
|
||||||
|
else:
|
||||||
|
del(self.deselectedDict[id])
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
# Not in deselected dictionary
|
||||||
|
return None
|
||||||
|
|
||||||
def forEachSelectedNodePathDo(self, func):
|
def forEachSelectedNodePathDo(self, func):
|
||||||
duplicateKeys = self.selectedDict.keys()[:]
|
"""
|
||||||
for key in duplicateKeys:
|
Perform given func on selected node paths. No node path
|
||||||
func(self.selectedDict[key])
|
connectivity verification performed
|
||||||
|
"""
|
||||||
|
selectedNodePaths = self.getSelectedAsList()
|
||||||
|
for nodePath in selectedNodePaths:
|
||||||
|
func(nodePath)
|
||||||
|
|
||||||
def forEachDeselectedNodePathDo(self, func):
|
def forEachDeselectedNodePathDo(self, func):
|
||||||
duplicateKeys = self.deselectedDict.keys()[:]
|
"""
|
||||||
for key in duplicateKeys:
|
Perform given func on deselected node paths. No node path
|
||||||
func(self.deselectedDict[key])
|
connectivity verification performed
|
||||||
|
"""
|
||||||
|
deselectedNodePaths = self.getDeselectedAsList()
|
||||||
|
for nodePath in deselectedNodePaths:
|
||||||
|
func(nodePath)
|
||||||
|
|
||||||
def getWrtAll(self):
|
def getWrtAll(self):
|
||||||
self.forEachSelectedNodePathDo(self.getWrt)
|
self.forEachSelectedNodePathDo(self.getWrt)
|
||||||
@ -175,11 +229,11 @@ class SelectedNodePaths(PandaObject):
|
|||||||
# Get this pointer
|
# Get this pointer
|
||||||
id = nodePath.id()
|
id = nodePath.id()
|
||||||
# First check selected dict
|
# First check selected dict
|
||||||
dnp = self.selectedDict.get(id, None)
|
dnp = self.getSelectedDict(id)
|
||||||
if dnp:
|
if dnp:
|
||||||
return dnp
|
return dnp
|
||||||
# Otherwise return result of deselected search
|
# Otherwise return result of deselected search
|
||||||
return self.selectedDict.get(id, None)
|
return self.getDeselectedDict(id)
|
||||||
|
|
||||||
def getNumSelected(self):
|
def getNumSelected(self):
|
||||||
return len(self.selectedDict.keys())
|
return len(self.selectedDict.keys())
|
||||||
|
@ -63,8 +63,8 @@ class DirectSession(PandaObject):
|
|||||||
'mouse2', 'mouse2-up',
|
'mouse2', 'mouse2-up',
|
||||||
'mouse3', 'mouse3-up']
|
'mouse3', 'mouse3-up']
|
||||||
|
|
||||||
def select(self, nodePath):
|
def select(self, nodePath, fMultiselect = 0):
|
||||||
dnp = self.selected.select(nodePath)
|
dnp = self.selected.select(nodePath, fMultiselect)
|
||||||
if dnp:
|
if dnp:
|
||||||
messenger.send('preSelectNodePath', [dnp])
|
messenger.send('preSelectNodePath', [dnp])
|
||||||
# Update the readout
|
# Update the readout
|
||||||
@ -127,6 +127,8 @@ class DirectSession(PandaObject):
|
|||||||
self.cameraControl.enableMouseFly()
|
self.cameraControl.enableMouseFly()
|
||||||
# Turn on object manipulation
|
# Turn on object manipulation
|
||||||
self.manipulationControl.enableManipulation()
|
self.manipulationControl.enableManipulation()
|
||||||
|
# Make sure list of selected items is reset
|
||||||
|
self.selected.reset()
|
||||||
# Accept appropriate hooks
|
# Accept appropriate hooks
|
||||||
self.enableKeyEvents()
|
self.enableKeyEvents()
|
||||||
self.enableMouseEvents()
|
self.enableMouseEvents()
|
||||||
@ -159,7 +161,7 @@ class DirectSession(PandaObject):
|
|||||||
def destroy(self):
|
def destroy(self):
|
||||||
self.disable()
|
self.disable()
|
||||||
|
|
||||||
def restart(self):
|
def reset(self):
|
||||||
self.enable()
|
self.enable()
|
||||||
|
|
||||||
def enableActionEvents(self):
|
def enableActionEvents(self):
|
||||||
|
@ -23,6 +23,15 @@
|
|||||||
name = namedNodeName
|
name = namedNodeName
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
def setName(self, name = '<noname>'):
|
||||||
|
"""Returns the name of the bottom node if it exists, or <noname>"""
|
||||||
|
from PandaModules import *
|
||||||
|
# Get the bottom node
|
||||||
|
node = self.node()
|
||||||
|
# Is it a named node?, If so, see if it has a name
|
||||||
|
if issubclass(node.__class__, NamedNode):
|
||||||
|
node.setName(name)
|
||||||
|
|
||||||
# For iterating over children
|
# For iterating over children
|
||||||
def getChildrenAsList(self):
|
def getChildrenAsList(self):
|
||||||
"""Converts a node path's child NodePathCollection into a list"""
|
"""Converts a node path's child NodePathCollection into a list"""
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,28 +2,29 @@ from PandaObject import *
|
|||||||
from DirectGeometry import *
|
from DirectGeometry import *
|
||||||
|
|
||||||
class PieMenu(NodePath, PandaObject):
|
class PieMenu(NodePath, PandaObject):
|
||||||
def __init__(self, direct, menu, action = None, fUpdateOnlyOnChange = 1):
|
def __init__(self, visibleMenu, menuItems,
|
||||||
|
action = None, fUpdateOnlyOnChange = 1):
|
||||||
NodePath.__init__(self)
|
NodePath.__init__(self)
|
||||||
# Create a toplevel node for aspect ratio scaling
|
# Create a toplevel node for aspect ratio scaling
|
||||||
self.assign(hidden.attachNewNode(NamedNode('PieMenu')))
|
self.assign(hidden.attachNewNode(NamedNode('PieMenu')))
|
||||||
# Attach the menu
|
# Attach the menu
|
||||||
self.menu = menu
|
self.visibleMenu = visibleMenu
|
||||||
# Try to flatten the menu (note, flattenStrong is too strong
|
# Try to flatten the visibleMenu (note, flattenStrong is too strong
|
||||||
# for texture text
|
# for texture text
|
||||||
menu.flattenMedium()
|
self.visibleMenu.flattenMedium()
|
||||||
self.menu.reparentTo(self)
|
self.visibleMenu.reparentTo(self)
|
||||||
# Initialize instance variables
|
# Initialize instance variables
|
||||||
self.direct = direct
|
self.menuItems = menuItems
|
||||||
self.numItems = self.menu.getNumChildren()
|
self.numItems = len(self.menuItems)
|
||||||
self.degreesPerItem = 360.0/self.numItems
|
self.degreesPerItem = 360.0/self.numItems
|
||||||
self.itemOffset = self.degreesPerItem / 2.0
|
self.itemOffset = self.degreesPerItem / 2.0
|
||||||
self.sfx = self.menu.getSx()
|
self.sfx = self.visibleMenu.getSx()
|
||||||
self.sfz = self.menu.getSz()
|
self.sfz = self.visibleMenu.getSz()
|
||||||
# Record target and action
|
# Record target and action
|
||||||
self.action = action
|
self.action = action
|
||||||
self.initialState = None
|
self.initialState = None
|
||||||
# Marking lines
|
# Marking lines
|
||||||
self.lines = LineNodePath(self.menu)
|
self.lines = LineNodePath(self.visibleMenu)
|
||||||
self.lines.setColor(VBase4(1))
|
self.lines.setColor(VBase4(1))
|
||||||
self.lines.setThickness(1)
|
self.lines.setThickness(1)
|
||||||
# Set flags
|
# Set flags
|
||||||
@ -43,15 +44,15 @@ class PieMenu(NodePath, PandaObject):
|
|||||||
taskMgr.removeTasksNamed('pieMenuTask')
|
taskMgr.removeTasksNamed('pieMenuTask')
|
||||||
|
|
||||||
# Where did the user press the button?
|
# Where did the user press the button?
|
||||||
self.originX = self.direct.chan.mouseX
|
self.originX = direct.chan.mouseX
|
||||||
self.originY = self.direct.chan.mouseY
|
self.originY = direct.chan.mouseY
|
||||||
|
|
||||||
# Pop up menu
|
# Pop up menu
|
||||||
self.reparentTo(render2d)
|
self.reparentTo(render2d)
|
||||||
self.setPos(self.originX,0.0,self.originY)
|
self.setPos(self.originX,0.0,self.originY)
|
||||||
# Compensate for window aspect ratio
|
# Compensate for window aspect ratio
|
||||||
self.setScale(1.0, 1.0,1.0)
|
self.setScale(1.0, 1.0,1.0)
|
||||||
#self.direct.chan.width/float(self.direct.chan.height))
|
#direct.chan.width/float(direct.chan.height))
|
||||||
# Start drawing the selection line
|
# Start drawing the selection line
|
||||||
self.lines.reset()
|
self.lines.reset()
|
||||||
self.lines.moveTo(0,0,0)
|
self.lines.moveTo(0,0,0)
|
||||||
@ -64,8 +65,8 @@ class PieMenu(NodePath, PandaObject):
|
|||||||
taskMgr.spawnTaskNamed(t, 'pieMenuTask')
|
taskMgr.spawnTaskNamed(t, 'pieMenuTask')
|
||||||
|
|
||||||
def pieMenuTask(self,state):
|
def pieMenuTask(self,state):
|
||||||
mouseX = self.direct.chan.mouseX
|
mouseX = direct.chan.mouseX
|
||||||
mouseY = self.direct.chan.mouseY
|
mouseY = direct.chan.mouseY
|
||||||
deltaX = mouseX - self.originX
|
deltaX = mouseX - self.originX
|
||||||
deltaY = mouseY - self.originY
|
deltaY = mouseY - self.originY
|
||||||
|
|
||||||
@ -78,10 +79,10 @@ class PieMenu(NodePath, PandaObject):
|
|||||||
if self.fUpdateOnlyOnChange:
|
if self.fUpdateOnlyOnChange:
|
||||||
# Only do this when things change
|
# Only do this when things change
|
||||||
if (self.currItem != -1):
|
if (self.currItem != -1):
|
||||||
self.performAction(-1)
|
self.performAction(self.initialState)
|
||||||
else:
|
else:
|
||||||
# Alway let use know mouse is in the center
|
# Alway let use know mouse is in the center
|
||||||
self.performAction(-1)
|
self.performAction(self.initialState)
|
||||||
self.currItem = -1
|
self.currItem = -1
|
||||||
else:
|
else:
|
||||||
# Outside of the center
|
# Outside of the center
|
||||||
@ -95,9 +96,9 @@ class PieMenu(NodePath, PandaObject):
|
|||||||
|
|
||||||
if self.fUpdateOnlyOnChange:
|
if self.fUpdateOnlyOnChange:
|
||||||
if (self.currItem != newItem):
|
if (self.currItem != newItem):
|
||||||
self.performAction(newItem)
|
self.performAction(self.menuItems[newItem])
|
||||||
else:
|
else:
|
||||||
self.performAction(newItem)
|
self.performAction(self.menuItems[newItem])
|
||||||
self.currItem = newItem
|
self.currItem = newItem
|
||||||
# Continue task
|
# Continue task
|
||||||
return Task.cont
|
return Task.cont
|
||||||
@ -111,11 +112,6 @@ class PieMenu(NodePath, PandaObject):
|
|||||||
def setItemOffset(self,newOffset):
|
def setItemOffset(self,newOffset):
|
||||||
self.itemOffset = newOffset
|
self.itemOffset = newOffset
|
||||||
|
|
||||||
def setNumItems(self,num):
|
|
||||||
self.numItems = num
|
|
||||||
self.degreesPerItem = 360.0 / self.numItems
|
|
||||||
self.itemOffset = self.degreesPerItem / 2.0
|
|
||||||
|
|
||||||
def setUpdateOnlyOnChange(self,flag):
|
def setUpdateOnlyOnChange(self,flag):
|
||||||
self.fUpdateOnlyOnChange = flag
|
self.fUpdateOnlyOnChange = flag
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ def tkloop(self):
|
|||||||
# dooneevent will return 0 if there are no more events
|
# dooneevent will return 0 if there are no more events
|
||||||
# waiting or 1 if there are still more.
|
# waiting or 1 if there are still more.
|
||||||
# DONT_WAIT tells tkinter not to block waiting for events
|
# DONT_WAIT tells tkinter not to block waiting for events
|
||||||
while tkinter.dooneevent(tkinter.DONT_WAIT):
|
while tkinter.dooneevent(tkinter.ALL_EVENTS | tkinter.DONT_WAIT):
|
||||||
pass
|
pass
|
||||||
# Run forever
|
# Run forever
|
||||||
return Task.cont
|
return Task.cont
|
||||||
@ -19,3 +19,5 @@ from TaskManagerGlobal import *
|
|||||||
|
|
||||||
# Spawn this task
|
# Spawn this task
|
||||||
taskMgr.spawnTaskNamed(Task.Task(tkloop), "tkloop")
|
taskMgr.spawnTaskNamed(Task.Task(tkloop), "tkloop")
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ from Tkinter import *
|
|||||||
from Tree import *
|
from Tree import *
|
||||||
import Pmw
|
import Pmw
|
||||||
|
|
||||||
|
|
||||||
class SceneGraphExplorer(Pmw.MegaWidget):
|
class SceneGraphExplorer(Pmw.MegaWidget):
|
||||||
"Graphical display of a scene graph"
|
"Graphical display of a scene graph"
|
||||||
def __init__(self, root = render, parent = None, **kw):
|
def __init__(self, root = render, parent = None, **kw):
|
||||||
@ -53,6 +52,10 @@ class SceneGraphExplorer(Pmw.MegaWidget):
|
|||||||
# Check keywords and initialise options based on input values.
|
# Check keywords and initialise options based on input values.
|
||||||
self.initialiseoptions(SceneGraphExplorer)
|
self.initialiseoptions(SceneGraphExplorer)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
""" Refresh scene graph explorer """
|
||||||
|
self._node.update()
|
||||||
|
|
||||||
def mouse2Down(self, event):
|
def mouse2Down(self, event):
|
||||||
self._width = 1.0 * self._canvas.winfo_width()
|
self._width = 1.0 * self._canvas.winfo_width()
|
||||||
self._height = 1.0 * self._canvas.winfo_height()
|
self._height = 1.0 * self._canvas.winfo_height()
|
||||||
@ -112,9 +115,15 @@ class SceneGraphExplorerItem(TreeItem):
|
|||||||
return sublist
|
return sublist
|
||||||
|
|
||||||
def OnSelect(self):
|
def OnSelect(self):
|
||||||
messenger.send('SGEFlashNodePath', [self.nodePath])
|
messenger.send('SGENodePath_Flash', [self.nodePath])
|
||||||
|
|
||||||
def MenuCommand(self, command):
|
def MenuCommand(self, command):
|
||||||
messenger.send('SGE' + command + 'NodePath', [self.nodePath])
|
messenger.send('SGENodePath_' + command, [self.nodePath])
|
||||||
|
|
||||||
|
|
||||||
|
def explore(nodePath):
|
||||||
|
tl = Toplevel()
|
||||||
|
tl.title('Explore: ' + nodePath.getName())
|
||||||
|
sge = SceneGraphExplorer(parent = tl, root = nodePath)
|
||||||
|
sge.pack(expand = 1, fill = 'both')
|
||||||
|
return sge
|
||||||
|
Loading…
x
Reference in New Issue
Block a user