Browse Source

*** empty log message ***

Mark Mine 25 years ago
parent
commit
9e9defff7e

+ 4 - 4
direct/src/directdevices/DirectDeviceManager.py

@@ -45,7 +45,7 @@ class DirectButtons(ButtonNode, PandaObject):
         self.nodePath = base.dataRoot.attachNewNode(self)
     
     def __getitem__(self, index):
-        if (index < 0) | (index > self.getNumButtons()):
+        if (index < 0) or (index > self.getNumButtons()):
             raise IndexError
         return self.getButtonState(index)
     
@@ -83,7 +83,7 @@ class DirectAnalogs(AnalogNode, PandaObject):
         self.nodePath = base.dataRoot.attachNewNode(self)
     
     def __getitem__(self, index):
-        if (index < 0) | (index > self.getNumControls()):
+        if (index < 0) or (index > self.getNumControls()):
             raise IndexError
         return self.getControlState(index)
     
@@ -111,7 +111,7 @@ class DirectAnalogs(AnalogNode, PandaObject):
     
     def normalizeChannel(self, chan, minVal = -1, maxVal = 1):
         try:
-            if (chan == 2) | (chan == 6):
+            if (chan == 2) or (chan == 6):
                 # These channels have reduced range
                 return self.normalize(self[chan] * 3.0, minVal, maxVal)
             else:
@@ -144,7 +144,7 @@ class DirectDials(DialNode, PandaObject):
         self.nodePath = base.dataRoot.attachNewNode(self)
     
     def __getitem__(self, index):
-        if (index < 0) | (index > self.getNumDials()):
+        if (index < 0) or (index > self.getNumDials()):
             raise IndexError
         return self.readDial(index)
     

+ 6 - 5
direct/src/directtools/DirectCameraControl.py

@@ -57,7 +57,7 @@ class DirectCameraControl(PandaObject):
         # Record undo point
         direct.pushUndo([direct.camera])
 	# Where are we in the display region?
-        if ((abs(direct.dr.mouseX) < 0.9) & (abs(direct.dr.mouseY) < 0.9)):
+        if ((abs(direct.dr.mouseX) < 0.9) and (abs(direct.dr.mouseY) < 0.9)):
             # MOUSE IS IN CENTRAL REGION
             # Hide the marker for this kind of motion
             self.coaMarker.hide()
@@ -73,7 +73,7 @@ class DirectCameraControl(PandaObject):
                 coa.assign(hitPt)
                 coaDist = hitPtDist
                 # Handle case of bad coa point (too close or too far)
-                if ((coaDist < (1.1 * direct.dr.near)) |
+                if ((coaDist < (1.1 * direct.dr.near)) or
                     (coaDist > direct.dr.far)):
                     # Just use existing point
                     coa.assign(self.coaMarker.getPos(direct.camera))
@@ -96,7 +96,7 @@ class DirectCameraControl(PandaObject):
             self.spawnXZTranslateOrHPanYZoom()
             # END MOUSE IN CENTRAL REGION
         else:
-            if ((abs(direct.dr.mouseX) > 0.9) & (abs(direct.dr.mouseY) > 0.9)):
+            if ((abs(direct.dr.mouseX) > 0.9) and (abs(direct.dr.mouseY) > 0.9)):
                 # Mouse is in corners, spawn roll task
                 self.spawnMouseRollTask()
             else:
@@ -217,10 +217,10 @@ class DirectCameraControl(PandaObject):
 
     def mouseRotateTask(self, state):
         # If moving outside of center, ignore motion perpendicular to edge
-        if ((state.constrainedDir == 'y') & (abs(direct.dr.mouseX) > 0.9)):
+        if ((state.constrainedDir == 'y') and (abs(direct.dr.mouseX) > 0.9)):
             deltaX = 0
             deltaY = direct.dr.mouseDeltaY
-        elif ((state.constrainedDir == 'x') & (abs(direct.dr.mouseY) > 0.9)):
+        elif ((state.constrainedDir == 'x') and (abs(direct.dr.mouseY) > 0.9)):
             deltaX = direct.dr.mouseDeltaX
             deltaY = 0
         else:
@@ -291,6 +291,7 @@ class DirectCameraControl(PandaObject):
     def homeCam(self):
         # Record undo point
         direct.pushUndo([direct.camera])
+        direct.camera.reparentTo(render)
         direct.camera.setMat(Mat4.identMat())
         # Resize coa marker
         self.updateCoaMarkerSize()

+ 8 - 8
direct/src/directtools/DirectManipulation.py

@@ -71,7 +71,7 @@ class DirectManipulationControl(PandaObject):
         return Task.done
 
     def watchMouseTask(self, state):
-        if (((abs (state.initX - direct.dr.mouseX)) > 0.01) |
+        if (((abs (state.initX - direct.dr.mouseX)) > 0.01) or
             ((abs (state.initY - direct.dr.mouseY)) > 0.01)):
             taskMgr.removeTasksNamed('manip-move-wait')
             self.mode = 'move'
@@ -197,7 +197,7 @@ class DirectManipulationControl(PandaObject):
         # Compute widget's xy coords in screen space
         t.coaCenter = getScreenXY(direct.widget)
         # These are used to rotate about view vector
-        if t.fMouseX & t.fMouseY:
+        if t.fMouseX and t.fMouseY:
             t.lastAngle = getCrankAngle(t.coaCenter)
         taskMgr.spawnTaskNamed(t, 'manipulateObject')
 
@@ -214,7 +214,7 @@ class DirectManipulationControl(PandaObject):
         # No widget interaction, determine free manip mode
         elif self.fFreeManip:
             # If we've been scaling and changed modes, reset object handles
-            if 0 & self.fScaling & (not direct.fAlt):
+            if 0 and self.fScaling and (not direct.fAlt):
                 self.objectHandles.transferObjectHandlesScale()
                 self.fScaling = 0
             # Alt key switches to a scaling mode
@@ -222,10 +222,10 @@ class DirectManipulationControl(PandaObject):
                 self.fScaling = 1
                 self.scale3D(state)
             # Otherwise, manip mode depends on where you started
-            elif state.fMouseX & state.fMouseY:
+            elif state.fMouseX and state.fMouseY:
                 # In the corner, spin around camera's axis
                 self.rotateAboutViewVector(state)
-            elif state.fMouseX | state.fMouseY:
+            elif state.fMouseX or state.fMouseY:
                 # Mouse started elsewhere in the outer frame, rotate
                 self.rotate2D(state)
             else:
@@ -393,10 +393,10 @@ class DirectManipulationControl(PandaObject):
         self.fScaleInit = 1
         tumbleRate = 360
         # If moving outside of center, ignore motion perpendicular to edge
-        if ((state.constrainedDir == 'y') & (abs(direct.dr.mouseX) > 0.9)):
+        if ((state.constrainedDir == 'y') and (abs(direct.dr.mouseX) > 0.9)):
             deltaX = 0
             deltaY = direct.dr.mouseDeltaY
-        elif ((state.constrainedDir == 'x') & (abs(direct.dr.mouseY) > 0.9)):
+        elif ((state.constrainedDir == 'x') and (abs(direct.dr.mouseY) > 0.9)):
             deltaX = direct.dr.mouseDeltaX
             deltaY = 0
         else:
@@ -450,7 +450,7 @@ class DirectManipulationControl(PandaObject):
         node, hitPt, hitPtDist = direct.iRay.pickGeom(
             fIntersectUnpickable = 1)
         # MRM: Need to handle moving COA
-        if (node != None) & (direct.selected.last != None):
+        if (node != None) and (direct.selected.last != None):
             # Record undo point
             direct.pushUndo(direct.selected)
             # Record wrt matrix

+ 5 - 5
direct/src/directtools/DirectSession.py

@@ -239,9 +239,9 @@ class DirectSession(PandaObject):
             self.selected.toggleVisAll()
         elif input == 'w':
             base.toggleWireframe()
-        elif (input == '[') | (input == '{'):
+        elif (input == '[') or (input == '{'):
             self.undo()
-        elif (input == ']') | (input == '}'):
+        elif (input == ']') or (input == '}'):
             self.redo()
         
     def select(self, nodePath, fMultiSelect = 0, fResetAncestry = 1):
@@ -402,7 +402,7 @@ class DirectSession(PandaObject):
             if i < l:
                 np = self.ancestry[i]
                 name = np.getName()
-                if (name != 'render') & (name != 'renderTop'):
+                if (name != 'render') and (name != 'renderTop'):
                     self.ancestryIndex = i
                     self.select(np, 0, 0)
                     self.flash(np)
@@ -414,7 +414,7 @@ class DirectSession(PandaObject):
             if i >= 0:
                 np = self.ancestry[i]
                 name = np.getName()
-                if (name != 'render') & (name != 'renderTop'):
+                if (name != 'render') and (name != 'renderTop'):
                     self.ancestryIndex = i
                     self.select(np, 0, 0)
                     self.flash(np)
@@ -434,7 +434,7 @@ class DirectSession(PandaObject):
         self.undoList = self.undoList[-25:]
         # Alert anyone who cares
         messenger.send('pushUndo')
-        if fResetRedo & (nodePathList != []):
+        if fResetRedo and (nodePathList != []):
             self.redoList = []
             messenger.send('redoListEmpty')
 

+ 31 - 31
direct/src/leveleditor/LevelEditor.py

@@ -571,7 +571,7 @@ class LevelEditor(NodePath, PandaObject):
                 if parentDNAObject:
                     # Yes it does, move node path (and DNA)
                     # to new parent (if active parent set)
-                    if ((self.NPParent != None) &
+                    if ((self.NPParent != None) and
                         (self.DNAParent != None)):
                         nodePath.reparentTo(self.NPParent)
                         parentDNAObject.remove(dnaNode)
@@ -702,11 +702,11 @@ class LevelEditor(NodePath, PandaObject):
 	chance = randint(0,100)
         if chance <= 15:
             return 5.0
-        elif (chance > 15) & (chance <= 30):
+        elif (chance > 15) and (chance <= 30):
             return 10.0
-        elif (chance > 30) & (chance <= 65):
+        elif (chance > 30) and (chance <= 65):
             return 15.0
-        elif (chance > 65) & (chance <= 85):
+        elif (chance > 65) and (chance <= 85):
             return 20.0
         elif (chance > 85):
             return 25.0
@@ -748,7 +748,7 @@ class LevelEditor(NodePath, PandaObject):
         # destination (part of cleanup
         taskMgr.removeTasksNamed('autoPositionGrid')
         # Now find where to put node path
-        if (hotKey is not None) & nodeClass.eq(DNA_PROP):
+        if (hotKey is not None) and nodeClass.eq(DNA_PROP):
             # If its a prop and a copy, place it based upon current
             # mouse position
             hitPt = self.getGridIntersectionPoint()
@@ -1023,7 +1023,7 @@ class LevelEditor(NodePath, PandaObject):
                     menuMode = 'cornice_orientation'
                 else:
                     menuMode = 'cornice_texture'
-            elif ((xPt < 0.3) | (xPt > 0.7)):
+            elif ((xPt < 0.3) or (xPt > 0.7)):
                 # Do wall operations
                 if direct.fControl:
                     menuMode = 'wall_color'
@@ -1061,10 +1061,10 @@ class LevelEditor(NodePath, PandaObject):
         # Update panel color if appropriate
         if self.DNATarget:
             objClass = DNAGetClassType(self.DNATarget)
-            if ((objClass.eq(DNA_WALL)) |
-                (objClass.eq(DNA_WINDOWS)) |
-                (objClass.eq(DNA_DOOR)) |
-                (objClass.eq(DNA_CORNICE)) |
+            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))
                 ):
                 self.panel.setCurrentColor(self.DNATarget.getColor())
@@ -1075,10 +1075,10 @@ class LevelEditor(NodePath, PandaObject):
             self.replaceSelected()
             
     def setDNATargetCode(self, type, code):
-        if (self.DNATarget != None) & (code != None):
+        if (self.DNATarget != None) and (code != None):
             # Update code
             self.DNATarget.setCode(code)
-        elif (self.DNATarget != None) & (code == None):
+        elif (self.DNATarget != None) and (code == None):
             # Delete object, record pertinant properties before
             # you delete the object so you can restore them later
             # Remove object
@@ -1092,7 +1092,7 @@ class LevelEditor(NodePath, PandaObject):
                 self.removeWindows(self.DNATarget, self.DNATargetParent)
             # Clear out DNATarget
             self.DNATarget = None
-        elif (self.DNATarget == None) & (code != None):
+        elif (self.DNATarget == None) and (code != None):
             # Add new object
             if (type == 'cornice'):
                 self.DNATarget = self.createCornice()
@@ -1114,13 +1114,13 @@ class LevelEditor(NodePath, PandaObject):
         self.replaceSelected()
         
     def setDNATargetOrientation(self, orientation):
-        if (self.DNATarget != None) & (orientation != None):
+        if (self.DNATarget != None) and (orientation != None):
             oldCode = self.DNATarget.getCode()[:-3]
             self.DNATarget.setCode(oldCode + '_' + orientation)
             self.replaceSelected()
             
     def setBuildingStyle(self, style):
-        if (self.DNATarget != None) & (style != None):
+        if (self.DNATarget != None) and (style != None):
             self.styleManager.setDNAFlatBuildingStyle(
                 self.DNATarget, style, 
                 width = self.DNATarget.getWidth(),
@@ -1139,19 +1139,19 @@ class LevelEditor(NodePath, PandaObject):
             self.replaceSelected()
             
     def setWindowCount(self, count):
-        if (self.DNATarget != None) & (count != 0):
+        if (self.DNATarget != None) and (count != 0):
             self.DNATarget.setWindowCount(count)
-        elif (self.DNATarget != None) & (count == 0):
+        elif (self.DNATarget != None) and (count == 0):
             # Remove windows and clear out DNATarget
             self.removeWindows(self.DNATarget, self.DNATargetParent)
             self.DNATarget = None
-        elif (self.DNATarget == None) & (count != 0):
+        elif (self.DNATarget == None) and (count != 0):
             self.DNATarget = self.createWindows()
             self.DNATargetParent.add(self.DNATarget)
         self.replaceSelected()
             
     def setWallStyle(self, style):
-        if (self.DNATarget != None) & (style != None):
+        if (self.DNATarget != None) and (style != None):
             self.styleManager.setDNAWallStyle(
                 self.DNATarget, style,
                 self.DNATarget.getHeight())
@@ -1241,7 +1241,7 @@ class LevelEditor(NodePath, PandaObject):
     # MANIPULATION FUNCTIONS
     def keyboardRotateSelected(self, arrowDirection):
         """ Rotate selected objects using arrow keys """
-        if ((arrowDirection == 'left') | (arrowDirection == 'up')):
+        if ((arrowDirection == 'left') or (arrowDirection == 'up')):
             self.setLastAngle(self.getLastAngle() + SNAP_ANGLE)
         else:
             self.setLastAngle(self.getLastAngle() - SNAP_ANGLE)
@@ -1401,7 +1401,7 @@ class LevelEditor(NodePath, PandaObject):
             return None
 
     def getRandomWindowCount(self):
-        if ((self.lastWall != None) & (self.lastBuilding != None)):
+        if ((self.lastWall != None) and (self.lastBuilding != None)):
             h = ROUND_INT(self.lastWall.getHeight())
             w = ROUND_INT(self.lastBuilding.getWidth())
             # Otherwise....
@@ -1460,7 +1460,7 @@ class LevelEditor(NodePath, PandaObject):
 	taskMgr.removeTasksNamed('autoMoveDelay')
 	handlesToCam = direct.widget.getPos(direct.camera)
 	handlesToCam = handlesToCam * ( direct.dr.near/handlesToCam[1])
-	if ((abs(handlesToCam[0]) > (direct.dr.nearWidth * 0.4)) |
+	if ((abs(handlesToCam[0]) > (direct.dr.nearWidth * 0.4)) or
             (abs(handlesToCam[2]) > (direct.dr.nearHeight * 0.4))):
             taskMgr.removeTasksNamed('manipulateCamera')
             direct.cameraControl.centerCamIn(0.5)
@@ -1701,7 +1701,7 @@ class LevelEditor(NodePath, PandaObject):
         xPt = hitPt[0]
         zPt = hitPt[2]
         # Left or right of building
-        if ((xPt < 0) | (xPt > aDNAFlatBuilding.getWidth())):
+        if ((xPt < 0) or (xPt > aDNAFlatBuilding.getWidth())):
             return -1
         # Below the building
         if zPt < 0:
@@ -2079,7 +2079,7 @@ class LevelStyleManager:
                 pair = map(string.strip, l.split(':'))
                 if style.__dict__.has_key(pair[0]):
                     # Convert colors and count strings to numerical values
-                    if ((string.find(pair[0],'_color') >= 0) |
+                    if ((string.find(pair[0],'_color') >= 0) or
                         (string.find(pair[0],'_count') >= 0)):
                         style[pair[0]] = eval(pair[1])
                     else:
@@ -2482,7 +2482,7 @@ class LevelStyleManager:
         for dnaType in DNA_TYPES:
             # Create a dictionary of dna types
             dict = {}
-            if ((dnaType == 'street') | (dnaType == 'prop') |
+            if ((dnaType == 'street') or (dnaType == 'prop') or
                 (dnaType == 'toon_landmark')):
                 dnaList = self.getCatalogCodes(dnaType)
             else:
@@ -2494,7 +2494,7 @@ class LevelStyleManager:
             attribute = LevelAttribute(dnaType + '_texture')
             attribute.setDict(dict)
             # Prepend None to allow option of no item
-            if ((dnaType == 'street') | (dnaType == 'prop') |
+            if ((dnaType == 'street') or (dnaType == 'prop') or
                 (dnaType == 'toon_landmark')):
                 attribute.setMenu(self.createTextPieMenu(dnaType, dnaList))
             elif (dnaType == 'wall'):
@@ -3320,12 +3320,12 @@ class LevelEditorPanel(Pmw.MegaToplevel):
     def updateSelectedObjColor(self, color):
         try:
             obj = self.levelEditor.DNATarget
-            if self.fUpdateSelected & (obj != None):
+            if self.fUpdateSelected and (obj != None):
                 objClass = DNAGetClassType(obj)
-                if ((objClass.eq(DNA_WALL)) |
-                    (objClass.eq(DNA_WINDOWS)) |
-                    (objClass.eq(DNA_DOOR)) |
-                    (objClass.eq(DNA_CORNICE)) |
+                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))
                     ):
                     self.levelEditor.setDNATargetColor(

+ 1 - 1
direct/src/leveleditor/PieMenu.py

@@ -74,7 +74,7 @@ class PieMenu(NodePath, PandaObject):
         self.lines.setVertex(1,(deltaX/self.sfx),0.0,(deltaY/self.sfz))
 
         # How far from starting point has user moved the cursor?
-        if ((abs(deltaX) < 0.1) & (abs(deltaY) < 0.1)):
+        if ((abs(deltaX) < 0.1) and (abs(deltaY) < 0.1)):
             # In the center
             if self.fUpdateOnlyOnChange:
                 # Only do this when things change

+ 4 - 4
direct/src/showbase/PythonUtil.py

@@ -109,21 +109,21 @@ def _pdir(obj, str = None, fOverloaded = 0, width = None,
         if str:
             if re.search(str, key, re.I):
                 aproposKeys.append(key)
-                if (not width) & (keyWidth > maxWidth):
+                if (not width) and (keyWidth > maxWidth):
                     maxWidth = keyWidth
         else:
             if key[:2] == '__':
                 privateKeys.append(key)
-                if (not width) & (keyWidth > maxWidth):
+                if (not width) and (keyWidth > maxWidth):
                     maxWidth = keyWidth
             elif (key[:10] == 'overloaded'):
                 if fOverloaded:
                     overloadedKeys.append(key)
-                    if (not width) & (keyWidth > maxWidth):
+                    if (not width) and (keyWidth > maxWidth):
                         maxWidth = keyWidth
             else:
                 remainingKeys.append(key)
-                if (not width) & (keyWidth > maxWidth):
+                if (not width) and (keyWidth > maxWidth):
                     maxWidth = keyWidth
     # Sort appropriate keys
     if str:

+ 20 - 20
direct/src/tkpanels/MopathRecorder.py

@@ -672,7 +672,7 @@ class MopathRecorder(AppShell, PandaObject):
         Hook called upon deselection of a node path used to select playback
         marker if subnode selected
         """
-        if ((nodePath.id() == self.playbackMarker.id()) |
+        if ((nodePath.id() == self.playbackMarker.id()) or
             (nodePath.id() == self.tangentMarker.id())):
             self.tangentGroup.hide()
 
@@ -947,7 +947,7 @@ class MopathRecorder(AppShell, PandaObject):
                 self.recordPoint(self.recordStart)
             # Everything else
             else:
-                if ((self.recordingType.get() == 'Refine') |
+                if ((self.recordingType.get() == 'Refine') or
                     (self.recordingType.get() == 'Extend')):
                     # Turn off looping playback
                     self.loopPlayback = 0
@@ -972,7 +972,7 @@ class MopathRecorder(AppShell, PandaObject):
             if self.samplingMode == 'Continuous':
                 # Kill old task
                 taskMgr.removeTasksNamed(self.name + '-recordTask')
-                if ((self.recordingType.get() == 'Refine') |
+                if ((self.recordingType.get() == 'Refine') or
                     (self.recordingType.get() == 'Extend')):
                     # Reparent node path back to parent
                     self['nodePath'].wrtReparentTo(self.nodePathParent)
@@ -988,7 +988,7 @@ class MopathRecorder(AppShell, PandaObject):
             self.setSamplingMode('Continuous')
             self.enableKeyframeButton()
             # Clean up after refine or extend
-            if ((self.recordingType.get() == 'Refine') |
+            if ((self.recordingType.get() == 'Refine') or
                 (self.recordingType.get() == 'Extend')):
                 # Merge prePoints, pointSet, postPoints
                 self.mergePoints()
@@ -1008,7 +1008,7 @@ class MopathRecorder(AppShell, PandaObject):
 
     def addKeyframe(self, fToggleRecord = 1):
         # Make sure we're in a recording mode!
-        if (fToggleRecord &
+        if (fToggleRecord and
             (not self.getVariable('Recording', 'Record').get())):
             # Set sampling mode
             self.setSamplingMode('Keyframe')
@@ -1042,16 +1042,16 @@ class MopathRecorder(AppShell, PandaObject):
 
     def recordPoint(self, time):
         # Call user define callback before recording point
-        if (self.getVariable('Recording', 'PRF Active').get() &
+        if (self.getVariable('Recording', 'PRF Active').get() and
             (self.preRecordFunc != None)):
             self.preRecordFunc()
         # Get point
         pos = self['nodePath'].getPos(self.nodePathParent)
         hpr = self['nodePath'].getHpr(self.nodePathParent)
         # Blend between recordNodePath and self['nodePath']
-        if ((self.recordingType.get() == 'Refine') |
+        if ((self.recordingType.get() == 'Refine') or
             (self.recordingType.get() == 'Extend')):
-            if ((time < self.controlStart) &
+            if ((time < self.controlStart) and
                 ((self.controlStart - self.recordStart) != 0.0)):
                 rPos = self.playbackNodePath.getPos(self.nodePathParent)
                 rHpr = self.playbackNodePath.getHpr(self.nodePathParent)
@@ -1060,8 +1060,8 @@ class MopathRecorder(AppShell, PandaObject):
                 # Transition between the recorded node path and the driven one
                 pos = (rPos * (1 - t)) + (pos * t)
                 hpr = (rHpr * (1 - t)) + (hpr * t)
-            elif ((self.recordingType.get() == 'Refine') &
-                  (time > self.controlStop) &
+            elif ((self.recordingType.get() == 'Refine') and
+                  (time > self.controlStop) and
                   ((self.recordStop - self.controlStop) != 0.0)):
                 rPos = self.playbackNodePath.getPos(self.nodePathParent)
                 rHpr = self.playbackNodePath.getHpr(self.nodePathParent)
@@ -1084,7 +1084,7 @@ class MopathRecorder(AppShell, PandaObject):
 
     def computeCurves(self):
         # Check to make sure curve fitters have points
-        if ((self.xyzCurveFitter.getNumSamples() == 0) |
+        if ((self.xyzCurveFitter.getNumSamples() == 0) or
             (self.hprCurveFitter.getNumSamples() == 0)):
             print 'MopathRecorder.computeCurves: Must define curve first'
             return
@@ -1288,7 +1288,7 @@ class MopathRecorder(AppShell, PandaObject):
         self.loopPlayback = self.getVariable('Playback', 'Loop').get()
 
     def playbackGoTo(self, time):
-        if (self.xyzNurbsCurve == None) & (self.hprNurbsCurve == None):
+        if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None):
             return
         self.playbackTime = CLAMP(time, 0.0, self.maxT)
         if self.xyzNurbsCurve != None:
@@ -1301,7 +1301,7 @@ class MopathRecorder(AppShell, PandaObject):
             self.playbackNodePath.setHpr(self.nodePathParent, hpr)
 
     def startPlayback(self):
-        if (self.xyzNurbsCurve == None) & (self.hprNurbsCurve == None):
+        if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None):
             return
         # Kill any existing tasks
         self.stopPlayback()
@@ -1329,7 +1329,7 @@ class MopathRecorder(AppShell, PandaObject):
             cTime = state.currentTime + dTime
         # Stop task if not looping and at end of curve
         # Or if refining curve and past recordStop
-        if ((self.recordingType.get() == 'Refine') &
+        if ((self.recordingType.get() == 'Refine') and
               (cTime > self.recordStop)):
             # Go to recordStop
             self.getWidget('Playback', 'Time').set(self.recordStop)
@@ -1338,8 +1338,8 @@ class MopathRecorder(AppShell, PandaObject):
             # Also kill record task
             self.toggleRecordVar()
             return Task.done
-        elif (((self.loopPlayback == 0) & (cTime > self.maxT)) |
-            ((self.recordingType.get() == 'Extend') & (cTime > self.maxT))):
+        elif (((self.loopPlayback == 0) and (cTime > self.maxT)) or
+            ((self.recordingType.get() == 'Extend') and (cTime > self.maxT))):
             # Go to maxT
             self.getWidget('Playback', 'Time').set(self.maxT)
             # Then stop playback
@@ -1373,7 +1373,7 @@ class MopathRecorder(AppShell, PandaObject):
         self.desampleFrequency = frequency
         
     def desampleCurve(self):
-        if ((self.xyzCurveFitter.getNumSamples() == 0) |
+        if ((self.xyzCurveFitter.getNumSamples() == 0) or
             (self.hprCurveFitter.getNumSamples() == 0)):
             print 'MopathRecorder.desampleCurve: Must define curve first'
             return
@@ -1393,7 +1393,7 @@ class MopathRecorder(AppShell, PandaObject):
         self.numSamples = int(numSamples)
         
     def sampleCurve(self, even = 'None Given'):
-        if (self.xyzNurbsCurve == None) & (self.hprNurbsCurve == None):
+        if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None):
             print 'MopathRecorder.sampleCurve: Must define curve first'
             return
         # Reset curve fitters
@@ -1662,7 +1662,7 @@ class MopathRecorder(AppShell, PandaObject):
         # Get points within bounds
         for time, pos, hpr in oldPoints:
             # Is it within the time?
-            if ((time > self.cropFrom) &
+            if ((time > self.cropFrom) and
                 (time < self.cropTo)):
                 # Add it to the curve fitters
                 t = time - self.cropFrom
@@ -1707,7 +1707,7 @@ class MopathRecorder(AppShell, PandaObject):
             nodePath = loader.loadModel(mopathFilename)
             if nodePath:
                 self.extractCurves(nodePath)
-                if ((self.xyzNurbsCurve != None) & 
+                if ((self.xyzNurbsCurve != None) and 
                     (self.hprNurbsCurve != None)):
                     # Save a pointset for this curve
                     self.savePointSet()

+ 6 - 6
direct/src/tkpanels/Placer.py

@@ -455,7 +455,7 @@ class Placer(AppShell):
             self.nodePathMenuEntry.configure(
                 background = self.nodePathMenuBG)
             # Check to see if node path and ref node path are the same
-            if ((self.refCS != None) &
+            if ((self.refCS != None) and
                 (self.refCS.id() == self['nodePath'].id())):
                 # Yes they are, use temp CS as ref
                 # This calls updatePlacer
@@ -499,7 +499,7 @@ class Placer(AppShell):
                     listbox = self.refNodePathMenu.component('scrolledlist')
                     listbox.setlist(self.refNodePathNames)
         # Check to see if node path and ref node path are the same
-        if (nodePath != None) & (nodePath.id() == self['nodePath'].id()):
+        if (nodePath != None) and (nodePath.id() == self['nodePath'].id()):
             # Yes they are, use temp CS and update listbox accordingly
             nodePath = self.tempCS
             self.refNodePathMenu.selectitem('self')
@@ -549,7 +549,7 @@ class Placer(AppShell):
         hpr = Vec3(0)
         scale = Vec3(1)
         np = self['nodePath']
-        if (np != None) & isinstance(np, NodePath):
+        if (np != None) and isinstance(np, NodePath):
             # Update temp CS
             self.updateAuxiliaryCoordinateSystems()
             # Update widgets
@@ -620,7 +620,7 @@ class Placer(AppShell):
 
     def xformRelative(self, value, axis):
         nodePath = self['nodePath']
-        if (nodePath != None) & (self.refCS != None):
+        if (nodePath != None) and (self.refCS != None):
             if axis == 'x':
                 nodePath.setX(self.refCS, value)
             elif axis == 'y':
@@ -639,8 +639,8 @@ class Placer(AppShell):
 
     def xformOrbit(self, value, axis):
         nodePath = self['nodePath']
-        if ((nodePath != None) & (self.refCS != None) &
-            (self.orbitFromCS != None) & (self.orbitToCS != None)):
+        if ((nodePath != None) and (self.refCS != None) and
+            (self.orbitFromCS != None) and (self.orbitToCS != None)):
             if axis == 'x':
                 self.posOffset.setX(value)
             elif axis == 'y':

+ 3 - 3
direct/src/tkwidgets/Dial.py

@@ -232,9 +232,9 @@ class Dial(Pmw.MegaWidget):
         delta = self.delta
         dialAngle = dialAngle % TWO_PI
         # Check for rollover, if necessary
-        if (self.lastAngle > ONEPOINTFIVE_PI) & (dialAngle < POINTFIVE_PI):
+        if (self.lastAngle > ONEPOINTFIVE_PI) and (dialAngle < POINTFIVE_PI):
             self.baseVal = self.baseVal + delta
-        elif (self.lastAngle < POINTFIVE_PI) & (dialAngle > ONEPOINTFIVE_PI):
+        elif (self.lastAngle < POINTFIVE_PI) and (dialAngle > ONEPOINTFIVE_PI):
             self.baseVal = self.baseVal - delta
         self.lastAngle = dialAngle
         # Update value and entry
@@ -257,7 +257,7 @@ class Dial(Pmw.MegaWidget):
             self.dialAngle = None
         else:
             self.updateIndicator(value)
-        if fCommand & (self['command'] != None):
+        if fCommand and (self['command'] != None):
             apply(self['command'], [value] + self['commandData'])
 
     def updateIndicator(self, value):

+ 2 - 2
direct/src/tkwidgets/EntryScale.py

@@ -223,7 +223,7 @@ class EntryScale(Pmw.MegaWidget):
         self.entry.checkentry()
         
         # execute command
-        if fCommand & (self['command'] is not None):
+        if fCommand and (self['command'] is not None):
             self['command']( newVal )
 
     def onReturn(self, *args):
@@ -349,7 +349,7 @@ class EntryScaleGroup(Pmw.MegaToplevel):
             self._value[i] = value[i]
             # Update entryScale, but don't execute its command
             self.entryScaleList[i].set(value[i], 0)
-        if fCommand & (self['command'] is not None):
+        if fCommand and (self['command'] is not None):
             self['command'](self._value)
 
     def setAt(self, index, value):

+ 2 - 2
direct/src/tkwidgets/Floater.py

@@ -182,7 +182,7 @@ class Floater(Pmw.MegaWidget):
         self.entry.checkentry()
         
         # execute command
-        if fCommand & (self['command'] is not None):
+        if fCommand and (self['command'] is not None):
             apply(self['command'], [newVal] + self['commandData'])
 
     def reset(self):
@@ -305,7 +305,7 @@ class FloaterGroup(Pmw.MegaToplevel):
             self._value[i] = value[i]
             # Update floater, but don't execute its command
             self.floaterList[i].set(value[i], 0)
-        if fCommand & (self['command'] is not None):
+        if fCommand and (self['command'] is not None):
             self['command'](self._value)
 
     def setAt(self, index, value):

+ 357 - 357
direct/src/tkwidgets/Tree.py

@@ -1,357 +1,357 @@
-# ADAPTED FROM IDLE TreeWidget.py
-# XXX TO DO:
-# - popup menu
-# - support partial or total redisplay
-# - key bindings (instead of quick-n-dirty bindings on Canvas):
-#   - up/down arrow keys to move focus around
-#   - ditto for page up/down, home/end
-#   - left/right arrows to expand/collapse & move out/in
-# - more doc strings
-# - add icons for "file", "module", "class", "method"; better "python" icon
-# - callback for selection???
-# - multiple-item selection
-# - tooltips
-# - redo geometry without magic numbers
-# - keep track of object ids to allow more careful cleaning
-# - optimize tree redraw after expand of subnode
-
-import os
-import sys
-import string
-from Tkinter import *
-from PandaObject import *
-
-# Initialize icon directory
-f = Filename('icons')
-f.resolveFilename(getModelPath())
-ICONDIR = f.toOsSpecific()
-if not os.path.isdir(ICONDIR):
-    raise RuntimeError, "can't find DIRECT icon directory (%s)" % `ICONDIR`
-
-class TreeNode:
-
-    def __init__(self, canvas, parent, item, menuList = []):
-        self.canvas = canvas
-        self.parent = parent
-        self.item = item
-        self.state = 'collapsed'
-        self.selected = 0
-        self.children = {}
-        self.kidKeys = []
-        self.x = self.y = None
-        self.iconimages = {} # cache of PhotoImage instances for icons
-        self.menuList = menuList
-        self.menuVar = IntVar()
-        self.menuVar.set(0)
-        self._popupMenu = None
-        if self.menuList:
-            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)
-
-    def destroy(self):
-        for key in self.kidKeys:
-            c = self.children[key]
-            del self.children[key]
-            c.destroy()
-        self.parent = None
-
-    def geticonimage(self, name):
-        try:
-            return self.iconimages[name]
-        except KeyError:
-            pass
-        file, ext = os.path.splitext(name)
-        ext = ext or ".gif"
-        fullname = os.path.join(ICONDIR, file + ext)
-        image = PhotoImage(master=self.canvas, file=fullname)
-        self.iconimages[name] = image
-        return image
-
-    def select(self, event=None):
-        if self.selected:
-            return
-        self.deselectall()
-        self.selected = 1
-        self.canvas.delete(self.image_id)
-        self.drawicon()
-        self.drawtext()
-        self.item.OnSelect()
-
-    def deselect(self, event=None):
-        if not self.selected:
-            return
-        self.selected = 0
-        self.canvas.delete(self.image_id)
-        self.drawicon()
-        self.drawtext()
-
-    def deselectall(self):
-        if self.parent:
-            self.parent.deselectall()
-        else:
-            self.deselecttree()
-
-    def deselecttree(self):
-        if self.selected:
-            self.deselect()
-        for key in self.kidKeys:
-            child = self.children[key]
-            child.deselecttree()
-
-    def flip(self, event=None):
-        if self.state == 'expanded':
-            self.collapse()
-        else:
-            self.expand()
-        self.item.OnDoubleClick()
-        return "break"
-
-    def popupMenu(self, event=None):
-        if self._popupMenu:
-            self._popupMenu.post(event.widget.winfo_pointerx(),
-                                 event.widget.winfo_pointery())
-            return "break"
-
-    def popupMenuCommand(self):
-        self.item.MenuCommand(self.menuList[self.menuVar.get()])
-
-    def expand(self, event=None):
-        if not self.item.IsExpandable():
-            return
-        if self.state != 'expanded':
-            self.state = 'expanded'
-            self.update()
-            self.view()
-
-    def collapse(self, event=None):
-        if self.state != 'collapsed':
-            self.state = 'collapsed'
-            self.update()
-
-    def view(self):
-        top = self.y - 2
-        bottom = self.lastvisiblechild().y + 17
-        height = bottom - top
-        visible_top = self.canvas.canvasy(0)
-        visible_height = self.canvas.winfo_height()
-        visible_bottom = self.canvas.canvasy(visible_height)
-        if visible_top <= top and bottom <= visible_bottom:
-            return
-        x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion'])
-        if top >= visible_top and height <= visible_height:
-            fraction = top + height - visible_height
-        else:
-            fraction = top
-        fraction = float(fraction) / y1
-        self.canvas.yview_moveto(fraction)
-
-    def lastvisiblechild(self):
-        if self.kidKeys and self.state == 'expanded':
-            return self.children[self.kidKeys[-1]].lastvisiblechild()
-        else:
-            return self
-
-    def update(self):
-        if self.parent:
-            self.parent.update()
-        else:
-            oldcursor = self.canvas['cursor']
-            self.canvas['cursor'] = "watch"
-            self.canvas.update()
-            self.canvas.delete(ALL)     # XXX could be more subtle
-            self.draw(7, 2)
-            x0, y0, x1, y1 = self.canvas.bbox(ALL)
-            self.canvas.configure(scrollregion=(0, 0, x1, y1))
-            self.canvas['cursor'] = oldcursor
-
-    def draw(self, x, y):
-        # XXX This hard-codes too many geometry constants!
-        self.x, self.y = x, y
-        self.drawicon()
-        self.drawtext()
-        if self.state != 'expanded':
-            return y+17
-        # draw children
-        #if not self.children:
-        #self.children = []
-        sublist = self.item._GetSubList()
-        if not sublist:
-            # IsExpandable() was mistaken; that's allowed
-            return y+17
-        self.kidKeys = []
-        for item in sublist:
-            key = item.nodePath.id()
-            if self.children.has_key(key):
-                child = self.children[key]
-            else:
-                child = TreeNode(self.canvas, self, item, self.menuList)
-            self.children[key] = child
-            self.kidKeys.append(key)
-        cx = x+20
-        cy = y+17
-        cylast = 0
-        for key in self.kidKeys:
-            child = self.children[key]
-            cylast = cy
-            self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50")
-            cy = child.draw(cx, cy)
-            if child.item.IsExpandable():
-                if child.state == 'expanded':
-                    iconname = "minusnode"
-                    callback = child.collapse
-                else:
-                    iconname = "plusnode"
-                    callback = child.expand
-                image = self.geticonimage(iconname)
-                id = self.canvas.create_image(x+9, cylast+7, image=image)
-                # XXX This leaks bindings until canvas is deleted:
-                self.canvas.tag_bind(id, "<1>", callback)
-                self.canvas.tag_bind(id, "<Double-1>", lambda x: None)
-        id = self.canvas.create_line(x+9, y+10, x+9, cylast+7,
-            ##stipple="gray50",     # XXX Seems broken in Tk 8.0.x
-            fill="gray50")
-        self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2
-        return cy
-
-    def drawicon(self):
-        if self.selected:
-            imagename = (self.item.GetSelectedIconName() or
-                         self.item.GetIconName() or
-                         "openfolder")
-        else:
-            imagename = self.item.GetIconName() or "folder"
-        image = self.geticonimage(imagename)
-        id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image)
-        self.image_id = id
-        self.canvas.tag_bind(id, "<1>", self.select)
-        self.canvas.tag_bind(id, "<Double-1>", self.flip)
-        self.canvas.tag_bind(id, "<3>", self.popupMenu)
-        
-    def drawtext(self):
-        textx = self.x+20-1
-        texty = self.y-1
-        labeltext = self.item.GetLabelText()
-        if labeltext:
-            id = self.canvas.create_text(textx, texty, anchor="nw",
-                                         text=labeltext)
-            self.canvas.tag_bind(id, "<1>", self.select)
-            self.canvas.tag_bind(id, "<Double-1>", self.flip)
-            x0, y0, x1, y1 = self.canvas.bbox(id)
-            textx = max(x1, 200) + 10
-        text = self.item.GetText() or "<no text>"
-        try:
-            self.entry
-        except AttributeError:
-            pass
-        else:
-            self.edit_finish()
-        try:
-            label = self.label
-        except AttributeError:
-            # padding carefully selected (on Windows) to match Entry widget:
-            self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2)
-        if self.selected:
-            self.label.configure(fg="white", bg="darkblue")
-        else:
-            self.label.configure(fg="black", bg="white")
-        id = self.canvas.create_window(textx, texty,
-                                       anchor="nw", window=self.label)
-        self.label.bind("<1>", self.select_or_edit)
-        self.label.bind("<Double-1>", self.flip)
-        self.label.bind("<3>", self.popupMenu)
-        self.text_id = id
-
-    def select_or_edit(self, event=None):
-        if self.selected and self.item.IsEditable():
-            self.edit(event)
-        else:
-            self.select(event)
-
-    def edit(self, event=None):
-        self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0)
-        self.entry.insert(0, self.label['text'])
-        self.entry.selection_range(0, END)
-        self.entry.pack(ipadx=5)
-        self.entry.focus_set()
-        self.entry.bind("<Return>", self.edit_finish)
-        self.entry.bind("<Escape>", self.edit_cancel)
-
-    def edit_finish(self, event=None):
-        try:
-            entry = self.entry
-            del self.entry
-        except AttributeError:
-            return
-        text = entry.get()
-        entry.destroy()
-        if text and text != self.item.GetText():
-            self.item.SetText(text)
-        text = self.item.GetText()
-        self.label['text'] = text
-        self.drawtext()
-        self.canvas.focus_set()
-
-    def edit_cancel(self, event=None):
-        self.drawtext()
-        self.canvas.focus_set()
-
-
-class TreeItem:
-
-    """Abstract class representing tree items.
-
-    Methods should typically be overridden, otherwise a default action
-    is used.
-
-    """
-
-    def __init__(self):
-        """Constructor.  Do whatever you need to do."""
-
-    def GetText(self):
-        """Return text string to display."""
-
-    def GetLabelText(self):
-        """Return label text string to display in front of text (if any)."""
-
-    def IsExpandable(self):
-        """Return whether there are subitems."""
-        return 1
-
-    def _GetSubList(self):
-        """Do not override!  Called by TreeNode."""
-        if not self.IsExpandable():
-            return []
-        sublist = self.GetSubList()
-        return sublist
-
-    def IsEditable(self):
-        """Return whether the item's text may be edited."""
-
-    def SetText(self, text):
-        """Change the item's text (if it is editable)."""
-
-    def GetIconName(self):
-        """Return name of icon to be displayed normally."""
-
-    def GetSelectedIconName(self):
-        """Return name of icon to be displayed when selected."""
-
-    def GetSubList(self):
-        """Return list of items forming sublist."""
-
-    def OnDoubleClick(self):
-        """Called on a double-click on the item."""
-
-    def OnSelect(self):
-        """Called when item selected."""
-
-
-
+# ADAPTED FROM IDLE TreeWidget.py
+# XXX TO DO:
+# - popup menu
+# - support partial or total redisplay
+# - key bindings (instead of quick-n-dirty bindings on Canvas):
+#   - up/down arrow keys to move focus around
+#   - ditto for page up/down, home/end
+#   - left/right arrows to expand/collapse and move out/in
+# - more doc strings
+# - add icons for "file", "module", "class", "method"; better "python" icon
+# - callback for selection???
+# - multiple-item selection
+# - tooltips
+# - redo geometry without magic numbers
+# - keep track of object ids to allow more careful cleaning
+# - optimize tree redraw after expand of subnode
+
+import os
+import sys
+import string
+from Tkinter import *
+from PandaObject import *
+
+# Initialize icon directory
+f = Filename('icons')
+f.resolveFilename(getModelPath())
+ICONDIR = f.toOsSpecific()
+if not os.path.isdir(ICONDIR):
+    raise RuntimeError, "can't find DIRECT icon directory (%s)" % `ICONDIR`
+
+class TreeNode:
+
+    def __init__(self, canvas, parent, item, menuList = []):
+        self.canvas = canvas
+        self.parent = parent
+        self.item = item
+        self.state = 'collapsed'
+        self.selected = 0
+        self.children = {}
+        self.kidKeys = []
+        self.x = self.y = None
+        self.iconimages = {} # cache of PhotoImage instances for icons
+        self.menuList = menuList
+        self.menuVar = IntVar()
+        self.menuVar.set(0)
+        self._popupMenu = None
+        if self.menuList:
+            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)
+
+    def destroy(self):
+        for key in self.kidKeys:
+            c = self.children[key]
+            del self.children[key]
+            c.destroy()
+        self.parent = None
+
+    def geticonimage(self, name):
+        try:
+            return self.iconimages[name]
+        except KeyError:
+            pass
+        file, ext = os.path.splitext(name)
+        ext = ext or ".gif"
+        fullname = os.path.join(ICONDIR, file + ext)
+        image = PhotoImage(master=self.canvas, file=fullname)
+        self.iconimages[name] = image
+        return image
+
+    def select(self, event=None):
+        if self.selected:
+            return
+        self.deselectall()
+        self.selected = 1
+        self.canvas.delete(self.image_id)
+        self.drawicon()
+        self.drawtext()
+        self.item.OnSelect()
+
+    def deselect(self, event=None):
+        if not self.selected:
+            return
+        self.selected = 0
+        self.canvas.delete(self.image_id)
+        self.drawicon()
+        self.drawtext()
+
+    def deselectall(self):
+        if self.parent:
+            self.parent.deselectall()
+        else:
+            self.deselecttree()
+
+    def deselecttree(self):
+        if self.selected:
+            self.deselect()
+        for key in self.kidKeys:
+            child = self.children[key]
+            child.deselecttree()
+
+    def flip(self, event=None):
+        if self.state == 'expanded':
+            self.collapse()
+        else:
+            self.expand()
+        self.item.OnDoubleClick()
+        return "break"
+
+    def popupMenu(self, event=None):
+        if self._popupMenu:
+            self._popupMenu.post(event.widget.winfo_pointerx(),
+                                 event.widget.winfo_pointery())
+            return "break"
+
+    def popupMenuCommand(self):
+        self.item.MenuCommand(self.menuList[self.menuVar.get()])
+
+    def expand(self, event=None):
+        if not self.item.IsExpandable():
+            return
+        if self.state != 'expanded':
+            self.state = 'expanded'
+            self.update()
+            self.view()
+
+    def collapse(self, event=None):
+        if self.state != 'collapsed':
+            self.state = 'collapsed'
+            self.update()
+
+    def view(self):
+        top = self.y - 2
+        bottom = self.lastvisiblechild().y + 17
+        height = bottom - top
+        visible_top = self.canvas.canvasy(0)
+        visible_height = self.canvas.winfo_height()
+        visible_bottom = self.canvas.canvasy(visible_height)
+        if visible_top <= top and bottom <= visible_bottom:
+            return
+        x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion'])
+        if top >= visible_top and height <= visible_height:
+            fraction = top + height - visible_height
+        else:
+            fraction = top
+        fraction = float(fraction) / y1
+        self.canvas.yview_moveto(fraction)
+
+    def lastvisiblechild(self):
+        if self.kidKeys and self.state == 'expanded':
+            return self.children[self.kidKeys[-1]].lastvisiblechild()
+        else:
+            return self
+
+    def update(self):
+        if self.parent:
+            self.parent.update()
+        else:
+            oldcursor = self.canvas['cursor']
+            self.canvas['cursor'] = "watch"
+            self.canvas.update()
+            self.canvas.delete(ALL)     # XXX could be more subtle
+            self.draw(7, 2)
+            x0, y0, x1, y1 = self.canvas.bbox(ALL)
+            self.canvas.configure(scrollregion=(0, 0, x1, y1))
+            self.canvas['cursor'] = oldcursor
+
+    def draw(self, x, y):
+        # XXX This hard-codes too many geometry constants!
+        self.x, self.y = x, y
+        self.drawicon()
+        self.drawtext()
+        if self.state != 'expanded':
+            return y+17
+        # draw children
+        #if not self.children:
+        #self.children = []
+        sublist = self.item._GetSubList()
+        if not sublist:
+            # IsExpandable() was mistaken; that's allowed
+            return y+17
+        self.kidKeys = []
+        for item in sublist:
+            key = item.nodePath.id()
+            if self.children.has_key(key):
+                child = self.children[key]
+            else:
+                child = TreeNode(self.canvas, self, item, self.menuList)
+            self.children[key] = child
+            self.kidKeys.append(key)
+        cx = x+20
+        cy = y+17
+        cylast = 0
+        for key in self.kidKeys:
+            child = self.children[key]
+            cylast = cy
+            self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50")
+            cy = child.draw(cx, cy)
+            if child.item.IsExpandable():
+                if child.state == 'expanded':
+                    iconname = "minusnode"
+                    callback = child.collapse
+                else:
+                    iconname = "plusnode"
+                    callback = child.expand
+                image = self.geticonimage(iconname)
+                id = self.canvas.create_image(x+9, cylast+7, image=image)
+                # XXX This leaks bindings until canvas is deleted:
+                self.canvas.tag_bind(id, "<1>", callback)
+                self.canvas.tag_bind(id, "<Double-1>", lambda x: None)
+        id = self.canvas.create_line(x+9, y+10, x+9, cylast+7,
+            ##stipple="gray50",     # XXX Seems broken in Tk 8.0.x
+            fill="gray50")
+        self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2
+        return cy
+
+    def drawicon(self):
+        if self.selected:
+            imagename = (self.item.GetSelectedIconName() or
+                         self.item.GetIconName() or
+                         "openfolder")
+        else:
+            imagename = self.item.GetIconName() or "folder"
+        image = self.geticonimage(imagename)
+        id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image)
+        self.image_id = id
+        self.canvas.tag_bind(id, "<1>", self.select)
+        self.canvas.tag_bind(id, "<Double-1>", self.flip)
+        self.canvas.tag_bind(id, "<3>", self.popupMenu)
+        
+    def drawtext(self):
+        textx = self.x+20-1
+        texty = self.y-1
+        labeltext = self.item.GetLabelText()
+        if labeltext:
+            id = self.canvas.create_text(textx, texty, anchor="nw",
+                                         text=labeltext)
+            self.canvas.tag_bind(id, "<1>", self.select)
+            self.canvas.tag_bind(id, "<Double-1>", self.flip)
+            x0, y0, x1, y1 = self.canvas.bbox(id)
+            textx = max(x1, 200) + 10
+        text = self.item.GetText() or "<no text>"
+        try:
+            self.entry
+        except AttributeError:
+            pass
+        else:
+            self.edit_finish()
+        try:
+            label = self.label
+        except AttributeError:
+            # padding carefully selected (on Windows) to match Entry widget:
+            self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2)
+        if self.selected:
+            self.label.configure(fg="white", bg="darkblue")
+        else:
+            self.label.configure(fg="black", bg="white")
+        id = self.canvas.create_window(textx, texty,
+                                       anchor="nw", window=self.label)
+        self.label.bind("<1>", self.select_or_edit)
+        self.label.bind("<Double-1>", self.flip)
+        self.label.bind("<3>", self.popupMenu)
+        self.text_id = id
+
+    def select_or_edit(self, event=None):
+        if self.selected and self.item.IsEditable():
+            self.edit(event)
+        else:
+            self.select(event)
+
+    def edit(self, event=None):
+        self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0)
+        self.entry.insert(0, self.label['text'])
+        self.entry.selection_range(0, END)
+        self.entry.pack(ipadx=5)
+        self.entry.focus_set()
+        self.entry.bind("<Return>", self.edit_finish)
+        self.entry.bind("<Escape>", self.edit_cancel)
+
+    def edit_finish(self, event=None):
+        try:
+            entry = self.entry
+            del self.entry
+        except AttributeError:
+            return
+        text = entry.get()
+        entry.destroy()
+        if text and text != self.item.GetText():
+            self.item.SetText(text)
+        text = self.item.GetText()
+        self.label['text'] = text
+        self.drawtext()
+        self.canvas.focus_set()
+
+    def edit_cancel(self, event=None):
+        self.drawtext()
+        self.canvas.focus_set()
+
+
+class TreeItem:
+
+    """Abstract class representing tree items.
+
+    Methods should typically be overridden, otherwise a default action
+    is used.
+
+    """
+
+    def __init__(self):
+        """Constructor.  Do whatever you need to do."""
+
+    def GetText(self):
+        """Return text string to display."""
+
+    def GetLabelText(self):
+        """Return label text string to display in front of text (if any)."""
+
+    def IsExpandable(self):
+        """Return whether there are subitems."""
+        return 1
+
+    def _GetSubList(self):
+        """Do not override!  Called by TreeNode."""
+        if not self.IsExpandable():
+            return []
+        sublist = self.GetSubList()
+        return sublist
+
+    def IsEditable(self):
+        """Return whether the item's text may be edited."""
+
+    def SetText(self, text):
+        """Change the item's text (if it is editable)."""
+
+    def GetIconName(self):
+        """Return name of icon to be displayed normally."""
+
+    def GetSelectedIconName(self):
+        """Return name of icon to be displayed when selected."""
+
+    def GetSubList(self):
+        """Return list of items forming sublist."""
+
+    def OnDoubleClick(self):
+        """Called on a double-click on the item."""
+
+    def OnSelect(self):
+        """Called when item selected."""
+
+
+

+ 1 - 1
direct/src/tkwidgets/VectorWidgets.py

@@ -213,7 +213,7 @@ class VectorEntry(Pmw.MegaWidget):
         
     def action(self, fCommand = 1):
         self._refreshFloaters()
-        if fCommand & (self['command'] != None):
+        if fCommand and (self['command'] != None):
             self['command'](self._value)        
         
     def reset(self):