WindowEvent.st
changeset 89 ea2bf46eb669
parent 84 e2d388e4e03f
child 115 1d93fd8c5371
--- a/WindowEvent.st	Mon Feb 06 01:30:10 1995 +0100
+++ b/WindowEvent.st	Mon Feb 06 01:38:04 1995 +0100
@@ -21,7 +21,7 @@
 COPYRIGHT (c) 1993 by Claus Gittinger
 	      All Rights Reserved
 
-$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.10 1994-11-22 14:32:22 claus Exp $
+$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.11 1995-02-06 00:38:02 claus Exp $
 '!
 
 !WindowEvent class methodsFor:'documentation'!
@@ -42,7 +42,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.10 1994-11-22 14:32:22 claus Exp $
+$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.11 1995-02-06 00:38:02 claus Exp $
 "
 !
 
@@ -84,7 +84,23 @@
 isKeyEvent
     "return true, if this event is a keyboard event"
 
-    ^ (type == #keyPress:x:y) or:[type == #keyRelease:x:y]
+    ^ (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
@@ -129,18 +145,42 @@
     "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.
+     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:[
 	"
@@ -153,61 +193,117 @@
 	] ifFalse:[
 	    selector := (selector , 'View:') asSymbol.
 	].
-	arguments isNil ifTrue:[
-	    delegate perform:selector with:view
-	] ifFalse:[
-	    delegate perform:selector withArguments:(arguments copyWith:view)
+	(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.
 	]
-    ] ifFalse:[
-	"
-	 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.
-	"
-	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:'
-	      #'exposeX:y:width:height:'
-	      #'graphicExposeX:y:width:height:'
-	      #'pointerEnter:x:y:'
-	    ) includes:selector) ifTrue:[
+    ].
+
+    "
+     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
+	]
+    ].
 
-	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
-    ]
+    "
+     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'!