historical/toontown-classic.git/panda/Pmw/Pmw_1_3/lib/PmwRadioSelect.py

235 lines
7.3 KiB
Python
Raw Normal View History

2024-01-16 11:20:27 -06:00
import types
import Tkinter
import Pmw
class RadioSelect(Pmw.MegaWidget):
# A collection of several buttons. In single mode, only one
# button may be selected. In multiple mode, any number of buttons
# may be selected.
def __init__(self, parent = None, **kw):
# Define the megawidget options.
INITOPT = Pmw.INITOPT
optiondefs = (
('buttontype', 'button', INITOPT),
('command', None, None),
('labelmargin', 0, INITOPT),
('labelpos', None, INITOPT),
('orient', 'horizontal', INITOPT),
('padx', 5, INITOPT),
('pady', 5, INITOPT),
('selectmode', 'single', INITOPT),
)
self.defineoptions(kw, optiondefs, dynamicGroups = ('Button',))
# Initialise the base class (after defining the options).
Pmw.MegaWidget.__init__(self, parent)
# Create the components.
interior = self.interior()
if self['labelpos'] is None:
self._radioSelectFrame = self._hull
else:
self._radioSelectFrame = self.createcomponent('frame',
(), None,
Tkinter.Frame, (interior,))
self._radioSelectFrame.grid(column=2, row=2, sticky='nsew')
interior.grid_columnconfigure(2, weight=1)
interior.grid_rowconfigure(2, weight=1)
self.createlabel(interior)
# Initialise instance variables.
self._buttonList = []
if self['selectmode'] == 'single':
self._singleSelect = 1
elif self['selectmode'] == 'multiple':
self._singleSelect = 0
else:
raise ValueError, 'bad selectmode option "' + \
self['selectmode'] + '": should be single or multiple'
if self['buttontype'] == 'button':
self.buttonClass = Tkinter.Button
elif self['buttontype'] == 'radiobutton':
self._singleSelect = 1
self.var = Tkinter.StringVar()
self.buttonClass = Tkinter.Radiobutton
elif self['buttontype'] == 'checkbutton':
self._singleSelect = 0
self.buttonClass = Tkinter.Checkbutton
else:
raise ValueError, 'bad buttontype option "' + \
self['buttontype'] + \
'": should be button, radiobutton or checkbutton'
if self._singleSelect:
self.selection = None
else:
self.selection = []
if self['orient'] not in ('horizontal', 'vertical'):
raise ValueError, 'bad orient option ' + repr(self['orient']) + \
': must be either \'horizontal\' or \'vertical\''
# Check keywords and initialise options.
self.initialiseoptions()
def getcurselection(self):
if self._singleSelect:
return self.selection
else:
return tuple(self.selection)
def getvalue(self):
return self.getcurselection()
def setvalue(self, textOrList):
if self._singleSelect:
self.__setSingleValue(textOrList)
else:
# Multiple selections
oldselection = self.selection
self.selection = textOrList
for button in self._buttonList:
if button in oldselection:
if button not in self.selection:
# button is currently selected but should not be
widget = self.component(button)
if self['buttontype'] == 'checkbutton':
widget.deselect()
else: # Button
widget.configure(relief='raised')
else:
if button in self.selection:
# button is not currently selected but should be
widget = self.component(button)
if self['buttontype'] == 'checkbutton':
widget.select()
else: # Button
widget.configure(relief='sunken')
def numbuttons(self):
return len(self._buttonList)
def index(self, index):
# Return the integer index of the button with the given index.
listLength = len(self._buttonList)
if type(index) == types.IntType:
if index < listLength:
return index
else:
raise ValueError, 'index "%s" is out of range' % index
elif index is Pmw.END:
if listLength > 0:
return listLength - 1
else:
raise ValueError, 'RadioSelect has no buttons'
else:
for count in range(listLength):
name = self._buttonList[count]
if index == name:
return count
validValues = 'a name, a number or Pmw.END'
raise ValueError, \
'bad index "%s": must be %s' % (index, validValues)
def button(self, buttonIndex):
name = self._buttonList[self.index(buttonIndex)]
return self.component(name)
def add(self, componentName, **kw):
if componentName in self._buttonList:
raise ValueError, 'button "%s" already exists' % componentName
kw['command'] = \
lambda self=self, name=componentName: self.invoke(name)
if not kw.has_key('text'):
kw['text'] = componentName
if self['buttontype'] == 'radiobutton':
if not kw.has_key('anchor'):
kw['anchor'] = 'w'
if not kw.has_key('variable'):
kw['variable'] = self.var
if not kw.has_key('value'):
kw['value'] = kw['text']
elif self['buttontype'] == 'checkbutton':
if not kw.has_key('anchor'):
kw['anchor'] = 'w'
button = apply(self.createcomponent, (componentName,
(), 'Button',
self.buttonClass, (self._radioSelectFrame,)), kw)
if self['orient'] == 'horizontal':
self._radioSelectFrame.grid_rowconfigure(0, weight=1)
col = len(self._buttonList)
button.grid(column=col, row=0, padx = self['padx'],
pady = self['pady'], sticky='nsew')
self._radioSelectFrame.grid_columnconfigure(col, weight=1)
else:
self._radioSelectFrame.grid_columnconfigure(0, weight=1)
row = len(self._buttonList)
button.grid(column=0, row=row, padx = self['padx'],
pady = self['pady'], sticky='ew')
self._radioSelectFrame.grid_rowconfigure(row, weight=1)
self._buttonList.append(componentName)
return button
def deleteall(self):
for name in self._buttonList:
self.destroycomponent(name)
self._buttonList = []
if self._singleSelect:
self.selection = None
else:
self.selection = []
def __setSingleValue(self, value):
self.selection = value
if self['buttontype'] == 'radiobutton':
widget = self.component(value)
widget.select()
else: # Button
for button in self._buttonList:
widget = self.component(button)
if button == value:
widget.configure(relief='sunken')
else:
widget.configure(relief='raised')
def invoke(self, index):
index = self.index(index)
name = self._buttonList[index]
if self._singleSelect:
self.__setSingleValue(name)
command = self['command']
if callable(command):
return command(name)
else:
# Multiple selections
widget = self.component(name)
if name in self.selection:
if self['buttontype'] == 'checkbutton':
widget.deselect()
else:
widget.configure(relief='raised')
self.selection.remove(name)
state = 0
else:
if self['buttontype'] == 'checkbutton':
widget.select()
else:
widget.configure(relief='sunken')
self.selection.append(name)
state = 1
command = self['command']
if callable(command):
return command(name, state)