# Based on iwidgets2.2.0/buttonbox.itk code.
class ButtonBox(Pmw
.MegaWidget
):
def __init__(self
, parent
= None, **kw
):
# Define the megawidget options.
('labelmargin', 0, INITOPT
),
('labelpos', None, INITOPT
),
('orient', 'horizontal', INITOPT
),
self
.defineoptions(kw
, optiondefs
, dynamicGroups
= ('Button',))
# Initialise the base class (after defining the options).
Pmw
.MegaWidget
.__init
__(self
, parent
)
interior
= self
.interior()
if self
['labelpos'] is None:
self
._buttonBoxFrame
= self
._hull
self
._buttonBoxFrame
= self
.createcomponent('frame',
Tkinter
.Frame
, (interior
,))
self
._buttonBoxFrame
.grid(column
=2, row
=2, sticky
='nsew')
self
.createlabel(interior
)
if orient
== 'horizontal':
interior
.grid_columnconfigure(columnOrRow
, weight
= 1)
elif orient
== 'vertical':
interior
.grid_rowconfigure(columnOrRow
, weight
= 1)
raise ValueError, 'bad orient option ' + repr(orient
) + \
': must be either \'horizontal\' or \'vertical\''
# Initialise instance variables.
# List of tuples describing the buttons:
# The index of the default button.
self
._defaultButton
= None
# Check keywords and initialise options.
self
.after_cancel(self
._timerId
)
Pmw
.MegaWidget
.destroy(self
)
return len(self
._buttonList
)
def index(self
, index
, forInsert
= 0):
listLength
= len(self
._buttonList
)
if type(index
) == types
.IntType
:
if forInsert
and index
<= listLength
:
elif not forInsert
and index
< listLength
:
raise ValueError, 'index "%s" is out of range' % index
raise ValueError, 'ButtonBox has no buttons'
elif index
is Pmw
.DEFAULT
:
if self
._defaultButton
is not None:
return self
._defaultButton
raise ValueError, 'ButtonBox has no default'
names
= map(lambda t
: t
[0], self
._buttonList
)
return names
.index(index
)
validValues
= 'a name, a number, Pmw.END or Pmw.DEFAULT'
'bad index "%s": must be %s' % (index
, validValues
)
def insert(self
, componentName
, beforeComponent
= 0, **kw
):
if componentName
in self
.components():
raise ValueError, 'button "%s" already exists' % componentName
if not kw
.has_key('text'):
kw
['text'] = componentName
button
= apply(self
.createcomponent
, (componentName
,
Tkinter
.Button
, (self
._buttonBoxFrame
,)), kw
)
index
= self
.index(beforeComponent
, 1)
horizontal
= self
['orient'] == 'horizontal'
numButtons
= len(self
._buttonList
)
# Shift buttons up one position.
for i
in range(numButtons
- 1, index
- 1, -1):
widget
= self
._buttonList
[i
][1]
widget
.grid(column
= pos
, row
= 0)
widget
.grid(column
= 0, row
= pos
)
# Display the new button.
button
.grid(column
= index
* 2 + 1, row
= 0, sticky
= 'ew',
padx
= self
['padx'], pady
= self
['pady'])
self
._buttonBoxFrame
.grid_columnconfigure(
numButtons
* 2 + 2, weight
= 1)
button
.grid(column
= 0, row
= index
* 2 + 1, sticky
= 'ew',
padx
= self
['padx'], pady
= self
['pady'])
self
._buttonBoxFrame
.grid_rowconfigure(
numButtons
* 2 + 2, weight
= 1)
self
._buttonList
.insert(index
, (componentName
, button
))
def add(self
, componentName
, **kw
):
return apply(self
.insert
, (componentName
, len(self
._buttonList
)), kw
)
index
= self
.index(index
)
(name
, widget
) = self
._buttonList
[index
]
self
.destroycomponent(name
)
numButtons
= len(self
._buttonList
)
# Shift buttons down one position.
horizontal
= self
['orient'] == 'horizontal'
for i
in range(index
+ 1, numButtons
):
widget
= self
._buttonList
[i
][1]
widget
.grid(column
= pos
, row
= 0)
widget
.grid(column
= 0, row
= pos
)
self
._buttonBoxFrame
.grid_columnconfigure(numButtons
* 2 - 1,
self
._buttonBoxFrame
.grid_columnconfigure(numButtons
* 2, weight
= 0)
self
._buttonBoxFrame
.grid_rowconfigure(numButtons
* 2, weight
= 0)
del self
._buttonList
[index
]
def setdefault(self
, index
):
# Turn off the default ring around the current default button.
if self
._defaultButton
is not None:
button
= self
._buttonList
[self
._defaultButton
][1]
button
.configure(default
= 'normal')
self
._defaultButton
= None
# Turn on the default ring around the new default button.
index
= self
.index(index
)
self
._defaultButton
= index
button
= self
._buttonList
[index
][1]
button
.configure(default
= 'active')
def invoke(self
, index
= Pmw
.DEFAULT
, noFlash
= 0):
# Invoke the callback associated with the *index* button. If
# *noFlash* is not set, flash the button to indicate to the
# user that something happened.
button
= self
._buttonList
[self
.index(index
)][1]
state
= button
.cget('state')
relief
= button
.cget('relief')
button
.configure(state
= 'active', relief
= 'sunken')
button
.configure(state
= state
, relief
= relief
)
def button(self
, buttonIndex
):
return self
._buttonList
[self
.index(buttonIndex
)][1]
def alignbuttons(self
, when
= 'later'):
self
._timerId
= self
.after_idle(self
.alignbuttons
, 'now')
# Determine the width of the maximum length button.
horizontal
= (self
['orient'] == 'horizontal')
for index
in range(len(self
._buttonList
)):
gridIndex
= index
* 2 + 1
width
= self
._buttonBoxFrame
.grid_bbox(gridIndex
, 0)[2]
width
= self
._buttonBoxFrame
.grid_bbox(0, gridIndex
)[2]
# Set the width of all the buttons to be the same.
for index
in range(len(self
._buttonList
)):
self
._buttonBoxFrame
.grid_columnconfigure(index
* 2 + 1,
self
._buttonBoxFrame
.grid_columnconfigure(0, minsize
= max)