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

Last change on this file since 115 was 115, checked in by mmc, 19 years ago

Updated all copyright notices.

File size: 3.9 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# ======================================================================
15
16namespace eval Rappture { # forward declaration }
17namespace eval Rappture::grab {
18    variable state ""  ;# local ("") or global ("-global") grab
19    variable stack ""  ;# stack of grab windows
20}
21
22proc Rappture::grab::init {} { # used for autoloading this module }
23
24bind all <Escape><Escape><Escape> Rappture::grab::reset
25
26# ----------------------------------------------------------------------
27# USAGE: grab ?-global? <window>
28# USAGE: grab set ?-global? <window>
29# USAGE: grab release <window>
30# USAGE: grab current ?<window>?
31# USAGE: grab status <window>
32#
33# This is a replacement for the usual Tk grab command.  It works
34# exactly the same way, but supports a stack of grab windows, so
35# one window can steal grab from another, and then give it back
36# later.
37# ----------------------------------------------------------------------
38rename grab _tk_grab
39proc grab {args} {
40    set op [lindex $args 0]
41    if {[winfo exists $op]} {
42        set op "set"
43    } elseif {$op == "-global" && [winfo exists [lindex $args end]]} {
44        set op "set"
45    }
46
47    if {$op == "set"} {
48        #
49        # Handle GRAB SET specially.
50        # Add the new grab window to the grab stack.
51        #
52        set state $::Rappture::grab::state
53        set window [lindex $args end]
54        if {[lsearch -exact $args -global] >= 0} {
55            set state "-global"
56        }
57
58        if {"" != $state} {
59            # if it's a global grab, store the -global flag away for later
60            set window [linsert $window 0 $state]
61
62            # all grabs from now on are global
63            set ::Rappture::grab::state "-global"
64        }
65
66        # add the current configuration to the grab stack
67        set ::Rappture::grab::stack \
68            [linsert $::Rappture::grab::stack 0 $window]
69
70        return [eval _tk_grab set $window]
71
72    } elseif {$op == "release"} {
73        #
74        # Handle GRAB RELEASE specially.
75        # Release the current grab and grab the next window on the stack.
76        # Note that the current grab is on the top of the stack.  The
77        # next one down is the one we want to revert to.
78        #
79        set window [lindex $::Rappture::grab::stack 1]
80        set ::Rappture::grab::stack [lrange $::Rappture::grab::stack 1 end]
81
82        # release the current grab
83        eval _tk_grab $args
84
85        # and set the next one
86        if {"" != $window} {
87            if {[lindex $window 0] != "-global"} {
88                # no more global grabs -- resume local grabs
89                set ::Rappture::grab::state ""
90            }
91            eval _tk_grab $window
92        }
93        return ""
94    }
95
96    # perform any other grab operation as usual...
97    return [eval _tk_grab $args]
98}
99
100# ----------------------------------------------------------------------
101# USAGE: Rappture::grab::reset
102#
103# Used internally to reset the grab whenever the user presses
104# Escape a bunch of times to break out of the grab.
105# ----------------------------------------------------------------------
106proc Rappture::grab::reset {} {
107    set w [_tk_grab current]
108    if {"" != $w} {
109        _tk_grab release $w
110    }
111    set Rappture::grab::stack ""
112    set Rappture::grab::state ""
113}
Note: See TracBrowser for help on using the repository browser.