| 30 |
A guide to the workbench internals<br> |
A guide to the workbench internals<br> |
| 31 |
</h1> |
</h1> |
| 32 |
<blockquote> <b>Summary</b> <br> |
<blockquote> <b>Summary</b> <br> |
| 33 |
This document describes how the Eclipse 3.1 workbench works. It |
This article describes how the Eclipse 3.1 workbench works, in |
| 34 |
describes the infrastructure that makes views and editors work. The |
particular the infrastructure for views and editors. The goal is to |
| 35 |
goal is to make the reader familiar with important classes in the |
teach you about important classes in the workbench, and how they |
| 36 |
workbench, and how they interact. It is assumed that the reader is |
interact. A familiarity with the basic workbench APIs for views, |
| 37 |
already familiar with using the workbench APIs and with creating views, |
editors, action sets, and so forth is assumed. |
|
editors, action sets, etc. |
|
| 38 |
<p><b>Stefan Xenos, IBM</b> <br> |
<p><b>Stefan Xenos, IBM</b> <br> |
| 39 |
<font size="-1">July 12, 2005</font> </p> |
<font size="-1">January 6, 2006</font> </p> |
| 40 |
</blockquote> |
</blockquote> |
| 41 |
<br> |
<br> |
| 42 |
<hr style="width: 100%; height: 2px;"> |
<hr style="width: 100%; height: 2px;"> |
| 43 |
<h1><a class="mozTocH1" name="mozTocId744856"></a>Table of Contents</h1> |
<h1><a class="mozTocH1" name="mozTocId744856"></a>Table of Contents</h1> |
| 44 |
<ul id="mozToc"> |
<ul id="mozToc"> |
| 45 |
<!--mozToc h2 1 h3 2 h4 3 h5 4 h6 5--><li><a href="#mozTocId917303">1.0 |
<!--mozToc h2 1 h3 2 h4 3 h5 4 h6 5--><li><a href="#mozTocId917303">1.0 |
| 46 |
Introduction |
Introduction </a></li> |
| 47 |
</a></li> |
<li><a href="#mozTocId270357">2.0 Inside a part </a> |
|
<li><a href="#mozTocId270357">2.0 Inside a part |
|
|
</a> |
|
| 48 |
<ul> |
<ul> |
| 49 |
<li><a href="#mozTocId713423">2.1 Part Lifecycle |
<li><a href="#mozTocId713423">2.1 Part Lifecycle </a></li> |
|
</a></li> |
|
| 50 |
<li><a href="#mozTocId789670">2.2 Part Construction</a></li> |
<li><a href="#mozTocId789670">2.2 Part Construction</a></li> |
| 51 |
</ul> |
</ul> |
| 52 |
</li> |
</li> |
| 53 |
<li><a href="#mozTocId409413">3.0 Workbench Layout |
<li><a href="#mozTocId409413">3.0 Workbench Layout </a> |
|
</a> |
|
| 54 |
<ul> |
<ul> |
| 55 |
<li><a href="#mozTocId95893">3.1 An example layout</a></li> |
<li><a href="#mozTocId95893">3.1 An example layout</a></li> |
| 56 |
<li><a href="#mozTocId114962">3.2 Zoom / Unzoom |
<li><a href="#mozTocId114962">3.2 Zoom / Unzoom |
| 57 |
protocol |
protocol </a></li> |
| 58 |
</a></li> |
<li><a href="#mozTocId977378">3.3 Layout protocol </a></li> |
|
<li><a href="#mozTocId977378">3.3 Layout protocol |
|
|
</a></li> |
|
| 59 |
<li><a href="#mozTocId162591">3.4 PartStack: |
<li><a href="#mozTocId162591">3.4 PartStack: |
| 60 |
Communicating with the Presentation API |
Communicating with the Presentation API </a></li> |
|
</a></li> |
|
| 61 |
<li><a href="#mozTocId479574">3.5 |
<li><a href="#mozTocId479574">3.5 |
| 62 |
PartSashContainer: The main workbench layout </a></li> |
PartSashContainer: The main workbench layout </a></li> |
| 63 |
<li><a href="#mozTocId887241">3.6 Drag / Drop</a></li> |
<li><a href="#mozTocId887241">3.6 Drag / Drop</a></li> |
| 65 |
</li> |
</li> |
| 66 |
<li><a href="#mozTocId443855">4.0 Action Bars</a> |
<li><a href="#mozTocId443855">4.0 Action Bars</a> |
| 67 |
<ul> |
<ul> |
| 68 |
<li><a href="#mozTocId652269">4.1 Editor Action Bars |
<li><a href="#mozTocId652269">4.1 Editor Action Bars </a></li> |
| 69 |
</a></li> |
<li><a href="#mozTocId340925">4.2 Action Sets </a></li> |
|
<li><a href="#mozTocId340925">4.2 Action Sets |
|
|
</a></li> |
|
| 70 |
<li><a href="#mozTocId277128">4.3 View Actions</a></li> |
<li><a href="#mozTocId277128">4.3 View Actions</a></li> |
| 71 |
</ul> |
</ul> |
| 72 |
</li> |
</li> |
| 78 |
<li><a href="#mozTocId308622">5.2 No method may |
<li><a href="#mozTocId308622">5.2 No method may |
| 79 |
open a modal dialog unless its JavaDoc says so</a></li> |
open a modal dialog unless its JavaDoc says so</a></li> |
| 80 |
<li><a href="#mozTocId753192">5.3 Lazy creation |
<li><a href="#mozTocId753192">5.3 Lazy creation |
| 81 |
should happen as late as possible |
should happen as late as possible </a></li> |
|
</a></li> |
|
| 82 |
<li><a href="#mozTocId921869">5.4 getters should |
<li><a href="#mozTocId921869">5.4 getters should |
| 83 |
not modify the thing they are supposed to measure |
not modify the thing they are supposed to measure </a></li> |
|
</a></li> |
|
| 84 |
</ul> |
</ul> |
| 85 |
</li> |
</li> |
| 86 |
</ul> |
</ul> |
| 107 |
src="workbench_high_level.PNG" style="width: 600px; height: 340px;"><br> |
src="workbench_high_level.PNG" style="width: 600px; height: 340px;"><br> |
| 108 |
</div> |
</div> |
| 109 |
<br> |
<br> |
| 110 |
Figure 1 shows how views and editors are owned by the workbench.<br> |
Figure 1 shows how views and editors are owned by the workbench. |
| 111 |
|
<br> |
| 112 |
<br> |
<br> |
| 113 |
The Workbench contains one or more WorkbenchWindows, each of which |
The Workbench contains one or more WorkbenchWindows, each of which |
| 114 |
contain zero or more WorkbenchPages. The WorkbenchWindow supplies the |
contain zero or more WorkbenchPages. The WorkbenchWindow supplies the |
| 115 |
trim widgets, and the WorkbenchPage supplies the window |
trim widgets, and the WorkbenchPage supplies the window contents. In |
| 116 |
contents. In theory, a WorkbenchWindow can contain any number of pages, |
theory, a WorkbenchWindow can contain any number of pages, but in |
| 117 |
but in practice there is never more than 1 page in a window.<br> |
practice there is never more than 1 page in a window. |
| 118 |
|
<br> |
| 119 |
<br> |
<br> |
| 120 |
Views and editors are owned by the page, through a ViewFactory and |
Views and editors are owned by the page, through a ViewFactory and |
| 121 |
EditorManager respectively. EditorManager stores the list of editors |
EditorManager respectively. EditorManager stores the list of editors |
| 122 |
and their shared |
and |
| 123 |
resources, and ViewFactory stores a reference counted list of views. |
their shared resources, and ViewFactory stores a reference counted list |
| 124 |
The workbench works in terms of EditorReferences and ViewReferences, |
of views. The workbench works in terms of EditorReferences and |
| 125 |
and in this article the terms "editor" or "view" will refer to these |
ViewReferences, and in this article the terms "editor" or "view" will |
| 126 |
classes specifically. In situations where the distinction between |
refer to these classes specifically. In situations where the |
| 127 |
editors and views is not important, we will simply use the term "part". |
distinction |
| 128 |
The implementation of the part (typically an IEditorPart or IViewPart) |
between editors and views is not important, we will simply use the term |
| 129 |
is created lazily when it is first needed. As shown in Figure 2, a |
"part". The implementation of the part (typically an IEditorPart or |
| 130 |
part reference exists for every tab but the implementation is only |
IViewPart) is created lazily when it is first needed. As shown in |
| 131 |
created the first time it becomes visible.<br> |
Figure |
| 132 |
|
2, a part reference exists for every tab but the implementation is only |
| 133 |
|
created the first time it becomes visible. |
| 134 |
|
<br> |
| 135 |
<br> |
<br> |
| 136 |
The page owns a set of perspectives. Perspectives contain a layout and |
The page owns a set of perspectives. Perspectives contain a layout and |
| 137 |
information about what action sets to enable. Although perspectives |
information about what action sets to enable. Although perspectives |
| 138 |
appear to contain views and the editor area, they only own a layout. |
appear to contain views and the editor area, they only own a layout. |
| 139 |
The page itself maintains a reference count for how many perspectives |
The |
| 140 |
are using each view, and has complete ownership of the parts and editor |
page itself maintains a reference count for how many perspectives are |
| 141 |
area.<br> |
using each view, and has complete ownership of the parts and editor |
| 142 |
|
area. |
| 143 |
|
<br> |
| 144 |
<br> |
<br> |
| 145 |
Not shown in figure 1 are the classes PerspectiveHelper and |
Not shown in figure 1 are the classes PerspectiveHelper and |
| 146 |
EditorAreaHelper. These classes exist largely for historic purposes, |
EditorAreaHelper. These classes exist largely for historic purposes, |
| 147 |
and in this article we will treat the former as though it were part of |
and |
| 148 |
the Perspective class and the latter as part of the WorkbenchPage class.<br> |
in this article we will treat the former as though it were part of the |
| 149 |
|
Perspective class and the latter as part of the WorkbenchPage class. |
| 150 |
|
<br> |
| 151 |
<br> |
<br> |
| 152 |
<br> |
<br> |
| 153 |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
| 174 |
interfaces to the same object. The I*Reference interfaces are |
interfaces to the same object. The I*Reference interfaces are |
| 175 |
implemented directly by WorkbenchPartReference and its subclasses. |
implemented directly by WorkbenchPartReference and its subclasses. |
| 176 |
IPresentablePart is a simple adapter that redirects its methods |
IPresentablePart is a simple adapter that redirects its methods |
| 177 |
directly to the part. PartPane implements the LayoutPart protocol which |
directly |
| 178 |
is needed to insert the part into the workbench layout. PartPane also |
to the part. PartPane implements the LayoutPart protocol which is |
| 179 |
manages the SWT resources (such as a top-level control) that are needed |
needed |
| 180 |
to include the control in the workbench layout.<br> |
to insert the part into the workbench layout. PartPane also manages the |
| 181 |
|
SWT resources (such as a top-level control) that are needed to include |
| 182 |
|
the control in the workbench layout. |
| 183 |
|
<br> |
| 184 |
<br> |
<br> |
| 185 |
The part implementation (the IEditorPart or IViewPart) is owned by the |
The part implementation (the IEditorPart or IViewPart) is owned by the |
| 186 |
reference. When the |
reference. When the implementation is created, it is given a PartSite. |
| 187 |
implementation is created, it is given a PartSite. The PartSite (seen |
The PartSite (seen by client code as an IWorkbenchPartSite, |
| 188 |
by client code as an IWorkbenchPartSite, IEditorSite, or IViewSite) |
IEditorSite, |
| 189 |
allows the client code to communicate with the reference and manages |
or IViewSite) allows the client code to communicate with the reference |
| 190 |
services created for the implementation.<br> |
and manages services created for the implementation. |
| 191 |
<br> |
<br> |
| 192 |
WorkbenchPartReferences allocates SWT resources lazily as needed. |
<br> |
| 193 |
Once created, the part reference must be explicitly disposed. Disposing |
WorkbenchPartReferences allocates SWT resources lazily as needed. Once |
| 194 |
the reference cleans up all of its resources (including the part |
created, the part reference must be explicitly disposed. Disposing the |
| 195 |
|
reference cleans up all of its resources (including the part |
| 196 |
implementation itself) and guarantees that the reference will never |
implementation itself) and guarantees that the reference will never |
| 197 |
allocate additional resources. The workbench page disposes the part |
allocate additional resources. The workbench page disposes the part |
| 198 |
reference once it is certain that it will never need to use that part |
reference once it is certain that it will never need to use that part |
| 199 |
again. Unlike SWT controls, it is valid to continue using the reference |
again. Unlike SWT controls, it is valid to continue using the reference |
| 200 |
after it has been disposed. A disposed part reference is unlikely to do |
after it has been disposed. A disposed part reference is unlikely to do |
| 201 |
anything interesting besides returning its name and cannot be used with |
anything interesting besides returning its name and cannot be used with |
| 202 |
any |
any methods in the workbench page. Since it is hard (or impossible) for |
|
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 |
clients to track the lifecycle of the reference, they are permitted to |
| 204 |
continue using its public interface after disposal.<br> |
continue using its public interface after disposal. |
| 205 |
|
<br> |
| 206 |
<br> |
<br> |
| 207 |
<h3><a class="mozTocH3" name="mozTocId713423"></a>2.1 Part Lifecycle<br> |
<h3><a class="mozTocH3" name="mozTocId713423"></a>2.1 Part Lifecycle<br> |
| 208 |
</h3> |
</h3> |
| 214 |
style="width: 445px; height: 590px;"><br> |
style="width: 445px; height: 590px;"><br> |
| 215 |
</div> |
</div> |
| 216 |
Figure 4 shows the part lifecycle as a state machine. The part |
Figure 4 shows the part lifecycle as a state machine. The part |
| 217 |
reference stores its current state in the integer state field.<br> |
reference |
| 218 |
|
stores its current state in the integer state field. |
| 219 |
|
<br> |
| 220 |
|
<br> |
| 221 |
|
Notes: |
| 222 |
<br> |
<br> |
|
Notes:<br> |
|
| 223 |
<ul> |
<ul> |
| 224 |
<li>The part is in a distinct state while it is in the process of |
<li>The part is in a distinct state while it is in the process of |
| 225 |
creating the implementation. It cannot be recursively re-created or |
creating the implementation. It cannot be recursively re-created or |
| 243 |
style="width: 892px; height: 700px;"><br> |
style="width: 892px; height: 700px;"><br> |
| 244 |
</div> |
</div> |
| 245 |
<br> |
<br> |
| 246 |
Figure 5 shows the process for creating a part. The horizontal |
Figure 5 shows the process for creating a part. The horizontal line |
| 247 |
line separates the two phases of creating a part. First the part is |
separates the two phases of creating a part. First the part is added to |
| 248 |
added to the layout, and then a real implementation is attached. These |
the layout, and then a real implementation is attached. These are two |
| 249 |
are two distinct operations, and the part can exist as a tab in the |
distinct operations, and the part can exist as a tab in the page with |
| 250 |
page with no implementation for some time before it becomes visible. |
no |
| 251 |
This diagram focuses on the interactions with the part reference, and |
implementation for some time before it becomes visible. This diagram |
| 252 |
skips the details of adding the part to the presentation and creating |
focuses on the interactions with the part reference, and skips the |
| 253 |
the part site.<br> |
details of adding the part to the presentation and creating the part |
| 254 |
<br> |
site. |
| 255 |
Suggestion: there are situations where it would be useful to only |
<br> |
| 256 |
add the part to the layout if it can be created successfully (this |
<br> |
| 257 |
would be necessary to pass a PartInitException thrown in the |
Suggestion: there are situations where it would be useful to only add |
| 258 |
implementation's init method up through IWorkbenchPage.openEditor). In |
the part to the layout if it can be created successfully (this would be |
| 259 |
these situations, it would be possible to merge both operations into |
necessary to pass a PartInitException thrown in the implementation's |
| 260 |
one atomic operation by creating the part before adding it to the |
init method up through IWorkbenchPage.openEditor). In these situations, |
| 261 |
layout. It is unknown if this would create event ordering bugs in |
it would be possible to merge both operations into one atomic operation |
| 262 |
client code.<br> |
by creating the part before adding it to the layout. It is unknown if |
| 263 |
|
this would create event ordering bugs in client code. |
| 264 |
|
<br> |
| 265 |
<br> |
<br> |
| 266 |
<span style="font-weight: bold;"></span> |
<span style="font-weight: bold;"></span> |
| 267 |
<h2><a class="mozTocH2" name="mozTocId409413"></a>3.0 Workbench Layout<br> |
<h2><a class="mozTocH2" name="mozTocId409413"></a>3.0 Workbench Layout<br> |
| 275 |
<br> |
<br> |
| 276 |
The workbench layout provides supports arranging parts using drag & |
The workbench layout provides supports arranging parts using drag & |
| 277 |
drop, resizing and detaching parts, fast views, etc. This section gives |
drop, resizing and detaching parts, fast views, etc. This section gives |
| 278 |
a quick overview of the layout mechanism.<br> |
a quick overview of the layout mechanism. |
| 279 |
|
<br> |
| 280 |
<br> |
<br> |
| 281 |
Anything in the workbench layout is a LayoutPart. A LayoutPart manages |
Anything in the workbench layout is a LayoutPart. A LayoutPart manages |
| 282 |
a set of widgets in a rectangular region of the screen, can contain or |
a |
| 283 |
|
set of widgets in a rectangular region of the screen, can contain or |
| 284 |
arrange other layout parts, returns size constraints, responds to drag |
arrange other layout parts, returns size constraints, responds to drag |
| 285 |
events, etc. To this extent, a LayoutPart is very similar to a custom |
events, etc. To this extent, a LayoutPart is very similar to a custom |
| 286 |
SWT Control. However, LayoutPart differs from Control in several |
SWT Control. However, LayoutPart differs from Control in several |
| 287 |
important ways.<br> |
important ways. |
| 288 |
|
<br> |
| 289 |
<ul> |
<ul> |
| 290 |
<li>The LayoutPart hierarchy is not the same as the widget hierarchy. |
<li>The LayoutPart hierarchy is not the same as the widget hierarchy. |
| 291 |
Even though one LayoutPart may contain another, their widgets may be |
Even though one LayoutPart may contain another, their widgets may be |
| 301 |
specify constraints about their own size.<br> |
specify constraints about their own size.<br> |
| 302 |
</li> |
</li> |
| 303 |
</ul> |
</ul> |
| 304 |
Figure 6 shows the LayoutPart hierarchy. Notice the symmetry |
Figure 6 shows the LayoutPart hierarchy. Notice the symmetry between |
| 305 |
between the View* classes and the Editor* classes. These classes exist |
the |
| 306 |
largely for historical reasons, and it should be possible to move all |
View* classes and the Editor* classes. These classes exist largely for |
| 307 |
of the functionality into the Part* base classes or other objects in |
historical reasons, and it should be possible to move all of the |
| 308 |
the system. Since all of the interesting behavior comes from the Part* |
functionality into the Part* base classes or other objects in the |
| 309 |
|
system. Since all of the interesting behavior comes from the Part* |
| 310 |
classes, the remainder of this section will focus on them without |
classes, the remainder of this section will focus on them without |
| 311 |
describing the minor differences between views and editors.<br> |
describing the minor differences between views and editors. |
| 312 |
|
<br> |
| 313 |
<br> |
<br> |
| 314 |
PartSashContainer arranges a set of child parts separated by a bunch of |
PartSashContainer provides the splitting behavior in the workbench |
| 315 |
sashes. This is the object that implements the most visible aspects of |
window. It arranges rectangular regions separated by |
|
the workbench layout. It arranges rectangular regions separated by |
|
| 316 |
sashes, and allows new regions to be created by splitting old ones. It |
sashes, and allows new regions to be created by splitting old ones. It |
| 317 |
also supports the size constraints that make minimized views possible, |
also supports the size constraints that make minimized views possible, |
| 318 |
and determines what it means for one of these regions to be maximized. |
and determines what it means for one of these regions to be maximized. |
| 320 |
it is also possible for it to contain another PartSashContainer. The |
it is also possible for it to contain another PartSashContainer. The |
| 321 |
latter case occurs since the editor area and the perspective both use a |
latter case occurs since the editor area and the perspective both use a |
| 322 |
PartSashContainer for their layout and one is embedded inside the |
PartSashContainer for their layout and one is embedded inside the |
| 323 |
other. PartSashContainer owns its stacks but does not own an embedded |
other. |
| 324 |
|
PartSashContainer owns its stacks but does not own an embedded |
| 325 |
PartSashContainer. In a workbench window, there is one |
PartSashContainer. In a workbench window, there is one |
| 326 |
PartSashContainer for each perspective and one for the editor area |
PartSashContainer |
| 327 |
itself.<br> |
for each perspective and one for the editor area itself. |
| 328 |
|
<br> |
| 329 |
<br> |
<br> |
| 330 |
PartStack arranges a stack of PartPanes. PartStack allows the |
PartStack arranges a stack of PartPanes. PartStack allows the |
| 331 |
presentation API to participate in the workbench layout. The code for |
presentation API to participate in the workbench layout. The code for |
| 332 |
creating the tabs and arranging parts is supplied by the active |
creating the tabs and arranging parts is supplied by the active |
| 333 |
presentation.<br> |
presentation. |
| 334 |
|
<br> |
| 335 |
<br> |
<br> |
| 336 |
PartPane allows views and editors to participate in the workbench |
PartPane allows views and editors to participate in the workbench |
| 337 |
layout. Although PartPanes are arranged by PartStacks they belong to |
layout. Although PartPanes are arranged by PartStacks they belong to |
| 338 |
part reference, not the stack. The same PartPane can exist in more than |
part reference, not the stack. The same PartPane can exist in more than |
| 339 |
one PartStack at a time if that part appears in more that one |
one PartStack at a time if that part appears in more that one |
| 340 |
perspective.<span style="font-weight: bold;"><br> |
perspective. |
| 341 |
|
<span style="font-weight: bold;"><br> |
| 342 |
<br> |
<br> |
| 343 |
</span> |
</span> |
| 344 |
<h3><a class="mozTocH3" name="mozTocId95893"></a>3.1 An example layout</h3> |
<h3><a class="mozTocH3" name="mozTocId95893"></a>3.1 An example layout</h3> |
| 345 |
LayoutParts are best explained through example. Imagine a |
LayoutParts are best explained through example. Imagine a |
| 346 |
WorkbenchWindow that contains custom Java and Java Browsing |
WorkbenchWindow that contains custom Java and Java Browsing |
| 347 |
perspectives that look like Figure 7 and Figure 8 |
perspectives |
| 348 |
respectively.<br> |
that look like Figure 7 and Figure 8 respectively. |
| 349 |
|
<br> |
| 350 |
<br> |
<br> |
| 351 |
<br> |
<br> |
| 352 |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
| 375 |
<br> |
<br> |
| 376 |
All LayoutParts have a container pointer that points to the object that |
All LayoutParts have a container pointer that points to the object that |
| 377 |
is currently managing their position. Since the same LayoutPart |
is currently managing their position. Since the same LayoutPart |
| 378 |
instance may exist in more than one perspective at once, this pointer |
instance |
| 379 |
points to the part's container in the currently-active perspective. In |
may exist in more than one perspective at once, this pointer points to |
| 380 |
the case of the projects view, above, the part is not in the current |
the part's container in the currently-active perspective. In the case |
| 381 |
perspective so its container pointer is null. When another |
of |
| 382 |
perspective becomes active, all the container pointers move to the new |
the projects view, above, the part is not in the current perspective so |
| 383 |
perspective. For historical reasons, this is accomplished by setting |
its container pointer is null. When another perspective becomes active, |
| 384 |
and |
all the container pointers move to the new perspective. For historical |
| 385 |
clearing the contianer pointer when the container becomes visible or |
reasons, this is accomplished by setting and clearing the contianer |
| 386 |
invisible. This works since only one perspective is visible at a time, |
pointer when the container becomes visible or invisible. This works |
| 387 |
but it also means that perspectives cannot be manipulated when they are |
since only one perspective is visible at a time, but it also means that |
| 388 |
invisible.<br> |
perspectives cannot be manipulated when they are invisible. |
| 389 |
|
<br> |
| 390 |
<br> |
<br> |
| 391 |
The diagram shows the internal objects that make up the only editor. |
The diagram shows the internal objects that make up the only editor. |
| 392 |
Although this detail has been omitted for the views, they would look |
Although this detail has been omitted for the views, they would look |
| 393 |
similar. Each view's PartPane is owned by a part reference which may |
similar. Each view's PartPane is owned by a part reference which may |
| 394 |
have an associated part implementation.<br> |
have an associated part implementation. |
| 395 |
|
<br> |
| 396 |
<br> |
<br> |
| 397 |
<h3><a class="mozTocH3" name="mozTocId114962"></a>3.2 Zoom / Unzoom |
<h3><a class="mozTocH3" name="mozTocId114962"></a>3.2 Zoom / Unzoom |
| 398 |
protocol<br> |
protocol<br> |
| 399 |
</h3> |
</h3> |
| 400 |
The notion of "zoom" is defined locally between a part and its |
The notion of "zoom" is defined locally between a part and its |
| 401 |
immediate container. Zoom changes are triggered bottom-up. A part asks |
immediate |
| 402 |
its parent to "zoom me", and the parent either does something with the |
container. Zoom changes are triggered bottom-up. A part asks its parent |
| 403 |
request or forwards the request up to its parent. Each container |
to "zoom me", and the parent either does something with the request or |
| 404 |
determines what it means for a child to be zoomed. Once a part's zoom |
forwards the request up to its parent. Each container determines what |
| 405 |
state changes, its parent notifies it by calling setZoomed. The part |
it |
| 406 |
may in turn zoom or unzoom one or more of its children.<br> |
means for a child to be zoomed. Once a part's zoom state changes, its |
| 407 |
|
parent notifies it by calling setZoomed. The part may in turn zoom or |
| 408 |
|
unzoom one or more of its children. |
| 409 |
|
<br> |
| 410 |
<br> |
<br> |
| 411 |
Anything that can contain LayoutParts must implement the following |
Anything that can contain LayoutParts must implement the following |
| 412 |
methods, to support zooming:<br> |
methods, to support zooming: |
| 413 |
|
<br> |
| 414 |
<span style="font-family: monospace;"><br> |
<span style="font-family: monospace;"><br> |
| 415 |
</span><code> /**<br> |
</span> |
| 416 |
|
<code> /**<br> |
| 417 |
* Called by child parts to request a zoom in, |
* Called by child parts to request a zoom in, |
| 418 |
given an immediate child <br> |
given an immediate child <br> |
| 419 |
* <br> |
* <br> |
| 440 |
<br> |
<br> |
| 441 |
/**<br> |
/**<br> |
| 442 |
* Returns true iff we are zoomed into the |
* Returns true iff we are zoomed into the |
| 443 |
given part, given an immediate child of this container.<br> |
given |
| 444 |
|
part, given an immediate child of this container.<br> |
| 445 |
* <br> |
* <br> |
| 446 |
* @param toTest part to test<br> |
* @param toTest part to test<br> |
| 447 |
* @return true iff this contianer is currently |
* @return true iff this contianer is currently |
| 449 |
*/<br> |
*/<br> |
| 450 |
public boolean childIsZoomed(LayoutPart toTest);<br> |
public boolean childIsZoomed(LayoutPart toTest);<br> |
| 451 |
<br> |
<br> |
| 452 |
</code><br> |
</code> |
| 453 |
Consider again Figure 7. If we were to double-click on the java |
<br> |
| 454 |
editor to zoom it, the LayoutParts would send messages to one another |
Consider again Figure 7. If we were to double-click on the java editor |
| 455 |
in the following sequence. (In this diagram, each cell represents a |
to zoom it, the LayoutParts would send messages to one another in the |
| 456 |
method call. Each column is an object. The reciever's column shows the |
following sequence. (In this diagram, each cell represents a method |
| 457 |
method name and the caller contains an arrow. Rows are in ascending |
call. Each column is an object. The reciever's column shows the method |
| 458 |
order of time.)<br> |
name and the caller contains an arrow. Rows are in ascending order of |
| 459 |
|
time.) |
| 460 |
|
<br> |
| 461 |
<br> |
<br> |
| 462 |
<table style="width: 100%; text-align: left;" border="1" cellpadding="2" |
<table style="width: 100%; text-align: left;" border="1" cellpadding="2" |
| 463 |
cellspacing="2"> |
cellspacing="2"> |
| 651 |
serves a similar function as the computeSize method on an SWT control, |
serves a similar function as the computeSize method on an SWT control, |
| 652 |
in that the parent layout uses it to consult with the part when |
in that the parent layout uses it to consult with the part when |
| 653 |
computing the part's size. ISizeProvider can provide a variety of |
computing the part's size. ISizeProvider can provide a variety of |
| 654 |
constraints:<br> |
constraints: |
| 655 |
|
<br> |
| 656 |
<br> |
<br> |
| 657 |
<table style="width: 100%; text-align: left;" border="1" cellpadding="2" |
<table style="width: 100%; text-align: left;" border="1" cellpadding="2" |
| 658 |
cellspacing="2"> |
cellspacing="2"> |
| 702 |
<br> |
<br> |
| 703 |
Although there are three kinds of constraints, they are all returned |
Although there are three kinds of constraints, they are all returned |
| 704 |
using a single method. See the JavaDoc on ISizeProvider for more |
using a single method. See the JavaDoc on ISizeProvider for more |
| 705 |
information.<br> |
information. |
| 706 |
|
<br> |
| 707 |
<br> |
<br> |
| 708 |
Whenever a size constraint changes, the part notifies its contianer by |
Whenever a size constraint changes, the part notifies its contianer by |
| 709 |
calling resizeChild(part). This tells the container to respond to the |
calling resizeChild(part). This tells the container to respond to the |
| 710 |
new constraints, and to resize the child if necessary (suggestion: |
new constraints, and to resize the child if necessary (suggestion: if |
| 711 |
if this is ever exposed as API, it would be better to separate the |
this is ever exposed as API, it would be better to separate the |
| 712 |
concerns of notifying the parent of changes and triggering a layout. In |
concerns |
| 713 |
general, it may be possible for more than one part to change without |
of notifying the parent of changes and triggering a layout. In general, |
| 714 |
requiring a layout between each change).<br> |
it may be possible for more than one part to change without requiring a |
| 715 |
|
layout between each change). |
| 716 |
|
<br> |
| 717 |
<br> |
<br> |
| 718 |
<h3><a class="mozTocH3" name="mozTocId162591"></a>3.4 PartStack: |
<h3><a class="mozTocH3" name="mozTocId162591"></a>3.4 PartStack: |
| 719 |
Communicating with the Presentation API<br> |
Communicating with the Presentation API<br> |
| 720 |
</h3> |
</h3> |
| 721 |
PartStack allows presentation to participate in the workbench layout. |
PartStack allows presentation to participate in the workbench layout. |
| 722 |
As shown in Figure 10, it wraps a single instance of |
As |
| 723 |
StackPresentation, and allows it the presentation to manipulate parts |
shown in Figure 10, it wraps a single instance of StackPresentation, |
| 724 |
by converting each visible part into an IPresentablePart. The part |
and |
| 725 |
stack outlives the StackPresentation. Whenever the part stack needs |
allows it the presentation to manipulate parts by converting each |
| 726 |
widgets, it creates the StackPresentation. If the widgets are no longer |
visible part into an IPresentablePart. The part stack outlives the |
| 727 |
needed, it disposes the StackPresentation and remembers its persisted |
StackPresentation. Whenever the part stack needs widgets, it creates |
| 728 |
form. Whenever the PartStack persists its StackPresenation, it |
the |
| 729 |
remembers the presentation ID so that it will not try to restore one |
StackPresentation. If the widgets are no longer needed, it disposes the |
| 730 |
StackPresentation from state saved by an incompatible presentation.<br> |
StackPresentation and remembers its persisted form. Whenever the |
| 731 |
|
PartStack persists its StackPresenation, it remembers the presentation |
| 732 |
|
ID so that it will not try to restore one StackPresentation from state |
| 733 |
|
saved by an incompatible presentation. |
| 734 |
|
<br> |
| 735 |
<br> |
<br> |
| 736 |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
| 737 |
10: Anatomy of PartStack</span><br> |
10: Anatomy of PartStack</span><br> |
| 738 |
<img alt="" src="PartStack.PNG" style="width: 430px; height: 225px;"><br> |
<img alt="" src="PartStack.PNG" style="width: 430px; height: 225px;"><br> |
| 739 |
<div style="text-align: left;"><br> |
<div style="text-align: left;"><br> |
|
Suggestion: it would be useful to update this document with a state |
|
|
diagram for PartStack, and message sequence charts for initializaiton |
|
|
and part activation.<br> |
|
| 740 |
<br> |
<br> |
| 741 |
</div> |
</div> |
| 742 |
</div> |
</div> |
| 750 |
</div> |
</div> |
| 751 |
<br> |
<br> |
| 752 |
PartSashContainer implements the main layout for a perspective and the |
PartSashContainer implements the main layout for a perspective and the |
| 753 |
editor area. As shown in Figure 11, PartSashContainer contains a |
editor area. As shown in Figure 11, PartSashContainer contains a list |
| 754 |
list of children, a (possibly null) zoomed part, and a LayoutTree that |
of |
| 755 |
manages the actual layout. <br> |
children, a (possibly null) zoomed part, and a LayoutTree that manages |
| 756 |
|
the actual layout. |
| 757 |
|
<br> |
| 758 |
<br> |
<br> |
| 759 |
LayoutTree is a binary tree (technically, a KD tree). Each internal |
LayoutTree is a binary tree (technically, a KD tree). Each internal |
| 760 |
node is an instance of LayoutTreeNode. It contains a draggable sash |
node |
| 761 |
|
is an instance of LayoutTreeNode. It contains a draggable sash |
| 762 |
(LayoutPartSash) that divides its area among its left and right |
(LayoutPartSash) that divides its area among its left and right |
| 763 |
children. LayoutTreeNodes can be horizontal or vertical based on the |
children. LayoutTreeNodes can be horizontal or vertical based on the |
| 764 |
orientation of the sash. For horizontal nodes, the "left" child is on |
orientation of the sash. For horizontal nodes, the "left" child is on |
| 765 |
top and the "right" child is on the bottom. Leaf nodes are instances of |
top and the "right" child is on the bottom. Leaf nodes are instances of |
| 766 |
LayoutTree (the base class), and they point to a LayoutPart that |
LayoutTree (the base class), and they point to a LayoutPart that |
| 767 |
occupies that region of the screen. Normally, this is a PartStack, but |
occupies that region of the screen. Normally, this is a PartStack, but |
| 768 |
in general it can be any LayoutPart. <br> |
in general it can be any LayoutPart. |
| 769 |
|
<br> |
| 770 |
<br> |
<br> |
| 771 |
Each LayoutTree occupies a recangular region of the screen that |
Each LayoutTree occupies a recangular region of the screen that |
| 772 |
encompasses its children. Internal nodes keep track of an integer size |
encompasses its children. Internal nodes keep track of an integer size |
| 773 |
for each child (implementation note: the sizes are stored in the |
for each child (implementation note: the sizes are stored in the |
| 774 |
associated LayoutPartSash, not the LayoutTreeNode itself). Normally, |
associated LayoutPartSash, not the LayoutTreeNode itself). Normally, |
| 775 |
the left and right sizes are used as a ratio for dividing up the |
the |
| 776 |
available space. However, when one child contains the editor area, the |
left and right sizes are used as a ratio for dividing up the available |
| 777 |
other becomes "non-compressible". If one side in non-compressible, the |
space. However, when one child contains the editor area, the other |
| 778 |
size value is interpreted as a fixed pixel size rather than a ratio. |
becomes "non-compressible". If one side in non-compressible, the size |
| 779 |
When the sash is moved, the size values are set to the current pixel |
value is interpreted as a fixed pixel size rather than a ratio. When |
| 780 |
sizes of the left and right children.<br> |
the |
| 781 |
<br> |
sash is moved, the size values are set to the current pixel sizes of |
| 782 |
Figure 12 shows an example LayoutTree. If this tree were rendered |
the |
| 783 |
in a workbench window, it would resemble Figure 3.5.3. The tall |
left and right children. |
| 784 |
vertical sash separating the package explorer from the editor area is |
<br> |
| 785 |
the root node. The left child is the leaf node holding the package |
<br> |
| 786 |
explorer's stack. The right node is the horizontal sash separating the |
Figure 12 shows an example LayoutTree. If this tree were rendered in a |
| 787 |
problems view from the editor area. The editor area itself is a |
workbench window, it would resemble Figure 13. The tall vertical sash |
| 788 |
PartSashContainer, which has its own LayoutTree. Note that the rounded |
separating the package explorer from the editor area is the root node. |
| 789 |
rectangles in Figure 3.5.2 are LayoutParts. The upper portion of the |
The left child is the leaf node holding the package explorer's stack. |
| 790 |
rectangle is the part type and the lower portion is some text to help |
The right node is the horizontal sash separating the problems view from |
| 791 |
locate the part in the screenshot. In this example, every internal node |
the editor area. The editor area itself is a PartSashContainer, which |
| 792 |
has the editor area on one side of it, so all sizes are interpreted as |
has its own LayoutTree. Note that the rounded rectangles in Figure 12 |
| 793 |
pixel sizes and not ratios.<br> |
are LayoutParts. The upper portion of the rectangle is the part type |
| 794 |
|
and |
| 795 |
|
the lower portion is some text to help locate the part in the |
| 796 |
|
screenshot. In this example, every internal node has the editor area on |
| 797 |
|
one side of it, so all sizes are interpreted as pixel sizes and not |
| 798 |
|
ratios. |
| 799 |
|
<br> |
| 800 |
<div style="text-align: center;"><span style="font-weight: bold;"></span><br> |
<div style="text-align: center;"><span style="font-weight: bold;"></span><br> |
| 801 |
<span style="font-weight: bold;">Figure 12: Example LayoutTree</span><br |
<span style="font-weight: bold;">Figure 12: Example LayoutTree</span><br |
| 802 |
style="font-weight: bold;"> |
style="font-weight: bold;"> |
| 810 |
<br> |
<br> |
| 811 |
Like LayoutParts, LayoutTrees also implement ISizeProvider and support |
Like LayoutParts, LayoutTrees also implement ISizeProvider and support |
| 812 |
size constraints. For external nodes, the size constraints come |
size constraints. For external nodes, the size constraints come |
| 813 |
directly from the LayoutPart. For internal nodes, the size constraints |
directly |
| 814 |
are computed from the child nodes as follows:<br> |
from the LayoutPart. For internal nodes, the size constraints are |
| 815 |
|
computed from the child nodes as follows: |
| 816 |
|
<br> |
| 817 |
<ol> |
<ol> |
| 818 |
<li>When computing a constraint perpendicular to the sash, the result |
<li>When computing a constraint perpendicular to the sash, the result |
| 819 |
is the sum of the constraints of the children plus the width of the |
is the sum of the constraints of the children plus the width of the |
| 823 |
</li> |
</li> |
| 824 |
</ol> |
</ol> |
| 825 |
An example can help make this a little less abstract. Imagine we're |
An example can help make this a little less abstract. Imagine we're |
| 826 |
computing the minimum width for the root node in Figure 12, which |
computing the minimum width for the root node in Figure 12, which is a |
| 827 |
is a tall vertical sash. Width measurements are perpendicular to the |
tall vertical sash. Width measurements are perpendicular to the sash, |
| 828 |
sash, so we end up with case 1. The minimum width is the minimum width |
so |
| 829 |
of the left stack plus the sash width plus the minimum width of the |
we end up with case 1. The minimum width is the minimum width of the |
| 830 |
right child. This makes sense because if we made the root node any |
left stack plus the sash width plus the minimum width of the right |
| 831 |
smaller, one of the three would need to be truncated or made smaller |
child. This makes sense because if we made the root node any smaller, |
| 832 |
than their minimum size.<br> |
one of the three would need to be truncated or made smaller than their |
| 833 |
|
minimum size. |
| 834 |
|
<br> |
| 835 |
<br> |
<br> |
| 836 |
The "right child" mentioned above is the horizontal sash separating the |
The "right child" mentioned above is the horizontal sash separating the |
| 837 |
problems view from the editor area. When computing its minimum width, |
problems view from the editor area. When computing its minimum width, |
| 838 |
we hit case 2: the minimum width of a horizantal sash is the maximum of |
we |
| 839 |
the minimum widths of each child. Intuitively, this means that the |
hit case 2: the minimum width of a horizantal sash is the maximum of |
| 840 |
child with the larger minimum size will be the first to reach its |
the |
| 841 |
minimum when the layout gets small.<br> |
minimum widths of each child. Intuitively, this means that the child |
| 842 |
|
with the larger minimum size will be the first to reach its minimum |
| 843 |
|
when |
| 844 |
|
the layout gets small. |
| 845 |
|
<br> |
| 846 |
<br> |
<br> |
| 847 |
<h3><a class="mozTocH3" name="mozTocId887241"></a>3.6 Drag / Drop</h3> |
<h3><a class="mozTocH3" name="mozTocId887241"></a>3.6 Drag / Drop</h3> |
| 848 |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
| 946 |
action bars. Each action bar implements IActionBars. It is possible to |
action bars. Each action bar implements IActionBars. It is possible to |
| 947 |
create one action bar as a child of another. In this situation, the |
create one action bar as a child of another. In this situation, the |
| 948 |
parent and child share the same widgets, but the child may be disabled |
parent and child share the same widgets, but the child may be disabled |
| 949 |
independently of the parent. Figure 15 shows how the workbench |
independently of the parent. Figure 15 shows how the workbench action |
| 950 |
action bars are |
bars are constructed. The rectangles indicate instances of IActionBars, |
| 951 |
constructed. The rectangles indicate instances of IActionBars, and the |
and the ovals indicate other entities that create or modify action |
| 952 |
ovals indicate other entities that create or modify action bars.<br> |
bars. |
| 953 |
|
Black arrows indicate the flow of information.<br> |
| 954 |
<br> |
<br> |
| 955 |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
<div style="text-align: center;"><span style="font-weight: bold;">Figure |
| 956 |
15: Action bar information flow</span><br> |
15: Action bar information flow</span><br> |
| 972 |
</div> |
</div> |
| 973 |
</div> |
</div> |
| 974 |
<br> |
<br> |
| 975 |
|
<br> |
| 976 |
The workbench window has a top level IActionBars instance that |
The workbench window has a top level IActionBars instance that |
| 977 |
contributes to the main menubar, coolbar, etc. (this top-level object |
contributes to the main menubar, coolbar, etc. This top-level object is |
| 978 |
is returned by WorkbenchWindow.getActionBars()).<br> |
returned by WorkbenchWindow.getActionBars(). |
| 979 |
|
Most action bars are descendants of this top-level object, with the |
| 980 |
|
notable exception of the view action bars.<br> |
| 981 |
|
<br> |
| 982 |
<br> |
<br> |
| 983 |
<h3><a class="mozTocH3" name="mozTocId652269"></a>4.1 Editor Action Bars<br> |
<h3><a class="mozTocH3" name="mozTocId652269"></a>4.1 Editor Action Bars<br> |
| 984 |
</h3> |
</h3> |
| 985 |
Each type of editor gets a reference-counted IActionBars instance that |
Each type of editor gets a reference-counted IActionBars instance that |
| 986 |
is a child of the window's action bars. For |
is a child of the window's action bars. For example, if the workbench |
| 987 |
example, if the workbench contains 10 java editors and 10 text editors, |
contains 10 java editors and 10 text editors, it will create one |
| 988 |
it will create one IActionBars to be shared among the Java editors and |
IActionBars to be shared among the Java editors and another IActionBars |
| 989 |
another IActionBars to be shared among the text editors. Editors can |
to be shared among the text editors. Editors can access this shared |
| 990 |
access this shared instance by calling getSite().getActionBars(). |
instance by calling getSite().getActionBars(). Editor action bars are |
| 991 |
Editor action bars are initialized by an instance of |
initialized by an instance of IEditorActionBarContributor, and |
| 992 |
IEditorActionBarContributor, and additional actions are added by the |
additional actions are added by the editorActions extension point. |
| 993 |
editorActions |
<br> |
|
extension point.<br> |
|
| 994 |
<br> |
<br> |
| 995 |
The reference counted IEditorActionBars are managed by the |
The reference counted IEditorActionBars are managed by the |
| 996 |
EditorManager, along with the IActionBarContributor.<br> |
EditorManager, along with the IActionBarContributor. |
| 997 |
|
<br> |
| 998 |
<br> |
<br> |
| 999 |
<h3><a class="mozTocH3" name="mozTocId340925"></a>4.2 Action Sets<br> |
<h3><a class="mozTocH3" name="mozTocId340925"></a>4.2 Action Sets<br> |
| 1000 |
</h3> |
</h3> |
| 1043 |
action bars, these are not shared and are not a child of the workbench |
action bars, these are not shared and are not a child of the workbench |
| 1044 |
window's root action bars. This means that view instances can |
window's root action bars. This means that view instances can |
| 1045 |
programmatically add actions to their action bar. Additional actions |
programmatically add actions to their action bar. Additional actions |
| 1046 |
are also added to a view's action bars through the viewActions |
are |
| 1047 |
extension point.<br> |
also added to a view's action bars through the viewActions extension |
| 1048 |
|
point. |
| 1049 |
|
<br> |
| 1050 |
<br> |
<br> |
| 1051 |
<h2><a class="mozTocH2" name="mozTocId642161"></a>5.0 General |
<h2><a class="mozTocH2" name="mozTocId642161"></a>5.0 General |
| 1052 |
Conventions</h2> |
Conventions</h2> |