"
COPYRIGHT (c) 1993 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.
"
Object subclass:#WindowEvent
instanceVariableNames:'view type arguments'
classVariableNames:''
poolDictionaries:''
category:'Interface-Support'
!
WindowEvent comment:'
COPYRIGHT (c) 1993 by Claus Gittinger
All Rights Reserved
$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.11 1995-02-06 00:38:02 claus Exp $
'!
!WindowEvent class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1993 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.
"
!
version
"
$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.11 1995-02-06 00:38:02 claus Exp $
"
!
documentation
"
Instances of WindowEvent are created for every event coming from
the graphics device, to be handled by a windowGroup.
Usually, they are queued by a sensor, and processed in some event loop
in the window group.
"
! !
!WindowEvent class methodsFor:'instance creation'!
for:aView type:aSymbol arguments:argArray
"create and return a new windowEvent for sending
aSymbol-message with arguments to aView"
^ (self new) for:aView type:aSymbol arguments:argArray
!
for:aView type:aSymbol
"create and return a new windowEvent for sending
aSymbol-message with no arguments to aView"
^ (self new) for:aView type:aSymbol arguments:#()
!
damageFor:aView rectangle:aRectangle
"create and return a new damage Event for aRectangle
in aView"
^ (self new) for:aView type:#damage arguments:aRectangle
! !
!WindowEvent methodsFor:'queries'!
isKeyEvent
"return true, if this event is a keyboard event"
^ (type == #keyPress:x:y:) or:[type == #keyRelease:x:y:]
!
isKeyPressEvent
"return true, if this event is a keyboard event"
^ (type == #keyPress:x:y:)
!
isButtonEvent
"return true, if this event is a button event"
^ (type == #buttonPress:x:y:)
or:[type == #buttonRelease:x:y:
or:[type == #'buttonShiftPress:x:y:'
or:[type == #'buttonMultiPress:x:y:'
or:[type == #'buttonMotion:x:y:']]]]
!
isDamage
"return true, if this is a damage event"
^ type == #damage
! !
!WindowEvent methodsFor:'accessing'!
view
"return the view, for which the event is for"
^ view
!
view:aView
"set the view, for which the event is for"
view := aView
!
type
"return the type of the event"
^ type
!
arguments
"return the arguments of the event"
^ arguments
!
arguments:anArray
"set the arguments"
arguments := anArray
!
rectangle
"return the damage rectangle"
^ arguments "consider this a kludge"
!
key
"return the key of the key-event. For non key-events, nil is returned."
((type == #keyPress:x:y:)
or:[type == #keyRelease:x:y:]) ifTrue:[
^ arguments at:1
].
^ nil
! !
!WindowEvent methodsFor:'sending'!
sendEvent
"forward the event represented by the receiver to the delegate,
the controller or the view. Only messages which are understood by
the delegate are forwarded.
Delegated messages get the original view as an extra argument."
self sendEventWithFocusOn:nil
!
sendEventWithFocusOn:focusView
"forward the event represented by the receiver to the delegate,
the controller or the view. If focusView is nonNil, and its a keyboard
event, the event is forwarded to it (but not if there is a delegate).
If there is a delegate, only messages which are understood by it are
forwarded. Delegated messages get the original view as an extra argument.
Delegation has higher priority than both controller or focusView
forwarding."
|delegate selector eventReceiver controller|
selector := type.
delegate := view delegate.
delegate notNil ifTrue:[
"
what a kludge - sending to delegate needs another
selector and an additional argument.
have to edit the selector ...
"
(selector endsWith:':') ifTrue:[
selector := (selector , 'view:') asSymbol.
] ifFalse:[
selector := (selector , 'View:') asSymbol.
].
(delegate respondsTo:selector) ifTrue:[
"
mhmh have to convert to logical coordinates ...
"
view transformation notNil ifTrue:[
(#(
#'buttonPress:x:y:'
#'buttonRelease:x:y:'
#'buttonShiftPress:x:y:'
#'buttonMultiPress:x:y:'
#'buttonMotion:x:y:'
#'keyPress:x:y:'
#'keyRelease:x:y:'
#'pointerEnter:x:y:'
#'exposeX:y:width:height:'
#'graphicExposeX:y:width:height:'
)includes:type) ifTrue:[
arguments at:2 put:(view transformation applyInverseToX:(arguments at:2)).
arguments at:3 put:(view transformation applyInverseToY:(arguments at:3)).
(#(
#'exposeX:y:width:height:'
#'graphicExposeX:y:width:height:'
)includes:type) ifTrue:[
arguments at:4 put:(view transformation applyInverseScaleX:(arguments at:4)).
arguments at:5 put:(view transformation applyInverseScaleY:(arguments at:5)).
].
].
].
arguments isNil ifTrue:[
delegate perform:selector with:view
] ifFalse:[
delegate perform:selector withArguments:(arguments copyWith:view)
].
^ self
].
selector := type.
].
"
if there is a controller, that one gets all user events
"
eventReceiver := view.
(controller := view controller) notNil ifTrue:[
(#(
#'buttonPress:x:y:'
#'buttonRelease:x:y:'
#'buttonShiftPress:x:y:'
#'buttonMultiPress:x:y:'
#'buttonMotion:x:y:'
#'keyPress:x:y:'
#'keyRelease:x:y:'
#'focusIn'
#'focusOut'
#'pointerEnter:x:y:'
#'pointerLeave:'
) includes:selector) ifTrue:[
eventReceiver := controller.
]
].
"
if there is a focusView, and its a keyboard event, pass it
to that view (or its controller). In this case, some coordinate which is outside of
the focusView is passed as x/y coordinates.
"
focusView notNil ifTrue:[
(#(#'keyPress:x:y:'
#'keyRelease:x:y:'
)includes:selector) ifTrue:[
eventReceiver := focusView.
(controller := focusView controller) notNil ifTrue:[
eventReceiver := controller.
].
eventReceiver perform:selector
withArguments:(Array with:(arguments at:1)
with:-1
with:-1).
^ self
]
].
"
another one:
if the view has a transformation, edit the selector
from #foo to #deviceFoo...
This allows the view to handle the event either in device or
logical coordinates. (since the deviceFoo-messages default implementation
in PseudoView translates and resends).
Actually, I could always send deviceXXX without speed penalty
(event sending is no high frequency operation), but that just adds
another context to any debuggers walkback, making things less clear.
"
view transformation notNil ifTrue:[
(#(
#'buttonPress:x:y:'
#'buttonRelease:x:y:'
#'buttonShiftPress:x:y:'
#'buttonMultiPress:x:y:'
#'buttonMotion:x:y:'
#'keyPress:x:y:'
#'keyRelease:x:y:'
#'exposeX:y:width:height:'
#'graphicExposeX:y:width:height:'
#'pointerEnter:x:y:'
) includes:selector) ifTrue:[
selector := selector asString.
selector at:1 put:(selector at:1) asUppercase.
selector := ('device' , selector) asSymbol
]
].
eventReceiver perform:selector withArguments:arguments
! !
!WindowEvent methodsFor:'private accessing'!
for:aView type:aSymbol arguments:argArray
"set the instances of the window event"
view := aView.
type := aSymbol.
arguments := argArray
! !