If you contribute a custom widget, you might want to allow your clients to
customize its look and feel.
To do so, you have to register the custom widget with the extension point
org.eclipse.rap.ui.themeableWidgets
and provide a couple of resources that are relevant for the RWT theming.
Those resources must conform to a naming convention to be found by RAP.
Once a custom widget is registered with the extension point, its theming
resources are located by their name.
To make RWT's theming engine consider a custom widget in the theming,
it needs to know this widget.
Thus, the custom widget's class has to be registered with the extension point
org.eclipse.rap.ui.themeableWidgets
.
Here is an example of a themeable widget extension:
<extension
point="org.eclipse.rap.ui.themeableWidgets">
<widget
class="my.custom.controls.XButton">
</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 path segment "internal" inserted and
<widget>
is the lower case class name of the custom widget.
For example, if your custom widget is my.custom.XButton
, you must
create a package
my.custom.internal.xbuttonkit
for your files.
If you are already familiar with the concept of RWT's life-cycle adapters
(LCAs) you already know this convention, as those reside in the same package.
Theming relevant resources include:
For more complex widgets you might also want to pass some extra JavaScript resources to the client. Those additional resources are not automatically discovered and must be registered manually.
The theme definition file is an XML-file with the name
<Widget>.theme.xml
.
This file defines elements and themeable properties for the widget.
Its contents must conform with the schema that is outlined by the following
example:
<theme>
<element name="XButton"
description="Custom buttons">
<property name="color"
description="Text color for custom buttons" />
<property name="border"
description="Border for custom buttons" />
...
</element>
</theme>
The root element is named theme
and contains one or more element
definitions.
The main element's name should match the widget's class name.
Nested sub-elements may also be defined, their name should also begin with the
widget's class name and add the sub-component's name with a dash, e.g.
XButton-FocusIndicator
.
The default theme file is a CSS-file with the name
<Widget>.default.css
.
This file must set a default value for each themeable property defined
in the theme definition file.
This default value becomes active when the default theme is used and whenever
a custom theme does not specify a value for this property.
This ensures that the themeable property can never become undefined.
Here's an example:
XButton {
color: #c0c0c0;
border: 1px solid #c0c0c0;
}
If the file contains non-ASCII characters, it has to be UTF-8 encoded.
The appearances file contains JavaScript code to be included in the
qooxdoo appearance theme.
It must have the name <Widget>.appearances.js
.
For details on the qooxdoo theming, refer to
http://qooxdoo.org/documentation/0.7/theme_support,
especially the section on appearances.
RAP currently cuts out a section to include in the qooxdoo appearance
theme.
Therefore, the relevant part must be enclosed in two lines that contain
the words BEGIN TEMPLATE
and END TEMPLATE
as shown
in the example below.
However, in order to be upward compatible, and to allow editing with
JavaScript editors, this file should contain valid JavaScript.
appearances = {
// BEGIN TEMPLATE //
"my-custom" : {
style : function( states ) {
var tv = new org.eclipse.swt.theme.ThemeValues( states );
return {
color : tv.getCssColor( "XButton", "color" ),
border : tv.getCssBorder( "XButton", "border" ),
...
}
}
}
// END TEMPLATE //
};
The above example shows the general pattern for appearance files in RAP. A ThemeValues object is created from the current states as passed to the style function. This object can then be queried for matching CSS property values. The ThemeValues#getCssXXX methods take the CSS element name as first parameter and the CSS property as second one. The return value will be a JavaScript representation of the property value that applies to widgets with these states. SWT style flags, states and widget variants are already taken into account by these functions.
This is a class that implements the interface
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
org.eclipse.swt.widgets.Control
.
This class defines a couple of getter methods, which must be aware of the
widget's default values, which in turn depend on the current theme.
Namely, this includes the methods
If a custom value has been set for one of these properties using the
respective setter method, the getters will simply return this value.
But if either no custom value has been set or the value has explicitly been
set to null
, the widget displays its default from the theme 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
must 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 another widget that doesn't have this flag.
In order to provide the Control
class with the necessary
information, you have to implement the theme adapter.