Issue #5170: Fixed regression caused when fixing #5768.
[python.git] / Tools / modulator / Tkextra.py
blob12271069af4f99bb43270ac91cb5e7a9b0c2321f
1 #! /usr/bin/env python
3 # A Python function that generates dialog boxes with a text message,
4 # optional bitmap, and any number of buttons.
5 # Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
7 from Tkinter import *
9 mainWidget = None
11 def dialog(master, title, text, bitmap, default, *args):
13 # 1. Create the top-level window and divide it into top
14 # and bottom parts.
16 w = Toplevel(master, {'class': 'Dialog'})
17 w.title(title)
18 w.iconname('Dialog')
20 top = Frame(w, {'relief': 'raised', 'bd': 1,
21 Pack: {'side': 'top', 'fill': 'both'}})
22 bot = Frame(w, {'relief': 'raised', 'bd': 1,
23 Pack: {'side': 'bottom', 'fill': 'both'}})
25 # 2. Fill the top part with the bitmap and message.
27 msg = Message(top,
28 {'width': '3i',
29 'text': text,
30 'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
31 Pack: {'side': 'right', 'expand': 1,
32 'fill': 'both',
33 'padx': '3m', 'pady': '3m'}})
34 if bitmap:
35 bm = Label(top, {'bitmap': bitmap,
36 Pack: {'side': 'left',
37 'padx': '3m', 'pady': '3m'}})
39 # 3. Create a row of buttons at the bottom of the dialog.
41 buttons = []
42 i = 0
43 for but in args:
44 b = Button(bot, {'text': but,
45 'command': ('set', 'button', i)})
46 buttons.append(b)
47 if i == default:
48 bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
49 Pack: {'side': 'left', 'expand': 1,
50 'padx': '3m', 'pady': '2m'}})
51 b.lift()
52 b.pack ({'in': bd, 'side': 'left',
53 'padx': '2m', 'pady': '2m',
54 'ipadx': '2m', 'ipady': '1m'})
55 else:
56 b.pack ({'side': 'left', 'expand': 1,
57 'padx': '3m', 'pady': '3m',
58 'ipady': '2m', 'ipady': '1m'})
59 i = i+1
61 # 4. Set up a binding for <Return>, if there's a default,
62 # set a grab, and claim the focus too.
64 if default >= 0:
65 w.bind('<Return>',
66 lambda e, b=buttons[default], i=default:
67 (b.flash(),
68 b.setvar('button', i)))
70 oldFocus = w.tk.call('focus') # XXX
71 w.grab_set()
72 w.focus()
74 # 5. Wait for the user to respond, then restore the focus
75 # and return the index of the selected button.
77 w.waitvar('button')
78 w.destroy()
79 w.tk.call('focus', oldFocus) # XXX
80 return w.getint(w.getvar('button'))
82 def strdialog(master, title, text, bitmap, default, *args):
84 # 1. Create the top-level window and divide it into top
85 # and bottom parts.
87 w = Toplevel(master, {'class': 'Dialog'})
88 w.title(title)
89 w.iconname('Dialog')
91 top = Frame(w, {'relief': 'raised', 'bd': 1,
92 Pack: {'side': 'top', 'fill': 'both'}})
93 if args:
94 bot = Frame(w, {'relief': 'raised', 'bd': 1,
95 Pack: {'side': 'bottom', 'fill': 'both'}})
97 # 2. Fill the top part with the bitmap, message and input field.
99 if bitmap:
100 bm = Label(top, {'bitmap': bitmap,
101 Pack: {'side': 'left',
102 'padx': '3m', 'pady': '3m'}})
104 msg = Message(top,
105 {'width': '3i',
106 'text': text,
107 'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
108 Pack: {'side': 'left',
109 'fill': 'both',
110 'padx': '3m', 'pady': '3m'}})
112 field = Entry(top,
113 {'relief':'sunken',
114 Pack:{'side':'left',
115 'fill':'x',
116 'expand':1,
117 'padx':'3m', 'pady':'3m'}})
118 # 3. Create a row of buttons at the bottom of the dialog.
120 buttons = []
121 i = 0
122 for but in args:
123 b = Button(bot, {'text': but,
124 'command': ('set', 'button', i)})
125 buttons.append(b)
126 if i == default:
127 bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
128 Pack: {'side': 'left', 'expand': 1,
129 'padx': '3m', 'pady': '2m'}})
130 b.lift()
131 b.pack ({'in': bd, 'side': 'left',
132 'padx': '2m', 'pady': '2m',
133 'ipadx': '2m', 'ipady': '1m'})
134 else:
135 b.pack ({'side': 'left', 'expand': 1,
136 'padx': '3m', 'pady': '3m',
137 'ipady': '2m', 'ipady': '1m'})
138 i = i+1
140 # 4. Set up a binding for <Return>, if there's a default,
141 # set a grab, and claim the focus too.
143 if not args:
144 w.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
145 field.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
146 elif default >= 0:
147 w.bind('<Return>',
148 lambda e, b=buttons[default], i=default:
149 (b.flash(),
150 b.setvar('button', i)))
151 field.bind('<Return>',
152 lambda e, b=buttons[default], i=default:
153 (b.flash(),
154 b.setvar('button', i)))
156 oldFocus = w.tk.call('focus') # XXX
157 w.grab_set()
158 field.focus()
160 # 5. Wait for the user to respond, then restore the focus
161 # and return the index of the selected button.
163 w.waitvar('button')
164 v = field.get()
165 w.destroy()
166 w.tk.call('focus', oldFocus) # XXX
167 if args:
168 return v, w.getint(w.getvar('button'))
169 else:
170 return v
172 def message(str):
173 i = dialog(mainWidget, 'Message', str, '', 0, 'OK')
175 def askyn(str):
176 i = dialog(mainWidget, 'Question', str, '', 0, 'No', 'Yes')
177 return i
179 def askync(str):
180 i = dialog(mainWidget, 'Question', str, '', 0, 'Cancel', 'No', 'Yes')
181 return i-1
183 def askstr(str):
184 i = strdialog(mainWidget, 'Question', str, '', 0)
185 return i
187 def askfile(str): # XXXX For now...
188 i = strdialog(mainWidget, 'Question', str, '', 0)
189 return i
191 # The rest is the test program.
193 def _go():
194 i = dialog(mainWidget,
195 'Not Responding',
196 "The file server isn't responding right now; "
197 "I'll keep trying.",
200 'OK')
201 print 'pressed button', i
202 i = dialog(mainWidget,
203 'File Modified',
204 'File "tcl.h" has been modified since '
205 'the last time it was saved. '
206 'Do you want to save it before exiting the application?',
207 'warning',
209 'Save File',
210 'Discard Changes',
211 'Return To Editor')
212 print 'pressed button', i
213 print message('Test of message')
214 print askyn('Test of yes/no')
215 print askync('Test of yes/no/cancel')
216 print askstr('Type a string:')
217 print strdialog(mainWidget, 'Question', 'Another string:', '',
218 0, 'Save', 'Save as text')
220 def _test():
221 global mainWidget
222 mainWidget = Frame()
223 Pack.config(mainWidget)
224 start = Button(mainWidget,
225 {'text': 'Press Here To Start', 'command': _go})
226 start.pack()
227 endit = Button(mainWidget,
228 {'text': 'Exit',
229 'command': 'exit',
230 Pack: {'fill' : 'both'}})
231 mainWidget.mainloop()
233 if __name__ == '__main__':
234 _test()