New extensions: theme mixins

0
0

Having “improved” a couple of the WiseJ produced extensions I thought it was about time I created my own. I’m trying to figure out how the theme mixin system works. The documentation leads me to think that I can use a mixin as part of my extension to get my component to inherit from the existing theme system (so for example when using blue1 my control will be blue, when using material3 it will be green and so on).

Assuming I have understood this correctly what would I put in a mixin assuming my control has an appearancekey of “myControl”? It looks like I can inherit from existing controls but then how do I map my CSS elements to those of the WiseJ control?

For example if I have a class .mycontrol-container how do I set its border style to match the combobox border style in the WiseJ themes?

Thanks

Nic

  • You must to post comments
0
0

Hi Nic,

Yes you can include (embed) a mixin with your extension. See the Bubble extension. It has an embedded mixin under /Platform.

If you have created a widget based on a qooxdoo or wisej widget then all you need to do is set the appearance key under properties:

appearance: { init: “bubble”, refine: true },

and the widget will pick up the styles and the properties from the theme.

For the styles, there is nothing you need to do since they are limited to the built-in decorator classes and automatically become css classes applied to the widget.

You can add new states in the theme by calling this.addState(“state-name”) and this.removeState(“state-name”). When the state changes, the system will automatically apply the new set of styles and properties.

For the properties it’s different. The themeable inherited properties are obviously inherited. If you add your own properties and want to theme them, add themeable: true, from the Bubble extension:

/**
* A style string that is applied to the widget as a state.
* When the style is changed, the previous style is removed from the states.
* This value is used in the theme to change the appearance of the bubble
* according to the style. I.e.: “warning”, “error”, “critical”, …
*/
style: { init: “”, check: “String”, apply: “_applyStyle”, themeable: true }

This adds a new property named “style” and makes it themeable. Now the theme can set a property named “style”. There is nothing to do in your implementation, the theme engine will assign the property as if it was assigned by code, and you simply have to code what you want the property to do in the apply method.

But….

How does all this become an HTML element?

The widget automatically creates a <div> content element (you can override it, but the default is usually fine). The content element is a “fastDOM” element, meaning that it’s not directly the DOM object, it’s in between, in order to flush the rendering all at once. You can use the content element to set attributes and styles as if it was a DOM element:

var el = this.getContentElement();

el.setStyle(“backgroundColor”, “red”);

So, if your property needs to change the HTML, you can do it by using the content element.

If you need a composite widget you can create more complex html or can nest child widgets. The best way is to look at the qooxdoo api (http://www.qooxdoo.org/current/api/#qx) and at how the widgets are built.

If you have instead used wisej.web.Widget (like the ChartJS extension) then it’s a different story. The wisej.web.Widget class was built to be able to import third part widgets easily without having to build a new Wisej class every time. The wisej.web.Widget is a qooxdoo/wisej widget that exposes a child element named “container” that can be used to render third party widgets.

The problem is how to translate theme values to “foreign” DOM element inside “container”. I guess this is the problem?

Remember that the theme has several elements: a) colors, b) images, c) fonts, d) appearances.

All of this are resolved automatically when the properties are standard qooxdoo/wisej properties. But when you are handling the html directly, as in the ChartJS extension, you need to invoke the translation:

Colors:

var colorMgr = qx.theme.manager.Color.getInstance();  <– singleton

var color = colorMgr.resolve(“myColor”); <=== the value of “myColor” in the theme is converted to an HTML color definition.

Images:

Images require two things: translation and loading. Once the image is translated from the theme then is still needs to be loaded.

var imageMgr = qx.util.AliasManager.getInstance(); <– singleton

var source = imageMgr.resolve(“my-icon”);

Now you have the image, either a data,base64 or a URL. You can assign this to any html element or background and let the browser handle the image. If you need to preload it, or of it’s an SVG that needs to change the color, then you need the image loader:

var imageLoader = qx.io.ImageLoader.load;  <— static

imageLoader.load(source, function(url, entry){

// here the image is loaded. if it was already loaded, this is called immediately.

});

Appearances:

Appearances group styles and properties. The easiest way to use the styles is to set the appearance key of the container widget: this.setAppearance(“my-appearance”);

For the properties, you can read them like this:

var appearanceMgr = qx.theme.manager.Appearance.getInstance();

var themeData = appearanceMgr.styleFrom(appearance, states, null, “”);

// themeData has the property values.

Using plain CSS files:

You can also simply add a css file in your extension and declare any css rule that will match the elements in your widget. All the extensions that use jquery widgets have also css files with them.

HTH

Qooxdoo is an amazing framework with a lot of stuff in it. Wisej extended it a lot and there are many many features all working together.

And please feel free to contact me directly and send me code for any additional info.

Best,

Luca

  • Nic Adams
    Thanks Luca, I’ve sent you an email with the source and some questions :) Nic
  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.