123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- # -*- mode: TCL; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
- #
- # $Id: Event.tcl,v 1.6 2004/04/09 21:37:01 hobbs Exp $
- #
- # Event.tcl --
- #
- # Handles the event bindings of the -command and -browsecmd options
- # (and various of others such as -validatecmd).
- #
- # Copyright (c) 1993-1999 Ioi Kim Lam.
- # Copyright (c) 2000-2001 Tix Project Group.
- # Copyright (c) 2004 ActiveState
- #
- # See the file "license.terms" for information on usage and redistribution
- # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- #
- #----------------------------------------------------------------------
- # Evaluate high-level bindings (-command, -browsecmd, etc):
- # with % subsitution or without (compatibility mode)
- #
- #
- # BUG : if a -command is intercepted by a hook, the hook must use
- # the same record name as the issuer of the -command. For the time
- # being, you must use the name "bind" as the record name!!!!!
- #
- #----------------------------------------------------------------------
- namespace eval ::tix {
- variable event_flags ""
- set evs [list % \# a b c d f h k m o p s t w x y A B E K N R S T W X Y]
- foreach ev $evs {
- lappend event_flags "%$ev"
- }
- # This is a "name stack" for storing the "bind" structures
- #
- # The bottom of the event stack is usually a raw event (generated by
- # tixBind) but it may also be a programatically triggered (caused by
- # tixEvalCmdBinding)
- variable EVENT
- set EVENT(nameStack) ""
- set EVENT(stackLevel) 0
- }
- proc tixBind {tag event action} {
- set cmd [linsert $::tix::event_flags 0 _tixRecordFlags $event]
- append cmd "; $action; _tixDeleteFlags;"
- bind $tag $event $cmd
- }
- proc tixPushEventStack {} {
- variable ::tix::EVENT
- set lastEvent [lindex $EVENT(nameStack) 0]
- incr EVENT(stackLevel)
- set thisEvent ::tix::_event$EVENT(stackLevel)
- set EVENT(nameStack) [list $thisEvent $EVENT(nameStack)]
- if {$lastEvent == ""} {
- upvar #0 $thisEvent this
- set this(type) <Application>
- } else {
- upvar #0 $lastEvent last
- upvar #0 $thisEvent this
- foreach name [array names last] {
- set this($name) $last($name)
- }
- }
- return $thisEvent
- }
- proc tixPopEventStack {varName} {
- variable ::tix::EVENT
- if {$varName ne [lindex $EVENT(nameStack) 0]} {
- error "unmatched tixPushEventStack and tixPopEventStack calls"
- }
- incr EVENT(stackLevel) -1
- set EVENT(nameStack) [lindex $EVENT(nameStack) 1]
- global $varName
- unset $varName
- }
- # Events triggered by tixBind
- #
- proc _tixRecordFlags [concat event $::tix::event_flags] {
- set thisName [tixPushEventStack]; upvar #0 $thisName this
- set this(type) $event
- foreach f $::tix::event_flags {
- set this($f) [set $f]
- }
- }
- proc _tixDeleteFlags {} {
- variable ::tix::EVENT
- tixPopEventStack [lindex $EVENT(nameStack) 0]
- }
- # programatically trigged events
- #
- proc tixEvalCmdBinding {w cmd {subst ""} args} {
- global tixPriv tix
- variable ::tix::EVENT
- set thisName [tixPushEventStack]; upvar #0 $thisName this
- if {$subst != ""} {
- upvar $subst bind
- if {[info exists bind(specs)]} {
- foreach spec $bind(specs) {
- set this($spec) $bind($spec)
- }
- }
- if {[info exists bind(type)]} {
- set this(type) $bind(type)
- }
- }
- if {[catch {
- if {![info exists tix(-extracmdargs)]
- || [string is true -strict $tix(-extracmdargs)]} {
- # Compatibility mode
- set ret [uplevel \#0 $cmd $args]
- } else {
- set ret [uplevel 1 $cmd]
- }
- } error]} {
- if {[catch {tixCmdErrorHandler $error} error]} {
- # double fault: just print out
- tixBuiltInCmdErrorHandler $error
- }
- tixPopEventStack $thisName
- return ""
- } else {
- tixPopEventStack $thisName
- return $ret
- }
- }
- proc tixEvent {option args} {
- global tixPriv
- variable ::tix::EVENT
- set varName [lindex $EVENT(nameStack) 0]
- if {$varName == ""} {
- error "tixEvent called when no event is being processed"
- } else {
- upvar #0 $varName event
- }
- switch -exact -- $option {
- type {
- return $event(type)
- }
- value {
- if {[info exists event(%V)]} {
- return $event(%V)
- } else {
- return ""
- }
- }
- flag {
- set f %[lindex $args 0]
- if {[info exists event($f)]} {
- return $event($f)
- }
- error "The flag \"[lindex $args 0]\" does not exist"
- }
- match {
- return [string match [lindex $args 0] $event(type)]
- }
- default {
- error "unknown option \"$option\""
- }
- }
- }
- # tixBuiltInCmdErrorHandler --
- #
- # Default method to report command handler errors. This procedure is
- # also called if double-fault happens (command handler causes error,
- # then tixCmdErrorHandler causes error).
- #
- proc tixBuiltInCmdErrorHandler {errorMsg} {
- global errorInfo tcl_platform
- if {![info exists errorInfo]} {
- set errorInfo "???"
- }
- if {$tcl_platform(platform) eq "windows"} {
- bgerror "Tix Error: $errorMsg"
- } else {
- puts "Error:\n $errorMsg\n$errorInfo"
- }
- }
- # tixCmdErrorHandler --
- #
- # You can redefine this command to handle the errors that occur
- # in the command handlers. See the programmer's documentation
- # for details
- #
- if {![llength [info commands tixCmdErrorHandler]]} {
- proc tixCmdErrorHandler {errorMsg} {
- tixBuiltInCmdErrorHandler $errorMsg
- }
- }
|