|
1 "{ Package: 'stx:libtool2' }" |
|
2 |
|
3 "{ NameSpace: Tools }" |
|
4 |
|
5 ApplicationModel subclass:#ViewTreeApplication |
|
6 instanceVariableNames:'model treeView hasSingleSelectionHolder clickedItem clickedPoint |
|
7 motionAction infoChannel testModeChannel process |
|
8 followFocusChannel' |
|
9 classVariableNames:'' |
|
10 poolDictionaries:'' |
|
11 category:'A-Views-Support' |
|
12 ! |
|
13 |
|
14 Object subclass:#MenuDesc |
|
15 instanceVariableNames:'title value action' |
|
16 classVariableNames:'' |
|
17 poolDictionaries:'' |
|
18 privateIn:ViewTreeApplication |
|
19 ! |
|
20 |
|
21 !ViewTreeApplication class methodsFor:'documentation'! |
|
22 |
|
23 documentation |
|
24 " |
|
25 Small application showing a ViewTreeModel use. |
|
26 |
|
27 It displays a hierarchical list of a selected TopView and |
|
28 all its contained subViews. |
|
29 Useful to have a look at subcomponents - to see how views |
|
30 are structured. |
|
31 |
|
32 |
|
33 [Instance variables:] |
|
34 model <ViewTreeModel> the used ViewTreeModel |
|
35 clickedItem <ViewTreeItem> item under the clickedPoint (motion action) |
|
36 clickedPoint <Point> point where the motion action started from. |
|
37 motionAction <Action> (oneArg-) action called durring buttonMotion. |
|
38 |
|
39 |
|
40 [author:] |
|
41 Claus Atzkern |
|
42 |
|
43 [see also:] |
|
44 ViewTreeModel |
|
45 ViewTreeItem |
|
46 " |
|
47 ! ! |
|
48 |
|
49 !ViewTreeApplication class methodsFor:'initialization'! |
|
50 |
|
51 initialize |
|
52 "add myself to the launcher menu |
|
53 " |
|
54 self installInLauncher. |
|
55 ! |
|
56 |
|
57 installInLauncher |
|
58 "add myself to the launcher menu |
|
59 " |
|
60 |menuItem icon| |
|
61 |
|
62 NewLauncher isNil ifTrue:[^ self]. |
|
63 |
|
64 icon := ToolbarIconLibrary inspectLocals20x20Icon magnifiedTo:28@28. |
|
65 |
|
66 menuItem := MenuItem new |
|
67 label: 'View Inspector'; |
|
68 value: [ ViewTreeApplication open]; |
|
69 isButton: true; |
|
70 icon: icon; |
|
71 nameKey: #viewInspect. |
|
72 |
|
73 menuItem startGroup:#right. |
|
74 NewLauncher addMenuItem:menuItem in:'toolbar' |
|
75 position:#( #before #help) |
|
76 space:false. |
|
77 |
|
78 " |
|
79 self installInLauncher |
|
80 self removeFromLauncher |
|
81 " |
|
82 ! |
|
83 |
|
84 postAutoload |
|
85 "add myself to the launcher menu |
|
86 " |
|
87 self installInLauncher. |
|
88 " |
|
89 self installInLauncher |
|
90 self removeFromLauncher |
|
91 " |
|
92 ! |
|
93 |
|
94 removeFromLauncher |
|
95 "remove myself from the launcher menu |
|
96 " |
|
97 NewLauncher isNil ifTrue:[^ self]. |
|
98 NewLauncher removeUserTool:#viewInspect |
|
99 |
|
100 " |
|
101 self installInLauncher |
|
102 self removeFromLauncher |
|
103 " |
|
104 ! |
|
105 |
|
106 unload |
|
107 "class is about to be unloaded - remove myself from the launcher menu |
|
108 " |
|
109 self removeFromLauncher. |
|
110 super unload. |
|
111 ! ! |
|
112 |
|
113 !ViewTreeApplication class methodsFor:'interface specs'! |
|
114 |
|
115 windowSpec |
|
116 "This resource specification was automatically generated |
|
117 by the UIPainter of ST/X." |
|
118 |
|
119 "Do not manually edit this!! If it is corrupted, |
|
120 the UIPainter may not be able to read the specification." |
|
121 |
|
122 " |
|
123 UIPainter new openOnClass:ViewTreeApplication andSelector:#windowSpec |
|
124 ViewTreeApplication new openInterface:#windowSpec |
|
125 ViewTreeApplication open |
|
126 " |
|
127 |
|
128 <resource: #canvas> |
|
129 |
|
130 ^ |
|
131 #(FullSpec |
|
132 name: windowSpec |
|
133 window: |
|
134 (WindowSpec |
|
135 label: 'ViewTreeInspector' |
|
136 name: 'ViewTreeInspector' |
|
137 min: (Point 10 10) |
|
138 max: (Point 1024 9999) |
|
139 bounds: (Rectangle 0 0 325 654) |
|
140 menu: menu |
|
141 ) |
|
142 component: |
|
143 (SpecCollection |
|
144 collection: ( |
|
145 (MenuPanelSpec |
|
146 name: 'toolbarMenu' |
|
147 layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0) |
|
148 menu: toolbarMenu |
|
149 textDefault: true |
|
150 ) |
|
151 (HierarchicalListViewSpec |
|
152 name: 'List' |
|
153 layout: (LayoutFrame 0 0.0 32 0.0 0 1.0 -24 1.0) |
|
154 level: 1 |
|
155 model: model |
|
156 menu: middleButtonMenu |
|
157 hasHorizontalScrollBar: true |
|
158 hasVerticalScrollBar: true |
|
159 miniScrollerHorizontal: true |
|
160 miniScrollerVertical: false |
|
161 backgroundColor: (Color 49.999237048905 49.999237048905 100.0) |
|
162 listModel: listOfItems |
|
163 multipleSelectOk: true |
|
164 useIndex: false |
|
165 highlightMode: label |
|
166 doubleClickSelector: doubleClicked: |
|
167 valueChangeSelector: selectionChanged |
|
168 showLeftIndicators: false |
|
169 indicatorSelector: indicatorClicked: |
|
170 useDefaultIcons: false |
|
171 postBuildCallback: postBuildTree: |
|
172 ) |
|
173 (LabelSpec |
|
174 name: 'infoChannel' |
|
175 layout: (LayoutFrame 0 0.0 -24 1.0 0 1.0 0 1.0) |
|
176 level: 1 |
|
177 translateLabel: true |
|
178 labelChannel: infoChannel |
|
179 adjust: left |
|
180 ) |
|
181 ) |
|
182 |
|
183 ) |
|
184 ) |
|
185 ! ! |
|
186 |
|
187 !ViewTreeApplication class methodsFor:'menu specs'! |
|
188 |
|
189 menu |
|
190 "This resource specification was automatically generated |
|
191 by the MenuEditor of ST/X." |
|
192 |
|
193 "Do not manually edit this!! If it is corrupted, |
|
194 the MenuEditor may not be able to read the specification." |
|
195 |
|
196 " |
|
197 MenuEditor new openOnClass:ViewTreeApplication andSelector:#menu |
|
198 (Menu new fromLiteralArrayEncoding:(ViewTreeApplication menu)) startUp |
|
199 " |
|
200 |
|
201 <resource: #menu> |
|
202 |
|
203 ^ |
|
204 #(Menu |
|
205 ( |
|
206 (MenuItem |
|
207 label: 'File' |
|
208 translateLabel: true |
|
209 submenu: |
|
210 (Menu |
|
211 ( |
|
212 (MenuItem |
|
213 label: 'Pick a View' |
|
214 itemValue: doPickViews |
|
215 translateLabel: true |
|
216 ) |
|
217 (MenuItem |
|
218 enabled: hasPickedView |
|
219 label: 'Release Picked View' |
|
220 itemValue: doUnpick |
|
221 translateLabel: true |
|
222 ) |
|
223 (MenuItem |
|
224 label: '-' |
|
225 ) |
|
226 (MenuItem |
|
227 label: 'Exit' |
|
228 itemValue: closeRequest |
|
229 translateLabel: true |
|
230 ) |
|
231 ) |
|
232 nil |
|
233 nil |
|
234 ) |
|
235 ) |
|
236 (MenuItem |
|
237 label: '' |
|
238 ) |
|
239 (MenuItem |
|
240 enabled: hasSingleSelectionHolder |
|
241 label: 'Menu' |
|
242 translateLabel: true |
|
243 submenuChannel: middleButtonMenu |
|
244 ) |
|
245 (MenuItem |
|
246 label: 'Components' |
|
247 translateLabel: true |
|
248 startGroup: right |
|
249 submenuChannel: submenuComponents: |
|
250 ) |
|
251 (MenuItem |
|
252 label: 'Applications' |
|
253 translateLabel: true |
|
254 submenuChannel: submenuApplications: |
|
255 ) |
|
256 ) |
|
257 nil |
|
258 nil |
|
259 ) |
|
260 ! |
|
261 |
|
262 middleButtonMenu |
|
263 "This resource specification was automatically generated |
|
264 by the MenuEditor of ST/X." |
|
265 |
|
266 "Do not manually edit this!! If it is corrupted, |
|
267 the MenuEditor may not be able to read the specification." |
|
268 |
|
269 " |
|
270 MenuEditor new openOnClass:ViewTreeApplication andSelector:#middleButtonMenu |
|
271 (Menu new fromLiteralArrayEncoding:(ViewTreeApplication middleButtonMenu)) startUp |
|
272 " |
|
273 |
|
274 <resource: #menu> |
|
275 |
|
276 ^ |
|
277 #(Menu |
|
278 ( |
|
279 (MenuItem |
|
280 label: 'Geometry' |
|
281 translateLabel: true |
|
282 submenuChannel: submenuGeometry: |
|
283 keepLinkedMenu: true |
|
284 ) |
|
285 (MenuItem |
|
286 label: 'Interface' |
|
287 translateLabel: true |
|
288 submenuChannel: submenuInterface: |
|
289 keepLinkedMenu: true |
|
290 ) |
|
291 (MenuItem |
|
292 label: 'Visibility' |
|
293 translateLabel: true |
|
294 submenuChannel: submenuVisibility: |
|
295 keepLinkedMenu: true |
|
296 ) |
|
297 (MenuItem |
|
298 label: '-' |
|
299 ) |
|
300 (MenuItem |
|
301 label: 'Browse View Class' |
|
302 itemValue: doBrowse: |
|
303 translateLabel: true |
|
304 argument: view |
|
305 ) |
|
306 (MenuItem |
|
307 label: 'Browse Model Class' |
|
308 itemValue: doBrowse: |
|
309 translateLabel: true |
|
310 isVisible: hasModel |
|
311 argument: model |
|
312 ) |
|
313 (MenuItem |
|
314 label: 'Browse Application Class' |
|
315 itemValue: doBrowse: |
|
316 translateLabel: true |
|
317 isVisible: hasApplication |
|
318 argument: application |
|
319 ) |
|
320 (MenuItem |
|
321 label: 'Browse Controller Class' |
|
322 itemValue: doBrowse: |
|
323 translateLabel: true |
|
324 isVisible: hasController |
|
325 argument: controller |
|
326 ) |
|
327 (MenuItem |
|
328 label: '-' |
|
329 ) |
|
330 (MenuItem |
|
331 label: 'Inspect View' |
|
332 itemValue: doInspect: |
|
333 translateLabel: true |
|
334 argument: view |
|
335 ) |
|
336 (MenuItem |
|
337 label: 'Inspect Window Group' |
|
338 itemValue: doInspect: |
|
339 translateLabel: true |
|
340 argument: group |
|
341 ) |
|
342 (MenuItem |
|
343 label: 'Inspect Model' |
|
344 itemValue: doInspect: |
|
345 translateLabel: true |
|
346 isVisible: hasModel |
|
347 argument: model |
|
348 ) |
|
349 (MenuItem |
|
350 label: 'Inspect Application' |
|
351 itemValue: doInspect: |
|
352 translateLabel: true |
|
353 isVisible: hasApplication |
|
354 argument: application |
|
355 ) |
|
356 (MenuItem |
|
357 label: 'Inspect Controller' |
|
358 itemValue: doInspect: |
|
359 translateLabel: true |
|
360 isVisible: hasController |
|
361 argument: controller |
|
362 ) |
|
363 (MenuItem |
|
364 label: '-' |
|
365 ) |
|
366 (MenuItem |
|
367 label: 'Flash' |
|
368 itemValue: doFlash |
|
369 translateLabel: true |
|
370 ) |
|
371 (MenuItem |
|
372 label: '-' |
|
373 ) |
|
374 (MenuItem |
|
375 label: 'Destroy' |
|
376 itemValue: doDestroy |
|
377 translateLabel: true |
|
378 ) |
|
379 (MenuItem |
|
380 label: '-' |
|
381 ) |
|
382 (MenuItem |
|
383 label: 'Instance Variables' |
|
384 translateLabel: true |
|
385 submenuChannel: submenuInspector: |
|
386 keepLinkedMenu: true |
|
387 ) |
|
388 (MenuItem |
|
389 label: '=' |
|
390 ) |
|
391 (MenuItem |
|
392 label: '' |
|
393 ) |
|
394 (MenuItem |
|
395 enabled: selectedComponentHasChildren |
|
396 label: 'Applications' |
|
397 nameKey: single |
|
398 translateLabel: true |
|
399 submenuChannel: submenuApplications: |
|
400 keepLinkedMenu: true |
|
401 ) |
|
402 (MenuItem |
|
403 enabled: selectedComponentHasChildren |
|
404 label: 'Components' |
|
405 nameKey: single |
|
406 translateLabel: true |
|
407 submenuChannel: submenuComponents: |
|
408 keepLinkedMenu: true |
|
409 ) |
|
410 ) |
|
411 nil |
|
412 nil |
|
413 ) |
|
414 ! |
|
415 |
|
416 toolbarMenu |
|
417 "This resource specification was automatically generated |
|
418 by the MenuEditor of ST/X." |
|
419 |
|
420 "Do not manually edit this!! If it is corrupted, |
|
421 the MenuEditor may not be able to read the specification." |
|
422 |
|
423 " |
|
424 MenuEditor new openOnClass:ViewTreeApplication andSelector:#toolbarMenu |
|
425 (Menu new fromLiteralArrayEncoding:(ViewTreeApplication toolbarMenu)) startUp |
|
426 " |
|
427 |
|
428 <resource: #menu> |
|
429 |
|
430 ^ |
|
431 #(Menu |
|
432 ( |
|
433 (MenuItem |
|
434 label: 'Test Mode' |
|
435 translateLabel: true |
|
436 indication: testModeChannel |
|
437 ) |
|
438 (MenuItem |
|
439 enabled: testModeChannel |
|
440 label: 'Follow Focus' |
|
441 translateLabel: true |
|
442 indication: followFocusChannel |
|
443 ) |
|
444 (MenuItem |
|
445 label: 'Select On Click' |
|
446 translateLabel: true |
|
447 indication: selectOnClickHolder |
|
448 ) |
|
449 ) |
|
450 nil |
|
451 nil |
|
452 ) |
|
453 ! ! |
|
454 |
|
455 !ViewTreeApplication methodsFor:'actions'! |
|
456 |
|
457 doubleClicked:anIndex |
|
458 self doInspect:#view. |
|
459 ! |
|
460 |
|
461 indicatorClicked:anIndex |
|
462 |item sensor| |
|
463 |
|
464 item := model listOfItems at:anIndex ifAbsent:nil. |
|
465 |
|
466 item notNil ifTrue:[ |
|
467 ( (sensor := self window sensor) notNil |
|
468 and:[(sensor ctrlDown or:[sensor shiftDown])] |
|
469 ) ifTrue:[ |
|
470 item recursiveToggleExpand |
|
471 ] ifFalse:[ |
|
472 item toggleExpand |
|
473 ] |
|
474 ]. |
|
475 ! ! |
|
476 |
|
477 !ViewTreeApplication methodsFor:'aspects'! |
|
478 |
|
479 followFocusChannel |
|
480 "boolean holder, which indicates whether selection changed dependend on the focus view |
|
481 " |
|
482 ^ followFocusChannel |
|
483 ! |
|
484 |
|
485 hasSingleSelectionHolder |
|
486 "boolean holder, true if one item is selected |
|
487 " |
|
488 ^ hasSingleSelectionHolder |
|
489 ! |
|
490 |
|
491 infoChannel |
|
492 "channel, which keeps a printable information |
|
493 " |
|
494 ^ infoChannel |
|
495 ! |
|
496 |
|
497 listOfItems |
|
498 "returns the hierarchical list of items |
|
499 " |
|
500 ^ model listOfItems |
|
501 ! |
|
502 |
|
503 model |
|
504 "returns my selection model, a ViewTreeModel |
|
505 " |
|
506 ^ model |
|
507 ! |
|
508 |
|
509 selectOnClickHolder |
|
510 "boolean holder, which indicates whether the selection will change on click |
|
511 " |
|
512 ^ model selectOnClickHolder |
|
513 ! |
|
514 |
|
515 testModeChannel |
|
516 "boolean holder, which indicates whether running in test or edit mode (eat input events) |
|
517 " |
|
518 ^ testModeChannel |
|
519 ! ! |
|
520 |
|
521 !ViewTreeApplication methodsFor:'change & update'! |
|
522 |
|
523 selectionChanged |
|
524 "called if the selection changed |
|
525 " |
|
526 |info view item| |
|
527 |
|
528 item := model selectedItem. |
|
529 |
|
530 item notNil ifTrue:[ |state| |
|
531 view := item widget. |
|
532 |
|
533 view id isNil ifTrue:[ |
|
534 state := 'no ID'. |
|
535 ] ifFalse:[ |
|
536 view shown ifTrue:[ |
|
537 state := 'visible'. |
|
538 ] ifFalse:[ |
|
539 state := 'invisible' |
|
540 ]. |
|
541 ]. |
|
542 info := '%1 [%2] - %3' bindWith:(view class name) |
|
543 with:(view name ? '') with:state allBold. |
|
544 |
|
545 ] ifFalse:[ |
|
546 info := '' |
|
547 ]. |
|
548 hasSingleSelectionHolder value:(view notNil). |
|
549 infoChannel value:info. |
|
550 ! |
|
551 |
|
552 update:something with:someArgument from:aModel |
|
553 |
|
554 aModel == testModeChannel ifTrue:[ |
|
555 model testMode:(testModeChannel value). |
|
556 ^ self |
|
557 ]. |
|
558 super update:something with:someArgument from:aModel. |
|
559 ! ! |
|
560 |
|
561 !ViewTreeApplication methodsFor:'event processing'! |
|
562 |
|
563 processButtonMotionEvent:ev |
|
564 "handle a button motion event |
|
565 " |
|
566 |click| |
|
567 |
|
568 motionAction notNil ifTrue:[ |
|
569 click := ev view sensor mousePoint. |
|
570 |
|
571 click = clickedPoint ifFalse:[ |
|
572 (clickedItem isNil or:[(click dist:clickedPoint) > 5.0]) ifTrue:[ |
|
573 motionAction value:click |
|
574 ] |
|
575 ] |
|
576 ]. |
|
577 ! |
|
578 |
|
579 processButtonPressEvent:ev |
|
580 "handle a buttopn press event |
|
581 " |
|
582 |sensor lastRectangle| |
|
583 |
|
584 sensor := model rootView sensor. |
|
585 clickedItem := model listOfItems detectItemRespondsToView:(ev view). |
|
586 |
|
587 (sensor ctrlDown or:[sensor shiftDown]) ifTrue:[ |
|
588 clickedItem notNil ifTrue:[ |
|
589 self selectOnClickHolder value ifTrue:[ |
|
590 model toggleSelectItem:clickedItem |
|
591 ]. |
|
592 ]. |
|
593 clickedItem := motionAction := nil. |
|
594 ] ifFalse:[ |
|
595 clickedPoint := ev view sensor mousePoint. |
|
596 lastRectangle := nil. |
|
597 |
|
598 motionAction :=[:p| |rootView| |
|
599 rootView := model rootView device rootView. |
|
600 clickedItem := nil. |
|
601 |
|
602 rootView xoring:[ |
|
603 lastRectangle notNil ifTrue:[ rootView displayRectangle:lastRectangle ] |
|
604 ifFalse:[ rootView clippedByChildren:false ]. |
|
605 |
|
606 p isNil ifTrue:[ |
|
607 rootView clippedByChildren:true. |
|
608 motionAction := nil. |
|
609 ] ifFalse:[ |
|
610 lastRectangle := Rectangle origin:(clickedPoint min:p) corner:(clickedPoint max:p). |
|
611 rootView displayRectangle:lastRectangle. |
|
612 ]. |
|
613 rootView flush. |
|
614 ]. |
|
615 lastRectangle |
|
616 ] |
|
617 ] |
|
618 ! |
|
619 |
|
620 processButtonReleaseEvent:anEvent |
|
621 "handle a button release event |
|
622 " |
|
623 |rootView rectangle newItems widget origin| |
|
624 |
|
625 motionAction isNil ifTrue:[ ^ self ]. |
|
626 clickedItem notNil ifTrue:[ ^ model selectItem:clickedItem ]. |
|
627 |
|
628 (rectangle := motionAction value:nil) notNil ifTrue:[ |
|
629 rootView := model rootView device rootView. |
|
630 newItems := OrderedCollection new. |
|
631 |
|
632 model rootItem recursiveDo:[:anItem| |
|
633 widget := anItem widget. |
|
634 origin := widget originRelativeTo:rootView. |
|
635 |
|
636 (rectangle containsRect:(Rectangle origin:origin extent:(widget extent))) ifTrue:[ |
|
637 newItems add:anItem. |
|
638 ] |
|
639 ]. |
|
640 model value:newItems. |
|
641 ]. |
|
642 ! |
|
643 |
|
644 processEvent:anEvent |
|
645 "process an event |
|
646 " |
|
647 |button menu| |
|
648 |
|
649 anEvent isKeyPressEvent ifTrue:[ ^ self processKeyPressEvent:anEvent ]. |
|
650 anEvent isButtonEvent ifFalse:[ ^ self ]. |
|
651 |
|
652 button := anEvent button. |
|
653 |
|
654 (button == 2 or:[button == #menu]) ifTrue:[ |
|
655 motionAction isNil ifTrue:[ |
|
656 anEvent isButtonPressEvent ifTrue:[ |
|
657 self selectOnClickHolder value ifTrue:[ |
|
658 menu := self middleButtonMenu value. |
|
659 menu notNil ifTrue:[ |
|
660 menu := MenuPanel menu:(Menu new fromLiteralArrayEncoding:menu) |
|
661 receiver:self. |
|
662 menu startUp. |
|
663 ] |
|
664 ]. |
|
665 ]. |
|
666 clickedItem := nil. |
|
667 ]. |
|
668 ^ self |
|
669 ]. |
|
670 |
|
671 anEvent isButtonPressEvent ifTrue:[ ^ self processButtonPressEvent:anEvent ]. |
|
672 anEvent isButtonMotionEvent ifTrue:[ ^ self processButtonMotionEvent:anEvent ]. |
|
673 |
|
674 anEvent isButtonReleaseEvent ifTrue:[ |
|
675 self selectOnClickHolder value ifTrue:[ |
|
676 self processButtonReleaseEvent:anEvent |
|
677 ]. |
|
678 ]. |
|
679 clickedItem := motionAction := nil. |
|
680 |
|
681 anEvent type == #'buttonMultiPress:x:y:' ifTrue:[ |
|
682 self selectOnClickHolder value ifTrue:[ |
|
683 self doInspect:#view. |
|
684 ]. |
|
685 ]. |
|
686 ! |
|
687 |
|
688 processKeyPressEvent:anEvent |
|
689 "process an key press event |
|
690 " |
|
691 |item prnt idx key max next| |
|
692 |
|
693 key := anEvent key. |
|
694 key isSymbol ifFalse:[^ self]. |
|
695 |
|
696 key == #Delete ifTrue:[ ^ self doDestroy ]. |
|
697 key == #InspectIt ifTrue:[ ^ self doInspect:#view ]. |
|
698 |
|
699 ( key == #CursorUp |
|
700 or:[key == #CursorDown |
|
701 or:[key == #CursorLeft |
|
702 or:[key == #CursorRight]]] |
|
703 ) ifFalse:[ |
|
704 ^ self |
|
705 ]. |
|
706 item := model selectedItem. |
|
707 |
|
708 item isNil ifTrue:[ |
|
709 ^ model selectedItem:(model first ? model rootItem) |
|
710 ]. |
|
711 |
|
712 prnt := item parent. |
|
713 prnt isNil ifTrue:[ |
|
714 "/ is the root item |
|
715 (key == #CursorUp or:[key == #CursorLeft]) ifTrue:[item := model listOfItems last] |
|
716 ifFalse:[item := item at:1 ifAbsent:item]. |
|
717 |
|
718 ^ model selectedItem:item |
|
719 ]. |
|
720 key == #CursorLeft ifTrue:[ ^ model selectedItem:prnt ]. |
|
721 |
|
722 key == #CursorRight ifTrue:[ |
|
723 next := item at:1 ifAbsent:nil. |
|
724 next notNil ifTrue:[ model selectedItem:next ]. |
|
725 ^ self |
|
726 ]. |
|
727 |
|
728 max := prnt size. |
|
729 |
|
730 key == #CursorUp ifTrue:[ |
|
731 idx := prnt identityIndexOf:item. |
|
732 idx == 1 ifTrue:[idx := max + 1]. |
|
733 model selectedItem:(prnt at:idx - 1). |
|
734 ^ self. |
|
735 ]. |
|
736 |
|
737 key == #CursorDown ifTrue:[ |
|
738 idx := prnt identityIndexOf:item. |
|
739 idx == max ifTrue:[idx := 0]. |
|
740 model selectedItem:(prnt at:idx + 1). |
|
741 ^ self. |
|
742 ]. |
|
743 ! |
|
744 |
|
745 processMappedView:aView |
|
746 "process a mapped event |
|
747 " |
|
748 |parent anchor| |
|
749 |
|
750 parent := self listOfItems detectItemRespondsToView:aView. |
|
751 parent isNil ifTrue:[ ^ self ]. |
|
752 |
|
753 NotFoundSignal handle:[:ex| |
|
754 "contained subvies used by spec are not yet created; |
|
755 thus we have to wait until last used subview is build |
|
756 " |
|
757 anchor := nil. |
|
758 ] do:[ |
|
759 anchor := parent class buildViewsFrom:(parent widget). |
|
760 ]. |
|
761 anchor notNil ifTrue:[ |
|
762 parent updateFromChildren:anchor children. |
|
763 ]. |
|
764 ! ! |
|
765 |
|
766 !ViewTreeApplication methodsFor:'initialization & release'! |
|
767 |
|
768 closeDownViews |
|
769 "release the grapped application |
|
770 " |
|
771 process := nil. |
|
772 super closeDownViews. |
|
773 self doUnpick. |
|
774 ! |
|
775 |
|
776 initialize |
|
777 "setup my model and channels |
|
778 " |
|
779 super initialize. |
|
780 |
|
781 infoChannel := '' asValue. |
|
782 hasSingleSelectionHolder := false asValue. |
|
783 followFocusChannel := false asValue. |
|
784 |
|
785 model := ViewTreeModel new. |
|
786 model inputEventAction:[:ev| self processEvent:ev ]. |
|
787 model mappedViewAction:[:vw| self processMappedView:vw ]. |
|
788 model application:self. |
|
789 |
|
790 testModeChannel := model testMode asValue. |
|
791 testModeChannel addDependent:self. |
|
792 ! |
|
793 |
|
794 postBuildTree:aTree |
|
795 treeView := aTree scrolledView. |
|
796 treeView hasConstantHeight:true. |
|
797 ! ! |
|
798 |
|
799 !ViewTreeApplication methodsFor:'menu queries'! |
|
800 |
|
801 hasApplication |
|
802 "returns true if the current selected view has an application |
|
803 " |
|
804 |view| |
|
805 |
|
806 view := self selectedView. |
|
807 ^ (view notNil and:[view application notNil]) |
|
808 ! |
|
809 |
|
810 hasController |
|
811 "returns true if the current selected item's view has a controller |
|
812 other than nil or the view itself |
|
813 " |
|
814 |view controller| |
|
815 |
|
816 view := self selectedView. |
|
817 |
|
818 view notNil ifTrue:[ |
|
819 controller := view controller. |
|
820 ^ (controller notNil and:[controller ~~ view]) |
|
821 ]. |
|
822 ^ false |
|
823 ! |
|
824 |
|
825 hasModel |
|
826 "returns true if the current selected view has a model |
|
827 " |
|
828 |view| |
|
829 |
|
830 view := self selectedView. |
|
831 ^ (view notNil and:[view model notNil]) |
|
832 ! |
|
833 |
|
834 hasPickedView |
|
835 "returns true if a view is picked |
|
836 " |
|
837 ^ model rootItem notNil |
|
838 ! ! |
|
839 |
|
840 !ViewTreeApplication methodsFor:'menu specs'! |
|
841 |
|
842 middleButtonMenu |
|
843 "returns the middleButton menu for the single selected item or nil |
|
844 " |
|
845 ^ [ model selectedItem notNil ifTrue:[self class middleButtonMenu] |
|
846 ifFalse:[nil] |
|
847 ] |
|
848 ! |
|
849 |
|
850 submenuApplications:aMenu |
|
851 |applications menu item list addBlock| |
|
852 |
|
853 item := aMenu selection nameKey == #single ifTrue:[model selectedItem] |
|
854 ifFalse:[model rootItem]. |
|
855 item isNil ifTrue:[^ nil]. |
|
856 |
|
857 applications := IdentityDictionary new. |
|
858 |
|
859 addBlock := [:el| |cls ctr| |
|
860 cls := self resolveApplicationClassFor:el. |
|
861 |
|
862 cls notNil ifTrue:[ |
|
863 ctr := applications at:cls ifAbsent:0. |
|
864 applications at:cls put:(ctr + 1). |
|
865 ]. |
|
866 ]. |
|
867 item recursiveDo:addBlock. |
|
868 addBlock value:item. |
|
869 |
|
870 applications isEmpty ifTrue:[^ nil ]. |
|
871 list := SortedCollection sortBlock:[:a :b| a title < b title ]. |
|
872 |
|
873 applications keysAndValuesDo:[:cls :ctr| |
|
874 list add:(MenuDesc title:(cls name) |
|
875 value:(ctr printString) |
|
876 action:[self doSelectNextOfApplicationClass:cls startingIn:item] |
|
877 ). |
|
878 ]. |
|
879 |
|
880 menu := MenuDesc buildFromList:list onGC:aMenu. |
|
881 menu do:[:el| |
|
882 el hideMenuOnActivated:false |
|
883 ]. |
|
884 ^ menu |
|
885 ! |
|
886 |
|
887 submenuComponents:aMenu |
|
888 |widgets list total menu item| |
|
889 |
|
890 item := aMenu selection nameKey == #single ifTrue:[model selectedItem] |
|
891 ifFalse:[model rootItem]. |
|
892 item isNil ifTrue:[^ nil]. |
|
893 |
|
894 widgets := IdentityDictionary new. |
|
895 total := 0. |
|
896 |
|
897 item recursiveDo:[:el| |cls ctr| |
|
898 cls := el widget. |
|
899 |
|
900 cls notNil ifTrue:[ |
|
901 cls := cls class. |
|
902 ctr := widgets at:cls ifAbsent:0. |
|
903 widgets at:cls put:(ctr + 1). |
|
904 total := total + 1. |
|
905 ]. |
|
906 ]. |
|
907 total == 0 ifTrue:[^ nil]. |
|
908 list := SortedCollection sortBlock:[:a :b| a title < b title ]. |
|
909 |
|
910 widgets keysAndValuesDo:[:cls :ctr| |
|
911 list add:(MenuDesc title:(cls name) |
|
912 value:(ctr printString) |
|
913 action:[self doSelectNextOfClass:cls startingIn:item] |
|
914 ). |
|
915 ]. |
|
916 list := list asOrderedCollection. |
|
917 list add:(MenuDesc separator). |
|
918 list add:(MenuDesc title:'Total' value:(total printString)). |
|
919 menu := MenuDesc buildFromList:list onGC:aMenu. |
|
920 menu do:[:el| |
|
921 el hideMenuOnActivated:false |
|
922 ]. |
|
923 ^ menu |
|
924 ! |
|
925 |
|
926 submenuGeometry:aMenu |
|
927 "builds and returns the geometry submenu |
|
928 " |
|
929 |view point inst list x y| |
|
930 |
|
931 view := self selectedView. |
|
932 view isNil ifTrue:[^ nil]. |
|
933 |
|
934 list := OrderedCollection new. |
|
935 |
|
936 "/ origin |
|
937 point := view relativeOrigin. |
|
938 point isNil ifTrue:[ point := view origin ]. |
|
939 |
|
940 x := view left. |
|
941 y := view top. |
|
942 |
|
943 (x == point x and:[y == point y]) ifTrue:[ inst := point ] |
|
944 ifFalse:[ inst := '%1 --> (%2@%3)' bindWith:point with:x with:y ]. |
|
945 |
|
946 list add:(MenuDesc title:'origin' value:inst). |
|
947 |
|
948 "/ corner |
|
949 point := view relativeCorner. |
|
950 point isNil ifTrue:[ point := view corner ]. |
|
951 |
|
952 x := view right. |
|
953 y := view bottom. |
|
954 |
|
955 (x == point x and:[y == point y]) ifTrue:[ inst := point ] |
|
956 ifFalse:[ inst := '%1 --> (%2@%3)' bindWith:point with:x with:y ]. |
|
957 |
|
958 list add:(MenuDesc title:'corner' value:inst). |
|
959 |
|
960 "/ extent |
|
961 (point := view relativeExtent) isNil ifTrue:[point := view extent]. |
|
962 list add:(MenuDesc title:'extent' value:point). |
|
963 |
|
964 "/ preferred extent |
|
965 list add:(MenuDesc title:'pref. extent' value:(view preferredExtent)). |
|
966 list add:(MenuDesc separator). |
|
967 |
|
968 "/ view insets |
|
969 inst := 'l:%1 r:%2 t:%3 b:%4' bindWith:(view leftInset) |
|
970 with:(view rightInset) |
|
971 with:(view topInset) |
|
972 with:(view bottomInset). |
|
973 |
|
974 list add:(MenuDesc title:'insets' value:inst). |
|
975 list add:(MenuDesc title:'borderWidth' value:(view borderWidth)). |
|
976 list add:(MenuDesc title:'level' value:(view level)). |
|
977 list add:(MenuDesc separator). |
|
978 |
|
979 (inst := view layout) notNil ifTrue:[ inst := inst displayString ]. |
|
980 list add:(MenuDesc title:'layout' value:inst). |
|
981 |
|
982 (inst := view transformation) notNil ifTrue:[ inst := inst displayString ]. |
|
983 list add:(MenuDesc title:'transformation' value:inst). |
|
984 |
|
985 ^ MenuDesc buildFromList:list onGC:aMenu |
|
986 ! |
|
987 |
|
988 submenuInspector:aMenu |
|
989 "builds and returns the inspector submenu |
|
990 " |
|
991 |view list n names label value| |
|
992 |
|
993 view := self selectedView. |
|
994 view isNil ifTrue:[^ nil]. |
|
995 |
|
996 n := view class instSize. |
|
997 n > 0 ifFalse:[^ nil ]. |
|
998 |
|
999 list := OrderedCollection new:n. |
|
1000 names := view class allInstVarNames. |
|
1001 |
|
1002 1 to:n do:[:i| |action| |
|
1003 label := (names at:i) printString. |
|
1004 value := view instVarAt:i. |
|
1005 value isNil ifTrue:[ |
|
1006 value := '------'. |
|
1007 action := nil. |
|
1008 ] ifFalse:[ |
|
1009 value := value displayString contractAtEndTo:40. |
|
1010 action := [(view instVarAt:i) inspect]. |
|
1011 ]. |
|
1012 list add:(MenuDesc title:label value:value action:action). |
|
1013 ]. |
|
1014 |
|
1015 ^ MenuDesc buildFromList:list onGC:aMenu |
|
1016 ! |
|
1017 |
|
1018 submenuInterface:aMenu |
|
1019 "builds and returns the interface submenu |
|
1020 " |
|
1021 |view label inst value list| |
|
1022 |
|
1023 view := self selectedView. |
|
1024 view isNil ifTrue:[^ nil]. |
|
1025 |
|
1026 list := OrderedCollection new. |
|
1027 |
|
1028 inst := view controller. |
|
1029 value := nil. |
|
1030 |
|
1031 inst isNil ifTrue:[ |
|
1032 label := nil |
|
1033 ] ifFalse:[ |
|
1034 inst == view ifTrue:[ label := '== view itself' ] |
|
1035 ifFalse:[ label := inst displayString. |
|
1036 value := [view controller inspect]. |
|
1037 ]. |
|
1038 ]. |
|
1039 list add:(MenuDesc title:'controller' value:label action:value). |
|
1040 |
|
1041 inst := view delegate. |
|
1042 inst notNil ifTrue:[ |
|
1043 list add:(MenuDesc title:'delegate' value:(inst displayString) action:[ view delegate inspect ]). |
|
1044 ]. |
|
1045 |
|
1046 inst := view application. |
|
1047 |
|
1048 inst notNil ifTrue:[ |topAppl| |
|
1049 list add:(MenuDesc title:'application' value:inst action:[ view application inspect ]). |
|
1050 |
|
1051 topAppl := inst topApplication. |
|
1052 |
|
1053 (topAppl notNil and:[topAppl ~~ inst]) ifTrue:[ |
|
1054 list add:(MenuDesc title:'topApplication' value:topAppl action:[ inst topApplication inspect ]). |
|
1055 ]. |
|
1056 ]. |
|
1057 list add:(MenuDesc separator). |
|
1058 |
|
1059 (view respondsTo:#'model:') ifTrue:[ |
|
1060 inst := model. |
|
1061 |
|
1062 inst isNil ifTrue:[ label := value := nil ] |
|
1063 ifFalse:[ label := inst displayString. |
|
1064 value := [ view model inspect ]. |
|
1065 ]. |
|
1066 |
|
1067 list add:(MenuDesc title:'model' value:label action:value). |
|
1068 |
|
1069 (inst notNil and:[view respondsTo:#modelInterface]) ifTrue:[ |
|
1070 view modelInterface keysAndValuesDo:[:key : val| |
|
1071 val isNil ifTrue:[ label := nil ] |
|
1072 ifFalse:[ label := val displayString ]. |
|
1073 |
|
1074 list add:(MenuDesc title:(' - ', key) value:label ). |
|
1075 ] |
|
1076 ]. |
|
1077 ]. |
|
1078 |
|
1079 (view respondsTo:#enableChannel) ifTrue:[ |
|
1080 inst := view enableChannel. |
|
1081 |
|
1082 inst isNil ifTrue:[ label := value := nil ] |
|
1083 ifFalse:[ label := inst displayString. |
|
1084 value := [ view enableChannel inspect ]. |
|
1085 ]. |
|
1086 |
|
1087 list add:(MenuDesc title:'enableChannel' value:label action:value). |
|
1088 ]. |
|
1089 |
|
1090 list last isSeparator ifFalse:[ list add:(MenuDesc separator) ]. |
|
1091 |
|
1092 (view respondsTo:#listHolder) ifTrue:[ |
|
1093 inst := view listHolder. |
|
1094 |
|
1095 inst isNil ifTrue:[ label := value := nil ] |
|
1096 ifFalse:[ label := inst class printString. |
|
1097 value := [ view listHolder inspect ]. |
|
1098 ]. |
|
1099 list add:(MenuDesc title:'listHolder' value:label action:value). |
|
1100 ]. |
|
1101 |
|
1102 (view respondsTo:#list) ifTrue:[ |
|
1103 inst := view list. |
|
1104 |
|
1105 inst isNil ifTrue:[ label := value := nil ] |
|
1106 ifFalse:[ label := '%1 [%2]' bindWith:(inst class printString) with:(inst size). |
|
1107 value := [ view list inspect ]. |
|
1108 ]. |
|
1109 |
|
1110 list add:(MenuDesc title:'list' value:label action:value). |
|
1111 ]. |
|
1112 |
|
1113 list last isSeparator ifTrue:[ list removeLast ]. |
|
1114 ^ MenuDesc buildFromList:list onGC:aMenu |
|
1115 ! |
|
1116 |
|
1117 submenuVisibility:aMenu |
|
1118 "builds and returns the geometry submenu |
|
1119 " |
|
1120 |view list value| |
|
1121 |
|
1122 view := self selectedView. |
|
1123 view isNil ifTrue:[^ nil]. |
|
1124 |
|
1125 list := OrderedCollection new. |
|
1126 |
|
1127 list add:(MenuDesc title:'device' value:(view device printString)). |
|
1128 list add:(MenuDesc title:'drawableId' value:(view id)). |
|
1129 list add:(MenuDesc title:'gcId' value:(view gcId)). |
|
1130 |
|
1131 list add:(MenuDesc separator). |
|
1132 |
|
1133 list add:(MenuDesc title:'shown' value:(view shown)). |
|
1134 list add:(MenuDesc title:'realized' value:(view realized)). |
|
1135 |
|
1136 list add:(MenuDesc separator). |
|
1137 |
|
1138 list add:(MenuDesc title:'hiddenOnRealize' value:(view isHiddenOnRealize)). |
|
1139 |
|
1140 (value := view visibilityChannel) isNil ifTrue:[ |
|
1141 list add:(MenuDesc title:'visibilityChannel' value:'------'). |
|
1142 ] ifFalse:[ |
|
1143 list add:(MenuDesc title:'visibilityChannel' |
|
1144 value:(value displayString) |
|
1145 action:[view visibilityChannel inspect]). |
|
1146 ]. |
|
1147 |
|
1148 |
|
1149 ^ MenuDesc buildFromList:list onGC:aMenu |
|
1150 ! ! |
|
1151 |
|
1152 !ViewTreeApplication methodsFor:'private'! |
|
1153 |
|
1154 selectFocusView |
|
1155 |rootView focusItem focusView| |
|
1156 |
|
1157 rootView := model rootView. |
|
1158 |
|
1159 (rootView notNil and:[rootView shown]) ifTrue:[ |
|
1160 focusView := rootView windowGroup focusView. |
|
1161 ]. |
|
1162 focusView isNil ifTrue:[^ self ]. |
|
1163 |
|
1164 focusItem := model selectedItem. |
|
1165 |
|
1166 (focusItem notNil and:[focusItem widget == focusView]) ifTrue:[ |
|
1167 ^ self |
|
1168 ]. |
|
1169 focusItem := model listOfItems recursiveDetect:[:el| el widget == focusView ]. |
|
1170 |
|
1171 focusItem notNil ifTrue:[ |
|
1172 model selectItem:focusItem. |
|
1173 ]. |
|
1174 ! |
|
1175 |
|
1176 setRootItem:aRootItemOrNil |
|
1177 |theProcess| |
|
1178 |
|
1179 aRootItemOrNil isNil ifTrue:[ |
|
1180 process := nil. |
|
1181 ] ifFalse:[ |
|
1182 "/ expand tree to level 3 |
|
1183 aRootItemOrNil do:[:aRootChild| |
|
1184 aRootChild do:[:aSubChild| aSubChild expand ]. |
|
1185 aRootChild expand. |
|
1186 ]. |
|
1187 aRootItemOrNil expand. |
|
1188 |
|
1189 process isNil ifTrue:[ |
|
1190 theProcess := process := |
|
1191 Process for:[ |update| |
|
1192 |
|
1193 update := false. |
|
1194 |
|
1195 [process == theProcess] whileTrue:[ |
|
1196 Delay waitForSeconds:0.5. |
|
1197 |
|
1198 (treeView notNil and:[process == theProcess and:[treeView shown]]) ifTrue:[ |
|
1199 (self isInTestmode and:[followFocusChannel value == true]) ifTrue:[ |
|
1200 self selectFocusView. |
|
1201 ]. |
|
1202 update ifTrue:[ |
|
1203 self updateShownStatus. |
|
1204 ]. |
|
1205 update := update not. |
|
1206 ]. |
|
1207 ]. |
|
1208 |
|
1209 ] priority:8. |
|
1210 theProcess name:'ViewTreeApplication::Follow Focus'. |
|
1211 theProcess resume. |
|
1212 ]. |
|
1213 ]. |
|
1214 model rootItem:aRootItemOrNil. |
|
1215 ! |
|
1216 |
|
1217 updateShownStatus |
|
1218 |rootItem min max visState listIdx visY0 visY1 height damage| |
|
1219 |
|
1220 rootItem := model rootItem. |
|
1221 (rootItem notNil and:[rootItem widget shown]) ifFalse:[^ self]. |
|
1222 |
|
1223 max := 0. |
|
1224 min := 9999999. |
|
1225 |
|
1226 rootItem recursiveEachVisibleItemDo:[:anItem| |
|
1227 visState := (anItem widget shown). |
|
1228 |
|
1229 visState ~~ anItem isDrawnShown ifTrue:[ |
|
1230 anItem isDrawnShown:visState. |
|
1231 listIdx := treeView identityIndexOf:anItem. |
|
1232 |
|
1233 listIdx > 0 ifTrue:[ |
|
1234 max := max max:listIdx. |
|
1235 min := min min:listIdx. |
|
1236 ]. |
|
1237 ]. |
|
1238 ]. |
|
1239 max < min ifTrue:[^ self]. |
|
1240 max := max + 1. |
|
1241 |
|
1242 visY0 := (treeView yVisibleOfLine:min) max:0. |
|
1243 visY1 := (treeView yVisibleOfLine:max) min:(treeView height). |
|
1244 height := visY1 - visY0. |
|
1245 |
|
1246 height > 2 ifTrue:[ |
|
1247 treeView shown ifTrue:[ |
|
1248 damage := Rectangle left:0 top:visY0 width:(treeView width) height:height. |
|
1249 treeView invalidateDeviceRectangle:damage repairNow:false. |
|
1250 ]. |
|
1251 ]. |
|
1252 ! ! |
|
1253 |
|
1254 !ViewTreeApplication methodsFor:'queries'! |
|
1255 |
|
1256 isInTestmode |
|
1257 "returns true if running in test mode - no events eaten |
|
1258 " |
|
1259 ^ testModeChannel value == true |
|
1260 ! ! |
|
1261 |
|
1262 !ViewTreeApplication methodsFor:'selection'! |
|
1263 |
|
1264 selectedView |
|
1265 "returns the selected view or nil |
|
1266 " |
|
1267 |item| |
|
1268 |
|
1269 item := model selectedItem. |
|
1270 item notNil ifTrue:[ ^ item widget ]. |
|
1271 ^ nil |
|
1272 ! ! |
|
1273 |
|
1274 !ViewTreeApplication methodsFor:'testing'! |
|
1275 |
|
1276 resolveApplicationClassFor:aTreeItem |
|
1277 aTreeItem isApplicationClass ifTrue:[ |
|
1278 ^ aTreeItem applicationClass |
|
1279 ]. |
|
1280 ^ nil |
|
1281 ! |
|
1282 |
|
1283 selectedComponentHasChildren |
|
1284 |item| |
|
1285 |
|
1286 item := model selectedItem. |
|
1287 ^ (item notNil and:[item hasChildren]) |
|
1288 ! ! |
|
1289 |
|
1290 !ViewTreeApplication methodsFor:'user operations'! |
|
1291 |
|
1292 doBrowse:what |
|
1293 "open browser on: |
|
1294 #view browse class |
|
1295 #model browse model class |
|
1296 #application browse application class |
|
1297 #controller browse controller class |
|
1298 " |
|
1299 |view inst| |
|
1300 |
|
1301 view := self selectedView. |
|
1302 view isNil ifTrue:[^ self]. |
|
1303 |
|
1304 what == #view ifTrue:[ inst := view ] |
|
1305 ifFalse:[what == #model ifTrue:[ inst := view model ] |
|
1306 ifFalse:[what == #application ifTrue:[ inst := view application ] |
|
1307 ifFalse:[what == #controller ifTrue:[ inst := view controller ] |
|
1308 ifFalse:[ |
|
1309 ^ self |
|
1310 ]]]]. |
|
1311 |
|
1312 inst notNil ifTrue:[ |
|
1313 inst class browserClass openInClass:(inst class) selector:nil |
|
1314 ]. |
|
1315 ! |
|
1316 |
|
1317 doDestroy |
|
1318 "destroy the current selected view |
|
1319 " |
|
1320 |item parent| |
|
1321 |
|
1322 item := model selectedItem. |
|
1323 item isNil ifTrue:[ ^ self]. |
|
1324 |
|
1325 parent := item parent. |
|
1326 |
|
1327 parent isNil ifTrue:[ |
|
1328 "/ the root |
|
1329 model withSelectionHiddenDo:[item deleteAll]. |
|
1330 ^ self |
|
1331 ]. |
|
1332 |
|
1333 model withSelectionHiddenDo:[ |
|
1334 |idx nsel| |
|
1335 |
|
1336 idx := parent identityIndexOf:item. |
|
1337 |
|
1338 idx == parent size ifTrue:[ |
|
1339 nsel := parent at:(idx - 1) ifAbsent:parent |
|
1340 ] ifFalse:[ |
|
1341 nsel := parent at:(idx + 1) |
|
1342 ]. |
|
1343 model setValue:nil. |
|
1344 item delete. |
|
1345 |
|
1346 parent isLayoutContainer ifTrue:[ |
|
1347 parent widget sizeChanged:nil |
|
1348 ]. |
|
1349 model value:nsel. |
|
1350 ]. |
|
1351 ! |
|
1352 |
|
1353 doFlash |
|
1354 "flash the selected view |
|
1355 " |
|
1356 |view| |
|
1357 |
|
1358 view := self selectedView. |
|
1359 view isNil ifTrue:[ ^ self]. |
|
1360 |
|
1361 view shown ifTrue:[ |
|
1362 model withSelectionHiddenDo:[ |
|
1363 view perform:#flash ifNotUnderstood:nil. |
|
1364 ]. |
|
1365 ]. |
|
1366 ! |
|
1367 |
|
1368 doInspect:what |
|
1369 "open inspector on: |
|
1370 #view inspect class |
|
1371 #group inspect windowGroup |
|
1372 #model inspect model |
|
1373 #application inspect application |
|
1374 #controller inspect controller |
|
1375 " |
|
1376 |inst| |
|
1377 |
|
1378 inst := self selectedView. |
|
1379 inst isNil ifTrue:[^ self]. |
|
1380 |
|
1381 what == #group ifTrue:[ inst := inst windowGroup ] |
|
1382 ifFalse:[what == #model ifTrue:[ inst := inst model ] |
|
1383 ifFalse:[what == #application ifTrue:[ inst := inst application ] |
|
1384 ifFalse:[what == #controller ifTrue:[ inst := inst controller ]]]]. |
|
1385 |
|
1386 inst notNil ifTrue:[ inst inspect ]. |
|
1387 ! |
|
1388 |
|
1389 doPickViews |
|
1390 "pick a window's topView |
|
1391 " |
|
1392 |window| |
|
1393 |
|
1394 self doUnpick. |
|
1395 |
|
1396 window := Screen current viewFromUser. |
|
1397 window isNil ifTrue:[^ self]. |
|
1398 |
|
1399 window := window topView. |
|
1400 |
|
1401 ( window == Screen current rootView |
|
1402 or:[window == self window topView] |
|
1403 ) ifTrue:[ |
|
1404 ^ self |
|
1405 ]. |
|
1406 self setRootItem:(ViewTreeItem buildViewsFrom:window). |
|
1407 ! |
|
1408 |
|
1409 doSelectNextOfApplicationClass:aClass startingIn:anItem |
|
1410 |startItem firstFound searchNext| |
|
1411 |
|
1412 startItem := model last. |
|
1413 searchNext := startItem notNil. |
|
1414 firstFound := nil. |
|
1415 |
|
1416 anItem recursiveDo:[:el| |
|
1417 el == startItem ifTrue:[ |
|
1418 searchNext := false |
|
1419 ] ifFalse:[ |
|
1420 (self resolveApplicationClassFor:el) == aClass ifTrue:[ |
|
1421 searchNext ifFalse:[^ model selectItem:el]. |
|
1422 |
|
1423 firstFound isNil ifTrue:[ |
|
1424 firstFound := el |
|
1425 ] |
|
1426 ] |
|
1427 ] |
|
1428 ]. |
|
1429 firstFound notNil ifTrue:[ |
|
1430 self window beep. |
|
1431 model selectItem:firstFound |
|
1432 ]. |
|
1433 ! |
|
1434 |
|
1435 doSelectNextOfClass:aClass startingIn:anItem |
|
1436 |startItem firstFound searchNext| |
|
1437 |
|
1438 startItem := model last. |
|
1439 searchNext := startItem notNil. |
|
1440 firstFound := nil. |
|
1441 |
|
1442 anItem recursiveDo:[:el| |
|
1443 el == startItem ifTrue:[ |
|
1444 searchNext := false |
|
1445 ] ifFalse:[ |
|
1446 el widget class == aClass ifTrue:[ |
|
1447 searchNext ifFalse:[^ model selectItem:el]. |
|
1448 |
|
1449 firstFound isNil ifTrue:[ |
|
1450 firstFound := el |
|
1451 ] |
|
1452 ] |
|
1453 ] |
|
1454 ]. |
|
1455 firstFound notNil ifTrue:[ |
|
1456 self window beep. |
|
1457 model selectItem:firstFound |
|
1458 ]. |
|
1459 ! |
|
1460 |
|
1461 doUnpick |
|
1462 "release current picked window and contained subwindows |
|
1463 " |
|
1464 self setRootItem:nil. |
|
1465 ! ! |
|
1466 |
|
1467 !ViewTreeApplication::MenuDesc class methodsFor:'building'! |
|
1468 |
|
1469 buildFromList:aList onGC:aMenu |
|
1470 |tabSpec menu w menuPanel| |
|
1471 |
|
1472 w := 0. |
|
1473 aList do:[:el| w := w max:(el widthOn:aMenu) ]. |
|
1474 |
|
1475 tabSpec := TabulatorSpecification new. |
|
1476 tabSpec unit:#pixel. |
|
1477 tabSpec positions:#(0 1.5 ). |
|
1478 tabSpec align:#(#left #left). |
|
1479 |
|
1480 w := w + 15. |
|
1481 tabSpec positions:(Array with:0 with:w). |
|
1482 |
|
1483 menu := Menu new. |
|
1484 |
|
1485 aList do:[:el| |
|
1486 menu addItem:(el asMenuItemWithTabulatorSpecification:tabSpec). |
|
1487 ]. |
|
1488 menuPanel := MenuPanel menu:menu. |
|
1489 ^ menuPanel |
|
1490 ! ! |
|
1491 |
|
1492 !ViewTreeApplication::MenuDesc class methodsFor:'instance creation'! |
|
1493 |
|
1494 separator |
|
1495 ^ self new |
|
1496 ! |
|
1497 |
|
1498 title:aTitle value:aValue |
|
1499 ^ self title:aTitle value:aValue action:nil |
|
1500 ! |
|
1501 |
|
1502 title:aTitle value:aValue action:anAction |
|
1503 ^ self new title:aTitle value:aValue action:anAction |
|
1504 ! ! |
|
1505 |
|
1506 !ViewTreeApplication::MenuDesc methodsFor:'accessing'! |
|
1507 |
|
1508 title |
|
1509 ^ title |
|
1510 ! ! |
|
1511 |
|
1512 !ViewTreeApplication::MenuDesc methodsFor:'building'! |
|
1513 |
|
1514 asMenuItemWithTabulatorSpecification:aTabSpec |
|
1515 |array| |
|
1516 |
|
1517 title isNil ifTrue:[ ^ MenuItem label:value ]. "/ separator |
|
1518 |
|
1519 array := Array with:(title, ':') with:'------'. |
|
1520 |
|
1521 value notNil ifTrue:[ |
|
1522 array at:2 put:(value printString, ' ') |
|
1523 ]. |
|
1524 |
|
1525 ^ MenuItem label:(MultiColListEntry fromStrings:array tabulatorSpecification:aTabSpec) |
|
1526 value:action |
|
1527 ! ! |
|
1528 |
|
1529 !ViewTreeApplication::MenuDesc methodsFor:'instance creation'! |
|
1530 |
|
1531 title:aTitle value:aValue action:anAction |
|
1532 "test for separator |
|
1533 " |
|
1534 title := aTitle withoutSeparators. |
|
1535 action := anAction. |
|
1536 |
|
1537 aValue notNil ifTrue:[ |
|
1538 value := aValue printString. |
|
1539 |
|
1540 value size > 70 ifTrue:[ |
|
1541 value := value copyFrom:1 to:70. |
|
1542 value := value, '...' |
|
1543 ] |
|
1544 ]. |
|
1545 ! ! |
|
1546 |
|
1547 !ViewTreeApplication::MenuDesc methodsFor:'queries'! |
|
1548 |
|
1549 isSeparator |
|
1550 ^ title isNil |
|
1551 ! |
|
1552 |
|
1553 widthOn:aGC |
|
1554 title isNil ifTrue:[^ 5]. "/ separator |
|
1555 ^ title widthOn:aGC |
|
1556 ! ! |
|
1557 |
|
1558 !ViewTreeApplication class methodsFor:'documentation'! |
|
1559 |
|
1560 version |
|
1561 ^ '$Header$' |
|
1562 ! ! |
|
1563 |
|
1564 ViewTreeApplication initialize! |