source: trunk/gui/scripts/postern.tcl @ 83

Last change on this file since 83 was 52, checked in by mmc, 19 years ago
  • Added a back door so we can debug Rappture applications running in the nanoHUB environment.
  • Added format and label controls to the axes of an XY plot.
  • Added a <molecule><about><emblems> directive, a boolean control indicating whether or not the molecule viewer should show the atom labels by default. If missing or "off", the labels are turned off. To turn labels on by default, this must be set to a boolean true value.
  • Fixed the packing bug that was causing tabbed notebooks to be the wrong size (size of last page, rather than max overall size).
  • Added -state option to comboboxes, so they can be disabled.
  • Added a grab stack, so that when a balloon dialog has the grab and a combobox steals it away, the balloon gets it back.
File size: 11.1 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: postern - a back door for debugging
3#
4#  This utility gives you a console that you can use to debug any
5#  live application.  You have to click and type the proper magic
6#  in the right spot, and a console area will appear to handle
7#  your requests.
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004-2005
11#  Purdue Research Foundation, West Lafayette, IN
12# ======================================================================
13package require BLT
14package require Itk
15
16blt::bitmap define Postern-dismiss {
17#define dismiss_width 10
18#define dismiss_height 8
19static unsigned char dismiss_bits[] = {
20   0x87, 0x03, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x78, 0x00, 0xfc, 0x00,
21   0xce, 0x01, 0x87, 0x03};
22}
23
24option add *Postern.size 2 widgetDefault
25option add *Postern.activeColor gray widgetDefault
26option add *Postern.popup above widgetDefault
27option add *Postern*Text.font \
28    -*-courier-medium-r-normal-*-*-120-* widgetDefault
29option add *Postern*Text.errorFont \
30    -*-courier-medium-o-normal-*-*-120-* widgetDefault
31
32itcl::class Rappture::Postern {
33    inherit itk::Widget
34
35    itk_option define -size size Size 1
36    itk_option define -activecolor activeColor ActiveColor ""
37    itk_option define -popup popup Popup ""
38
39    constructor {args} { # defined below }
40    destructor { # defined below }
41    public method open {}
42    public method close {}
43    public method activate {args}
44    public method command {option}
45
46    public method _fake_puts {args}
47
48    private variable _active 0    ;# true when active and able to open
49    private variable _focus ""    ;# focus before this widget took over
50    private variable _afterid ""  ;# id for after event that clears activate
51
52    private variable _history ""  ;# list of recent commands
53    private variable _hpos 0      ;# current index in _history
54}
55
56itk::usual Postern {
57    keep -cursor -background
58}
59
60# ----------------------------------------------------------------------
61# CONSTRUCTOR
62# ----------------------------------------------------------------------
63itcl::body Rappture::Postern::constructor {args} {
64    global env
65
66    # this sequence gets things started...
67    bind $itk_component(hull) \
68        <Button-1><Button-1><Button-3><Button-3> \
69        [itcl::code $this activate on]
70
71    #
72    # Get the magic word from the environment.
73    #
74    if {[info exists env(RAPPTURE_POSTERN)]} {
75        set event ""
76        foreach letter [split $env(RAPPTURE_POSTERN) ""] {
77            append event "<Key-$letter>"
78        }
79        bind $itk_component(hull) $event [itcl::code $this open]
80    }
81
82    #
83    # Build the debug dialog.
84    #
85    Rappture::Balloon $itk_component(hull).popup \
86        -deactivatecommand [itcl::code $this activate off]
87
88    set inner [$itk_component(hull).popup component inner]
89    set inner [frame $inner.bd -borderwidth 4 -relief flat]
90    pack $inner -expand yes -fill both
91
92    button $inner.dismiss -bitmap Postern-dismiss \
93        -relief flat -overrelief raised \
94        -command [itcl::code $this close]
95    pack $inner.dismiss -anchor e
96
97    Rappture::Scroller $inner.area
98    pack $inner.area -expand yes -fill both
99    text $inner.area.text
100    $inner.area contents $inner.area.text
101
102    $inner.area.text tag configure error -foreground red \
103        -font [option get $inner.area.text errorFont Font]
104    $inner.area.text tag configure stderr -foreground red \
105        -font [option get $inner.area.text errorFont Font]
106    $inner.area.text tag configure stdout -foreground blue \
107        -font [option get $inner.area.text errorFont Font]
108
109    bind $inner.area.text <KeyPress> \
110        [itcl::code $this command key]
111    bind $inner.area.text <KeyPress-BackSpace> \
112        [itcl::code $this command backspace]
113    bind $inner.area.text <Control-KeyPress-h> \
114        [itcl::code $this command backspace]
115
116    bind $inner.area.text <KeyPress-Return> \
117        [itcl::code $this command execute]
118
119    bind $inner.area.text <KeyPress-Up> \
120        "[itcl::code $this command previous]; break"
121    bind $inner.area.text <Control-KeyPress-p> \
122        "[itcl::code $this command previous]; break"
123
124    bind $inner.area.text <KeyPress-Down> \
125        "[itcl::code $this command next]; break"
126    bind $inner.area.text <Control-KeyPress-n> \
127        "[itcl::code $this command next]; break"
128
129    command prompt
130
131    eval itk_initialize $args
132}
133
134# ----------------------------------------------------------------------
135# DESTRUCTOR
136# ----------------------------------------------------------------------
137itcl::body Rappture::Postern::destructor {} {
138    if {"" != $_afterid} {
139        after cancel $_afterid
140        set _afterid ""
141    }
142}
143
144# ----------------------------------------------------------------------
145# USAGE: active ?on|off?
146#
147# Used to query or set the activation state of this widget.  When
148# the widget is "active", it changes color and accepts the magic
149# pass phrase that will open up the debug panel.  A short delay after
150# being activated, it deactivates itself.
151# ----------------------------------------------------------------------
152itcl::body Rappture::Postern::activate {args} {
153    if {[llength $args] == 0} {
154        return $_active
155    }
156
157    if {"" != $_afterid} {
158        after cancel $_afterid
159        set _afterid ""
160    }
161
162    if {$args} {
163        component hull configure -background $itk_option(-activecolor)
164        set _focus [focus]
165        focus $itk_component(hull)
166        set _active 1
167        set _afterid [after 3000 [itcl::code $this activate off]]
168    } else {
169        focus $_focus
170        set _focus ""
171        component hull configure -background $itk_option(-background)
172
173        if {[info commands _tcl_puts] != ""} {
174            # set puts back to normal
175            rename ::puts ""
176            rename ::_tcl_puts ::puts
177        }
178        set _active 0
179    }
180}
181
182# ----------------------------------------------------------------------
183# USAGE: open
184#
185# Used to open the debug area.  If the widget is active, then the
186# debug area pops up near it.  Otherwise, this method does nothing.
187# ----------------------------------------------------------------------
188itcl::body Rappture::Postern::open {} {
189    if {$_active} {
190        if {"" != $_afterid} {
191            # don't deactivate until we close
192            after cancel $_afterid
193            set _afterid ""
194        }
195
196        $itk_component(hull).popup activate \
197            $itk_component(hull) $itk_option(-popup)
198
199        set text [$itk_component(hull).popup component inner].bd.area.text
200        focus $text
201
202        # make puts send output to this display
203        rename ::puts ::_tcl_puts
204        proc ::puts {args} [format {%s _fake_puts $args} $this]
205    }
206}
207
208itcl::body Rappture::Postern::close {} {
209    $itk_component(hull).popup deactivate
210}
211
212# ----------------------------------------------------------------------
213# USAGE: command prompt
214# USAGE: command execute
215# USAGE: command next
216# USAGE: command previous
217# USAGE: command key
218#
219# Used to handle various editing operations in the text area.
220# ----------------------------------------------------------------------
221itcl::body Rappture::Postern::command {option} {
222    set text [$itk_component(hull).popup component inner].bd.area.text
223
224    switch -- $option {
225        prompt {
226            if {[lindex [split [$text index end-1char] .] 1] != 0} {
227                $text insert end "\n"
228            }
229            $text insert end "% "
230            $text mark set command end-1char
231            $text mark gravity command left
232            $text mark set insert end
233            $text see insert
234        }
235        key {
236            if {[$text compare insert < command]} {
237                $text mark set insert end
238                $text see insert
239            }
240        }
241        backspace {
242            if {[catch {$text index sel.first}] == 0} {
243                if {[$text compare sel.first < command]
244                      || [$text compare sel.last < command]} {
245                    $text tag remove sel 1.0 end
246                }
247            }
248            if {[$text compare insert < command]} {
249                $text mark set insert end
250                $text see insert
251            }
252            if {[$text compare insert == command]} {
253                return -code break  ;# don't erase past start of command
254            }
255        }
256        execute {
257            set cmd [string trim [$text get command end]]
258            if {"" == $cmd} {
259                command prompt
260            } else {
261                lappend _history $cmd
262                if {[llength $_history] > 100} {
263                    set _history [lrange $_history end-100 end]
264                }
265                set _hpos [llength $_history]
266
267                $text insert end "\n"
268                if {[catch {uplevel #0 $cmd} result]} {
269                    $text insert end $result error
270                } else {
271                    $text insert end $result
272                }
273                command prompt
274            }
275            return -code break
276        }
277        next {
278            if {$_hpos < [llength $_history]} {
279                incr _hpos
280                set cmd [lindex $_history $_hpos]
281                $text delete command end
282                $text insert command $cmd
283                $text mark set insert end
284                $text see insert
285            }
286        }
287        previous {
288            if {$_hpos > 0} {
289                incr _hpos -1
290                set cmd [lindex $_history $_hpos]
291                $text delete command end
292                $text insert command $cmd
293                $text mark set insert end
294                $text see insert
295            }
296        }
297        default {
298            error "bad option \"$option\""
299        }
300    }
301}
302
303# ----------------------------------------------------------------------
304# USAGE: _fake_puts {?-nonewline? ?<channel>? <string>}
305#
306# This method acts as a replacement for puts.  It sends output
307# to the postern screen, itstead of stdin/stdout.
308# ----------------------------------------------------------------------
309itcl::body Rappture::Postern::_fake_puts {arglist} {
310    Rappture::getopts arglist params {
311        flag group -nonewline
312    }
313    switch -- [llength $arglist] {
314        1 {
315            set channel stdout
316            set string [lindex $arglist 0]
317        }
318        2 {
319            set channel [lindex $arglist 0]
320            set string [lindex $arglist 1]
321        }
322        default {
323            error "wrong # args: should be \"puts ?-nonewline? ?channel? string\""
324        }
325    }
326
327    set text [$itk_component(hull).popup component inner].bd.area.text
328    if {$channel == "stdout" || $channel == "stderr"} {
329        $text insert end $string $channel
330        if {!$params(-nonewline)} {
331            $text insert end "\n"
332        }
333    } else {
334        eval _tcl_puts $arglist
335    }
336}
337
338# ----------------------------------------------------------------------
339# CONFIGURATION OPTION: -size
340# ----------------------------------------------------------------------
341itcl::configbody Rappture::Postern::size {
342    component hull configure \
343        -width $itk_option(-size) \
344        -height $itk_option(-size)
345}
Note: See TracBrowser for help on using the repository browser.