I’m very excited about this release! By far the largest update for years with an extensive set of updates, that truly affects the developers ability to create beautiful and useful UIs. Skipping the previous release was definitely the right choice, cause now I can bring you a coherent and tested set of new features and improvements!

Skyscraper

We are still in the Alpha-cycle and not in the Beta-cycle as I had hoped due to one outstanding refactoring task holding us back. But the improvements all around more than makes up for it, so let me tell you about all the new, exciting features.

New features in graphics system

The graphics system has received a round of very exciting updates that will enable more dynamic and better looking UIs. All in all I now feel that the graphics system has reached a level of maturity and features that will enable the vision I’ve had for WonderGUI.

  • Gamma correction - WonderGUI now properly supports gamma correction and sRGB surfaces. This allows for more correct shadows, tinting and blending. Gamma correction is free for the OpenGL renderer but quite costly for the software renderer, so it can be disabled.

  • Gradients - Blits, fills and segments can now be tinted with a gradient. All tinting is free for the OpenGL renderer, but can get costly in software rendering (depending on specific operation).

  • Tiling - Instead of stretching, a surface can now also be tiled across the destination rectangle. The tiled surface can also be scrolled, scaled and rotated for some funky effects.

  • PieChart - Pie-charts can now be drawn through a simple GfxDevice api-call. These can be used not only for drawing pie charts, but are also suitable for rounded meters, knobs and spinners.

  • A8 Canvas - An A8 surface (alpha only, 8 bits per pixel) can now be used as the Canvas. These are useful for shadow, glow and masking effects.

  • Morphing - A new blend mode has been added: Morph. This is somewhat similar to Blend, but morphes between the source and destination (including their alpha channels) instead of blending one onto the other.

Both Software and OpenGL rendering are fully up-to-date and there is no noticable difference in output.

New skins and vastly improved skinning posibilities

The most exciting feature of this release is probably the vast improvements to the skin system and addition of several new skins. This completely opens up new possibilites to style the widgets in advanced ways and do sophisticated things with simple widgets and powerful skins.

The most interesting part is the MeterSkins, which displays values provided by the widget in various ways. This value could be the progress of a timer or progress bar, the position of a slider or knob or… anything else depending on the widget.

Also the DoubleSkin and BakeSkin allows several skins to be combined in various ways, making it possible to style even the simplest widget into something very sophisticated.

  • FillMeterSkin - A filled box that grows vertically or horizontally with the meter value. Suggested usecases include progress bars, volume meters and slider backgrounds.

  • FrameMeterSkin - A skin that uses frame-based animations to display the meter value. Suggested usecases includes almost anything since whatever effect you want could be made as an animation.

  • PieMeterSkin - A skin that uses the pie-chart primitive to display the meter value. Suggested usecases includes knobs, rounded timers and progressbars as well as busy-spinners.

  • SpinMeterSkin - A skin that rotates a bitmap to display the meter value. Suggested usecases includes knobs and timers.

  • LambdaSkin - A skin where you provide the drawing method in a Lambda function. Suggested usecase is any skin where you want to do something specific not covered by existing skins.

  • StaticBoxSkin - A simplified, static version of BoxSkin. Suggested usecase is wherever you want a static outlined fill, like widget and window backgrounds.

  • StaticBlockSkin - A simplified, static version of BlockSkin. Suggested usecase is wherever you want a static bitmap or nine-patch, like widget and window backgrounds.

  • DoubleSkin - A skin that combines two skins. A front-skin is draw ontop of (and optionally inside) a back-skin. Allows for some simple combination effects.

  • BakeSkin - A skin that bakes together two or more skins in a back-surface before blitting it to the output destination. This allows you to blend backgrounds, foregrounds, glow effects, shadows etc in creative ways for enhanced visual effects.

  • TileSkin - A state-aware skin tiling a surface.

  • StaticTileSkin - A simplified, static version of the above. Suggested usecases includes backgrounds.

More improvements to the skin system are to be expected in the next release. I have a long list of new skins and features that I plan to add over time.

New Widgets

A large number of new widgets have been added. Only a handfull widgets remain before I consider WonderGUI to have a complete set of the fundamentals and therefore ready for general usage (first non-alpha/beta release).

  • Knob - A simple widget which controls a value that you change by pressing and dragging up- and down. Combine it with a SpinMeterSkin, PieMeterSkin or FrameMeterSkin to make it look like a turning knob of your choice.

  • Slider - A normal slider, vertical or horizontal, with a handle that you drag to change its value.

  • RangeSlider - A slider, vertical or horizontal, with two handles so you can set a range.

  • Timer - A simple widget which shows a countdown or similar using whichever MeterSkin you prefer.

  • SelectBox - A simple SelectBox-widget, displaying a string and providing a pulldown menu from which to select a value. A bit primitive at the moment, can’t be controlled by keyboard and can’t have a scrollbar in the list.

  • PianoKeyboard - A quite sophisticated widget for displaying a row of pressable piano keys. Keys can somewhat overlap for a nice 3D effect and number and order of keys can be specified.

  • SideCanvas - This is a utility widget used by other widgets when they need to display content outside their own geometry. Used by SelectBox to display the menu. Not meant to be used directly.

  • CanvasStack - A sophisticated widget for enabling widgets to draw in separate layers which are then blended together. Would need a complete article on its own, but allows for some really neat graphics effects.

  • DesignLayer - This widget is just in its embryonic state, but is intended to be a tool for introspection and manipulation of the widgets in real-time. Will be gradually improved over the next several releases until it becomes useful.

In additon to this, the AnimPlayer widget has received a large refactory, utilizing the same CAnimFrames component as FrameMeterSkin. Also, the RefreshButton widget has been removed since it wasn’t really used anymore and had fallen behind in its design. Future improvements to Skins will make it completely redundant.

Error handling

A system for catching and handling errors has been implemented. It doesn’t rely on exceptions or return values, but a user-specified callback that can do anything you want (like throw an exception, assert or just log the error). Specific information about the error including an error code, severity rating, human readable explanation and file, line and method where it occurred is provided.

So far error-handling has been added to a few key areas, but several hundred more are needed to make WonderGUI a truly robust library. The goal is of course that no programmer mistake should result in confusing crashes inside WonderGUI at a later point if it can be detected. This might never be reached, but it is a worthy goal nevertheless. A catch-rate of 90-95% would still be awesome and is definitely doable over time.

Other improvements

A large amount of improvements and bugfixes have been done all over the place. Here is a list of the most noteworthy ones:

  • Introspection - This release includes some very basic introspection support in that you can now see not only the class name of any wg::Object, but also iterate up through its class hierarchy.

  • Text system MU-ified - The text system now uses the MU-coordinate system just like the widgets instead of pixels as before.

  • TextStyle rewrite - The TextStyle class turned out to have a lot of issues, both in logic and implementation. A full rewrite was necessary. The new one is simplified - more coherent, lightweight and easier to understand.

  • Backup fonts - A font can now specify a backup font which will be used for any glyphs missing in this font.

  • Dataset - A template class that can be used to turn any arbitrary struct or object into a reference counted wg::Object.

  • Baggage - Widgets and Surfaces can now carry “Baggage”, that is a pointer to any kind of wg::Object you like. The intended use is to allow you to attach meta data to your widgets and surfaces, suggestedly in the form of a Dataset or Blob. This removes the need for a separate hashmap with metadata.

So, what’s next?

My immediate focus will be on a graphics device for Apple’s Metal API, since I have a contract to develop it. Support for the next-gen graphics accelerators (Vulkan, DirectX and Metal) is very important for WonderGUI’s future and Metal will be the first one to be implemented.

Besides this there are three areas I would like to put effort into:

  • More widgets - Without a complete set of the fundamental widgets, WonderGUI is only useful to a subset of its potential userbase. At least three widgets needs to be added (TableList, Menubar and Tablist) and some need to be updated or improved in various ways.

  • More skins - I’ve made a list of roughly 40 skins that would be needed to allow for all the designs and effects I have in mind. Today I have 16 of them (the 16 most important ones I would say) and most of them are not yet feature complete.

  • Fully MU-ified framework - Currently the graphics system API (GfxDevices and Surfaces) work with pixels instead MU (measuring units), which causes some unecessary friction and confusion. I want to make it all coherent and easier to use by using MU as the unit everywhere.

As mentioned at the top, I had hoped to make this release the first Beta, but after writing some new skins and widgets it became apparent that staying with pixel coordinates for the Text and Graphics APIs while everything else had been converted to the new MU-coordinates was very awkward, confusing and prone to cause bugs. Some more refactoring (that I previously wasn’t sure would be beneficial) turned out to be necessary. In this release I have converted the Text APIs to use MU, but the Graphics APIs are still on pixels. Until that is done, every WonderGUI release will be labeled Alpha.

I will once again aim for a new release in 3 months, but will not shy away from skipping another release if it turns out to be the right thing to do.