Color and Border Objects
The color object
How to use
The current model uses a color object to store the complex informations of a single color. The properties color and backgroundColor of Widget have been transformed to use this new model already. This means the default way to define a new color for a widget looks somewhat like the following:
myWidget.setColor(new qx.renderer.color.Color([200,30,66]));
The array inside the constructor call contains the seperated RGB values.
Support for named HTML colors
Color also understands the old sixteen HTML color names:
- maroon
- red
- orange
- yellow
- olive
- purple
- fuchsia
- white
- lime
- green
- navy
- blue
- aqua
- teal
- black
- silver
- gray
Other web-safe colors are currently not supported by their name.
Support for Hex values
Color understands hex colors, reads them and internally converts them to a numeric RGB representation. You can use the short definition like #333 or in the default way #333333.
Support for single integers
One nice additional feature is that you can define a color by a single integer value. For example “128” means nothing more or less than [128,128,128] but is a bit shorter. Needless to say, that this only works for grayscale colors.
The new border object
How to use
The border object follows the color object style. Here is an example:
myWidget.setBorder(new qx.renderer.border.Border(2, "solid", new qx.renderer.color.Color([200,30,66])));
The first argument inside the Border constructor is the border width. The second one defines the border style. The third is the color value (needs to be any value which Color can handle).
Available border styles:
- solid
- double
- dotted
- dashed
(more in BorderObject, simply continue reading ;) )
Share object instances
With the new code you can define your (color- and border-) objects in a global data structure and share them between multiple widgets for example. This means your application, for instance, could store an internal array with the most-used colors of your application. This allows you to make your application look different without searching for the real color value strings as before.
Sharing colors
First define some colors:
var appColors = { bg : new qx.renderer.color.Color("white"), fg : new qx.renderer.color.Color("#332211"), frame : new qx.renderer.color.Color("676767") };
And use them:
myWidget.setBackgroundColor(appColors.bg); myWidget.setColor(appColors.fg); myWidget.setBorder(new qx.renderer.border.Border(1, "solid", appColors.frame));
Sharing borders
Naturally you can also do this with borders.
var appBorders = { frame : new qx.renderer.border.Border(1, "solid", appColors.frame) };
And use them as above with the colors:
myWidget.setBorder(appBorders.frame);
Dynamically updating
As this is not enough for some guys we also have developed a dynamic updating for colors and borders. This only works if you use ColorObject instead of Color and BorderObject instead of Border.
Both new objects bring a bit of overhead, so if you don’t need their additional features please use the basic types instead.
Additional Features
Only two things currently:
- Object Binding
- Themed Values
Object Binding
The basic objects (Color and Border) only apply the styles to the object of their current value. There is no binding. If you update the border or the value of the color later they will look like before.
If you use ColorObject and BorderObject instead the widgets will register themselves to the color or border object and will get informed if they are updated.
Have a look at the following code:
var myBoundedColor = new qx.renderer.color.ColorObject([20,10,100]); myWidget.setBackgroundColor(myBoundedColor); myWidget.addEventListener("click", function(e) { myBoundedColor.setValue([200,30,50]); };
In this example the widget gets the background color RGB. And it will always be updated if you change the value of the color object again.
This also work with BorderObject like you can see here:
var myBoundedBorder = new qx.renderer.border.BorderObject(1, "solid", new qx.renderer.color.ColorObject([200,10,20])); myWidget.setBorder(myBoundedBorder); myWidget.addEventListener("click", function(e) { myBoundedBorder.setTopWidth(4); };
The widget will get a one pixel reddish border but the top width is four pixels.
Border will use Color for its color, and BorderObject will use ColorObject instead.
Themes
Color Themes
The next step of the revolution is the introductions of themes (for colors and borders). Themes works with named colors. We currently use all the known system colors supported by CSS 2.1. We use their name but not their value. If we find out later that these colors are not enough already we need to add some more. But currently it seems to be a good base to start with.
A short overview of the supported color values (case-insensitive).
ActiveBorder: Active window border.ActiveCaption: Active window caption.AppWorkspace: Background color of multiple document interface.Background: Desktop background.ButtonFace: Face color for three-dimensional display elements.ButtonHighlight: Highlight color for three-dimensional display elements (for edges facing away from the light source).ButtonShadow: Shadow color for three-dimensional display elements.ButtonText: Text on push buttons.CaptionText: Text in caption, size box, and scrollbar arrow box.GrayText: Grayed (disabled) text.Highlight: Item(s) selected in a control.HighlightText: Text of item(s) selected in a control.InactiveBorder: Inactive window border.InactiveCaption: Inactive window caption.InactiveCaptionText: Color of text in an inactive caption.InfoBackground: Background color for tooltip controls.InfoText: Text color for tooltip controls.Menu: Menu background.MenuText: Text in menus.Scrollbar: Scroll bar gray area.ThreeDDarkShadow: Dark shadow for three-dimensional display elements.ThreeDFace: Face color for three-dimensional display elements.ThreeDHighlight: Highlight color for three-dimensional display elements.ThreeDLightShadow: Light color for three-dimensional display elements (for edges facing the light source).ThreeDShadow: Dark shadow for three-dimensional display elements.Window: Window background.WindowFrame: Window frame.WindowText: Text in windows.
As themed colors need to be updated if the theme will be changed during the site runtime it has been decided to only allow ColorObject to be themeable.
Border Themes
There are some “special” styles which are additionally available in BorderObject:
- outset
- inset
- groove
- ridge
These are typically colored by the browser itself and not by the user. Here you can simply leave out the third argument in the constructor call of BorderObject.
Border uses Color as mentioned before, it is not possible to use these style values with Border. You must use BorderObject instead.
BorderObject instances will follow in later versions but has currently no priority.
Built-in Converter
To make this color and border handling a bit more user friendly and more compatible to the old style, we have introduced “converter” possibilities to our property handling. This means that the value, before it is stored, is sent to a converter method which will “transform” the value to an acceptable one for the property.
Color Caching
This is currently built-in for the Widget properties color and backgroundColor and the four color properties of Border.
The method used is ColorCache. A new global function which gets an input value, converts it to a key, looks if the key is already known, uses the previously instantiated color object, or create a new one and store it internally.
This has some advantages:
- Already converted RGB, Hex or HSB values for a key could be re-used between multiple widgets without the user have to know something from these shared usage.
- Automatically minimize the object usage for often used colors.
- Much simpler color setups for objects.
myWidget.setColor("red"); myWidget.setColor(200,100,30); myWidget.setColor([200,100,30]); myWidget.setColor("#338899"); myWidget.setColor("#389");
Border Caching
This functionality also exists for the new border handling. The border property of Widget already uses this new method.
All the following lines should create the same border. And all of them use the same border object, created by the first line.
myWidget.setBorder(1, "solid", "red"); myWidget.setBorder([1, "solid", "red"]); myWidget.setBorder("1px solid red");
