This article relates to the old property-based theming system. Since 1.1M4, RAP provides a new mechanism for theming based on CSS which is now the default (see here). Thus, the preferred way of making widgets themeable is currently changing. If you develop new custom widgets, please refer to the RAP newsgroup and look for updates of this article in the Eclipse CVS.
Once you wrote a custom widget, you might want to allow your users to customize
some aspects of its presentation.
To do so, you have to provide a couple of resources that are relevant for the
theming and register the widget with the extension point
org.eclipse.rap.ui.themeableWidgets
.
The resources must conform to a naming convention so that they can be found.
Once a custom widget is registered with the extension point, they are
located by their name.
You have to register your custom RWT widget with the extension point
org.eclipse.rap.ui.themeableWidgets
.
As a result of the resolve-by-name strategy, only the custom widget class must
be registered.
The following is an example of a themeable widget extension definition:
<extension point="org.eclipse.rap.ui.themeableWidgets"> <widget id="my.custom.datepicker" class="my.custom.controls.DatePicker"> </widget> </extension>
The custom widget must provide the theme-relevant resources in a package which
is named after the schema
<internal-package>.<widget>kit
where
<internal-package>
is the package name with the segment "internal" inserted somewhere in the path
and
<widget>
is the lower case class name of the custom widget.
For example, if your custom widget is my.custom.XWidget
, you must
create a package
my.custom.internal.xwidgetkit
or attribute
my.internal.custom.xwidgetkit
for your files.
By the way, if you are already familiar with the concept of life-cycle adapters
(LCAs), they reside in the very same package.
Theming relevant resources include:
org.eclipse.rwt.theme.IControlThemeAdapter
.
The name must match the pattern <Widget>ThemeAdapter
.
You must provide such a class if your custom widget's default values for
background color, foreground color, font, or border width differ from the
defaults of its superclass.
Your custom widget will always be an (indirect) descendant of the class
org.eclipse.swt.widgets.Control
.
This class defines a couple of getter methods, which must be aware of the
widget's default values, which depend on the current theme.
Namely, this includes the methods
null
, the widget displays its default and the getters must
reflect the actual state of the widget.
For example, if your custom widget has a light gray background by default, the
method getBackground
should return this color instead of
null
.
The value can depend on the particular instance of the widget, e.g. a widget
created with the style flag SWT.BORDER
might be displayed with a
different border than one without this flag.
In order to provide the Control
class with the necessary
information, you have to implement the theme adapter.
The theme definition file is an XML-file with the name
<Widget>.theme.xml
.
You must provide this file if you want to define new theming keys which allow
to make certain aspects of your widget's presentation configurable.
Its contents must conform with the schema that is outlined by the following
example:
<theme> <color name="mywidget.background" description="Background color for MyWidget" default="248, 248, 255"/> <border name="mywidget.border" description="Default border for MyWidget" default="1 black"/> <image name="mywidget.active.bgimage" description="Background image for title bar of active Shells" default="resource/images/mywidget_bg.png"/> ... </theme>The root element is named
theme
and contains one or more elements
that define new theming keys.
The possible types are:
color
)dimension
)boxdim
)border
)font
)image
)name
: contains the name of the key.
This name can be freely chosen, but to avoid conflicts, it should start with the
custom widget name.
description
: contains a description that allows the user to
understand which aspects of the widget are affected by this key.
default
contains the default value for this theming key in a
valid format (see the article on RWT Theming) for
format definitions.
targetPath
: (optional) only for images, this attribute
widget/<targetPath>
.name
.
The appearance fragment file is a piece of JavaScipt code to be included in the
qooxdoo appearance theme.
For details on the qooxdoo theming, refer to
http://qooxdoo.org/documentation/0.7/theme_support,
especially the section on appearances.
The appearance fragment file must have the name <Widget>.appearances.js
.
Normally, the contents of the file are directly included in the appearance
section of the generated qooxdoo theme file.
Unfortunately, some JavaScript editors might generate warnings as the file
contains only a fragment and not a complete valid JavaScript program.
In this case, you can surround the fragment with some extra dummy code that
makes your JavaScript editor happy.
The fragment to be actually included must be enclosed in two lines that contain
the words BEGIN TEMPLATE
and END TEMPLATE
as shown in
the example below.
If these lines are present, only the lines in between are included in the
appearance theme.
appearances = { // BEGIN TEMPLATE // "my-custom" : { style : function( states ) { var tv = new org.eclipse.swt.theme.ThemeValues( states ); return { border : tv.getBorder( states.rwt_BORDER ? "mycontrol.BORDER.border" : "mycontrol.border" ), backgroundColor : tv.getColor( "mycontrol.background" ), padding : tv.getBoxDimension( "mycontrol.padding" ), backgroundImage : tv.getImage( "mycontrol.background.image" ) } } } // END TEMPLATE // };
In the above example, the state rwt_BORDER
signals that the
SWT.BORDER
style flag is set.
This state is not automatically available.
It must explicitly be set in the life-cycle adapter (LCA).
If you don't provide an LCA on your own, this is done in the LCA of your super
class (usually CompositeLCA), otherwise it is your responsibility to make the
required states available.
Update:
Since RAP 1.1M3, you should not refer to the names of colors, borders,
and fonts in your appearance. Also, the makro THEME_VALUE()
is
obsolete.
To refer to theme values, use an instance of the class ThemeValues as shown in
the example above.
This class transforms all types of theme values in a format suitable for the
qooxdoo appearance theme.
Moreover, it supports widget variants and tries to resolve the variant value
first.