91 "Modified (comment): / 19-07-2019 / 14:30:29 / Claus Gittinger" |
93 "Modified (comment): / 19-07-2019 / 14:30:29 / Claus Gittinger" |
92 ! ! |
94 ! ! |
93 |
95 |
94 !ShowMeHowItWorks methodsFor:'commands'! |
96 !ShowMeHowItWorks methodsFor:'commands'! |
95 |
97 |
|
98 intro |
|
99 <action> |
|
100 |
|
101 self tell:'you can stopp the shou - by pressing - the shiftkee'. |
|
102 |
|
103 "Created: / 19-07-2019 / 15:49:19 / Claus Gittinger" |
|
104 ! |
|
105 |
96 pause |
106 pause |
97 <action> |
107 <action> |
98 |
108 |
99 Dialog information:'Show Paused.\Click on "OK" to proceed' |
109 Dialog information:(self class classResources stringWithCRs:'Show Paused.\Click on "OK" to proceed') |
100 |
110 |
101 "Created: / 19-07-2019 / 15:03:17 / Claus Gittinger" |
111 "Created: / 19-07-2019 / 15:03:17 / Claus Gittinger" |
102 ! |
112 "Modified: / 19-07-2019 / 16:13:33 / Claus Gittinger" |
103 |
113 ! |
104 showing:message do:operations |
114 |
|
115 show:message |
105 "execute operations while showing (and speaking) some message." |
116 "execute operations while showing (and speaking) some message." |
106 |
117 |
107 <action> |
118 <action> |
108 |
119 |
|
120 self showing:message do:nil |
|
121 |
|
122 "Created: / 19-07-2019 / 15:59:18 / Claus Gittinger" |
|
123 ! |
|
124 |
|
125 showing:message do:operationsOrNothing |
|
126 "execute operations while showing (and speaking) some message." |
|
127 |
|
128 <action> |
|
129 |
109 |messageView talkDone| |
130 |messageView talkDone| |
110 |
131 |
111 self assert:operations isSequenceable. |
132 self assert:(operationsOrNothing isNil or:[operationsOrNothing isSequenceable]). |
112 |
133 |
113 messageView := ActiveHelpView for:message. |
134 messageView := ActiveHelpView for:message. |
114 "/ messageView shapeStyle:#cartoon. |
135 "/ messageView shapeStyle:#cartoon. |
115 [ |
136 [ |
116 messageView realize. |
137 messageView realize. |
125 "/ |
146 "/ |
126 "/ allow speaker some headoff |
147 "/ allow speaker some headoff |
127 Delay waitForSeconds:(message size / 20). |
148 Delay waitForSeconds:(message size / 20). |
128 ]. |
149 ]. |
129 |
150 |
130 self doStream:(operations readStream). |
151 operationsOrNothing notEmptyOrNil ifTrue:[ |
|
152 self doStream:(operationsOrNothing readStream). |
|
153 ]. |
131 ] ensure:[ |
154 ] ensure:[ |
132 messageView destroy |
155 messageView destroy |
133 ]. |
156 ]. |
134 self talking ifTrue:[ |
157 self talking ifTrue:[ |
135 talkDone wait. |
158 talkDone wait. |
136 ]. |
159 ]. |
137 |
160 |
138 "Created: / 19-07-2019 / 11:19:27 / Claus Gittinger" |
161 "Created: / 19-07-2019 / 11:19:27 / Claus Gittinger" |
139 "Modified (format): / 19-07-2019 / 15:02:12 / Claus Gittinger" |
162 "Modified: / 19-07-2019 / 15:59:52 / Claus Gittinger" |
140 ! |
163 ! |
141 |
164 |
142 wait:seconds |
165 wait:seconds |
143 <action> |
166 <action> |
144 |
167 |
145 Delay waitForSeconds:seconds |
168 Delay waitForSeconds:seconds |
146 |
169 |
147 "Created: / 19-07-2019 / 15:09:45 / Claus Gittinger" |
170 "Created: / 19-07-2019 / 15:09:45 / Claus Gittinger" |
148 ! ! |
171 ! ! |
149 |
172 |
150 !ShowMeHowItWorks methodsFor:'commands - mouse'! |
173 !ShowMeHowItWorks methodsFor:'commands - checking'! |
|
174 |
|
175 isEmpty:componentName |
|
176 <action> |
|
177 |
|
178 |component| |
|
179 |
|
180 component := self componentNamed:componentName. |
|
181 component isScrollWrapper ifTrue:[ component := component scrolledView ]. |
|
182 component isTextView ifTrue:[ |
|
183 ^ component contents isEmptyOrNil |
|
184 ] ifFalse:[ |
|
185 self halt. |
|
186 ]. |
|
187 self error:'isEmpty: unhandled component type: ',component displayString. |
|
188 |
|
189 "Created: / 19-07-2019 / 15:33:47 / Claus Gittinger" |
|
190 ! |
|
191 |
|
192 unless:query do:actions |
|
193 <action> |
|
194 |
|
195 |result| |
|
196 |
|
197 result := self doCommand:query. |
|
198 result ifFalse:[ |
|
199 self doCommand:actions |
|
200 ]. |
|
201 |
|
202 "Created: / 19-07-2019 / 15:33:32 / Claus Gittinger" |
|
203 ! ! |
|
204 |
|
205 !ShowMeHowItWorks methodsFor:'commands - mouse & keyboard'! |
|
206 |
|
207 click |
|
208 "press-release" |
|
209 |
|
210 <action> |
|
211 |
|
212 ^ self click:1 inComponent:lastComponent |
|
213 |
|
214 "Created: / 19-07-2019 / 16:11:03 / Claus Gittinger" |
|
215 ! |
151 |
216 |
152 click:buttonNr |
217 click:buttonNr |
153 "press-release" |
218 "press-release" |
154 |
219 |
155 <action> |
220 <action> |
156 |
221 |
157 self click:buttonNr inComponent:lastComponent |
222 self assert:(buttonNr isInteger). |
|
223 ^ self click:buttonNr inComponent:lastComponent |
158 |
224 |
159 "Created: / 19-07-2019 / 13:21:20 / Claus Gittinger" |
225 "Created: / 19-07-2019 / 13:21:20 / Claus Gittinger" |
160 "Modified: / 19-07-2019 / 14:55:18 / Claus Gittinger" |
226 "Modified: / 19-07-2019 / 16:10:19 / Claus Gittinger" |
161 ! |
227 ! |
162 |
228 |
163 enter:aString |
229 clickIn:componentName |
164 "enter text into the last component" |
230 "press-release" |
165 |
231 |
166 <action> |
232 <action> |
167 |
233 |
168 lastComponent simulateTextInput:aString at:(lastComponent extent // 2) sendDisplayEvent:false |
234 ^ self click:1 inComponent:(self componentNamed:componentName) |
169 |
235 |
170 "Created: / 19-07-2019 / 14:29:27 / Claus Gittinger" |
236 "Created: / 19-07-2019 / 16:09:58 / Claus Gittinger" |
|
237 ! |
|
238 |
|
239 fastMoveTo:componentName |
|
240 "move the mouse to componentName without circling" |
|
241 |
|
242 <action> |
|
243 |
|
244 |component| |
|
245 |
|
246 component := self componentNamed:componentName. |
|
247 self movePointerToComponent:component. |
|
248 |
|
249 "Created: / 19-07-2019 / 15:39:23 / Claus Gittinger" |
171 ! |
250 ! |
172 |
251 |
173 moveTo:componentName |
252 moveTo:componentName |
174 "move the mouse to componentName, |
253 "move the mouse to componentName, |
175 then circle around it a few times" |
254 then circle around it a few times" |
176 |
255 |
177 <action> |
256 <action> |
178 |
257 |
179 |component| |
258 |component| |
180 |
259 |
181 lastComponentName := componentName. |
260 component := self componentNamed:componentName. |
182 |
|
183 component := self findComponent:componentName. |
|
184 component isNil ifTrue:[ |
|
185 self error:'no component found for: ',componentName. |
|
186 ]. |
|
187 lastComponent := component. |
|
188 |
|
189 self movePointerToComponent:component. |
261 self movePointerToComponent:component. |
190 self circlePointerAroundComponent:component. |
262 self circlePointerAroundComponent:component. |
191 |
263 |
192 "Created: / 19-07-2019 / 11:20:42 / Claus Gittinger" |
264 "Created: / 19-07-2019 / 11:20:42 / Claus Gittinger" |
193 "Modified (format): / 19-07-2019 / 14:55:27 / Claus Gittinger" |
265 "Modified: / 19-07-2019 / 15:38:11 / Claus Gittinger" |
194 ! |
266 ! |
195 |
267 |
196 select:itemsLabel |
268 select:itemsLabel |
197 "select an item by label, |
269 "select an item by label, |
198 allowed after moving to: |
270 allowed after moving to: |
232 aSelectionInListView |
304 aSelectionInListView |
233 " |
305 " |
234 |
306 |
235 <action> |
307 <action> |
236 |
308 |
237 (lastComponent isKindOf:ComboView) ifTrue:[ |
309 |widget y offset| |
|
310 |
|
311 (widget := lastComponent) isScrollWrapper ifTrue:[ |
|
312 widget := widget scrolledView |
|
313 ]. |
|
314 |
|
315 (widget isKindOf:ComboView) ifTrue:[ |
238 "/ click on the menubutton |
316 "/ click on the menubutton |
239 self movePointerToComponent:lastComponent menuButton. |
317 self movePointerToComponent:widget menuButton. |
240 self click:1 inComponent:lastComponent menuButton. |
318 self click:1 inComponent:widget menuButton. |
241 Delay waitForSeconds:0.5. |
319 Delay waitForSeconds:0.5. |
242 lastComponent select:itemsIndex. |
320 widget select:itemsIndex. |
243 Delay waitForSeconds:0.5. |
321 Delay waitForSeconds:0.5. |
244 self halt. |
322 self halt. |
245 ^ self |
323 ^ self |
246 ]. |
324 ]. |
|
325 (widget isKindOf:SelectionInListView) ifTrue:[ |
|
326 "/ click on the item |
|
327 y := widget yOfLine:itemsIndex. |
|
328 offset := (widget width // 2) @ y. |
|
329 self movePointerToComponent:widget offset:offset. |
|
330 widget simulateButtonPress:1 at:offset sendDisplayEvent:false. |
|
331 Delay waitForSeconds:(self clickTime). |
|
332 widget simulateButtonRelease:1 at:offset sendDisplayEvent:false. |
|
333 Delay waitForSeconds:0.5. |
|
334 ^ self |
|
335 ]. |
247 self error:'cannot select this component' |
336 self error:'cannot select this component' |
248 |
337 |
249 "Created: / 19-07-2019 / 14:20:11 / Claus Gittinger" |
338 "Created: / 19-07-2019 / 14:20:11 / Claus Gittinger" |
|
339 "Modified: / 19-07-2019 / 16:22:47 / Claus Gittinger" |
|
340 ! |
|
341 |
|
342 type:aString |
|
343 "enter text into the last component" |
|
344 |
|
345 <action> |
|
346 |
|
347 lastComponent simulateTextInput:aString at:(lastComponent extent // 2) sendDisplayEvent:false |
|
348 |
|
349 "Created: / 19-07-2019 / 15:50:40 / Claus Gittinger" |
250 ! ! |
350 ! ! |
251 |
351 |
252 !ShowMeHowItWorks methodsFor:'defaults'! |
352 !ShowMeHowItWorks methodsFor:'defaults'! |
253 |
353 |
254 circlingCount |
354 circlingCount |
293 ^ 400. "/ pixels per second |
402 ^ 400. "/ pixels per second |
294 |
403 |
295 "Created: / 19-07-2019 / 13:05:40 / Claus Gittinger" |
404 "Created: / 19-07-2019 / 13:05:40 / Claus Gittinger" |
296 ! |
405 ! |
297 |
406 |
|
407 shortClickTime |
|
408 "when clicking" |
|
409 |
|
410 ^ 100 milliseconds |
|
411 |
|
412 "Created: / 19-07-2019 / 15:21:29 / Claus Gittinger" |
|
413 ! |
|
414 |
298 talking |
415 talking |
299 ^ true |
416 ^ true |
300 |
417 |
301 "Created: / 19-07-2019 / 14:31:14 / Claus Gittinger" |
418 "Created: / 19-07-2019 / 14:31:14 / Claus Gittinger" |
302 ! ! |
419 ! ! |
303 |
420 |
304 !ShowMeHowItWorks methodsFor:'helper'! |
421 !ShowMeHowItWorks methodsFor:'helper'! |
|
422 |
|
423 componentNamed:componentName |
|
424 "retrieve a component by name or report an error if not found" |
|
425 |
|
426 |component| |
|
427 |
|
428 lastComponentName := componentName. |
|
429 |
|
430 component := self findComponent:componentName. |
|
431 component isNil ifTrue:[ |
|
432 self error:'no component found for: ',componentName. |
|
433 ]. |
|
434 lastComponent := component. |
|
435 ^ component |
|
436 |
|
437 "Created: / 19-07-2019 / 15:37:35 / Claus Gittinger" |
|
438 ! |
305 |
439 |
306 findComponent:componentName |
440 findComponent:componentName |
307 "find a component by name - in the active and possibly in any app" |
441 "find a component by name - in the active and possibly in any app" |
308 |
442 |
309 |app component candidates| |
443 |app component candidates| |
456 ]. |
590 ]. |
457 |
591 |
458 "Created: / 19-07-2019 / 13:12:40 / Claus Gittinger" |
592 "Created: / 19-07-2019 / 13:12:40 / Claus Gittinger" |
459 ! |
593 ! |
460 |
594 |
461 click:buttonNr inComponent:component |
|
462 "press-release in a component" |
|
463 |
|
464 component simulateButtonPress:buttonNr at:(component extent // 2) sendDisplayEvent:false. |
|
465 Delay waitForSeconds:(self clickTime). |
|
466 component simulateButtonRelease:buttonNr at:(component extent // 2) sendDisplayEvent:false. |
|
467 |
|
468 "/ self click:buttonNr atPosition:(component extent // 2) |
|
469 |
|
470 "Created: / 19-07-2019 / 13:18:27 / Claus Gittinger" |
|
471 ! |
|
472 |
|
473 movePointerToComponent:aWidget |
595 movePointerToComponent:aWidget |
474 "move the mouse to aWidget's center" |
596 "move the mouse to aWidget's center" |
475 |
597 |
476 self movePointerToPosition:(aWidget screenBounds center rounded). |
598 self movePointerToPosition:(aWidget screenBounds center rounded). |
477 |
599 |
478 "Created: / 19-07-2019 / 13:11:33 / Claus Gittinger" |
600 "Created: / 19-07-2019 / 13:11:33 / Claus Gittinger" |
|
601 ! |
|
602 |
|
603 movePointerToComponent:aWidget offset:offset |
|
604 "move the mouse to position inside aWidget's" |
|
605 |
|
606 self movePointerToPosition:(aWidget screenBounds origin + offset) rounded. |
|
607 |
|
608 "Created: / 19-07-2019 / 16:18:58 / Claus Gittinger" |
479 ! |
609 ! |
480 |
610 |
481 movePointerToPosition:newPosition |
611 movePointerToPosition:newPosition |
482 "move the mouse to newPosition" |
612 "move the mouse to newPosition" |
483 |
613 |
506 screen flush. |
636 screen flush. |
507 Delay waitFor:stepDelayTime. |
637 Delay waitFor:stepDelayTime. |
508 ]. |
638 ]. |
509 |
639 |
510 "Created: / 19-07-2019 / 12:57:30 / Claus Gittinger" |
640 "Created: / 19-07-2019 / 12:57:30 / Claus Gittinger" |
|
641 ! ! |
|
642 |
|
643 !ShowMeHowItWorks methodsFor:'menu actions - mouse buttons'! |
|
644 |
|
645 click:buttonNr inComponent:component |
|
646 "press-release in a component" |
|
647 |
|
648 |t| |
|
649 |
|
650 t := self shortClickTime. |
|
651 (component isKindOf:Button) ifTrue:[ |
|
652 t := self longClickTime |
|
653 ]. |
|
654 self click:buttonNr inComponent:component clickTime:t |
|
655 |
|
656 "Created: / 19-07-2019 / 13:18:27 / Claus Gittinger" |
|
657 "Modified: / 19-07-2019 / 15:22:47 / Claus Gittinger" |
|
658 ! |
|
659 |
|
660 click:buttonNr inComponent:component clickTime:clickTime |
|
661 "press-release in a component" |
|
662 |
|
663 component simulateButtonPress:buttonNr at:(component extent // 2) sendDisplayEvent:false. |
|
664 Delay waitForSeconds:clickTime. |
|
665 component simulateButtonRelease:buttonNr at:(component extent // 2) sendDisplayEvent:false. |
|
666 |
|
667 "/ self click:buttonNr atPosition:(component extent // 2) |
|
668 |
|
669 "Created: / 19-07-2019 / 15:21:05 / Claus Gittinger" |
511 ! |
670 ! |
512 |
671 |
513 press:buttonNr |
672 press:buttonNr |
514 "press at the current position" |
673 "press at the current position" |
515 |
674 |
566 "Created: / 19-07-2019 / 13:53:05 / Claus Gittinger" |
725 "Created: / 19-07-2019 / 13:53:05 / Claus Gittinger" |
567 ! ! |
726 ! ! |
568 |
727 |
569 !ShowMeHowItWorks methodsFor:'running'! |
728 !ShowMeHowItWorks methodsFor:'running'! |
570 |
729 |
571 doStream:specStream |
730 doCommand:op |
572 |previousStream| |
731 |numArgs sel args method| |
573 |
732 |
574 previousStream := opStream. |
|
575 [ |
|
576 opStream := specStream. |
|
577 [opStream atEnd] whileFalse:[ |
|
578 self nextCommand. |
|
579 Display shiftDown ifTrue:[ |
|
580 self tell:'Shou stopped by shiftkee'. |
|
581 ^ AbortOperationRequest raise |
|
582 ]. |
|
583 ]. |
|
584 ] ensure:[ |
|
585 opStream := previousStream |
|
586 ]. |
|
587 |
|
588 "<<END |
|
589 ShowMeHowItWorks do:#( |
|
590 showing: 'Choose the number of arguments' |
|
591 do: ( |
|
592 moveTo: NumberOfArguments |
|
593 select: '1' |
|
594 ) |
|
595 showing: 'Click into the "receiver" field' |
|
596 do: ( |
|
597 moveTo: ReceiverEditor |
|
598 click: ReceiverEditor |
|
599 ) |
|
600 showing: 'Enter a value (or expression) into "receiver" field' |
|
601 do: ( |
|
602 enter: '100' |
|
603 ) |
|
604 showing: 'Click into the "first argument" field' |
|
605 do: ( |
|
606 moveTo: Arg1Editor |
|
607 click: ReceiverEditor |
|
608 ) |
|
609 showing: 'Enter a value (or expression) into "receiver" field' |
|
610 do: ( |
|
611 enter: '100' |
|
612 ) |
|
613 ) |
|
614 END" |
|
615 |
|
616 "Created: / 19-07-2019 / 10:52:24 / Claus Gittinger" |
|
617 "Modified: / 19-07-2019 / 15:00:44 / Claus Gittinger" |
|
618 ! |
|
619 |
|
620 nextCommand |
|
621 |op numArgs sel args method| |
|
622 |
|
623 op := opStream next. |
|
624 op isArray ifTrue:[ |
733 op isArray ifTrue:[ |
|
734 op first isArray ifTrue:[ |
|
735 self doStream:op readStream. |
|
736 ^ self. |
|
737 ]. |
|
738 |
625 "/ construct a selector from keyword parts at odd indices |
739 "/ construct a selector from keyword parts at odd indices |
626 sel := ((op with:(1 to:op size) select:[:el :idx | idx odd]) asStringWith:'') asSymbol. |
740 sel := ((op with:(1 to:op size) select:[:el :idx | idx odd]) asStringWith:'') asSymbol. |
627 "/ construct arg vector from parts at even indices |
741 "/ construct arg vector from parts at even indices |
628 args := op with:(1 to:op size) select:[:el :idx | idx even]. |
742 args := op with:(1 to:op size) select:[:el :idx | idx even]. |
629 ] ifFalse:[ |
743 ] ifFalse:[ |
666 enter: '100' |
781 enter: '100' |
667 ) |
782 ) |
668 ) |
783 ) |
669 END" |
784 END" |
670 |
785 |
|
786 "Created: / 19-07-2019 / 15:34:55 / Claus Gittinger" |
|
787 ! |
|
788 |
|
789 doStream:specStream |
|
790 |previousStream| |
|
791 |
|
792 previousStream := opStream. |
|
793 [ |
|
794 opStream := specStream. |
|
795 [opStream atEnd] whileFalse:[ |
|
796 self nextCommand. |
|
797 Display shiftDown ifTrue:[ |
|
798 self tell:'you stopped the shou, thank you, for watching'. |
|
799 ^ AbortOperationRequest raise |
|
800 ]. |
|
801 ]. |
|
802 ] ensure:[ |
|
803 opStream := previousStream |
|
804 ]. |
|
805 |
|
806 "<<END |
|
807 ShowMeHowItWorks do:#( |
|
808 showing: 'Choose the number of arguments' |
|
809 do: ( |
|
810 moveTo: NumberOfArguments |
|
811 select: '1' |
|
812 ) |
|
813 showing: 'Click into the "receiver" field' |
|
814 do: ( |
|
815 moveTo: ReceiverEditor |
|
816 click: ReceiverEditor |
|
817 ) |
|
818 showing: 'Enter a value (or expression) into "receiver" field' |
|
819 do: ( |
|
820 enter: '100' |
|
821 ) |
|
822 showing: 'Click into the "first argument" field' |
|
823 do: ( |
|
824 moveTo: Arg1Editor |
|
825 click: ReceiverEditor |
|
826 ) |
|
827 showing: 'Enter a value (or expression) into "receiver" field' |
|
828 do: ( |
|
829 enter: '100' |
|
830 ) |
|
831 ) |
|
832 END" |
|
833 |
|
834 "Created: / 19-07-2019 / 10:52:24 / Claus Gittinger" |
|
835 "Modified: / 19-07-2019 / 16:02:51 / Claus Gittinger" |
|
836 ! |
|
837 |
|
838 nextCommand |
|
839 self doCommand:(opStream next). |
|
840 |
|
841 "<<END |
|
842 ShowMeHowItWorks do:#( |
|
843 showing: 'Choose the number of arguments' |
|
844 do: ( |
|
845 moveTo: NumberOfArguments |
|
846 select: '1' |
|
847 ) |
|
848 showing: 'Click into the "receiver" field' |
|
849 do: ( |
|
850 moveTo: ReceiverEditor |
|
851 click: ReceiverEditor |
|
852 ) |
|
853 showing: 'Enter a value (or expression) into "receiver" field' |
|
854 do: ( |
|
855 enter: '100' |
|
856 ) |
|
857 showing: 'Click into the "first argument" field' |
|
858 do: ( |
|
859 moveTo: Arg1Editor |
|
860 click: ReceiverEditor |
|
861 ) |
|
862 showing: 'Enter a value (or expression) into "receiver" field' |
|
863 do: ( |
|
864 enter: '100' |
|
865 ) |
|
866 ) |
|
867 END" |
|
868 |
671 "Created: / 19-07-2019 / 10:54:04 / Claus Gittinger" |
869 "Created: / 19-07-2019 / 10:54:04 / Claus Gittinger" |
672 "Modified: / 19-07-2019 / 14:53:15 / Claus Gittinger" |
870 "Modified: / 19-07-2019 / 15:35:15 / Claus Gittinger" |
673 ! ! |
871 ! ! |
674 |
872 |
675 !ShowMeHowItWorks class methodsFor:'documentation'! |
873 !ShowMeHowItWorks class methodsFor:'documentation'! |
676 |
874 |
677 version_CVS |
875 version_CVS |