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 ) {
return {
border : states.rwt_BORDER ? "mycontrol.BORDER.border" : "mycontrol.border",
backgroundColor : "mycontrol.background",
padding : THEME_VALUE( "mycontrol.padding" ),
backgroundImage : "widget/mycontrol/bg.gif"
}
}
}
// 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.
In your appearance, you can directly refer to the colors,
borders, and fonts defined in your theme
definition file.
For dimensions and box dimensions, you have
to use the macro THEME_VALUE() as shown in the above example.
This macro is substituted with the current value in a valid format.
This is necessary because the qooxdoo theming does not allow for referring to
dimensions and box dimensions by a key.
For images, you must refer to the key specified in the theme
definition file, prefixed with widget/.