12 January 2011

Mostly-Declarative Eclipse Perspective Folders

I came across something not long ago that I did not realize could be done with perspective layouts. In the documentation for a org.eclipse.ui.perspectiveExtensions view, the relative field has this:
the unique identifier of a view which already exists in the perspective. This will be used as a reference point for placement of the view. The relationship between these two views is defined by relationship. Ignored if relationship is "fast".
Previously, I had thought that meant strictly that only a "view id" (including the ID for the editor area) could be used here - a thought that is reinforced by the tooling which lets you select any declared view ID in scope, including the org.eclipse.ui.editorss ID.


The issue in my application was that I needed a folder in the perspective - which could only be declared by the perspective factory - to be populated with view instances (same ID, various secondary IDs) from a down-stream bundle. The perspective factory can't have a dependency on the contributing bundle, and copying the view ID string literal into the up-stream bundle was not a tolerable solution.


What I wanted was to be able to declare a page layout folder as a perspective extension, or otherwise solely in the plugin.xml files for the bundles but was unable to find a way to do this.


However, as a solution, I discovered that a new folder can be created in the perspective factory code and then the down-stream perspective extensions can reference the folder's ID as a view ID. Ah-ha!


Now the solution:

public class PerspectiveFactoryWithFolder implements IPerspectiveFactory
{
   /** A layout folder for the right side of the perspective */
   public static final String RIGHT_FOLDER = "net.bilnoski.module.ui.perspective.folder.right";
   
   public void createInitialLayout(IPageLayout layout)
   {
      layout.setEditorAreaVisible(false);
      
      layout.createPlaceholderFolder(RIGHT_FOLDER, IPageLayout.RIGHT, 0.7f, layout.getEditorArea());
   }
}
<extension
      point="org.eclipse.ui.perspectiveExtensions">
   <perspectiveExtension
         targetID="net.bilnoski.module.perspective">
      <view
            closeable="true"
            id="net.bilnoski.module2.view:*"
            minimized="false"
            moveable="true"
            relationship="stack"
            relative="net.bilnoski.module.ui.perspective.folder.right"
            showTitle="true"
            visible="true">
      </view>
   </perspectiveExtension>
</extension>


Only the folders must be declared in code, and the rest I was still able to statically in plugin.xml declarations. An acceptable compromise, especially since I needed the perspective factories to exist anyway to hide the editor area.