platform-ui-home/workbench_design/Inside the workbench.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (view) (download) (as text)

1 : sxenos 1.1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 :     <html>
3 :     <head>
4 : sxenos 1.4 <meta http-equiv="Content-Type"
5 :     content="text/html; charset=windows-1252">
6 : sxenos 1.1 <title>Inside the Workbench: A guide to the workbench internals</title>
7 : sxenos 1.4 <link rel="stylesheet" href="default_style.css">
8 : sxenos 1.1 </head>
9 : sxenos 1.4 <body link="#0000ff" vlink="#800080">
10 :     <div align="right">&nbsp; <font face="Times New Roman, Times, serif"
11 : sxenos 1.5 size="2">Copyright © 2005 International Business Machines Corp.</font>
12 : sxenos 1.4 <table border="0" cellpadding="2" cellspacing="0" width="100%">
13 : sxenos 1.1 <tbody>
14 :     <tr>
15 :     <td colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font
16 : sxenos 1.4 face="Arial,Helvetica"><font color="#ffffff">&nbsp;Eclipse Corner
17 :     Article</font></font></b></td>
18 : sxenos 1.1 </tr>
19 :     </tbody>
20 :     </table>
21 :     </div>
22 : sxenos 1.4 <div align="left">
23 :     <h1><a class="mozTocH1" name="mozTocId282580"></a><img
24 :     src="images/Idea.jpg" align="middle" height="86" width="120"></h1>
25 :     </div>
26 :     <p>&nbsp;</p>
27 :     <h1 align="center"><a class="mozTocH1" name="mozTocId119947"></a>Inside
28 :     the
29 : sxenos 1.1 Workbench<br>
30 :     A guide to the workbench internals<br>
31 : sxenos 1.4 </h1>
32 : sxenos 1.5 <blockquote> <b>Summary</b> <br>
33 : sxenos 1.4 This document describes how the Eclipse 3.1 workbench works. It
34 :     describes the infrastructure that makes views and editors work. The
35 : sxenos 1.1 goal is to make the reader familiar with important classes in the
36 :     workbench, and how they interact. It is assumed that the reader is
37 : sxenos 1.3 already familiar with using the workbench APIs and with creating views,
38 : sxenos 1.4 editors, action sets, etc.
39 :     <p><b>Stefan Xenos, IBM</b> <br>
40 :     <font size="-1">July 12, 2005</font> </p>
41 :     </blockquote>
42 : sxenos 1.1 <br>
43 :     <hr style="width: 100%; height: 2px;">
44 : sxenos 1.4 <h1><a class="mozTocH1" name="mozTocId744856"></a>Table of Contents</h1>
45 : sxenos 1.1 <ul id="mozToc">
46 : sxenos 1.4 <!--mozToc h2 1 h3 2 h4 3 h5 4 h6 5--><li><a href="#mozTocId917303">1.0
47 :     Introduction
48 :     </a></li>
49 :     <li><a href="#mozTocId270357">2.0 Inside a part
50 :     </a>
51 : sxenos 1.1 <ul>
52 : sxenos 1.4 <li><a href="#mozTocId713423">2.1 Part Lifecycle
53 :     </a></li>
54 :     <li><a href="#mozTocId789670">2.2 Part Construction</a></li>
55 : sxenos 1.1 </ul>
56 :     </li>
57 : sxenos 1.4 <li><a href="#mozTocId409413">3.0 Workbench Layout
58 :     </a>
59 : sxenos 1.1 <ul>
60 : sxenos 1.4 <li><a href="#mozTocId95893">3.1 An example layout</a></li>
61 :     <li><a href="#mozTocId114962">3.2 Zoom / Unzoom
62 :     protocol
63 :     </a></li>
64 :     <li><a href="#mozTocId977378">3.3 Layout protocol
65 :     </a></li>
66 :     <li><a href="#mozTocId162591">3.4 PartStack:
67 :     Communicating with the Presentation API
68 :     </a></li>
69 :     <li><a href="#mozTocId479574">3.5
70 :     PartSashContainer: The main workbench layout </a></li>
71 :     <li><a href="#mozTocId887241">3.6 Drag / Drop</a></li>
72 : sxenos 1.1 </ul>
73 :     </li>
74 : sxenos 1.5 <li><a href="#mozTocId443855">4.0 Action Bars</a>
75 : sxenos 1.1 <ul>
76 : sxenos 1.5 <li><a href="#mozTocId652269">4.1 Editor Action Bars
77 : sxenos 1.4 </a></li>
78 : sxenos 1.5 <li><a href="#mozTocId340925">4.2 Action Sets
79 : sxenos 1.4 </a></li>
80 : sxenos 1.5 <li><a href="#mozTocId277128">4.3 View Actions</a></li>
81 : sxenos 1.1 </ul>
82 :     </li>
83 : sxenos 1.5 <li><a href="#mozTocId642161">5.0 General
84 : sxenos 1.4 Conventions</a>
85 : sxenos 1.1 <ul>
86 : sxenos 1.5 <li><a href="#mozTocId892615">5.1 Objects must not
87 : sxenos 1.4 be returned through API until they are fully initialized</a></li>
88 : sxenos 1.5 <li><a href="#mozTocId308622">5.2 No method may
89 : sxenos 1.4 open a modal dialog unless its JavaDoc says so</a></li>
90 : sxenos 1.5 <li><a href="#mozTocId753192">5.3 Lazy creation
91 : sxenos 1.4 should happen as late as possible
92 :     </a></li>
93 : sxenos 1.5 <li><a href="#mozTocId921869">5.4 getters should
94 : sxenos 1.4 not modify the thing they are supposed to measure
95 :     </a></li>
96 : sxenos 1.1 </ul>
97 :     </li>
98 :     </ul>
99 : sxenos 1.4 <br>
100 : sxenos 1.1 <div style="margin-left: 40px;"><span style="font-weight: bold;"></span></div>
101 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId917303"></a><span
102 : sxenos 1.1 style="font-weight: bold;"></span><span style="font-weight: bold;">1.0
103 :     Introduction</span>
104 :     <br>
105 : sxenos 1.4 </h2>
106 : sxenos 1.3 <span style="font-weight: bold;"></span> This document describes
107 :     workbench internals and not API. The design of internals changes
108 :     frequently. For information on newer Eclipse versions, the latest
109 :     version of this document can be found on the <a
110 :     href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-ui-home/dev.html">UI
111 :     development resources page</a>.<br>
112 :     <br>
113 : sxenos 1.1 <br>
114 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
115 : sxenos 1.4 1: Ownership of views and editors<br>
116 : sxenos 1.1 <br>
117 :     </span></div>
118 :     <div style="text-align: center;"><img alt=""
119 :     src="workbench_high_level.PNG" style="width: 600px; height: 340px;"><br>
120 :     </div>
121 :     <br>
122 : sxenos 1.4 Figure 1 shows how views and editors are owned by the workbench.<br>
123 : sxenos 1.1 <br>
124 :     The Workbench contains one or more WorkbenchWindows, each of which
125 :     contain zero or more WorkbenchPages. The WorkbenchWindow supplies the
126 :     trim widgets, and the WorkbenchPage supplies the window
127 :     contents. In theory, a WorkbenchWindow can contain any number of pages,
128 :     but in practice there is never more than 1 page in a window.<br>
129 :     <br>
130 :     Views and editors are owned by the page, through a ViewFactory and
131 :     EditorManager respectively. EditorManager stores the list of editors
132 :     and their shared
133 :     resources, and ViewFactory stores a reference counted list of views.
134 :     The workbench works in terms of EditorReferences and ViewReferences,
135 :     and in this article the terms "editor" or "view" will refer to these
136 :     classes specifically. In situations where the distinction between
137 :     editors and views is not important, we will simply use the term "part".
138 :     The implementation of the part (typically an IEditorPart or IViewPart)
139 : sxenos 1.4 is created lazily when it is first needed. As shown in Figure 2, a
140 : sxenos 1.1 part reference exists for every tab but the implementation is only
141 :     created the first time it becomes visible.<br>
142 :     <br>
143 :     The page owns a set of perspectives. Perspectives contain a layout and
144 :     information about what action sets to enable. Although perspectives
145 :     appear to contain views and the editor area, they only own a layout.
146 :     The page itself maintains a reference count for how many perspectives
147 :     are using each view, and has complete ownership of the parts and editor
148 :     area.<br>
149 :     <br>
150 :     Not shown in figure 1 are the classes PerspectiveHelper and
151 :     EditorAreaHelper. These classes exist largely for historic purposes,
152 :     and in this article we will treat the former as though it were part of
153 :     the Perspective class and the latter as part of the WorkbenchPage class.<br>
154 :     <br>
155 :     <br>
156 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
157 : sxenos 1.4 2: Workbench objects and what they look like<br>
158 : sxenos 1.1 <br>
159 :     </span></div>
160 :     <div style="text-align: center;"><img alt="" src="what_you_see.PNG"
161 :     style="width: 892px; height: 700px;"><br>
162 :     </div>
163 :     <br>
164 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId270357"></a>2.0 Inside a part<br>
165 :     </h2>
166 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">
167 : sxenos 1.4 Figure 3: Anatomy of a part</span><br>
168 : sxenos 1.1 </div>
169 :     <div style="text-align: center;"><img alt="" src="anatomy_of_a_part.PNG"
170 :     style="width: 420px; height: 280px;"><br>
171 :     </div>
172 : sxenos 1.4 Internally, a part consists of several objects (Figure 3).
173 : sxenos 1.1 WorkbenchPartReference is the topmost representation of the part.
174 :     Depending on where it is used, the part reference is often exposed as
175 :     IWorkbenchPartReference, IViewReference, IEditorRefenece, or
176 :     IPresentablePart, or PartPane. These are essentially different
177 :     interfaces to the same object. The I*Reference interfaces are
178 :     implemented directly by WorkbenchPartReference and its subclasses.
179 :     IPresentablePart is a simple adapter that redirects its methods
180 :     directly to the part. PartPane implements the LayoutPart protocol which
181 :     is needed to insert the part into the workbench layout. PartPane also
182 :     manages the SWT resources (such as a top-level control) that are needed
183 :     to include the control in the workbench layout.<br>
184 :     <br>
185 :     The part implementation (the IEditorPart or IViewPart) is owned by the
186 :     reference. When the
187 :     implementation is created, it is given a PartSite. The PartSite (seen
188 :     by client code as an IWorkbenchPartSite, IEditorSite, or IViewSite)
189 :     allows the client code to communicate with the reference and manages
190 :     services created for the implementation.<br>
191 :     <br>
192 : sxenos 1.3 WorkbenchPartReferences allocates SWT resources lazily as needed.
193 : sxenos 1.1 Once created, the part reference must be explicitly disposed. Disposing
194 :     the reference cleans up all of its resources (including the part
195 :     implementation itself) and guarantees that the reference will never
196 :     allocate additional resources. The workbench page disposes the part
197 :     reference once it is certain that it will never need to use that part
198 :     again. Unlike SWT controls, it is valid to continue using the reference
199 :     after it has been disposed. A disposed part reference is unlikely to do
200 :     anything interesting besides returning its name and cannot be used with
201 :     any
202 :     methods in the workbench page. Since it is hard (or impossible) for
203 :     clients to track the lifecycle of the reference, they are permitted to
204 :     continue using its public interface after disposal.<br>
205 :     <br>
206 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId713423"></a>2.1 Part Lifecycle<br>
207 :     </h3>
208 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
209 : sxenos 1.4 4: WorkbenchPartReference states<br>
210 : sxenos 1.1 <br>
211 :     </span></div>
212 :     <div style="text-align: center;"><img alt="" src="part_states.PNG"
213 :     style="width: 445px; height: 590px;"><br>
214 :     </div>
215 : sxenos 1.4 Figure 4 shows the part lifecycle as a state machine. The part
216 : sxenos 1.1 reference stores its current state in the integer state field.<br>
217 :     <br>
218 :     Notes:<br>
219 :     <ul>
220 :     <li>The part is in a distinct state while it is in the process of
221 :     creating the implementation. It cannot be recursively re-created or
222 :     disposed while it is in this state.</li>
223 :     <li>The part implementation cannot be recreated once the reference
224 :     has been disposed.</li>
225 :     <li>Parts cannot return to the lazy state once they have been
226 :     created. This is a limitation in the 3.1 implementation, not a
227 :     functional requirement.</li>
228 :     <li>It is valid to continue using the public interface of
229 :     WorkbenchPartReference once it has been disposed, however a disposed
230 :     reference cannot be passed to methods in workbench page (since it is,
231 :     by definition, no longer part of any page).</li>
232 :     </ul>
233 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId789670"></a>2.2 Part Construction</h3>
234 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
235 : sxenos 1.4 5: Message sequence for creating a part<br>
236 : sxenos 1.1 <br>
237 :     </span></div>
238 :     <div style="text-align: center;"><img alt="" src="part_creation_msc.PNG"
239 :     style="width: 892px; height: 700px;"><br>
240 :     </div>
241 :     <br>
242 : sxenos 1.4 Figure 5 shows the process for creating a part. The horizontal
243 : sxenos 1.1 line separates the two phases of creating a part. First the part is
244 :     added to the layout, and then a real implementation is attached. These
245 :     are two distinct operations, and the part can exist as a tab in the
246 :     page with no implementation for some time before it becomes visible.
247 :     This diagram focuses on the interactions with the part reference, and
248 :     skips the details of adding the part to the presentation and creating
249 :     the part site.<br>
250 :     <br>
251 : sxenos 1.4 Suggestion: there are situations where it would be useful to only
252 : sxenos 1.1 add the part to the layout if it can be created successfully (this
253 :     would be necessary to pass a PartInitException thrown in the
254 :     implementation's init method up through IWorkbenchPage.openEditor). In
255 :     these situations, it would be possible to merge both operations into
256 :     one atomic operation by creating the part before adding it to the
257 :     layout. It is unknown if this would create event ordering bugs in
258 :     client code.<br>
259 :     <br>
260 :     <span style="font-weight: bold;"></span>
261 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId409413"></a>3.0 Workbench Layout<br>
262 :     </h2>
263 : sxenos 1.1 <br>
264 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
265 : sxenos 1.4 6: LayoutPart hierarchy</span><br>
266 : sxenos 1.1 <img alt="" src="LayoutPart_hierarchy.PNG"
267 :     style="width: 302px; height: 412px;"><br>
268 :     </div>
269 :     <br>
270 :     The workbench layout provides supports arranging parts using drag &amp;
271 :     drop, resizing and detaching parts, fast views, etc. This section gives
272 :     a quick overview of the layout mechanism.<br>
273 :     <br>
274 :     Anything in the workbench layout is a LayoutPart. A LayoutPart manages
275 :     a set of widgets in a rectangular region of the screen, can contain or
276 :     arrange other layout parts, returns size constraints, responds to drag
277 :     events, etc. To this extent, a LayoutPart is very similar to a custom
278 :     SWT Control. However, LayoutPart differs from Control in several
279 :     important ways.<br>
280 :     <ul>
281 :     <li>The LayoutPart hierarchy is not the same as the widget hierarchy.
282 :     Even though one LayoutPart may contain another, their widgets may be
283 :     peers. This allows drag and drop to work on platforms where SWT doesn't
284 :     support reparenting, since a LayoutPart can be reparented without
285 :     reparenting its widgets.<br>
286 :     </li>
287 :     <li>LayoutParts mainly perform layout-related tasks, unlike Controls
288 :     which also supply behavior and appearance. The behavior of a LayoutPart
289 :     is supplied by the widgets it arranges.<br>
290 :     </li>
291 :     <li>LayoutParts know about higher-level concepts like zoom, and can
292 :     specify constraints about their own size.<br>
293 :     </li>
294 :     </ul>
295 : sxenos 1.4 Figure 6 shows the LayoutPart hierarchy. Notice the symmetry
296 : sxenos 1.1 between the View* classes and the Editor* classes. These classes exist
297 :     largely for historical reasons, and it should be possible to move all
298 :     of the functionality into the Part* base classes or other objects in
299 :     the system. Since all of the interesting behavior comes from the Part*
300 :     classes, the remainder of this section will focus on them without
301 :     describing the minor differences between views and editors.<br>
302 :     <br>
303 :     PartSashContainer arranges a set of child parts separated by a bunch of
304 :     sashes. This is the object that implements the most visible aspects of
305 :     the workbench layout. It arranges rectangular regions separated by
306 :     sashes, and allows new regions to be created by splitting old ones. It
307 :     also supports the size constraints that make minimized views possible,
308 :     and determines what it means for one of these regions to be maximized.
309 :     Typically, a PartSashContainer contains a bunch of PartStacks, although
310 :     it is also possible for it to contain another PartSashContainer. The
311 :     latter case occurs since the editor area and the perspective both use a
312 :     PartSashContainer for their layout and one is embedded inside the
313 :     other. PartSashContainer owns its stacks but does not own an embedded
314 :     PartSashContainer. In a workbench window, there is one
315 :     PartSashContainer for each perspective and one for the editor area
316 :     itself.<br>
317 :     <br>
318 :     PartStack arranges a stack of PartPanes. PartStack allows the
319 :     presentation API to participate in the workbench layout. The code for
320 :     creating the tabs and arranging parts is supplied by the active
321 :     presentation.<br>
322 :     <br>
323 :     PartPane allows views and editors to participate in the workbench
324 :     layout. Although PartPanes are arranged by PartStacks they belong to
325 :     part reference, not the stack. The same PartPane can exist in more than
326 :     one PartStack at a time if that part appears in more that one
327 :     perspective.<span style="font-weight: bold;"><br>
328 :     <br>
329 :     </span>
330 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId95893"></a>3.1 An example layout</h3>
331 : sxenos 1.1 LayoutParts are best explained through example. Imagine a
332 :     WorkbenchWindow that contains custom Java and Java Browsing
333 : sxenos 1.4 perspectives that look like Figure 7 and Figure 8
334 : sxenos 1.1 respectively.<br>
335 :     <br>
336 :     <br>
337 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
338 : sxenos 1.4 7: Example Java Perspective</span><br>
339 : sxenos 1.1 <img alt="" src="perspective1.PNG" style="width: 571px; height: 495px;"><br>
340 :     <br>
341 : sxenos 1.4 <span style="font-weight: bold;">Figure 8: Example Java Browsing
342 : sxenos 1.1 perspective</span><br>
343 :     <img alt="" src="perspective2.PNG" style="width: 571px; height: 495px;"><br>
344 :     </div>
345 :     <br>
346 : sxenos 1.4 <br>
347 :     Assume that the window resembles Figure 7. In this case, the Java
348 : sxenos 1.1 perspective is active, the Java Browsing perspective is hidden, and the
349 : sxenos 1.4 objects are connected as shown in Figure 9:<br>
350 :     <br>
351 : sxenos 1.1 <br>
352 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
353 : sxenos 1.4 9: LayoutPart instances when two perspectives are open</span><br>
354 : sxenos 1.1 <img alt="" src="perspective1_2_instances.PNG"
355 :     style="width: 555px; height: 670px;"><br>
356 :     <div style="text-align: left;"><br>
357 :     </div>
358 :     </div>
359 :     <br>
360 : sxenos 1.2 <br>
361 :     All LayoutParts have a container pointer that points to the object that
362 :     is currently managing their position. Since the same LayoutPart
363 :     instance may exist in more than one perspective at once, this pointer
364 :     points to the part's container in the currently-active perspective. In
365 :     the case of the projects view, above, the part is not in the current
366 :     perspective so its container pointer is null. When another
367 :     perspective becomes active, all the container pointers move to the new
368 :     perspective. For historical reasons, this is accomplished by setting
369 :     and
370 :     clearing the contianer pointer when the container becomes visible or
371 :     invisible. This works since only one perspective is visible at a time,
372 :     but it also means that perspectives cannot be manipulated when they are
373 :     invisible.<br>
374 : sxenos 1.1 <br>
375 :     The diagram shows the internal objects that make up the only editor.
376 :     Although this detail has been omitted for the views, they would look
377 :     similar. Each view's PartPane is owned by a part reference which may
378 : sxenos 1.2 have an associated part implementation.<br>
379 : sxenos 1.1 <br>
380 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId114962"></a>3.2 Zoom / Unzoom
381 : sxenos 1.1 protocol<br>
382 : sxenos 1.4 </h3>
383 : sxenos 1.1 The notion of "zoom" is defined locally between a part and its
384 :     immediate container. Zoom changes are triggered bottom-up. A part asks
385 :     its parent to "zoom me", and the parent either does something with the
386 :     request or forwards the request up to its parent. Each container
387 :     determines what it means for a child to be zoomed. Once a part's zoom
388 :     state changes, its parent notifies it by calling setZoomed. The part
389 :     may in turn zoom or unzoom one or more of its children.<br>
390 :     <br>
391 :     Anything that can contain LayoutParts must implement the following
392 : sxenos 1.4 methods, to support zooming:<br>
393 :     <span style="font-family: monospace;"><br>
394 : sxenos 1.1 </span><code>&nbsp;&nbsp;&nbsp; /**<br>
395 :     &nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom in,
396 :     given an immediate child <br>
397 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
398 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toZoom part to zoom in on<br>
399 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
400 :     &nbsp;&nbsp;&nbsp; public void childRequestZoomIn(LayoutPart toZoom);<br>
401 :     &nbsp;&nbsp;&nbsp; <br>
402 :     &nbsp;&nbsp;&nbsp; /**<br>
403 :     &nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom out<br>
404 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
405 :     &nbsp;&nbsp;&nbsp; public void childRequestZoomOut();<br>
406 :     &nbsp;&nbsp;&nbsp; <br>
407 :     &nbsp;&nbsp;&nbsp; /**<br>
408 :     &nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff the given child is obscured
409 :     due to the fact that the container is zoomed into<br>
410 :     &nbsp;&nbsp;&nbsp;&nbsp; * another part. <br>
411 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
412 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
413 :     &nbsp;&nbsp;&nbsp;&nbsp; * @return true iff the part is currently
414 :     obscured <br>
415 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
416 :     &nbsp;&nbsp;&nbsp; public boolean childObscuredByZoom(LayoutPart
417 :     toTest);<br>
418 :     &nbsp;&nbsp;&nbsp; <br>
419 :     &nbsp;&nbsp;&nbsp; /**<br>
420 :     &nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff we are zoomed into the
421 :     given part, given an immediate child of this container.<br>
422 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
423 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
424 :     &nbsp;&nbsp;&nbsp;&nbsp; * @return true iff this contianer is currently
425 :     zooming in on the given part<br>
426 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
427 :     &nbsp;&nbsp;&nbsp; public boolean childIsZoomed(LayoutPart toTest);<br>
428 : sxenos 1.4 <br>
429 : sxenos 1.1 </code><br>
430 : sxenos 1.4 Consider again Figure 7. If we were to double-click on the java
431 : sxenos 1.1 editor to zoom it, the LayoutParts would send messages to one another
432 :     in the following sequence. (In this diagram, each cell represents a
433 :     method call. Each column is an object. The reciever's column shows the
434 :     method name and the caller contains an arrow. Rows are in ascending
435 :     order of time.)<br>
436 :     <br>
437 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
438 :     cellspacing="2">
439 :     <tbody>
440 :     <tr>
441 :     <td style="vertical-align: top; font-weight: bold;">Java Editor
442 :     (PartPane)<br>
443 :     </td>
444 :     <td style="vertical-align: top; font-weight: bold;">PartStack<br>
445 :     </td>
446 :     <td style="vertical-align: top; font-weight: bold;">editor area
447 :     (EditorSashContainer)<br>
448 :     </td>
449 :     <td style="vertical-align: top; font-weight: bold;">ViewSashContainer<br>
450 :     </td>
451 :     </tr>
452 :     <tr>
453 :     <td style="vertical-align: top;">requestZoomIn<br>
454 :     </td>
455 :     <td style="vertical-align: top;"><br>
456 :     </td>
457 :     <td style="vertical-align: top;"><br>
458 :     </td>
459 :     <td style="vertical-align: top;"><br>
460 :     </td>
461 :     </tr>
462 :     <tr>
463 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
464 :     style="width: 42px; height: 17px;"><br>
465 :     </td>
466 :     <td style="vertical-align: top;">childRequestZoomIn(java editor)<br>
467 :     </td>
468 :     <td style="vertical-align: top;"><br>
469 :     </td>
470 :     <td style="vertical-align: top;"><br>
471 :     </td>
472 :     </tr>
473 :     <tr>
474 :     <td style="vertical-align: top;"><br>
475 :     </td>
476 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
477 :     style="width: 42px; height: 17px;"><br>
478 :     </td>
479 :     <td style="vertical-align: top;">childRequestZoomIn(java editor's
480 :     part stack)<br>
481 :     </td>
482 :     <td style="vertical-align: top;"><br>
483 :     </td>
484 :     </tr>
485 :     <tr>
486 :     <td style="vertical-align: top;"><br>
487 :     </td>
488 :     <td style="vertical-align: top;"><br>
489 :     </td>
490 :     <td style="vertical-align: top;">if there were other editor
491 :     stacks in the layout, we would call setVisible(false) on them here</td>
492 :     <td style="vertical-align: top;"><br>
493 :     </td>
494 :     </tr>
495 :     <tr>
496 :     <td style="vertical-align: top;"><br>
497 :     </td>
498 :     <td style="vertical-align: top;"><br>
499 :     </td>
500 :     <td style="vertical-align: top;">remember the partStack as the
501 :     zoomed part<br>
502 :     </td>
503 :     <td style="vertical-align: top;"><br>
504 :     </td>
505 :     </tr>
506 :     <tr>
507 :     <td style="vertical-align: top;"><br>
508 :     </td>
509 :     <td style="vertical-align: top;">setZoomed(true)<br>
510 :     </td>
511 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
512 :     style="width: 42px; height: 17px;"><br>
513 :     </td>
514 :     <td style="vertical-align: top;"><br>
515 :     </td>
516 :     </tr>
517 :     <tr>
518 :     <td style="vertical-align: top;">setZoomed(true)<br>
519 :     </td>
520 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
521 :     style="width: 42px; height: 17px;"><br>
522 :     </td>
523 :     <td style="vertical-align: top;"><br>
524 :     </td>
525 :     <td style="vertical-align: top;"><br>
526 :     </td>
527 :     </tr>
528 :     <tr>
529 :     <td style="vertical-align: top;"><br>
530 :     </td>
531 :     <td style="vertical-align: top;"><br>
532 :     </td>
533 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
534 :     style="width: 42px; height: 17px;"><br>
535 :     </td>
536 :     <td style="vertical-align: top;">childRequestZoomIn(editor area)<br>
537 :     </td>
538 :     </tr>
539 :     <tr>
540 :     <td style="vertical-align: top;"><br>
541 :     </td>
542 :     <td style="vertical-align: top;"><br>
543 :     </td>
544 :     <td style="vertical-align: top;"><br>
545 :     </td>
546 :     <td style="vertical-align: top;">call setVisible(false) on all
547 :     PartStacks for views in the perspective<br>
548 :     </td>
549 :     </tr>
550 :     <tr>
551 :     <td style="vertical-align: top;"><br>
552 :     </td>
553 :     <td style="vertical-align: top;"><br>
554 :     </td>
555 :     <td style="vertical-align: top;"><br>
556 :     </td>
557 :     <td style="vertical-align: top;">remember the editor area as the
558 :     zoomed part<br>
559 :     </td>
560 :     </tr>
561 :     <tr>
562 :     <td style="vertical-align: top;"><br>
563 :     </td>
564 :     <td style="vertical-align: top;"><br>
565 :     </td>
566 :     <td style="vertical-align: top;">setZoomed(true)<br>
567 :     </td>
568 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
569 :     style="width: 42px; height: 17px;"></td>
570 :     </tr>
571 :     <tr>
572 :     <td style="vertical-align: top;"><br>
573 :     </td>
574 :     <td style="vertical-align: top;"><br>
575 :     </td>
576 :     <td style="vertical-align: top;"><br>
577 :     </td>
578 :     <td style="vertical-align: top;">trigger a layout<br>
579 :     </td>
580 :     </tr>
581 :     <tr>
582 :     <td style="vertical-align: top;"><br>
583 :     </td>
584 :     <td style="vertical-align: top;"><br>
585 :     </td>
586 :     <td style="vertical-align: top;">setBounds(zoomed bounds)<br>
587 :     </td>
588 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
589 :     style="width: 42px; height: 17px;"></td>
590 :     </tr>
591 :     <tr>
592 :     <td style="vertical-align: top;"><br>
593 :     </td>
594 :     <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
595 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
596 :     style="width: 42px; height: 17px;"></td>
597 :     <td style="vertical-align: top;"><br>
598 :     </td>
599 :     </tr>
600 :     <tr>
601 :     <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
602 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
603 :     style="width: 42px; height: 17px;"></td>
604 :     <td style="vertical-align: top;"><br>
605 :     </td>
606 :     <td style="vertical-align: top;"><br>
607 :     </td>
608 :     </tr>
609 :     <tr>
610 :     <td style="vertical-align: top;"><br>
611 :     </td>
612 :     <td style="vertical-align: top;"><br>
613 :     </td>
614 :     <td style="vertical-align: top;">trigger a layout (nothing to do)<br>
615 :     </td>
616 :     <td style="vertical-align: top;"><br>
617 :     </td>
618 :     </tr>
619 :     </tbody>
620 :     </table>
621 :     <br>
622 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId977378"></a>3.3 Layout protocol<br>
623 :     </h3>
624 : sxenos 1.1 Every LayoutPart can specify constraints on their size. Parts specify
625 :     constraints by implementing the ISizeProvider interface. ISizeProvider
626 :     serves a similar function as the computeSize method on an SWT control,
627 :     in that the parent layout uses it to consult with the part when
628 :     computing the part's size. ISizeProvider can provide a variety of
629 :     constraints:<br>
630 :     <br>
631 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
632 :     cellspacing="2">
633 :     <tbody>
634 :     <tr>
635 :     <td style="vertical-align: top; font-weight: bold;">Constraint
636 :     type<br>
637 :     </td>
638 :     <td style="vertical-align: top; font-weight: bold;">Meaning<br>
639 :     </td>
640 :     </tr>
641 :     <tr>
642 :     <td style="vertical-align: top;">Minimum size<br>
643 :     </td>
644 :     <td style="vertical-align: top;">Given the available space along
645 :     one dimension, the part returns the minimum size that it can be
646 :     compressed to along the other dimension. For example, a stack would
647 :     typically set its minimum size to be large enough to fit its tabs. The
648 :     information about available perpendicular space could allow a stack to
649 :     have wrapping tabs and still reserve enough vertical space for the tabs
650 :     once they are wrapped to fill the available horizontal space.<br>
651 :     </td>
652 :     </tr>
653 :     <tr>
654 :     <td style="vertical-align: top;">Maximum size<br>
655 :     </td>
656 :     <td style="vertical-align: top;">Given the available space along
657 :     one dimension, the part returns the maximum size that it can utilize
658 :     along the other dimension. For example, minimized stacks are
659 :     implemented by setting their maximum size to the minimized size.
660 :     Non-minimized stacks typically have an unbounded maximum size.<br>
661 :     </td>
662 :     </tr>
663 :     <tr>
664 :     <td style="vertical-align: top;">Preferred size<br>
665 :     </td>
666 :     <td style="vertical-align: top;">Given the availble space along
667 :     one dimension and a preferred size, this returns the size closest to
668 :     the preferred size at which the part would look best. Parts can use
669 :     this to quantize their size. For example, a part can ensure that its
670 :     size is always chosen such that it can be completely filled with
671 :     toolbar icons leaving no space left over.<br>
672 :     </td>
673 :     </tr>
674 :     </tbody>
675 :     </table>
676 :     <br>
677 :     Although there are three kinds of constraints, they are all returned
678 :     using a single method. See the JavaDoc on ISizeProvider for more
679 :     information.<br>
680 :     <br>
681 :     Whenever a size constraint changes, the part notifies its contianer by
682 :     calling resizeChild(part). This tells the container to respond to the
683 : sxenos 1.4 new constraints, and to resize the child if necessary (suggestion:
684 : sxenos 1.1 if this is ever exposed as API, it would be better to separate the
685 :     concerns of notifying the parent of changes and triggering a layout. In
686 :     general, it may be possible for more than one part to change without
687 :     requiring a layout between each change).<br>
688 :     <br>
689 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId162591"></a>3.4 PartStack:
690 : sxenos 1.1 Communicating with the Presentation API<br>
691 : sxenos 1.4 </h3>
692 : sxenos 1.1 PartStack allows presentation to participate in the workbench layout.
693 : sxenos 1.4 As shown in Figure 10, it wraps a single instance of
694 : sxenos 1.1 StackPresentation, and allows it the presentation to manipulate parts
695 :     by converting each visible part into an IPresentablePart. The part
696 :     stack outlives the StackPresentation. Whenever the part stack needs
697 :     widgets, it creates the StackPresentation. If the widgets are no longer
698 :     needed, it disposes the StackPresentation and remembers its persisted
699 :     form. Whenever the PartStack persists its StackPresenation, it
700 :     remembers the presentation ID so that it will not try to restore one
701 :     StackPresentation from state saved by an incompatible presentation.<br>
702 :     <br>
703 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
704 : sxenos 1.4 10: Anatomy of PartStack</span><br>
705 : sxenos 1.1 <img alt="" src="PartStack.PNG" style="width: 430px; height: 225px;"><br>
706 :     <div style="text-align: left;"><br>
707 : sxenos 1.4 Suggestion: it would be useful to update this document with a state
708 : sxenos 1.1 diagram for PartStack, and message sequence charts for initializaiton
709 :     and part activation.<br>
710 :     <br>
711 :     </div>
712 :     </div>
713 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId479574"></a>3.5
714 : sxenos 1.1 PartSashContainer: The main workbench layout <br>
715 : sxenos 1.4 </h3>
716 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
717 : sxenos 1.4 11: PartSashContainer</span><br>
718 : sxenos 1.1 <img alt="" src="PartSashContainer.PNG"
719 :     style="width: 428px; height: 305px;"><br>
720 :     </div>
721 :     <br>
722 :     PartSashContainer implements the main layout for a perspective and the
723 : sxenos 1.4 editor area. As shown in Figure 11, PartSashContainer contains a
724 : sxenos 1.1 list of children, a (possibly null) zoomed part, and a LayoutTree that
725 :     manages the actual layout. <br>
726 :     <br>
727 :     LayoutTree is a binary tree (technically, a KD tree). Each internal
728 :     node is an instance of LayoutTreeNode. It contains a draggable sash
729 :     (LayoutPartSash) that divides its area among its left and right
730 :     children. LayoutTreeNodes can be horizontal or vertical based on the
731 :     orientation of the sash. For horizontal nodes, the "left" child is on
732 :     top and the "right" child is on the bottom. Leaf nodes are instances of
733 :     LayoutTree (the base class), and they point to a LayoutPart that
734 :     occupies that region of the screen. Normally, this is a PartStack, but
735 :     in general it can be any LayoutPart. <br>
736 :     <br>
737 :     Each LayoutTree occupies a recangular region of the screen that
738 :     encompasses its children. Internal nodes keep track of an integer size
739 :     for each child (implementation note: the sizes are stored in the
740 :     associated LayoutPartSash, not the LayoutTreeNode itself). Normally,
741 :     the left and right sizes are used as a ratio for dividing up the
742 :     available space. However, when one child contains the editor area, the
743 :     other becomes "non-compressible". If one side in non-compressible, the
744 :     size value is interpreted as a fixed pixel size rather than a ratio.
745 :     When the sash is moved, the size values are set to the current pixel
746 :     sizes of the left and right children.<br>
747 :     <br>
748 : sxenos 1.4 Figure 12 shows an example LayoutTree. If this tree were rendered
749 : sxenos 1.1 in a workbench window, it would resemble Figure 3.5.3. The tall
750 :     vertical sash separating the package explorer from the editor area is
751 :     the root node. The left child is the leaf node holding the package
752 :     explorer's stack. The right node is the horizontal sash separating the
753 :     problems view from the editor area. The editor area itself is a
754 :     PartSashContainer, which has its own LayoutTree. Note that the rounded
755 :     rectangles in Figure 3.5.2 are LayoutParts. The upper portion of the
756 :     rectangle is the part type and the lower portion is some text to help
757 :     locate the part in the screenshot. In this example, every internal node
758 :     has the editor area on one side of it, so all sizes are interpreted as
759 :     pixel sizes and not ratios.<br>
760 :     <div style="text-align: center;"><span style="font-weight: bold;"></span><br>
761 : sxenos 1.4 <span style="font-weight: bold;">Figure 12: Example LayoutTree</span><br
762 : sxenos 1.1 style="font-weight: bold;">
763 :     <img alt="" src="example_LayoutTree.PNG"
764 :     style="width: 480px; height: 462px; font-weight: bold;"><br>
765 :     <span style="font-weight: bold;"><br>
766 : sxenos 1.4 Figure 13: Example perspective</span><br style="font-weight: bold;">
767 : sxenos 1.1 <img alt="" src="perspective1.PNG"
768 :     style="width: 571px; height: 495px; font-weight: bold;"><br>
769 :     </div>
770 :     <br>
771 :     Like LayoutParts, LayoutTrees also implement ISizeProvider and support
772 :     size constraints. For external nodes, the size constraints come
773 :     directly from the LayoutPart. For internal nodes, the size constraints
774 :     are computed from the child nodes as follows:<br>
775 :     <ol>
776 :     <li>When computing a constraint perpendicular to the sash, the result
777 :     is the sum of the constraints of the children plus the width of the
778 :     sash.</li>
779 :     <li>When computing a constraint parallel to the sash, the result is
780 :     the maximum of the constraints of the children<br>
781 :     </li>
782 :     </ol>
783 :     An example can help make this a little less abstract. Imagine we're
784 : sxenos 1.4 computing the minimum width for the root node in Figure 12, which
785 : sxenos 1.1 is a tall vertical sash. Width measurements are perpendicular to the
786 :     sash, so we end up with case 1. The minimum width is the minimum width
787 :     of the left stack plus the sash width plus the minimum width of the
788 :     right child. This makes sense because if we made the root node any
789 :     smaller, one of the three would need to be truncated or made smaller
790 :     than their minimum size.<br>
791 :     <br>
792 :     The "right child" mentioned above is the horizontal sash separating the
793 :     problems view from the editor area. When computing its minimum width,
794 :     we hit case 2: the minimum width of a horizantal sash is the maximum of
795 :     the minimum widths of each child. Intuitively, this means that the
796 :     child with the larger minimum size will be the first to reach its
797 :     minimum when the layout gets small.<br>
798 :     <br>
799 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId887241"></a>3.6 Drag / Drop</h3>
800 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
801 : sxenos 1.4 14: LayoutPart drop regions</span><br>
802 : sxenos 1.1 </div>
803 :     <div style="text-align: center;"><img alt="" src="drag_regions.PNG"
804 :     style="width: 571px; height: 495px;"><br>
805 :     <div style="text-align: left;"><br>
806 :     Dragging a workbench part is triggered by calling DragUtil.performDrag.
807 :     SWT controls can respond to drag / drop by registering an
808 :     IDragOverListener with DragUtil .addDragTarget. If multiple drag
809 :     listeners are registered for the same screen position, the one
810 :     associated with the most specific control gets precidence.<br>
811 :     <br>
812 :     Rather than register drag listeners directly, LayoutParts implement a
813 :     getDropTarget method. When the window recieves a drag event, it
814 :     delegates to the top-level LayoutPart's getDropTarget. Each part either
815 :     delegates to one of its children or handles the drag event directly. If
816 :     the part returns null from getDropTarget, this means that the part has
817 :     no special preference for the drop event, and the parent may provide a
818 :     default behavior. Unlike IDragOverListener, getDropTarget works
819 :     top-down. The parent may overload any drag regions that are recognized
820 :     by the child, or provide default behaviors for drag regions not
821 :     recognized by the child.<br>
822 :     <br>
823 : sxenos 1.4 Figure 14 shows regions of the workbench where LayoutParts can be
824 : sxenos 1.1 dropped. The workbench checks these regions in the following order:<br>
825 :     <br>
826 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
827 :     cellspacing="2">
828 :     <tbody>
829 :     <tr>
830 :     <td style="vertical-align: top;"><span
831 :     style="color: rgb(0, 51, 0);">1. green region</span><br>
832 :     </td>
833 :     <td style="vertical-align: top;">The fast view bar registers a
834 :     IDragOverListener that responds to views being dragged.<br>
835 :     </td>
836 :     </tr>
837 :     <tr>
838 :     <td style="vertical-align: top;"><span
839 :     style="background-color: rgb(0, 0, 0);"><span
840 :     style="background-color: rgb(255, 255, 255);">2. black regions</span></span><br>
841 :     </td>
842 :     <td style="vertical-align: top;">These areas are reserved by
843 :     PartSashContainer.getDropTarget. When the user drags a part over this
844 :     region, the PartSashContainer interprets this as a split and does not
845 :     ask its child to participate in the drag. This ensures that it is never
846 :     possible for the child to prevent splitting by reserving its entire
847 :     area as a drop region. The region outside the PartSashContainer's
848 :     client area is handled by an IDragOverListener registered with the
849 :     shell. This allows parts to be attached to the edge of the layout by
850 :     dragging over the window trim.<br>
851 :     </td>
852 :     </tr>
853 :     <tr>
854 :     <td style="vertical-align: top;"><span
855 :     style="color: rgb(255, 0, 0);">3. red regions</span><br>
856 :     </td>
857 :     <td style="vertical-align: top;">For most of the screen area,
858 :     PartSashContainer delegates to its child (PartStack.getDropTarget).
859 :     PartStack filters out objects that don't belong in the stack (no
860 :     editors in view stacks, etc) and delegates to the presentation
861 :     (StackPresentation.dragOver). The default presentation recognizes the
862 :     tabs and title area as drop targets, but returns null everywhere else.
863 :     This is the best practice for presentations and PartStack since it
864 :     permits PartSashContainer to extend the split regions where possible.<br>
865 :     </td>
866 :     </tr>
867 :     <tr>
868 :     <td style="vertical-align: top;"><span
869 :     style="color: rgb(0, 0, 153);">4. blue regions</span><br>
870 :     </td>
871 :     <td style="vertical-align: top;">If the child doesn't have any
872 :     particular use for the drop location, the PartSashContainer extends the
873 :     split regions. If the child allows objects of this type to be added
874 :     (determined by calling LayoutPart.allowsAdd), it uses the center of the
875 :     rectangle for stacking. Otherwise, the entire region is used for
876 :     splitting. The latter case occurs when dragging views over the editor
877 :     area or when dragging over a standalone view.<br>
878 :     </td>
879 :     </tr>
880 :     <tr>
881 :     <td style="vertical-align: top;">5. outside the window (not shown)<br>
882 :     </td>
883 :     <td style="vertical-align: top;">The workbench page registers an
884 :     IDragOverListener that responds to views being dragged outside the
885 :     workbench window, and interprets this as a detach operation.<br>
886 :     </td>
887 :     </tr>
888 :     </tbody>
889 :     </table>
890 :     <br>
891 :     By convention, all methods used for drag / drop work in display
892 :     coordinates.<br>
893 : sxenos 1.4 <br>
894 : sxenos 1.1 </div>
895 :     </div>
896 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId443855"></a>4.0 Action Bars</h2>
897 : sxenos 1.1 Parts contribute to menus, toolbars, coolbars, popup menus, etc. using
898 :     action bars. Each action bar implements IActionBars. It is possible to
899 :     create one action bar as a child of another. In this situation, the
900 :     parent and child share the same widgets, but the child may be disabled
901 : sxenos 1.4 independently of the parent. Figure 15 shows how the workbench
902 : sxenos 1.1 action bars are
903 :     constructed. The rectangles indicate instances of IActionBars, and the
904 :     ovals indicate other entities that create or modify action bars.<br>
905 :     <br>
906 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
907 : sxenos 1.4 15: Action bar information flow</span><br>
908 : sxenos 1.1 <img alt="" src="action_bar_flow.PNG"
909 :     style="width: 800px; height: 600px;"><br>
910 :     <div style="text-align: left;"><p:colorscheme
911 :     colors="#FFFFFF,#000000,#808080,#000000,#00CC99,#3333CC,#CCCCFF,#B2B2B2"></p:colorscheme>
912 :     <div v:shape="_x0000_s2050" class="O">
913 :     <div style=""><span style="font-size: 50%;"><br>
914 :     </span><span style="font-family: Symbol; font-size: 50%;"></span><span
915 :     style="font-size: 50%;"></span><span
916 :     style="font-family: Symbol; font-size: 50%;"></span><span
917 :     style="font-size: 50%;"></span><span
918 :     style="font-family: Symbol; font-size: 50%;"></span><span
919 :     style="font-size: 50%;"></span></div>
920 :     <div style=""><span style="display: none;">
921 :     </span></div>
922 :     </div>
923 :     </div>
924 :     </div>
925 :     <br>
926 :     The workbench window has a top level IActionBars instance that
927 :     contributes to the main menubar, coolbar, etc. (this top-level object
928 :     is returned by WorkbenchWindow.getActionBars()).<br>
929 :     <br>
930 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId652269"></a>4.1 Editor Action Bars<br>
931 :     </h3>
932 : sxenos 1.1 Each type of editor gets a reference-counted IActionBars instance that
933 :     is a child of the window's action bars. For
934 :     example, if the workbench contains 10 java editors and 10 text editors,
935 :     it will create one IActionBars to be shared among the Java editors and
936 :     another IActionBars to be shared among the text editors. Editors can
937 :     access this shared instance by calling getSite().getActionBars().
938 :     Editor action bars are initialized by an instance of
939 :     IEditorActionBarContributor, and additional actions are added by the
940 :     editorActions
941 :     extension point.<br>
942 :     <br>
943 :     The reference counted IEditorActionBars are managed by the
944 :     EditorManager, along with the IActionBarContributor.<br>
945 :     <br>
946 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId340925"></a>4.2 Action Sets<br>
947 :     </h3>
948 : sxenos 1.1 An action set is an action bar that is identified by ID. Action sets
949 :     are contributed by the actionSets extension point, and their action
950 :     bars are a child of the workbench window's root action bars. Visibility
951 :     of action sets is controlled by the following function:<br>
952 :     <br>
953 :     <div style="margin-left: 40px;"><img alt="" src="action_set_formula.PNG"
954 :     style="width: 208px; height: 29px;"><br>
955 :     </div>
956 :     <br>
957 :     Where:<br>
958 :     <br>
959 :     <div style="margin-left: 40px;">P = set of actions enabled in the
960 :     perspective. Returned by Perspective.getAlwaysOnActionSets().
961 :     Initialized by the perspective factory, perspective extensions
962 :     extension point, and IWonkbenchPage.showActionSet.<br>
963 :     A = action sets associated with the active part (associated by the
964 :     actionSetPartAssociations extension point).<br>
965 :     E = action sets associated with the active editor (associated by the
966 :     actionSetPartAssociations extension point).<br>
967 :     D = action sets that are enabled by default (a property of the
968 :     actionSets extension markup).<br>
969 :     N = action sets that are explicitly disabled in the current
970 :     perspective. Initialized by IWorkbenchPage.hideActionSet.<br>
971 :     </div>
972 :     <br>
973 :     The sets P and N are persisted with the current perspective between
974 :     sessions. The sets A and E can change every time the active part or
975 :     editor changes.<br>
976 :     <br>
977 :     The workbench page uses the class ActionSetManager to compute action
978 :     set enablement. This class keeps two reference counts for each action
979 :     set: <br>
980 :     <ul>
981 :     <li>a "showCount" indicates how many of P, A, E, and D the action set
982 :     appears in</li>
983 :     <li>a "hideCount" indicates whether the action set appears in N</li>
984 :     </ul>
985 :     The action set is visible iff showCount is nonzero and hideCount is
986 :     zero.<br>
987 :     <br>
988 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId277128"></a>4.3 View Actions</h3>
989 : sxenos 1.1 Each view instance is given its own IActionBars instance. Unlike editor
990 :     action bars, these are not shared and are not a child of the workbench
991 :     window's root action bars. This means that view instances can
992 :     programmatically add actions to their action bar. Additional actions
993 :     are also added to a view's action bars through the viewActions
994 :     extension point.<br>
995 :     <br>
996 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId642161"></a>5.0 General
997 :     Conventions</h2>
998 : sxenos 1.1 This section describes coding conventions that apply to the entire
999 :     workbench.<br>
1000 : sxenos 1.4 <br>
1001 :     <h3><a class="mozTocH3" name="mozTocId892615"></a>5.1 Objects must not
1002 :     be returned through API until they are fully initialized</h3>
1003 : sxenos 1.1 Some objects require several public methods to be called in a specific
1004 :     order before they are considered fully initialized. For example, to
1005 :     initialize an IViewPart, it is necessary to call the constructor,
1006 :     setInitializationData, init, and createPartControl before the part is
1007 :     considered initialized. Until <span style="font-style: italic;">all</span>
1008 :     of the above have happened successfully, it must not be possible to
1009 :     reach the object through any API method.<br>
1010 :     <br>
1011 : sxenos 1.3 Keep in mind that the object may trigger other client code during its
1012 :     own
1013 : sxenos 1.1 initialization, so it should not even be possible for an object to find
1014 :     itself during construction.<br>
1015 : sxenos 1.4 <br>
1016 :     <h3><a class="mozTocH3" name="mozTocId308622"></a>5.2 No method may
1017 :     open a modal dialog unless its JavaDoc says so</h3>
1018 : sxenos 1.1 Any method that has the possibility of opening a modal (or of calling
1019 :     Display.readAndDispatch through any other means) needs to be clearly
1020 :     documented. All callers of that method must be prepared to handle
1021 :     background
1022 :     threads running arbitrary code in *syncExecs during the method call. It
1023 :     is always a bug to open a modal dialog when extending or overloading a
1024 :     method unless the JavaDoc in the base class says otherwise. Permitting
1025 :     opening of dialogs in a method that did not previously do so is a
1026 :     breaking change for all callers of that method.<br>
1027 :     <br>
1028 :     Some common bugs:<br>
1029 :     <ul>
1030 :     <li>Views are never allowed to call MessageDialog.openError from
1031 :     their createPartControls method, especially when handling an exception.</li>
1032 :     <li>Parts can be closed in a *syncExec. If a part calls a method that
1033 :     opens dialogs, it might not still exist when the method returns. After
1034 :     calling the method, the part must check that it hasn't been disposed
1035 :     before using their widgets or accessing any members that would have
1036 : sxenos 1.4 been deallocated by the disposal.</li>
1037 : sxenos 1.1 </ul>
1038 : sxenos 1.4 <br>
1039 :     <h3><a class="mozTocH3" name="mozTocId753192"></a>5.3 Lazy creation
1040 : sxenos 1.1 should happen as late as possible<br>
1041 : sxenos 1.4 </h3>
1042 : sxenos 1.1 Part implementations should be created at the latest possible moment.
1043 :     The workbench's internal state should be restored as much as possible
1044 :     before the first object is created from an extension point. Parts
1045 :     should not be materialized until they are needed.<br>
1046 : sxenos 1.4 <br>
1047 :     <h3><a class="mozTocH3" name="mozTocId921869"></a>5.4 getters should
1048 : sxenos 1.1 not modify the thing they are supposed to measure<br>
1049 : sxenos 1.4 </h3>
1050 : sxenos 1.1 This applies to any situation where there is a getter and an associated
1051 :     listener that monitors changes in the getter's value. The getter should
1052 :     never cause such a property change to be fired while computing its
1053 :     return value.<br>
1054 :     <br>
1055 :     For example, IWorkbenchPage.getActivePart() should never create the
1056 :     active part. Unless the active part already exists and a property
1057 :     change was fired to all IPartListeners, getActivePart must return null.<br>
1058 :     <br>
1059 :     <br>
1060 :     </body>
1061 :     </html>