2 COPYRIGHT (c) 2007 by eXept Software AG
5 This software is furnished under a license and may be used
6 only in accordance with the terms of that license and with the
7 inclusion of the above copyright notice. This software may not
8 be provided or otherwise made available to, or used by, any
9 other person. No title to or ownership of the software is
12 "{ Package: 'stx:libtool2' }"
14 "{ NameSpace: Tools }"
16 ToolApplicationModel subclass:#ViewTreeInspectorApplication
17 instanceVariableNames:'model treeView hasSingleSelectionHolder clickedItem clickedPoint
18 motionAction process followFocusChannel showNamesHolder
22 category:'Interface-Smalltalk'
25 Object subclass:#MenuDesc
26 instanceVariableNames:'title value action'
29 privateIn:ViewTreeInspectorApplication
32 HierarchicalItem subclass:#ViewTreeItem
33 instanceVariableNames:'widget isDrawnShown exists xOffsetAdditionalName'
34 classVariableNames:'HandleExtent'
36 privateIn:ViewTreeInspectorApplication
39 ValueModel subclass:#ViewTreeModel
40 instanceVariableNames:'lockSema selectedSuperItems selection hiddenLevel listOfItems
41 inputEventAction mappedViewAction beforeSelectionChangedAction
42 icons timedUpdateTask selectOnClickHolder testModeChannel
43 hasTargetWidgetChannel catchEvents'
46 privateIn:ViewTreeInspectorApplication
49 HierarchicalList subclass:#ItemList
50 instanceVariableNames:'treeModel eventHook eventHookInitialized showWidgetNames'
53 privateIn:ViewTreeInspectorApplication::ViewTreeModel
56 !ViewTreeInspectorApplication class methodsFor:'documentation'!
60 COPYRIGHT (c) 2007 by eXept Software AG
63 This software is furnished under a license and may be used
64 only in accordance with the terms of that license and with the
65 inclusion of the above copyright notice. This software may not
66 be provided or otherwise made available to, or used by, any
67 other person. No title to or ownership of the software is
74 Small application showing a ViewTreeModel use.
76 It displays a hierarchical list of a selected TopView and
77 all its contained subViews.
78 Useful to have a look at subcomponents - to see how views
83 model <ViewTreeModel> the used ViewTreeModel
84 clickedItem <ViewTreeItem> item under the clickedPoint (motion action)
85 clickedPoint <Point> point where the motion action started from.
86 motionAction <Action> (oneArg-) action called durring buttonMotion.
98 !ViewTreeInspectorApplication class methodsFor:'initialization'!
101 "add myself to the launcher menu
103 self installInLauncher.
107 "add myself to the launcher menu"
111 NewLauncher isNil ifTrue:[^ self].
112 "/ cg - disabled. the icon is too ugly.
115 icon := ToolbarIconLibrary inspectLocals20x20Icon magnifiedTo:28@28.
117 menuItem := MenuItem new
118 label: 'View Tree Inspector';
119 value: [ ViewTreeInspectorApplication open];
122 nameKey: #viewInspect.
124 menuItem startGroup:#right.
125 NewLauncher addMenuItem:menuItem in:'toolbar'
126 position:#( #before #help)
130 self installInLauncher
131 self removeFromLauncher
136 "add myself to the launcher menu
138 self installInLauncher.
140 self installInLauncher
141 self removeFromLauncher
146 "remove myself from the launcher menu
148 NewLauncher isNil ifTrue:[^ self].
149 NewLauncher removeUserTool:#viewInspect
152 self installInLauncher
153 self removeFromLauncher
158 "class is about to be unloaded - remove myself from the launcher menu
160 self removeFromLauncher.
164 !ViewTreeInspectorApplication class methodsFor:'image specs'!
167 "This resource specification was automatically generated
168 by the ImageEditor of ST/X."
170 "Do not manually edit this!! If it is corrupted,
171 the ImageEditor may not be able to read the specification."
174 self crossHairIcon inspect
175 ImageEditor openOnClass:self andSelector:#crossHairIcon
176 Icon flushCachedIcons
182 constantNamed:'Tools::ViewTreeInspectorApplication class crossHairIcon'
183 ifAbsentPut:[(Depth1Image new) width: 24; height: 24; photometric:(#palette); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@F0@@XL@@>>@A8O@A>?@B,Z B(J @@@@B(J B,Z A>?@A8O@@>>@@XL@@F0@@@@@@@@@@@@@@@@@@@@@') ; colorMapFromArray:#[255 255 255 0 0 0]; mask:((Depth1Image new) width: 24; height: 24; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@G0@@_<@@?>@A??@C?? C?? G??0G<_0G<_0G<_0G??0C?? C?? A??@@?>@@_<@@G0@@@@@@@@@@@@@@@@@') ; yourself); yourself]
187 "This resource specification was automatically generated
188 by the ImageEditor of ST/X."
190 "Do not manually edit this!! If it is corrupted,
191 the ImageEditor may not be able to read the specification."
194 self pickWindowIcon inspect
195 ImageEditor openOnClass:self andSelector:#pickWindowIcon
196 Icon flushCachedIcons
202 constantNamed:'Tools::ViewTreeInspectorApplication class pickWindowIcon'
203 ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
204 ,;N3,;N3,;N3,;N3,;N3,;N3,;N3,3H<P38;M3P,H2@^GA(VEQHQCP0KA D<[&-%XU=WST%BN#D!!GQ$TD@(IBP\BQF)+Z6E_U4-FPCX+G1,WEA@JBP$HAT23
205 ,;N3,;N3,;N3,;N$():Z&IRR&1!!^,;N3,;N3,;N3,;N$)JJ^&)"T$),0W[N3,;N3,;N3,;N3,:R"'')*X%IJWK523,;N3,;N3,0@@@KN3)JJ^&)"T$"5Z,;N3
206 ,;N3@@B3-KL@@JJ^&)"T$)D*V[N3,;N3@KN3-KR4)JH@&)"T$)*MJE"3,;N3,0B3)JJ4&*R"@I*X%IJZ#RYV,;N3,0B3@JR"-JR"-I(@%IJV%H %U[N3,;L@
207 -@B4-KR4-KR4@IRR%IJEIER3,;N3@KL@)JJ4():4&@BO#9RR!!RIS,;N3,;L@,:R"-JJ^& BT#8>O#8H"T+N3,;N3@KN$@@@@'')(@%H>O#(>AH%F3,;N3,;L@
208 @JR4'' @@%IJO#8>O RIO,;N3,;N3):P@@@BX%IJO#8>O#7<"S*63,;N$():Z&IRR&IRR#8>O#8=>H"&-,;N$():Z&IRR&)"T$(>O#8>O @<)R$!!GQTD?OS$8
209 MSL.I2H"H"H"H"HO,;N3,;N3,;N3,;N3,;N3,;N3,;N3,0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 0 50 164 0 50 171 0 137 0 0 206 0 1 50 177 2 56 178 3 64 241 3 67 246 3 73 255 4 74 255 5 63 191 7 66 194 10 71 196 10 79 255 12 59 167 12 82 255 14 77 199 18 83 201 19 88 255 21 91 255 23 89 204 27 95 206 28 97 255 29 72 179 30 100 255 32 101 209 36 106 255 36 107 211 39 109 255 41 113 214 45 115 255 45 119 216 48 118 255 50 87 176 50 125 219 51 88 176 51 88 177 52 89 178 52 90 178 53 90 178 53 127 212 54 91 179 54 123 255 54 131 221 55 92 180 55 95 181 56 93 180 56 94 181 57 127 255 57 149 229 58 99 184 58 137 224 61 104 187 63 132 255 63 143 226 64 108 190 66 113 193 66 135 255 67 149 229 68 157 232 69 117 196 71 155 231 72 122 199 72 141 255 75 126 202 75 144 255 75 160 234 77 163 236 78 131 206 80 149 255 81 136 209 84 140 212 84 153 255 87 145 215 88 157 255 91 168 235 93 161 255 94 154 222 96 157 223 96 165 255 97 159 225 98 160 225 98 162 226 99 163 227 100 165 228 101 166 229 101 170 255 102 167 230 103 169 231 104 170 232 104 173 255 105 172 233 105 174 234 106 175 235 109 178 255 112 180 255 117 186 255 119 187 255 122 154 245 125 160 253 125 193 255 126 161 253 126 194 255 127 162 254 130 165 254 132 200 255 132 201 255 133 60 36 135 170 255 139 207 255 140 175 255 144 179 255 149 184 255 153 188 255 157 192 255 162 196 255 166 200 255 170 204 255 174 208 255 174 218 230 177 212 255 181 215 255 185 219 255 188 222 255 191 225 255 212 211 224 218 217 230 219 219 230 220 220 231 222 221 232 223 223 233 225 224 234 225 225 234 226 226 237 227 226 235 227 227 236 227 227 238 228 228 237 229 229 239 231 230 238 231 231 238 231 231 240 232 232 241 233 232 239 233 233 240 234 234 242 235 234 241 236 236 243 237 236 242 237 237 244 238 237 243 238 238 244 239 238 243 239 239 245 240 239 244 241 240 245 241 241 246 241 241 247 242 242 246 242 242 247 243 243 247 243 243 248 244 244 248 244 244 249 245 244 247 246 246 249 246 246 250 247 246 249 247 247 250 248 248 251 249 249 250 249 249 251 250 250 251 250 250 252 251 251 252 251 251 253 253 253 254 254 254 255 255 255 255 0 0 0]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@C????????????????????????????????????????????????????????????????????????????????@@@C') ; yourself); yourself]
213 "This resource specification was automatically generated
214 by the ImageEditor of ST/X."
216 "Do not manually edit this!! If it is corrupted,
217 the ImageEditor may not be able to read the specification."
220 self pickWindowIcon2 inspect
221 ImageEditor openOnClass:self andSelector:#pickWindowIcon2
222 Icon flushCachedIcons
228 constantNamed:'Tools::ViewTreeInspectorApplication class pickWindowIcon2'
229 ifAbsentPut:[(Depth8Image new) width: 22; height: 23; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
230 @CH<O#,7MB0#HA8\F!!XUD!!DMC@,F@P@<[&U!!W5]MRTH:LRD]FQPPB $IA0H@QF)+XU=WR4Y@M",_F1\TD@(IBP E@D23,;N3,;N3,;N3,;N"'')*X%IJ[F@A^
231 ,;N3,;N3,0@@@@@@():Z&IRR&3@@W+N3,;N3@@B3,0B3)@@@&)"T$),0@E63,;N3@KN3@@@@@@B"'' BX%IJWK0A\,;N3@KN3,;N3@JR"'')*X@IRR&24@V+N3
232 @KN3,;L@@@@@@I:Z&IP@$),*@E&3,0B3,;N3,:P@():Z&IRT@IJ[J@AX,0B3@KL@,;L@@@B^& BT@IP@&2X@U+L@,0B3@KL@)JJ^@I @%@BT@I,%@EV3@@@@
233 @@@@@JR"'' @@@@@@@@B[I@AT,0B3@KL@)@B$()8@&@BZ@IP@&2H@T;L@,0B3@JR$@@@@%I @& BT@I,"@EJ3,0B3,:R$)I8@&IRX%I*X@IJ[H AQ,;L@,:R$
234 )@@@@@@@&IRO#0BO RH@S;N3,0B$)JR"'' BX%I"T#0BO#7<"@D:-,;N$@JR$@@@@@@BR#0BO#8=>H AN+[N$)JH@@I"T@I"T@@BO#8>O_"H@JZ63)JJ^&) @
235 @@@@@IJO#8>O#8@O@B&3,;N3,;N3,;N3,;N"'')*X%IJ[C0@)R$]EPS<=NS 5L28''H"H"H"H"H <b') ; colorMapFromArray:#[0 0 0 0 50 164 0 50 171 0 137 0 0 206 0 1 50 177 2 56 178 3 64 241 3 67 246 3 73 255 4 74 255 5 63 191 7 66 194 10 71 196 10 79 255 12 59 167 12 82 255 14 77 199 18 83 201 19 88 255 21 91 255 23 89 204 27 95 206 28 97 255 29 72 179 30 100 255 32 101 209 36 106 255 36 107 211 39 109 255 41 113 214 45 115 255 45 119 216 48 118 255 50 87 176 50 125 219 51 88 176 51 88 177 52 89 178 52 90 178 53 90 178 53 127 212 54 91 179 54 123 255 54 131 221 55 92 180 55 95 181 56 93 180 56 94 181 57 127 255 57 149 229 58 99 184 58 137 224 61 104 187 63 132 255 63 143 226 64 108 190 66 113 193 66 135 255 67 149 229 68 157 232 69 117 196 71 155 231 72 122 199 72 141 255 75 126 202 75 144 255 75 160 234 77 163 236 78 131 206 80 149 255 81 136 209 84 140 212 84 153 255 87 145 215 88 157 255 91 168 235 93 161 255 94 154 222 96 157 223 96 165 255 97 159 225 98 160 225 98 162 226 99 163 227 100 165 228 101 166 229 101 170 255 102 167 230 103 169 231 104 170 232 104 173 255 105 172 233 105 174 234 106 175 235 109 178 255 112 180 255 117 186 255 119 187 255 122 154 245 125 160 253 125 193 255 126 161 253 126 194 255 127 162 254 130 165 254 132 200 255 132 201 255 133 60 36 135 170 255 139 207 255 140 175 255 144 179 255 149 184 255 153 188 255 157 192 255 162 196 255 166 200 255 170 204 255 174 208 255 174 218 230 177 212 255 181 215 255 185 219 255 188 222 255 191 225 255 212 211 224 218 217 230 219 219 230 220 220 231 222 221 232 223 223 233 225 224 234 225 225 234 226 226 237 227 226 235 227 227 236 227 227 238 228 228 237 229 229 239 231 230 238 231 231 238 231 231 240 232 232 241 233 232 239 233 233 240 234 234 242 235 234 241 236 236 243 237 236 242 237 237 244 238 237 243 238 238 244 239 238 243 239 239 245 240 239 244 241 240 245 241 241 246 241 241 247 242 242 246 242 242 247 243 243 247 243 243 248 244 244 248 244 244 249 245 244 247 246 246 249 246 246 250 247 246 249 247 247 250 248 248 251 249 249 250 249 249 251 250 250 251 250 250 252 251 251 252 251 251 253 253 253 254 254 254 255 255 255 255]; mask:((Depth1Image new) width: 22; height: 23; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<_??<') ; yourself); yourself]
239 "This resource specification was automatically generated
240 by the ImageEditor of ST/X."
242 "Do not manually edit this!! If it is corrupted,
243 the ImageEditor may not be able to read the specification."
246 self releaseViewIcon inspect
247 ImageEditor openOnClass:self andSelector:#releaseViewIcon
248 Icon flushCachedIcons
254 constantNamed:'Tools::ViewTreeInspectorApplication releaseViewIcon'
255 ifAbsentPut:[(Depth8Image new) width: 24; height: 24; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
256 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
257 @@@@@@@@@@@@@@A8^G!!7O3ACP5*P@@A8^G @@@@@@@@@@@A8^@@@OE0/!!P0S#0@@^G @@@@@@@@@@@B (@@''D#48"1.CX5H@(J@@@@@@@@@@@@B (@@@@@@"
258 ''%!!/P7,@(J@@@@@@@@@@@@@%I@@@@BH%IRTQV5P@IRT@@@@@@@@@@@ANSP@@@@ANS$8:T80@S$8@@@@@@@@@@@AN&UYWK(EYQ@\FUPQHXT8@@@@@@@@@@@AN
259 HC2!!TVY:Y#-%I*IKMD8@@@@@@@@@@@A$\@83XBEG%).GGX _!!&P@@@@@@@@@@@AO[P5+ &(WPYN@["!!E\$<@@@@@@@@@@@B_F''FQPAXX_!!&TGH4HB9<@@@@@
260 @@@@@@B_%3HCJ7=BKPU,Q)01B9<@@@@@@@@@@@@PBP8T_F!!''JPI)_Y"D&!!@@@@@@@@@@@@@$B)I9TGXO''WQIWQ93W0@@@@@@@@@@@@@$"U=JR$)JR$)JR$)_
261 "P@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
262 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@') ; colorMapFromArray:#[132 141 152 147 150 154 250 223 1 246 214 0 205 172 133 238 195 0 213 180 146 217 186 150 188 136 0 206 151 0 183 125 9 208 208 202 196 204 214 255 255 210 255 255 219 210 178 65 242 242 235 106 112 117 96 107 126 250 255 255 255 241 0 154 154 151 255 227 0 67 35 0 52 17 0 253 211 0 208 159 0 167 178 193 222 168 0 248 231 45 208 174 26 199 152 26 225 184 36 255 249 75 220 220 215 77 88 108 241 241 235 245 245 239 255 250 109 242 249 255 255 255 142 255 237 1 142 148 162 242 212 1 143 154 176 174 133 0 222 189 144 169 179 192 177 184 193 184 129 0 255 255 194 253 241 60 210 210 205 214 214 209 77 83 92 230 230 225 98 106 114 243 243 238 117 117 114 255 252 115 255 255 255 115 123 147 130 140 156 152 156 159 241 210 0 53 18 0 151 116 0 162 170 184 218 187 150 193 143 4 220 165 0 206 188 46 181 130 21 204 173 44 206 206 201 208 167 44 72 84 108 240 240 234 244 244 238 243 243 237 212 182 79 255 255 126 131 135 141 119 133 159 132 141 163 195 162 126 219 188 133 218 185 135 180 180 176 221 190 150 175 181 191 176 183 196 181 189 201 202 170 38 209 209 204 207 207 202 251 241 74 229 229 224 238 238 233 226 234 245 244 244 237 255 251 113 255 255 124 255 241 2 255 234 3 249 219 0 255 249 29 252 243 30 227 181 0 212 165 5 222 170 0 173 179 194 216 171 19 255 255 198 208 208 203 156 90 7 206 175 50 91 91 95 211 180 71 242 242 237 246 246 241 212 182 80 255 255 123 129 137 152 255 239 8 251 223 0 59 25 0 251 215 0 228 183 0 222 191 149 249 238 43 177 186 197 187 129 0 186 194 206 209 209 203 249 238 67 255 255 211 226 226 221 235 235 229 100 103 111 76 93 127 255 255 112 88 104 139 130 135 148 149 155 158 247 218 0 224 194 126 255 217 0 228 184 0 13 30 68 161 138 32 204 152 0 255 255 53 206 155 18 207 207 201 255 250 72 255 255 82 209 176 59 232 232 227 243 243 236 245 245 240 255 255 115 255 255 251]; mask:((Depth1Image new) width: 24; height: 24; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@G8@@O<@@O>@@@^@@@N@@@N@@?? @?? @?? @?? @?? @?? @?? @?? @_?@@@@@@@@@@@@@@@@@@@@@') ; yourself); yourself]
265 !ViewTreeInspectorApplication class methodsFor:'interface specs'!
268 "This resource specification was automatically generated
269 by the UIPainter of ST/X."
271 "Do not manually edit this!! If it is corrupted,
272 the UIPainter may not be able to read the specification."
275 UIPainter new openOnClass:Tools::ViewTreeInspectorApplication andSelector:#windowSpec
276 Tools::ViewTreeInspectorApplication new openInterface:#windowSpec
277 Tools::ViewTreeInspectorApplication open
287 label: 'View Tree Inspector'
288 name: 'View Tree Inspector'
290 max: (Point 1024 9999)
291 bounds: (Rectangle 0 0 381 654)
299 layout: (LayoutFrame 0 0.0 0 0 0 1.0 40 0)
303 (VariableVerticalPanelSpec
304 name: 'VariableVerticalPanel1'
305 layout: (LayoutFrame 0 0.0 40 0.0 0 1.0 0 1.0)
309 (HierarchicalListViewSpec
313 menu: middleButtonMenu
314 hasHorizontalScrollBar: true
315 hasVerticalScrollBar: true
316 miniScrollerHorizontal: true
317 miniScrollerVertical: false
318 listModel: listOfItems
319 multipleSelectOk: true
322 showLeftIndicators: false
323 indicatorSelector: indicatorClicked:
324 useDefaultIcons: false
325 postBuildCallback: postBuildTree:
329 viewClassName: 'InspectorView'
330 postBuildCallback: postBuildInspectorView:
335 handles: (Any 0.5 1.0)
343 !ViewTreeInspectorApplication class methodsFor:'menu specs'!
346 "This resource specification was automatically generated
347 by the MenuEditor of ST/X."
349 "Do not manually edit this!! If it is corrupted,
350 the MenuEditor may not be able to read the specification."
354 MenuEditor new openOnClass:Tools::ViewTreeInspectorApplication andSelector:#menu
355 (Menu new fromLiteralArrayEncoding:(Tools::ViewTreeInspectorApplication menu)) startUp
370 itemValue: doPickView
373 enabled: hasTargetWidgetChannel
374 label: 'Release Picked View'
387 hideMenuOnActivated: false
388 indication: testModeChannel
391 enabled: testModeChannel
392 label: 'Follow Focus'
393 hideMenuOnActivated: false
394 indication: followFocusChannel
400 label: 'Select on Click'
401 hideMenuOnActivated: false
402 indication: selectOnClickHolder
408 label: 'Show Name of Widgets'
409 hideMenuOnActivated: false
410 indication: showNamesHolder
422 itemValue: closeRequest
430 enabled: hasSingleSelectionHolder
432 submenuChannel: middleButtonMenu
440 enabled: hasSingleSelectionHolder
446 enabled: hasSingleSelectionHolder
448 itemValue: doInspect:
455 enabled: hasTargetWidgetChannel
456 label: 'All Components'
458 submenuChannel: submenuComponents:
478 enabled: hasSingleSelectionHolder
481 argument: application
484 enabled: hasSingleSelectionHolder
486 itemValue: doInspect:
487 argument: application
493 enabled: hasTargetWidgetChannel
494 label: 'All Applications'
495 submenuChannel: submenuApplications:
508 enabled: hasSingleSelectionHolder
510 itemValue: doInspect:
517 label: 'Open Process Monitor'
518 itemValue: doOpenProcessMonitor
527 startGroup: conditionalRight
532 label: 'Documentation'
533 itemValue: openDocumentation
539 label: 'About this Application...'
540 itemValue: openAboutThisApplication
554 "This resource specification was automatically generated
555 by the MenuEditor of ST/X."
557 "Do not manually edit this!! If it is corrupted,
558 the MenuEditor may not be able to read the specification."
561 MenuEditor new openOnClass:ViewTreeApplication andSelector:#middleButtonMenu
562 (Menu new fromLiteralArrayEncoding:(ViewTreeApplication middleButtonMenu)) startUp
573 submenuChannel: submenuGeometry:
579 submenuChannel: submenuInterface:
585 submenuChannel: submenuVisibility:
592 label: 'Browse View Class'
598 label: 'Browse Model Class'
605 label: 'Browse Application Class'
608 isVisible: hasApplication
609 argument: application
612 label: 'Browse Controller Class'
615 isVisible: hasController
622 label: 'Inspect View'
623 itemValue: doInspect:
628 label: 'Inspect Window Group'
629 itemValue: doInspect:
634 label: 'Inspect Model'
635 itemValue: doInspect:
641 label: 'Inspect Application'
642 itemValue: doInspect:
644 isVisible: hasApplication
645 argument: application
648 label: 'Inspect Controller'
649 itemValue: doInspect:
651 isVisible: hasController
674 label: 'Instance Variables'
676 submenuChannel: submenuInspector:
686 enabled: selectedComponentHasChildren
687 label: 'Applications'
690 submenuChannel: submenuApplications:
694 enabled: selectedComponentHasChildren
698 submenuChannel: submenuComponents:
708 "This resource specification was automatically generated
709 by the MenuEditor of ST/X."
711 "Do not manually edit this!! If it is corrupted,
712 the MenuEditor may not be able to read the specification."
716 MenuEditor new openOnClass:Tools::ViewTreeInspectorApplication andSelector:#toolbarMenu
717 (Menu new fromLiteralArrayEncoding:(Tools::ViewTreeInspectorApplication toolbarMenu)) startUp
726 enabled: hasTargetWidgetChannel
730 labelImage: (ResourceRetriever ToolbarIconLibrary reloadIcon)
736 label: 'Pick a View and Catch Events'
737 itemValue: doPickView
738 translateLabel: false
740 hideMenuOnActivated: false
741 labelImage: (ResourceRetriever #'Tools::ViewTreeInspectorApplication' pickWindowIcon2)
744 enabled: hasTargetWidgetChannel
745 label: 'Release Picked View and Uncatch Events'
746 itemValue: doUncatchEvents
748 labelImage: (ResourceRetriever #'Tools::ViewTreeInspectorApplication' releaseViewIcon)
754 enabled: hasSingleSelectionHolder
755 label: 'Browse Application'
757 translateLabel: false
759 hideMenuOnActivated: false
760 labelImage: (ResourceRetriever ToolbarIconLibrary systemBrowser24x24Icon2)
761 argument: application
764 enabled: hasSingleSelectionHolder
765 label: 'Inspect Application'
766 itemValue: doInspect:
767 translateLabel: false
769 hideMenuOnActivated: false
770 labelImage: (ResourceRetriever ToolbarIconLibrary inspect22x24Icon)
771 argument: application
779 !ViewTreeInspectorApplication class methodsFor:'startup'!
790 "show a particular window's topView hierarchy,
791 select the given view"
797 app showWindow:aView.
800 !ViewTreeInspectorApplication methodsFor:'actions'!
802 indicatorClicked:anIndex
805 item := model listOfItems at:anIndex ifAbsent:nil.
808 ( (sensor := self window sensor) notNil
809 and:[(sensor ctrlDown or:[sensor shiftDown])]
811 item recursiveToggleExpand
818 !ViewTreeInspectorApplication methodsFor:'aspects'!
821 "boolean holder, which indicates whether selection changed dependend on the focus view"
826 hasSingleSelectionHolder
827 "boolean holder, true if one item is selected"
829 ^ hasSingleSelectionHolder
832 hasTargetWidgetChannel
833 "answer the channel which is set to true if a target widget exists"
835 ^ model hasTargetWidgetChannel
839 "returns the hierarchical list of items"
845 "returns my selection model, a ViewTreeModel"
851 "boolean holder, which indicates whether the selection will change on click"
853 ^ model selectOnClickHolder
857 "boolean holder, which indicates whether application names or widget names
858 as additional text are shown for the items"
864 "answer a boolean channel which describes the behaviour how to process
865 events on the target view.
867 false: all input events are eaten and the selection is shown on the target view.
868 true: no input events are eaten and no selection is shown on the target view."
870 ^ model testModeChannel
873 !ViewTreeInspectorApplication methodsFor:'change & update'!
878 item := model selectedItem.
880 item notNil ifTrue:[ |state|
883 view id isNil ifTrue:[
892 info := '%1 [%2] - %3' bindWith:(view class name)
893 with:(view name ? '') with:state allBold.
898 hasSingleSelectionHolder value:(view notNil).
899 inspectorView inspect:view.
902 update:something with:someArgument from:aModel
905 aModel == showNamesHolder ifTrue:[
906 oldSelection := model selectedItem.
907 model selectedItem:nil.
908 self listOfItems showWidgetNames:(aModel value).
909 model selectedItem:oldSelection.
913 aModel == model ifTrue:[
914 self selectionChanged.
918 super update:something with:someArgument from:aModel.
921 !ViewTreeInspectorApplication methodsFor:'event processing'!
923 processButtonMotionEvent:ev
926 motionAction isNil ifTrue:[^ self].
928 (rootView := model rootView) isNil ifTrue:[
929 clickedItem := motionAction := nil.
933 click := rootView device
934 translatePoint:((ev x)@ (ev y))
938 click = clickedPoint ifFalse:[
939 (clickedItem isNil or:[(click dist:clickedPoint) > 5.0]) ifTrue:[
940 motionAction value:click
945 processButtonPressEvent:ev
946 |rootView sensor lastRectangle|
948 rootView := model rootView.
949 sensor := model rootView sensor.
950 clickedItem := model listOfItems detectItemRespondsToView:(ev view).
952 (sensor ctrlDown or:[sensor shiftDown]) ifTrue:[
953 clickedItem notNil ifTrue:[
954 self selectOnClickHolder value ifTrue:[
955 model toggleSelectItem:clickedItem
958 clickedItem := motionAction := nil.
962 clickedPoint := rootView device translatePoint:((ev x)@ (ev y)) fromView:(ev view) toView:rootView.
963 lastRectangle := nil.
966 rootView := model rootView device rootView.
967 rootView := model rootView.
971 lastRectangle notNil ifTrue:[ rootView displayRectangle:lastRectangle ]
972 ifFalse:[ rootView clippedByChildren:false ].
975 rootView clippedByChildren:true.
978 lastRectangle := Rectangle origin:(clickedPoint min:p) corner:(clickedPoint max:p).
979 rootView displayRectangle:lastRectangle.
987 processButtonReleaseEvent:anEvent
988 |rootView rectangle newItems widget origin|
990 (rootView := model rootView) isNil ifTrue:[
991 clickedItem := motionAction := nil.
994 motionAction isNil ifTrue:[ ^ self ].
995 clickedItem notNil ifTrue:[ ^ model selectItem:clickedItem ].
997 rectangle := motionAction value:nil.
998 rectangle isNil ifTrue:[^ self].
1000 newItems := OrderedCollection new.
1002 model rootItem recursiveDo:[:anItem|
1003 widget := anItem widget.
1004 origin := widget originRelativeTo:rootView.
1006 (rectangle containsRect:(Rectangle origin:origin extent:(widget extent))) ifTrue:[
1007 newItems add:anItem.
1010 model value:newItems.
1013 processEvent:anEvent
1016 anEvent isKeyPressEvent ifTrue:[ self processKeyPressEvent:anEvent. ^ self ].
1017 anEvent isButtonEvent ifFalse:[ ^ self ].
1019 button := anEvent button.
1021 (button == 2 or:[button == #menu]) ifTrue:[
1022 motionAction isNil ifTrue:[
1023 anEvent isButtonPressEvent ifTrue:[
1024 self selectOnClickHolder value ifTrue:[
1025 menu := self middleButtonMenu value.
1026 menu notNil ifTrue:[
1028 menu:(Menu new fromLiteralArrayEncoding:menu)
1039 anEvent isButtonPressEvent ifTrue:[ self processButtonPressEvent:anEvent. ^ self ].
1040 anEvent isButtonMotionEvent ifTrue:[ self processButtonMotionEvent:anEvent. ^ self ].
1042 anEvent isButtonReleaseEvent ifTrue:[
1043 self selectOnClickHolder value ifTrue:[
1044 self processButtonReleaseEvent:anEvent
1047 clickedItem := motionAction := nil.
1049 anEvent type == #'buttonMultiPress:x:y:' ifTrue:[
1050 self selectOnClickHolder value ifTrue:[
1051 self doInspect:#view.
1056 processKeyPressEvent:anEvent
1057 |item prnt idx key max next|
1060 key isSymbol ifFalse:[^ self].
1062 key == #Delete ifTrue:[ ^ self doDestroy ].
1063 key == #InspectIt ifTrue:[ ^ self doInspect:#view ].
1066 or:[key == #CursorDown
1067 or:[key == #CursorLeft
1068 or:[key == #CursorRight]]]
1072 item := model selectedItem.
1075 ^ model selectedItem:(model first ? model rootItem)
1078 prnt := item parent.
1081 (key == #CursorUp or:[key == #CursorLeft]) ifTrue:[item := model listOfItems last]
1082 ifFalse:[item := item at:1 ifAbsent:item].
1084 ^ model selectedItem:item
1086 key == #CursorLeft ifTrue:[ ^ model selectedItem:prnt ].
1088 key == #CursorRight ifTrue:[
1089 next := item at:1 ifAbsent:nil.
1090 next notNil ifTrue:[ model selectedItem:next ].
1096 key == #CursorUp ifTrue:[
1097 idx := prnt identityIndexOf:item.
1098 idx == 1 ifTrue:[idx := max + 1].
1099 model selectedItem:(prnt at:idx - 1).
1103 key == #CursorDown ifTrue:[
1104 idx := prnt identityIndexOf:item.
1105 idx == max ifTrue:[idx := 0].
1106 model selectedItem:(prnt at:idx + 1).
1111 processMappedView:aView
1114 parent := self listOfItems detectItemRespondsToView:aView.
1115 parent isNil ifTrue:[ ^ self ].
1117 NotFoundSignal handle:[:ex|
1118 "contained subvies used by spec are not yet created;
1119 thus we have to wait until last used subview is build
1123 anchor := parent class buildViewsFrom:(parent widget).
1125 anchor notNil ifTrue:[
1126 parent updateFromChildren:anchor children.
1130 !ViewTreeInspectorApplication methodsFor:'initialization & release'!
1133 "release the grapped application"
1136 super closeDownViews.
1141 "setup my model and channels"
1145 hasSingleSelectionHolder := false asValue.
1146 followFocusChannel := false asValue.
1148 model := ViewTreeModel new.
1149 model inputEventAction:[:ev| self processEvent:ev ].
1150 model mappedViewAction:[:vw| self processMappedView:vw ].
1151 model application:self.
1152 model addDependent:self.
1155 showNamesHolder := false asValue.
1156 showNamesHolder addDependent:self.
1159 postBuildInspectorView:anInspector
1160 inspectorView := anInspector.
1164 treeView := aTree scrolledView.
1165 treeView hasConstantHeight:true.
1168 !ViewTreeInspectorApplication methodsFor:'menu queries'!
1171 "returns true if the current selected view has an application"
1175 view := self selectedView.
1176 ^ (view notNil and:[view application notNil])
1180 "returns true if the current selected item's view has a controller
1181 other than nil or the view itself"
1185 view := self selectedView.
1187 view notNil ifTrue:[
1188 controller := view controller.
1189 ^ (controller notNil and:[controller ~~ view])
1195 "returns true if the current selected view has a model"
1199 view := self selectedView.
1200 ^ (view notNil and:[view model notNil])
1203 !ViewTreeInspectorApplication methodsFor:'menu specs'!
1206 "returns the middleButton menu for the single selected item or nil"
1209 model selectedItem notNil
1210 ifTrue:[self class middleButtonMenu]
1215 submenuApplications:aMenu
1216 |applications menu item list addBlock|
1218 item := aMenu selection nameKey == #single ifTrue:[model selectedItem]
1219 ifFalse:[model rootItem].
1220 item isNil ifTrue:[^ nil].
1222 applications := IdentityDictionary new.
1224 addBlock := [:el| |cls ctr|
1225 cls := self resolveApplicationClassFor:el.
1228 ctr := applications at:cls ifAbsent:0.
1229 applications at:cls put:(ctr + 1).
1232 item recursiveDo:addBlock.
1233 addBlock value:item.
1235 applications isEmpty ifTrue:[^ nil ].
1236 list := SortedCollection sortBlock:[:a :b| a title < b title ].
1238 applications keysAndValuesDo:[:cls :ctr|
1239 list add:(MenuDesc title:(cls name)
1240 value:(ctr printString)
1241 action:[self doSelectNextOfApplicationClass:cls startingIn:item]
1245 menu := MenuDesc buildFromList:list onGC:aMenu.
1247 el hideMenuOnActivated:false
1252 submenuComponents:aMenu
1253 |widgets list total menu item|
1255 item := aMenu selection nameKey == #single ifTrue:[model selectedItem]
1256 ifFalse:[model rootItem].
1257 item isNil ifTrue:[^ nil].
1259 widgets := IdentityDictionary new.
1262 item recursiveDo:[:el| |cls ctr|
1267 ctr := widgets at:cls ifAbsent:0.
1268 widgets at:cls put:(ctr + 1).
1272 total == 0 ifTrue:[^ nil].
1273 list := SortedCollection sortBlock:[:a :b| a title < b title ].
1275 widgets keysAndValuesDo:[:cls :ctr|
1276 list add:(MenuDesc title:(cls name)
1277 value:(ctr printString)
1278 action:[self doSelectNextOfClass:cls startingIn:item]
1281 list := list asOrderedCollection.
1282 list add:(MenuDesc separator).
1283 list add:(MenuDesc title:'Total' value:(total printString)).
1284 menu := MenuDesc buildFromList:list onGC:aMenu.
1286 el hideMenuOnActivated:false
1291 submenuGeometry:aMenu
1292 "builds and returns the geometry submenu"
1294 |view point inst list x y|
1296 view := self selectedView.
1297 view isNil ifTrue:[^ nil].
1299 list := OrderedCollection new.
1302 point := view relativeOrigin.
1303 point isNil ifTrue:[ point := view origin ].
1308 (x == point x and:[y == point y]) ifTrue:[ inst := point ]
1309 ifFalse:[ inst := '%1 --> (%2@%3)' bindWith:point with:x with:y ].
1311 list add:(MenuDesc title:'origin' value:inst).
1314 point := view relativeCorner.
1315 point isNil ifTrue:[ point := view corner ].
1320 (x == point x and:[y == point y]) ifTrue:[ inst := point ]
1321 ifFalse:[ inst := '%1 --> (%2@%3)' bindWith:point with:x with:y ].
1323 list add:(MenuDesc title:'corner' value:inst).
1326 (point := view relativeExtent) isNil ifTrue:[point := view extent].
1327 list add:(MenuDesc title:'extent' value:point).
1330 list add:(MenuDesc title:'pref. extent' value:(view preferredExtent)).
1331 list add:(MenuDesc separator).
1334 inst := 'l:%1 r:%2 t:%3 b:%4' bindWith:(view leftInset)
1335 with:(view rightInset)
1336 with:(view topInset)
1337 with:(view bottomInset).
1339 list add:(MenuDesc title:'insets' value:inst).
1340 list add:(MenuDesc title:'borderWidth' value:(view borderWidth)).
1341 list add:(MenuDesc title:'level' value:(view level)).
1342 list add:(MenuDesc separator).
1344 (inst := view layout) notNil ifTrue:[ inst := inst displayString ].
1345 list add:(MenuDesc title:'layout' value:inst).
1347 (inst := view transformation) notNil ifTrue:[ inst := inst displayString ].
1348 list add:(MenuDesc title:'transformation' value:inst).
1350 ^ MenuDesc buildFromList:list onGC:aMenu
1353 submenuInspector:aMenu
1354 "builds and returns the inspector submenu"
1356 |view list n names label value|
1358 view := self selectedView.
1359 view isNil ifTrue:[^ nil].
1361 n := view class instSize.
1362 n > 0 ifFalse:[^ nil ].
1364 list := OrderedCollection new:n.
1365 names := view class allInstVarNames.
1367 1 to:n do:[:i| |action|
1368 label := (names at:i) printString.
1369 value := view instVarAt:i.
1370 value isNil ifTrue:[
1374 value := value displayString contractAtEndTo:40.
1375 action := [(view instVarAt:i) inspect].
1377 list add:(MenuDesc title:label value:value action:action).
1380 ^ MenuDesc buildFromList:list onGC:aMenu
1383 submenuInterface:aMenu
1384 "builds and returns the interface submenu"
1386 |view label inst value list|
1388 view := self selectedView.
1389 view isNil ifTrue:[^ nil].
1391 list := OrderedCollection new.
1393 inst := view controller.
1399 inst == view ifTrue:[
1400 label := '== view itself'
1402 label := inst displayString.
1403 value := [view controller inspect].
1406 list add:(MenuDesc title:'controller' value:label action:value).
1408 inst := view delegate.
1409 inst notNil ifTrue:[
1410 list add:(MenuDesc title:'delegate' value:(inst displayString) action:[ view delegate inspect ]).
1413 inst := view application.
1415 inst notNil ifTrue:[
1418 list add:(MenuDesc title:'application' value:inst action:[ view application inspect ]).
1420 topAppl := inst topApplication.
1422 (topAppl notNil and:[topAppl ~~ inst]) ifTrue:[
1423 list add:(MenuDesc title:'topApplication' value:topAppl action:[ inst topApplication inspect ]).
1426 list add:(MenuDesc separator).
1428 (view respondsTo:#'model') ifTrue:[
1432 ifTrue:[ label := value := nil ]
1433 ifFalse:[ label := inst displayString.
1434 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1435 value := [ view model inspect ].
1438 list add:(MenuDesc title:'model' value:label action:value).
1440 (inst notNil and:[view respondsTo:#modelInterface]) ifTrue:[
1441 view modelInterface keysAndValuesDo:[:key : val|
1442 val isNil ifTrue:[ label := nil ]
1443 ifFalse:[ label := val displayString ].
1445 list add:(MenuDesc title:(' - ', key) value:label ).
1450 (view respondsTo:#enableChannel) ifTrue:[
1451 inst := view enableChannel.
1453 inst isNil ifTrue:[ label := value := nil ]
1454 ifFalse:[ label := inst displayString.
1455 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1456 value := [ view enableChannel inspect ].
1459 list add:(MenuDesc title:'enableChannel' value:label action:value).
1462 #( #action #pressAction #releaseAction ) do:[:actionSelector |
1463 (view respondsTo:actionSelector) ifTrue:[
1464 inst := view perform:actionSelector.
1467 ifTrue:[ label := value := nil ]
1468 ifFalse:[ label := inst displayString.
1469 value := [ (view perform:actionSelector) inspect ].
1472 list add:(MenuDesc title:'action' value:label action:value).
1476 list last isSeparator ifFalse:[ list add:(MenuDesc separator) ].
1478 (view respondsTo:#listHolder) ifTrue:[
1479 inst := view listHolder.
1481 inst isNil ifTrue:[ label := value := nil ]
1482 ifFalse:[ label := inst class printString.
1483 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1484 value := [ view listHolder inspect ].
1486 list add:(MenuDesc title:'listHolder' value:label action:value).
1489 (view respondsTo:#list) ifTrue:[
1492 inst isNil ifTrue:[ label := value := nil ]
1493 ifFalse:[ label := '%1 [%2]' bindWith:(inst class printString) with:(inst size).
1494 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1495 value := [ view list inspect ].
1498 list add:(MenuDesc title:'list' value:label action:value).
1501 list last isSeparator ifTrue:[ list removeLast ].
1502 ^ MenuDesc buildFromList:list onGC:aMenu
1504 "Modified: / 27-04-2012 / 14:22:34 / cg"
1507 submenuVisibility:aMenu
1508 "builds and returns the geometry submenu"
1512 view := self selectedView.
1513 view isNil ifTrue:[^ nil].
1515 list := OrderedCollection new.
1517 list add:(MenuDesc title:'device' value:(view device printString)).
1518 list add:(MenuDesc title:'drawableId' value:(view id)).
1519 list add:(MenuDesc title:'gcId' value:(view gcId)).
1521 list add:(MenuDesc separator).
1523 list add:(MenuDesc title:'shown' value:(view shown)).
1524 list add:(MenuDesc title:'realized' value:(view realized)).
1526 list add:(MenuDesc separator).
1528 list add:(MenuDesc title:'hiddenOnRealize' value:(view isHiddenOnRealize)).
1530 (value := view visibilityChannel) isNil ifTrue:[
1531 list add:(MenuDesc title:'visibilityChannel' value:'------').
1533 list add:(MenuDesc title:'visibilityChannel'
1534 value:(value displayString)
1535 action:[view visibilityChannel inspect]).
1538 ^ MenuDesc buildFromList:list onGC:aMenu
1541 !ViewTreeInspectorApplication methodsFor:'private'!
1543 aspectLabelFor:aModel inApplicationOf:aView
1546 aModel isNil ifTrue:[^ ''].
1547 aView isNil ifTrue:[^ ''].
1548 (app := aView application) isNil ifTrue:[^ ''].
1549 app builder bindings keysAndValuesDo:[:aspect :value |
1550 value == aModel ifTrue:[^ ' [aspect: ',aspect,']'].
1552 app class allInstVarNames do:[:nm |
1553 (app instVarNamed:nm) == aModel ifTrue:[^ ' [instvar: ',nm,']']
1558 "Created: / 27-04-2012 / 14:22:09 / cg"
1562 |rootView focusView|
1564 rootView := model rootView.
1566 (rootView notNil and:[rootView shown]) ifTrue:[
1567 focusView := rootView windowGroup focusView.
1569 focusView isNil ifTrue:[^ self ].
1571 self selectView:focusView
1575 |currentItem viewItem|
1577 currentItem := model selectedItem.
1579 (currentItem notNil and:[currentItem widget == aView]) ifTrue:[
1582 viewItem := model listOfItems recursiveDetect:[:el| el widget == aView ].
1584 viewItem notNil ifTrue:[
1585 model selectItem:viewItem.
1589 setRootItem:aRootItemOrNil
1592 aRootItemOrNil isNil ifTrue:[
1595 "/ expand tree to level 3
1596 aRootItemOrNil do:[:aRootChild|
1597 aRootChild do:[:aSubChild| aSubChild expand ].
1600 aRootItemOrNil expand.
1602 process isNil ifTrue:[
1603 theProcess := process :=
1606 |update testModeChannel|
1609 testModeChannel := model testModeChannel.
1611 [process == theProcess] whileTrue:[
1612 Delay waitForSeconds:0.5.
1614 (treeView notNil and:[process == theProcess and:[treeView shown]]) ifTrue:[
1615 (testModeChannel value == true and:[followFocusChannel value == true]) ifTrue:[
1616 self selectFocusView.
1619 self updateShownStatus.
1621 update := update not.
1625 priority:(Processor userSchedulingPriority).
1626 theProcess name:'ViewTreeInspector - Focus Follower'.
1630 model rootItem:aRootItemOrNil.
1632 "Modified: / 25-07-2013 / 12:03:44 / cg"
1636 |rootItem min max visState listIdx visY0 visY1 height damage|
1638 rootItem := model rootItem.
1639 (rootItem notNil and:[rootItem widget shown]) ifFalse:[^ self].
1644 rootItem recursiveEachVisibleItemDo:[:anItem|
1645 visState := (anItem widget shown).
1647 visState ~~ anItem isDrawnShown ifTrue:[
1648 anItem isDrawnShown:visState.
1649 listIdx := treeView identityIndexOf:anItem.
1651 listIdx > 0 ifTrue:[
1652 max := max max:listIdx.
1653 min := min min:listIdx.
1657 max < min ifTrue:[^ self].
1660 visY0 := (treeView yVisibleOfLine:min) max:0.
1661 visY1 := (treeView yVisibleOfLine:max) min:(treeView height).
1662 height := visY1 - visY0.
1665 treeView shown ifTrue:[
1666 damage := Rectangle left:0 top:visY0 width:(treeView width) height:height.
1667 treeView invalidateDeviceRectangle:damage repairNow:false.
1672 !ViewTreeInspectorApplication methodsFor:'selection'!
1675 "answer the selected view or nil"
1679 item := model selectedItem.
1680 item notNil ifTrue:[ ^ item widget ].
1684 !ViewTreeInspectorApplication methodsFor:'testing'!
1686 resolveApplicationClassFor:aTreeItem
1687 aTreeItem isApplicationClass ifTrue:[
1688 ^ aTreeItem applicationClass
1693 selectedComponentHasChildren
1696 item := model selectedItem.
1697 ^ (item notNil and:[item hasChildren])
1700 !ViewTreeInspectorApplication methodsFor:'user operations'!
1705 #model browse model class
1706 #application browse application class
1707 #controller browse controller class
1711 view := self selectedView.
1712 view isNil ifTrue:[^ self].
1714 what == #view ifTrue:[ inst := view ]
1715 ifFalse:[what == #model ifTrue:[ inst := view model ]
1716 ifFalse:[what == #application ifTrue:[ inst := view application ]
1717 ifFalse:[what == #controller ifTrue:[ inst := view controller ]
1722 inst notNil ifTrue:[
1723 inst class browserClass openInClass:(inst class) selector:nil
1728 "destroy the current selected view"
1732 item := model selectedItem.
1733 item isNil ifTrue:[ ^ self].
1735 parent := item parent.
1737 parent isNil ifTrue:[
1739 model withSelectionHiddenDo:[item deleteAll].
1743 model withSelectionHiddenDo:[
1746 idx := parent identityIndexOf:item.
1748 idx == parent size ifTrue:[
1749 nsel := parent at:(idx - 1) ifAbsent:parent
1751 nsel := parent at:(idx + 1)
1756 parent isLayoutContainer ifTrue:[
1757 parent widget sizeChanged:nil
1764 "flash the selected view"
1768 view := self selectedView.
1769 view isNil ifTrue:[ ^ self].
1772 model withSelectionHiddenDo:[
1773 view perform:#flash ifNotUnderstood:nil.
1781 #group inspect windowGroup
1782 #model inspect model
1783 #application inspect application
1784 #controller inspect controller
1785 #process inspect application's process
1789 inst := self selectedView.
1790 inst isNil ifTrue:[^ self].
1792 what == #group ifTrue:[ inst := inst windowGroup ]
1793 ifFalse:[what == #model ifTrue:[ inst := inst model ]
1794 ifFalse:[what == #application ifTrue:[ inst := inst application ]
1795 ifFalse:[what == #controller ifTrue:[ inst := inst controller ]
1796 ifFalse:[what == #process ifTrue:[ inst := inst windowGroup process ]]]]].
1798 inst notNil ifTrue:[ inst inspect ].
1801 doOpenProcessMonitor
1802 (ProcessMonitorV2 ? ProcessMonitor) open
1804 "Created: / 25-07-2013 / 12:34:23 / cg"
1808 "pick a window's topView"
1810 |screen clickedView topWindow cursor|
1814 cursor := Cursor fromImage:(self class crossHairIcon).
1816 screen := Screen current.
1817 clickedView := screen viewFromPoint:(screen pointFromUserShowing:cursor).
1818 clickedView isNil ifTrue:[^ self].
1820 topWindow := clickedView topView.
1822 ( topWindow == Screen current rootView
1823 or:[topWindow == self window topView]
1828 self showWindow:clickedView
1834 model rootView withAllSubViewsDo:[:v | v redraw; invalidate].
1837 doSelectNextOfApplicationClass:aClass startingIn:anItem
1838 |startItem firstFound searchNext|
1840 startItem := model last.
1841 searchNext := startItem notNil.
1844 anItem recursiveDo:[:el|
1845 el == startItem ifTrue:[
1848 (self resolveApplicationClassFor:el) == aClass ifTrue:[
1849 searchNext ifFalse:[^ model selectItem:el].
1851 firstFound isNil ifTrue:[
1857 firstFound notNil ifTrue:[
1859 model selectItem:firstFound
1863 doSelectNextOfClass:aClass startingIn:anItem
1864 |startItem firstFound searchNext|
1866 startItem := model last.
1867 searchNext := startItem notNil.
1870 anItem recursiveDo:[:el|
1871 el == startItem ifTrue:[
1874 el widget class == aClass ifTrue:[
1875 searchNext ifFalse:[^ model selectItem:el].
1877 firstFound isNil ifTrue:[
1883 firstFound notNil ifTrue:[
1885 model selectItem:firstFound
1890 model catchEvents:false.
1895 "release current picked window and contained subwindows"
1897 self setRootItem:nil.
1901 HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#VIEWTREEINSPECTOR'
1905 "show a particular window's topView hierarchy,
1906 select the given view"
1910 topWindow := aView topView.
1912 model catchEvents:true.
1913 self setRootItem:(ViewTreeItem buildViewsFrom:topWindow).
1914 self selectView:aView.
1917 !ViewTreeInspectorApplication::MenuDesc class methodsFor:'building'!
1919 buildFromList:aList onGC:aMenu
1920 |tabSpec menu w menuPanel|
1923 aList do:[:el| w := w max:(el widthOn:aMenu) ].
1925 tabSpec := TabulatorSpecification new.
1926 tabSpec unit:#pixel.
1927 tabSpec positions:#(0 1.5 ).
1928 tabSpec align:#(#left #left).
1931 tabSpec positions:(Array with:0 with:w).
1936 menu addItem:(el asMenuItemWithTabulatorSpecification:tabSpec).
1938 menuPanel := MenuPanel menu:menu.
1942 !ViewTreeInspectorApplication::MenuDesc class methodsFor:'instance creation'!
1948 title:aTitle value:aValue
1949 ^ self title:aTitle value:aValue action:nil
1952 title:aTitle value:aValue action:anAction
1953 ^ self new title:aTitle value:aValue action:anAction
1956 !ViewTreeInspectorApplication::MenuDesc methodsFor:'accessing'!
1962 !ViewTreeInspectorApplication::MenuDesc methodsFor:'building'!
1964 asMenuItemWithTabulatorSpecification:aTabSpec
1967 title isNil ifTrue:[ ^ MenuItem label:value ]. "/ separator
1969 array := Array with:(title, ':') with:'------'.
1971 value notNil ifTrue:[
1972 array at:2 put:(value printString, ' ')
1976 label:(MultiColListEntry fromStrings:array tabulatorSpecification:aTabSpec)
1980 !ViewTreeInspectorApplication::MenuDesc methodsFor:'instance creation'!
1982 title:aTitle value:aValue action:anAction
1985 title := aTitle withoutSeparators.
1988 aValue notNil ifTrue:[
1989 value := aValue printString.
1991 value size > 70 ifTrue:[
1992 value := value copyFrom:1 to:70.
1993 value := value, '...'
1998 !ViewTreeInspectorApplication::MenuDesc methodsFor:'queries'!
2005 title isNil ifTrue:[^ 5]. "/ separator
2009 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'building'!
2011 buildViewsFrom:aView
2012 "build the items starting from a source view;
2015 |item subViews subItems|
2017 aView isNil ifTrue:[^ nil].
2019 item := self forView:aView.
2020 subViews := aView subViews.
2022 subViews notEmptyOrNil ifTrue:[
2023 subItems := OrderedCollection new.
2024 subViews do:[:aSubView|
2025 subItems add:(self buildViewsFrom:aSubView).
2027 item children:subItems.
2032 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'documentation'!
2036 ViewTreeItems represants a pickable object within a ViewTreeModel.
2037 The class is used to build up the hierarchical tree.
2039 [Instance variables:]
2040 widget <View> the widget represented by the item
2041 spec <UISpecification> the UISpecification or nil
2044 HandleExtent <Point> keeps the extent of a handle
2060 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'initialization'!
2063 "set the extent of the Handle
2065 HandleExtent := 6@6.
2068 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'instance creation'!
2073 item := self basicNew initialize.
2079 self error:'not allowed'.
2083 on:aView withSpec:aSpec
2086 item := self basicNew initialize.
2087 item on:aView withSpec:aSpec.
2091 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'accessing'!
2096 widget notNil ifTrue:[
2097 appl := widget application.
2098 appl notNil ifTrue:[^ appl class ].
2104 "returns true if the last display operations was done during the widget was shown
2109 isDrawnShown:aBoolean
2110 isDrawnShown := aBoolean.
2114 "returns the widget assigned to the root or nil
2120 "returns the spec-class assigned to the item
2126 "returns the assigned treeModel, an instance of ViewTreeModel
2132 "returns the widget assigned to the item
2137 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'accessing layout'!
2139 boundsRelativeToRoot
2140 "returns the bounds relative to the root widget
2142 ^ self originRelativeToRoot extent:(widget extent)
2145 cornerRelativeToRoot
2146 "returns the corner relative to the root widget
2148 ^ self originRelativeToRoot + (widget extent)
2152 "returns the extent of the widget
2158 "returns the type of layout assigned to the wiget; nil if the
2159 superView cannot resize its sub widgets
2161 |layout specClass superView|
2163 (superView := widget superView) isNil ifTrue:[
2167 specClass := superView specClass.
2169 (specClass notNil and:[specClass isLayoutContainer]) ifTrue:[
2170 ^ specClass canResizeSubComponents ifTrue:[#Extent] ifFalse:[nil]
2173 (layout := widget geometryLayout) isNil ifTrue:[
2177 layout isLayout ifTrue:[
2178 layout isLayoutFrame ifTrue:[ ^ #LayoutFrame ].
2179 layout isAlignmentOrigin ifTrue:[ ^ #AlignmentOrigin ].
2180 layout isLayoutOrigin ifTrue:[ ^ #LayoutOrigin ].
2182 layout isRectangle ifTrue:[ ^ #Rectangle ].
2183 layout isPoint ifTrue:[ ^ #Point ].
2186 Transcript showCR:'UNSUPPORTRD LAYOUT: ', layout printString.
2190 originRelativeToRoot
2191 "returns the origin relative to the root widget
2193 ^ widget originRelativeTo:(self rootView)
2196 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'accessing optimize'!
2199 "redefined: optimize
2205 |subViews list item|
2207 children size ~~ 0 ifTrue:[
2210 isExpanded := false.
2211 subViews := widget subViews.
2213 subViews size == 0 ifTrue:[^ false].
2215 list := OrderedCollection new.
2217 subViews do:[:aSubView|
2218 item := self class buildViewsFrom:aSubView.
2227 "redefined: returns list of children
2232 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'displaying'!
2234 additionalLabelForItem:anItem
2235 "answer an additional label for an Item"
2237 parent notNil ifTrue:[
2238 ^ parent additionalLabelForItem:anItem
2243 displayIcon:anIcon atX:x y:y on:aGC
2246 super displayIcon:anIcon atX:x y:y on:aGC.
2248 self exists ifFalse:[
2249 aGC paint:(Color red).
2252 y1 := y + anIcon height - 2.
2258 aGC displayLineFromX:x0 y:y0 toX:(x0 + w) y:y1.
2259 aGC displayLineFromX:x0 y:y1 toX:(x0 + w) y:y0.
2265 displayOn:aGC x:x y:y h:h
2266 |labelHeight additionalName label isValidAndShown|
2268 label := self label.
2269 label isEmptyOrNil ifTrue:[^ self].
2271 widget id isNil ifTrue:[
2272 isDrawnShown := false.
2274 self exists ifFalse:[
2275 xOffsetAdditionalName := nil.
2277 isValidAndShown := false.
2279 isValidAndShown := widget shown.
2281 isValidAndShown ifFalse:[
2282 label := Text string:label emphasis:#italic.
2283 label colorizeAllWith:Color grey.
2286 labelHeight := self heightOn:aGC.
2287 self displayLabel:label h:labelHeight on:aGC x:x y:y h:h.
2289 xOffsetAdditionalName notNil ifTrue:[
2290 additionalName := self additionalLabelForItem:self.
2292 additionalName notNil ifTrue:[
2293 self displayLabel:additionalName
2294 h:labelHeight on:aGC
2295 x:(x + xOffsetAdditionalName)
2299 xOffsetAdditionalName := nil.
2304 recursiveAdditionalNameBehaviourChanged
2305 width := xOffsetAdditionalName := nil.
2307 children notNil ifTrue:[
2308 children do:[:each| each recursiveAdditionalNameBehaviourChanged ]
2313 "return the width of the receiver, if it is to be displayed on aGC
2317 width isNil ifTrue:[
2318 width := self widthOf:(self label) on:aGC.
2321 additionalName := self additionalLabelForItem:self.
2323 additionalName notNil ifTrue:[
2324 xOffsetAdditionalName := width + 10.
2325 width := xOffsetAdditionalName + (self widthOf:additionalName on:aGC).
2328 xOffsetAdditionalName := nil.
2334 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'enumerating'!
2336 handlesDo:aTwoArgAction
2337 "evaluate the two arg block on each handle; the arguments to the block is
2338 the rectangle relative to the rootView and the handle type which is
2339 set to nil if not resizeable.
2341 TYPES: type position( X - Y )
2342 -------------------------
2352 nil ** handle not pickable **
2354 |type relOrg relCrn maxExt rootView w h
2355 xL "{ Class:SmallInteger }"
2356 xC "{ Class:SmallInteger }"
2357 xR "{ Class:SmallInteger }"
2358 yT "{ Class:SmallInteger }"
2359 yC "{ Class:SmallInteger }"
2360 yB "{ Class:SmallInteger }"
2362 rootView := self rootView.
2363 relOrg := widget originRelativeTo:rootView.
2364 relOrg isNil ifTrue:[ ^ self ]. "/ widget destroyed
2366 relOrg := relOrg - (HandleExtent // 2).
2367 relCrn := relOrg + widget extent.
2368 maxExt := rootView extent - HandleExtent.
2370 xL := relOrg x max:0.
2371 xR := relCrn x min:(maxExt x).
2374 yT := relOrg y max:0.
2375 yB := relCrn y min:(maxExt y).
2378 type := self layoutType.
2379 w := HandleExtent x.
2380 h := HandleExtent y.
2382 (type == #LayoutFrame or:[type == #Rectangle]) ifTrue:[
2383 aTwoArgAction value:(Rectangle left:xL top:yT width:w height:h) value:#LT.
2384 aTwoArgAction value:(Rectangle left:xL top:yC width:w height:h) value:#LC.
2385 aTwoArgAction value:(Rectangle left:xL top:yB width:w height:h) value:#LB.
2386 aTwoArgAction value:(Rectangle left:xC top:yT width:w height:h) value:#CT.
2387 aTwoArgAction value:(Rectangle left:xC top:yB width:w height:h) value:#CB.
2388 aTwoArgAction value:(Rectangle left:xR top:yT width:w height:h) value:#RT.
2389 aTwoArgAction value:(Rectangle left:xR top:yC width:w height:h) value:#RC.
2390 aTwoArgAction value:(Rectangle left:xR top:yB width:w height:h) value:#RB.
2394 aTwoArgAction value:(Rectangle left:xL top:yT width:w height:h) value:nil.
2395 aTwoArgAction value:(Rectangle left:xL top:yB width:w height:h) value:nil.
2396 aTwoArgAction value:(Rectangle left:xR top:yT width:w height:h) value:nil.
2398 type == #Extent ifTrue:[
2399 aTwoArgAction value:(Rectangle left:xC top:yB width:w height:h) value:#CB.
2400 aTwoArgAction value:(Rectangle left:xR top:yC width:w height:h) value:#RC.
2401 aTwoArgAction value:(Rectangle left:xR top:yB width:w height:h) value:#RB.
2404 aTwoArgAction value:(Rectangle left:xR top:yB width:w height:h) value:nil.
2407 recursiveEachVisibleItemDo:anOneArgBlock
2408 "recursive evaluate the block on each child which is visible
2410 (isExpanded and:[children size > 0]) ifTrue:[
2411 children do:[:aChild|
2412 anOneArgBlock value:aChild.
2413 aChild recursiveEachVisibleItemDo:anOneArgBlock.
2418 subViewsDo:aOneArgBlock
2419 "evaluate aBlock for all subviews other than InputView's
2423 subViews := widget subViews.
2425 subViews notNil ifTrue:[
2426 subViews do:aOneArgBlock
2430 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'initialization'!
2437 "setup default attributes
2440 isDrawnShown := false.
2441 isExpanded := false.
2442 children := OrderedCollection new.
2445 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'operations delete'!
2448 "delete self and all contained items; the assigned views are destroyed
2449 in case of rootView, only the children are deleted
2451 parent isHierarchicalItem ifTrue:[
2462 "delete all contained items; the assigned views are destroyed
2464 children size == 0 ifTrue:[^ self].
2467 self nonCriticalDo:[:el| el widget destroy ].
2472 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'operations layout'!
2475 "convert the layout of the widget to a LayoutFrame;
2477 |extent layout newLyt lftFrc lftOff topFrc topOff|
2479 layout := widget geometryLayout.
2481 layout isNil ifTrue:[
2482 ^ widget bounds asLayout
2485 layout isLayout ifFalse:[
2486 layout isRectangle ifTrue:[
2487 ^ LayoutFrame leftOffset:(layout left) rightOffset:(layout right)
2488 topOffset:(layout top) bottomOffset:(layout bottom)
2490 layout isPoint ifTrue:[
2491 extent := widget extent.
2492 ^ LayoutFrame leftOffset:(layout x) rightOffset:(layout x + extent x)
2493 topOffset:(layout y) bottomOffset:(layout y + extent y)
2496 Transcript showCR:'UNSUPPORTRD LAYOUT: ', layout printString.
2500 layout isLayoutFrame ifTrue:[ ^ layout copy ].
2502 lftFrc := layout leftFraction.
2503 lftOff := layout leftOffset.
2504 topFrc := layout topFraction.
2505 topOff := layout topOffset.
2506 extent := widget extent.
2508 newLyt := LayoutFrame leftFraction:lftFrc offset:lftOff
2509 rightFraction:lftFrc offset:(lftOff + extent x)
2510 topFraction:topFrc offset:topOff
2511 bottomFraction:topFrc offset:(topOff + extent y).
2513 ( layout isAlignmentOrigin
2514 and:[(layout leftAlignmentFraction ~= 0 or:[layout topAlignmentFraction ~= 0])]
2518 svRc := widget superView viewRectangle.
2519 prBd := widget preferredBounds.
2521 dlta := ( ((layout rectangleRelativeTo:svRc preferred:prBd) corner)
2522 - ((newLyt rectangleRelativeTo:svRc preferred:prBd) corner)
2525 newLyt leftOffset:(lftOff + dlta x).
2526 newLyt rightOffset:(lftOff + extent x + dlta x).
2527 newLyt topOffset:(topOff + dlta y).
2528 newLyt bottomOffset:(topOff + extent y + dlta y).
2534 "move the widget n pixele left and right
2538 self isMoveable ifFalse:[ ^ self ].
2540 (layout := widget geometryLayout) isNil ifTrue:[
2542 widget origin:(widget origin + (l@t)).
2546 layout := layout copy.
2548 layout isLayout ifTrue:[
2549 layout leftOffset:(layout leftOffset + l)
2550 topOffset:(layout topOffset + t).
2552 layout isLayoutFrame ifTrue:[
2553 layout rightOffset:(layout rightOffset + l).
2554 layout bottomOffset:(layout bottomOffset + t).
2558 layout isRectangle ifTrue:[
2559 layout setLeft:(layout left + l).
2560 layout setTop:(layout top + t).
2562 layout isPoint ifFalse:[^ self].
2563 layout x:(layout x + l) y:(layout y + t).
2566 widget geometryLayout:layout.
2569 resizeLeft:l top:t right:r bottom:b
2570 "resize the widget measured in pixels
2574 self isResizeable ifFalse:[
2578 (layout := widget geometryLayout) isNil ifTrue:[
2580 (r == l and:[b == t]) ifFalse:[
2581 widget extent:(widget computeExtent + ((r-l) @ (b-t))).
2586 layout isLayout ifTrue:[
2587 layout := layout copy.
2589 layout leftOffset:(layout leftOffset + l)
2590 topOffset:(layout topOffset + t).
2592 layout isLayoutFrame ifTrue:[
2593 layout bottomOffset:(layout bottomOffset + b).
2594 layout rightOffset:(layout rightOffset + r).
2597 layout isRectangle ifFalse:[^ self].
2598 layout := layout copy.
2600 layout left:(layout left + l)
2601 right:(layout right + r)
2602 top:(layout top + t)
2603 bottom:(layout bottom + b).
2605 widget geometryLayout:layout.
2608 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'operations update'!
2617 list isNil ifTrue:[list := OrderedCollection new].
2621 list notNil ifTrue:[
2622 list do:[:el| self remove:el ].
2626 updateFromChildren:mergedList
2627 "update my children against the list of items derived from
2631 mergedList size == 0 ifTrue:[ ^ self removeAll ].
2632 children size == 0 ifTrue:[ ^ self addAll:mergedList ].
2635 self nonCriticalDo:[:el| |wdg|
2637 mergedList detect:[:e2| e2 widget == wdg ] ifNone:[ self remove:el ].
2640 mergedList keysAndValuesDo:[:i :el| |wdg e2|
2643 e2 := self at:i ifAbsent:nil.
2645 (e2 isNil or:[e2 widget ~~ wdg]) ifTrue:[
2646 self add:el beforeIndex:i
2652 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'printing & storing'!
2655 "get the icon used for presentation
2659 specClass := self specClass.
2660 specClass isNil ifTrue:[^ nil].
2662 model := self treeModel.
2664 model notNil ifTrue:[
2665 ^ model iconAt:specClass ifNonePut:[specClass icon]
2671 "get the label used for presentation
2677 "append a a printed representation of the item to aStream
2679 aStream nextPutAll:(self string)
2685 ^ widget class name.
2688 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'queries'!
2691 "returns true if the layout of the widget can be changed and the
2692 layout is not organized by its superView
2697 canResizeSubComponents
2698 "returns true if the widget can resize its sub components
2702 specClass := self specClass.
2704 specClass notNil ifTrue:[
2705 ^ specClass canResizeSubComponents
2711 widget id notNil ifTrue:[^ true ].
2713 exists ~~ false ifTrue:[
2716 widget superView notNil ifTrue:[
2717 (parent isHierarchicalItem and:[parent exists]) ifTrue:[
2718 exists := (parent widget subViews includesIdentical:widget).
2728 cls := widget class.
2730 ^ ( cls == ApplicationSubView
2731 or:[cls == ApplicationWindow
2732 or:[cls == SubCanvas]]
2739 model := self treeModel.
2740 model notNil ifTrue:[^ model isSelected:self].
2744 supportsSubComponents
2745 "returns true if the widget supports sub components
2749 widget isScrollWrapper ifTrue:[
2752 specClass := self specClass.
2754 specClass notNil ifTrue:[
2755 ^ specClass supportsSubComponents
2760 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'testing'!
2763 "returns true if the widget is in a layout container
2767 sv := widget superView.
2770 specClass := sv specClass.
2772 specClass notNil ifTrue:[
2773 ^ specClass isLayoutContainer
2780 "answer whether corresponding view instances of the spec class can contain
2781 (and arrange) other view
2785 specClass := self specClass.
2787 specClass notNil ifTrue:[
2788 ^ specClass isLayoutContainer
2794 "returns true if the widget is not in a layout container
2796 self isInLayoutContainer ifFalse:[
2797 ^ widget superView notNil
2803 "returns true if the widget is resizeable
2807 sv := widget superView.
2810 specClass := sv specClass.
2812 specClass notNil ifTrue:[
2813 ^ specClass canResizeSubComponents
2819 !ViewTreeInspectorApplication::ViewTreeModel class methodsFor:'documentation'!
2823 Instances of ViewTreeModel can be used as model on a View and all
2824 it contained subviews for a HierarchicalListView.
2825 The model keeps two values, the hierarchical representation of the views
2826 and subviews (ViewTreeItems) and the selection, a list of selected ViewTreeItems's.
2827 It shows the selected items highlighted.
2830 [Instance variables:]
2831 lockSema <Semaphore> lock selection notifications and redraws
2833 testModeChannel <ValueHolder> true, than running in test mode.
2835 hasTargetWidgetChannel <ValueHolder> true, than any target view is grapped
2837 selection <Sequence or nil> selected items or nil
2839 hiddenLevel <Integer> internal use; redrawing the selection
2840 only is done if the counter is 0.
2842 listOfItems <HierarchicalList> hiearchical list build from existing items.
2844 selectedSuperItems <Sequence> list of selected super items; items selected
2845 but not contained in another selected item.
2847 inputEventAction <Action> called for each InputEvent
2849 mappedViewAction <Action> called for a new mapped view which
2850 can not be found in the current item list.
2852 beforeSelectionChangedAction <Action> called before the selection changed
2864 example 1: pick any window and show views and contained views
2866 |top sel model panel|
2868 model := ViewTreeModel new.
2869 top := StandardSystemView new; extent:440@400.
2870 sel := ScrollableView for:HierarchicalListView miniScroller:true origin:0.0@0.0 corner:1.0@1.0 in:top.
2873 panel := HorizontalPanelView origin:0.0@1.0 corner:1.0@1.0 in:top.
2875 panel horizontalLayout:#fitSpace.
2877 Button label:'Exit' action:[model rootItem:nil. top destroy] in:panel.
2878 Button label:'Pick Views' action:[ |win|
2879 ( (win := Screen current viewFromUser) notNil
2880 and:[(win := win topView) ~~ Screen current rootView
2883 model rootItem:(ViewTreeItem buildViewsFrom:win)
2889 sel multipleSelectOk:true.
2890 sel list:model listOfItems.
2894 sel doubleClickAction:[:i| |el|
2895 el := model listOfItems at:i.
2896 el spec notNil ifTrue:[ el spec inspect ] ifFalse:[ el widget inspect ]
2898 sel indicatorAction:[:i| (model listOfItems at:i) toggleExpand ].
2900 model inputEventAction:[:anEvent| |item|
2901 anEvent isButtonEvent ifTrue:[
2902 anEvent isButtonPressEvent ifTrue:[
2903 model selectedItem:(model listOfItems detectItemRespondsToView:(anEvent view)).
2905 anEvent type == #'buttonMultiPress:x:y:' ifTrue:[
2906 (item := model selectedItem) notNil ifTrue:[item widget inspect]
2913 [[top shown] whileTrue:[Delay waitForSeconds:0.5]. model rootItem:nil] forkAt:8
2919 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing'!
2921 application:anApplication
2922 listOfItems application:anApplication.
2925 catchEvents:aBoolean
2926 catchEvents := aBoolean.
2928 self redrawUnselected:selection andLock:false checkTestMode:false.
2933 "get the rootItem the event viewer is established on
2939 "set the rootItem the event viewer is established on
2943 timedUpdateTask := nil.
2947 anItem notNil ifTrue:[ expanded := anItem isExpanded ]
2948 ifFalse:[ expanded := false ].
2951 listOfItems root:anItem.
2953 anItem notNil ifTrue:[
2954 timedUpdateTask := Process for:[ self timedUpdateTaskCycle ] priority:8.
2955 timedUpdateTask name:'Update'.
2956 timedUpdateTask resume.
2960 (expanded and:[anItem notNil]) ifTrue:[
2967 "get the top widget the event viewer is established on, a View
2969 ^ listOfItems rootView
2972 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing actions'!
2974 beforeSelectionChangedAction
2975 "none argument action which is called before
2976 the selection changed
2978 ^ beforeSelectionChangedAction
2981 beforeSelectionChangedAction:aNoneArgBlock
2982 "none argument action which is called before
2983 the selection changed
2985 beforeSelectionChangedAction := aNoneArgBlock.
2989 "called for each input event; the argument to the action is the WindowEvent
2994 inputEventAction:aOneArgActionTheEvent
2995 "called for each input event; the argument to the action is the WindowEvent
2997 inputEventAction := aOneArgActionTheEvent.
3001 "called for a new mapped view which can not be found
3002 in the current item list
3007 mappedViewAction:aOneArgBlockTheMappedView
3008 "called for a new mapped view which can not be found
3009 in the current item list
3011 mappedViewAction := aOneArgBlockTheMappedView
3014 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing look'!
3016 iconAt:aKey ifNonePut:aNoneArgBlock
3019 icon := icons at:aKey ifAbsent:nil.
3020 icon notNil ifTrue:[^ icon].
3022 icon := aNoneArgBlock value.
3023 icon isNil ifTrue:[^ nil].
3025 view := self rootView.
3026 view isNil ifTrue:[^ icon].
3028 icon := icon copy onDevice:(view device).
3029 icon isImage ifTrue:[
3030 icon clearMaskedPixels.
3032 icons at:aKey put:icon.
3036 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing visibility'!
3039 "show the selection if signaled; increments hiddenLevel
3040 see: #waitHiddenLevel
3042 (hiddenLevel := hiddenLevel - 1) < 1 ifTrue:[
3044 self invalidateSelection.
3049 "hide the selection until signaled; increments hiddenLevel
3050 see: #signalHiddenLevel
3052 self redrawUnselected:selection andLock:true
3055 withSelectionHiddenDo:aNoneArgumentBlock
3056 "apply block with selection hidden
3059 [ self waitHiddenLevel.
3061 aNoneArgumentBlock value
3063 ] valueNowOrOnUnwindDo:[
3064 self signalHiddenLevel.
3068 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'aspects'!
3070 hasTargetWidgetChannel
3071 "answer the channel which is set to true if a target widget exists"
3073 ^ hasTargetWidgetChannel
3077 "hiearchical list build from existing items"
3083 "boolean holder, which indicates whether the selection will change on click
3085 ^ selectOnClickHolder
3089 "answer a boolean channel which describes the behaviour how to process
3090 events on the target view.
3092 false: all input events are eaten and the selection is shown on the target view.
3093 true: no input events are eaten and no selection is shown on the target view."
3098 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'change & update'!
3101 hasTargetWidgetChannel value:(self rootItem notNil).
3104 timedUpdateTaskCycle
3107 myTaskId := timedUpdateTask.
3109 listOfItems root notNil ifTrue:[
3110 view := listOfItems root widget.
3113 [ view notNil ] whileTrue:[
3114 Delay waitForSeconds:0.5.
3116 (myTaskId == timedUpdateTask and:[view id notNil]) ifFalse:[
3119 (view sensor hasUserEvent:#updateChildren for:self) ifFalse:[
3120 view sensor pushUserEvent:#updateChildren for:self.
3124 timedUpdateTask == myTaskId ifTrue:[
3125 timedUpdateTask := nil.
3126 listOfItems root:nil.
3130 update:something with:someArgument from:aModel
3132 aModel == testModeChannel ifTrue:[
3133 (hiddenLevel == 0 and:[selection size > 0]) ifTrue:[
3134 testModeChannel value ifTrue:[
3135 self redrawUnselected:selection andLock:false checkTestMode:false.
3137 self invalidateSelection.
3142 super update:something with:someArgument from:aModel.
3148 rootItem := listOfItems root.
3149 rootItem isNil ifTrue:[^ self].
3151 rootItem exists ifFalse:[
3152 listOfItems root:nil.
3154 rootItem updateChildren.
3158 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'event processing'!
3160 processEvent:anEvent
3161 "catch and process all WindowEvents for the rootComponent and its contained
3162 widgets; redraw selection in case of damage...
3163 return true, if the event was eaten"
3165 |evView item rootView testMode|
3167 catchEvents ifFalse:[^ false].
3169 evView := anEvent view.
3170 evView isNil ifTrue:[
3171 (anEvent isMessageSendEvent not or:[anEvent receiver ~~ self]) ifTrue:[
3177 rootView := listOfItems rootView.
3178 rootView isNil ifTrue:[ ^ false ].
3180 anEvent isConfigureEvent ifTrue:[
3181 hiddenLevel == 0 ifTrue:[
3182 self redrawUnselected:selection andLock:false.
3187 "/ check whether view is contained within the rootView
3188 (evView == rootView or:[evView isComponentOf:rootView]) ifFalse:[
3192 anEvent isInputEvent ifFalse:[
3193 anEvent isDamage ifTrue:[
3194 hiddenLevel == 0 ifTrue:[self invalidateSelection].
3198 anEvent isMapEvent ifTrue:[
3199 mappedViewAction notNil ifTrue:[
3200 item := listOfItems recursiveDetect:[:el| el widget == evView].
3201 item isNil ifTrue:[ mappedViewAction value:evView ]
3206 anEvent type == #terminate ifTrue:[
3207 item := listOfItems recursiveDetect:[:el| el widget == evView].
3208 item notNil ifTrue:[ self processTerminateForItem:item ].
3213 testMode := testModeChannel value.
3215 anEvent isFocusEvent ifTrue:[
3216 evView == rootView ifTrue:[
3217 self invalidateSelection
3221 anEvent isPointerEnterLeaveEvent ifTrue:[ ^ testMode not ].
3224 inputEventAction notNil ifTrue:[ inputEventAction value:anEvent ].
3226 anEvent isButtonPressEvent ifTrue:[
3227 selectOnClickHolder value ifTrue:[
3228 self selectItem:(listOfItems detectItemRespondsToView:evView).
3233 (hiddenLevel ~~ 0 and:[anEvent isButtonReleaseEvent]) ifTrue:[
3235 self signalHiddenLevel.
3241 processTerminateForItem:anItem
3242 "received terminate for an item
3247 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'initialization'!
3250 "setup the default attributes
3255 lockSema := RecursionLock new.
3256 listOfItems := ItemList new on:self.
3257 selectedSuperItems := #().
3258 icons := IdentityDictionary new.
3259 catchEvents := true.
3261 hasTargetWidgetChannel := false asValue.
3262 selectOnClickHolder := true asValue.
3264 testModeChannel := false asValue.
3265 testModeChannel addDependent:self.
3268 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'private selection'!
3271 "invalidate the current selection
3275 testModeChannel value ifTrue:[ ^ self ]. "/ test whether running testMode
3278 and:[selection notNil
3279 and:[(topView := listOfItems rootView) notNil
3280 and:[topView shown]]]
3282 topView sensor pushUserEvent:#redrawSelection for:self withArguments:#()
3286 recursiveRepair:theDamages startIn:aView relativeTo:aRootView
3287 "repair all views and contained views, which intersects the damage.
3288 !!!! all damages repaired are removed from the list of damages !!!!
3290 |color relOrg damage subViews repaired
3291 bwWidth "{ Class:SmallInteger }"
3292 x "{ Class:SmallInteger }"
3293 y "{ Class:SmallInteger }"
3294 w "{ Class:SmallInteger }"
3295 h "{ Class:SmallInteger }"
3296 relOrgX "{ Class:SmallInteger }"
3297 relOrgY "{ Class:SmallInteger }"
3298 width "{ Class:SmallInteger }"
3299 height "{ Class:SmallInteger }"
3300 size "{ Class:SmallInteger }"
3302 (aView shown and:[theDamages notEmpty]) ifFalse:[ ^ self ].
3304 subViews := aView subViews.
3306 subViews size ~~ 0 ifTrue:[
3307 subViews reverseDo:[:v| self recursiveRepair:theDamages startIn:v relativeTo:aRootView ].
3308 theDamages isEmpty ifTrue:[ ^ self ].
3311 relOrg := aView originRelativeTo:aRootView.
3312 bwWidth := aView borderWidth.
3313 size := theDamages size.
3315 "/ compute relative origin starting from border left@top
3316 relOrgX := relOrg x - bwWidth.
3317 relOrgY := relOrg y - bwWidth.
3318 width := aView width + bwWidth + bwWidth.
3319 height := aView height + bwWidth + bwWidth.
3321 size to:1 by:-1 do:[:anIndex|
3322 repaired := damage := theDamages at:anIndex.
3324 "/ compute the rectangle into the view
3325 y := damage top - relOrgY.
3326 x := damage left - relOrgX.
3330 x < 0 ifTrue:[ w := w + x. x := 0. repaired := nil ].
3331 y < 0 ifTrue:[ h := h + y. y := 0. repaired := nil ].
3332 x + w > width ifTrue:[ w := width - x. repaired := nil ].
3333 y + h > height ifTrue:[ h := height - y. repaired := nil ].
3335 (w > 0 and:[h > 0]) ifTrue:[
3336 bwWidth ~~ 0 ifTrue:[
3337 color isNil ifTrue:[
3338 "/ must force redraw of border
3339 color := aView borderColor.
3340 aView borderColor:(Color colorId:1).
3341 aView borderColor:color.
3346 (x := x - bwWidth) < 0 ifTrue:[w := w + x. x := 0].
3347 (y := y - bwWidth) < 0 ifTrue:[h := h + y. y := 0].
3349 h > 0 ifFalse:[w := 0]. "/ later testing on width only
3353 aView clearRectangleX:x y:y width:w height:h.
3354 aView exposeX:x y:y width:w height:h
3356 repaired notNil ifTrue:[ theDamages removeFromIndex:anIndex toIndex:anIndex ].
3362 "redraw all items selected
3366 testModeChannel value ifTrue:[ ^ self ]. "/ test whether running testMode
3369 and:[(size := selection size) > 0
3370 and:[(topView := listOfItems rootView) notNil
3372 and:[(topView sensor hasEvent:#redrawSelection for:self) not]]]]
3382 list size > 0 ifTrue:[
3383 topView paint:(Color black).
3384 topView clippedByChildren:false.
3386 list keysAndValuesReverseDo:[:anIndex :anItem|
3387 (anIndex == 1 and:[size > 1]) ifTrue:[ topView paint:(Color red) ].
3389 anItem handlesDo:[:aRect :what|
3390 what isNil ifTrue:[topView displayRectangle:aRect]
3391 ifFalse:[topView fillRectangle:aRect]
3394 topView clippedByChildren:true.
3399 redrawUnselected:aList andLock:doLock
3400 "redraw all items unselected; if doLock is true, the hiddenLevel
3401 is incremented and thus the select mechanism is locked.
3403 self redrawUnselected:aList andLock:doLock checkTestMode:true.
3406 redrawUnselected:aList andLock:doLock checkTestMode:checkTestMode
3407 "redraw all items unselected; if doLock is true, the hiddenLevel
3408 is incremented and thus the select mechanism is locked.
3410 |rootView damages subViews x y w h|
3413 hiddenLevel := hiddenLevel + 1.
3414 hiddenLevel ~~ 1 ifTrue:[^ self].
3416 hiddenLevel ~~ 0 ifTrue:[^ self].
3418 checkTestMode ifTrue:[
3419 testModeChannel value ifTrue:[ ^ self ]. "/ test whether running testMode
3423 and:[(rootView := listOfItems rootView) notNil
3424 and:[rootView shown]]
3430 damages := OrderedCollection new:(8 * aList size).
3433 item handlesDo:[:handle :what|
3434 damages reverseDo:[:el|
3435 (el intersects:handle) ifTrue:[
3436 damages removeIdentical:el.
3438 handle left:(handle left min:el left)
3439 right:(handle right max:el right)
3440 top:(handle top min:el top)
3441 bottom:(handle bottom max:el bottom)
3454 rootView clearRectangleX:x y:y width:w height:h.
3455 rootView exposeX:x y:y width:w height:h.
3458 (subViews := rootView subViews) notNil ifTrue:[
3459 subViews reverseDo:[:v| self recursiveRepair:damages startIn:v relativeTo:rootView ].
3464 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'queries'!
3467 "answer false, all input events are eaten and the selection is shown on the target view.
3468 answer true, no input events are eaten and no selection is shown on the target view."
3470 ^ testModeChannel value
3473 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection accessing'!
3476 "returns the selected item at an index or nil
3478 selection notNil ifTrue:[
3479 ^ selection at:anIndex ifAbsent:nil
3484 at:anIndex ifAbsent:aBlock
3485 "returns the selected item at an index or the result of the block
3487 selection notNil ifTrue:[
3488 ^ selection at:anIndex ifAbsent:aBlock
3494 "returns the first selected item or nil
3500 "returns the last selected item or nil
3502 ^ selection notNil ifTrue:[selection last] ifFalse:[nil]
3506 "returns the single selected item or nil (size ~~ 1 nil is returned)
3508 ^ selection size == 1 ifTrue:[selection at:1] ifFalse:[nil]
3512 "returs the list of selected superItems; items selected
3513 but not contained in another selected item.
3515 ^ selectedSuperItems
3519 "returns the number of items selected
3524 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection adding & removing'!
3527 "add an item to the current selection
3531 item isNil ifTrue:[^ item].
3534 selection isNil ifTrue:[
3535 newSelect := Array with:item.
3537 (self includes:item) ifFalse:[
3538 newSelect := selection copyWith:item
3542 newSelect size ~~ selection size ifTrue:[
3544 self value:newSelect
3550 addAll:aCollectionOfItems
3551 "add a collection of items to the current selection
3555 aCollectionOfItems size == 0 ifTrue:[ ^ aCollectionOfItems ].
3558 selection isNil ifTrue:[
3559 newSelect := Array withAll:aCollectionOfItems.
3561 newSelect := OrderedCollection withAll:selection.
3563 aCollectionOfItems do:[:el|
3564 (selection includesIdentical:el) ifFalse:[newSelect add:el]
3567 self value:newSelect.
3569 ^ aCollectionOfItems
3573 "clear the selection
3579 "remove the item from the current selection
3583 item isNil ifTrue:[^ nil].
3586 (selection notNil and:[selection includesIdentical:item]) ifTrue:[
3587 selection size == 1 ifTrue:[ newSelect := nil ]
3588 ifFalse:[ newSelect := selection copyWithout:item ].
3590 self value:newSelect
3597 "clear the selection
3603 "remove all items of the collection from the current selection
3607 selection isNil ifTrue:[ ^ loItems ].
3608 loItems size == 0 ifTrue:[ ^ loItems ].
3611 selection notNil ifTrue:[
3612 newSelect := selection select:[:el| (loItems includesIdentical:el) not ].
3613 self value:newSelect.
3624 root := listOfItems root.
3629 newSelection := OrderedCollection new.
3630 root recursiveDo:[:el| newSelection add:el ].
3632 self value:newSelection.
3636 "set the current selection to the item
3642 "set the current selection to the root item
3644 self value:(self rootItem).
3648 "set the current selection to the item
3650 self selectItem:anItem.
3653 toggleSelectItem:anItem
3654 "toggle selection-state of the item; add or remove the item from the
3657 anItem notNil ifTrue:[
3658 (self includes:anItem) ifTrue:[self remove:anItem]
3659 ifFalse:[self add:anItem]
3664 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection enumerating'!
3667 "for each element in the selection, evaluate the argument, aBlock
3668 and return a new collection with the results
3672 res := OrderedCollection new.
3673 self do:[:el| res add:(aBlock value:el)].
3678 "evaluate the argument, aBlock for each item in the selection
3682 cashedSelection := selection.
3683 cashedSelection isNil ifTrue:[^ nil].
3684 ^ cashedSelection do:aOneArgBlock
3687 from:start do:aOneArgBlock
3688 "evaluate the argument, aBlock for the items starting at index start
3692 cashedSelection := selection.
3693 cashedSelection isNil ifTrue:[^ nil].
3694 ^ cashedSelection from:start do:aOneArgBlock
3697 from:start to:stop do:aOneArgBlock
3698 "evaluate the argument, aBlock for the items with index start to
3699 stop in the selection.
3703 cashedSelection := selection.
3704 cashedSelection isNil ifTrue:[^ nil].
3705 ^ cashedSelection from:start to:stop do:aOneArgBlock
3708 reverseDo:aOneArgBlock
3709 "evaluate the argument, aBlock for each item in the selection
3713 cashedSelection := selection.
3714 cashedSelection isNil ifTrue:[^ nil].
3715 ^ cashedSelection reverseDo:aOneArgBlock
3719 "return a new collection with all elements from the selection, for which
3720 the argument aBlock evaluates to true.
3724 res := OrderedCollection new.
3725 self do:[:el| (aBlock value:el) ifTrue:[res add:el] ].
3729 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection protocol'!
3731 changed:aParameter with:oldSelection
3732 "update the visibility staus of the current selection
3734 |unselected rootView rootItem selSize|
3736 selSize := selection size.
3738 selSize == 0 ifTrue:[
3739 selectedSuperItems := #().
3741 selSize == 1 ifTrue:[
3742 selectedSuperItems := Array with:(selection at:1).
3744 rootItem := listOfItems root.
3746 (selection includesIdentical:rootItem) ifTrue:[
3747 selectedSuperItems := Array with:rootItem.
3749 selectedSuperItems := OrderedCollection new:selSize.
3751 selection do:[:anItem|
3752 anItem parentsDetect:[:el| selection includesIdentical:el ]
3753 ifNone:[ selectedSuperItems add:anItem ].
3760 and:[(rootView := listOfItems rootView) notNil
3761 and:[rootView shown]]
3763 selSize == 0 ifTrue:[
3764 "/ must redraw the old selection unselected
3765 self redrawUnselected:oldSelection andLock:false
3767 self invalidateSelection.
3769 oldSelection size ~~ 0 ifTrue:[
3770 "/ must redraw all elements no longer in the selection
3771 unselected := oldSelection select:[:el| (selection includesIdentical:el) not ].
3772 self redrawUnselected:unselected andLock:false.
3776 super changed:aParameter with:oldSelection.
3779 setValue:aNewSelection
3780 "set the selection without notifying
3786 aNewSelection notNil ifTrue:[
3788 aNewSelection isCollection ifFalse:[
3789 (selection size == 1 and:[selection first == aNewSelection]) ifTrue:[
3790 newSelect := selection
3792 newSelect := Array with:aNewSelection.
3795 aNewSelection notEmpty ifTrue:[
3796 aNewSelection size ~~ selection size ifTrue:[
3797 newSelect := aNewSelection copy.
3799 idx := selection findFirst:[:el| (aNewSelection includesIdentical:el) not ].
3801 idx ~~ 0 ifTrue:[newSelect := aNewSelection copy]
3802 ifFalse:[newSelect := selection ].
3808 newSelect ~~ selection ifTrue:[
3809 beforeSelectionChangedAction value.
3810 selection := newSelect.
3811 selection notNil ifTrue:[selection do:[:el| el makeVisible]]
3816 "set my value & send change notifications to my dependents.
3817 Send the change message even if the value didn't change.
3822 oldSelection := selection.
3823 self setValue:aValue.
3824 self changed:#value with:oldSelection
3829 "returns the current selection
3835 "change the current selection and send change notifications to my
3836 dependents if it changed.
3841 oldSelection := selection.
3842 self setValue:aValue.
3844 oldSelection == selection ifFalse:[
3845 self changed:#value with:oldSelection
3850 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection searching'!
3853 "evaluate the argument, aBlock for each item in the selection until
3854 the block returns true; in this case return the element which caused
3855 the true evaluation.
3856 If none of the evaluations returns true, an error is raised
3858 ^ self detect:aBlock ifNone:[self errorNotFound]
3861 detect:aBlock ifNone:exceptionBlock
3862 "evaluate the argument, aBlock for each item in the selection until the
3863 block returns true; in this case return the element which caused the
3865 If none of the evaluations returns true, the result of the evaluation
3866 of the exceptionBlock is returned
3870 cashedSelection := selection.
3871 cashedSelection isNil ifTrue:[ ^ exceptionBlock value ].
3872 ^ cashedSelection detect:aBlock ifNone:exceptionBlock
3876 "evaluate the argument, aBlock for each item in the selection until
3877 the block returns true; in this case return the element which caused
3878 the true evaluation. The items are processed in reverse order.
3879 If none of the evaluations returns true, an error is raised
3881 ^ self detectLast:aBlock ifNone:[self errorNotFound]
3884 detectLast:aBlock ifNone:exceptionBlock
3885 "evaluate the argument, aBlock for each item in the selection until
3886 the block returns true; in this case return the element which caused
3887 the true evaluation. The items are processed in reverse order.
3888 If none of the evaluations returns true, the result of the evaluation
3889 of the exceptionBlock is returned
3893 cashedSelection := selection.
3894 cashedSelection isNil ifTrue:[ ^ exceptionBlock value ].
3895 ^ cashedSelection detectLast:aBlock ifNone:exceptionBlock
3898 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection testing'!
3901 "returns true if the item is in the current selection
3905 cashedSelection := selection.
3906 cashedSelection isNil ifTrue:[^ false].
3907 ^ cashedSelection includesIdentical:anItem
3910 includesAll:aCollection
3911 "return true, if all items of the collection are included in the current selection
3915 aCollection size ~~ 0 ifTrue:[
3916 cashedSelection := selection.
3917 cashedSelection isNil ifTrue:[ ^ false ].
3919 aCollection do:[:el|
3920 (cashedSelection includesIdentical:el) ifFalse:[^ false]
3926 includesAny:aCollection
3927 "return true, if the any item of the collection is in the current selection
3931 aCollection notNil ifTrue:[
3932 cashedSelection := selection.
3934 cashedSelection notNil ifTrue:[
3935 aCollection do:[:el|
3936 (cashedSelection includesIdentical:el) ifTrue:[^ true]
3943 includesIdentical:anItem
3944 "returns true if the item is in the current selection
3946 ^ self includes:anItem
3950 "returns true if the current selection is empty
3952 ^ selection size == 0
3956 "returns true if the item is in the current selection
3958 ^ self includes:anItem
3962 "returns true if the current selection is not empty
3964 ^ selection size ~~ 0
3967 !ViewTreeInspectorApplication::ViewTreeModel::ItemList class methodsFor:'documentation'!
3971 Kind of HierarchicalList class which contains all the visible
3972 ViewTreeItem's and the root, the anchor of the hierarchical list.
3974 [Instance variables:]
3975 treeModel <ViewTreeModel> all events are delegated to
3976 eventHook <BlockValue> save and resore the pre/post -EventHook
3989 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'accessing'!
3992 "set the root item; delegate events to my treeModel
3996 theRoot == root ifTrue:[^ self].
3998 rootView := self rootView.
4001 rootView notNil ifTrue:[ |wgrp|
4002 wgrp := rootView windowGroup.
4004 wgrp notNil ifTrue:[
4005 wgrp removePreEventHook:treeModel.
4006 wgrp removePostEventHook:self.
4011 rootView := self rootView.
4013 rootView notNil ifTrue:[
4014 "must setup a task because there might not exist a windowGroup at the moment
4018 [rootView == self rootView] whileTrue:[
4019 wgrp := rootView windowGroup.
4020 wgrp notNil ifTrue:[
4022 wgrp addPreEventHook:treeModel.
4023 wgrp addPostEventHook:self.
4025 Delay waitForMilliseconds:100.
4029 ] forkAt:(Processor userSchedulingPriority + 2).
4031 treeModel notNil ifTrue:[
4032 treeModel targetWidgetChanged.
4039 "returns the widget assigned to the root or nil
4041 ^ root notNil ifTrue:[root widget] ifFalse:[nil]
4045 "returne the treeModel, a ViewTreeModel
4050 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'accessing look'!
4052 additionalLabelForItem:anItem
4053 "answer the additional lable for an item or nil"
4055 |widget l applClass applClassName key|
4057 widget := anItem widget.
4060 showWidgetNames == true ifTrue:[
4061 l := '"', widget name, '"'
4064 anItem isApplicationClass ifTrue:[
4065 applClass := anItem applicationClass.
4066 applClass notNil ifTrue:[
4067 applClassName := '[', applClass name allBold, ']'.
4068 l := (l isNil ifTrue:[''] ifFalse:[l , ' ']) , applClassName
4072 application notNil ifTrue:[
4073 key := application builder namedComponents keyAtValue:widget ifAbsent:nil.
4083 "answer true if the additional text is the widget name
4084 otherwise the name of the application"
4086 ^ showWidgetNames ? true
4089 showWidgetNames:aBoolean
4090 "set true if the additional text is the widget name
4091 otherwise the name of the application"
4093 self showWidgetNames == aBoolean ifFalse:[
4094 showWidgetNames := aBoolean.
4096 root notNil ifTrue:[
4097 root recursiveAdditionalNameBehaviourChanged.
4103 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'event processing'!
4105 processEvent:anEvent
4108 ^ treeModel isInTestMode not
4111 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'instance creation'!
4114 "set the model, a ViewTreeModel
4116 treeModel := aModel.
4118 "/ showWidgetNames := false.
4119 showWidgetNames := true.
4122 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'searching'!
4124 detectItemRespondsToView:aView
4125 "returns the bottom-most item which contains the view
4129 root notNil ifTrue:[
4131 topView := root widget.
4133 [ view notNil ] whileTrue:[
4134 topView == view ifTrue:[^ root].
4135 item := root recursiveDetect:[:el| el widget == view ].
4136 item notNil ifTrue:[^ item].
4137 view := view superView
4143 recursiveDetect:aOneOrgBlock
4144 "recursive find the first child, for which evaluation
4145 of the block returns true; if none nil is returned
4147 root notNil ifTrue:[
4148 (aOneOrgBlock value:root) ifTrue:[ ^ root ].
4149 ^ root recursiveDetect:aOneOrgBlock
4154 !ViewTreeInspectorApplication class methodsFor:'documentation'!
4165 ViewTreeInspectorApplication initialize!
4166 ViewTreeInspectorApplication::ViewTreeItem initialize!