# HG changeset patch # User Claus Gittinger # Date 1571565665 -7200 # Node ID 0b36f57fd1c995db8c249083cfb35c210b9584a2 # Parent 49da17b54a22d6447282f5f872a295c3d6f1fb76 #FEATURE by exept class: ShowMeHowItWorks class definition added: #doShowFile: #press:inComponent: #release:inComponent: #setLanguage: #withViewAndPositionFor:do: comment/format in: #intro changed: #click:inComponent: #click:inComponent:clickTime: #language: #prepare (send #setLanguage: instead of #language:) #press: #release: category of: #press: #release: class: ShowMeHowItWorks class added: #application:doShowFile: #scriptFormat diff -r 49da17b54a22 -r 0b36f57fd1c9 ShowMeHowItWorks.st --- a/ShowMeHowItWorks.st Sun Oct 20 08:33:57 2019 +0200 +++ b/ShowMeHowItWorks.st Sun Oct 20 12:01:05 2019 +0200 @@ -7,7 +7,8 @@ Object subclass:#ShowMeHowItWorks instanceVariableNames:'application opStream streamStack lastComponentName lastComponent lastResult voice translate language verifying - closeApplicationWhenFinished defaultComponentWaitTime ui' + closeApplicationWhenFinished defaultComponentWaitTime ui + theShowFile' classVariableNames:'IntroShownCount DebugMode StartLabel' poolDictionaries:'' category:'Interface-Help' @@ -51,6 +52,52 @@ )) ) +! + +scriptFormat +" + + speaking: + show: 'text' + + mouse movement: + moveTo: '' move there and circle around + fastMoveTo: '' move without circling + (drag: '' toComponent: '' dropAt: show:'text') + pos is one of #topLeft, #topCenter, #topRght, #bottomLeft, #bottomCenter, #bottomRight + text is spoken before the drop + + mouse actions: + click + click: buttonNumber + select: itemsIndexOrLabelOrPattern + itemsIndexOrLabelOrPattern can be an integer or text + + misc: + wait: seconds just pause + + label: 'name' for debugging, presentation can be started at some + label, by setting the StartLabel class variable + + (waitFor: '' timeout:seconds) + wait for a component to appear + + open 'nameOfAppModelClass' + open an application (class) + intro + +component naming: + '' can be: + name of a component, as defined in the UI-spec's nameKey, + helpKey + title + label + + a path like 'ProjectTree/ToolBar' will first find ProjectTrue, then ToolBar + a menu item index like 'Toolbar/item[idx]' + + +" ! ! !ShowMeHowItWorks class methodsFor:'running'! @@ -76,6 +123,27 @@ "Modified (comment): / 23-07-2019 / 10:26:42 / Claus Gittinger" ! +application:anApplicationOrNilForAll doShowFile:aFilename + "spec contains a list of action commands (show: / moveTo: etc.)" + + self new + application:anApplicationOrNilForAll; + doShowFile:aFilename + + " + ShowMeHowItWorks do: + #( + (language: de) + (show: 'üben üben üben') + (wait: 0.5) + (moveTo: NameOfComponent) + ) + " + + "Created: / 19-07-2019 / 10:52:59 / Claus Gittinger" + "Modified (comment): / 23-07-2019 / 10:26:42 / Claus Gittinger" +! + do:specArray "spec contains a list of action commands (show: / moveTo: etc.)" @@ -144,6 +212,13 @@ "if set, only that application is presented (widget search is limtied to that one)" application := anApplication. +! + +setLanguage:lang + voice := OperatingSystem bestVoiceForLanguage:lang. + language := lang. + + "Created: / 23-07-2019 / 10:27:02 / Claus Gittinger" ! ! !ShowMeHowItWorks methodsFor:'commands'! @@ -159,7 +234,9 @@ IntroShownCount > 3 ifTrue:[^ self]. IntroShownCount := IntroShownCount + 1. - self language:(Smalltalk language). + language isNil ifTrue:[ + self setLanguage:(Smalltalk language). + ]. self tell:(self class classResources string:'You can stop this show, by pressing the SHIFT key'). @@ -176,9 +253,8 @@ language:lang - voice := OperatingSystem bestVoiceForLanguage:lang. + self setLanguage:lang. translate := false. - language := lang. "Created: / 23-07-2019 / 10:27:02 / Claus Gittinger" ! @@ -621,6 +697,81 @@ "Modified: / 19-07-2019 / 15:38:11 / Claus Gittinger" ! +press:buttonNr + + + "press at the current position" + + self assert:(buttonNr isInteger). + ^ self press:buttonNr inComponent:lastComponent. + +"/ "press at the current position" +"/ +"/ |position screen x y| +"/ +"/ verifying ifTrue:[^ self]. +"/ +"/ screen := Screen current. +"/ position := screen pointerPosition. +"/ x := position x. +"/ y := position y. +"/ +"/ "/ self movePointerToScreenPosition:position. +"/ +"/ false "OperatingSystem isOSXlike" ifTrue:[ +"/ |osxPos| +"/ +"/ osxPos := OperatingSystem getMousePosition. +"/ x := osxPos x rounded. +"/ y := osxPos y rounded. +"/ OperatingSystem generateButtonEvent:buttonNr down:true x:x y:y. +"/ ^ self. +"/ ]. +"/ +"/ screen sendKeyOrButtonEvent:#buttonPress x:x y:y keyOrButton:buttonNr state:0 toViewId:(screen rootWindowId). +"/ screen flush. +"/ +"/ "Created: / 19-07-2019 / 13:52:38 / Claus Gittinger" +"/ "Modified: / 23-07-2019 / 09:38:31 / Claus Gittinger" +! + +release:buttonNr + + + "release at the current position" + + + + self assert:(buttonNr isInteger). + ^ self press:buttonNr inComponent:lastComponent. +"/ |position screen x y| +"/ +"/ verifying ifTrue:[^ self]. +"/ +"/ screen := Screen current. +"/ position := screen pointerPosition. +"/ x := position x. +"/ y := position y. +"/ +"/ self movePointerToScreenPosition:position. +"/ +"/ false "OperatingSystem isOSXlike" ifTrue:[ +"/ |osxPos| +"/ +"/ osxPos := OperatingSystem getMousePosition. +"/ x := osxPos x rounded. +"/ y := osxPos y rounded. +"/ OperatingSystem generateButtonEvent:buttonNr down:false x:x y:y. +"/ ^ self. +"/ ]. +"/ +"/ screen sendKeyOrButtonEvent:#buttonRelease x:x y:y keyOrButton:buttonNr state:0 toViewId:(screen rootWindowId). +"/ screen flush. + + "Created: / 19-07-2019 / 13:53:05 / Claus Gittinger" + "Modified: / 23-07-2019 / 09:38:38 / Claus Gittinger" +! + select:itemsIndexOrLabelOrPattern "select an item by label, allowed after moving to: @@ -1247,7 +1398,9 @@ |t| t := self shortClickTime. - (component isKindOf:Button) ifTrue:[ + ((component isKindOf:Button) + or:[(component askFor:#isMenuItem)] + )ifTrue:[ t := self longClickTime ]. self click:buttonNr inComponent:component clickTime:t @@ -1259,6 +1412,32 @@ click:buttonNr inComponent:viewOrMenuItem clickTime:clickTime "press-release in a component" + self withViewAndPositionFor:viewOrMenuItem do:[:viewToClick :clickPos | + viewToClick simulateButtonPress:buttonNr at:clickPos sendDisplayEvent:false. + Delay waitForSeconds:clickTime. + viewToClick simulateButtonRelease:buttonNr at:clickPos sendDisplayEvent:false. + ]. +! + +press:buttonNr inComponent:viewOrMenuItem + "press in a component" + + self withViewAndPositionFor:viewOrMenuItem do:[:viewToClick :clickPos | + viewToClick simulateButtonPress:buttonNr at:clickPos sendDisplayEvent:false. + ] +! + +release:buttonNr inComponent:viewOrMenuItem + "release in a component" + + self withViewAndPositionFor:viewOrMenuItem do:[:viewToClick :clickPos | + viewToClick simulateButtonRelease:buttonNr at:clickPos sendDisplayEvent:false. + ] +! + +withViewAndPositionFor:viewOrMenuItem do:aBlock + "helper for click, press and release" + |viewToClick clickPos| self assert:viewOrMenuItem notNil. @@ -1272,76 +1451,7 @@ viewToClick := viewOrMenuItem. clickPos := viewToClick extent // 2. ]. - - viewToClick simulateButtonPress:buttonNr at:clickPos sendDisplayEvent:false. - Delay waitForSeconds:clickTime. - viewToClick simulateButtonRelease:buttonNr at:clickPos sendDisplayEvent:false. - -"/ self click:buttonNr atPosition:(component extent // 2) - - "Created: / 19-07-2019 / 15:21:05 / Claus Gittinger" -! - -press:buttonNr - "press at the current position" - - |position screen x y| - - verifying ifTrue:[^ self]. - - screen := Screen current. - position := screen pointerPosition. - x := position x. - y := position y. - - "/ self movePointerToScreenPosition:position. - - false "OperatingSystem isOSXlike" ifTrue:[ - |osxPos| - - osxPos := OperatingSystem getMousePosition. - x := osxPos x rounded. - y := osxPos y rounded. - OperatingSystem generateButtonEvent:buttonNr down:true x:x y:y. - ^ self. - ]. - - screen sendKeyOrButtonEvent:#buttonPress x:x y:y keyOrButton:buttonNr state:0 toViewId:(screen rootWindowId). - screen flush. - - "Created: / 19-07-2019 / 13:52:38 / Claus Gittinger" - "Modified: / 23-07-2019 / 09:38:31 / Claus Gittinger" -! - -release:buttonNr - "press-release at the current position" - - |position screen x y| - - verifying ifTrue:[^ self]. - - screen := Screen current. - position := screen pointerPosition. - x := position x. - y := position y. - - "/ self movePointerToScreenPosition:position. - - false "OperatingSystem isOSXlike" ifTrue:[ - |osxPos| - - osxPos := OperatingSystem getMousePosition. - x := osxPos x rounded. - y := osxPos y rounded. - OperatingSystem generateButtonEvent:buttonNr down:false x:x y:y. - ^ self. - ]. - - screen sendKeyOrButtonEvent:#buttonRelease x:x y:y keyOrButton:buttonNr state:0 toViewId:(screen rootWindowId). - screen flush. - - "Created: / 19-07-2019 / 13:53:05 / Claus Gittinger" - "Modified: / 23-07-2019 / 09:38:38 / Claus Gittinger" + aBlock value:viewToClick value:clickPos. ! ! !ShowMeHowItWorks methodsFor:'helpers - mouse movement'! @@ -1589,9 +1699,23 @@ "Modified: / 25-07-2019 / 11:48:53 / Claus Gittinger" ! +doShowFile:aFilename + "the file from which the show was loaded" + + |spec| + + theShowFile := aFilename. + aFilename readingFileWithEncoding:#utf8 do:[:s | + spec := Array readFrom:s. + ]. + self do:spec. + + +! + prepare language isNil ifTrue:[ - self language:(Smalltalk language). + self setLanguage:(Smalltalk language). ]. translate := false.