ShowMeHowItWorks.st
changeset 3798 eafc4c1bb53e
parent 3797 5ab4b911e388
child 3799 bbb4c1dbce25
equal deleted inserted replaced
3797:5ab4b911e388 3798:eafc4c1bb53e
   228     "Created: / 23-07-2019 / 10:27:02 / Claus Gittinger"
   228     "Created: / 23-07-2019 / 10:27:02 / Claus Gittinger"
   229 ! !
   229 ! !
   230 
   230 
   231 !ShowMeHowItWorks methodsFor:'commands'!
   231 !ShowMeHowItWorks methodsFor:'commands'!
   232 
   232 
       
   233 freezePin:pinName ofStep:stepName with:freezeString
       
   234     <action>
       
   235 
       
   236     |diagramEditor pinPO|
       
   237 
       
   238     (diagramEditor := lastComponent) isScrollWrapper ifTrue:[
       
   239         diagramEditor := lastComponent scrolledView
       
   240     ].
       
   241     pinPO := diagramEditor 
       
   242             detectPOForWhich:[:po |
       
   243                 po isPin 
       
   244                 and:[ po name = pinName
       
   245                 and:[ po owningStepPO name = stepName ]]
       
   246             ].
       
   247     diagramEditor selection:{ pinPO }.
       
   248     diagramEditor doubleClickOn:pinPO.
       
   249     self fastMoveTo:(lastComponentName,'/','EditField').
       
   250     self click.
       
   251     self type:freezeString.
       
   252     self key:#Return.
       
   253 !
       
   254 
   233 intro
   255 intro
   234     <action>
   256     <action>
   235 
   257 
   236     verifying ifTrue:[^ self].
   258     verifying ifTrue:[^ self].
   237 
   259 
   308             (application masterApplication ? application) topViews first raise.
   330             (application masterApplication ? application) topViews first raise.
   309         ].
   331         ].
   310         ^ self
   332         ^ self
   311     ].
   333     ].
   312     self halt.
   334     self halt.
       
   335 !
       
   336 
       
   337 selectPin:pinName ofStep:stepName
       
   338     <action>
       
   339 
       
   340     |diagramEditor pinPo|
       
   341 
       
   342     (diagramEditor := lastComponent) isScrollWrapper ifTrue:[
       
   343         diagramEditor := lastComponent scrolledView
       
   344     ].
       
   345     pinPo := diagramEditor 
       
   346             detectPOForWhich:[:po |
       
   347                 po isPin 
       
   348                 and:[ po name = pinName
       
   349                 and:[ po owningStepPO name = stepName ]]
       
   350             ].
       
   351     self movePointerToComponent:diagramEditor offset:pinPo frame center.
       
   352     diagramEditor selection:{ pinPo }. 
       
   353 
   313 !
   354 !
   314 
   355 
   315 show:message
   356 show:message
   316     "showing (and speak) some message."
   357     "showing (and speak) some message."
   317 
   358 
   486     "Created: / 19-07-2019 / 15:33:32 / Claus Gittinger"
   527     "Created: / 19-07-2019 / 15:33:32 / Claus Gittinger"
   487 ! !
   528 ! !
   488 
   529 
   489 !ShowMeHowItWorks methodsFor:'commands - mouse & keyboard'!
   530 !ShowMeHowItWorks methodsFor:'commands - mouse & keyboard'!
   490 
   531 
       
   532 clear
       
   533     "clear entry fields"
       
   534 
       
   535     <action>
       
   536 
       
   537     verifying ifTrue:[^ self].
       
   538 
       
   539     lastComponent contents:nil
       
   540 !
       
   541 
   491 click
   542 click
   492     "press-release"
   543     "press-release"
   493     
   544     
   494     <action>
   545     <action>
   495 
   546 
   649 
   700 
   650     "Created: / 19-07-2019 / 12:34:25 / Claus Gittinger"
   701     "Created: / 19-07-2019 / 12:34:25 / Claus Gittinger"
   651     "Modified (format): / 19-07-2019 / 14:55:34 / Claus Gittinger"
   702     "Modified (format): / 19-07-2019 / 14:55:34 / Claus Gittinger"
   652 !
   703 !
   653 
   704 
       
   705 fastMoveRelativeX:dX y:dY
       
   706     "move the mouse to a new relative position"
       
   707     
       
   708     <action>
       
   709 
       
   710     |screen newPos currentPos|
       
   711 
       
   712     verifying ifTrue:[^ self].
       
   713 
       
   714     screen := Screen current.
       
   715     currentPos := screen pointerPosition.   
       
   716     newPos := currentPos + (dX @ dY).
       
   717     self fastMovePointerToScreenPosition:newPos
       
   718 !
       
   719 
   654 fastMoveTo:componentName
   720 fastMoveTo:componentName
   655     "move the mouse to componentName without circling"
   721     "move the mouse to componentName without circling"
   656 
   722 
   657     <action>
   723     <action>
   658 
   724 
   667     "
   733     "
   668 
   734 
   669     "Created: / 19-07-2019 / 15:39:23 / Claus Gittinger"
   735     "Created: / 19-07-2019 / 15:39:23 / Claus Gittinger"
   670     "Modified: / 20-07-2019 / 08:14:16 / Claus Gittinger"
   736     "Modified: / 20-07-2019 / 08:14:16 / Claus Gittinger"
   671     "Modified (comment): / 23-07-2019 / 09:33:31 / Claus Gittinger"
   737     "Modified (comment): / 23-07-2019 / 09:33:31 / Claus Gittinger"
       
   738 !
       
   739 
       
   740 key:aKeySymbol
       
   741     "press/release a key"
       
   742 
       
   743     <action>
       
   744 
       
   745     |t|
       
   746 
       
   747     verifying ifTrue:[^ self].
       
   748 
       
   749     t := Display ctrlDown ifTrue:[0.05] ifFalse:[0.1].
       
   750     lastComponent 
       
   751         simulateKey:aKeySymbol at:(lastComponent extent // 2) sendDisplayEvent:false keyPressTime:t
       
   752 
       
   753     "Created: / 19-07-2019 / 15:50:40 / Claus Gittinger"
   672 !
   754 !
   673 
   755 
   674 moveTo:componentName
   756 moveTo:componentName
   675     "move the mouse to componentName,
   757     "move the mouse to componentName,
   676      then circle around it a few times"
   758      then circle around it a few times"
   825         Delay waitForSeconds:0.1.
   907         Delay waitForSeconds:0.1.
   826         component simulateButtonRelease:1 at:(0 @ (yPos + 3)) sendDisplayEvent:false.
   908         component simulateButtonRelease:1 at:(0 @ (yPos + 3)) sendDisplayEvent:false.
   827         "/ component selection:idx.
   909         "/ component selection:idx.
   828         ^ self
   910         ^ self
   829     ].
   911     ].
   830 
   912     (component isKindOf:SelectionInListModelView) ifTrue:[
   831     self error:'cannot select this component'
   913         |idx yPos|
       
   914 
       
   915         itemsIndexOrLabelOrPattern isInteger ifTrue:[
       
   916             idx := itemsIndexOrLabelOrPattern
       
   917         ] ifFalse:[
       
   918             itemsIndexOrLabelOrPattern includesMatchCharacters ifTrue:[
       
   919                 idx := component indexOfElementForWhich:[:el | el notNil and:[itemsIndexOrLabelOrPattern match:el string]]. 
       
   920             ] ifFalse:[
       
   921                 idx := component indexOfElementForWhich:[:el | el notNil and:[el string = itemsIndexOrLabelOrPattern]].
       
   922             ].
       
   923             idx == 0 ifTrue:[
       
   924                 self error:'no such item in hierarchicalList: ',itemsIndexOrLabelOrPattern
       
   925             ].
       
   926         ].
       
   927         yPos := component yVisibleOfLine:idx.
       
   928         self movePointerToComponent:component offset:(0 @ (yPos + 3)).
       
   929         component simulateButtonPress:1 at:(0 @ (yPos + 3)) sendDisplayEvent:false.
       
   930         Delay waitForSeconds:0.1.
       
   931         component simulateButtonRelease:1 at:(0 @ (yPos + 3)) sendDisplayEvent:false.
       
   932         "/ component selection:idx.
       
   933         ^ self
       
   934     ].
       
   935 
       
   936     (component isKindOf:ItemInView) ifTrue:[
       
   937         component isMenuItem ifTrue:[
       
   938             self movePointerToComponent:component.
       
   939             self halt.
       
   940         ].
       
   941     ].
       
   942 
       
   943     self error:('cannot select this component: %1' bindWith:component className)
   832 
   944 
   833     "Created: / 19-07-2019 / 12:34:25 / Claus Gittinger"
   945     "Created: / 19-07-2019 / 12:34:25 / Claus Gittinger"
   834     "Modified (format): / 19-07-2019 / 14:55:34 / Claus Gittinger"
   946     "Modified (format): / 19-07-2019 / 14:55:34 / Claus Gittinger"
   835 !
   947 !
   836 
   948 
  1154 findComponent:componentNameOrPath in:anApplicationOrViewOrMenuItem
  1266 findComponent:componentNameOrPath in:anApplicationOrViewOrMenuItem
  1155     "find a component by name inside an app or inside a view.
  1267     "find a component by name inside an app or inside a view.
  1156      Uses the NameKey of the spec, and optionally the label or modelKey.
  1268      Uses the NameKey of the spec, and optionally the label or modelKey.
  1157      Can return either a view or a menu item"
  1269      Can return either a view or a menu item"
  1158 
  1270 
  1159     |idxString idx app window component componentNameSymbol 
  1271     |quoted idxString idx app window component componentNameSymbol 
  1160      foundByName foundByHelpKey foundByTitle foundByLabel item
  1272      foundByName foundByHelpKey foundByTitle foundByLabel item
  1161      checkIfAllMenuItemsDoTheSame|
  1273      checkIfAllMenuItemsDoTheSame|
  1162 
  1274 
  1163     (componentNameOrPath includes:$/) ifTrue:[
  1275     "/ split at "/";
  1164         (idx := componentNameOrPath indexOf:$/) ~~ 0 ifTrue:[
  1276     "/ but not if inside quotes
  1165             |containerName restPath container|
  1277     quoted := false.
  1166 
  1278     componentNameOrPath doWithIndex:[:ch :idx |
  1167             containerName := componentNameOrPath copyTo:idx-1.
  1279         ch == $" ifTrue:[
  1168             restPath := componentNameOrPath copyFrom:idx+1.
  1280             quoted := quoted not.
  1169             container := self findComponent:containerName in:anApplicationOrViewOrMenuItem.
  1281         ] ifFalse:[
  1170             container isNil ifTrue:[ ^ nil ].
  1282             ((ch == $/) and:[quoted not]) ifTrue:[
  1171             ^ self findComponent:restPath in:container
  1283                 |containerName restPath container|
       
  1284 
       
  1285                 containerName := componentNameOrPath copyTo:idx-1.
       
  1286                 restPath := componentNameOrPath copyFrom:idx+1.
       
  1287                 container := self findComponent:containerName in:anApplicationOrViewOrMenuItem.
       
  1288                 container isNil ifTrue:[ ^ nil ].
       
  1289                 ^ self findComponent:restPath in:container
       
  1290             ]
  1172         ]
  1291         ]
  1173     ].
  1292     ].
       
  1293 
       
  1294     (anApplicationOrViewOrMenuItem isKindOf:ItemInView) ifTrue:[
       
  1295         anApplicationOrViewOrMenuItem isMenuItem ifTrue:[
       
  1296             ^ self findComponent:componentNameOrPath in:anApplicationOrViewOrMenuItem item submenu
       
  1297         ].
       
  1298     ].
       
  1299 
  1174     (componentNameOrPath startsWith:'item[') ifTrue:[
  1300     (componentNameOrPath startsWith:'item[') ifTrue:[
  1175         anApplicationOrViewOrMenuItem isMenu ifFalse:[
  1301         anApplicationOrViewOrMenuItem isMenu ifFalse:[
  1176             self assert:false message:'container is not a menu'.
  1302             self assert:false message:'container is not a menu'.
  1177         ].
  1303         ].
  1178         idxString := (componentNameOrPath withoutPrefix:'item[') withoutSuffix:']'.
  1304         idxString := (componentNameOrPath withoutPrefix:'item[') withoutSuffix:']'.
  1179         (idxString conform:#isDigit) ifTrue:[
  1305         (idxString conform:#isDigit) ifTrue:[
  1180             idx := Integer readFrom:idxString.
  1306             idx := Integer readFrom:idxString.
  1181             item := anApplicationOrViewOrMenuItem itemAtIndex:idx.
  1307             item := anApplicationOrViewOrMenuItem itemAtIndex:idx.
  1182         ] ifFalse:[
  1308         ] ifFalse:[
  1183             item := anApplicationOrViewOrMenuItem itemAt:idxString.
  1309             idxString := idxString withoutQuotes.
  1184         ].
  1310             idxString includesMatchCharacters ifTrue:[
  1185         self assert:item notNil.
  1311                 item := 
       
  1312                     anApplicationOrViewOrMenuItem itemForWhich:[:item |
       
  1313                         (item nameKey matches: idxString)
       
  1314                         or:[ (item textLabel matches: idxString) 
       
  1315                         or:[ (item value isSymbol and:[item value matches: idxString])]]
       
  1316                     ]
       
  1317             ] ifFalse:[
       
  1318                 item := 
       
  1319                     anApplicationOrViewOrMenuItem itemForWhich:[:item |
       
  1320                         item nameKey = idxString
       
  1321                         or:[ item textLabel = idxString 
       
  1322                         or:[ (item value isSymbol and:[ item value = idxString ])]]
       
  1323                     ]
       
  1324             ].
       
  1325         ].
       
  1326         self assert:item notNil message:('no menu item named "%1"' bindWith:idxString).
  1186         ^ ItemInView new view:anApplicationOrViewOrMenuItem item:item boundsInView:(item layout)
  1327         ^ ItemInView new view:anApplicationOrViewOrMenuItem item:item boundsInView:(item layout)
  1187     ].
  1328     ].
  1188     (componentNameOrPath startsWith:'tab[') ifTrue:[
  1329     (componentNameOrPath startsWith:'tab[') ifTrue:[
  1189         (anApplicationOrViewOrMenuItem isKindOf:NoteBookView) ifFalse:[
  1330         (anApplicationOrViewOrMenuItem isKindOf:NoteBookView) ifFalse:[
  1190             self assert:false message:'container is not a notebook'.
  1331             self assert:false message:'container is not a notebook'.
  1192         idxString := (componentNameOrPath withoutPrefix:'tab[') withoutSuffix:']'.
  1333         idxString := (componentNameOrPath withoutPrefix:'tab[') withoutSuffix:']'.
  1193         (idxString conform:#isDigit) ifTrue:[
  1334         (idxString conform:#isDigit) ifTrue:[
  1194             idx := Integer readFrom:idxString.
  1335             idx := Integer readFrom:idxString.
  1195             item := anApplicationOrViewOrMenuItem tabAtIndex:idx.
  1336             item := anApplicationOrViewOrMenuItem tabAtIndex:idx.
  1196         ] ifFalse:[
  1337         ] ifFalse:[
       
  1338             idxString := idxString withoutQuotes.
  1197             item := anApplicationOrViewOrMenuItem tabForWhich:[:tab | tab tabItem rawLabel = idxString].
  1339             item := anApplicationOrViewOrMenuItem tabForWhich:[:tab | tab tabItem rawLabel = idxString].
  1198             item isNil ifTrue:[
  1340             item isNil ifTrue:[
  1199                 item := anApplicationOrViewOrMenuItem tabForWhich:[:tab | tab printableLabel = idxString].
  1341                 item := anApplicationOrViewOrMenuItem tabForWhich:[:tab | tab printableLabel = idxString].
  1200                 item isNil ifTrue:[
  1342                 item isNil ifTrue:[
  1201                     item := anApplicationOrViewOrMenuItem tabForWhich:[:tab | tab activeHelpKey = idxString].
  1343                     item := anApplicationOrViewOrMenuItem tabForWhich:[:tab | tab activeHelpKey = idxString].
  1396     (aWidgetOrMenuItemOrTab askFor:#isMenuItem) ifTrue:[
  1538     (aWidgetOrMenuItemOrTab askFor:#isMenuItem) ifTrue:[
  1397         |menuPanel menuBounds|
  1539         |menuPanel menuBounds|
  1398 
  1540 
  1399         aWidgetOrMenuItemOrTab isVisible ifTrue:[
  1541         aWidgetOrMenuItemOrTab isVisible ifTrue:[
  1400             (itemLayout := aWidgetOrMenuItemOrTab layout) notNil ifTrue:[
  1542             (itemLayout := aWidgetOrMenuItemOrTab layout) notNil ifTrue:[
  1401                 menuPanel := aWidgetOrMenuItemOrTab menuPanel.
  1543                 menuPanel := aWidgetOrMenuItemOrTab view.
  1402                 menuPanel shown ifTrue:[
  1544                 menuPanel shown ifTrue:[
  1403                     menuBounds := menuPanel screenBounds.
  1545                     menuBounds := menuPanel screenBounds.
  1404                     ^ itemLayout + menuBounds origin 
  1546                     ^ itemLayout + menuBounds origin 
  1405                 ].
  1547                 ].
  1406             ].
  1548             ].
  1442 
  1584 
  1443 click:buttonNr inComponent:viewOrMenuItem clickTime:clickTime 
  1585 click:buttonNr inComponent:viewOrMenuItem clickTime:clickTime 
  1444     "press-release in a component"
  1586     "press-release in a component"
  1445 
  1587 
  1446     self withViewAndPositionFor:viewOrMenuItem do:[:viewToClick :clickPos |
  1588     self withViewAndPositionFor:viewOrMenuItem do:[:viewToClick :clickPos |
  1447         viewToClick simulateButtonPress:buttonNr at:clickPos sendDisplayEvent:false.
  1589         Display activePointerGrab == Display rootView ifTrue:[
  1448         Delay waitForSeconds:clickTime.
  1590             |pos|
  1449         viewToClick simulateButtonRelease:buttonNr at:clickPos sendDisplayEvent:false.
  1591 
       
  1592             pos := Display translatePoint:clickPos fromView:viewToClick toView:nil.
       
  1593             OperatingSystem isOSXlike ifTrue:[
       
  1594                 OperatingSystem 
       
  1595                     generateMouseMoveEventX:pos x y:pos y;
       
  1596                     generateButtonEvent:buttonNr down:true x:pos x y:pos y;
       
  1597                     generateButtonEvent:buttonNr down:false x:pos x y:pos y;
       
  1598                     generateButtonEvent:buttonNr down:true x:pos x y:pos y;
       
  1599                     generateButtonEvent:buttonNr down:false x:pos x y:pos y.
       
  1600                 ^ self.
       
  1601             ].
       
  1602             Display rootView simulateButtonPress:buttonNr at:pos sendDisplayEvent:true.
       
  1603             Delay waitForSeconds:clickTime.
       
  1604             Display rootView simulateButtonRelease:buttonNr at:pos sendDisplayEvent:true.
       
  1605         ] ifFalse:[
       
  1606             viewToClick simulateButtonPress:buttonNr at:clickPos sendDisplayEvent:false.
       
  1607             Delay waitForSeconds:clickTime.
       
  1608             viewToClick simulateButtonRelease:buttonNr at:clickPos sendDisplayEvent:false.
       
  1609         ].
  1450     ].
  1610     ].
  1451 !
  1611 !
  1452 
  1612 
  1453 press:buttonNr inComponent:viewOrMenuItem 
  1613 press:buttonNr inComponent:viewOrMenuItem 
  1454     "press in a component"
  1614     "press in a component"
  1472     |viewToClick clickPos|
  1632     |viewToClick clickPos|
  1473 
  1633 
  1474     self assert:viewOrMenuItem notNil.
  1634     self assert:viewOrMenuItem notNil.
  1475     verifying ifTrue:[^ self].
  1635     verifying ifTrue:[^ self].
  1476 
  1636 
  1477     ((viewOrMenuItem askFor:#isMenuItem) 
  1637     (viewOrMenuItem isKindOf:ItemInView) ifTrue:[
  1478     or:[ (viewOrMenuItem askFor:#isNoteBookTab) ]) ifTrue:[
       
  1479         viewToClick := viewOrMenuItem view.
  1638         viewToClick := viewOrMenuItem view.
  1480         clickPos := viewOrMenuItem layout center.
  1639         clickPos := viewOrMenuItem layout center.
  1481         self assert:(clickPos notNil).
  1640         self assert:(clickPos notNil).
  1482     ] ifFalse:[
  1641     ] ifFalse:[
  1483         viewToClick := viewOrMenuItem.
  1642         viewToClick := viewOrMenuItem.
  1636 
  1795 
  1637     screen := Screen current.
  1796     screen := Screen current.
  1638     start := screen pointerPosition.   
  1797     start := screen pointerPosition.   
  1639 
  1798 
  1640     distance := start dist:newPosition.
  1799     distance := start dist:newPosition.
       
  1800     distance = 0 ifTrue:[
       
  1801         "/ already there
       
  1802         screen setPointerPosition:newPosition. "/ do it anyway, in case of rounding errors
       
  1803         ^ self
       
  1804     ].
       
  1805 
  1641     moveTime := (distance / pixelsPerSecond) seconds.   "/ time to move
  1806     moveTime := (distance / pixelsPerSecond) seconds.   "/ time to move
  1642     stepDelayTime := self pointerAnimationDelay.        "/ update every 50ms
  1807     stepDelayTime := self pointerAnimationDelay.        "/ update every 50ms
  1643     
  1808     
  1644     numSteps := moveTime / stepDelayTime.
  1809     numSteps := moveTime / stepDelayTime.
  1645     numSteps = 0 ifTrue:[
  1810     numSteps = 0 ifTrue:[
  1646         "/ already there
  1811         "/ already there
       
  1812         screen setPointerPosition:newPosition. "/ do it anyway, in case of rounding errors
  1647         ^ self
  1813         ^ self
  1648     ].
  1814     ].
  1649     
  1815     
  1650     delta := (newPosition - start) / numSteps.
  1816     delta := (newPosition - start) / numSteps.
  1651     1 to:numSteps do:[:step |
  1817     1 to:numSteps do:[:step |
  2109     boundsInView := boundsInViewArg.
  2275     boundsInView := boundsInViewArg.
  2110 ! !
  2276 ! !
  2111 
  2277 
  2112 !ShowMeHowItWorks::ItemInView methodsFor:'testing'!
  2278 !ShowMeHowItWorks::ItemInView methodsFor:'testing'!
  2113 
  2279 
       
  2280 isItemInView
       
  2281     ^ true
       
  2282 !
       
  2283 
  2114 isMenuItem
  2284 isMenuItem
  2115     ^ item askFor:#isMenuItem
  2285     ^ item askFor:#isMenuItem
  2116 !
  2286 !
  2117 
  2287 
  2118 isNoteBookTab
  2288 isNoteBookTab
  2119     ^ item isKindOf:NoteBookView::Tab
  2289     ^ item isKindOf:NoteBookView::Tab
       
  2290 !
       
  2291 
       
  2292 isVisible
       
  2293     ^ view shown
       
  2294     and:[item isVisible]
  2120 ! !
  2295 ! !
  2121 
  2296 
  2122 !ShowMeHowItWorks class methodsFor:'documentation'!
  2297 !ShowMeHowItWorks class methodsFor:'documentation'!
  2123 
  2298 
  2124 version_CVS
  2299 version_CVS