1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
|
#
# Copyright (c) Medical Research Council, Laboratory of Molecular Biology,
# 1995. All rights reserved.
#
# This file is part of the Staden Package. See the Staden Package copyright
# notice for information on the restrictions for usage and distribution, and
# for a disclaimer of all warranties.
#
##############################################################################
# displays a stack dump for tcl
proc stack_dump {} {
puts "ERROR!!! - Tcl stackframe follows"
for {set i [info level]} {$i > 0} {incr i -1} {
puts "Level $i: [info level $i]"
}
}
##############################################################################
# checks if an input is an integer
proc isinteger { value } {
return [regexp {^[+-]?[0-9]+$} $value]
}
##############################################################################
# checks if an input is an float
proc isfloat { value } {
return [regexp {^[+-]?[0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?$} $value]
}
##############################################################################
#Set busy mode
proc InitBusy {main menu name} {
global busy_main_path busy_menu_path busy_menu_name
set busy_main_path $main
set busy_menu_path $menu
set busy_menu_name $name
}
proc SetBusy {} {
global busy_main_path busy_menu_path busy_menu_name busy_menu_state
set busy_menu_state [menu_state_save $busy_menu_path $busy_menu_name]
menu_state_set $busy_menu_name -2 $busy_menu_path
foreach win "[winfo children .]" {
if {$win != "$busy_main_path"} {
catch {$win configure -cursor watch}
}
}
grab $busy_main_path
}
proc ClearBusy {} {
global busy_main_path busy_menu_path busy_menu_name busy_menu_state
menu_state_restore $busy_menu_path $busy_menu_name $busy_menu_state
foreach win "[winfo children .]" {
catch {$win configure -cursor top_left_arrow}
}
grab release $busy_main_path
}
##############################################################################
#Creates a popup menu
proc create_popup {w title} {
if {[winfo exists $w]} {destroy $w}
menu $w -tearoff 0 -disabledforeground blue
set bg [lindex [$w configure -bg] 4]
$w add command -state disabled -label "$title" \
-background [tk::Darken $bg 80] \
-font menu_title_font
return $w
}
##############################################################################
#two functions to set and get the "current frame" - useful for instances
#when you have two frames and you wish to differentiate between them by,
#say clicking in one
proc SetCurFrame {s frame} {
global $s.frame $s.frame_index
set $s.frame_index 0
set $s.frame $frame
}
proc GetCurFrame {s} {
global $s.frame $s.frame_index
set f [lindex [set $s.frame] [set $s.frame_index]]
incr $s.frame_index
if {[set $s.frame_index] >= [llength [set $s.frame]]} {
set $s.frame_index 0
}
return $f
}
##############################################################################
#deletes a file with error checking
proc DeleteFile { file } {
catch {file delete $file} e
if {$e != ""} {
tk_messageBox -icon error -type ok -title "Delete file" \
-message $e
}
}
##############################################################################
# Fixes the maximum size of a toplevel window to take into account screen
# borders, such as the Windows task bar or a CDE desktop.
proc fix_maxsize {w} {
global tk_utils_defs
set border_x [keylget tk_utils_defs X_BORDER_SIZE]
set border_y [keylget tk_utils_defs Y_BORDER_SIZE]
foreach {width height} [wm maxsize $w] {}
if {$width > [winfo screenwidth .]} {
set width [winfo screenwidth .]
}
if {$height > [winfo screenheight .]} {
set height [winfo screenheight .]
}
incr width -$border_x
incr height -$border_y
wm maxsize $w $width $height
}
##############################################################################
# Fixes the maximum size of a toplevel window that contains a gridded text
# window (so needs character coords) to take into account screen borders,
# such as the Windows task bar or a CDE desktop.
proc fix_maxsize_text {w font_width font_height extra_width extra_height} {
global tk_utils_defs
set border_x [keylget tk_utils_defs X_BORDER_SIZE]
set border_y [keylget tk_utils_defs Y_BORDER_SIZE]
set width [winfo screenwidth .]
set height [winfo screenheight .]
incr width -$border_x
incr height -$border_y
set width [expr ($width - $extra_width) / $font_width]
set height [expr ($height - $extra_height) / $font_height]
wm maxsize $w $width $height
}
#
# Force window size using wm geometry. This is needed in addition to
# fix_maxsize as on some window managers (AfterStep, MacOS X, etc) the
# wm maxsize command is ignored.
#
proc fit_on_screen2 {w} {
global tk_utils_defs
puts fit_on_screen2
#10.10.02 (added but commented out - see fit_on_screen comment below)
#wm geometry $w {}
set border_x [keylget tk_utils_defs X_BORDER_SIZE]
set border_y [keylget tk_utils_defs Y_BORDER_SIZE]
foreach {width height} [wm maxsize $w] {}
if {$width > [winfo screenwidth .]} {
set width [winfo screenwidth .]
}
if {$height > [winfo screenheight .]} {
set height [winfo screenheight .]
}
incr width -$border_x
incr height -$border_y
update idletasks
set wid [lindex [split [wm geometry $w] x+] 0]
set hei [lindex [split [wm geometry $w] x+] 1]
if {$wid > $width} {
set wid $width
}
if {$hei > $height} {
set hei $height
}
wm geometry $w ${wid}x$hei
}
proc fit_on_screen {w} {
# FIXME: MacOS X hack to deal with ignoring wm maxsize. This fixed
# delay may still cause problems on slow macs, but this code will
# be rewritten once the container class has been implemented.
#after 1000 "catch {fit_on_screen2 $w}"
#kfs/jkb 10.10.02
#fit_on_screen currently causes problems - especially the 1 second delay
#which makes bringing up lots of plots at the same time (eg codon pref)
#very slow. Also, if you bring up 2 comparison plots, separate them out
#and then superimpose them again, the new plot does not shrink in size as
#it should. Tried adding a wm geometry $w {} (see above) which solved this
#problem but it also lost manual resizing information.
#We think fit_on_screen's only purpose was to solve resizing issues on
#on the mac, specifically, using wm geometry to force resizing windows
#when they grow too large for the screen. Ideally wm maxsize will solve
#this, but apparently not on all window managers.
#Since we are about to upgrade the mac, we need to see if this is still
#necessary.
return
}
#
# Implements a "do <script> ??until|while? <expression>?" loop
#
# It is as fast as builtin "while" command for loops with
# more than just a few iterations.
#
# From http://mini.net/tcl/917.html
#
proc do {script {arg2 {}} {arg3 {}}} {
if {![string length $arg2$arg3]} {set arg2 0}
if {[string compare $arg3 {}]} {
switch -- $arg2 {
until {set bool "!"}
while {set bool ""}
default {return -code 1 "usage: do script ??until|while? expr?"}
}
}
set ret [catch { uplevel $script } result]
switch $ret {
0 -
4 {}
3 {return}
default {
return -code $ret $result
}
}
set ret [catch {uplevel [list while ${bool}($arg3) $script]} result]
return -code $ret $result
}
#
# Implements a tmpnam function. Prefix is optional, but if set then it
# is the start of the temporary filename (excluding the directory portion).
#
proc tmpnam {{prefix tmp}} {
global tcl_platform env
if { "$tcl_platform(platform)" != "windows" } {
set tdir "/tmp/"
} else {
if {[info exists env(TMP)]} {
set tdir $env(TMP)/
} elseif {[info exists env(TEMP)]} {
set tdir $env(TEMP)/
} else {
set tdir "C:/"
}
regsub -all {\\} $tdir / tdir
}
set pid [pid]
set count -1
do {
incr count
set fname "${tdir}${prefix}${pid}_$count"
} while {[file exists $fname]}
return $fname
}
#
# Equivalent calling syntax to lappend.
# You may want to look at http://wiki.tcl.tk/1482 for information.
# Note the $v[set v {}] code is trickery to cheat the reference counting,
# which prevents linsert from making a complete new copy of the list.
#
# With Tcl8.5 the foreach loop can be replaced by
# set v [linsert $v[set v {}] 0 {*}$args]
#
proc lprepend {var args} {
upvar 1 $var v
lappend v ;# Used as a an "is a list" check and to do var creation
set p 0
foreach a $args {
set v [linsert $v[set v {}] $p $a]
incr p
}
}
# Lreverse - native to tcl 8.5 and above
# See http://www2.tcl.tk/17188
if {[info command lreverse] == ""} {
proc lreverse l {
set r {}
set i [llength $l]
while {[incr i -1]} {lappend r [lindex $l $i]}
lappend r [lindex $l 0]
}
}
#############################################################################
# Fixing of auto-repeat "run on" giving a laggy appearance to applications.
namespace eval ::auto_repeat {
set release_time 0
set key_idle 1
# Key press. Consume any auto-repeat keys (detected as simultaneous
# KeyRelease and KeyPress events) when we're busy so we don't
# start accumulating a large queue.
proc AutoRepeatPress {k t} {
variable release_time
variable key_idle
if {$t == $release_time && !$key_idle} {
return -code break;
}
set key_idle 0
after idle {set ::auto_repeat::key_idle 1}
}
# Key release. If we've had an idle event loop process since
# the last press then we're safe to assume auto-repeat is not
# swamping the application
proc AutoRepeatRelease {k t} {
variable release_time
variable key_idle
if {$key_idle} {
set release_time 0
} else {
set release_time $t
}
}
bind AutoRepeat <Any-KeyPress> {::auto_repeat::AutoRepeatPress %K %t}
bind AutoRepeat <Any-KeyRelease> {::auto_repeat::AutoRepeatRelease %K %t}
}
# Applies a correction to window $w to remove excess auto-repeated key
# events if processing is failing to keep up.
proc AutoRepeatCorrect {w} {
bindtags $w [linsert [bindtags $w] 0 AutoRepeat]
}
|