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
447 enabled: hasSingleSelectionHolder
450 argument: application
453 enabled: hasSingleSelectionHolder
455 itemValue: doInspect:
456 argument: application
462 enabled: hasTargetWidgetChannel
463 label: 'All Applications'
464 submenuChannel: submenuApplications:
477 enabled: hasSingleSelectionHolder
483 enabled: hasSingleSelectionHolder
485 itemValue: doInspect:
492 enabled: hasTargetWidgetChannel
493 label: 'All Components'
495 submenuChannel: submenuComponents:
504 startGroup: conditionalRight
509 label: 'Documentation'
510 itemValue: openDocumentation
516 label: 'About this Application...'
517 itemValue: openAboutThisApplication
531 "This resource specification was automatically generated
532 by the MenuEditor of ST/X."
534 "Do not manually edit this!! If it is corrupted,
535 the MenuEditor may not be able to read the specification."
538 MenuEditor new openOnClass:ViewTreeApplication andSelector:#middleButtonMenu
539 (Menu new fromLiteralArrayEncoding:(ViewTreeApplication middleButtonMenu)) startUp
550 submenuChannel: submenuGeometry:
556 submenuChannel: submenuInterface:
562 submenuChannel: submenuVisibility:
569 label: 'Browse View Class'
575 label: 'Browse Model Class'
582 label: 'Browse Application Class'
585 isVisible: hasApplication
586 argument: application
589 label: 'Browse Controller Class'
592 isVisible: hasController
599 label: 'Inspect View'
600 itemValue: doInspect:
605 label: 'Inspect Window Group'
606 itemValue: doInspect:
611 label: 'Inspect Model'
612 itemValue: doInspect:
618 label: 'Inspect Application'
619 itemValue: doInspect:
621 isVisible: hasApplication
622 argument: application
625 label: 'Inspect Controller'
626 itemValue: doInspect:
628 isVisible: hasController
651 label: 'Instance Variables'
653 submenuChannel: submenuInspector:
663 enabled: selectedComponentHasChildren
664 label: 'Applications'
667 submenuChannel: submenuApplications:
671 enabled: selectedComponentHasChildren
675 submenuChannel: submenuComponents:
685 "This resource specification was automatically generated
686 by the MenuEditor of ST/X."
688 "Do not manually edit this!! If it is corrupted,
689 the MenuEditor may not be able to read the specification."
693 MenuEditor new openOnClass:Tools::ViewTreeInspectorApplication andSelector:#toolbarMenu
694 (Menu new fromLiteralArrayEncoding:(Tools::ViewTreeInspectorApplication toolbarMenu)) startUp
703 enabled: hasTargetWidgetChannel
707 labelImage: (ResourceRetriever ToolbarIconLibrary reloadIcon)
713 label: 'Pick a View and Catch Events'
714 itemValue: doPickView
715 translateLabel: false
717 hideMenuOnActivated: false
718 labelImage: (ResourceRetriever #'Tools::ViewTreeInspectorApplication' pickWindowIcon2)
721 enabled: hasTargetWidgetChannel
722 label: 'Release Picked View and Uncatch Events'
723 itemValue: doUncatchEvents
725 labelImage: (ResourceRetriever #'Tools::ViewTreeInspectorApplication' releaseViewIcon)
731 enabled: hasSingleSelectionHolder
732 label: 'Browse Application'
734 translateLabel: false
736 hideMenuOnActivated: false
737 labelImage: (ResourceRetriever ToolbarIconLibrary systemBrowser24x24Icon2)
738 argument: application
741 enabled: hasSingleSelectionHolder
742 label: 'Inspect Application'
743 itemValue: doInspect:
744 translateLabel: false
746 hideMenuOnActivated: false
747 labelImage: (ResourceRetriever ToolbarIconLibrary inspect22x24Icon)
748 argument: application
756 !ViewTreeInspectorApplication class methodsFor:'startup'!
767 "show a particular window's topView hierarchy,
768 select the given view"
774 app showWindow:aView.
777 !ViewTreeInspectorApplication methodsFor:'actions'!
779 indicatorClicked:anIndex
782 item := model listOfItems at:anIndex ifAbsent:nil.
785 ( (sensor := self window sensor) notNil
786 and:[(sensor ctrlDown or:[sensor shiftDown])]
788 item recursiveToggleExpand
795 !ViewTreeInspectorApplication methodsFor:'aspects'!
798 "boolean holder, which indicates whether selection changed dependend on the focus view"
803 hasSingleSelectionHolder
804 "boolean holder, true if one item is selected"
806 ^ hasSingleSelectionHolder
809 hasTargetWidgetChannel
810 "answer the channel which is set to true if a target widget exists"
812 ^ model hasTargetWidgetChannel
816 "returns the hierarchical list of items"
822 "returns my selection model, a ViewTreeModel"
828 "boolean holder, which indicates whether the selection will change on click"
830 ^ model selectOnClickHolder
834 "boolean holder, which indicates whether application names or widget names
835 as additional text are shown for the items"
841 "answer a boolean channel which describes the behaviour how to process
842 events on the target view.
844 false: all input events are eaten and the selection is shown on the target view.
845 true: no input events are eaten and no selection is shown on the target view."
847 ^ model testModeChannel
850 !ViewTreeInspectorApplication methodsFor:'change & update'!
855 item := model selectedItem.
857 item notNil ifTrue:[ |state|
860 view id isNil ifTrue:[
869 info := '%1 [%2] - %3' bindWith:(view class name)
870 with:(view name ? '') with:state allBold.
875 hasSingleSelectionHolder value:(view notNil).
876 inspectorView inspect:view.
879 update:something with:someArgument from:aModel
882 aModel == showNamesHolder ifTrue:[
883 oldSelection := model selectedItem.
884 model selectedItem:nil.
885 self listOfItems showWidgetNames:(aModel value).
886 model selectedItem:oldSelection.
890 aModel == model ifTrue:[
891 self selectionChanged.
895 super update:something with:someArgument from:aModel.
898 !ViewTreeInspectorApplication methodsFor:'event processing'!
900 processButtonMotionEvent:ev
903 motionAction isNil ifTrue:[^ self].
905 (rootView := model rootView) isNil ifTrue:[
906 clickedItem := motionAction := nil.
910 click := rootView device
911 translatePoint:((ev x)@ (ev y))
915 click = clickedPoint ifFalse:[
916 (clickedItem isNil or:[(click dist:clickedPoint) > 5.0]) ifTrue:[
917 motionAction value:click
922 processButtonPressEvent:ev
923 |rootView sensor lastRectangle|
925 rootView := model rootView.
926 sensor := model rootView sensor.
927 clickedItem := model listOfItems detectItemRespondsToView:(ev view).
929 (sensor ctrlDown or:[sensor shiftDown]) ifTrue:[
930 clickedItem notNil ifTrue:[
931 self selectOnClickHolder value ifTrue:[
932 model toggleSelectItem:clickedItem
935 clickedItem := motionAction := nil.
939 clickedPoint := rootView device translatePoint:((ev x)@ (ev y)) fromView:(ev view) toView:rootView.
940 lastRectangle := nil.
943 rootView := model rootView device rootView.
944 rootView := model rootView.
948 lastRectangle notNil ifTrue:[ rootView displayRectangle:lastRectangle ]
949 ifFalse:[ rootView clippedByChildren:false ].
952 rootView clippedByChildren:true.
955 lastRectangle := Rectangle origin:(clickedPoint min:p) corner:(clickedPoint max:p).
956 rootView displayRectangle:lastRectangle.
964 processButtonReleaseEvent:anEvent
965 |rootView rectangle newItems widget origin|
967 (rootView := model rootView) isNil ifTrue:[
968 clickedItem := motionAction := nil.
971 motionAction isNil ifTrue:[ ^ self ].
972 clickedItem notNil ifTrue:[ ^ model selectItem:clickedItem ].
974 rectangle := motionAction value:nil.
975 rectangle isNil ifTrue:[^ self].
977 newItems := OrderedCollection new.
979 model rootItem recursiveDo:[:anItem|
980 widget := anItem widget.
981 origin := widget originRelativeTo:rootView.
983 (rectangle containsRect:(Rectangle origin:origin extent:(widget extent))) ifTrue:[
987 model value:newItems.
993 anEvent isKeyPressEvent ifTrue:[ self processKeyPressEvent:anEvent. ^ self ].
994 anEvent isButtonEvent ifFalse:[ ^ self ].
996 button := anEvent button.
998 (button == 2 or:[button == #menu]) ifTrue:[
999 motionAction isNil ifTrue:[
1000 anEvent isButtonPressEvent ifTrue:[
1001 self selectOnClickHolder value ifTrue:[
1002 menu := self middleButtonMenu value.
1003 menu notNil ifTrue:[
1005 menu:(Menu new fromLiteralArrayEncoding:menu)
1016 anEvent isButtonPressEvent ifTrue:[ self processButtonPressEvent:anEvent. ^ self ].
1017 anEvent isButtonMotionEvent ifTrue:[ self processButtonMotionEvent:anEvent. ^ self ].
1019 anEvent isButtonReleaseEvent ifTrue:[
1020 self selectOnClickHolder value ifTrue:[
1021 self processButtonReleaseEvent:anEvent
1024 clickedItem := motionAction := nil.
1026 anEvent type == #'buttonMultiPress:x:y:' ifTrue:[
1027 self selectOnClickHolder value ifTrue:[
1028 self doInspect:#view.
1033 processKeyPressEvent:anEvent
1034 |item prnt idx key max next|
1037 key isSymbol ifFalse:[^ self].
1039 key == #Delete ifTrue:[ ^ self doDestroy ].
1040 key == #InspectIt ifTrue:[ ^ self doInspect:#view ].
1043 or:[key == #CursorDown
1044 or:[key == #CursorLeft
1045 or:[key == #CursorRight]]]
1049 item := model selectedItem.
1052 ^ model selectedItem:(model first ? model rootItem)
1055 prnt := item parent.
1058 (key == #CursorUp or:[key == #CursorLeft]) ifTrue:[item := model listOfItems last]
1059 ifFalse:[item := item at:1 ifAbsent:item].
1061 ^ model selectedItem:item
1063 key == #CursorLeft ifTrue:[ ^ model selectedItem:prnt ].
1065 key == #CursorRight ifTrue:[
1066 next := item at:1 ifAbsent:nil.
1067 next notNil ifTrue:[ model selectedItem:next ].
1073 key == #CursorUp ifTrue:[
1074 idx := prnt identityIndexOf:item.
1075 idx == 1 ifTrue:[idx := max + 1].
1076 model selectedItem:(prnt at:idx - 1).
1080 key == #CursorDown ifTrue:[
1081 idx := prnt identityIndexOf:item.
1082 idx == max ifTrue:[idx := 0].
1083 model selectedItem:(prnt at:idx + 1).
1088 processMappedView:aView
1091 parent := self listOfItems detectItemRespondsToView:aView.
1092 parent isNil ifTrue:[ ^ self ].
1094 NotFoundSignal handle:[:ex|
1095 "contained subvies used by spec are not yet created;
1096 thus we have to wait until last used subview is build
1100 anchor := parent class buildViewsFrom:(parent widget).
1102 anchor notNil ifTrue:[
1103 parent updateFromChildren:anchor children.
1107 !ViewTreeInspectorApplication methodsFor:'initialization & release'!
1110 "release the grapped application"
1113 super closeDownViews.
1118 "setup my model and channels"
1122 hasSingleSelectionHolder := false asValue.
1123 followFocusChannel := false asValue.
1125 model := ViewTreeModel new.
1126 model inputEventAction:[:ev| self processEvent:ev ].
1127 model mappedViewAction:[:vw| self processMappedView:vw ].
1128 model application:self.
1129 model addDependent:self.
1132 showNamesHolder := false asValue.
1133 showNamesHolder addDependent:self.
1136 postBuildInspectorView:anInspector
1137 inspectorView := anInspector.
1141 treeView := aTree scrolledView.
1142 treeView hasConstantHeight:true.
1145 !ViewTreeInspectorApplication methodsFor:'menu queries'!
1148 "returns true if the current selected view has an application"
1152 view := self selectedView.
1153 ^ (view notNil and:[view application notNil])
1157 "returns true if the current selected item's view has a controller
1158 other than nil or the view itself"
1162 view := self selectedView.
1164 view notNil ifTrue:[
1165 controller := view controller.
1166 ^ (controller notNil and:[controller ~~ view])
1172 "returns true if the current selected view has a model"
1176 view := self selectedView.
1177 ^ (view notNil and:[view model notNil])
1180 !ViewTreeInspectorApplication methodsFor:'menu specs'!
1183 "returns the middleButton menu for the single selected item or nil"
1186 model selectedItem notNil
1187 ifTrue:[self class middleButtonMenu]
1192 submenuApplications:aMenu
1193 |applications menu item list addBlock|
1195 item := aMenu selection nameKey == #single ifTrue:[model selectedItem]
1196 ifFalse:[model rootItem].
1197 item isNil ifTrue:[^ nil].
1199 applications := IdentityDictionary new.
1201 addBlock := [:el| |cls ctr|
1202 cls := self resolveApplicationClassFor:el.
1205 ctr := applications at:cls ifAbsent:0.
1206 applications at:cls put:(ctr + 1).
1209 item recursiveDo:addBlock.
1210 addBlock value:item.
1212 applications isEmpty ifTrue:[^ nil ].
1213 list := SortedCollection sortBlock:[:a :b| a title < b title ].
1215 applications keysAndValuesDo:[:cls :ctr|
1216 list add:(MenuDesc title:(cls name)
1217 value:(ctr printString)
1218 action:[self doSelectNextOfApplicationClass:cls startingIn:item]
1222 menu := MenuDesc buildFromList:list onGC:aMenu.
1224 el hideMenuOnActivated:false
1229 submenuComponents:aMenu
1230 |widgets list total menu item|
1232 item := aMenu selection nameKey == #single ifTrue:[model selectedItem]
1233 ifFalse:[model rootItem].
1234 item isNil ifTrue:[^ nil].
1236 widgets := IdentityDictionary new.
1239 item recursiveDo:[:el| |cls ctr|
1244 ctr := widgets at:cls ifAbsent:0.
1245 widgets at:cls put:(ctr + 1).
1249 total == 0 ifTrue:[^ nil].
1250 list := SortedCollection sortBlock:[:a :b| a title < b title ].
1252 widgets keysAndValuesDo:[:cls :ctr|
1253 list add:(MenuDesc title:(cls name)
1254 value:(ctr printString)
1255 action:[self doSelectNextOfClass:cls startingIn:item]
1258 list := list asOrderedCollection.
1259 list add:(MenuDesc separator).
1260 list add:(MenuDesc title:'Total' value:(total printString)).
1261 menu := MenuDesc buildFromList:list onGC:aMenu.
1263 el hideMenuOnActivated:false
1268 submenuGeometry:aMenu
1269 "builds and returns the geometry submenu"
1271 |view point inst list x y|
1273 view := self selectedView.
1274 view isNil ifTrue:[^ nil].
1276 list := OrderedCollection new.
1279 point := view relativeOrigin.
1280 point isNil ifTrue:[ point := view origin ].
1285 (x == point x and:[y == point y]) ifTrue:[ inst := point ]
1286 ifFalse:[ inst := '%1 --> (%2@%3)' bindWith:point with:x with:y ].
1288 list add:(MenuDesc title:'origin' value:inst).
1291 point := view relativeCorner.
1292 point isNil ifTrue:[ point := view corner ].
1297 (x == point x and:[y == point y]) ifTrue:[ inst := point ]
1298 ifFalse:[ inst := '%1 --> (%2@%3)' bindWith:point with:x with:y ].
1300 list add:(MenuDesc title:'corner' value:inst).
1303 (point := view relativeExtent) isNil ifTrue:[point := view extent].
1304 list add:(MenuDesc title:'extent' value:point).
1307 list add:(MenuDesc title:'pref. extent' value:(view preferredExtent)).
1308 list add:(MenuDesc separator).
1311 inst := 'l:%1 r:%2 t:%3 b:%4' bindWith:(view leftInset)
1312 with:(view rightInset)
1313 with:(view topInset)
1314 with:(view bottomInset).
1316 list add:(MenuDesc title:'insets' value:inst).
1317 list add:(MenuDesc title:'borderWidth' value:(view borderWidth)).
1318 list add:(MenuDesc title:'level' value:(view level)).
1319 list add:(MenuDesc separator).
1321 (inst := view layout) notNil ifTrue:[ inst := inst displayString ].
1322 list add:(MenuDesc title:'layout' value:inst).
1324 (inst := view transformation) notNil ifTrue:[ inst := inst displayString ].
1325 list add:(MenuDesc title:'transformation' value:inst).
1327 ^ MenuDesc buildFromList:list onGC:aMenu
1330 submenuInspector:aMenu
1331 "builds and returns the inspector submenu"
1333 |view list n names label value|
1335 view := self selectedView.
1336 view isNil ifTrue:[^ nil].
1338 n := view class instSize.
1339 n > 0 ifFalse:[^ nil ].
1341 list := OrderedCollection new:n.
1342 names := view class allInstVarNames.
1344 1 to:n do:[:i| |action|
1345 label := (names at:i) printString.
1346 value := view instVarAt:i.
1347 value isNil ifTrue:[
1351 value := value displayString contractAtEndTo:40.
1352 action := [(view instVarAt:i) inspect].
1354 list add:(MenuDesc title:label value:value action:action).
1357 ^ MenuDesc buildFromList:list onGC:aMenu
1360 submenuInterface:aMenu
1361 "builds and returns the interface submenu"
1363 |view label inst value list|
1365 view := self selectedView.
1366 view isNil ifTrue:[^ nil].
1368 list := OrderedCollection new.
1370 inst := view controller.
1376 inst == view ifTrue:[
1377 label := '== view itself'
1379 label := inst displayString.
1380 value := [view controller inspect].
1383 list add:(MenuDesc title:'controller' value:label action:value).
1385 inst := view delegate.
1386 inst notNil ifTrue:[
1387 list add:(MenuDesc title:'delegate' value:(inst displayString) action:[ view delegate inspect ]).
1390 inst := view application.
1392 inst notNil ifTrue:[
1395 list add:(MenuDesc title:'application' value:inst action:[ view application inspect ]).
1397 topAppl := inst topApplication.
1399 (topAppl notNil and:[topAppl ~~ inst]) ifTrue:[
1400 list add:(MenuDesc title:'topApplication' value:topAppl action:[ inst topApplication inspect ]).
1403 list add:(MenuDesc separator).
1405 (view respondsTo:#'model') ifTrue:[
1409 ifTrue:[ label := value := nil ]
1410 ifFalse:[ label := inst displayString.
1411 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1412 value := [ view model inspect ].
1415 list add:(MenuDesc title:'model' value:label action:value).
1417 (inst notNil and:[view respondsTo:#modelInterface]) ifTrue:[
1418 view modelInterface keysAndValuesDo:[:key : val|
1419 val isNil ifTrue:[ label := nil ]
1420 ifFalse:[ label := val displayString ].
1422 list add:(MenuDesc title:(' - ', key) value:label ).
1427 (view respondsTo:#enableChannel) ifTrue:[
1428 inst := view enableChannel.
1430 inst isNil ifTrue:[ label := value := nil ]
1431 ifFalse:[ label := inst displayString.
1432 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1433 value := [ view enableChannel inspect ].
1436 list add:(MenuDesc title:'enableChannel' value:label action:value).
1439 #( #action #pressAction #releaseAction ) do:[:actionSelector |
1440 (view respondsTo:actionSelector) ifTrue:[
1441 inst := view perform:actionSelector.
1444 ifTrue:[ label := value := nil ]
1445 ifFalse:[ label := inst displayString.
1446 value := [ (view perform:actionSelector) inspect ].
1449 list add:(MenuDesc title:'action' value:label action:value).
1453 list last isSeparator ifFalse:[ list add:(MenuDesc separator) ].
1455 (view respondsTo:#listHolder) ifTrue:[
1456 inst := view listHolder.
1458 inst isNil ifTrue:[ label := value := nil ]
1459 ifFalse:[ label := inst class printString.
1460 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1461 value := [ view listHolder inspect ].
1463 list add:(MenuDesc title:'listHolder' value:label action:value).
1466 (view respondsTo:#list) ifTrue:[
1469 inst isNil ifTrue:[ label := value := nil ]
1470 ifFalse:[ label := '%1 [%2]' bindWith:(inst class printString) with:(inst size).
1471 label := label,(self aspectLabelFor:inst inApplicationOf:view).
1472 value := [ view list inspect ].
1475 list add:(MenuDesc title:'list' value:label action:value).
1478 list last isSeparator ifTrue:[ list removeLast ].
1479 ^ MenuDesc buildFromList:list onGC:aMenu
1481 "Modified: / 27-04-2012 / 14:22:34 / cg"
1484 submenuVisibility:aMenu
1485 "builds and returns the geometry submenu"
1489 view := self selectedView.
1490 view isNil ifTrue:[^ nil].
1492 list := OrderedCollection new.
1494 list add:(MenuDesc title:'device' value:(view device printString)).
1495 list add:(MenuDesc title:'drawableId' value:(view id)).
1496 list add:(MenuDesc title:'gcId' value:(view gcId)).
1498 list add:(MenuDesc separator).
1500 list add:(MenuDesc title:'shown' value:(view shown)).
1501 list add:(MenuDesc title:'realized' value:(view realized)).
1503 list add:(MenuDesc separator).
1505 list add:(MenuDesc title:'hiddenOnRealize' value:(view isHiddenOnRealize)).
1507 (value := view visibilityChannel) isNil ifTrue:[
1508 list add:(MenuDesc title:'visibilityChannel' value:'------').
1510 list add:(MenuDesc title:'visibilityChannel'
1511 value:(value displayString)
1512 action:[view visibilityChannel inspect]).
1515 ^ MenuDesc buildFromList:list onGC:aMenu
1518 !ViewTreeInspectorApplication methodsFor:'private'!
1520 aspectLabelFor:aModel inApplicationOf:aView
1523 aModel isNil ifTrue:[^ ''].
1524 aView isNil ifTrue:[^ ''].
1525 (app := aView application) isNil ifTrue:[^ ''].
1526 app builder bindings keysAndValuesDo:[:aspect :value |
1527 value == aModel ifTrue:[^ ' [aspect: ',aspect,']'].
1529 app class allInstVarNames do:[:nm |
1530 (app instVarNamed:nm) == aModel ifTrue:[^ ' [instvar: ',nm,']']
1535 "Created: / 27-04-2012 / 14:22:09 / cg"
1539 |rootView focusView|
1541 rootView := model rootView.
1543 (rootView notNil and:[rootView shown]) ifTrue:[
1544 focusView := rootView windowGroup focusView.
1546 focusView isNil ifTrue:[^ self ].
1548 self selectView:focusView
1552 |currentItem viewItem|
1554 currentItem := model selectedItem.
1556 (currentItem notNil and:[currentItem widget == aView]) ifTrue:[
1559 viewItem := model listOfItems recursiveDetect:[:el| el widget == aView ].
1561 viewItem notNil ifTrue:[
1562 model selectItem:viewItem.
1566 setRootItem:aRootItemOrNil
1569 aRootItemOrNil isNil ifTrue:[
1572 "/ expand tree to level 3
1573 aRootItemOrNil do:[:aRootChild|
1574 aRootChild do:[:aSubChild| aSubChild expand ].
1577 aRootItemOrNil expand.
1579 process isNil ifTrue:[
1580 theProcess := process :=
1581 Process for:[ |update testModeChannel|
1584 testModeChannel := model testModeChannel.
1586 [process == theProcess] whileTrue:[
1587 Delay waitForSeconds:0.5.
1589 (treeView notNil and:[process == theProcess and:[treeView shown]]) ifTrue:[
1590 (testModeChannel value == true and:[followFocusChannel value == true]) ifTrue:[
1591 self selectFocusView.
1594 self updateShownStatus.
1596 update := update not.
1601 theProcess name:'ViewTreeInspector - Follow Focus'.
1605 model rootItem:aRootItemOrNil.
1609 |rootItem min max visState listIdx visY0 visY1 height damage|
1611 rootItem := model rootItem.
1612 (rootItem notNil and:[rootItem widget shown]) ifFalse:[^ self].
1617 rootItem recursiveEachVisibleItemDo:[:anItem|
1618 visState := (anItem widget shown).
1620 visState ~~ anItem isDrawnShown ifTrue:[
1621 anItem isDrawnShown:visState.
1622 listIdx := treeView identityIndexOf:anItem.
1624 listIdx > 0 ifTrue:[
1625 max := max max:listIdx.
1626 min := min min:listIdx.
1630 max < min ifTrue:[^ self].
1633 visY0 := (treeView yVisibleOfLine:min) max:0.
1634 visY1 := (treeView yVisibleOfLine:max) min:(treeView height).
1635 height := visY1 - visY0.
1638 treeView shown ifTrue:[
1639 damage := Rectangle left:0 top:visY0 width:(treeView width) height:height.
1640 treeView invalidateDeviceRectangle:damage repairNow:false.
1645 !ViewTreeInspectorApplication methodsFor:'selection'!
1648 "answer the selected view or nil"
1652 item := model selectedItem.
1653 item notNil ifTrue:[ ^ item widget ].
1657 !ViewTreeInspectorApplication methodsFor:'testing'!
1659 resolveApplicationClassFor:aTreeItem
1660 aTreeItem isApplicationClass ifTrue:[
1661 ^ aTreeItem applicationClass
1666 selectedComponentHasChildren
1669 item := model selectedItem.
1670 ^ (item notNil and:[item hasChildren])
1673 !ViewTreeInspectorApplication methodsFor:'user operations'!
1678 #model browse model class
1679 #application browse application class
1680 #controller browse controller class
1684 view := self selectedView.
1685 view isNil ifTrue:[^ self].
1687 what == #view ifTrue:[ inst := view ]
1688 ifFalse:[what == #model ifTrue:[ inst := view model ]
1689 ifFalse:[what == #application ifTrue:[ inst := view application ]
1690 ifFalse:[what == #controller ifTrue:[ inst := view controller ]
1695 inst notNil ifTrue:[
1696 inst class browserClass openInClass:(inst class) selector:nil
1701 "destroy the current selected view"
1705 item := model selectedItem.
1706 item isNil ifTrue:[ ^ self].
1708 parent := item parent.
1710 parent isNil ifTrue:[
1712 model withSelectionHiddenDo:[item deleteAll].
1716 model withSelectionHiddenDo:[
1719 idx := parent identityIndexOf:item.
1721 idx == parent size ifTrue:[
1722 nsel := parent at:(idx - 1) ifAbsent:parent
1724 nsel := parent at:(idx + 1)
1729 parent isLayoutContainer ifTrue:[
1730 parent widget sizeChanged:nil
1737 "flash the selected view"
1741 view := self selectedView.
1742 view isNil ifTrue:[ ^ self].
1745 model withSelectionHiddenDo:[
1746 view perform:#flash ifNotUnderstood:nil.
1754 #group inspect windowGroup
1755 #model inspect model
1756 #application inspect application
1757 #controller inspect controller
1761 inst := self selectedView.
1762 inst isNil ifTrue:[^ self].
1764 what == #group ifTrue:[ inst := inst windowGroup ]
1765 ifFalse:[what == #model ifTrue:[ inst := inst model ]
1766 ifFalse:[what == #application ifTrue:[ inst := inst application ]
1767 ifFalse:[what == #controller ifTrue:[ inst := inst controller ]]]].
1769 inst notNil ifTrue:[ inst inspect ].
1773 "pick a window's topView"
1775 |screen clickedView topWindow cursor|
1779 cursor := Cursor fromImage:(self class crossHairIcon).
1781 screen := Screen current.
1782 clickedView := screen viewFromPoint:(screen pointFromUserShowing:cursor).
1783 clickedView isNil ifTrue:[^ self].
1785 topWindow := clickedView topView.
1787 ( topWindow == Screen current rootView
1788 or:[topWindow == self window topView]
1793 self showWindow:clickedView
1799 model rootView withAllSubViewsDo:[:v | v redraw; invalidate].
1802 doSelectNextOfApplicationClass:aClass startingIn:anItem
1803 |startItem firstFound searchNext|
1805 startItem := model last.
1806 searchNext := startItem notNil.
1809 anItem recursiveDo:[:el|
1810 el == startItem ifTrue:[
1813 (self resolveApplicationClassFor:el) == aClass ifTrue:[
1814 searchNext ifFalse:[^ model selectItem:el].
1816 firstFound isNil ifTrue:[
1822 firstFound notNil ifTrue:[
1824 model selectItem:firstFound
1828 doSelectNextOfClass:aClass startingIn:anItem
1829 |startItem firstFound searchNext|
1831 startItem := model last.
1832 searchNext := startItem notNil.
1835 anItem recursiveDo:[:el|
1836 el == startItem ifTrue:[
1839 el widget class == aClass ifTrue:[
1840 searchNext ifFalse:[^ model selectItem:el].
1842 firstFound isNil ifTrue:[
1848 firstFound notNil ifTrue:[
1850 model selectItem:firstFound
1855 model catchEvents:false.
1860 "release current picked window and contained subwindows"
1862 self setRootItem:nil.
1866 HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#VIEWTREEINSPECTOR'
1870 "show a particular window's topView hierarchy,
1871 select the given view"
1875 topWindow := aView topView.
1877 model catchEvents:true.
1878 self setRootItem:(ViewTreeItem buildViewsFrom:topWindow).
1879 self selectView:aView.
1882 !ViewTreeInspectorApplication::MenuDesc class methodsFor:'building'!
1884 buildFromList:aList onGC:aMenu
1885 |tabSpec menu w menuPanel|
1888 aList do:[:el| w := w max:(el widthOn:aMenu) ].
1890 tabSpec := TabulatorSpecification new.
1891 tabSpec unit:#pixel.
1892 tabSpec positions:#(0 1.5 ).
1893 tabSpec align:#(#left #left).
1896 tabSpec positions:(Array with:0 with:w).
1901 menu addItem:(el asMenuItemWithTabulatorSpecification:tabSpec).
1903 menuPanel := MenuPanel menu:menu.
1907 !ViewTreeInspectorApplication::MenuDesc class methodsFor:'instance creation'!
1913 title:aTitle value:aValue
1914 ^ self title:aTitle value:aValue action:nil
1917 title:aTitle value:aValue action:anAction
1918 ^ self new title:aTitle value:aValue action:anAction
1921 !ViewTreeInspectorApplication::MenuDesc methodsFor:'accessing'!
1927 !ViewTreeInspectorApplication::MenuDesc methodsFor:'building'!
1929 asMenuItemWithTabulatorSpecification:aTabSpec
1932 title isNil ifTrue:[ ^ MenuItem label:value ]. "/ separator
1934 array := Array with:(title, ':') with:'------'.
1936 value notNil ifTrue:[
1937 array at:2 put:(value printString, ' ')
1941 label:(MultiColListEntry fromStrings:array tabulatorSpecification:aTabSpec)
1945 !ViewTreeInspectorApplication::MenuDesc methodsFor:'instance creation'!
1947 title:aTitle value:aValue action:anAction
1950 title := aTitle withoutSeparators.
1953 aValue notNil ifTrue:[
1954 value := aValue printString.
1956 value size > 70 ifTrue:[
1957 value := value copyFrom:1 to:70.
1958 value := value, '...'
1963 !ViewTreeInspectorApplication::MenuDesc methodsFor:'queries'!
1970 title isNil ifTrue:[^ 5]. "/ separator
1974 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'building'!
1976 buildViewsFrom:aView
1977 "build the items starting from a source view;
1980 |item subViews subItems|
1982 aView isNil ifTrue:[^ nil].
1984 item := self forView:aView.
1985 subViews := aView subViews.
1987 subViews notEmptyOrNil ifTrue:[
1988 subItems := OrderedCollection new.
1989 subViews do:[:aSubView|
1990 subItems add:(self buildViewsFrom:aSubView).
1992 item children:subItems.
1997 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'documentation'!
2001 ViewTreeItems represants a pickable object within a ViewTreeModel.
2002 The class is used to build up the hierarchical tree.
2004 [Instance variables:]
2005 widget <View> the widget represented by the item
2006 spec <UISpecification> the UISpecification or nil
2009 HandleExtent <Point> keeps the extent of a handle
2025 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'initialization'!
2028 "set the extent of the Handle
2030 HandleExtent := 6@6.
2033 !ViewTreeInspectorApplication::ViewTreeItem class methodsFor:'instance creation'!
2038 item := self basicNew initialize.
2044 self error:'not allowed'.
2048 on:aView withSpec:aSpec
2051 item := self basicNew initialize.
2052 item on:aView withSpec:aSpec.
2056 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'accessing'!
2061 widget notNil ifTrue:[
2062 appl := widget application.
2063 appl notNil ifTrue:[^ appl class ].
2069 "returns true if the last display operations was done during the widget was shown
2074 isDrawnShown:aBoolean
2075 isDrawnShown := aBoolean.
2079 "returns the widget assigned to the root or nil
2085 "returns the spec-class assigned to the item
2091 "returns the assigned treeModel, an instance of ViewTreeModel
2097 "returns the widget assigned to the item
2102 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'accessing layout'!
2104 boundsRelativeToRoot
2105 "returns the bounds relative to the root widget
2107 ^ self originRelativeToRoot extent:(widget extent)
2110 cornerRelativeToRoot
2111 "returns the corner relative to the root widget
2113 ^ self originRelativeToRoot + (widget extent)
2117 "returns the extent of the widget
2123 "returns the type of layout assigned to the wiget; nil if the
2124 superView cannot resize its sub widgets
2126 |layout specClass superView|
2128 (superView := widget superView) isNil ifTrue:[
2132 specClass := superView specClass.
2134 (specClass notNil and:[specClass isLayoutContainer]) ifTrue:[
2135 ^ specClass canResizeSubComponents ifTrue:[#Extent] ifFalse:[nil]
2138 (layout := widget geometryLayout) isNil ifTrue:[
2142 layout isLayout ifTrue:[
2143 layout isLayoutFrame ifTrue:[ ^ #LayoutFrame ].
2144 layout isAlignmentOrigin ifTrue:[ ^ #AlignmentOrigin ].
2145 layout isLayoutOrigin ifTrue:[ ^ #LayoutOrigin ].
2147 layout isRectangle ifTrue:[ ^ #Rectangle ].
2148 layout isPoint ifTrue:[ ^ #Point ].
2151 Transcript showCR:'UNSUPPORTRD LAYOUT: ', layout printString.
2155 originRelativeToRoot
2156 "returns the origin relative to the root widget
2158 ^ widget originRelativeTo:(self rootView)
2161 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'accessing optimize'!
2164 "redefined: optimize
2170 |subViews list item|
2172 children size ~~ 0 ifTrue:[
2175 isExpanded := false.
2176 subViews := widget subViews.
2178 subViews size == 0 ifTrue:[^ false].
2180 list := OrderedCollection new.
2182 subViews do:[:aSubView|
2183 item := self class buildViewsFrom:aSubView.
2192 "redefined: returns list of children
2197 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'displaying'!
2199 additionalLabelForItem:anItem
2200 "answer an additional label for an Item"
2202 parent notNil ifTrue:[
2203 ^ parent additionalLabelForItem:anItem
2208 displayIcon:anIcon atX:x y:y on:aGC
2211 super displayIcon:anIcon atX:x y:y on:aGC.
2213 self exists ifFalse:[
2214 aGC paint:(Color red).
2217 y1 := y + anIcon height - 2.
2223 aGC displayLineFromX:x0 y:y0 toX:(x0 + w) y:y1.
2224 aGC displayLineFromX:x0 y:y1 toX:(x0 + w) y:y0.
2230 displayOn:aGC x:x y:y h:h
2231 |labelHeight additionalName label isValidAndShown|
2233 label := self label.
2234 label isEmptyOrNil ifTrue:[^ self].
2236 widget id isNil ifTrue:[
2237 isDrawnShown := false.
2239 self exists ifFalse:[
2240 xOffsetAdditionalName := nil.
2242 isValidAndShown := false.
2244 isValidAndShown := widget shown.
2246 isValidAndShown ifFalse:[
2247 label := Text string:label emphasis:#italic.
2248 label colorizeAllWith:Color grey.
2251 labelHeight := self heightOn:aGC.
2252 self displayLabel:label h:labelHeight on:aGC x:x y:y h:h.
2254 xOffsetAdditionalName notNil ifTrue:[
2255 additionalName := self additionalLabelForItem:self.
2257 additionalName notNil ifTrue:[
2258 self displayLabel:additionalName
2259 h:labelHeight on:aGC
2260 x:(x + xOffsetAdditionalName)
2264 xOffsetAdditionalName := nil.
2269 recursiveAdditionalNameBehaviourChanged
2270 width := xOffsetAdditionalName := nil.
2272 children notNil ifTrue:[
2273 children do:[:each| each recursiveAdditionalNameBehaviourChanged ]
2278 "return the width of the receiver, if it is to be displayed on aGC
2282 width isNil ifTrue:[
2283 width := self widthOf:(self label) on:aGC.
2286 additionalName := self additionalLabelForItem:self.
2288 additionalName notNil ifTrue:[
2289 xOffsetAdditionalName := width + 10.
2290 width := xOffsetAdditionalName + (self widthOf:additionalName on:aGC).
2293 xOffsetAdditionalName := nil.
2299 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'enumerating'!
2301 handlesDo:aTwoArgAction
2302 "evaluate the two arg block on each handle; the arguments to the block is
2303 the rectangle relative to the rootView and the handle type which is
2304 set to nil if not resizeable.
2306 TYPES: type position( X - Y )
2307 -------------------------
2317 nil ** handle not pickable **
2319 |type relOrg relCrn maxExt rootView w h
2320 xL "{ Class:SmallInteger }"
2321 xC "{ Class:SmallInteger }"
2322 xR "{ Class:SmallInteger }"
2323 yT "{ Class:SmallInteger }"
2324 yC "{ Class:SmallInteger }"
2325 yB "{ Class:SmallInteger }"
2327 rootView := self rootView.
2328 relOrg := widget originRelativeTo:rootView.
2329 relOrg isNil ifTrue:[ ^ self ]. "/ widget destroyed
2331 relOrg := relOrg - (HandleExtent // 2).
2332 relCrn := relOrg + widget extent.
2333 maxExt := rootView extent - HandleExtent.
2335 xL := relOrg x max:0.
2336 xR := relCrn x min:(maxExt x).
2339 yT := relOrg y max:0.
2340 yB := relCrn y min:(maxExt y).
2343 type := self layoutType.
2344 w := HandleExtent x.
2345 h := HandleExtent y.
2347 (type == #LayoutFrame or:[type == #Rectangle]) ifTrue:[
2348 aTwoArgAction value:(Rectangle left:xL top:yT width:w height:h) value:#LT.
2349 aTwoArgAction value:(Rectangle left:xL top:yC width:w height:h) value:#LC.
2350 aTwoArgAction value:(Rectangle left:xL top:yB width:w height:h) value:#LB.
2351 aTwoArgAction value:(Rectangle left:xC top:yT width:w height:h) value:#CT.
2352 aTwoArgAction value:(Rectangle left:xC top:yB width:w height:h) value:#CB.
2353 aTwoArgAction value:(Rectangle left:xR top:yT width:w height:h) value:#RT.
2354 aTwoArgAction value:(Rectangle left:xR top:yC width:w height:h) value:#RC.
2355 aTwoArgAction value:(Rectangle left:xR top:yB width:w height:h) value:#RB.
2359 aTwoArgAction value:(Rectangle left:xL top:yT width:w height:h) value:nil.
2360 aTwoArgAction value:(Rectangle left:xL top:yB width:w height:h) value:nil.
2361 aTwoArgAction value:(Rectangle left:xR top:yT width:w height:h) value:nil.
2363 type == #Extent ifTrue:[
2364 aTwoArgAction value:(Rectangle left:xC top:yB width:w height:h) value:#CB.
2365 aTwoArgAction value:(Rectangle left:xR top:yC width:w height:h) value:#RC.
2366 aTwoArgAction value:(Rectangle left:xR top:yB width:w height:h) value:#RB.
2369 aTwoArgAction value:(Rectangle left:xR top:yB width:w height:h) value:nil.
2372 recursiveEachVisibleItemDo:anOneArgBlock
2373 "recursive evaluate the block on each child which is visible
2375 (isExpanded and:[children size > 0]) ifTrue:[
2376 children do:[:aChild|
2377 anOneArgBlock value:aChild.
2378 aChild recursiveEachVisibleItemDo:anOneArgBlock.
2383 subViewsDo:aOneArgBlock
2384 "evaluate aBlock for all subviews other than InputView's
2388 subViews := widget subViews.
2390 subViews notNil ifTrue:[
2391 subViews do:aOneArgBlock
2395 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'initialization'!
2402 "setup default attributes
2405 isDrawnShown := false.
2406 isExpanded := false.
2407 children := OrderedCollection new.
2410 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'operations delete'!
2413 "delete self and all contained items; the assigned views are destroyed
2414 in case of rootView, only the children are deleted
2416 parent isHierarchicalItem ifTrue:[
2427 "delete all contained items; the assigned views are destroyed
2429 children size == 0 ifTrue:[^ self].
2432 self nonCriticalDo:[:el| el widget destroy ].
2437 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'operations layout'!
2440 "convert the layout of the widget to a LayoutFrame;
2442 |extent layout newLyt lftFrc lftOff topFrc topOff|
2444 layout := widget geometryLayout.
2446 layout isNil ifTrue:[
2447 ^ widget bounds asLayout
2450 layout isLayout ifFalse:[
2451 layout isRectangle ifTrue:[
2452 ^ LayoutFrame leftOffset:(layout left) rightOffset:(layout right)
2453 topOffset:(layout top) bottomOffset:(layout bottom)
2455 layout isPoint ifTrue:[
2456 extent := widget extent.
2457 ^ LayoutFrame leftOffset:(layout x) rightOffset:(layout x + extent x)
2458 topOffset:(layout y) bottomOffset:(layout y + extent y)
2461 Transcript showCR:'UNSUPPORTRD LAYOUT: ', layout printString.
2465 layout isLayoutFrame ifTrue:[ ^ layout copy ].
2467 lftFrc := layout leftFraction.
2468 lftOff := layout leftOffset.
2469 topFrc := layout topFraction.
2470 topOff := layout topOffset.
2471 extent := widget extent.
2473 newLyt := LayoutFrame leftFraction:lftFrc offset:lftOff
2474 rightFraction:lftFrc offset:(lftOff + extent x)
2475 topFraction:topFrc offset:topOff
2476 bottomFraction:topFrc offset:(topOff + extent y).
2478 ( layout isAlignmentOrigin
2479 and:[(layout leftAlignmentFraction ~= 0 or:[layout topAlignmentFraction ~= 0])]
2483 svRc := widget superView viewRectangle.
2484 prBd := widget preferredBounds.
2486 dlta := ( ((layout rectangleRelativeTo:svRc preferred:prBd) corner)
2487 - ((newLyt rectangleRelativeTo:svRc preferred:prBd) corner)
2490 newLyt leftOffset:(lftOff + dlta x).
2491 newLyt rightOffset:(lftOff + extent x + dlta x).
2492 newLyt topOffset:(topOff + dlta y).
2493 newLyt bottomOffset:(topOff + extent y + dlta y).
2499 "move the widget n pixele left and right
2503 self isMoveable ifFalse:[ ^ self ].
2505 (layout := widget geometryLayout) isNil ifTrue:[
2507 widget origin:(widget origin + (l@t)).
2511 layout := layout copy.
2513 layout isLayout ifTrue:[
2514 layout leftOffset:(layout leftOffset + l)
2515 topOffset:(layout topOffset + t).
2517 layout isLayoutFrame ifTrue:[
2518 layout rightOffset:(layout rightOffset + l).
2519 layout bottomOffset:(layout bottomOffset + t).
2523 layout isRectangle ifTrue:[
2524 layout setLeft:(layout left + l).
2525 layout setTop:(layout top + t).
2527 layout isPoint ifFalse:[^ self].
2528 layout x:(layout x + l) y:(layout y + t).
2531 widget geometryLayout:layout.
2534 resizeLeft:l top:t right:r bottom:b
2535 "resize the widget measured in pixels
2539 self isResizeable ifFalse:[
2543 (layout := widget geometryLayout) isNil ifTrue:[
2545 (r == l and:[b == t]) ifFalse:[
2546 widget extent:(widget computeExtent + ((r-l) @ (b-t))).
2551 layout isLayout ifTrue:[
2552 layout := layout copy.
2554 layout leftOffset:(layout leftOffset + l)
2555 topOffset:(layout topOffset + t).
2557 layout isLayoutFrame ifTrue:[
2558 layout bottomOffset:(layout bottomOffset + b).
2559 layout rightOffset:(layout rightOffset + r).
2562 layout isRectangle ifFalse:[^ self].
2563 layout := layout copy.
2565 layout left:(layout left + l)
2566 right:(layout right + r)
2567 top:(layout top + t)
2568 bottom:(layout bottom + b).
2570 widget geometryLayout:layout.
2573 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'operations update'!
2582 list isNil ifTrue:[list := OrderedCollection new].
2586 list notNil ifTrue:[
2587 list do:[:el| self remove:el ].
2591 updateFromChildren:mergedList
2592 "update my children against the list of items derived from
2596 mergedList size == 0 ifTrue:[ ^ self removeAll ].
2597 children size == 0 ifTrue:[ ^ self addAll:mergedList ].
2600 self nonCriticalDo:[:el| |wdg|
2602 mergedList detect:[:e2| e2 widget == wdg ] ifNone:[ self remove:el ].
2605 mergedList keysAndValuesDo:[:i :el| |wdg e2|
2608 e2 := self at:i ifAbsent:nil.
2610 (e2 isNil or:[e2 widget ~~ wdg]) ifTrue:[
2611 self add:el beforeIndex:i
2617 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'printing & storing'!
2620 "get the icon used for presentation
2624 specClass := self specClass.
2625 specClass isNil ifTrue:[^ nil].
2627 model := self treeModel.
2629 model notNil ifTrue:[
2630 ^ model iconAt:specClass ifNonePut:[specClass icon]
2636 "get the label used for presentation
2642 "append a a printed representation of the item to aStream
2644 aStream nextPutAll:(self string)
2650 ^ widget class name.
2653 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'queries'!
2656 "returns true if the layout of the widget can be changed and the
2657 layout is not organized by its superView
2662 canResizeSubComponents
2663 "returns true if the widget can resize its sub components
2667 specClass := self specClass.
2669 specClass notNil ifTrue:[
2670 ^ specClass canResizeSubComponents
2676 widget id notNil ifTrue:[^ true ].
2678 exists ~~ false ifTrue:[
2681 widget superView notNil ifTrue:[
2682 (parent isHierarchicalItem and:[parent exists]) ifTrue:[
2683 exists := (parent widget subViews includesIdentical:widget).
2693 cls := widget class.
2695 ^ ( cls == ApplicationSubView
2696 or:[cls == ApplicationWindow
2697 or:[cls == SubCanvas]]
2704 model := self treeModel.
2705 model notNil ifTrue:[^ model isSelected:self].
2709 supportsSubComponents
2710 "returns true if the widget supports sub components
2714 widget isScrollWrapper ifTrue:[
2717 specClass := self specClass.
2719 specClass notNil ifTrue:[
2720 ^ specClass supportsSubComponents
2725 !ViewTreeInspectorApplication::ViewTreeItem methodsFor:'testing'!
2728 "returns true if the widget is in a layout container
2732 sv := widget superView.
2735 specClass := sv specClass.
2737 specClass notNil ifTrue:[
2738 ^ specClass isLayoutContainer
2745 "answer whether corresponding view instances of the spec class can contain
2746 (and arrange) other view
2750 specClass := self specClass.
2752 specClass notNil ifTrue:[
2753 ^ specClass isLayoutContainer
2759 "returns true if the widget is not in a layout container
2761 self isInLayoutContainer ifFalse:[
2762 ^ widget superView notNil
2768 "returns true if the widget is resizeable
2772 sv := widget superView.
2775 specClass := sv specClass.
2777 specClass notNil ifTrue:[
2778 ^ specClass canResizeSubComponents
2784 !ViewTreeInspectorApplication::ViewTreeModel class methodsFor:'documentation'!
2788 Instances of ViewTreeModel can be used as model on a View and all
2789 it contained subviews for a HierarchicalListView.
2790 The model keeps two values, the hierarchical representation of the views
2791 and subviews (ViewTreeItems) and the selection, a list of selected ViewTreeItems's.
2792 It shows the selected items highlighted.
2795 [Instance variables:]
2796 lockSema <Semaphore> lock selection notifications and redraws
2798 testModeChannel <ValueHolder> true, than running in test mode.
2800 hasTargetWidgetChannel <ValueHolder> true, than any target view is grapped
2802 selection <Sequence or nil> selected items or nil
2804 hiddenLevel <Integer> internal use; redrawing the selection
2805 only is done if the counter is 0.
2807 listOfItems <HierarchicalList> hiearchical list build from existing items.
2809 selectedSuperItems <Sequence> list of selected super items; items selected
2810 but not contained in another selected item.
2812 inputEventAction <Action> called for each InputEvent
2814 mappedViewAction <Action> called for a new mapped view which
2815 can not be found in the current item list.
2817 beforeSelectionChangedAction <Action> called before the selection changed
2829 example 1: pick any window and show views and contained views
2831 |top sel model panel|
2833 model := ViewTreeModel new.
2834 top := StandardSystemView new; extent:440@400.
2835 sel := ScrollableView for:HierarchicalListView miniScroller:true origin:0.0@0.0 corner:1.0@1.0 in:top.
2838 panel := HorizontalPanelView origin:0.0@1.0 corner:1.0@1.0 in:top.
2840 panel horizontalLayout:#fitSpace.
2842 Button label:'Exit' action:[model rootItem:nil. top destroy] in:panel.
2843 Button label:'Pick Views' action:[ |win|
2844 ( (win := Screen current viewFromUser) notNil
2845 and:[(win := win topView) ~~ Screen current rootView
2848 model rootItem:(ViewTreeItem buildViewsFrom:win)
2854 sel multipleSelectOk:true.
2855 sel list:model listOfItems.
2859 sel doubleClickAction:[:i| |el|
2860 el := model listOfItems at:i.
2861 el spec notNil ifTrue:[ el spec inspect ] ifFalse:[ el widget inspect ]
2863 sel indicatorAction:[:i| (model listOfItems at:i) toggleExpand ].
2865 model inputEventAction:[:anEvent| |item|
2866 anEvent isButtonEvent ifTrue:[
2867 anEvent isButtonPressEvent ifTrue:[
2868 model selectedItem:(model listOfItems detectItemRespondsToView:(anEvent view)).
2870 anEvent type == #'buttonMultiPress:x:y:' ifTrue:[
2871 (item := model selectedItem) notNil ifTrue:[item widget inspect]
2878 [[top shown] whileTrue:[Delay waitForSeconds:0.5]. model rootItem:nil] forkAt:8
2884 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing'!
2886 application:anApplication
2887 listOfItems application:anApplication.
2890 catchEvents:aBoolean
2891 catchEvents := aBoolean.
2893 self redrawUnselected:selection andLock:false checkTestMode:false.
2898 "get the rootItem the event viewer is established on
2904 "set the rootItem the event viewer is established on
2908 timedUpdateTask := nil.
2912 anItem notNil ifTrue:[ expanded := anItem isExpanded ]
2913 ifFalse:[ expanded := false ].
2916 listOfItems root:anItem.
2918 anItem notNil ifTrue:[
2919 timedUpdateTask := Process for:[ self timedUpdateTaskCycle ] priority:8.
2920 timedUpdateTask name:'Update'.
2921 timedUpdateTask resume.
2925 (expanded and:[anItem notNil]) ifTrue:[
2932 "get the top widget the event viewer is established on, a View
2934 ^ listOfItems rootView
2937 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing actions'!
2939 beforeSelectionChangedAction
2940 "none argument action which is called before
2941 the selection changed
2943 ^ beforeSelectionChangedAction
2946 beforeSelectionChangedAction:aNoneArgBlock
2947 "none argument action which is called before
2948 the selection changed
2950 beforeSelectionChangedAction := aNoneArgBlock.
2954 "called for each input event; the argument to the action is the WindowEvent
2959 inputEventAction:aOneArgActionTheEvent
2960 "called for each input event; the argument to the action is the WindowEvent
2962 inputEventAction := aOneArgActionTheEvent.
2966 "called for a new mapped view which can not be found
2967 in the current item list
2972 mappedViewAction:aOneArgBlockTheMappedView
2973 "called for a new mapped view which can not be found
2974 in the current item list
2976 mappedViewAction := aOneArgBlockTheMappedView
2979 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing look'!
2981 iconAt:aKey ifNonePut:aNoneArgBlock
2984 icon := icons at:aKey ifAbsent:nil.
2985 icon notNil ifTrue:[^ icon].
2987 icon := aNoneArgBlock value.
2988 icon isNil ifTrue:[^ nil].
2990 view := self rootView.
2991 view isNil ifTrue:[^ icon].
2993 icon := icon copy onDevice:(view device).
2994 icon isImage ifTrue:[
2995 icon clearMaskedPixels.
2997 icons at:aKey put:icon.
3001 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'accessing visibility'!
3004 "show the selection if signaled; increments hiddenLevel
3005 see: #waitHiddenLevel
3007 (hiddenLevel := hiddenLevel - 1) < 1 ifTrue:[
3009 self invalidateSelection.
3014 "hide the selection until signaled; increments hiddenLevel
3015 see: #signalHiddenLevel
3017 self redrawUnselected:selection andLock:true
3020 withSelectionHiddenDo:aNoneArgumentBlock
3021 "apply block with selection hidden
3024 [ self waitHiddenLevel.
3026 aNoneArgumentBlock value
3028 ] valueNowOrOnUnwindDo:[
3029 self signalHiddenLevel.
3033 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'aspects'!
3035 hasTargetWidgetChannel
3036 "answer the channel which is set to true if a target widget exists"
3038 ^ hasTargetWidgetChannel
3042 "hiearchical list build from existing items"
3048 "boolean holder, which indicates whether the selection will change on click
3050 ^ selectOnClickHolder
3054 "answer a boolean channel which describes the behaviour how to process
3055 events on the target view.
3057 false: all input events are eaten and the selection is shown on the target view.
3058 true: no input events are eaten and no selection is shown on the target view."
3063 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'change & update'!
3066 hasTargetWidgetChannel value:(self rootItem notNil).
3069 timedUpdateTaskCycle
3072 myTaskId := timedUpdateTask.
3074 listOfItems root notNil ifTrue:[
3075 view := listOfItems root widget.
3078 [ view notNil ] whileTrue:[
3079 Delay waitForSeconds:0.5.
3081 (myTaskId == timedUpdateTask and:[view id notNil]) ifFalse:[
3084 (view sensor hasUserEvent:#updateChildren for:self) ifFalse:[
3085 view sensor pushUserEvent:#updateChildren for:self.
3089 timedUpdateTask == myTaskId ifTrue:[
3090 timedUpdateTask := nil.
3091 listOfItems root:nil.
3095 update:something with:someArgument from:aModel
3097 aModel == testModeChannel ifTrue:[
3098 (hiddenLevel == 0 and:[selection size > 0]) ifTrue:[
3099 testModeChannel value ifTrue:[
3100 self redrawUnselected:selection andLock:false checkTestMode:false.
3102 self invalidateSelection.
3107 super update:something with:someArgument from:aModel.
3113 rootItem := listOfItems root.
3114 rootItem isNil ifTrue:[^ self].
3116 rootItem exists ifFalse:[
3117 listOfItems root:nil.
3119 rootItem updateChildren.
3123 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'event processing'!
3125 processEvent:anEvent
3126 "catch and process all WindowEvents for the rootComponent and its contained
3127 widgets; redraw selection in case of damage...
3128 return true, if the event was eaten"
3130 |evView item rootView testMode|
3132 catchEvents ifFalse:[^ false].
3134 evView := anEvent view.
3135 evView isNil ifTrue:[
3136 (anEvent isMessageSendEvent not or:[anEvent receiver ~~ self]) ifTrue:[
3142 rootView := listOfItems rootView.
3143 rootView isNil ifTrue:[ ^ false ].
3145 anEvent isConfigureEvent ifTrue:[
3146 hiddenLevel == 0 ifTrue:[
3147 self redrawUnselected:selection andLock:false.
3152 "/ check whether view is contained within the rootView
3153 (evView == rootView or:[evView isComponentOf:rootView]) ifFalse:[
3157 anEvent isInputEvent ifFalse:[
3158 anEvent isDamage ifTrue:[
3159 hiddenLevel == 0 ifTrue:[self invalidateSelection].
3163 anEvent isMapEvent ifTrue:[
3164 mappedViewAction notNil ifTrue:[
3165 item := listOfItems recursiveDetect:[:el| el widget == evView].
3166 item isNil ifTrue:[ mappedViewAction value:evView ]
3171 anEvent type == #terminate ifTrue:[
3172 item := listOfItems recursiveDetect:[:el| el widget == evView].
3173 item notNil ifTrue:[ self processTerminateForItem:item ].
3178 testMode := testModeChannel value.
3180 anEvent isFocusEvent ifTrue:[
3181 evView == rootView ifTrue:[
3182 self invalidateSelection
3186 anEvent isPointerEnterLeaveEvent ifTrue:[ ^ testMode not ].
3189 inputEventAction notNil ifTrue:[ inputEventAction value:anEvent ].
3191 anEvent isButtonPressEvent ifTrue:[
3192 selectOnClickHolder value ifTrue:[
3193 self selectItem:(listOfItems detectItemRespondsToView:evView).
3198 (hiddenLevel ~~ 0 and:[anEvent isButtonReleaseEvent]) ifTrue:[
3200 self signalHiddenLevel.
3206 processTerminateForItem:anItem
3207 "received terminate for an item
3212 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'initialization'!
3215 "setup the default attributes
3220 lockSema := RecursionLock new.
3221 listOfItems := ItemList new on:self.
3222 selectedSuperItems := #().
3223 icons := IdentityDictionary new.
3224 catchEvents := true.
3226 hasTargetWidgetChannel := false asValue.
3227 selectOnClickHolder := true asValue.
3229 testModeChannel := false asValue.
3230 testModeChannel addDependent:self.
3233 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'private selection'!
3236 "invalidate the current selection
3240 testModeChannel value ifTrue:[ ^ self ]. "/ test whether running testMode
3243 and:[selection notNil
3244 and:[(topView := listOfItems rootView) notNil
3245 and:[topView shown]]]
3247 topView sensor pushUserEvent:#redrawSelection for:self withArguments:#()
3251 recursiveRepair:theDamages startIn:aView relativeTo:aRootView
3252 "repair all views and contained views, which intersects the damage.
3253 !!!! all damages repaired are removed from the list of damages !!!!
3255 |color relOrg damage subViews repaired
3256 bwWidth "{ Class:SmallInteger }"
3257 x "{ Class:SmallInteger }"
3258 y "{ Class:SmallInteger }"
3259 w "{ Class:SmallInteger }"
3260 h "{ Class:SmallInteger }"
3261 relOrgX "{ Class:SmallInteger }"
3262 relOrgY "{ Class:SmallInteger }"
3263 width "{ Class:SmallInteger }"
3264 height "{ Class:SmallInteger }"
3265 size "{ Class:SmallInteger }"
3267 (aView shown and:[theDamages notEmpty]) ifFalse:[ ^ self ].
3269 subViews := aView subViews.
3271 subViews size ~~ 0 ifTrue:[
3272 subViews reverseDo:[:v| self recursiveRepair:theDamages startIn:v relativeTo:aRootView ].
3273 theDamages isEmpty ifTrue:[ ^ self ].
3276 relOrg := aView originRelativeTo:aRootView.
3277 bwWidth := aView borderWidth.
3278 size := theDamages size.
3280 "/ compute relative origin starting from border left@top
3281 relOrgX := relOrg x - bwWidth.
3282 relOrgY := relOrg y - bwWidth.
3283 width := aView width + bwWidth + bwWidth.
3284 height := aView height + bwWidth + bwWidth.
3286 size to:1 by:-1 do:[:anIndex|
3287 repaired := damage := theDamages at:anIndex.
3289 "/ compute the rectangle into the view
3290 y := damage top - relOrgY.
3291 x := damage left - relOrgX.
3295 x < 0 ifTrue:[ w := w + x. x := 0. repaired := nil ].
3296 y < 0 ifTrue:[ h := h + y. y := 0. repaired := nil ].
3297 x + w > width ifTrue:[ w := width - x. repaired := nil ].
3298 y + h > height ifTrue:[ h := height - y. repaired := nil ].
3300 (w > 0 and:[h > 0]) ifTrue:[
3301 bwWidth ~~ 0 ifTrue:[
3302 color isNil ifTrue:[
3303 "/ must force redraw of border
3304 color := aView borderColor.
3305 aView borderColor:(Color colorId:1).
3306 aView borderColor:color.
3311 (x := x - bwWidth) < 0 ifTrue:[w := w + x. x := 0].
3312 (y := y - bwWidth) < 0 ifTrue:[h := h + y. y := 0].
3314 h > 0 ifFalse:[w := 0]. "/ later testing on width only
3318 aView clearRectangleX:x y:y width:w height:h.
3319 aView exposeX:x y:y width:w height:h
3321 repaired notNil ifTrue:[ theDamages removeFromIndex:anIndex toIndex:anIndex ].
3327 "redraw all items selected
3331 testModeChannel value ifTrue:[ ^ self ]. "/ test whether running testMode
3334 and:[(size := selection size) > 0
3335 and:[(topView := listOfItems rootView) notNil
3337 and:[(topView sensor hasEvent:#redrawSelection for:self) not]]]]
3347 list size > 0 ifTrue:[
3348 topView paint:(Color black).
3349 topView clippedByChildren:false.
3351 list keysAndValuesReverseDo:[:anIndex :anItem|
3352 (anIndex == 1 and:[size > 1]) ifTrue:[ topView paint:(Color red) ].
3354 anItem handlesDo:[:aRect :what|
3355 what isNil ifTrue:[topView displayRectangle:aRect]
3356 ifFalse:[topView fillRectangle:aRect]
3359 topView clippedByChildren:true.
3364 redrawUnselected:aList andLock:doLock
3365 "redraw all items unselected; if doLock is true, the hiddenLevel
3366 is incremented and thus the select mechanism is locked.
3368 self redrawUnselected:aList andLock:doLock checkTestMode:true.
3371 redrawUnselected:aList andLock:doLock checkTestMode:checkTestMode
3372 "redraw all items unselected; if doLock is true, the hiddenLevel
3373 is incremented and thus the select mechanism is locked.
3375 |rootView damages subViews x y w h|
3378 hiddenLevel := hiddenLevel + 1.
3379 hiddenLevel ~~ 1 ifTrue:[^ self].
3381 hiddenLevel ~~ 0 ifTrue:[^ self].
3383 checkTestMode ifTrue:[
3384 testModeChannel value ifTrue:[ ^ self ]. "/ test whether running testMode
3388 and:[(rootView := listOfItems rootView) notNil
3389 and:[rootView shown]]
3395 damages := OrderedCollection new:(8 * aList size).
3398 item handlesDo:[:handle :what|
3399 damages reverseDo:[:el|
3400 (el intersects:handle) ifTrue:[
3401 damages removeIdentical:el.
3403 handle left:(handle left min:el left)
3404 right:(handle right max:el right)
3405 top:(handle top min:el top)
3406 bottom:(handle bottom max:el bottom)
3419 rootView clearRectangleX:x y:y width:w height:h.
3420 rootView exposeX:x y:y width:w height:h.
3423 (subViews := rootView subViews) notNil ifTrue:[
3424 subViews reverseDo:[:v| self recursiveRepair:damages startIn:v relativeTo:rootView ].
3429 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'queries'!
3432 "answer false, all input events are eaten and the selection is shown on the target view.
3433 answer true, no input events are eaten and no selection is shown on the target view."
3435 ^ testModeChannel value
3438 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection accessing'!
3441 "returns the selected item at an index or nil
3443 selection notNil ifTrue:[
3444 ^ selection at:anIndex ifAbsent:nil
3449 at:anIndex ifAbsent:aBlock
3450 "returns the selected item at an index or the result of the block
3452 selection notNil ifTrue:[
3453 ^ selection at:anIndex ifAbsent:aBlock
3459 "returns the first selected item or nil
3465 "returns the last selected item or nil
3467 ^ selection notNil ifTrue:[selection last] ifFalse:[nil]
3471 "returns the single selected item or nil (size ~~ 1 nil is returned)
3473 ^ selection size == 1 ifTrue:[selection at:1] ifFalse:[nil]
3477 "returs the list of selected superItems; items selected
3478 but not contained in another selected item.
3480 ^ selectedSuperItems
3484 "returns the number of items selected
3489 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection adding & removing'!
3492 "add an item to the current selection
3496 item isNil ifTrue:[^ item].
3499 selection isNil ifTrue:[
3500 newSelect := Array with:item.
3502 (self includes:item) ifFalse:[
3503 newSelect := selection copyWith:item
3507 newSelect size ~~ selection size ifTrue:[
3509 self value:newSelect
3515 addAll:aCollectionOfItems
3516 "add a collection of items to the current selection
3520 aCollectionOfItems size == 0 ifTrue:[ ^ aCollectionOfItems ].
3523 selection isNil ifTrue:[
3524 newSelect := Array withAll:aCollectionOfItems.
3526 newSelect := OrderedCollection withAll:selection.
3528 aCollectionOfItems do:[:el|
3529 (selection includesIdentical:el) ifFalse:[newSelect add:el]
3532 self value:newSelect.
3534 ^ aCollectionOfItems
3538 "clear the selection
3544 "remove the item from the current selection
3548 item isNil ifTrue:[^ nil].
3551 (selection notNil and:[selection includesIdentical:item]) ifTrue:[
3552 selection size == 1 ifTrue:[ newSelect := nil ]
3553 ifFalse:[ newSelect := selection copyWithout:item ].
3555 self value:newSelect
3562 "clear the selection
3568 "remove all items of the collection from the current selection
3572 selection isNil ifTrue:[ ^ loItems ].
3573 loItems size == 0 ifTrue:[ ^ loItems ].
3576 selection notNil ifTrue:[
3577 newSelect := selection select:[:el| (loItems includesIdentical:el) not ].
3578 self value:newSelect.
3589 root := listOfItems root.
3594 newSelection := OrderedCollection new.
3595 root recursiveDo:[:el| newSelection add:el ].
3597 self value:newSelection.
3601 "set the current selection to the item
3607 "set the current selection to the root item
3609 self value:(self rootItem).
3613 "set the current selection to the item
3615 self selectItem:anItem.
3618 toggleSelectItem:anItem
3619 "toggle selection-state of the item; add or remove the item from the
3622 anItem notNil ifTrue:[
3623 (self includes:anItem) ifTrue:[self remove:anItem]
3624 ifFalse:[self add:anItem]
3629 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection enumerating'!
3632 "for each element in the selection, evaluate the argument, aBlock
3633 and return a new collection with the results
3637 res := OrderedCollection new.
3638 self do:[:el| res add:(aBlock value:el)].
3643 "evaluate the argument, aBlock for each item in the selection
3647 cashedSelection := selection.
3648 cashedSelection isNil ifTrue:[^ nil].
3649 ^ cashedSelection do:aOneArgBlock
3652 from:start do:aOneArgBlock
3653 "evaluate the argument, aBlock for the items starting at index start
3657 cashedSelection := selection.
3658 cashedSelection isNil ifTrue:[^ nil].
3659 ^ cashedSelection from:start do:aOneArgBlock
3662 from:start to:stop do:aOneArgBlock
3663 "evaluate the argument, aBlock for the items with index start to
3664 stop in the selection.
3668 cashedSelection := selection.
3669 cashedSelection isNil ifTrue:[^ nil].
3670 ^ cashedSelection from:start to:stop do:aOneArgBlock
3673 reverseDo:aOneArgBlock
3674 "evaluate the argument, aBlock for each item in the selection
3678 cashedSelection := selection.
3679 cashedSelection isNil ifTrue:[^ nil].
3680 ^ cashedSelection reverseDo:aOneArgBlock
3684 "return a new collection with all elements from the selection, for which
3685 the argument aBlock evaluates to true.
3689 res := OrderedCollection new.
3690 self do:[:el| (aBlock value:el) ifTrue:[res add:el] ].
3694 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection protocol'!
3696 changed:aParameter with:oldSelection
3697 "update the visibility staus of the current selection
3699 |unselected rootView rootItem selSize|
3701 selSize := selection size.
3703 selSize == 0 ifTrue:[
3704 selectedSuperItems := #().
3706 selSize == 1 ifTrue:[
3707 selectedSuperItems := Array with:(selection at:1).
3709 rootItem := listOfItems root.
3711 (selection includesIdentical:rootItem) ifTrue:[
3712 selectedSuperItems := Array with:rootItem.
3714 selectedSuperItems := OrderedCollection new:selSize.
3716 selection do:[:anItem|
3717 anItem parentsDetect:[:el| selection includesIdentical:el ]
3718 ifNone:[ selectedSuperItems add:anItem ].
3725 and:[(rootView := listOfItems rootView) notNil
3726 and:[rootView shown]]
3728 selSize == 0 ifTrue:[
3729 "/ must redraw the old selection unselected
3730 self redrawUnselected:oldSelection andLock:false
3732 self invalidateSelection.
3734 oldSelection size ~~ 0 ifTrue:[
3735 "/ must redraw all elements no longer in the selection
3736 unselected := oldSelection select:[:el| (selection includesIdentical:el) not ].
3737 self redrawUnselected:unselected andLock:false.
3741 super changed:aParameter with:oldSelection.
3744 setValue:aNewSelection
3745 "set the selection without notifying
3751 aNewSelection notNil ifTrue:[
3753 aNewSelection isCollection ifFalse:[
3754 (selection size == 1 and:[selection first == aNewSelection]) ifTrue:[
3755 newSelect := selection
3757 newSelect := Array with:aNewSelection.
3760 aNewSelection notEmpty ifTrue:[
3761 aNewSelection size ~~ selection size ifTrue:[
3762 newSelect := aNewSelection copy.
3764 idx := selection findFirst:[:el| (aNewSelection includesIdentical:el) not ].
3766 idx ~~ 0 ifTrue:[newSelect := aNewSelection copy]
3767 ifFalse:[newSelect := selection ].
3773 newSelect ~~ selection ifTrue:[
3774 beforeSelectionChangedAction value.
3775 selection := newSelect.
3776 selection notNil ifTrue:[selection do:[:el| el makeVisible]]
3781 "set my value & send change notifications to my dependents.
3782 Send the change message even if the value didn't change.
3787 oldSelection := selection.
3788 self setValue:aValue.
3789 self changed:#value with:oldSelection
3794 "returns the current selection
3800 "change the current selection and send change notifications to my
3801 dependents if it changed.
3806 oldSelection := selection.
3807 self setValue:aValue.
3809 oldSelection == selection ifFalse:[
3810 self changed:#value with:oldSelection
3815 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection searching'!
3818 "evaluate the argument, aBlock for each item in the selection until
3819 the block returns true; in this case return the element which caused
3820 the true evaluation.
3821 If none of the evaluations returns true, an error is raised
3823 ^ self detect:aBlock ifNone:[self errorNotFound]
3826 detect:aBlock ifNone:exceptionBlock
3827 "evaluate the argument, aBlock for each item in the selection until the
3828 block returns true; in this case return the element which caused the
3830 If none of the evaluations returns true, the result of the evaluation
3831 of the exceptionBlock is returned
3835 cashedSelection := selection.
3836 cashedSelection isNil ifTrue:[ ^ exceptionBlock value ].
3837 ^ cashedSelection detect:aBlock ifNone:exceptionBlock
3841 "evaluate the argument, aBlock for each item in the selection until
3842 the block returns true; in this case return the element which caused
3843 the true evaluation. The items are processed in reverse order.
3844 If none of the evaluations returns true, an error is raised
3846 ^ self detectLast:aBlock ifNone:[self errorNotFound]
3849 detectLast:aBlock ifNone:exceptionBlock
3850 "evaluate the argument, aBlock for each item in the selection until
3851 the block returns true; in this case return the element which caused
3852 the true evaluation. The items are processed in reverse order.
3853 If none of the evaluations returns true, the result of the evaluation
3854 of the exceptionBlock is returned
3858 cashedSelection := selection.
3859 cashedSelection isNil ifTrue:[ ^ exceptionBlock value ].
3860 ^ cashedSelection detectLast:aBlock ifNone:exceptionBlock
3863 !ViewTreeInspectorApplication::ViewTreeModel methodsFor:'selection testing'!
3866 "returns true if the item is in the current selection
3870 cashedSelection := selection.
3871 cashedSelection isNil ifTrue:[^ false].
3872 ^ cashedSelection includesIdentical:anItem
3875 includesAll:aCollection
3876 "return true, if all items of the collection are included in the current selection
3880 aCollection size ~~ 0 ifTrue:[
3881 cashedSelection := selection.
3882 cashedSelection isNil ifTrue:[ ^ false ].
3884 aCollection do:[:el|
3885 (cashedSelection includesIdentical:el) ifFalse:[^ false]
3891 includesAny:aCollection
3892 "return true, if the any item of the collection is in the current selection
3896 aCollection notNil ifTrue:[
3897 cashedSelection := selection.
3899 cashedSelection notNil ifTrue:[
3900 aCollection do:[:el|
3901 (cashedSelection includesIdentical:el) ifTrue:[^ true]
3908 includesIdentical:anItem
3909 "returns true if the item is in the current selection
3911 ^ self includes:anItem
3915 "returns true if the current selection is empty
3917 ^ selection size == 0
3921 "returns true if the item is in the current selection
3923 ^ self includes:anItem
3927 "returns true if the current selection is not empty
3929 ^ selection size ~~ 0
3932 !ViewTreeInspectorApplication::ViewTreeModel::ItemList class methodsFor:'documentation'!
3936 Kind of HierarchicalList class which contains all the visible
3937 ViewTreeItem's and the root, the anchor of the hierarchical list.
3939 [Instance variables:]
3940 treeModel <ViewTreeModel> all events are delegated to
3941 eventHook <BlockValue> save and resore the pre/post -EventHook
3954 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'accessing'!
3957 "set the root item; delegate events to my treeModel
3961 theRoot == root ifTrue:[^ self].
3963 rootView := self rootView.
3966 rootView notNil ifTrue:[ |wgrp|
3967 wgrp := rootView windowGroup.
3969 wgrp notNil ifTrue:[
3970 wgrp removePreEventHook:treeModel.
3971 wgrp removePostEventHook:self.
3976 rootView := self rootView.
3978 rootView notNil ifTrue:[
3979 "must setup a task because there might not exist a windowGroup at the moment
3983 [rootView == self rootView] whileTrue:[
3984 wgrp := rootView windowGroup.
3985 wgrp notNil ifTrue:[
3987 wgrp addPreEventHook:treeModel.
3988 wgrp addPostEventHook:self.
3990 Delay waitForMilliseconds:100.
3994 ] forkAt:(Processor userSchedulingPriority + 2).
3996 treeModel notNil ifTrue:[
3997 treeModel targetWidgetChanged.
4004 "returns the widget assigned to the root or nil
4006 ^ root notNil ifTrue:[root widget] ifFalse:[nil]
4010 "returne the treeModel, a ViewTreeModel
4015 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'accessing look'!
4017 additionalLabelForItem:anItem
4018 "answer the additional lable for an item or nil"
4020 |widget l applClass applClassName key|
4022 widget := anItem widget.
4025 showWidgetNames == true ifTrue:[
4026 l := '"', widget name, '"'
4029 anItem isApplicationClass ifTrue:[
4030 applClass := anItem applicationClass.
4031 applClass notNil ifTrue:[
4032 applClassName := '[', applClass name allBold, ']'.
4033 l := (l isNil ifTrue:[''] ifFalse:[l , ' ']) , applClassName
4037 application notNil ifTrue:[
4038 key := application builder namedComponents keyAtValue:widget ifAbsent:nil.
4048 "answer true if the additional text is the widget name
4049 otherwise the name of the application"
4051 ^ showWidgetNames ? true
4054 showWidgetNames:aBoolean
4055 "set true if the additional text is the widget name
4056 otherwise the name of the application"
4058 self showWidgetNames == aBoolean ifFalse:[
4059 showWidgetNames := aBoolean.
4061 root notNil ifTrue:[
4062 root recursiveAdditionalNameBehaviourChanged.
4068 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'event processing'!
4070 processEvent:anEvent
4073 ^ treeModel isInTestMode not
4076 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'instance creation'!
4079 "set the model, a ViewTreeModel
4081 treeModel := aModel.
4083 "/ showWidgetNames := false.
4084 showWidgetNames := true.
4087 !ViewTreeInspectorApplication::ViewTreeModel::ItemList methodsFor:'searching'!
4089 detectItemRespondsToView:aView
4090 "returns the bottom-most item which contains the view
4094 root notNil ifTrue:[
4096 topView := root widget.
4098 [ view notNil ] whileTrue:[
4099 topView == view ifTrue:[^ root].
4100 item := root recursiveDetect:[:el| el widget == view ].
4101 item notNil ifTrue:[^ item].
4102 view := view superView
4108 recursiveDetect:aOneOrgBlock
4109 "recursive find the first child, for which evaluation
4110 of the block returns true; if none nil is returned
4112 root notNil ifTrue:[
4113 (aOneOrgBlock value:root) ifTrue:[ ^ root ].
4114 ^ root recursiveDetect:aOneOrgBlock
4119 !ViewTreeInspectorApplication class methodsFor:'documentation'!
4130 ViewTreeInspectorApplication initialize!
4131 ViewTreeInspectorApplication::ViewTreeItem initialize!