# HG changeset patch # User Claus Gittinger # Date 1576661550 -3600 # Node ID 54027288924cb8b4d6e9f8f0f68c167a80b61274 # Parent bb3677b7a7bb6a71fbcd54610d8111c944ceee75 #REFACTORING by cg class: DisplaySurface added:16 methods FIX: these methods are needed here (to be understood by rootview) diff -r bb3677b7a7bb -r 54027288924c DisplaySurface.st --- a/DisplaySurface.st Wed Dec 18 10:32:14 2019 +0100 +++ b/DisplaySurface.st Wed Dec 18 10:32:30 2019 +0100 @@ -2396,6 +2396,304 @@ "Modified: / 9.1.1999 / 01:58:09 / cg" ! ! +!DisplaySurface methodsFor:'event simulation'! + +simulateButtonMotion:buttonMask to:aPoint sendDisplayEvent:sendDisplayEvent + "simulate a button motion by determining which sub-view is affected and + synthetically generating a buttonPressEvent for whatever view is underneath. + Returns the view which precessed the event or nil." + + |ev| + + ev := WindowEvent buttonMotion:buttonMask x:0 y:0 view:self. + "/ x/y will be set in simulateUserEvent:at:sendDisplayEvent: + ^ self simulateUserEvent:ev at:aPoint sendDisplayEvent:sendDisplayEvent +! + +simulateButtonPress:button at:aPoint + "simulate a button press by determining which sub-view is affected and + synthetically generating a buttonPressEvent for whatever view is underneath. + Returns the view which precessed the event or nil." + + ^ self simulateButtonPress:button at:aPoint sendDisplayEvent:false + + "Created: / 12-07-2011 / 14:36:02 / cg" +! + +simulateButtonPress:button at:aPoint sendDisplayEvent:sendDisplayEvent + "simulate a button press by determining which sub-view is affected and + synthetically generating a buttonPressEvent for whatever view is underneath. + Returns the view which precessed the event or nil." + + |ev| + + ev := WindowEvent buttonPress:button x:0 y:0 view:self. + "/ x/y will be set in simulateUserEvent:at:sendDisplayEvent: + ^ self simulateUserEvent:ev at:aPoint sendDisplayEvent:sendDisplayEvent + + "Created: / 12-07-2011 / 14:36:02 / cg" + "Modified (comment): / 19-07-2019 / 13:57:45 / Claus Gittinger" +! + +simulateButtonRelease:button at:aPoint + "simulate a button release by determining which sub-view is affected and + synthetically generating a buttonPressEvent for whatever view is underneath. + Returns the view which precessed the event or nil." + + ^ self simulateButtonRelease:button at:aPoint sendDisplayEvent:false + + "Created: / 12-07-2011 / 14:54:37 / cg" +! + +simulateButtonRelease:button at:aPoint sendDisplayEvent:sendDisplayEvent + "simulate a button release by determining which sub-view is affected and + synthetically generating a buttonPressEvent for whatever view is underneath. + Returns the view which precessed the event or nil." + + |ev| + + ev := WindowEvent buttonRelease:button x:0 y:0 view:self. + "/ x/y will be set in simulateUserEvent:at:sendDisplayEvent: + ^ self simulateUserEvent:ev at:aPoint sendDisplayEvent:sendDisplayEvent + + "Created: / 12-07-2011 / 14:54:37 / cg" + "Modified (comment): / 19-07-2019 / 13:57:58 / Claus Gittinger" +! + +simulateKey:aKeySymbolOrCharacter at:aPoint sendDisplayEvent:sendDisplayEvent keyPressTime:seconds + "simulate text input by generating alternating keyPress/keyRelease events." + + (aKeySymbolOrCharacter isCharacter + and:[ aKeySymbolOrCharacter isLetter + and:[ aKeySymbolOrCharacter isUppercase + ]]) ifTrue:[ + self simulateKeyPress:#Shift at:aPoint sendDisplayEvent:sendDisplayEvent. + self simulateKeyPress:aKeySymbolOrCharacter asLowercase at:aPoint sendDisplayEvent:sendDisplayEvent. + Delay waitForSeconds:seconds. + self simulateKeyRelease:aKeySymbolOrCharacter asLowercase at:aPoint sendDisplayEvent:sendDisplayEvent. + self simulateKeyRelease:#Shift at:aPoint sendDisplayEvent:sendDisplayEvent. + ] ifFalse:[ + self simulateKeyPress:aKeySymbolOrCharacter at:aPoint sendDisplayEvent:sendDisplayEvent. + Delay waitForSeconds:seconds. + self simulateKeyRelease:aKeySymbolOrCharacter at:aPoint sendDisplayEvent:sendDisplayEvent. + ]. + + "Created: / 19-07-2019 / 14:40:52 / Claus Gittinger" +! + +simulateKeyPress:keyOrStringOrSymbol at:aPoint + "simulate a key press by determining which sub-view is affected and + synthetically generating a keyPressEvent for whatever view is underneath. + Returns the view which processed the event or nil." + + ^ self simulateKeyPress:keyOrStringOrSymbol at:aPoint sendDisplayEvent:false +! + +simulateKeyPress:keyOrStringOrSymbol at:aPoint sendDisplayEvent:sendDisplayEvent + "simulate a key press by determining which sub-view is affected and + synthetically generating a keyPressEvent for whatever view is underneath. + Returns the view which processed the event or nil." + + |sequence ev lastView| + + (keyOrStringOrSymbol isCharacter or:[keyOrStringOrSymbol isSymbol]) + ifTrue:[ sequence := Array with:keyOrStringOrSymbol ] + ifFalse:[ sequence := keyOrStringOrSymbol ]. + + sequence do:[:each | + ev := WindowEvent keyPress:each x:0 y:0 view:self. + "/ x/y will be set in simulateUserEvent:at:sendDisplayEvent: + lastView := self simulateUserEvent:ev at:aPoint sendDisplayEvent:sendDisplayEvent + ]. + ^ lastView + + "Modified (comment): / 19-07-2019 / 13:58:06 / Claus Gittinger" +! + +simulateKeyPressRelease:keyOrStringOrSymbol at:aPoint + "simulate a key release by determining which sub-view is affected and + synthetically generating a keyPressEvent for whatever view is underneath. + Returns the view which processed the event or nil." + + ^ self simulateKeyPressRelease:keyOrStringOrSymbol at:aPoint sendDisplayEvent:false +! + +simulateKeyPressRelease:keyOrStringOrSymbol at:aPoint sendDisplayEvent:sendDisplayEvent + "simulate a key release by determining which sub-view is affected and + synthetically generating a keyPressEvent for whatever view is underneath. + Returns the view which processed the event or nil." + + |sequence ev1 ev2 lastView| + + (keyOrStringOrSymbol isCharacter or:[keyOrStringOrSymbol isSymbol]) + ifTrue:[ sequence := Array with:keyOrStringOrSymbol ] + ifFalse:[ sequence := keyOrStringOrSymbol ]. + + sequence do:[:each | + ev1 := WindowEvent keyPress:each x:0 y:0 view:self. + "/ x/y will be set in simulateUserEvent:at:sendDisplayEvent: + lastView := self simulateUserEvent:ev1 at:aPoint sendDisplayEvent:sendDisplayEvent. + + ev2 := WindowEvent keyRelease:each x:0 y:0 view:self. + "/ x/y will be set in simulateUserEvent:at:sendDisplayEvent: + lastView := self simulateUserEvent:ev2 at:aPoint sendDisplayEvent:sendDisplayEvent. + ]. + ^ lastView + + "Modified (comment): / 19-07-2019 / 13:58:14 / Claus Gittinger" +! + +simulateKeyRelease:keyOrStringOrSymbol at:aPoint + "simulate a key release by determining which sub-view is affected and + synthetically generating a keyPressEvent for whatever view is underneath. + Returns the view which processed the event or nil." + + ^ self simulateKeyRelease:keyOrStringOrSymbol at:aPoint sendDisplayEvent:false +! + +simulateKeyRelease:keyOrStringOrSymbol at:aPoint sendDisplayEvent:sendDisplayEvent + "simulate a key release by determining which sub-view is affected and + synthetically generating a keyPressEvent for whatever view is underneath. + Returns the view which processed the event or nil." + + |sequence ev lastView| + + (keyOrStringOrSymbol isCharacter or:[keyOrStringOrSymbol isSymbol]) + ifTrue:[ sequence := Array with:keyOrStringOrSymbol ] + ifFalse:[ sequence := keyOrStringOrSymbol ]. + + sequence do:[:each | + ev := WindowEvent keyRelease:each x:0 y:0 view:self. + "/ x/y will be set in simulateUserEvent:at:sendDisplayEvent: + lastView := self simulateUserEvent:ev at:aPoint sendDisplayEvent:sendDisplayEvent + ]. + ^ lastView + + "Modified (comment): / 19-07-2019 / 13:58:18 / Claus Gittinger" +! + +simulateTextInput:aString at:aPoint sendDisplayEvent:sendDisplayEvent + "simulate text input by generating alternating keyPress/keyRelease events." + + self simulateTextInput:aString at:aPoint sendDisplayEvent:sendDisplayEvent keyPressTime:0.05 +! + +simulateTextInput:aString at:aPoint sendDisplayEvent:sendDisplayEvent keyPressTime:seconds + "simulate text input by generating alternating keyPress/keyRelease events." + + aString do:[:eachCharacter | + self simulateKey:eachCharacter at:aPoint sendDisplayEvent:sendDisplayEvent keyPressTime:seconds + ]. + + "Created: / 19-07-2019 / 14:40:52 / Claus Gittinger" +! + +simulateUserEvent:ev at:aPoint + "simulate a button press by determining which sub-view is affected and + synthetically generating a buttonPressEvent for whatever view is underneath. + Cares for any active grab - i.e. if some other view has grabbed the pointer or keyboard + the event is sent to the grabView with pointer coordinate translated as required + (typically these are popup views like menus) + Returns the view which precessed the event or nil." + + ^ self simulateUserEvent:ev at:aPoint sendDisplayEvent:false +! + +simulateUserEvent:ev at:aPoint sendDisplayEvent:sendDisplayEvent + "simulate a button event by determining which sub-view is affected and + synthetically generating an event for whatever view is underneath. + + If sendDisplayEvent is true, a real physical event is generated via sendEvent, from the Display (xserver). + Otherwise, the event is pushed into the widget's event queue, without a roundtrip through the display. + + Otherwise, care for any active grab - i.e. if some other view has grabbed the pointer or keyboard + the event is sent to the grabView with pointer coordinate translated as required + (typically these are popup views like menus) + + Returns the view which processed the event or nil. + For displayEvent sending, always return the receiver, as we do not know how the grab processing came out at the end" + + |targetView pointXLated sensor evArg| + + sendDisplayEvent ifTrue:[ + "/ translate to screen coordinates + pointXLated := device translatePoint:aPoint from:(self id) to:(device rootWindowId). + "/ and send it via the display + ev isButtonPressEvent ifTrue:[ + evArg := #buttonPress + ] ifFalse:[ ev isButtonReleaseEvent ifTrue:[ + evArg := #buttonRelease + ] ifFalse:[ ev isKeyPressEvent ifTrue:[ + evArg := #keyPress + ] ifFalse:[ ev isKeyReleaseEvent ifTrue:[ + evArg := #keyRelease + ] ifFalse:[ + evArg := ev type + ]]]]. + device + sendKeyOrButtonEvent:evArg + x:pointXLated x y:pointXLated y + keyOrButton:(ev isKeyEvent ifTrue:[ev rawKey] ifFalse:[ev button]) + state:(ev modifierFlags) + toViewId:self id. + ^ self. + ]. + + (ev isButtonEvent or:[ev isPointerEnterLeaveEvent]) ifTrue:[ + "/ if there is a pointer grab, the event has to be sent to that one + targetView := device activePointerGrab. + "/ Transcript showCR:'direct to %1' with:targetView. + ] ifFalse:[ + (ev isKeyEvent) ifTrue:[ + "/ if there is a keyboard grab, the event has to be sent to that one + targetView := device activeKeyboardGrab. + "/ Transcript showCR:'direct to %1' with:targetView. + ]. + ]. + + targetView isNil ifTrue:[ + ((0@0 extent:self extent) containsPoint:aPoint) ifTrue:[ + self subViews do:[:each | + |whichView| + + whichView := each simulateUserEvent:ev + at:(device translatePoint:aPoint fromView:self toView:each) + sendDisplayEvent:false. + whichView notNil ifTrue:[^ whichView]. + ]. + targetView := self. + ]. + ]. + + targetView notNil ifTrue:[ + sensor := targetView sensor. + targetView == self ifTrue:[ + pointXLated := aPoint + ] ifFalse:[ + pointXLated := device translatePoint:aPoint fromView:self toView:targetView. + ]. + ev x:(pointXLated x). + ev y:(pointXLated y). + ev view:targetView. + + ev isButtonPressEvent ifTrue:[ + sensor buttonPress:ev button x:ev x y:ev y view:targetView. + ] ifFalse:[ + ev isButtonReleaseEvent ifTrue:[ + sensor buttonRelease:ev button x:(ev x) y:(ev y) view:targetView. + ] ifFalse:[ + sensor pushEvent:ev. + ] + ]. + ^ targetView + ]. + + ^ nil + + "Created: / 12-07-2011 / 14:53:19 / cg" + "Modified (format): / 19-07-2019 / 14:08:26 / Claus Gittinger" +! ! + !DisplaySurface methodsFor:'initialization & release'! destroy