Browse Source

Added ability to set color of selection box (if needed to be different than the default red).

Justin Butler 20 years ago
parent
commit
12c5c4e0f3

+ 7 - 0
direct/src/directtools/DirectGlobals.py

@@ -31,3 +31,10 @@ SKIP_BACKFACE = 2
 SKIP_CAMERA = 4
 SKIP_UNPICKABLE = 8
 SKIP_ALL = SKIP_HIDDEN | SKIP_BACKFACE | SKIP_CAMERA | SKIP_UNPICKABLE
+
+# bit flags for indicating how editable an object is
+EDIT_TYPE_UNMOVABLE = 1
+EDIT_TYPE_UNSCALABLE = 2
+EDIT_TYPE_UNROTATABLE = 4
+EDIT_TYPE_UNEDITABLE = EDIT_TYPE_UNMOVABLE | EDIT_TYPE_UNSCALABLE | EDIT_TYPE_UNROTATABLE
+

+ 33 - 13
direct/src/directtools/DirectManipulation.py

@@ -175,14 +175,34 @@ class DirectManipulationControl(PandaObject):
     def removeManipulateObjectTask(self):
         taskMgr.remove('manipulateObject')
 
+    #--------------------------------------------------------------------------
+    # Function:   get edit types list for specified objects which indicate
+    #             how editable the objects are
+    # Parameters: object, list of object to get edit types for
+    # Changes:    none
+    # Returns:    list of edit types
+    #--------------------------------------------------------------------------
+    def getEditTypes(self,objects):
+        # See if any of the selected in the don't manipulate tag list
+        editTypes = 0
+        for tag in self.unmovableTagList:
+            for selected in objects:
+                unmovableTag = selected.getTag(tag)
+                if (unmovableTag):
+                    # check value of unmovableTag to see if it is
+                    # completely uneditable or if it allows only certain
+                    # types of editing
+                    editTypes |= int(unmovableTag)
+        return editTypes
+
     def manipulateObject(self):
         # Only do this if something is selected
         selectedList = direct.selected.getSelectedAsList()
-        # See if any of the selected in the don't manipulate tag list
-        for tag in self.unmovableTagList:
-            for selected in selectedList:
-                if selected.hasTag(tag):
-                    return
+        # See if any of the selected are completely uneditable
+        editTypes = self.getEditTypes(selectedList)
+        if (editTypes & EDIT_TYPE_UNEDITABLE == EDIT_TYPE_UNEDITABLE):
+            return
+        self.currEditTypes = editTypes
         if selectedList:
             # Remove the task to keep the widget attached to the object
             taskMgr.remove('followSelectedNodePath')
@@ -234,11 +254,11 @@ class DirectManipulationControl(PandaObject):
         # Widget takes precedence
         if self.constraint:
             type = self.constraint[2:]
-            if type == 'post':
+            if type == 'post' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
                 self.xlate1D(state)
-            elif type == 'disc':
+            elif type == 'disc' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
                 self.xlate2D(state)
-            elif type == 'ring':
+            elif type == 'ring' and not self.currEditTypes & EDIT_TYPE_UNROTATABLE:
                 self.rotate1D(state)
         # No widget interaction, determine free manip mode
         elif self.fFreeManip:
@@ -247,17 +267,17 @@ class DirectManipulationControl(PandaObject):
                 self.objectHandles.transferObjectHandlesScale()
                 self.fScaling = 0
             # Alt key switches to a scaling mode
-            if direct.fControl:
+            if direct.fControl and not self.currEditTypes & EDIT_TYPE_UNSCALABLE:
                 self.fScaling = 1
                 self.scale3D(state)
             # Otherwise, manip mode depends on where you started
-            elif state.fMouseX and state.fMouseY:
+            elif state.fMouseX and state.fMouseY and not self.currEditTypes & EDIT_TYPE_UNROTATABLE:
                 # In the corner, spin around camera's axis
                 self.rotateAboutViewVector(state)
-            elif state.fMouseX or state.fMouseY:
+            elif state.fMouseX or state.fMouseY and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
                 # Mouse started elsewhere in the outer frame, rotate
                 self.rotate2D(state)
-            else:
+            elif not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
                 # Mouse started in central region, xlate
                 # Mode depends on shift key
                 if direct.fShift or direct.fControl:
@@ -281,6 +301,7 @@ class DirectManipulationControl(PandaObject):
     def removeTag(self, tag):
         self.unmovableTagList.remove(tag)
 
+
     ### WIDGET MANIPULATION METHODS ###
     def xlate1D(self, state):
         # Constrained 1D Translation along widget axis
@@ -962,4 +983,3 @@ class ObjectHandles(NodePath,PandaObject):
         return self.hitPt
 
 
-

+ 17 - 7
direct/src/directtools/DirectSelection.py

@@ -9,12 +9,12 @@ COA_CENTER = 1
 # MRM: To do: handle broken node paths in selected and deselected dicts
 class DirectNodePath(NodePath):
     # A node path augmented with info, bounding box, and utility methods
-    def __init__(self, nodePath):
+    def __init__(self, nodePath, bboxColor=None):
         # Initialize the superclass
         NodePath.__init__(self)
         self.assign(nodePath)
         # Create a bounding box
-        self.bbox = DirectBoundingBox(self)
+        self.bbox = DirectBoundingBox(self, bboxColor)
         center = self.bbox.getCenter()
         # Create matrix to hold the offset between the nodepath
         # and its center of action (COA)
@@ -69,7 +69,7 @@ class SelectedNodePaths(PandaObject):
         if not nodePath:
             print 'Nothing selected!!'
             return None
-        
+
         # Reset selected objects and highlight if multiSelect is false
         if not fMultiSelect:
             self.deselectAll()
@@ -244,13 +244,13 @@ class SelectedNodePaths(PandaObject):
 
 
 class DirectBoundingBox:
-    def __init__(self, nodePath):
+    def __init__(self, nodePath, bboxColor=None):
         # Record the node path
         self.nodePath = nodePath
         # Compute bounds, min, max, etc.
         self.computeTightBounds()
         # Generate the bounding box
-        self.lines = self.createBBoxLines()
+        self.lines = self.createBBoxLines(bboxColor)
 
     def recompute(self):
         # Compute bounds, min, max, etc.
@@ -285,11 +285,14 @@ class DirectBoundingBox:
         self.min = Point3(self.center - Point3(self.radius))
         self.max = Point3(self.center + Point3(self.radius))
         
-    def createBBoxLines(self):
+    def createBBoxLines(self, bboxColor=None):
         # Create a line segments object for the bbox
         lines = LineNodePath(hidden)
         lines.node().setName('bboxLines')
-        lines.setColor(VBase4(1., 0., 0., 1.))
+        if (bboxColor):
+            lines.setColor(VBase4(*bboxColor))
+        else:
+            lines.setColor(VBase4(1., 0., 0., 1.))
         lines.setThickness(0.5)
 
         minX = self.min[0]
@@ -329,6 +332,13 @@ class DirectBoundingBox:
         
         return lines
 
+    def setBoxColorScale(self,r,g,b,a):
+        if (self.lines):
+            self.lines.reset()
+            self.lines = None
+        self.lines = self.createBBoxLines((r,g,b,a))
+        self.show()
+
     def updateBBoxLines(self):
         ls = self.lines.lineSegs