Eclipse 4.0: Automatically created Theme Switching Menu/Toolbar

Recently I took a look at Tom Schindl’s great e4 SimpleIDE demo and found his implementation for an automatically created “Theme” menu. I liked it so much that I could not resist and adopted Tom’s implementation to my e4 contacts demo. I pimped it a bit so that theme icons in the menu as well as a theme switching toolbar are supported. The idea is that all themes defined with the extension point org.eclipse.e4.ui.css.swt.theme are checked at startup and the application’s workbench model is updated dynamically. If there is a png file for a corresponding css, it will be treated automatically as theme icon. For example: dark-gradient.css and dark-gradient.png correspond. The result in the user interface are an automatically created “Theme” menu and an icon-based theme toolbar.

How does it work?

First we need a couple of themes,  the e4 contacts demo currently comes with 3 themes:

<extension point="org.eclipse.e4.ui.css.swt.theme">
  <theme
     basestylesheeturi="css/dark-gradient.css"
     id="org.eclipse.e4.demo.contacts.themes.darkgradient"
     label="Dark Gradient Theme">
  </theme>
  <theme
      basestylesheeturi="css/bright-gradient.css"
      id="org.eclipse.e4.demo.contacts.themes.brightgradient"
      label="Bright Gradient Theme">
  </theme>
  <theme
      basestylesheeturi="css/blue-gradient.css"
      id="org.eclipse.e4.demo.contacts.themes.blue"
      label="Blue Gradient Theme">
  </theme>
</extension>

Then we use the extension point org.eclipse.e4.workbench.model to add a model contribution. We need a “processor” to contribute dynamically to the workbench model. The contacts demo provides two processors, one for the menu and the other for the toolbar. To specify which already existing model element should be injected as dependency in the processor’s Java object, we specify an element with a id. In the applications workbench model these ids belong to the main menu bar and the main toolbar.

   <extension
         id="modelContribution"
         point="org.eclipse.e4.workbench.model">
      <processor
            beforefragment="true"
            class="org.eclipse.e4.demo.contacts.processors.MenuThemeProcessor">
         <element
               id="menu:org.eclipse.ui.main.menu">
         </element>
      </processor>
      <processor
            beforefragment="true"
            class="org.eclipse.e4.demo.contacts.processors.ToolbarThemeProcessor">
         <element
               id="toolbar:org.eclipse.ui.main.toolbar">
         </element>
      </processor>
   </extension>

Now we have to implement the Processors in Java. As most classes in e4, a processor is a pure POJO and gets the necessary stuff injected. Since I wanted to provide two processors in the contacts demo, I split the work into an AbstractThemeProcessor and two concrete implementations for the menu and the toolbar. The AbstractThemeProcesor’s method execute() gets invoked because it is annotated with @Execute.

public abstract class AbstractThemeProcessor {

	@Execute
	public void process() {
...

The main task of the abstract class is to get the ThemingEngine and the command used for switching the theme (this is defined regularly in the workbench model). Then it loops though all available themes and invokes the processTheme method of the concrete implementations. As an example, here is the code snippet of the ToolbarThemeProcessor that shows how the toolbar is injected and toolbar items are added dynamically.

public class ToolbarThemeProcessor extends AbstractThemeProcessor {

	@Inject
	@Named("toolbar:org.eclipse.ui.main.toolbar")
	private MToolBar toolbar;

	@Override
	protected void processTheme(String name, MCommand switchCommand,
			MParameter themeId, String iconURI) {
		MHandledToolItem toolItem = MMenuFactory.INSTANCE
				.createHandledToolItem();
		toolItem.setCommand(switchCommand);
		toolItem.getParameters().add(themeId);
		if (iconURI != null) {
			toolItem.setIconURI(iconURI);
		}
		toolbar.getChildren().add(toolItem);
	}
...

The code for the MenuThemeProcessor is very similar. If you want to play around with running code, download e4 1.0 RC0 and check out the latest version of my contacts demo from cvs (host: dev.eclipse.org, repository path: /cvsroot/eclipse, user:anonymous, path to bundle: e4/org.eclipse.e4.ui/examples/org.eclipse.e4.demo.contacts).

Have Fun

Kai
Follow me on Twitter

This Post Has 3 Comments

  1. Lars Vogel

    Thanks Kai for blogging about this feature. Cool stuff.

  2. Wim Jongman

    Thanks Kai, Great stuff!! (no we will not let you win the worldcup)

  3. Pepe

    Hi! You missed the most important! How can i get all the availables themes. I would like to see process() code

Leave a Reply

I accept the Privacy Policy