This document represents a description of a new welcome implementation that will be used by Eclipse products that want to promote contributions into the Welcome pages. The implementation will be provided by Eclipse platform and available for use and configuration.
The Welcome framework in Eclipse provides for defining welcome pages with unique contribution points or 'anchors'. Other components can provide extensions that add content into these anchors. Although this mechanism worked well for closed solutions, it is increasingly hard to maintain for large products. Due to the 'bottom-up' nature of contributions from clients into the welcome pages, it is hard to control the final result and resolve conflicting contributions.
Take a provider of a reusable Eclipse feature as an example. He/she has created a useful feature consisting of a number of plug-ins. The feature can take part in several products, each one having its own Welcome implementation. There are several problems that the feature provider will face when creating Welcome contribution:
It is clearly obvious that the Welcome contribution of a reusable feature would be much easier to develop with the following conditions in place:
Based on the conclusions made in the previous section, the User Assistance team now provides a recommended Welcome implementation that will be used by all products that want to support better Welcome control. Eclipse Platform and SDK products will switch to this implementation and others will be encouraged to follow suit.
The universal Welcome solution is based on our experience with Welcome implementations and the need to have an implementation in place that contributors can count on. The implementation is built using the current Welcome framework which has been minimally enhanced to better support it. For this reason, all existing Welcome implementation will continue to work and clients will be able to switch to the new model according to their schedules. Of course, as long as they don't switch, they will not reap the benefits of the new implementation such as intelligent content merging, new visual solution etc.
While designing the universal welcome implementation, we started from the following principles:
In order to hook to the universal Welcome, developers should have a product-based Eclipse application. This requires the use of the org.eclipse.runtime.products extension point (the assumption is that the product has already been defined):
<extension id="foo" point="org.eclipse.core.runtime.products"> <product application="org.eclipse.ui.ide.workbench" description="Product Foo to use for testing the universal intro" name="Product Foo"> </product> </extension>
For this example, assume that the extension is define in plugin.xml file sitting in the bundle with the bundle id of com.example.intro. A long-existing feature of the Eclipse intro support is the ability to hook products and intros using the product-intro binding:
<extension point="org.eclipse.ui.intro"> <introProductBinding introId="org.eclipse.ui.intro.universal" productId="com.example.intro.foo"/> </extension>
The extension above binds the universal intro implementation (org.eclipse.ui.intro.universal) and our product id.
Universal intro customization is split between product branding properties and preferences. Product branding properties are set by the product and cannot be modified. They include product title, branding image and branding image text:
<product application="org.eclipse.ui.ide.workbench" description="Product Foo to use for testing the universal intro" name="Product Foo"> <property name="introTitle" value="Welcome to Product Bar"/> <property name="introBrandingImage" value="product:eclipse.png"/> <property name="introBrandingImageText" value="XYZ Company"/> </product>
Product properties whose values represent a file name relative to the product bundle must be qualified with the 'product:' prefix. The following properties are supported:
Second half of universal intro variables are accessible as preferences. The split is due to the fact that these variables can be configured by users and are exposed in the new Welcome preference page. The initial values for these preferences should be placed in the 'plugin_customization.ini' file that is referenced from the product extension. These preferences are:
The combination of product properties and default preference values can fully configure the Universal Welcome if no further customization is desired. For products that want to allow users to customize Welcome, a preference page is available. The following code should be added to the product's plugin.xml:
<extension point="org.eclipse.ui.preferencePages"> <page category="org.eclipse.ui.preferencePages.Workbench" class="org.eclipse.ui.intro.universal.ExtensionFactory:welcomeCustomization" id="com.example.intro.introCustomization" name="%introCustomizationPreference.name"> <keywordReference id="org.eclipse.ui.ide.appearance"/> </page> </extension>
This code will add the Welcome customization preference page:
The page allows users to select the presentation theme. The original choice is provided by the theme preference in the plugin_customization.ini file. In addition, users can choose from the list of available root pages. Checking the root page causes the related tab to appear at the top of the dialog.
When saved, this preference page will prefix the variables with the product id so that it does not interfere with the settings made for other products in the same workbench. Alternatively, selecting the checkbox above will not prefix the variables, making the stored settings visible to all the products.
When launching the universal Welcome configured as shown above, you will notice that all of the second level page that branch off the root page have an empty content area. This is because shared Welcome does not have content of its own. These areas are populated using intro config extensions.
The traditional way of contributing config extensions is to specify a full path of the anchor element in the target page. This method is still supported but it has proven to be somewhat fragile. As mentioned before, specifying an exact place where the extension will end up in the target is premature for extension authors. They may not know all the products in which their extension will end up, and therefore don't know where they should appear according to each product's focus. In the universal Welcome, this decision is left to product authors. Extension authors now have the option of specifying an incomplete target path, allowing the product author to fill in the blanks.
Config extensions that want to use late target path resolution need to fulfill three conditions:
The ability to resolve extension target paths is a new intro support feature in Eclipse 3.2 added to make universal Welcome more powerful. The feature itself is generic in that it can be used in other Welcome implementations, not just the universal one. In Eclipse 3.2, CustomizableIntroPart can accept an optional intro customizer class that can affect its behavior in several ways. One of the roles of the customizer is to perform late target path resolution. Of course, as far as product authors are concerned, this is all just implementation detail because in universal Welcome implementation, late target path resolution is performed using the data file mentioned earlier. This file is stored using the org.eclipse.ui.intro/INTRO_DATA preference.
The 'INTRO_DATA' file uses XML format and allows product authors to control the content of the main Welcome pages. Welcome contribution authors are required to specify only the page Id in their target paths. The rest is defined in this file. The file contains a sequence of 'page' elements, each containing a number of 'group' elements. Group elements specify page-relative path and have contributions for children. Contribution elements are used to specify two aspects:
<extensions> <page id="overview"> <group path="page-content/top-left"> <extension id="foo1" importance="high"/> <extension id="bar" importance="high"/> <extension id="foo2" importance="medium"/> </group> <group path="page-content/top-right"> <extension id="foo3" importance="low"/> <extension id="foo4" importance="low"/> <extension id="foo5" importance="callout"/> </group> <hidden> <extension id="foo6"/> <extension id="foo7"/> </hidden> </page> <page id="whatsnew"> ... </page> </extensions>
In the example above, contributions 'foo1', 'bar' and foo2' will be in the
left, and 'foo3', 'foo4' and 'foo5' in the right column on the page. The
relative order of contributions is also extracted from this file. In addition,
contributions are classified based on the
importance attribute that
can have four valid values: high, medium, low and
callout, with low as the default. Each value has matching
presentation that makes it stand out on the page. First three are simply
different levels of importance according to the product author (note that the
same contribution may receive a different importance classification in two
separate products). The last one (callout) is used to single out
contributions that are of a completely different nature (for example, a
contribution that offers links to videos or animation).
Contributions that are not listed are appended after the listed contributions and assigned a low importance value. This is important for contributions added after the product has shipped - they still need to show up.
Contributions not relevant to the project can be hidden by explicitly listing them as children of the 'hidden' element.
An extension contributed into one of the root pages can itself contain anchors, providing for others to add content. This causes a problem because the final resolved path of the content in the extension is not known in advance. For this reason, target paths for content in extensions that use late path resolution must itself be resolved:
<?xml version="1.0" encoding="utf-8" ?> <introContent> <extensionContent id="extra" name="Extra" alt-style="css/swt.properties" style="css/overview.css" path="overview/@"> <group id="extra-group" style-id="content-group"> <link label="Extra Overview link" url="http://org.eclipse.ui.intro/showPage?id=extraOverview" id="extra-overview"> <text>Showing the third-level extra page for overview</text> </link> <anchor id="additions"/> </group> </extensionContent> </introContent>
In order to contribute into the anchor 'additions' in the extension above, we should use the following path: "overview/@extra/extra-group/additions". The segment '@extra' will be replaced with the resolved path of the extension with the id 'extra' in the 'overview' page. For example, if the extension is placed in the upper left segment of the page, the resolved path will be: "overview/page-content/upper-left/extra-group/additions".
In addition to providing intro customization to the end users for the first time, Welcome preference page will allow product authors to create the introData.xml file to be used for the first startup. The procedure is simple:
List 'Available Extensions' holds all the extensions that are currently hidden. They can be moved to one of the four quadrants of each page.
The intent of the shared Welcome implementation is that all products that want intelligent content merging should point at it instead of creating their own Welcome. This implies that it is possible to end up in a situation where multiple products all pointing at the same shared Welcome coexist in the Eclipse workbench. Intro is handling this situation as follows:
[Note: the above currently does not work - only active product intro data is consulted]
Most of the extensions coming into the main Welcome pages offer links to open further pages contributed by the extensions themselves. It is recommended to create these pages in such a way as to continue with the shared Welcome visual design. The main requirement is to show the appropriate navigator at the top of the page.
It is fairly easy to do that using the 'include' element. The idea is to include the navigation content at the beginning of contributed page. Unlike the current Welcome implementation, shared Welcome main pages have navigation section that is different for each page. For this reason, pages that branch off these pages should include the navigation from the parent page. For example:
<?xml version="1.0" encoding="utf-8" ?> <introContent> <extensionContent id="extra" name="Extra" alt-style="css/swt.properties" style="css/overview.css" path="overview/@"> <link label="Extra Overview link" url="http://org.eclipse.ui.intro/showPage?id=extraOverview" id="extra-overview"> <text>Showing the third-level extra page for overview</text> </link> </extensionContent> <page id="extraOverview" style="$theme$/html/overview.css" style-id="page"> <title style-id="intro-header">$introTitle$</title> <group id="extra-group1" filteredFrom="swt"/> <include path="overview/navigation-links"/> <group id="page-content"> <group id="content-header" label="EXTRA OVERVIEW" filteredFrom="swt"> </group> <text style-id="page-title" id="page-title" filteredFrom="html">EXTRA OVERVIEW</text> <text style-id="page-description" id="page-description">Extra overview page description.</text> <!-- Add content here --> </group> </page> </introContent>
The extension above contributed into the overview page contributes a link that shows another page whose definition is part of the extension. Note how we define the title element using substitution variable (the variable will be resolved based on the product property). We also include the group 'navigation-links' that belongs to the 'overview' page at the beginning of the page content definition. We also add the 'extra-group1' div because it is can be used by some themes for adding additional page decoration (indeed, it is used in 'Purple Mesh' theme for that exact purpose).
In order to make universal welcome possible, we made a number of enhancements in the Welcome framework. These enhancements are of general nature and are are applicable to other Welcome implementations:
groupelement in the intro content schema. This attribute indicates that the children of the group will be dynamically computed by the intro configurer.
launchBarelement in the org.eclipse.ui.intro.config extension point. When true, the shortcuts will be computed by the intro configurer.
pageelements in the intro content schema. It provides for setting the background image on these elements.
true, the group will have the ability to expand and collapse its children by selecting the title and/or the toggle button.
New in 3.2 is support for Welcome themes. Themes can be plugged is using the new element that is part of org.eclipse.ui.intro.configExtension extension point. Plug-in org.eclipse.ui.intro.universal plugs in two themes:
<extension point="org.eclipse.ui.intro.configExtension"> <theme default="true" id="org.eclipse.ui.intro.universal.circles" name="%theme.name.circles" path="$nl$/themes/circles" previewImage="themes/circles/preview.png"> <property name="launchbarBackground" value="#a1c2cb"/> <property name="launchbarOverviewIcon" value="$theme$graphics/launchbar/overview16.png"/> <property name="launchbarFirststepsIcon" value="$theme$graphics/launchbar/firststeps16.png"/> <property name="launchbarTutorialsIcon" value="$theme$graphics/launchbar/tutorials16.png"/> <property name="launchbarSamplesIcon" value="$theme$graphics/launchbar/samples16.png"/> <property name="launchbarWhatsnewIcon" value="$theme$graphics/launchbar/whatsnew16.png"/> <property name="launchbarMigrateIcon" value="$theme$graphics/launchbar/migrate16.png"/> <property name="launchbarWebresourcesIcon" value="$theme$graphics/launchbar/webresources16.png"/> </theme> <theme id="org.eclipse.ui.intro.universal.purpleMesh" name="%theme.name.purpleMesh" path="$nl$/themes/purpleMesh" previewImage="themes/purpleMesh/preview.png"> <property name="launchbarBackground" value="#c6c3e8"/> <property name="launchbarOverviewIcon" value="$theme$graphics/launchbar/overview.gif"/> <property name="launchbarFirststepsIcon" value="$theme$graphics/launchbar/firststeps16.png"/> <property name="launchbarTutorialsIcon" value="$theme$graphics/launchbar/tutorials.gif"/> <property name="launchbarSamplesIcon" value="$theme$graphics/launchbar/samples.gif"/> <property name="launchbarWhatsnewIcon" value="$theme$graphics/launchbar/whatsnew.gif"/> <property name="launchbarMigrateIcon" value="$theme$graphics/launchbar/migrate16.png"/> <property name="launchbarWebresourcesIcon" value="$theme$graphics/launchbar/webresources16.png"/> </theme> </extension>
Each theme has a unique identifier, translatable name, preview image and a path to the root theme folder. Intro plug-in does not provide any UI for theme manipulation. The only way to select a theme is via the preference org.eclipse.ui.intro/INTRO_THEME in plugin_customization.ini.
Theme support by itself does not make intro implementations theme-enabled. It is simply a way of grouping all the presentation files (styles and images) in one place that can be pointed at or switched as one. Concrete intro implementations can choose to expose themes in a more substantial way (and in fact Universal Welcome implementation does exactly that).
Theme-enabled intro implementation must make all the references to style and presentation resources using the $theme$ substitution variable. Absolute paths for images, pages, styles etc. will be computed by resolving the substitution variable using the path of the currently active theme.