PageRenderTime 850ms CodeModel.GetById 131ms app.highlight 566ms RepoModel.GetById 103ms app.codeStats 0ms

/Demo/tix/tixwidgets.py

http://unladen-swallow.googlecode.com/
Python | 1003 lines | 982 code | 6 blank | 15 comment | 7 complexity | 4f3e85a6034f890908cd07e129daf860 MD5 | raw file
   1# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
   2#
   3# $Id: tixwidgets.py 36560 2004-07-18 06:16:08Z tim_one $
   4#
   5# tixwidgets.py --
   6#
   7#       For Tix, see http://tix.sourceforge.net
   8#
   9#       This is a demo program of some of the Tix widgets available in Python.
  10#       If you have installed Python & Tix properly, you can execute this as
  11#
  12#               % python tixwidgets.py
  13#
  14
  15import os, os.path, sys, Tix
  16from Tkconstants import *
  17import traceback, tkMessageBox
  18
  19TCL_DONT_WAIT           = 1<<1
  20TCL_WINDOW_EVENTS       = 1<<2
  21TCL_FILE_EVENTS         = 1<<3
  22TCL_TIMER_EVENTS        = 1<<4
  23TCL_IDLE_EVENTS         = 1<<5
  24TCL_ALL_EVENTS          = 0
  25
  26class Demo:
  27    def __init__(self, top):
  28        self.root = top
  29        self.exit = -1
  30
  31        self.dir = None                         # script directory
  32        self.balloon = None                     # balloon widget
  33        self.useBalloons = Tix.StringVar()
  34        self.useBalloons.set('0')
  35        self.statusbar = None                   # status bar widget
  36        self.welmsg = None                      # Msg widget
  37        self.welfont = ''                       # font name
  38        self.welsize = ''                       # font size
  39
  40        progname = sys.argv[0]
  41        dirname = os.path.dirname(progname)
  42        if dirname and dirname != os.curdir:
  43            self.dir = dirname
  44            index = -1
  45            for i in range(len(sys.path)):
  46                p = sys.path[i]
  47                if p in ("", os.curdir):
  48                    index = i
  49            if index >= 0:
  50                sys.path[index] = dirname
  51            else:
  52                sys.path.insert(0, dirname)
  53        else:
  54            self.dir = os.getcwd()
  55        sys.path.insert(0, self.dir+'/samples')
  56
  57    def MkMainMenu(self):
  58        top = self.root
  59        w = Tix.Frame(top, bd=2, relief=RAISED)
  60        file = Tix.Menubutton(w, text='File', underline=0, takefocus=0)
  61        help = Tix.Menubutton(w, text='Help', underline=0, takefocus=0)
  62        file.pack(side=LEFT)
  63        help.pack(side=RIGHT)
  64        fm = Tix.Menu(file, tearoff=0)
  65        file['menu'] = fm
  66        hm = Tix.Menu(help, tearoff=0)
  67        help['menu'] = hm
  68
  69        fm.add_command(label='Exit', underline=1,
  70                     command = lambda self=self: self.quitcmd () )
  71        hm.add_checkbutton(label='BalloonHelp', underline=0, command=ToggleHelp,
  72                           variable=self.useBalloons)
  73        # The trace variable option doesn't seem to work, instead I use 'command'
  74        #apply(w.tk.call, ('trace', 'variable', self.useBalloons, 'w',
  75        #                     ToggleHelp))
  76
  77        return w
  78
  79    def MkMainNotebook(self):
  80        top = self.root
  81        w = Tix.NoteBook(top, ipadx=5, ipady=5, options="""
  82        tagPadX 6
  83        tagPadY 4
  84        borderWidth 2
  85        """)
  86        # This may be required if there is no *Background option
  87        top['bg'] = w['bg']
  88
  89        w.add('wel', label='Welcome', underline=0,
  90              createcmd=lambda w=w, name='wel': MkWelcome(w, name))
  91        w.add('cho', label='Choosers', underline=0,
  92              createcmd=lambda w=w, name='cho': MkChoosers(w, name))
  93        w.add('scr', label='Scrolled Widgets', underline=0,
  94              createcmd=lambda w=w, name='scr': MkScroll(w, name))
  95        w.add('mgr', label='Manager Widgets', underline=0,
  96              createcmd=lambda w=w, name='mgr': MkManager(w, name))
  97        w.add('dir', label='Directory List', underline=0,
  98              createcmd=lambda w=w, name='dir': MkDirList(w, name))
  99        w.add('exp', label='Run Sample Programs', underline=0,
 100              createcmd=lambda w=w, name='exp': MkSample(w, name))
 101        return w
 102
 103    def MkMainStatus(self):
 104        global demo
 105        top = self.root
 106
 107        w = Tix.Frame(top, relief=Tix.RAISED, bd=1)
 108        demo.statusbar = Tix.Label(w, relief=Tix.SUNKEN, bd=1)
 109        demo.statusbar.form(padx=3, pady=3, left=0, right='%70')
 110        return w
 111
 112    def build(self):
 113        root = self.root
 114        z = root.winfo_toplevel()
 115        z.wm_title('Tix Widget Demonstration')
 116        if z.winfo_screenwidth() <= 800:
 117            z.geometry('790x590+10+10')
 118        else:
 119            z.geometry('890x640+10+10')
 120        demo.balloon = Tix.Balloon(root)
 121        frame1 = self.MkMainMenu()
 122        frame2 = self.MkMainNotebook()
 123        frame3 = self.MkMainStatus()
 124        frame1.pack(side=TOP, fill=X)
 125        frame3.pack(side=BOTTOM, fill=X)
 126        frame2.pack(side=TOP, expand=1, fill=BOTH, padx=4, pady=4)
 127        demo.balloon['statusbar'] = demo.statusbar
 128        z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
 129
 130        # To show Tcl errors - uncomment this to see the listbox bug.
 131        # Tkinter defines a Tcl tkerror procedure that in effect
 132        # silences all background Tcl error reporting.
 133        # root.tk.eval('if {[info commands tkerror] != ""} {rename tkerror pytkerror}')
 134    def quitcmd (self):
 135        """Quit our mainloop. It is up to you to call root.destroy() after."""
 136        self.exit = 0
 137
 138    def loop(self):
 139        """This is an explict replacement for _tkinter mainloop()
 140        It lets you catch keyboard interrupts easier, and avoids
 141        the 20 msec. dead sleep() which burns a constant CPU."""
 142        while self.exit < 0:
 143            # There are 2 whiles here. The outer one lets you continue
 144            # after a ^C interrupt.
 145            try:
 146                # This is the replacement for _tkinter mainloop()
 147                # It blocks waiting for the next Tcl event using select.
 148                while self.exit < 0:
 149                    self.root.tk.dooneevent(TCL_ALL_EVENTS)
 150            except SystemExit:
 151                # Tkinter uses SystemExit to exit
 152                #print 'Exit'
 153                self.exit = 1
 154                return
 155            except KeyboardInterrupt:
 156                if tkMessageBox.askquestion ('Interrupt', 'Really Quit?') == 'yes':
 157                    # self.tk.eval('exit')
 158                    self.exit = 1
 159                    return
 160                continue
 161            except:
 162                # Otherwise it's some other error - be nice and say why
 163                t, v, tb = sys.exc_info()
 164                text = ""
 165                for line in traceback.format_exception(t,v,tb):
 166                    text += line + '\n'
 167                try: tkMessageBox.showerror ('Error', text)
 168                except: pass
 169                self.exit = 1
 170                raise SystemExit, 1
 171
 172    def destroy (self):
 173        self.root.destroy()
 174
 175def RunMain(root):
 176    global demo
 177
 178    demo = Demo(root)
 179
 180    demo.build()
 181    demo.loop()
 182    demo.destroy()
 183
 184# Tabs
 185def MkWelcome(nb, name):
 186    w = nb.page(name)
 187    bar = MkWelcomeBar(w)
 188    text = MkWelcomeText(w)
 189    bar.pack(side=TOP, fill=X, padx=2, pady=2)
 190    text.pack(side=TOP, fill=BOTH, expand=1)
 191
 192def MkWelcomeBar(top):
 193    global demo
 194
 195    w = Tix.Frame(top, bd=2, relief=Tix.GROOVE)
 196    b1 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
 197    b2 = Tix.ComboBox(w, command=lambda w=top: MainTextFont(w))
 198    b1.entry['width'] = 15
 199    b1.slistbox.listbox['height'] = 3
 200    b2.entry['width'] = 4
 201    b2.slistbox.listbox['height'] = 3
 202
 203    demo.welfont = b1
 204    demo.welsize = b2
 205
 206    b1.insert(Tix.END, 'Courier')
 207    b1.insert(Tix.END, 'Helvetica')
 208    b1.insert(Tix.END, 'Lucida')
 209    b1.insert(Tix.END, 'Times Roman')
 210
 211    b2.insert(Tix.END, '8')
 212    b2.insert(Tix.END, '10')
 213    b2.insert(Tix.END, '12')
 214    b2.insert(Tix.END, '14')
 215    b2.insert(Tix.END, '18')
 216
 217    b1.pick(1)
 218    b2.pick(3)
 219
 220    b1.pack(side=Tix.LEFT, padx=4, pady=4)
 221    b2.pack(side=Tix.LEFT, padx=4, pady=4)
 222
 223    demo.balloon.bind_widget(b1, msg='Choose\na font',
 224                             statusmsg='Choose a font for this page')
 225    demo.balloon.bind_widget(b2, msg='Point size',
 226                             statusmsg='Choose the font size for this page')
 227    return w
 228
 229def MkWelcomeText(top):
 230    global demo
 231
 232    w = Tix.ScrolledWindow(top, scrollbar='auto')
 233    win = w.window
 234    text = 'Welcome to TIX in Python'
 235    title = Tix.Label(win,
 236                      bd=0, width=30, anchor=Tix.N, text=text)
 237    msg = Tix.Message(win,
 238                      bd=0, width=400, anchor=Tix.N,
 239                      text='Tix is a set of mega-widgets based on TK. This program \
 240demonstrates the widgets in the Tix widget set. You can choose the pages \
 241in this window to look at the corresponding widgets. \n\n\
 242To quit this program, choose the "File | Exit" command.\n\n\
 243For more information, see http://tix.sourceforge.net.')
 244    title.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
 245    msg.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10)
 246    demo.welmsg = msg
 247    return w
 248
 249def MainTextFont(w):
 250    global demo
 251
 252    if not demo.welmsg:
 253        return
 254    font = demo.welfont['value']
 255    point = demo.welsize['value']
 256    if font == 'Times Roman':
 257        font = 'times'
 258    fontstr = '%s %s' % (font, point)
 259    demo.welmsg['font'] = fontstr
 260
 261def ToggleHelp():
 262    if demo.useBalloons.get() == '1':
 263        demo.balloon['state'] = 'both'
 264    else:
 265        demo.balloon['state'] = 'none'
 266
 267def MkChoosers(nb, name):
 268    w = nb.page(name)
 269    options = "label.padX 4"
 270
 271    til = Tix.LabelFrame(w, label='Chooser Widgets', options=options)
 272    cbx = Tix.LabelFrame(w, label='tixComboBox', options=options)
 273    ctl = Tix.LabelFrame(w, label='tixControl', options=options)
 274    sel = Tix.LabelFrame(w, label='tixSelect', options=options)
 275    opt = Tix.LabelFrame(w, label='tixOptionMenu', options=options)
 276    fil = Tix.LabelFrame(w, label='tixFileEntry', options=options)
 277    fbx = Tix.LabelFrame(w, label='tixFileSelectBox', options=options)
 278    tbr = Tix.LabelFrame(w, label='Tool Bar', options=options)
 279
 280    MkTitle(til.frame)
 281    MkCombo(cbx.frame)
 282    MkControl(ctl.frame)
 283    MkSelect(sel.frame)
 284    MkOptMenu(opt.frame)
 285    MkFileEnt(fil.frame)
 286    MkFileBox(fbx.frame)
 287    MkToolBar(tbr.frame)
 288
 289    # First column: comBox and selector
 290    cbx.form(top=0, left=0, right='%33')
 291    sel.form(left=0, right='&'+str(cbx), top=cbx)
 292    opt.form(left=0, right='&'+str(cbx), top=sel, bottom=-1)
 293
 294    # Second column: title .. etc
 295    til.form(left=cbx, top=0,right='%66')
 296    ctl.form(left=cbx, right='&'+str(til), top=til)
 297    fil.form(left=cbx, right='&'+str(til), top=ctl)
 298    tbr.form(left=cbx, right='&'+str(til), top=fil, bottom=-1)
 299
 300    #
 301    # Third column: file selection
 302    fbx.form(right=-1, top=0, left='%66')
 303
 304def MkCombo(w):
 305    options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 14)
 306
 307    static = Tix.ComboBox(w, label='Static', editable=0, options=options)
 308    editable = Tix.ComboBox(w, label='Editable', editable=1, options=options)
 309    history = Tix.ComboBox(w, label='History', editable=1, history=1,
 310                           anchor=Tix.E, options=options)
 311    static.insert(Tix.END, 'January')
 312    static.insert(Tix.END, 'February')
 313    static.insert(Tix.END, 'March')
 314    static.insert(Tix.END, 'April')
 315    static.insert(Tix.END, 'May')
 316    static.insert(Tix.END, 'June')
 317    static.insert(Tix.END, 'July')
 318    static.insert(Tix.END, 'August')
 319    static.insert(Tix.END, 'September')
 320    static.insert(Tix.END, 'October')
 321    static.insert(Tix.END, 'November')
 322    static.insert(Tix.END, 'December')
 323
 324    editable.insert(Tix.END, 'Angola')
 325    editable.insert(Tix.END, 'Bangladesh')
 326    editable.insert(Tix.END, 'China')
 327    editable.insert(Tix.END, 'Denmark')
 328    editable.insert(Tix.END, 'Ecuador')
 329
 330    history.insert(Tix.END, '/usr/bin/ksh')
 331    history.insert(Tix.END, '/usr/local/lib/python')
 332    history.insert(Tix.END, '/var/adm')
 333
 334    static.pack(side=Tix.TOP, padx=5, pady=3)
 335    editable.pack(side=Tix.TOP, padx=5, pady=3)
 336    history.pack(side=Tix.TOP, padx=5, pady=3)
 337
 338states = ['Bengal', 'Delhi', 'Karnataka', 'Tamil Nadu']
 339
 340def spin_cmd(w, inc):
 341    idx = states.index(demo_spintxt.get()) + inc
 342    if idx < 0:
 343        idx = len(states) - 1
 344    elif idx >= len(states):
 345        idx = 0
 346# following doesn't work.
 347#    return states[idx]
 348    demo_spintxt.set(states[idx])       # this works
 349
 350def spin_validate(w):
 351    global states, demo_spintxt
 352
 353    try:
 354        i = states.index(demo_spintxt.get())
 355    except ValueError:
 356        return states[0]
 357    return states[i]
 358    # why this procedure works as opposed to the previous one beats me.
 359
 360def MkControl(w):
 361    global demo_spintxt
 362
 363    options="label.width %d label.anchor %s entry.width %d" % (10, Tix.E, 13)
 364
 365    demo_spintxt = Tix.StringVar()
 366    demo_spintxt.set(states[0])
 367    simple = Tix.Control(w, label='Numbers', options=options)
 368    spintxt = Tix.Control(w, label='States', variable=demo_spintxt,
 369                          options=options)
 370    spintxt['incrcmd'] = lambda w=spintxt: spin_cmd(w, 1)
 371    spintxt['decrcmd'] = lambda w=spintxt: spin_cmd(w, -1)
 372    spintxt['validatecmd'] = lambda w=spintxt: spin_validate(w)
 373
 374    simple.pack(side=Tix.TOP, padx=5, pady=3)
 375    spintxt.pack(side=Tix.TOP, padx=5, pady=3)
 376
 377def MkSelect(w):
 378    options = "label.anchor %s" % Tix.CENTER
 379
 380    sel1 = Tix.Select(w, label='Mere Mortals', allowzero=1, radio=1,
 381                      orientation=Tix.VERTICAL,
 382                      labelside=Tix.TOP,
 383                      options=options)
 384    sel2 = Tix.Select(w, label='Geeks', allowzero=1, radio=0,
 385                      orientation=Tix.VERTICAL,
 386                      labelside= Tix.TOP,
 387                      options=options)
 388
 389    sel1.add('eat', text='Eat')
 390    sel1.add('work', text='Work')
 391    sel1.add('play', text='Play')
 392    sel1.add('party', text='Party')
 393    sel1.add('sleep', text='Sleep')
 394
 395    sel2.add('eat', text='Eat')
 396    sel2.add('prog1', text='Program')
 397    sel2.add('prog2', text='Program')
 398    sel2.add('prog3', text='Program')
 399    sel2.add('sleep', text='Sleep')
 400
 401    sel1.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
 402    sel2.pack(side=Tix.LEFT, padx=5, pady=3, fill=Tix.X)
 403
 404def MkOptMenu(w):
 405    options='menubutton.width 15 label.anchor %s' % Tix.E
 406
 407    m = Tix.OptionMenu(w, label='File Format : ', options=options)
 408    m.add_command('text', label='Plain Text')
 409    m.add_command('post', label='PostScript')
 410    m.add_command('format', label='Formatted Text')
 411    m.add_command('html', label='HTML')
 412    m.add_command('sep')
 413    m.add_command('tex', label='LaTeX')
 414    m.add_command('rtf', label='Rich Text Format')
 415
 416    m.pack(fill=Tix.X, padx=5, pady=3)
 417
 418def MkFileEnt(w):
 419    msg = Tix.Message(w,
 420                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 421                      text='Press the "open file" icon button and a TixFileSelectDialog will popup.')
 422    ent = Tix.FileEntry(w, label='Select a file : ')
 423    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
 424    ent.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
 425
 426def MkFileBox(w):
 427    """The FileSelectBox is a Motif-style box with various enhancements.
 428    For example, you can adjust the size of the two listboxes
 429    and your past selections are recorded.
 430    """
 431    msg = Tix.Message(w,
 432                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 433                      text='The Tix FileSelectBox 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.')
 434    box = Tix.FileSelectBox(w)
 435    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
 436    box.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
 437
 438def MkToolBar(w):
 439    """The Select widget is also good for arranging buttons in a tool bar.
 440    """
 441    global demo
 442
 443    options='frame.borderWidth 1'
 444
 445    msg = Tix.Message(w,
 446                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 447                      text='The Select widget is also good for arranging buttons in a tool bar.')
 448    bar = Tix.Frame(w, bd=2, relief=Tix.RAISED)
 449    font = Tix.Select(w, allowzero=1, radio=0, label='', options=options)
 450    para = Tix.Select(w, allowzero=0, radio=1, label='', options=options)
 451
 452    font.add('bold', bitmap='@' + demo.dir + '/bitmaps/bold.xbm')
 453    font.add('italic', bitmap='@' + demo.dir + '/bitmaps/italic.xbm')
 454    font.add('underline', bitmap='@' + demo.dir + '/bitmaps/underline.xbm')
 455    font.add('capital', bitmap='@' + demo.dir + '/bitmaps/capital.xbm')
 456
 457    para.add('left', bitmap='@' + demo.dir + '/bitmaps/leftj.xbm')
 458    para.add('right', bitmap='@' + demo.dir + '/bitmaps/rightj.xbm')
 459    para.add('center', bitmap='@' + demo.dir + '/bitmaps/centerj.xbm')
 460    para.add('justify', bitmap='@' + demo.dir + '/bitmaps/justify.xbm')
 461
 462    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
 463    bar.pack(side=Tix.TOP, fill=Tix.X, padx=3, pady=3)
 464    font.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
 465    para.pack({'in':bar}, side=Tix.LEFT, padx=3, pady=3)
 466
 467def MkTitle(w):
 468    msg = Tix.Message(w,
 469                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 470                      text='There are many types of "chooser" widgets that allow the user to input different types of information')
 471    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
 472
 473def MkScroll(nb, name):
 474    w = nb.page(name)
 475    options='label.padX 4'
 476
 477    sls = Tix.LabelFrame(w, label='Tix.ScrolledListBox', options=options)
 478    swn = Tix.LabelFrame(w, label='Tix.ScrolledWindow', options=options)
 479    stx = Tix.LabelFrame(w, label='Tix.ScrolledText', options=options)
 480
 481    MkSList(sls.frame)
 482    MkSWindow(swn.frame)
 483    MkSText(stx.frame)
 484
 485    sls.form(top=0, left=0, right='%33', bottom=-1)
 486    swn.form(top=0, left=sls, right='%66', bottom=-1)
 487    stx.form(top=0, left=swn, right=-1, bottom=-1)
 488
 489
 490def MkSList(w):
 491    """This TixScrolledListBox is configured so that it uses scrollbars
 492    only when it is necessary. Use the handles to resize the listbox and
 493    watch the scrollbars automatically appear and disappear.  """
 494    top = Tix.Frame(w, width=300, height=330)
 495    bot = Tix.Frame(w)
 496    msg = Tix.Message(top,
 497                      relief=Tix.FLAT, width=200, anchor=Tix.N,
 498                      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.')
 499
 500    list = Tix.ScrolledListBox(top, scrollbar='auto')
 501    list.place(x=50, y=150, width=120, height=80)
 502    list.listbox.insert(Tix.END, 'Alabama')
 503    list.listbox.insert(Tix.END, 'California')
 504    list.listbox.insert(Tix.END, 'Montana')
 505    list.listbox.insert(Tix.END, 'New Jersey')
 506    list.listbox.insert(Tix.END, 'New York')
 507    list.listbox.insert(Tix.END, 'Pennsylvania')
 508    list.listbox.insert(Tix.END, 'Washington')
 509
 510    rh = Tix.ResizeHandle(top, bg='black',
 511                          relief=Tix.RAISED,
 512                          handlesize=8, gridded=1, minwidth=50, minheight=30)
 513    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x))
 514    top.propagate(0)
 515    msg.pack(fill=Tix.X)
 516    btn.pack(anchor=Tix.CENTER)
 517    top.pack(expand=1, fill=Tix.BOTH)
 518    bot.pack(fill=Tix.BOTH)
 519    list.bind('<Map>', func=lambda arg=0, rh=rh, list=list:
 520              list.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(list)))
 521
 522def SList_reset(rh, list):
 523    list.place(x=50, y=150, width=120, height=80)
 524    list.update()
 525    rh.attach_widget(list)
 526
 527def MkSWindow(w):
 528    """The ScrolledWindow widget allows you to scroll any kind of Tk
 529    widget. It is more versatile than a scrolled canvas widget.
 530    """
 531    global demo
 532
 533    text = 'The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.'
 534
 535    file = os.path.join(demo.dir, 'bitmaps', 'tix.gif')
 536    if not os.path.isfile(file):
 537        text += ' (Image missing)'
 538
 539    top = Tix.Frame(w, width=330, height=330)
 540    bot = Tix.Frame(w)
 541    msg = Tix.Message(top,
 542                      relief=Tix.FLAT, width=200, anchor=Tix.N,
 543                      text=text)
 544
 545    win = Tix.ScrolledWindow(top, scrollbar='auto')
 546
 547    image1 = win.window.image_create('photo', file=file)
 548    lbl = Tix.Label(win.window, image=image1)
 549    lbl.pack(expand=1, fill=Tix.BOTH)
 550
 551    win.place(x=30, y=150, width=190, height=120)
 552
 553    rh = Tix.ResizeHandle(top, bg='black',
 554                          relief=Tix.RAISED,
 555                          handlesize=8, gridded=1, minwidth=50, minheight=30)
 556    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x))
 557    top.propagate(0)
 558    msg.pack(fill=Tix.X)
 559    btn.pack(anchor=Tix.CENTER)
 560    top.pack(expand=1, fill=Tix.BOTH)
 561    bot.pack(fill=Tix.BOTH)
 562
 563    win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
 564             win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
 565
 566def SWindow_reset(rh, win):
 567    win.place(x=30, y=150, width=190, height=120)
 568    win.update()
 569    rh.attach_widget(win)
 570
 571def MkSText(w):
 572    """The TixScrolledWindow widget allows you to scroll any kind of Tk
 573    widget. It is more versatile than a scrolled canvas widget."""
 574    top = Tix.Frame(w, width=330, height=330)
 575    bot = Tix.Frame(w)
 576    msg = Tix.Message(top,
 577                      relief=Tix.FLAT, width=200, anchor=Tix.N,
 578                      text='The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.')
 579
 580    win = Tix.ScrolledText(top, scrollbar='auto')
 581    win.text['wrap'] = 'none'
 582    win.text.insert(Tix.END, '''When -scrollbar is set to "auto", the
 583scrollbars are shown only when needed.
 584Additional modifiers can be used to force a
 585scrollbar to be shown or hidden. For example,
 586"auto -y" means the horizontal scrollbar
 587should be shown when needed but the vertical
 588scrollbar should always be hidden;
 589"auto +x" means the vertical scrollbar
 590should be shown when needed but the horizontal
 591scrollbar should always be shown, and so on.'''
 592)
 593    win.place(x=30, y=150, width=190, height=100)
 594
 595    rh = Tix.ResizeHandle(top, bg='black',
 596                          relief=Tix.RAISED,
 597                          handlesize=8, gridded=1, minwidth=50, minheight=30)
 598    btn = Tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x))
 599    top.propagate(0)
 600    msg.pack(fill=Tix.X)
 601    btn.pack(anchor=Tix.CENTER)
 602    top.pack(expand=1, fill=Tix.BOTH)
 603    bot.pack(fill=Tix.BOTH)
 604    win.bind('<Map>', func=lambda arg=0, rh=rh, win=win:
 605             win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win)))
 606
 607def SText_reset(rh, win):
 608    win.place(x=30, y=150, width=190, height=120)
 609    win.update()
 610    rh.attach_widget(win)
 611
 612def MkManager(nb, name):
 613    w = nb.page(name)
 614    options='label.padX 4'
 615
 616    pane = Tix.LabelFrame(w, label='Tix.PanedWindow', options=options)
 617    note = Tix.LabelFrame(w, label='Tix.NoteBook', options=options)
 618
 619    MkPanedWindow(pane.frame)
 620    MkNoteBook(note.frame)
 621
 622    pane.form(top=0, left=0, right=note, bottom=-1)
 623    note.form(top=0, right=-1, bottom=-1)
 624
 625def MkPanedWindow(w):
 626    """The PanedWindow widget allows the user to interactively manipulate
 627    the sizes of several panes. The panes can be arranged either vertically
 628    or horizontally.
 629    """
 630    msg = Tix.Message(w,
 631                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 632                      text='The PanedWindow widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.')
 633    group = Tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
 634    group.entry.insert(0,'comp.lang.python')
 635    pane = Tix.PanedWindow(w, orientation='vertical')
 636
 637    p1 = pane.add('list', min=70, size=100)
 638    p2 = pane.add('text', min=70)
 639    list = Tix.ScrolledListBox(p1)
 640    text = Tix.ScrolledText(p2)
 641
 642    list.listbox.insert(Tix.END, "  12324 Re: Tkinter is good for your health")
 643    list.listbox.insert(Tix.END, "+ 12325 Re: Tkinter is good for your health")
 644    list.listbox.insert(Tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
 645    list.listbox.insert(Tix.END, "  12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
 646    list.listbox.insert(Tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
 647    list.listbox.insert(Tix.END, "  12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
 648    list.listbox.insert(Tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)")
 649
 650    text.text['bg'] = list.listbox['bg']
 651    text.text['wrap'] = 'none'
 652    text.text.insert(Tix.END, """
 653Mon, 19 Jun 1995 11:39:52        comp.lang.python              Thread   34 of  220
 654Lines 353       A new way to put text and bitmaps together iNo responses
 655ioi@blue.seas.upenn.edu                Ioi K. Lam at University of Pennsylvania
 656
 657Hi,
 658
 659I have implemented a new image type called "compound". It allows you
 660to glue together a bunch of bitmaps, images and text strings together
 661to form a bigger image. Then you can use this image with widgets that
 662support the -image option. For example, you can display a text string string
 663together with a bitmap, at the same time, inside a TK button widget.
 664""")
 665    list.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
 666    text.pack(expand=1, fill=Tix.BOTH, padx=4, pady=6)
 667
 668    msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
 669    group.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
 670    pane.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH, expand=1)
 671
 672def MkNoteBook(w):
 673    msg = Tix.Message(w,
 674                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 675                      text='The NoteBook widget allows you to layout a complex interface into individual pages.')
 676    # prefix = Tix.OptionName(w)
 677    # if not prefix: prefix = ''
 678    # w.option_add('*' + prefix + '*TixNoteBook*tagPadX', 8)
 679    options = "entry.width %d label.width %d label.anchor %s" % (10, 18, Tix.E)
 680
 681    nb = Tix.NoteBook(w, ipadx=6, ipady=6, options=options)
 682    nb.add('hard_disk', label="Hard Disk", underline=0)
 683    nb.add('network', label="Network", underline=0)
 684
 685    # Frame for the buttons that are present on all pages
 686    common = Tix.Frame(nb.hard_disk)
 687    common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
 688    CreateCommonButtons(common)
 689
 690    # Widgets belonging only to this page
 691    a = Tix.Control(nb.hard_disk, value=12, label='Access Time: ')
 692    w = Tix.Control(nb.hard_disk, value=400, label='Write Throughput: ')
 693    r = Tix.Control(nb.hard_disk, value=400, label='Read Throughput: ')
 694    c = Tix.Control(nb.hard_disk, value=1021, label='Capacity: ')
 695    a.pack(side=Tix.TOP, padx=20, pady=2)
 696    w.pack(side=Tix.TOP, padx=20, pady=2)
 697    r.pack(side=Tix.TOP, padx=20, pady=2)
 698    c.pack(side=Tix.TOP, padx=20, pady=2)
 699
 700    common = Tix.Frame(nb.network)
 701    common.pack(side=Tix.RIGHT, padx=2, pady=2, fill=Tix.Y)
 702    CreateCommonButtons(common)
 703
 704    a = Tix.Control(nb.network, value=12, label='Access Time: ')
 705    w = Tix.Control(nb.network, value=400, label='Write Throughput: ')
 706    r = Tix.Control(nb.network, value=400, label='Read Throughput: ')
 707    c = Tix.Control(nb.network, value=1021, label='Capacity: ')
 708    u = Tix.Control(nb.network, value=10, label='Users: ')
 709    a.pack(side=Tix.TOP, padx=20, pady=2)
 710    w.pack(side=Tix.TOP, padx=20, pady=2)
 711    r.pack(side=Tix.TOP, padx=20, pady=2)
 712    c.pack(side=Tix.TOP, padx=20, pady=2)
 713    u.pack(side=Tix.TOP, padx=20, pady=2)
 714
 715    msg.pack(side=Tix.TOP, padx=3, pady=3, fill=Tix.BOTH)
 716    nb.pack(side=Tix.TOP, padx=5, pady=5, fill=Tix.BOTH, expand=1)
 717
 718def CreateCommonButtons(f):
 719    ok = Tix.Button(f, text='OK', width = 6)
 720    cancel = Tix.Button(f, text='Cancel', width = 6)
 721    ok.pack(side=Tix.TOP, padx=2, pady=2)
 722    cancel.pack(side=Tix.TOP, padx=2, pady=2)
 723
 724def MkDirList(nb, name):
 725    w = nb.page(name)
 726    options = "label.padX 4"
 727
 728    dir = Tix.LabelFrame(w, label='Tix.DirList', options=options)
 729    fsbox = Tix.LabelFrame(w, label='Tix.ExFileSelectBox', options=options)
 730    MkDirListWidget(dir.frame)
 731    MkExFileWidget(fsbox.frame)
 732    dir.form(top=0, left=0, right='%40', bottom=-1)
 733    fsbox.form(top=0, left='%40', right=-1, bottom=-1)
 734
 735def MkDirListWidget(w):
 736    """The TixDirList widget gives a graphical representation of the file
 737    system directory and makes it easy for the user to choose and access
 738    directories.
 739    """
 740    msg = Tix.Message(w,
 741                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 742                      text='The Tix DirList widget gives a graphical representation of the file system directory and makes it easy for the user to choose and access directories.')
 743    dirlist = Tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16')
 744    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
 745    dirlist.pack(side=Tix.TOP, padx=3, pady=3)
 746
 747def MkExFileWidget(w):
 748    """The TixExFileSelectBox widget is more user friendly than the Motif
 749    style FileSelectBox.  """
 750    msg = Tix.Message(w,
 751                      relief=Tix.FLAT, width=240, anchor=Tix.N,
 752                      text='The Tix ExFileSelectBox widget is more user friendly than the Motif style FileSelectBox.')
 753    # There's a bug in the ComboBoxes - the scrolledlistbox is destroyed
 754    box = Tix.ExFileSelectBox(w, bd=2, relief=Tix.RAISED)
 755    msg.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=3, pady=3)
 756    box.pack(side=Tix.TOP, padx=3, pady=3)
 757
 758###
 759### List of all the demos we want to show off
 760comments = {'widget' : 'Widget Demos', 'image' : 'Image Demos'}
 761samples = {'Balloon'            : 'Balloon',
 762           'Button Box'         : 'BtnBox',
 763           'Combo Box'          : 'ComboBox',
 764           'Compound Image'     : 'CmpImg',
 765           'Directory List'     : 'DirList',
 766           'Directory Tree'     : 'DirTree',
 767           'Control'            : 'Control',
 768           'Notebook'           : 'NoteBook',
 769           'Option Menu'        : 'OptMenu',
 770           'Paned Window'       : 'PanedWin',
 771           'Popup Menu'         : 'PopMenu',
 772           'ScrolledHList (1)'  : 'SHList1',
 773           'ScrolledHList (2)'  : 'SHList2',
 774           'Tree (dynamic)'     : 'Tree'
 775}
 776
 777# There are still a lot of demos to be translated:
 778##      set root {
 779##          {d "File Selectors"         file    }
 780##          {d "Hierachical ListBox"    hlist   }
 781##          {d "Tabular ListBox"        tlist   {c tixTList}}
 782##          {d "Grid Widget"            grid    {c tixGrid}}
 783##          {d "Manager Widgets"        manager }
 784##          {d "Scrolled Widgets"       scroll  }
 785##          {d "Miscellaneous Widgets"  misc    }
 786##          {d "Image Types"            image   }
 787##      }
 788##
 789##      set image {
 790##          {d "Compound Image"         cmpimg  }
 791##          {d "XPM Image"              xpm     {i pixmap}}
 792##      }
 793##
 794##      set cmpimg {
 795##done      {f "In Buttons"             CmpImg.tcl      }
 796##          {f "In NoteBook"            CmpImg2.tcl     }
 797##          {f "Notebook Color Tabs"    CmpImg4.tcl     }
 798##          {f "Icons"                  CmpImg3.tcl     }
 799##      }
 800##
 801##      set xpm {
 802##          {f "In Button"              Xpm.tcl         {i pixmap}}
 803##          {f "In Menu"                Xpm1.tcl        {i pixmap}}
 804##      }
 805##
 806##      set file {
 807##added     {f DirList                          DirList.tcl     }
 808##added     {f DirTree                          DirTree.tcl     }
 809##          {f DirSelectDialog                  DirDlg.tcl      }
 810##          {f ExFileSelectDialog               EFileDlg.tcl    }
 811##          {f FileSelectDialog                 FileDlg.tcl     }
 812##          {f FileEntry                        FileEnt.tcl     }
 813##      }
 814##
 815##      set hlist {
 816##          {f HList                    HList1.tcl      }
 817##          {f CheckList                ChkList.tcl     {c tixCheckList}}
 818##done      {f "ScrolledHList (1)"      SHList.tcl      }
 819##done      {f "ScrolledHList (2)"      SHList2.tcl     }
 820##done      {f Tree                     Tree.tcl        }
 821##done      {f "Tree (Dynamic)"         DynTree.tcl     {v win}}
 822##      }
 823##
 824##      set tlist {
 825##          {f "ScrolledTList (1)"      STList1.tcl     {c tixTList}}
 826##          {f "ScrolledTList (2)"      STList2.tcl     {c tixTList}}
 827##      }
 828##      global tcl_platform
 829##      #  This demo hangs windows
 830##      if {$tcl_platform(platform) != "windows"} {
 831##na    lappend tlist     {f "TList File Viewer"        STList3.tcl     {c tixTList}}
 832##      }
 833##
 834##      set grid {
 835##na        {f "Simple Grid"            SGrid0.tcl      {c tixGrid}}
 836##na        {f "ScrolledGrid"           SGrid1.tcl      {c tixGrid}}
 837##na        {f "Editable Grid"          EditGrid.tcl    {c tixGrid}}
 838##      }
 839##
 840##      set scroll {
 841##          {f ScrolledListBox          SListBox.tcl    }
 842##          {f ScrolledText             SText.tcl       }
 843##          {f ScrolledWindow           SWindow.tcl     }
 844##na        {f "Canvas Object View"     CObjView.tcl    {c tixCObjView}}
 845##      }
 846##
 847##      set manager {
 848##          {f ListNoteBook             ListNBK.tcl     }
 849##done      {f NoteBook                 NoteBook.tcl    }
 850##done      {f PanedWindow              PanedWin.tcl    }
 851##      }
 852##
 853##      set misc {
 854##done      {f Balloon                  Balloon.tcl     }
 855##done      {f ButtonBox                BtnBox.tcl      }
 856##done      {f ComboBox                 ComboBox.tcl    }
 857##done      {f Control                  Control.tcl     }
 858##          {f LabelEntry               LabEntry.tcl    }
 859##          {f LabelFrame               LabFrame.tcl    }
 860##          {f Meter                    Meter.tcl       {c tixMeter}}
 861##done      {f OptionMenu               OptMenu.tcl     }
 862##done      {f PopupMenu                PopMenu.tcl     }
 863##          {f Select                   Select.tcl      }
 864##          {f StdButtonBox             StdBBox.tcl     }
 865##      }
 866##
 867
 868stypes = {}
 869stypes['widget'] = ['Balloon', 'Button Box', 'Combo Box', 'Control',
 870                    'Directory List', 'Directory Tree',
 871                    'Notebook', 'Option Menu', 'Popup Menu', 'Paned Window',
 872                    'ScrolledHList (1)', 'ScrolledHList (2)', 'Tree (dynamic)']
 873stypes['image'] = ['Compound Image']
 874
 875def MkSample(nb, name):
 876    w = nb.page(name)
 877    options = "label.padX 4"
 878
 879    pane = Tix.PanedWindow(w, orientation='horizontal')
 880    pane.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH)
 881    f1 = pane.add('list', expand='1')
 882    f2 = pane.add('text', expand='5')
 883    f1['relief'] = 'flat'
 884    f2['relief'] = 'flat'
 885
 886    lab = Tix.LabelFrame(f1, label='Select a sample program:')
 887    lab.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
 888    lab1 = Tix.LabelFrame(f2, label='Source:')
 889    lab1.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5, pady=5)
 890
 891    slb = Tix.Tree(lab.frame, options='hlist.width 20')
 892    slb.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=5)
 893
 894    stext = Tix.ScrolledText(lab1.frame, name='stext')
 895    font = root.tk.eval('tix option get fixed_font')
 896    stext.text.config(font=font)
 897
 898    frame = Tix.Frame(lab1.frame, name='frame')
 899
 900    run = Tix.Button(frame, text='Run ...', name='run')
 901    view = Tix.Button(frame, text='View Source ...', name='view')
 902    run.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
 903    view.pack(side=Tix.LEFT, expand=0, fill=Tix.NONE)
 904
 905    stext.text['bg'] = slb.hlist['bg']
 906    stext.text['state'] = 'disabled'
 907    stext.text['wrap'] = 'none'
 908    stext.text['width'] = 80
 909
 910    frame.pack(side=Tix.BOTTOM, expand=0, fill=Tix.X, padx=7)
 911    stext.pack(side=Tix.TOP, expand=0, fill=Tix.BOTH, padx=7)
 912
 913    slb.hlist['separator'] = '.'
 914    slb.hlist['width'] = 25
 915    slb.hlist['drawbranch'] = 0
 916    slb.hlist['indent'] = 10
 917    slb.hlist['wideselect'] = 1
 918    slb.hlist['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
 919    slb.hlist['browsecmd'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'browse')
 920
 921    run['command']      = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run')
 922    view['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'view')
 923
 924    for type in ['widget', 'image']:
 925        if type != 'widget':
 926            x = Tix.Frame(slb.hlist, bd=2, height=2, width=150,
 927                          relief=Tix.SUNKEN, bg=slb.hlist['bg'])
 928            slb.hlist.add_child(itemtype=Tix.WINDOW, window=x, state='disabled')
 929        x = slb.hlist.add_child(itemtype=Tix.TEXT, state='disabled',
 930                                text=comments[type])
 931        for key in stypes[type]:
 932            slb.hlist.add_child(x, itemtype=Tix.TEXT, data=key,
 933                                text=key)
 934    slb.hlist.selection_clear()
 935
 936    run['state'] = 'disabled'
 937    view['state'] = 'disabled'
 938
 939def Sample_Action(w, slb, stext, run, view, action):
 940    global demo
 941
 942    hlist = slb.hlist
 943    anchor = hlist.info_anchor()
 944    if not anchor:
 945        run['state'] = 'disabled'
 946        view['state'] = 'disabled'
 947    elif not hlist.info_parent(anchor):
 948        # a comment
 949        return
 950
 951    run['state'] = 'normal'
 952    view['state'] = 'normal'
 953    key = hlist.info_data(anchor)
 954    title = key
 955    prog = samples[key]
 956
 957    if action == 'run':
 958        exec('import ' + prog)
 959        w = Tix.Toplevel()
 960        w.title(title)
 961        rtn = eval(prog + '.RunSample')
 962        rtn(w)
 963    elif action == 'view':
 964        w = Tix.Toplevel()
 965        w.title('Source view: ' + title)
 966        LoadFile(w, demo.dir + '/samples/' + prog + '.py')
 967    elif action == 'browse':
 968        ReadFile(stext.text, demo.dir + '/samples/' + prog + '.py')
 969
 970def LoadFile(w, fname):
 971    global root
 972    b = Tix.Button(w, text='Close', command=w.destroy)
 973    t = Tix.ScrolledText(w)
 974    #    b.form(left=0, bottom=0, padx=4, pady=4)
 975    #    t.form(left=0, bottom=b, right='-0', top=0)
 976    t.pack()
 977    b.pack()
 978
 979    font = root.tk.eval('tix option get fixed_font')
 980    t.text.config(font=font)
 981    t.text['bd'] = 2
 982    t.text['wrap'] = 'none'
 983
 984    ReadFile(t.text, fname)
 985
 986def ReadFile(w, fname):
 987    old_state = w['state']
 988    w['state'] = 'normal'
 989    w.delete('0.0', Tix.END)
 990
 991    try:
 992        f = open(fname)
 993        lines = f.readlines()
 994        for s in lines:
 995            w.insert(Tix.END, s)
 996        f.close()
 997    finally:
 998#       w.see('1.0')
 999        w['state'] = old_state
1000
1001if __name__ == '__main__':
1002    root = Tix.Tk()
1003    RunMain(root)