Browse Source

*** empty log message ***

slpatto 23 years ago
parent
commit
c2c4531a0a

+ 147 - 0
direct/src/gui/DirectCheckButton.py

@@ -0,0 +1,147 @@
+from DirectButton import *
+from DirectLabel import *
+
+class DirectCheckButton(DirectButton):
+    """
+    DirectCheckButton(parent) - Create a DirectGuiWidget which responds
+    to mouse clicks by setting a state of on or off and execute a callback
+    function (passing that state through) if defined
+    """
+    def __init__(self, parent = aspect2d, **kw):
+        # Inherits from DirectButton
+        # A Direct Frame can have:
+        # - A background texture (pass in path to image, or Texture Card)
+        # - A midground geometry item (pass in geometry)
+        # - A foreground text Node (pass in text string or Onscreen Text)
+        # For a direct button:
+        # Each button has 4 states (ready, press, rollover, disabled)
+        # The same image/geom/text can be used for all four states or each
+        # state can have a different text/geom/image
+        # State transitions happen automatically based upon mouse interaction
+        # Responds to click event and calls command if None
+        
+        optiondefs = (
+            ('indicatorValue', 0, self.setIndicatorValue),
+            # boxBorder defines the space created around the check box
+            ('boxBorder', 0, None),
+            # boxPlacement maps left, above, right, below
+            ('boxPlacement', 'left', None),
+            )
+        # Merge keyword options with default options
+        self.defineoptions(kw, optiondefs)
+        # Initialize superclasses
+        DirectButton.__init__(self, parent)
+        
+        self.indicator = self.createcomponent("indicator", (), None,
+                                              DirectLabel, (self,),
+                                              numStates = 2,
+                                              state = 'disabled',
+                                              text = ('X' , 'X'),
+                                              relief = 'sunken',
+                                              )
+       
+        # Call option initialization functions
+        self.initialiseoptions(DirectCheckButton)
+        # After initialization with X giving it the correct size, put back space 
+        self.indicator['text'] = (' ', '*')
+        self.indicator['text_pos'] = (0,-.17)
+
+        
+    # Override the resetFrameSize of DirectGuiWidget inorder to provide space for label
+    def resetFrameSize(self):
+        self.setFrameSize(fClearFrame = 1)
+        
+    def setFrameSize(self, fClearFrame = 0):
+        
+        if self['frameSize']:
+            # Use user specified bounds
+            self.bounds = self['frameSize']
+        else:
+            # Use ready state to compute bounds
+            frameType = self.frameStyle[0].getType()
+            if fClearFrame and (frameType != PGFrameStyle.TNone):
+                self.frameStyle[0].setType(PGFrameStyle.TNone)
+                self.guiItem.setFrameStyle(0, self.frameStyle[0])
+                # To force an update of the button
+                self.guiItem.getStateDef(0)
+            # Clear out frame before computing bounds
+            self.getBounds()
+            # Restore frame style if necessary
+            if (frameType != PGFrameStyle.TNone):
+                self.frameStyle[0].setType(frameType)
+                self.guiItem.setFrameStyle(0, self.frameStyle[0])
+
+            # Ok, they didn't set specific bounds,
+            #  let's add room for the label indicator
+            #  get the difference in height
+            
+            diff = self.indicator.getHeight() + (2*self['boxBorder']) - (self.bounds[3] - self.bounds[2])
+            # If background is smaller then indicator, enlarge background
+            if diff > 0:
+                if self['boxPlacement'] == 'left':            #left
+                    self.bounds[0] += -(self.indicator.getWidth() + (2*self['boxBorder']))
+                    self.bounds[3] += diff/2
+                    self.bounds[2] -= diff/2
+                elif self['boxPlacement'] == 'below':          #below
+                    self.bounds[2] += -(self.indicator.getHeight() + (2*self['boxBorder']))
+                elif self['boxPlacement'] == 'right':          #right
+                    self.bounds[1] += self.indicator.getWidth() + (2*self['boxBorder'])
+                    self.bounds[3] += diff/2
+                    self.bounds[2] -= diff/2
+                else:                                    #above
+                    self.bounds[3] += self.indicator.getHeight() + (2*self['boxBorder'])
+
+            # Else make space on correct side for indicator
+            else:
+                if self['boxPlacement'] == 'left':            #left
+                    self.bounds[0] += -(self.indicator.getWidth() + (2*self['boxBorder']))
+                elif self['boxPlacement'] == 'below':          #below
+                    self.bounds[2] += -(self.indicator.getHeight() + (2*self['boxBorder']))
+                elif self['boxPlacement'] == 'right':          #right
+                    self.bounds[1] += self.indicator.getWidth() + (2*self['boxBorder'])
+                else:                                    #above
+                    self.bounds[3] += self.indicator.getHeight() + (2*self['boxBorder'])
+
+        # Set frame to new dimensions
+        self.guiItem.setFrame(self.bounds[0], self.bounds[1],
+                              self.bounds[2], self.bounds[3])  #3 is top border!!
+
+        # If they didn't specify a position, put it in the center of new area
+        if not self.indicator['pos']:
+            bbounds = self.bounds
+            lbounds = self.indicator.bounds
+            newpos = [0,0,0]
+
+            if self['boxPlacement'] == 'left':            #left
+                newpos[0] += bbounds[0]-lbounds[0] + self['boxBorder']
+                dropValue = (bbounds[3]-bbounds[2]-lbounds[3]+lbounds[2])/2 + self['boxBorder']
+                newpos[2] += bbounds[3]-lbounds[3] + self['boxBorder'] - dropValue
+            elif self['boxPlacement'] == 'right':            #right
+                newpos[0] += bbounds[1]-lbounds[1] - self['boxBorder']
+                dropValue = (bbounds[3]-bbounds[2]-lbounds[3]+lbounds[2])/2 + self['boxBorder']
+                newpos[2] += bbounds[3]-lbounds[3] + self['boxBorder'] - dropValue
+            elif self['boxPlacement'] == 'above':            #above
+                newpos[2] += bbounds[3]-lbounds[3] - self['boxBorder']
+            else:                                      #below
+                newpos[2] += bbounds[2]-lbounds[2] + self['boxBorder']
+
+            self.indicator.setPos(newpos[0],newpos[1],newpos[2])
+
+        
+    def commandFunc(self, event):
+        self['indicatorValue'] = 1 - self['indicatorValue']
+
+        if self['command']:
+            # Pass any extra args to command
+            apply(self['command'], [self['indicatorValue']] + self['extraArgs'])
+            
+    def setIndicatorValue(self):
+        self.component('indicator').guiItem.setState(self['indicatorValue'])
+        
+
+
+
+
+
+
+

+ 3 - 1
direct/src/gui/DirectFrame.py

@@ -23,6 +23,7 @@ class DirectFrame(DirectGuiWidget):
             ('geom',            None,       self.setGeom),
             ('geom',            None,       self.setGeom),
             # A foreground text node
             # A foreground text node
             ('text',            None,       self.setText),
             ('text',            None,       self.setText),
+            ('textMayChange',   1,          None),
             )
             )
         # Merge keyword options with default options
         # Merge keyword options with default options
         self.defineoptions(kw, optiondefs,
         self.defineoptions(kw, optiondefs,
@@ -71,7 +72,8 @@ class DirectFrame(DirectGuiWidget):
                         (), parent = self.stateNodePath[i],
                         (), parent = self.stateNodePath[i],
                         text = text, scale = 1,
                         text = text, scale = 1,
                         sort = TEXT_SORT_INDEX,
                         sort = TEXT_SORT_INDEX,
-                        mayChange = 1)
+                        mayChange = self['textMayChange'],
+                        )
 
 
     def setGeom(self):
     def setGeom(self):
         # Determine argument type
         # Determine argument type

+ 1 - 0
direct/src/gui/DirectGui.py

@@ -14,3 +14,4 @@ from DirectLabel import *
 from DirectScrolledList import *
 from DirectScrolledList import *
 from DirectDialog import *
 from DirectDialog import *
 from DirectWaitBar import *
 from DirectWaitBar import *
+from DirectCheckButton import *

+ 3 - 2
direct/src/gui/DirectGuiBase.py

@@ -866,13 +866,14 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
         self.guiItem.setFrame(self.bounds[0], self.bounds[1],
         self.guiItem.setFrame(self.bounds[0], self.bounds[1],
                               self.bounds[2], self.bounds[3])
                               self.bounds[2], self.bounds[3])
 
 
+
     def getBounds(self, state = 0):
     def getBounds(self, state = 0):
         self.stateNodePath[state].calcTightBounds(self.ll, self.ur)
         self.stateNodePath[state].calcTightBounds(self.ll, self.ur)
         # Scale bounds to give a pad around graphics
         # Scale bounds to give a pad around graphics
-        self.bounds = (self.ll[0] - self['pad'][0],
+        self.bounds = [self.ll[0] - self['pad'][0],
                        self.ur[0] + self['pad'][0],
                        self.ur[0] + self['pad'][0],
                        self.ll[2] - self['pad'][1],
                        self.ll[2] - self['pad'][1],
-                       self.ur[2] + self['pad'][1])
+                       self.ur[2] + self['pad'][1]]
         return self.bounds
         return self.bounds
 
 
     def getWidth(self):
     def getWidth(self):

+ 9 - 2
direct/src/gui/DirectScrolledList.py

@@ -103,6 +103,11 @@ class DirectScrolledList(DirectFrame):
             item = self["items"][i]
             item = self["items"][i]
             item.show()
             item.show()
             item.setPos(0,0, - (i - self.index) * self.maxHeight)
             item.setPos(0,0, - (i - self.index) * self.maxHeight)
+
+       
+        if self['command']:
+            # Pass any extra args to command
+            apply(self['command'], self['extraArgs'])    
         return ret
         return ret
 
 
     def __scrollByTask(self, task):
     def __scrollByTask(self, task):
@@ -123,6 +128,7 @@ class DirectScrolledList(DirectFrame):
         task.delta = 1
         task.delta = 1
         self.scrollBy(task.delta)
         self.scrollBy(task.delta)
         taskMgr.add(task, self.taskName("scroll"))
         taskMgr.add(task, self.taskName("scroll"))
+        
 
 
     def __decButtonDown(self, event):
     def __decButtonDown(self, event):
         task = Task.Task(self.__scrollByTask)
         task = Task.Task(self.__scrollByTask)
@@ -135,13 +141,14 @@ class DirectScrolledList(DirectFrame):
     def __buttonUp(self, event):
     def __buttonUp(self, event):
         taskMgr.remove(self.taskName("scroll"))
         taskMgr.remove(self.taskName("scroll"))
 
 
-    def addItem(self, item):
+    def addItem(self, item, refresh=1):
         """
         """
         Add this string and extraArg to the list
         Add this string and extraArg to the list
         """
         """
         self['items'].append(item)
         self['items'].append(item)
         item.reparentTo(self.itemFrame)
         item.reparentTo(self.itemFrame)
-        self.refresh()
+        if refresh:
+            self.refresh()
         
         
 
 
     def removeItem(self, item):
     def removeItem(self, item):