After 6 months of hard work I can finally present another release of WonderGUI. This release packs some very valuable updates to the framework, enabling sophisticated styling and advanced effects on a wide scale. Read on to know more about the exciting new features.

Nine

But first I want to say that I hav decided to keep WonderGUI in the alpha phase a bit longer since I:

a) Still have not converted the Graphics layer to use MU (a WonderGUI specific way to handle screen coordinates).

b) I have decided to take a second hard look on how certain classes are constructed.

c) I have one more super awesome feature I would love to squeeze in for 3.0. :)

These three issues are all likely to cause large changes to parts of the API and once we enter beta phase I want no more of that. Just additions and trivial changes.

Anyway, let’s dive into all the exciting features of this release! :)

Layered rendering

This is the most exciting feature of this release. The CanvasStack widget of alpha8 was a very interesting development and it made me think in new directions when it comes to how Widgets are drawn on the screen. After some serious thoughts I decided to retire the CanvasStack and build its functionality straight into the graphics system. This took way more work than I had anticipated and I needed a second attempt before I got it right, but now it is here!

Layered rendering works a bit like layers in Photoshop or GIMP. A number of layers can be created and the widgets can draw into any layers they want, which are then blended together onto the screen. One simple, but effectful way to utilize this is to create widgets with shadows and glow effects that affects surrounding widgets. I tink it is easiest to explain with an example:



Let’s say we are going to create a UI that resembles an old, industrial control panel with knobs, large push buttons and lamps. We start by creating four layers: background, shadow, foreground and glow.

In the background layer we draw the background of the control panel and any widgets that are flat or sunken into the background.

In the foreground layer we draw knobs, levers and large buttons that stand up from the panel as well as turned on lamps that shall emit light onto background and widgets.

The shadows from the knobs, levers and buttons in the foreground layer are drawn into the shadow layer. Since the shadows exist in their own layer we can use a clever combination of inverted colors and blendmodes to create shadows that don’t increase darkness when they overlap, which will look much more natural. We also avoid casting shadows on the tall widgets in the foreground layer, by blending the shadow layer onto the background before the foreground layer.

Likewise, we combine the light from the lamps in the glow layer using similar techniques, preventing whiteout effects when several lamps shine on the same area. And since the glow layer is added last, it will be applied to both the background and foreground alike.

The result is that the tall widgets only cast shadows onto the background, not each other or turned on lamps, and the light from the lamps combines nicely onto background and other widgets.



Creating widgets with deep shadows and radient light that spreads onto surrounding widgets is just one way to use layered rendering to increase the realism of your UI. However, using layered rendering in the right way takes some skills and efforts as well as some artistic knowledge about how to combine layers to generate the effects you want. It also increases the resource usage of the application, something I intend to largely mitigate with some planned, future optimizations.

The unique Skin concept of WonderGUI plays wonderfully into this, since you can define and combine several skins onto one widget, each working on a different layer. Speaking of skins, that brings us to the next most exciting feature…

Animated skins and skin transitions

Although the skin concept of WonderGUI always has held great promise, it was first with the previous release that we started to tap that potential when we added a large amount of skins, the functionality to combine them and gave widgets the posibility to more directly influence their skins.

In this release we take it one large step further by introducing animated skins. A skin can utilize animations for just running a continous animation or make transitions between states (like a widget slowly changing color when hovered by the mouse or a checkmark gradually being drawn when selected).

These kinds of transitions have been standard features of many UI Toolkits for years, so it is an area where WonderGUI has been lacking. It is therefore very pleasing to finally start closing this gap. There is still work to be done on individual skins before we can configure them to use animations the way we want, but the system to allow it is now in place, along with two skins that shows the potential.

I also believe that the way this has been implemented in WonderGUI is way more flexible than in most UI Toolkits and will allow for some inovative UI effects.

Metal API support

Alpha9 includes a backend for using Apples Metal API for rendering. This means we now have three backends - Software, OpenGL and Metal.

The Metal backend has not been tested in production yet and is likely to have bugs, but it has passed my test suite. It is also the first backend for modern rendering APIs, but I hope to be able to add support for Vulkan and DirectX in the not so distant future.

Gradients

All graphics backends now supports gradients. Gradients can be used for fills and tinting graphics when blitting. They can also be used to fill areas when drawing charts and such.

All skins have been upgraded to support gradients, with the exception of ColorSkin and StaticColorSkin, where specific gradient skins will be provided instead.

New widgets

Three more widgets have been added:

  • TooltipLayer can be used to provide tooltips in a simple and consistent way, while also allowing for a lot of customization of look and placement of individual tooltips. Just insert a TooltipLayer into your hierarchy and add tooltip strings to your widgets and see them come to life.

  • CanvasCapsule provides a canvas for its children, allowing for off-screen buffering of parts of the UI that might be time consuming to redraw. It can also provide a separate set of layers for its canvas, allowing for layered rendering of only parts of the UI.

  • RenderLayerCapsule can be useful if you use layered rendering. It simply allows you to switch the layer the widgets it encapsulates renders into, enabling you to not only render skins into separate layers, but also graphics drawn by the widget itself (like the text of a TextDisplay).

New skins

Three new skins have been added:

  • SpinAnimSkin is a simple animated skin that continously spins a bitmap.

  • ScrollSkin is an animated skin specifically made to support Apple-style checkboxes where a button slides left and right when selected or unselected. But it is flexible enough to probably find other uses as well.

  • StaticGradientSkin draws a simple, static gradient. Useful for backgrounds and such.

Other improvements

  • The concept of locking and unlocking a Surface for access to its pixels turned out to be flawed and too restrictive. Instead a new concept of PixelBuffers have been introduced, which allows for more fexibility and performance improvements.

  • Shared pointers are now threadsafe (but weak pointers are not). This allows us to safely move object between threads, although they may still only be accessed from one thread at a time.

  • The class Origo has been renamed Placement. Makes more sense considering how it is used.

  • BlockSkin and StaticBlockSkin now supports a “rigid part” that doesn’t scale with the rest of the skin.

  • Support for inverting the mouse wheel has been added to support Apples “natural scroll direction”.

  • Some simple “object tracking” feature has been added to Base. This can be used to debug memory leaks resulting from forgotten shared pointers or just to check how many objects of each type currently are alive.

So, what’s next?

Actually, I don’t know. The three things preventing WonderGUI from going into Beta is of course high on the agenda, but so are adding a few fundamental missing widgets. There is also a large number of small issues (papercuts) that I hope to take care of in the near future.

But mostly what will be done next will depend on circumstances currently unknown. No matter what, WonderGUI will keep on improving and evolving in exciting directions!