1#! /usr/local/bin/python
2#
3# $Id: tixwidgets.py,v 1.2 2000/11/22 08:03:01 idiscovery Exp $
4#
5# tixwidgets.py --
6# 	This is a demo program of all Tix widgets available from Python. If
7#	you have installed Python & Tix properly, you can execute this as
8#
9#		% tixwidget.py
10#
11
12import os, sys, Tix
13
14class Demo:
15    pass
16
17root = Tix.Tk()
18demo = Demo()
19demo.dir = None				# script directory
20demo.balloon = None			# balloon widget
21demo.useBalloons = Tix.StringVar()
22demo.useBalloons.set('0')
23demo.statusbar = None			# status bar widget
24demo.welmsg = None			# Msg widget
25demo.welfont = ''			# font name
26demo.welsize = ''			# font size
27
28def main():
29    global demo, root
30
31    progname = sys.argv[0]
32    dirname = os.path.dirname(progname)
33    if dirname and dirname != os.curdir:
34	demo.dir = dirname
35	index = -1
36	for i in range(len(sys.path)):
37	    p = sys.path[i]
38	    if p in ("", os.curdir):
39		index = i
40	if index >= 0:
41	    sys.path[index] = dirname
42	else:
43	    sys.path.insert(0, dirname)
44    else:
45	demo.dir = os.getcwd()
46    sys.path.insert(0, demo.dir+'/samples')
47
48    root.withdraw()
49    root = Tix.Toplevel()
50    root.title('Tix Widget Demonstration')
51    root.geometry('780x570+50+50')
52
53    demo.balloon = Tix.Balloon(root)
54    frame1 = MkMainMenu(root)
55    frame2 = MkMainNotebook(root)
56    frame3 = MkMainStatus(root)
57    frame1.pack(side=Tix.TOP, fill=Tix.X)
58    frame3.pack(side=Tix.BOTTOM, fill=Tix.X)
59    frame2.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=4, pady=4)
60    demo.balloon['statusbar'] = demo.statusbar
61    root.mainloop()
62
63def exit_cmd(event=None):
64    sys.exit()
65
66def MkMainMenu(top):
67    global demo
68
69    w = Tix.Frame(top, bd=2, relief=Tix.RAISED)
70    file = Tix.Menubutton(w, text='File', underline=0, takefocus=0)
71    help = Tix.Menubutton(w, text='Help', underline=0, takefocus=0)
72    file.pack(side=Tix.LEFT)
73    help.pack(side=Tix.RIGHT)
74    fm = Tix.Menu(file)
75    file['menu'] = fm
76    hm = Tix.Menu(help)
77    help['menu'] = hm
78
79    fm.add_command(label='Exit', underline=1, accelerator='Ctrl+X',
80		   command=exit_cmd)
81    hm.add_checkbutton(label='BalloonHelp', underline=0, command=ToggleHelp,
82		       variable=demo.useBalloons)
83    # The trace variable option doesn't seem to work, instead I use 'command'
84    #apply(w.tk.call, ('trace', 'variable', demo.useBalloons, 'w',
85    #		      ToggleHelp))
86    top.bind_all("<Control-x>", exit_cmd)
87    top.bind_all("<Control-X>", exit_cmd)
88    return w
89
90def MkMainNotebook(top):
91    top.option_add('*TixNoteBook*tagPadX', 6)
92    top.option_add('*TixNoteBook*tagPadY', 4)
93    top.option_add('*TixNoteBook*borderWidth', 2)
94    top.option_add('*TixNoteBook*font',
95		   '-*-helvetica-bold-o-normal-*-14-*-*-*-*-*-*-*')
96    w = Tix.NoteBook(top, ipadx=5, ipady=5)
97    w.add('wel', label='Welcome', underline=0,
98	  createcmd=lambda w=w, name='wel': MkWelcome(w, name))
99    w.add('cho', label='Choosers', underline=0,
100	  createcmd=lambda w=w, name='cho': MkChoosers(w, name))
101    w.add('scr', label='Scrolled Widgets', underline=0,
102	  createcmd=lambda w=w, name='scr': MkScroll(w, name))
103    w.add('mgr', label='Manager Widgets', underline=0,
104	  createcmd=lambda w=w, name='mgr': MkManager(w, name))
105    w.add('dir', label='Directory List', underline=0,
106	  createcmd=lambda w=w, name='dir': MkDirList(w, name))
107    w.add('exp', label='Run Sample Programs', underline=0,
108	  createcmd=lambda w=w, name='exp': MkSample(w, name))
109    return w
110
111def MkMainStatus(top):
112    global demo
113
114    w = Tix.Frame(top, relief=Tix.RAISED, bd=1)
115    demo.statusbar = Tix.Label(w, relief=Tix.SUNKEN, bd=1, font='-*-helvetica-medium-r-normal-*-14-*-*-*-*-*-*-*')
116    demo.statusbar.form(padx=3, pady=3, left=0, right='%70')
117    return w
118
119def MkWelcome(nb, name):
120    w = nb.page(name)
121    bar = MkWelcomeBar(w)
122    text = MkWelcomeText(w)
123    bar.pack(side=Tix.TOP, fill=Tix.X, padx=2, pady=2)
124    text.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
125
126def MkWelcomeBar(top):
127    global demo
128
129    w = Tix.Frame(top, bd=2, relief=Tix.GROOVE)
130    b1 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
131    b2 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
132    b1.entry['width'] = 15
133    b1.slistbox.listbox['height'] = 3
134    b2.entry['width'] = 4
135    b2.slistbox.listbox['height'] = 3
136
137    demo.welfont = b1
138    demo.welsize = b2
139
140    b1.insert(Tix.END, 'Courier')
141    b1.insert(Tix.END, 'Helvetica')
142    b1.insert(Tix.END, 'Lucida')
143    b1.insert(Tix.END, 'Times Roman')
144
145    b2.insert(Tix.END, '8')
146    b2.insert(Tix.END, '10')
147    b2.insert(Tix.END, '12')
148    b2.insert(Tix.END, '14')
149    b2.insert(Tix.END, '18')
150
151    b1.pick(1)
152    b2.pick(3)
153
154    b1.pack(side=Tix.LEFT, padx=4, pady=4)
155    b2.pack(side=Tix.LEFT, padx=4, pady=4)
156
157    demo.balloon.bind_widget(b1, msg='Choose\na font',
158			     statusmsg='Choose a font for this page')
159    demo.balloon.bind_widget(b2, msg='Point size',
160			     statusmsg='Choose the font size for this page')
161    return w
162
163def MkWelcomeText(top):
164    global demo
165
166    w = Tix.ScrolledWindow(top, scrollbar='auto')
167    win = w.window
168    title = Tix.Label(win, font='-*-times-bold-r-normal-*-18-*-*-*-*-*-*-*',
169		      bd=0, width=30, anchor=Tix.N, text='Welcome to TIX Version 4.0 from Python Version 1.3')
170    msg = Tix.Message(win, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
171		      bd=0, width=400, anchor=Tix.N,
172		      text='Tix 4.0 is a set of mega-widgets based on TK. This program \
173demonstrates the widgets in the Tix widget set. You can choose the pages \
174in this window to look at the corresponding widgets. \n\n\
175To quit this program, choose the "File | Exit" command.')
176    title.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
177    msg.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
178    demo.welmsg = msg
179    return w
180
181def MainTextFont(w):
182    global demo
183
184    if not demo.welmsg:
185	return
186    font = demo.welfont['value']
187    point = demo.welsize['value']
188    if font == 'Times Roman':
189	font = 'times'
190    fontstr = '-*-%s-bold-r-normal-*-%s-*-*-*-*-*-*-*' % (font, point)
191    demo.welmsg['font'] = fontstr
192
193def ToggleHelp():
194    if demo.useBalloons.get() == '1':
195	demo.balloon['state'] = 'both'
196    else:
197	demo.balloon['state'] = 'none'
198
199def MkChoosers(nb, name):
200    w = nb.page(name)
201    prefix = Tix.OptionName(w)
202    if not prefix:
203	prefix = ''
204    w.option_add('*' + prefix + '*TixLabelFrame*label.padX', 4)
205
206    til = Tix.LabelFrame(w, label='Chooser Widgets')
207    cbx = Tix.LabelFrame(w, label='tixComboBox')
208    ctl = Tix.LabelFrame(w, label='tixControl')
209    sel = Tix.LabelFrame(w, label='tixSelect')
210    opt = Tix.LabelFrame(w, label='tixOptionMenu')
211    fil = Tix.LabelFrame(w, label='tixFileEntry')
212    fbx = Tix.LabelFrame(w, label='tixFileSelectBox')
213    tbr = Tix.LabelFrame(w, label='Tool Bar')
214
215    MkTitle(til.frame)
216    MkCombo(cbx.frame)
217    MkControl(ctl.frame)
218    MkSelect(sel.frame)
219    MkOptMenu(opt.frame)
220    MkFileEnt(fil.frame)
221    MkFileBox(fbx.frame)
222    MkToolBar(tbr.frame)
223
224    # First column: comBox and selector
225    cbx.form(top=0, left=0, right='%33')
226    sel.form(left=0, right='&'+str(cbx), top=cbx)
227    opt.form(left=0, right='&'+str(cbx), top=sel, bottom=-1)
228
229    # Second column: title .. etc
230    til.form(left=cbx, top=0,right='%66')
231    ctl.form(left=cbx, right='&'+str(til), top=til)
232    fil.form(left=cbx, right='&'+str(til), top=ctl)
233    tbr.form(left=cbx, right='&'+str(til), top=fil, bottom=-1)
234
235    #
236    # Third column: file selection
237    fbx.form(right=-1, top=0, left='%66')
238
239def MkCombo(w):
240    prefix = Tix.OptionName(w)
241    if not prefix: prefix = ''
242    w.option_add('*' + prefix + '*TixComboBox*label.width', 10)
243    w.option_add('*' + prefix + '*TixComboBox*label.anchor', Tix.E)
244    w.option_add('*' + prefix + '*TixComboBox*entry.width', 14)
245
246    static = Tix.ComboBox(w, label='Static', editable=0)
247    editable = Tix.ComboBox(w, label='Editable', editable=1)
248    history = Tix.ComboBox(w, label='History', editable=1, history=1,
249			   anchor=Tix.E)
250    static.insert(Tix.END, 'January')
251    static.insert(Tix.END, 'February')
252    static.insert(Tix.END, 'March')
253    static.insert(Tix.END, 'April')
254    static.insert(Tix.END, 'May')
255    static.insert(Tix.END, 'June')
256    static.insert(Tix.END, 'July')
257    static.insert(Tix.END, 'August')
258    static.insert(Tix.END, 'September')
259    static.insert(Tix.END, 'October')
260    static.insert(Tix.END, 'November')
261    static.insert(Tix.END, 'December')
262
263    editable.insert(Tix.END, 'Angola')
264    editable.insert(Tix.END, 'Bangladesh')
265    editable.insert(Tix.END, 'China')
266    editable.insert(Tix.END, 'Denmark')
267    editable.insert(Tix.END, 'Ecuador')
268
269    history.insert(Tix.END, '/usr/bin/ksh')
270    history.insert(Tix.END, '/usr/local/lib/python')
271    history.insert(Tix.END, '/var/adm')
272
273    static.pack(side=Tix.TOP, padx=5, pady=3)
274    editable.pack(side=Tix.TOP, padx=5, pady=3)
275    history.pack(side=Tix.TOP, padx=5, pady=3)
276
277states = ['Bengal', 'Delhi', 'Karnataka', 'Tamil Nadu']
278
279def spin_cmd(w, inc):
280    idx = states.index(demo_spintxt.get()) + inc
281    if idx < 0:
282	idx = len(states) - 1
283    elif idx >= len(states):
284	idx = 0
285# following doesn't work.
286#    return states[idx]
287    demo_spintxt.set(states[idx])	# this works
288
289def spin_validate(w):
290    global states, demo_spintxt
291
292    try:
293	i = states.index(demo_spintxt.get())
294    except:
295	return states[0]
296    return states[i]
297    # why this procedure works as opposed to the previous one beats me.
298
299def MkControl(w):
300    global demo_spintxt
301
302    prefix = Tix.OptionName(w)
303    if not prefix: prefix = ''
304    w.option_add('*' + prefix + '*TixControl*label.width', 10)
305    w.option_add('*' + prefix + '*TixControl*label.anchor', Tix.E)
306    w.option_add('*' + prefix + '*TixControl*entry.width', 13)
307
308    demo_spintxt = Tix.StringVar()
309    demo_spintxt.set(states[0])
310    simple = Tix.Control(w, label='Numbers')
311    spintxt = Tix.Control(w, label='States', variable=demo_spintxt)
312    spintxt['incrcmd'] = lambda w=spintxt: spin_cmd(w, 1)
313    spintxt['decrcmd'] = lambda w=spintxt: spin_cmd(w, -1)
314    spintxt['validatecmd'] = lambda w=spintxt: spin_validate(w)
315
316    simple.pack(side=Tix.TOP, padx=5, pady=3)
317    spintxt.pack(side=Tix.TOP, padx=5, pady=3)
318
319def MkSelect(w):
320    prefix = Tix.OptionName(w)
321    if not prefix: prefix = ''
322    w.option_add('*' + prefix + '*TixSelect*label.anchor', Tix.CENTER)
323    w.option_add('*' + prefix + '*TixSelect*orientation', Tix.VERTICAL)
324    w.option_add('*' + prefix + '*TixSelect*labelSide', Tix.TOP)
325
326    sel1 = Tix.Select(w, label='Mere Mortals', allowzero=1, radio=1)
327    sel2 = Tix.Select(w, label='Geeks', allowzero=1, radio=0)
328
329    sel1.add('eat', text='Eat')
330    sel1.add('work', text='Work')
331    sel1.add('play', text='Play')
332    sel1.add('party', text='Party')
333    sel1.add('sleep', text='Sleep')
334
335    sel2.add('eat', text='Eat')
336    sel2.add('prog1', text='Program')
337    sel2.add('prog2', text='Program')
338    sel2.add('prog3', text='Program')
339    sel2.add('sleep', text='Sleep')
340
341    sel1.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
342    sel2.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
343
344def MkOptMenu(w):
345    prefix = Tix.OptionName(w)
346    if not prefix: prefix = ''
347    w.option_add('*' + prefix + '*TixOptionMenu*label.anchor', Tix.E)
348    m = Tix.OptionMenu(w, label='File Format : ', options='menubutton.width 15')
349    m.add_command('text', label='Plain Text')
350    m.add_command('post', label='PostScript')
351    m.add_command('format', label='Formatted Text')
352    m.add_command('html', label='HTML')
353    m.add_command('sep')
354    m.add_command('tex', label='LaTeX')
355    m.add_command('rtf', label='Rich Text Format')
356
357    m.pack(fill=Tix.X, padx=5, pady=3)
358
359def MkFileEnt(w):
360    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
361		      relief=Tix.FLAT, width=240, anchor=Tix.N,
362		      text='Press the "open file" icon button and a TixFileSelectDialog will popup.')
363    ent = Tix.FileEntry(w, label='Select a file : ')
364    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
365    ent.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
366
367def MkFileBox(w):
368    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
369		      relief=Tix.FLAT, width=240, anchor=Tix.N,
370		      text='The TixFileSelectBox is a Motif-style box with various enhancements. For example, you can adjust the size of the two listboxes and your past selections are recorded.')
371    box = Tix.FileSelectBox(w)
372    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
373    box.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
374
375def MkToolBar(w):
376    global demo
377
378    prefix = Tix.OptionName(w)
379    if not prefix: prefix = ''
380    w.option_add('*' + prefix + '*TixSelect*frame.borderWidth', 1)
381    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
382		      relief=Tix.FLAT, width=240, anchor=Tix.N,
383		      text='The Select widget is also good for arranging buttons in a tool bar.')
384    bar = Tix.Frame(w, bd=2, relief=Tix.RAISED)
385    font = Tix.Select(w, allowzero=1, radio=0, label='')
386    para = Tix.Select(w, allowzero=0, radio=1, label='')
387
388    font.add('bold', bitmap='@' + demo.dir + '/bitmaps/bold.xbm')
389    font.add('italic', bitmap='@' + demo.dir + '/bitmaps/italic.xbm')
390    font.add('underline', bitmap='@' + demo.dir + '/bitmaps/underline.xbm')
391    font.add('capital', bitmap='@' + demo.dir + '/bitmaps/capital.xbm')
392
393    para.add('left', bitmap='@' + demo.dir + '/bitmaps/leftj.xbm')
394    para.add('right', bitmap='@' + demo.dir + '/bitmaps/rightj.xbm')
395    para.add('center', bitmap='@' + demo.dir + '/bitmaps/centerj.xbm')
396    para.add('justify', bitmap='@' + demo.dir + '/bitmaps/justify.xbm')
397
398    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
399    bar.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
400    font.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
401    para.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
402
403def MkTitle(w):
404    prefix = Tix.OptionName(w)
405    if not prefix: prefix = ''
406    w.option_add('*' + prefix + '*TixSelect*frame.borderWidth', 1)
407    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
408		      relief=Tix.FLAT, width=240, anchor=Tix.N,
409		      text='There are many types of "chooser" widgets that allow the user to input different types of information')
410    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
411
412def MkScroll(nb, name):
413    w = nb.page(name)
414    prefix = Tix.OptionName(w)
415    if not prefix:
416	prefix = ''
417    w.option_add('*' + prefix + '*TixLabelFrame*label.padX', 4)
418
419    sls = Tix.LabelFrame(w, label='tixScrolledListBox')
420    swn = Tix.LabelFrame(w, label='tixScrolledWindow')
421    stx = Tix.LabelFrame(w, label='tixScrolledText')
422
423    MkSList(sls.frame)
424    MkSWindow(swn.frame)
425    MkSText(stx.frame)
426
427    sls.form(top=0, left=0, right='%33', bottom=-1)
428    swn.form(top=0, left=sls, right='%66', bottom=-1)
429    stx.form(top=0, left=swn, right=-1, bottom=-1)
430
431def MkSList(w):
432    top = Tix.Frame(w, width=300, height=330)
433    bot = Tix.Frame(w)
434    msg = Tix.Message(top, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
435		      relief=Tix.FLAT, width=200, anchor=Tix.N,
436		      text='This TixScrolledListBox is configured so that it uses scrollbars only when it is necessary. Use the handles to resize the listbox and watch the scrollbars automatically appear and disappear.')
437
438    list = Tix.ScrolledListBox(top, scrollbar='auto')
439    list.place(x=50, y=150, width=120, height=80)
440    list.listbox.insert(Tix.END, 'Alabama')
441    list.listbox.insert(Tix.END, 'California')
442    list.listbox.insert(Tix.END, 'Montana')
443    list.listbox.insert(Tix.END, 'New Jersey')
444    list.listbox.insert(Tix.END, 'New York')
445    list.listbox.insert(Tix.END, 'Pennsylvania')
446    list.listbox.insert(Tix.END, 'Washington')
447
448    rh = Tix.ResizeHandle(top, bg='black',
449			  relief=Tix.RAISED,
450			  handlesize=8, gridded=1, minwidth=50, minheight=30)
451    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x))
452    top.propagate(0)
453    msg.pack(fill=Tix.X)
454    btn.pack(anchor=Tix.CENTER)
455    top.pack(expand=1, fill=Tix.BOTH)
456    bot.pack(fill=Tix.BOTH)
457    list.bind('<Map>', func=lambda arg=0, rh=rh, list=list:
458	      list.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(list)))
459
460def SList_reset(rh, list):
461    list.place(x=50, y=150, width=120, height=80)
462    list.update()
463    rh.attach_widget(list)
464
465def MkSWindow(w):
466    global demo
467
468    top = Tix.Frame(w, width=330, height=330)
469    bot = Tix.Frame(w)
470    msg = Tix.Message(top, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
471		      relief=Tix.FLAT, width=200, anchor=Tix.N,
472		      text='The TixScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.')
473    win = Tix.ScrolledWindow(top, scrollbar='auto')
474    image = Tix.Image('photo', file=demo.dir + "/bitmaps/tix.gif")
475    lbl = Tix.Label(win.window, image=image)
476    lbl.pack(expand=1, fill=Tix.BOTH)
477
478    win.place(x=30, y=150, width=190, height=120)
479
480    rh = Tix.ResizeHandle(top, bg='black',
481			  relief=Tix.RAISED,
482			  handlesize=8, gridded=1, minwidth=50, minheight=30)
483    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x))
484    top.propagate(0)
485    msg.pack(fill=Tix.X)
486    btn.pack(anchor=Tix.CENTER)
487    top.pack(expand=1, fill=Tix.BOTH)
488    bot.pack(fill=Tix.BOTH)
489    win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
490	     win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
491
492def SWindow_reset(rh, win):
493    win.place(x=30, y=150, width=190, height=120)
494    win.update()
495    rh.attach_widget(win)
496
497def MkSText(w):
498    top = Tix.Frame(w, width=330, height=330)
499    bot = Tix.Frame(w)
500    msg = Tix.Message(top, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
501		      relief=Tix.FLAT, width=200, anchor=Tix.N,
502		      text='The TixScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.')
503
504    win = Tix.ScrolledText(top, scrollbar='auto')
505#    win.text['wrap'] = 'none'
506    win.text.insert(Tix.END, 'This is a text widget embedded in a scrolled window. Although the original Tix demo does not have any text here, I decided to put in some so that you can see the effect of scrollbars etc.')
507    win.place(x=30, y=150, width=190, height=100)
508
509    rh = Tix.ResizeHandle(top, bg='black',
510			  relief=Tix.RAISED,
511			  handlesize=8, gridded=1, minwidth=50, minheight=30)
512    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x))
513    top.propagate(0)
514    msg.pack(fill=Tix.X)
515    btn.pack(anchor=Tix.CENTER)
516    top.pack(expand=1, fill=Tix.BOTH)
517    bot.pack(fill=Tix.BOTH)
518    win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
519	     win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
520
521def SText_reset(rh, win):
522    win.place(x=30, y=150, width=190, height=120)
523    win.update()
524    rh.attach_widget(win)
525
526def MkManager(nb, name):
527    w = nb.page(name)
528    prefix = Tix.OptionName(w)
529    if not prefix:
530	prefix = ''
531    w.option_add('*' + prefix + '*TixLabelFrame*label.padX', 4)
532
533    pane = Tix.LabelFrame(w, label='tixPanedWindow')
534    note = Tix.LabelFrame(w, label='tixNoteBook')
535
536    MkPanedWindow(pane.frame)
537    MkNoteBook(note.frame)
538
539    pane.form(top=0, left=0, right=note, bottom=-1)
540    note.form(top=0, right=-1, bottom=-1)
541
542def MkPanedWindow(w):
543    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
544		      relief=Tix.FLAT, width=240, anchor=Tix.N,
545		      text='The PanedWindow widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.')
546    group = Tix.Label(w, text='Newsgroup: comp.lang.python')
547    pane = Tix.PanedWindow(w, orientation='vertical')
548
549    p1 = pane.add('list', min=70, size=100)
550    p2 = pane.add('text', min=70)
551    list = Tix.ScrolledListBox(p1)
552    text = Tix.ScrolledText(p2)
553
554    list.listbox.insert(Tix.END, "  12324 Re: TK is good for your health")
555    list.listbox.insert(Tix.END, "+ 12325 Re: TK is good for your health")
556    list.listbox.insert(Tix.END, "+ 12326 Re: Tix is even better for your health (Was: TK is good...)")
557    list.listbox.insert(Tix.END, "  12327 Re: Tix is even better for your health (Was: TK is good...)")
558    list.listbox.insert(Tix.END, "+ 12328 Re: Tix is even better for your health (Was: TK is good...)")
559    list.listbox.insert(Tix.END, "  12329 Re: Tix is even better for your health (Was: TK is good...)")
560    list.listbox.insert(Tix.END, "+ 12330 Re: Tix is even better for your health (Was: TK is good...)")
561
562    text.text['bg'] = list.listbox['bg']
563    text.text['wrap'] = 'none'
564    text.text.insert(Tix.END, """
565Mon, 19 Jun 1995 11:39:52        comp.lang.tcl              Thread   34 of  220
566Lines 353       A new way to put text and bitmaps together iNo responses
567ioi@blue.seas.upenn.edu                Ioi K. Lam at University of Pennsylvania
568
569Hi,
570
571I have implemented a new image type called "compound". It allows you
572to glue together a bunch of bitmaps, images and text strings together
573to form a bigger image. Then you can use this image with widgets that
574support the -image option. This way you can display very fancy stuffs
575in your GUI. For example, you can display a text string string
576together with a bitmap, at the same time, inside a TK button widget. A
577screenshot of compound images can be found at the bottom of this page:
578
579        http://www.cis.upenn.edu/~ioi/tix/screenshot.html
580
581You can also you is in other places such as putting fancy bitmap+text
582in menus, tabs of tixNoteBook widgets, etc. This feature will be
583included in the next release of Tix (4.0b1). Count on it to make jazzy
584interfaces!""")
585    list.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
586    text.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
587
588    msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
589    group.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
590    pane.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH, expand=1)
591
592def MkNoteBook(w):
593    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
594		      relief=Tix.FLAT, width=240, anchor=Tix.N,
595		      text='The NoteBook widget allows you to layout a complex interface into individual pages.')
596    prefix = Tix.OptionName(w)
597    if not prefix:
598	prefix = ''
599    w.option_add('*' + prefix + '*TixControl*entry.width', 10)
600    w.option_add('*' + prefix + '*TixControl*label.width', 18)
601    w.option_add('*' + prefix + '*TixControl*label.anchor', Tix.E)
602    w.option_add('*' + prefix + '*TixNoteBook*tagPadX', 8)
603
604    nb = Tix.NoteBook(w, ipadx=6, ipady=6)
605    nb.add('hard_disk', label="Hard Disk", underline=0)
606    nb.add('network', label="Network", underline=0)
607
608    # Frame for the buttons that are present on all pages
609    common = Tix.Frame(nb.hard_disk)
610    common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
611    CreateCommonButtons(common)
612
613    # Widgets belonging only to this page
614    a = Tix.Control(nb.hard_disk, value=12, label='Access Time: ')
615    w = Tix.Control(nb.hard_disk, value=400, label='Write Throughput: ')
616    r = Tix.Control(nb.hard_disk, value=400, label='Read Throughput: ')
617    c = Tix.Control(nb.hard_disk, value=1021, label='Capacity: ')
618    a.pack(side=Tix.TOP, padx=20, pady=2)
619    w.pack(side=Tix.TOP, padx=20, pady=2)
620    r.pack(side=Tix.TOP, padx=20, pady=2)
621    c.pack(side=Tix.TOP, padx=20, pady=2)
622
623    common = Tix.Frame(nb.network)
624    common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
625    CreateCommonButtons(common)
626
627    a = Tix.Control(nb.network, value=12, label='Access Time: ')
628    w = Tix.Control(nb.network, value=400, label='Write Throughput: ')
629    r = Tix.Control(nb.network, value=400, label='Read Throughput: ')
630    c = Tix.Control(nb.network, value=1021, label='Capacity: ')
631    u = Tix.Control(nb.network, value=10, label='Users: ')
632    a.pack(side=Tix.TOP, padx=20, pady=2)
633    w.pack(side=Tix.TOP, padx=20, pady=2)
634    r.pack(side=Tix.TOP, padx=20, pady=2)
635    c.pack(side=Tix.TOP, padx=20, pady=2)
636    u.pack(side=Tix.TOP, padx=20, pady=2)
637
638    msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
639    nb.pack(side=Tix.TOP, padx=5, pady=5, fill=Tix.BOTH, expand=1)
640
641def CreateCommonButtons(f):
642    ok = Tix.Button(f, text='OK', width = 6)
643    cancel = Tix.Button(f, text='Cancel', width = 6)
644    ok.pack(side=Tix.TOP, padx=2, pady=2)
645    cancel.pack(side=Tix.TOP, padx=2, pady=2)
646
647def MkDirList(nb, name):
648    w = nb.page(name)
649    prefix = Tix.OptionName(w)
650    if not prefix:
651	prefix = ''
652    w.option_add('*' + prefix + '*TixLabelFrame*label.padX', 4)
653
654    dir = Tix.LabelFrame(w, label='tixDirList')
655    fsbox = Tix.LabelFrame(w, label='tixExFileSelectBox')
656    MkDirListWidget(dir.frame)
657    MkExFileWidget(fsbox.frame)
658    dir.form(top=0, left=0, right='%40', bottom=-1)
659    fsbox.form(top=0, left='%40', right=-1, bottom=-1)
660
661def MkDirListWidget(w):
662    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
663		      relief=Tix.FLAT, width=240, anchor=Tix.N,
664		      text='The TixDirList widget gives a graphical representation of the file system directory and makes it easy for the user to choose and access directories.')
665    dirlist = Tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16')
666    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
667    dirlist.pack(side=Tix.TOP, padx=3, pady=3)
668
669def MkExFileWidget(w):
670    msg = Tix.Message(w, font='-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*',
671		      relief=Tix.FLAT, width=240, anchor=Tix.N,
672		      text='The TixExFileSelectBox widget is more user friendly than the Motif style FileSelectBox.')
673    # There's a bug in the ComboBoxes - the scrolledlistbox is destroyed
674    box = Tix.ExFileSelectBox(w, bd=2, relief=Tix.RAISED)
675    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
676    box.pack(side=Tix.TOP, padx=3, pady=3)
677
678###
679### List of all the demos we want to show off
680comments = {'widget' : 'Widget Demos', 'image' : 'Image Demos'}
681samples = {'Balloon'		: 'Balloon',
682	   'Button Box'		: 'BtnBox',
683	   'Combo Box'		: 'ComboBox',
684	   'Compound Image'	: 'CmpImg',
685	   'Control'		: 'Control',
686	   'Notebook'		: 'NoteBook',
687	   'Option Menu'	: 'OptMenu',
688	   'Popup Menu'		: 'PopMenu',
689	   'ScrolledHList (1)'	: 'SHList1',
690	   'ScrolledHList (2)'	: 'SHList2',
691	   'Tree (dynamic)'	: 'Tree'
692}
693
694stypes = {}
695stypes['widget'] = ['Balloon', 'Button Box', 'Combo Box', 'Control',
696		    'Notebook', 'Option Menu', 'Popup Menu',
697		    'ScrolledHList (1)', 'ScrolledHList (2)', 'Tree (dynamic)']
698stypes['image'] = ['Compound Image']
699
700def MkSample(nb, name):
701    w = nb.page(name)
702    prefix = Tix.OptionName(w)
703    if not prefix:
704	prefix = ''
705    w.option_add('*' + prefix + '*TixLabelFrame*label.padX', 4)
706
707    lab = Tix.Label(w, text='Select a sample program:', anchor=Tix.W)
708    lab1 = Tix.Label(w, text='Source:', anchor=Tix.W)
709
710    slb = Tix.ScrolledHList(w, options='listbox.exportSelection 0')
711    slb.hlist['command'] = lambda args=0, w=w,slb=slb: Sample_Action(w, slb, 'run')
712    slb.hlist['browsecmd'] = lambda args=0, w=w,slb=slb: Sample_Action(w, slb, 'browse')
713
714    stext = Tix.ScrolledText(w, name='stext')
715    stext.text.bind('<1>', stext.text.focus())
716    stext.text.bind('<Up>', lambda w=stext.text: w.yview(scroll='-1 unit'))
717    stext.text.bind('<Down>', lambda w=stext.text: w.yview(scroll='1 unit'))
718    stext.text.bind('<Left>', lambda w=stext.text: w.xview(scroll='-1 unit'))
719    stext.text.bind('<Right>', lambda w=stext.text: w.xview(scroll='1 unit'))
720
721    run = Tix.Button(w, text='Run ...', name='run', command=lambda args=0, w=w,slb=slb: Sample_Action(w, slb, 'run'))
722    view = Tix.Button(w, text='View Source ...', name='view', command=lambda args=0,w=w,slb=slb: Sample_Action(w, slb, 'view'))
723
724    lab.form(top=0, left=0, right='&'+str(slb))
725    slb.form(left=0, top=lab, bottom=-4)
726    lab1.form(left='&'+str(stext), top=0, right='&'+str(stext), bottom=stext)
727    run.form(left=str(slb)+' 30', bottom=-4)
728    view.form(left=run, bottom=-4)
729    stext.form(bottom=str(run)+' -5', left='&'+str(run), right='-0', top='&'+str(slb))
730
731    stext.text['bg'] = slb.hlist['bg']
732    stext.text['state'] = 'disabled'
733    stext.text['wrap'] = 'none'
734    #XXX    stext.text['font'] = fixed_font
735
736    slb.hlist['separator'] = '.'
737    slb.hlist['width'] = 25
738    slb.hlist['drawbranch'] = 0
739    slb.hlist['indent'] = 10
740    slb.hlist['wideselect'] = 1
741
742    for type in ['widget', 'image']:
743	if type != 'widget':
744	    x = Tix.Frame(slb.hlist, bd=2, height=2, width=150,
745			  relief=Tix.SUNKEN, bg=slb.hlist['bg'])
746	    slb.hlist.add_child(itemtype=Tix.WINDOW, window=x, state='disabled')
747	x = slb.hlist.add_child(itemtype=Tix.TEXT, state='disabled',
748				text=comments[type])
749	for key in stypes[type]:
750	    slb.hlist.add_child(x, itemtype=Tix.TEXT, data=key,
751				text=key)
752    slb.hlist.selection_clear()
753
754    run['state'] = 'disabled'
755    view['state'] = 'disabled'
756
757def Sample_Action(w, slb, action):
758    global demo
759
760    run = w._nametowidget(str(w) + '.run')
761    view = w._nametowidget(str(w) + '.view')
762    stext = w._nametowidget(str(w) + '.stext')
763
764    hlist = slb.hlist
765    anchor = hlist.info_anchor()
766    if not anchor:
767	run['state'] = 'disabled'
768	view['state'] = 'disabled'
769    elif not hlist.info_parent(anchor):
770	# a comment
771	return
772
773    run['state'] = 'normal'
774    view['state'] = 'normal'
775    key = hlist.info_data(anchor)
776    title = key
777    prog = samples[key]
778
779    if action == 'run':
780	exec('import ' + prog)
781	w = Tix.Toplevel()
782	w.title(title)
783	rtn = eval(prog + '.RunSample')
784	rtn(w)
785    elif action == 'view':
786	w = Tix.Toplevel()
787	w.title('Source view: ' + title)
788	LoadFile(w, demo.dir + '/samples/' + prog + '.py')
789    elif action == 'browse':
790	ReadFile(stext.text, demo.dir + '/samples/' + prog + '.py')
791
792def LoadFile(w, fname):
793    b = Tix.Button(w, text='Close', command=w.destroy)
794    t = Tix.ScrolledText(w)
795    #    b.form(left=0, bottom=0, padx=4, pady=4)
796    #    t.form(left=0, bottom=b, right='-0', top=0)
797    t.pack()
798    b.pack()
799
800    t.text['highlightcolor'] = t['bg']
801    t.text['bd'] = 2
802    t.text['bg'] = t['bg']
803    t.text['wrap'] = 'none'
804
805    ReadFile(t.text, fname)
806
807def ReadFile(w, fname):
808    old_state = w['state']
809    w['state'] = 'normal'
810    w.delete('0.0', Tix.END)
811
812    try:
813	f = open(fname)
814	lines = f.readlines()
815	for s in lines:
816	    w.insert(Tix.END, s)
817	f.close()
818    finally:
819#	w.see('1.0')
820	w['state'] = old_state
821
822if __name__ == '__main__':
823    main()
824