KeyboardForwarder.st
author claus
Fri, 12 May 1995 20:01:16 +0200
changeset 142 8473a0af99ac
parent 140 0db355079dc4
child 144 cf645a1ebbb3
permissions -rw-r--r--
.

"
 COPYRIGHT (c) 1995 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"


'From Smalltalk/X, Version:2.10.5 on 30-mar-1995 at 5:32:55 am'!

Object subclass:#KeyboardForwarder
	 instanceVariableNames:'sourceView destinationView destination condition'
	 classVariableNames:''
	 poolDictionaries:''
	 category:'Interface-Support'
!

!KeyboardForwarder class methodsFor:'documentation'!

version
"
$Header: /cvs/stx/stx/libview/KeyboardForwarder.st,v 1.5 1995-05-12 18:00:26 claus Exp $
"
!

documentation
"
    Instances of this class can be used as delegates to forward keyboard
    events to some object or other view (via aView delegate:).
    Notice, that delegates dont have to be instances of
    myself; any object with a protocol similar to mine can be used as
    a delegate. 
    (i.e. any object that responds to 
     handlesKeyPress:view: / keyPress:x:y:view: / delegatesTo: etc.)

    However, I provide the most common functions required for conditional
    event delegation and instances of myself are for example used to forward 
    events from elements of some dialogBoxes to the enterfield/fieldGroup - 
    this allows keyboard input to be forwarded to the active text-field even 
    while the mouse pointer is somewhere else.

    Another application of delegation is to catch keyboard input to some standard
    widget, optionally processing and resending the key-event.

    Instance Variables:

	destinationView         <View>          the view which shall receive
						the forwarded keyboard events.

	destination             <Object>        the object which shall receive
						the forwarded keyboard events.

	sourceView              <ViewOrNil>     if non-nil, only events from this
						view are forwarded.
						(currently nowhere used)

	condition               <Symbol>        an additional condition for forwarding
						currently only #noFocus is implemented.
						The #noFocus condition will only forward
						events if no explicit focus has been
						set in the windowGroup.
"
!

copyright
"
 COPYRIGHT (c) 1995 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

! !

!KeyboardForwarder class methodsFor:'instance creation'!

from:sourceView toView:destinationView
    "create and return a new KeyboardForwarder to redirect key events
     for sourceView to destinationView. Events from other than the sourceView
     will not be forwarded. The forwarded event will be reported excluding
     the original view as argument (i.e. as #keyPress:x:y:). 
     Use this, if the destination is a view."

    ^ self new sourceView:sourceView; destinationView:destinationView
!

from:sourceView to:destination
    "create and return a new KeyboardForwarder to redirect key events
     for sourceView to destination. Events from other than the sourceView
     will not be forwarded. The forwarded event will be reported including
     the original view as argument (i.e. as #keyPress:x:y:view:). 
     Use this, if the destination is not a view."

    ^ self new sourceView:sourceView; destination:destination
!

toView:destinationView
    "create and return a new KeyboardForwarder to redirect any key event
     to destinationView (Independent of the view in which the event originally
     occurred). The forwarded event will be reported excluding
     the original view as argument (i.e. as #keyPress:x:y:). 
     Use this, if the destination is a view."

    ^ self new destinationView:destinationView
!

to:destination
    "create and return a new KeyboardForwarder to redirect any key event
     to destination (Independent of the view in which the event originally
     occurred). The forwarded event will be reported including
     the original view as argument (i.e. as #keyPress:x:y:view:). 
     Use this, if the destination is not a view."

    ^ self new destination:destination
!

toView:destinationView condition:aConditionSymbol
    "create and return a new KeyboardForwarder to redirect any key event
     to destinationView (Independent of the view in which the event originally
     occurred) but only, if some condition as specified by aConditionSymbol
     is met. The forwarded event will be reported excluding
     the original view as argument (i.e. as #keyPress:x:y:). 
     Use this, if the destination is a view."

    ^ self new destinationView:destinationView; condition:aConditionSymbol
!

to:destination condition:aConditionSymbol
    "create and return a new KeyboardForwarder to redirect any key event
     to destinationView (Independent of the view in which the event originally
     occurred) but only, if some condition as specified by aConditionSymbol
     is met. The forwarded event will be reported including
     the original view as argument (i.e. as #keyPress:x:y:view:). 
     Use this, if the destination is not a view."

    ^ self new destination:destination; condition:aConditionSymbol
! !

!KeyboardForwarder methodsFor:'private accessing'!

condition:aCondition
    condition := aCondition
!

destinationView:aView
    destinationView := aView
!

destinationView
    ^ destinationView
!

destination:anObject 
    destination := anObject
!

destination
    ^ destination
!

sourceView:aView
    sourceView := aView
!

sourceView
    ^ sourceView
! !

!KeyboardForwarder methodsFor:'queries'!

delegatesTo:someone
    "return true, if I delegate events to someone"

    ^ destination == someone or:[destinationView == someone]
!

handlesKeyPress:key inView:aView
    "this is the query from the sensor to ask me if I would like to
     get a keyPress event for key from aView. Return true, if I want so,
     false otherwise."

    condition notNil ifTrue:[
	condition == #noFocus ifTrue:[
	    aView windowGroup focusView notNil ifTrue:[^ false]
	]
    ].
    sourceView notNil ifTrue:[
	^ aView == sourceView
    ].
    ^ true
!

handlesKeyRelease:key inView:aView
    "this is the query from the sensor to ask me if I would like to
     get a keyRelease event for key from aView. Return true, if I want so,
     false otherwise."

    condition notNil ifTrue:[
	condition == #noFocus ifTrue:[
	    aView windowGroup focusView notNil ifTrue:[^ false]
	]
    ].
    sourceView notNil ifTrue:[
	^ aView == sourceView
    ].
    ^ true
! !

!KeyboardForwarder methodsFor:'event forwarding'!

keyPress:key x:x y:y view:aView
    "handle a delegated event - this is sent by the sensor to actually
     forward the event (i.e. after I returned true on handlesKeyPress:.
     Take care of cyclic delegation (via a kludge-test for negative coordinate)."

    x < 0 ifTrue:[
	"
	 already delegated ... ignore
	"
	^ self
    ].

    destination notNil ifTrue:[
	destination keyPress:key x:-1 y:-1 view:aView.
    ] ifFalse:[
	WindowEvent
	    sendEvent:#keyPress:x:y:
	    arguments:(Array with:key with:-1 with:-1)
	    view:destinationView
"/        destinationView keyPress:key x:-1 y:-1 
    ]
!

keyRelease:key x:x y:y view:aView
    "handle a delegated event - this is sent by the sensor to actually
     forward the event (i.e. after I returned true on handlesKeyRelease:.
     Take care of cyclic delegation (via a kludge-test for negative coordinate)."

    x < 0 ifTrue:[
	"
	 already delegated ... ignore
	"
	^ self
    ].

    destination notNil ifTrue:[
	WindowEvent
	    sendEvent:#keyRelease:x:y:
	    arguments:(Array with:key with:-1 with:-1)
	    view:destinationView
"/        destinationView keyRelease:key x:-1 y:-1 view:aView
    ] ifFalse:[
	destinationView keyRelease:key x:-1 y:-1 
    ]
! !