[175] | 1 | #
|
---|
| 2 | # tabnotebook.tcl
|
---|
| 3 | #
|
---|
| 4 | # ----------------------------------------------------------------------
|
---|
| 5 | # Bindings for the BLT tabnotebook widget
|
---|
| 6 | # ----------------------------------------------------------------------
|
---|
| 7 | # AUTHOR: George Howlett
|
---|
| 8 | # Bell Labs Innovations for Lucent Technologies
|
---|
| 9 | # gah@bell-labs.com
|
---|
| 10 | # http://www.tcltk.com/blt
|
---|
| 11 | # ----------------------------------------------------------------------
|
---|
| 12 | # Copyright (c) 1998 Lucent Technologies, Inc.
|
---|
| 13 | # ======================================================================
|
---|
| 14 | #
|
---|
| 15 | # Permission to use, copy, modify, and distribute this software and its
|
---|
| 16 | # documentation for any purpose and without fee is hereby granted,
|
---|
| 17 | # provided that the above copyright notice appear in all copies and that
|
---|
| 18 | # both that the copyright notice and warranty disclaimer appear in
|
---|
| 19 | # supporting documentation, and that the names of Lucent Technologies
|
---|
| 20 | # any of their entities not be used in advertising or publicity
|
---|
| 21 | # pertaining to distribution of the software without specific, written
|
---|
| 22 | # prior permission.
|
---|
| 23 | #
|
---|
| 24 | # Lucent Technologies disclaims all warranties with regard to this
|
---|
| 25 | # software, including all implied warranties of merchantability and
|
---|
| 26 | # fitness. In no event shall Lucent be liable for any special, indirect
|
---|
| 27 | # or consequential damages or any damages whatsoever resulting from loss
|
---|
| 28 | # of use, data or profits, whether in an action of contract, negligence
|
---|
| 29 | # or other tortuous action, arising out of or in connection with the use
|
---|
| 30 | # or performance of this software.
|
---|
| 31 | #
|
---|
| 32 | # ======================================================================
|
---|
| 33 |
|
---|
| 34 | #
|
---|
| 35 | # Indicates whether to activate (highlight) tabs when the mouse passes
|
---|
| 36 | # over them. This is turned off during scan operations.
|
---|
| 37 | #
|
---|
| 38 | set bltTabnotebook(activate) yes
|
---|
| 39 |
|
---|
| 40 | # ----------------------------------------------------------------------
|
---|
| 41 | #
|
---|
| 42 | # ButtonPress assignments
|
---|
| 43 | #
|
---|
| 44 | # <ButtonPress-2> Starts scan mechanism (pushes the tabs)
|
---|
| 45 | # <B2-Motion> Adjust scan
|
---|
| 46 | # <ButtonRelease-2> Stops scan
|
---|
| 47 | #
|
---|
| 48 | # ----------------------------------------------------------------------
|
---|
| 49 | bind Tabnotebook <B2-Motion> {
|
---|
| 50 | %W scan dragto %x %y
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | bind Tabnotebook <ButtonPress-2> {
|
---|
| 54 | set bltTabnotebook(cursor) [%W cget -cursor]
|
---|
| 55 | set bltTabnotebook(activate) no
|
---|
| 56 | %W configure -cursor hand1
|
---|
| 57 | %W scan mark %x %y
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | bind Tabnotebook <ButtonRelease-2> {
|
---|
| 61 | %W configure -cursor $bltTabnotebook(cursor)
|
---|
| 62 | set bltTabnotebook(activate) yes
|
---|
| 63 | %W activate @%x,%y
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | # ----------------------------------------------------------------------
|
---|
| 67 | #
|
---|
| 68 | # KeyPress assignments
|
---|
| 69 | #
|
---|
| 70 | # <KeyPress-Up> Moves focus to the tab immediately above the
|
---|
| 71 | # current.
|
---|
| 72 | # <KeyPress-Down> Moves focus to the tab immediately below the
|
---|
| 73 | # current.
|
---|
| 74 | # <KeyPress-Left> Moves focus to the tab immediately left of the
|
---|
| 75 | # currently focused tab.
|
---|
| 76 | # <KeyPress-Right> Moves focus to the tab immediately right of the
|
---|
| 77 | # currently focused tab.
|
---|
| 78 | # <KeyPress-space> Invokes the commands associated with the current
|
---|
| 79 | # tab.
|
---|
| 80 | # <KeyPress-Return> Same as above.
|
---|
| 81 | # <KeyPress> Go to next tab starting with the ASCII character.
|
---|
| 82 | #
|
---|
| 83 | # ----------------------------------------------------------------------
|
---|
| 84 | bind Tabnotebook <KeyPress-Up> { blt::SelectTab %W "up" }
|
---|
| 85 | bind Tabnotebook <KeyPress-Down> { blt::SelectTab %W "down" }
|
---|
| 86 | bind Tabnotebook <KeyPress-Right> { blt::SelectTab %W "right" }
|
---|
| 87 | bind Tabnotebook <KeyPress-Left> { blt::SelectTab %W "left" }
|
---|
| 88 | bind Tabnotebook <KeyPress-space> { %W invoke focus }
|
---|
| 89 | bind Tabnotebook <KeyPress-Return> { %W invoke focus }
|
---|
| 90 |
|
---|
| 91 | bind Tabnotebook <KeyPress> {
|
---|
| 92 | if { [string match {[A-Za-z0-9]*} "%A"] } {
|
---|
| 93 | blt::FindMatchingTab %W %A
|
---|
| 94 | }
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | # ----------------------------------------------------------------------
|
---|
| 98 | #
|
---|
| 99 | # FirstMatchingTab --
|
---|
| 100 | #
|
---|
| 101 | # Find the first tab (from the tab that currently has focus)
|
---|
| 102 | # starting with the same first letter as the tab. It searches
|
---|
| 103 | # in order of the tab positions and wraps around. If no tab
|
---|
| 104 | # matches, it stops back at the current tab.
|
---|
| 105 | #
|
---|
| 106 | # Arguments:
|
---|
| 107 | # widget Tabnotebook widget.
|
---|
| 108 | # key ASCII character of key pressed
|
---|
| 109 | #
|
---|
| 110 | # ----------------------------------------------------------------------
|
---|
| 111 | proc blt::FindMatchingTab { widget key } {
|
---|
| 112 | set key [string tolower $key]
|
---|
| 113 | set itab [$widget index focus]
|
---|
| 114 | set numTabs [$widget size]
|
---|
| 115 | for { set i 0 } { $i < $numTabs } { incr i } {
|
---|
| 116 | if { [incr itab] >= $numTabs } {
|
---|
| 117 | set itab 0
|
---|
| 118 | }
|
---|
| 119 | set label [string tolower [$widget tab cget $itab -text]]
|
---|
| 120 | if { [string index $label 0] == $key } {
|
---|
| 121 | break
|
---|
| 122 | }
|
---|
| 123 | }
|
---|
| 124 | $widget focus $itab
|
---|
| 125 | $widget see focus
|
---|
| 126 | }
|
---|
| 127 |
|
---|
| 128 | # ----------------------------------------------------------------------
|
---|
| 129 | #
|
---|
| 130 | # SelectTab --
|
---|
| 131 | #
|
---|
| 132 | # Invokes the command for the tab. If the widget associated tab
|
---|
| 133 | # is currently torn off, the tearoff is raised.
|
---|
| 134 | #
|
---|
| 135 | # Arguments:
|
---|
| 136 | # widget Tabnotebook widget.
|
---|
| 137 | # x y Unused.
|
---|
| 138 | #
|
---|
| 139 | # ----------------------------------------------------------------------
|
---|
| 140 | proc blt::SelectTab { widget tab } {
|
---|
| 141 | set index [$widget index $tab]
|
---|
| 142 | if { $index != "" } {
|
---|
| 143 | $widget select $index
|
---|
| 144 | $widget focus $index
|
---|
| 145 | $widget see $index
|
---|
| 146 | set w [$widget tab tearoff $index]
|
---|
| 147 | if { ($w != "") && ($w != "$widget") } {
|
---|
| 148 | raise [winfo toplevel $w]
|
---|
| 149 | }
|
---|
| 150 | $widget invoke $index
|
---|
| 151 | }
|
---|
| 152 | }
|
---|
| 153 |
|
---|
| 154 | # ----------------------------------------------------------------------
|
---|
| 155 | #
|
---|
| 156 | # DestroyTearoff --
|
---|
| 157 | #
|
---|
| 158 | # Destroys the toplevel window and the container tearoff
|
---|
| 159 | # window holding the embedded widget. The widget is placed
|
---|
| 160 | # back inside the tab.
|
---|
| 161 | #
|
---|
| 162 | # Arguments:
|
---|
| 163 | # widget Tabnotebook widget.
|
---|
| 164 | # tab Tab selected.
|
---|
| 165 | #
|
---|
| 166 | # ----------------------------------------------------------------------
|
---|
| 167 | proc blt::DestroyTearoff { widget tab } {
|
---|
| 168 | set id [$widget id $tab]
|
---|
| 169 | set top "$widget.toplevel-$id"
|
---|
| 170 | if { [winfo exists $top] } {
|
---|
| 171 | wm withdraw $top
|
---|
| 172 | update
|
---|
| 173 | $widget tab tearoff $tab $widget
|
---|
| 174 | destroy $top
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | # ----------------------------------------------------------------------
|
---|
| 179 | #
|
---|
| 180 | # CreateTearoff --
|
---|
| 181 | #
|
---|
| 182 | # Creates a new toplevel window and moves the embedded widget
|
---|
| 183 | # into it. The toplevel is placed just below the tab. The
|
---|
| 184 | # DELETE WINDOW property is set so that if the toplevel window
|
---|
| 185 | # is requested to be deleted by the window manager, the embedded
|
---|
| 186 | # widget is placed back inside of the tab. Note also that
|
---|
| 187 | # if the tabnotebook container is ever destroyed, the toplevel is
|
---|
| 188 | # also destroyed.
|
---|
| 189 | #
|
---|
| 190 | # Arguments:
|
---|
| 191 | # widget Tabnotebook widget.
|
---|
| 192 | # tab Tab selected.
|
---|
| 193 | # x y The coordinates of the mouse pointer.
|
---|
| 194 | #
|
---|
| 195 | # ----------------------------------------------------------------------
|
---|
| 196 | proc blt::CreateTearoff { widget tab rootX rootY } {
|
---|
| 197 |
|
---|
| 198 | # ------------------------------------------------------------------
|
---|
| 199 | # When reparenting the window contained in the tab, check if the
|
---|
| 200 | # window or any window in its hierarchy currently has focus.
|
---|
| 201 | # Since we're reparenting windows behind its back, Tk can
|
---|
| 202 | # mistakenly activate the keyboard focus when the mouse enters the
|
---|
| 203 | # old toplevel. The simplest way to deal with this problem is to
|
---|
| 204 | # take the focus off the window and set it to the tabnotebook widget
|
---|
| 205 | # itself.
|
---|
| 206 | # ------------------------------------------------------------------
|
---|
| 207 |
|
---|
| 208 | set focus [focus]
|
---|
| 209 | set window [$widget tab cget $tab -window]
|
---|
| 210 | set index [$widget index $tab]
|
---|
| 211 | if { ($focus == $window) || ([string match $window.* $focus]) } {
|
---|
| 212 | focus -force $widget
|
---|
| 213 | }
|
---|
| 214 | set id [$widget id $index]
|
---|
| 215 | set top "$widget.toplevel-$id"
|
---|
| 216 | toplevel $top
|
---|
| 217 | $widget tab tearoff $tab $top.container
|
---|
| 218 | table $top $top.container -fill both
|
---|
| 219 |
|
---|
| 220 | incr rootX 10 ; incr rootY 10
|
---|
| 221 | wm geometry $top +$rootX+$rootY
|
---|
| 222 |
|
---|
| 223 | set parent [winfo toplevel $widget]
|
---|
| 224 | wm title $top "[wm title $parent]: [$widget tab cget $index -text]"
|
---|
| 225 | wm transient $top $parent
|
---|
| 226 |
|
---|
| 227 | # If the user tries to delete the toplevel, put the window back
|
---|
| 228 | # into the tab folder.
|
---|
| 229 |
|
---|
| 230 | wm protocol $top WM_DELETE_WINDOW [list blt::DestroyTearoff $widget $tab]
|
---|
| 231 |
|
---|
| 232 | # If the container is ever destroyed, automatically destroy the
|
---|
| 233 | # toplevel too.
|
---|
| 234 |
|
---|
| 235 | bind $top.container <Destroy> [list destroy $top]
|
---|
| 236 | }
|
---|
| 237 |
|
---|
| 238 | # ----------------------------------------------------------------------
|
---|
| 239 | #
|
---|
| 240 | # ToggleTearoff --
|
---|
| 241 | #
|
---|
| 242 | # Toggles the tab tearoff. If the tab contains a embedded widget,
|
---|
| 243 | # it is placed inside of a toplevel window. If the widget has
|
---|
| 244 | # already been torn off, the widget is replaced back in the tab.
|
---|
| 245 | #
|
---|
| 246 | # Arguments:
|
---|
| 247 | # widget tabnotebook widget.
|
---|
| 248 | # x y The coordinates of the mouse pointer.
|
---|
| 249 | #
|
---|
| 250 | # ----------------------------------------------------------------------
|
---|
| 251 | proc blt::ToggleTearoff { widget x y index } {
|
---|
| 252 | set tab [$widget index $index]
|
---|
| 253 | if { $tab == "" } {
|
---|
| 254 | return
|
---|
| 255 | }
|
---|
| 256 | $widget invoke $tab
|
---|
| 257 |
|
---|
| 258 | set container [$widget tab tearoff $index]
|
---|
| 259 | if { $container == "$widget" } {
|
---|
| 260 | blt::CreateTearoff $widget $tab $x $y
|
---|
| 261 | } elseif { $container != "" } {
|
---|
| 262 | blt::DestroyTearoff $widget $tab
|
---|
| 263 | }
|
---|
| 264 | }
|
---|
| 265 |
|
---|
| 266 | # ----------------------------------------------------------------------
|
---|
| 267 | #
|
---|
| 268 | # TabnotebookInit
|
---|
| 269 | #
|
---|
| 270 | # Invoked from C whenever a new tabnotebook widget is created.
|
---|
| 271 | # Sets up the default bindings for the all tab entries.
|
---|
| 272 | # These bindings are local to the widget, so they can't be
|
---|
| 273 | # set through the usual widget class bind tags mechanism.
|
---|
| 274 | #
|
---|
| 275 | # <Enter> Activates the tab.
|
---|
| 276 | # <Leave> Deactivates all tabs.
|
---|
| 277 | # <ButtonPress-1> Selects the tab and invokes its command.
|
---|
| 278 | # <Control-ButtonPress-1>
|
---|
| 279 | # Toggles the tab tearoff. If the tab contains
|
---|
| 280 | # a embedded widget, it is placed inside of a
|
---|
| 281 | # toplevel window. If the widget has already
|
---|
| 282 | # been torn off, the widget is replaced back
|
---|
| 283 | # in the tab.
|
---|
| 284 | #
|
---|
| 285 | # Arguments:
|
---|
| 286 | # widget tabnotebook widget
|
---|
| 287 | #
|
---|
| 288 | # ----------------------------------------------------------------------
|
---|
| 289 | proc blt::TabnotebookInit { widget } {
|
---|
| 290 | $widget bind all <Enter> {
|
---|
| 291 | if { $bltTabnotebook(activate) } {
|
---|
| 292 | %W activate current
|
---|
| 293 | }
|
---|
| 294 | }
|
---|
| 295 | $widget bind all <Leave> {
|
---|
| 296 | %W activate ""
|
---|
| 297 | }
|
---|
| 298 | $widget bind all <ButtonPress-1> {
|
---|
| 299 | blt::SelectTab %W "current"
|
---|
| 300 | }
|
---|
| 301 | $widget bind all <Control-ButtonPress-1> {
|
---|
| 302 | blt::ToggleTearoff %W %X %Y active
|
---|
| 303 | }
|
---|
| 304 | $widget configure -perforationcommand {
|
---|
| 305 | blt::ToggleTearoff %W $bltTabnotebook(x) $bltTabnotebook(y) select
|
---|
| 306 | }
|
---|
| 307 | $widget bind Perforation <Enter> {
|
---|
| 308 | %W perforation activate on
|
---|
| 309 | }
|
---|
| 310 | $widget bind Perforation <Leave> {
|
---|
| 311 | %W perforation activate off
|
---|
| 312 | }
|
---|
| 313 | $widget bind Perforation <ButtonPress-1> {
|
---|
| 314 | set bltTabnotebook(x) %X
|
---|
| 315 | set bltTabnotebook(y) %Y
|
---|
| 316 | %W perforation invoke
|
---|
| 317 | }
|
---|
| 318 | }
|
---|