Guise: Unified UI for Haxe

Haxe is a great platform for future-proofing your work, and with NME it provides a solid tool-chain for cross-platform native development.

Unfortunately, it lacks a real solution for the issue of user interfaces.
That’s why I’ve been building Guise, a UI library for native and non-native user interfaces.

Ideally, Haxe should have a UI system that does the following:

  • Should be able to be dropped in quickly and easily, with little setup code.
  • Allows the use of native controls where desired.
  • Allows the developer to switch to non-native (i.e. drawn) controls when the design requires.
  • Future display libraries should be able to be implemented quickly so that non-native controls are portable.

Guise attempts to solve each of these issues.
Note: Guise is just a working title, if anyone has a better name, comment at the bottom.

Guise is not Haxe 3 ready yet, only 2.10 (although there is a branch being worked on)

Check out the repository here.

Current usage types

Before getting into the details, I’ll show a few examples of Guise using different platforms/styles.
You’ll notice that I’ve only implemented a handful of controls so far, this has been done to keep the codebase flexible while the core architecture is still being finalised.

Graphics API in NME

Graphics API Style

This style uses a flash-type graphics API to draw UI elements to screen.
Skins are written in XML which is interpreted at compile-time (no loading/parsing XML needed).
Transitions between skin states are generated automatically based on the skin (although would probably be customisable in future).

Currently it is using NME, although it can support any number of drawing APIs (and did support CreateJS at one point).

Note: The skin used here is based on Allan Knutson’s Chutzpah style.

Bitmap API in Starling

Bitmap API Style

This style uses a texture-based bitmap API to draw styles on the GPU.
Currently it’s using Starling as it’s underlying display platform, but we anticipate dropping Starling support in favour of Nicolas’ H2D library (when it is a little more mature and supports a few more platforms).

There is also no reason that NME couldn’t support this type of skin, so expect to see that in the future (this would allow use alongside the graphics-type API above).

Note: The skin used here is based on Mani’s UI style.

HTML5 in Chrome

HTML5 Wrapper

We see this wrapper coming in handy when a native app needs to be pushed to the web.
Obviously you’d want to get some CSS in there as well.

I’ve just included here as an image for those on old browsers (sliders are very weird in IE9 btw).

Waxe on Windows

Waxe Wrapper

Waxe is a Haxe wrapper for wxWidgets, a native UI binding library for Windows, OSX and Linux. Unfortunately the project seems to have stalled (Hugh?), but I still believe it’s a good starting point for native UIs (especially for OSX).

The wrapper classes made for Waxe would hopefully provide the base for wrapping a similar solution for mobile, wrapping a library like Basis or MoSync NativeUI (with a set of externs), which would then open up support for iOS, Android and WP7 native controls.

Disclaimer

Whilst I haven’t pushed anything to haxelib yet, I’ll include the information below for anyone who wants to poke around the repository and test it out.

Setup

To use Guise with a native UI wrapper, you’d do something like this (file paths will have to be relative to calling class):

1
2
3
var root = new ComposeRoot();
root.addTraits([WindowTag, StageTag]);
XmlToCode.path("guise/Platforms/Waxe.xml").install(root);

And if you were using Guise with non-native controls, you’d set up like this:

1
2
3
4
var root = new ComposeRoot();
root.addTraits([WindowTag, StageTag]);
XmlToCode.path("guise/Platforms/NME.xml").install(root);
XmlToCode.path("guise/Styles/Chutzpah.xml").install(root);

All of these XML files get turned into classes at compile-time by the XmlToCode macro I built recently.

Adding controls

You can add a Text Button like this:

1
2
3
4
var item:ComposeItem = new ComposeItem();
item.addTraits([new TextButtonTag("Text Button"),
                new BoxPos(0,0,100,30)]);
root.addChild(item);

And a text input:

1
2
3
4
var item:ComposeItem = new ComposeItem();
item.addTraits([new TextInputTag("Type here"),
                new BoxPos(0,0,100,30)]);
root.addChild(item);

The code is exactly the same regardless of the intended platform, just the initial install call changes.

Skinning

The skinning system is very flexible and doesn’t push an anticipated structure on the developer. For example, a TextInput control can be skinned to have no text field, or ten of them, or an icon, or whatever your designer desires.
Each control has states, these are like MouseOver, Inactive or Focused; multiple states can be active at once. Each control also has layers and these layers can take on a different appearance based on which states are active. Each layer can also change it’s size and position based on which states are active (and transitions between these positions will be generated).

Future?

As mentioned above, we’re waiting for a few other haxe libraries to stabalize before integrating them, but once they have been integrated we’ll have all popular platforms covered in one way or another.

Native Layouts

Currently Guise has a few Haxe-based layouts and I intend to expand on this, but sometimes there is no substitute for native layouts. Supporting these would be a matter of providing some sort of NativeLayout class which would read a platform-specific layout file (XIB for iOS/OSX, Layout XML for Android, XAML for windows). The generation of all of these layout files from a common source file is the subject of another research project I’m working on (slowly).

Skin editor

As skinning is done in XML, I will at some point look at the viability of building a visual editing tool. This would use vector based drawing tools which could then be exported as either Graphics skins or Bitmap skins (with scale-9, bitmap fonts, etc).

15 Comments

  1. http://lapinbionic.free.fr/rebeccaminkoff/124.htmlレベッカミンコフ バッグ REBECCA MINKOFF HU15EFCX02 442 FASHION CLASSICS MINI 5 ZIP ショルダーバッグ MIDNIGHT/SILVER【new0624】:1&one

  2. eagerly waiting for your haxe 3 support in guise. I want to use guise with waxe backend on top of haxe 3.

    • Unfortunately December is busier than I’d hoped. It looks like an official release probably won’t come till at least March. If anyone wants to collaborate though I’m happy to open up the process a bit.

  3. Martin Petersen

    October 1, 2013 at 11:51 am

    Any word on the Haxe3 port?

    • I have begun, but I stopped as many of the supporting libraries weren’t completely Haxe 3 compatible yet. I did get iOS controls working in the Haxe 3 branch (using BasisApple).

      I might get a chance in December to look into Guise again.

  4. Is there any documentation?

    I had a look at Git repo, but there seems to be no documentation there, nor link to one, nor any obvious demo code. This is most likely because I am bad at navigating other people’s code repositories.

    With a quick look through the source folders, there seems to be no obvious folder that contains a list of Objects that relate to the components in the library. But then, Git confuses me, there’s no easy way to search for “Window” or “Popup” or “Panel”…

    At the moment I can’t even tell whether this library does what I want (basic windowing support), let alone how to use it if it does.

    • Hi Dewi,
      There’s currently no documentation or any demo code.
      It’s really not at a point where it can be used in production yet.

      I will be adding more information soon, but for the time being this is all I can offer.

      Controls get added to apps using the classes/enums contained in the / src / guise / controls / ControlTags.hx file.

      These classes don’t actually define much of the functionality, they only describe the API available to project code. Control code gets added onto items based on the Platform / Skin.

  5. This is so awesome.

  6. Hi,
    To bad it uses xml. It should be optional, like Mad Components.

    • Using XML is optional.

      These calls are using an entirely unrelated library to generate a haxe class and then I’m calling the static ‘install’ method on that class:

      XmlToCode.path(“guise/Styles/Chutzpah.xml”).install(root);

      If you’d prefer to write your styles in haxe code (or convert some other serialised language into haxe code), you’re more than welcome to do it.

  7. Great work, however I think it’s a big mistake to think that generating UIs and layouts at compile time is better than runtime. Parsing a bit of XML to determine layout is easily within the capabilities of all modern platforms. The bottleneck is usually development, especially on multiple platforms, and being able to (at runtime) update your UI layout across multiple devices massively speeds up this process.

    Please consider not forcing the UI layout to be built at compile time, but to be generated and updated at runtime.

    • Why not be able to choose compile time or runtime for building the UI
      It is possible thx to the macros

      Nice work Tom! I did not try it yet, but clearly Haxe lacks a unified UI set

    • @Dion – The compile-time XML reading is currently just for converting the platform/skin XML into a class (which can be used at any time while running). The controls still get added and arranged at runtime (in code).

      I still believe there is room for the native XML layout formats used in most platforms (they can do their own peculiar optimisations based on the platform’s strengths, which a completely haxe based solution can’t). The trick is to find a way to unify these proprietary XML formats into one solution (which I don’t have a good answer for yet).

      @lexa – Thanks for the props.

  8. Great to see!

    Regarding the future of Haxe, this has been discussed some days ago:
    https://groups.google.com/d/topic/haxelang/Zjovd-gx9V8/discussion

    Keep it up!

    – Cambiata

Leave a Reply

Your email address will not be published.

*

© 2017 Thomas Byrne

Theme by Anders NorenUp ↑