source: trunk/gui/scripts/grab.tcl @ 1313

Last change on this file since 1313 was 210, checked in by mmc, 18 years ago

Last few fixes for file upload/download. Changed the "Download..."
button to an icon, and added a "Download..." option on the drop-down
list for the Results area. Fixed the "Upload..." to pop up a message,
in case the web form doesn't appear.

Fixed the "grab" function, so it won't fail with a Tk error box.
If it can't get the grab, it tries a few more times and then gives
up. Also, fixed <Esc><Esc><Esc> desperation binding to release
any busy windows.

File size: 4.2 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: grab - improved version of the Tk grab command
3#
4#  This version of "grab" keeps a stack of grab windows, so one
5#  window can steal and release the grab, and the grab will revert
6#  to the previous window.  If things get jammed up, you can press
7#  <Escape> three times to release the grab.
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004-2005  Purdue Research Foundation
11#
12#  See the file "license.terms" for information on usage and
13#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14# ======================================================================
15package require BLT
16
17namespace eval Rappture { # forward declaration }
18namespace eval Rappture::grab {
19    variable state ""  ;# local ("") or global ("-global") grab
20    variable stack ""  ;# stack of grab windows
21}
22
23proc Rappture::grab::init {} { # used for autoloading this module }
24
25bind all <Escape><Escape><Escape> Rappture::grab::reset
26
27# ----------------------------------------------------------------------
28# USAGE: grab ?-global? <window>
29# USAGE: grab set ?-global? <window>
30# USAGE: grab release <window>
31# USAGE: grab current ?<window>?
32# USAGE: grab status <window>
33#
34# This is a replacement for the usual Tk grab command.  It works
35# exactly the same way, but supports a stack of grab windows, so
36# one window can steal grab from another, and then give it back
37# later.
38# ----------------------------------------------------------------------
39rename grab _tk_grab
40proc grab {args} {
41    set op [lindex $args 0]
42    if {[winfo exists $op]} {
43        set op "set"
44    } elseif {$op == "-global" && [winfo exists [lindex $args end]]} {
45        set op "set"
46    }
47
48    if {$op == "set"} {
49        #
50        # Handle GRAB SET specially.
51        # Add the new grab window to the grab stack.
52        #
53        set state $::Rappture::grab::state
54        set window [lindex $args end]
55        if {[lsearch -exact $args -global] >= 0} {
56            set state "-global"
57        }
58
59        if {"" != $state} {
60            # if it's a global grab, store the -global flag away for later
61            set window [linsert $window 0 $state]
62
63            # all grabs from now on are global
64            set ::Rappture::grab::state "-global"
65        }
66
67        # add the current configuration to the grab stack
68        set ::Rappture::grab::stack \
69            [linsert $::Rappture::grab::stack 0 $window]
70
71        return [eval _grabset $window]
72
73    } elseif {$op == "release"} {
74        #
75        # Handle GRAB RELEASE specially.
76        # Release the current grab and grab the next window on the stack.
77        # Note that the current grab is on the top of the stack.  The
78        # next one down is the one we want to revert to.
79        #
80        set window [lindex $::Rappture::grab::stack 1]
81        set ::Rappture::grab::stack [lrange $::Rappture::grab::stack 1 end]
82
83        # release the current grab
84        eval _tk_grab $args
85
86        # and set the next one
87        if {"" != $window} {
88            if {[lindex $window 0] != "-global"} {
89                # no more global grabs -- resume local grabs
90                set ::Rappture::grab::state ""
91            }
92            eval _grabset $window
93        }
94        return ""
95    }
96
97    # perform any other grab operation as usual...
98    return [eval _tk_grab $args]
99}
100
101proc _grabset {args} {
102    # give it 3 tries, if necessary
103    for {set i 0} {$i < 3} {incr i} {
104        set status [catch {eval _tk_grab set $args} result]
105        if {$status == 0} {
106            return $result
107        }
108        after 100; update
109    }
110    # oh well, we tried...
111    return ""
112}
113
114# ----------------------------------------------------------------------
115# USAGE: Rappture::grab::reset
116#
117# Used internally to reset the grab whenever the user presses
118# Escape a bunch of times to break out of the grab.
119# ----------------------------------------------------------------------
120proc Rappture::grab::reset {} {
121    set w [_tk_grab current]
122    if {"" != $w} {
123        _tk_grab release $w
124    }
125    set Rappture::grab::stack ""
126    set Rappture::grab::state ""
127
128    foreach win [blt::busy windows] {
129        blt::busy release $win
130    }
131}
Note: See TracBrowser for help on using the repository browser.