source: trunk/gui/scripts/notebook.tcl @ 1

Last change on this file since 1 was 1, checked in by mmc, 16 years ago

initial import

File size: 8.3 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: notebook - series of pages, but only one packed at a time
3#
4#  This widget acts as the core of a tabbed notebook, without the tabs.
5#  It allows you to create a series of pages, and display one page at
6#  time.  The overall widget is just big enough to accommodate all of
7#  the pages within it.
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004  Purdue Research Foundation, West Lafayette, IN
11# ======================================================================
12package require Itk
13
14option add *Notebook.width 0 widgetDefault
15option add *Notebook.height 0 widgetDefault
16
17itcl::class Rappture::Notebook {
18    inherit itk::Widget
19
20    itk_option define -width width Width 0
21    itk_option define -height height Height 0
22
23    constructor {args} { # defined below }
24    destructor { # defined below }
25
26    public method insert {pos args}
27    public method delete {args}
28    public method index {name}
29    public method page {name}
30    public method current {args}
31
32    protected method _fixSize {}
33
34    private variable _count 0       ;# counter for unique names
35    private variable _pages ""      ;# list of page frames
36    private variable _name2page     ;# maps name => frame for page
37    private variable _current ""    ;# page currently shown
38}
39                                                                               
40itk::usual Notebook {
41    keep -background -cursor
42}
43
44# ----------------------------------------------------------------------
45# CONSTRUCTOR
46# ----------------------------------------------------------------------
47itcl::body Rappture::Notebook::constructor {args} {
48    pack propagate $itk_component(hull) no
49    eval itk_initialize $args
50}
51
52# ----------------------------------------------------------------------
53# DESTRUCTOR
54# ----------------------------------------------------------------------
55itcl::body Rappture::Notebook::destructor {} {
56    after cancel [itcl::code $this _fixSize]
57}
58
59# ----------------------------------------------------------------------
60# USAGE: insert <pos> ?<name> <name>...?
61#
62# Used to insert one or more pages in the notebook.  Each page is
63# identified by its <name>.  Returns the widget name for each
64# page created.
65# ----------------------------------------------------------------------
66itcl::body Rappture::Notebook::insert {pos args} {
67    set rlist ""
68    foreach name $args {
69        if {[lsearch $_pages $name] >= 0} {
70            error "page \"$name\" already exists"
71        }
72        set pname "page[incr _count]"
73        itk_component add $pname {
74            frame $itk_interior.$pname
75        }
76        set _pages [linsert $_pages $pos $name]
77        set _name2page($name) $itk_component($pname)
78
79        bind $itk_component($pname) <Configure> [itcl::code $this _fixSize]
80
81        after cancel [itcl::code $this _fixSize]
82        after idle [itcl::code $this _fixSize]
83
84        lappend rlist $itk_component($pname)
85    }
86    return $rlist
87}
88
89# ----------------------------------------------------------------------
90# USAGE: delete -all
91# USAGE: delete ?<name> <name>...?
92#
93# Used to delete one or more pages from the notebook.  With the -all
94# flag, it deletes all pages.  Otherwise, it deletes each page
95# by name.  You can also delete a page by using an index of the
96# form "@n".
97# ----------------------------------------------------------------------
98itcl::body Rappture::Notebook::delete {args} {
99    if {$args == "-all"} {
100        set args $_pages
101    }
102    foreach name $args {
103        set i [index $name]
104        set pname [lindex $_pages $i]
105        if {$pname != ""} {
106            set _pages [lreplace $_pages $i $i]
107            destroy $_name2page($pname)
108            unset _name2page($pname)
109        }
110    }
111}
112
113# ----------------------------------------------------------------------
114# USAGE: index <name>|@n
115#
116# Used to convert a page <name> to its corresponding integer index.
117# ----------------------------------------------------------------------
118itcl::body Rappture::Notebook::index {name} {
119    set i [lsearch $_pages $name]
120    if {$i >= 0} {
121        return $i
122    }
123    if {[regexp {^@([0-9]+)$} $name match i]} {
124        return $i
125    }
126    error "bad page name \"$name\": should be @int or one of [join [lsort $_pages] {, }]"
127}
128
129# ----------------------------------------------------------------------
130# USAGE: page <name>|@n
131#
132# Used to convert a page <name> to its corresponding frame.
133# ----------------------------------------------------------------------
134itcl::body Rappture::Notebook::page {name} {
135    set i [index $name]
136    set name [lindex $_pages $i]
137    return $_name2page($name)
138}
139
140# ----------------------------------------------------------------------
141# USAGE: current ?<name>|next>>|<<prev?
142#
143# Used to query/set the current page in the notebook.  With no args,
144# it returns the name of the current page.  Otherwise, it sets the
145# current page.  The special token "next>>" is used to set the notebook
146# to the next logical page, and "<<prev" sets to the previous.
147# ----------------------------------------------------------------------
148itcl::body Rappture::Notebook::current {args} {
149    switch -- [llength $args] {
150        0 {
151            return $_current
152        }
153        1 {
154            set name [lindex $args 0]
155            set index 0
156            if {$name == "next>>"} {
157                if {$_current == ""} {
158                    set index 0
159                } else {
160                    set i [lsearch -exact $_pages $_current]
161                    set index [expr {$i+1}]
162                    if {$index >= [llength $_pages]} {
163                        set index [expr {[llength $_pages]-1}]
164                    }
165                }
166            } elseif {$name == "<<prev"} {
167                if {$_current == ""} {
168                    set index end
169                } else {
170                    set i [lsearch -exact $_pages $_current]
171                    set index [expr {$i-1}]
172                    if {$index < 0} {
173                        set index 0
174                    }
175                }
176            } else {
177                set index [lsearch -exact $_pages $name]
178                if {$index < 0} {
179                    error "can't move to page \"$name\""
180                }
181            }
182
183            set _current [lindex $_pages $index]
184
185            foreach w [pack slaves $itk_component(hull)] {
186                pack forget $w
187            }
188            pack $_name2page($_current) -expand yes -fill both
189        }
190        default {
191            error "wrong # args: should be \"current name|next>>|<<prev\""
192        }
193    }
194}
195
196# ----------------------------------------------------------------------
197# USAGE: _fixSize
198#
199# Invoked automatically whenever a page changes size or the -width
200# or -height options change.  When the -width/-height are zero, this
201# method computes the minimum size needed to accommodate all pages.
202# Otherwise, it passes the size request onto the hull.
203# ----------------------------------------------------------------------
204itcl::body Rappture::Notebook::_fixSize {} {
205    if {$itk_option(-width) <= 0} {
206        set maxw 0
207        foreach name $_pages {
208            set w [winfo reqwidth $_name2page($name)]
209            if {$w > $maxw} { set maxw $w }
210        }
211        component hull configure -width $maxw
212    } else {
213        component hull configure -width $itk_option(-width)
214    }
215
216    if {$itk_option(-height) <= 0} {
217        set maxh 0
218        foreach name $_pages {
219            set h [winfo reqheight $_name2page($name)]
220            if {$h > $maxh} { set maxh $h }
221        }
222        component hull configure -height $maxh
223    } else {
224        component hull configure -height $itk_option(-height)
225    }
226}
227
228# ----------------------------------------------------------------------
229# OPTION: -width
230# ----------------------------------------------------------------------
231itcl::configbody Rappture::Notebook::width {
232    after cancel [itcl::code $this _fixSize]
233    after idle [itcl::code $this _fixSize]
234}
235
236# ----------------------------------------------------------------------
237# OPTION: -height
238# ----------------------------------------------------------------------
239itcl::configbody Rappture::Notebook::height {
240    after cancel [itcl::code $this _fixSize]
241    after idle [itcl::code $this _fixSize]
242}
Note: See TracBrowser for help on using the repository browser.