mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-27 13:42:28 -06:00
220 lines
9.9 KiB
Python
220 lines
9.9 KiB
Python
|
"""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['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')['geom_color'] = self.colors[self['indicatorValue']]
|