Procházet zdrojové kódy

Added DirectRadioButton

Gyedo Jeon před 17 roky
rodič
revize
2a094776c6
2 změnil soubory, kde provedl 220 přidání a 0 odebrání
  1. 1 0
      direct/src/gui/DirectGui.py
  2. 219 0
      direct/src/gui/DirectRadioButton.py

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

@@ -24,3 +24,4 @@ from DirectScrollBar import *
 from DirectScrolledFrame import *
 from DirectScrolledFrame import *
 from DirectCheckButton import *
 from DirectCheckButton import *
 from DirectOptionMenu import *
 from DirectOptionMenu import *
+from DirectRadioButton import *

+ 219 - 0
direct/src/gui/DirectRadioButton.py

@@ -0,0 +1,219 @@
+"""Undocumented Module"""
+
+__all__ = ['DirectRadioButton']
+
+from pandac.PandaModules import *
+import DirectGuiGlobals as DGG
+from DirectButton import *
+from DirectLabel import *
+
+class DirectRadioButton(DirectButton):
+    """
+    DirectRadioButton(parent) - Create a DirectGuiWidget which responds
+    to mouse clicks by setting given value to given variable and
+    execute a callback function (passing that state through) if defined
+    """
+    def __init__(self, parent = None, **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
+
+        self.colors = None
+        optiondefs = (
+            ('indicatorValue', 0, self.setIndicatorValue),
+            # variable is a list whose value will be set by this radio button
+            ('variable', [], None),
+            # value is the value to be set when this radio button is selected
+            ('value', [], None),
+            # others is a list of other radio buttons sharing same variable
+            ('others', [], None),
+            # boxBorder defines the space created around the check box
+            ('boxBorder', 0, None),
+            # boxPlacement maps left, above, right, below
+            ('boxPlacement', 'left', None),
+            # boxGeom defines geom to indicate current radio button is selected or not
+            ('boxGeom', None, None),
+            ('boxGeomColor', None, None),
+            ('boxGeomScale', 1.0, None),
+            ('boxImage', loader.loadModel('models/gui/radio_button_gui'), None),
+            ('boxImageScale', 1.0, None),
+            ('boxImageColor', VBase4(1, 1, 1, 1), None),
+            ('boxRelief', None, 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,
+                                              image = self['boxImage'],
+                                              image_scale = self['boxImageScale'],
+                                              image_color = self['boxImageColor'],
+                                              geom = self['boxGeom'],
+                                              geom_scale = self['boxGeomScale'],
+                                              geom_color = self['boxGeomColor'],
+                                              state = 'disabled',
+                                              text = ('X', 'X'),
+                                              relief = self['boxRelief'],
+                                              )
+
+        # Call option initialization functions
+        self.initialiseoptions(DirectRadioButton)
+        # After initialization with X giving it the correct size, put back space
+        if self['boxGeom'] ==  None:
+            self.indicator['text'] = (' ', '*')
+            self.indicator['text_pos'] = (0, -.5)
+        else:
+            self.indicator['text'] = (' ', ' ')
+
+        if self['boxGeomColor'] != None and self['boxGeom'] != None:
+            self.colors = [VBase4(1, 1, 1, 0), self['boxGeomColor']]
+            self.component('indicator')['geom_color'] = VBase4(1, 1, 1, 0)
+
+        needToCheck = True
+        if len(self['value']) == len(self['variable']) != 0:
+            for i in range(len(self['value'])):
+                if self['variable'][i] != self['value'][i]:
+                    needToCheck = False
+                    break
+
+        if needToCheck:
+            self.check()
+
+    # 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']
+            frameType = self.frameStyle[0].getType()
+            ibw = self.indicator['borderWidth']
+        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
+
+            ibw = self.indicator['borderWidth']
+            indicatorWidth = (self.indicator.getWidth() + (2*ibw[0]))
+            indicatorHeight = (self.indicator.getHeight() + (2*ibw[1]))
+            diff = (indicatorHeight + (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] += -(indicatorWidth + (2*self['boxBorder']))
+                    self.bounds[3] += diff/2
+                    self.bounds[2] -= diff/2
+                elif self['boxPlacement'] == 'below':          #below
+                    self.bounds[2] += -(indicatorHeight+(2*self['boxBorder']))
+                elif self['boxPlacement'] == 'right':          #right
+                    self.bounds[1] += indicatorWidth + (2*self['boxBorder'])
+                    self.bounds[3] += diff/2
+                    self.bounds[2] -= diff/2
+                else:                                    #above
+                    self.bounds[3] += indicatorHeight + (2*self['boxBorder'])
+
+            # Else make space on correct side for indicator
+            else:
+                if self['boxPlacement'] == 'left':            #left
+                    self.bounds[0] += -(indicatorWidth + (2*self['boxBorder']))
+                elif self['boxPlacement'] == 'below':          #below
+                    self.bounds[2] += -(indicatorHeight + (2*self['boxBorder']))
+                elif self['boxPlacement'] == 'right':          #right
+                    self.bounds[1] += indicatorWidth + (2*self['boxBorder'])
+                else:                                    #above
+                    self.bounds[3] += indicatorHeight + (2*self['boxBorder'])
+
+        # Set frame to new dimensions
+        if ((frameType != PGFrameStyle.TNone) and
+            (frameType != PGFrameStyle.TFlat)):
+            bw = self['borderWidth']
+        else:
+            bw = (0, 0)
+        # Set frame to new dimensions
+        self.guiItem.setFrame(
+            self.bounds[0] - bw[0],
+            self.bounds[1] + bw[0],
+            self.bounds[2] - bw[1],
+            self.bounds[3] + bw[1])
+
+        # 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'] + ibw[0]
+                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'] - ibw[0]
+                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'] - ibw[1]
+            else:                                      #below
+                newpos[2] += bbounds[2]-lbounds[2] + self['boxBorder'] + ibw[1]
+
+            self.indicator.setPos(newpos[0], newpos[1], newpos[2])
+
+
+    def commandFunc(self, event):
+        if len(self['value']) == len(self['variable']) != 0:            
+            for i in range(len(self['value'])):
+                self['variable'][i] = self['value'][i]
+        self.check()
+
+    def check(self):
+        self['indicatorValue'] = 1
+        self.setIndicatorValue()
+
+        for other in self['others']:
+            if other != self:
+                other.uncheck()
+
+        if self['command']:
+            # Pass any extra args to command
+            apply(self['command'], [self['indicatorValue']] + self['extraArgs'])
+
+    def setOthers(self, others):
+        self['others'] = others
+
+    def uncheck(self):
+        self['indicatorValue'] = 0
+        if self.colors != None:
+            self.component('indicator')['geom_color'] = self.colors[self['indicatorValue']]
+
+    def setIndicatorValue(self):
+        self.component('indicator').guiItem.setState(self['indicatorValue'])
+        if self.colors != None:
+            self.component('indicator')['image_color'] = self.colors[self['indicatorValue']]