Category Archives: Feathers UI

Posts about the open source, cross-platform Feathers UI component library for Haxe and OpenFL (formerly Adobe AIR and Starling).

Feathers UI for Haxe and OpenFL: Now live on Kickstarter

UPDATE: Feathers UI for Haxe and OpenFL is fully funded on Kickstarter!

UPDATE: For the latest news and announcements about alpha/beta preview builds, follow the Feathers UI blog.

About eight years ago, I open sourced the code for what would become Feathers UI. I was spending my days trying to be an indie game developer at the time, and I had recently tried out Daniel Sperl’s excellent Starling library. I could see that if my games switched to Starling, I’d get smoother animations and other performance improvements. For my games, I had already created a basic set of user interface components (buttons, lists, toggle switches, sliders and things like that) that worked on both iPhone and Android. After recreating those UI components in Starling, I decided that others might find them useful for building apps too. Publishing them on Github would change my life for nearly a decade.

Today, the technology landscape has changed a lot compared to 2011, with all sorts of new mobile devices — and web browsers that no longer allow plugins. While Feathers UI was generously sponsored by a company for a number of years, they’ve now moved in different strategic directions that, sadly, won’t include Feathers. Yet, over all this time, Feathers UI has grown and matured well beyond anything that I had ever imagined. Software developers have created so many amazing apps and games, and I am constantly inspired by how they use Feathers in incredible new ways. Certainly, much has changed on the web and in the wider realm of technology, but I believe that Feathers UI still has great value for software developers building creative apps and games.

That’s why I’m launching a Kickstarter for Feathers UI, and I hope that you’ll support this project by becoming a backer. I’m looking to rebuild Feathers UI on a new foundation that will continue to make it easy to build cross-platform user interfaces on mobile, desktop, smart TVs, and even game consoles. This new version of Feathers UI will use the Haxe programming language and the OpenFL library. Developers who are already experienced with Feathers UI will feel right at home with a similar language and familiar APIs, but also new features and access to new platforms.

Support Feathers UI on Kickstarter

Additionally, I’m going to make Feathers UI into a more sustainable business that can fund itself going forward. I’m planning to introduce new premium add-ons that developers can purchase to support Feathers directly. These add-ons will include new advanced components (like charts and graphs), pre-made themes in a variety of styles, and in-depth technical educational content that teaches you the inner workings of Feathers UI. Of course, the core Feathers UI library will remain open source, and it will continue to expand with new UI components and features! These add-ons will be for developers with more specialized needs.

I may have written the code for Feathers UI, but the community gave it life. I hope that you will back the project on Kickstarter and help me re-imagine a modern Feathers UI that takes the best of the original Starling version, combines it with the advantages of Haxe and OpenFL, and makes it better than ever. Keep this excellent UI component and layout library in your toolbox by showing your support on Kickstarter.

A look at the architecture changes in Feathers 3.0.0

Over three years ago, I released Feathers 1.0, targeting Starling 1.3. Today, I release Feathers 3.0 targeting Starling 2. It’s been an amazing experience to work hard and improve an open source project every day with the enthusiastic support of both Adobe and the wonderful Starling community.

As a new major release, Feathers 3.0 gave me the opportunity to re-imagine part of the Feathers architecture, based on feedback from developers who use Feathers in their apps and from my own experiences building new components. Let me point out a few of those architecture changes and the reasons why I made them.

Shared Constants

Way back in 1.0, I should have moved shared constants into their own classes. Instead, with each new version of Feathers, duplicate constants like HORIZONTAL_ALIGN_LEFT, SCROLL_POLICY_ON, and others repeatedly appeared throughout the Feathers codebase. I now realize that a single place to find HorizontalAlign.LEFT and ScrollPolicy.ON would have been better, and this is one of the things I cleaned up in Feathers 3.0.

When I started developing these components, I defined constants on the classes that used them because it seemed very convenient. If you needed to use a constant with the Slider class, you’d find it… on the Slider class! At the time, Feathers didn’t use many subclasses, and it had only a handful of components and layouts. I didn’t fully realize that defining constants like this wouldn’t scale very well as Feathers grew much larger over time.

By the time I started developing Feathers 2.0, I got frustrated as I saw myself duplicating constants in subclasses (so that developers wouldn’t need to know the inheritance hierarchy to find them), and I sometimes forgot to do it when new constants were added to the base classes. It was clear that things were getting a little messy in ways that I did not foresee. However, I worried that making this change would be too disruptive at the time, with the big theme changes that were included in Feathers 2.0, so the constants stayed as-is.

As I started working on Feathers 3.0 this year, I decided that this change finally needed to happen. It would indeed be disruptive, but the duplication and its side effects were getting out of hand. Using shared constant classes like VerticalAlign, RelativePosition, and Direction would be way easier for me to maintain going forward with a smaller learning curve and fewer bugs. I really wish I had made this change three years ago, but if I had waited for everything to be perfect, 1.0 would never have been released.

I’ve done my best to ease the pain of this migration. The old constants still exist, and they will not be removed until at least 18 months from now or until the next major version (whichever takes longer). Take your time switching over, and don’t feel like it must happen immediately when you upgrade. Be sure to try out the regular expressions in the Feathers 3.0 Migration Guide. You can use them with your editor’s Find/Replace feature to quickly swap out the old constants with the new. I used them on the example themes, and it was so much faster than doing the replacements manually.

saveMeasurements()

When a Feathers component’s width or height is not set explicitly, it needs to calculate appropriate dimensions during validation. Usually, this calculation is based on the dimensions of its skins and sub-components. Custom component developers will be familiar with the old setSizeInternal() method that was used to commit the calculated dimensions. This method has been deprecated and replaced with one named saveMeasurements() that accepts width and height the same as before, but also minimum dimensions as well.

Previously, the minWidth and minHeight properties defaulted to 0, and you could change them manually. However, in many layouts, the minimum dimensions may be used as a fallback. For instance, in a VerticalLayout where percentWidth is specified on children, their minWidth values of those children may be used as a fallback when the parent container’s width is not set. In previous versions, 0 would be used, which wasn’t always ideal.

Now, all core Feathers components calculate their minWidth and minHeight when needed. Custom component developers are encouraged to do the same.

As a bonus, this change helped me discover me some places where I could optimize Feathers by avoiding validation when it wasn’t necessary. This leaves Feathers in a better place for new, more advanced components that may be coming in future versions.

feathers-compat

As Feathers evolves, some APIs are inevitably deprecated and, eventually, removed. For instance, Feathers 3.0 includes a new class named ImageSkin that replaces an “advanced” class named SmartDisplayObjectValueSelector that was more cumbersome to use. Both optimize skinning by reusing the same display object with multiple textures, but ImageSKin does it in a better way.

It would be better if developers did not use SmartDisplayObjectValueSelector anymore, and I’d like to remove it from Feathers. However, existing code doesn’t rewrite itself, so developers may want to continue using this class for a while and still benefit from the bug fixes in Feathers 3.0. That’s where feathers-compat comes into play. Classes like SmartDisplayObjectValueSelector can be moved into feathers-compat so that they’re still available, if needed.

If you’re upgrading an app built with an earlier version of Feathers, and you find that some classes are missing, be sure to check if they’re included in feathers-compat.

New components on the way!

Feathers now has a stronger foundation that has been re-enforced with these architecture improvements (not just in Feathers, but in Starling too!). Starting with version 3.1 and beyond, I can start adding new and more advanced components. Stay tuned for news on what I have planned!

Also, thank you again to the community for your support, bug reports, and feedback. With your help, Feathers is better than it ever could have been if I were developing it alone. Happy coding!

Feathers MXML internals: abstracting away Starling initialization

In Starling projects, we need a startup class that extends flash.display.Sprite or flash.display.MovieClip. In this class, we create a starling.core.Starling instance, and we set up behavior for things like resizing the view port and pausing our app or game when it goes into the background. For many projects, this class looks mostly the same. When I create a new project, I usually just copy the startup class from an existing project and modify it to pass in a different Starling root class. It would be ideal if I could simply abstract this bootstrap code away instead.

Flex applications require a significant amount of bootstrapping code too. We don’t deal with any of it, though, because the Flex SDK compiler abstracts much of it away. We can simply create a simple MXML file extending spark.components.Application:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
	xmlns:s="library://ns.adobe.com/flex/spark">
</s:Application>

However, behind the scenes, a Flex SWF starts up with an mx.managers.SystemManager instance as the root display object. The spark.components.Application instance isn’t the root. It’s a child. Once the SWF fully loads and the Flex framework is ready, the SystemManager instantiates the Application and adds it to the display list.

You don’t need to worry about this bootstrapping code in Flex because the spark.components.Application class defines the following metadata:

[Frame(factoryClass="mx.managers.SystemManager")]

As long as you subclass Application this metadata will tell the compiler that your class should be included on the second frame of the SWF, and the class defined in the factoryClass should be the root display object instantiated when the SWF starts up. Once the first frame loads, the SystemManager can display a preloader while the second frame is loading. When the second frame is ready, the SystemManager instantiates the Application and adds it to the display list.

[Frame] metadata isn’t restricted to Flex applications. An ActionScript project built with the Flex SDK compiler may use [Frame] metadata too. In fact, some developers may have already used this metadata with Starling projects to create a preloader for SWFs that run in a web browser.

While it isn’t a strict requirement for supporting MXML in Feathers, I want the new project experience to be as simple Flex’s. We shouldn’t need to manually instantiate Starling and set up code to resize the view port and things. It should be part of some hidden bootstrap code. A new Feathers MXML application should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<feathers:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
	xmlns:feathers="library://ns.feathersui.com/mxml">
</feathers:Application>

The upcoming Feathers MXML SDK will include a feathers.core.Application class that takes advantage of [Frame] metadata.

package feathers.core
{
	import feathers.controls.LayoutGroup;

	[Frame(factoryClass="feathers.core.StarlingBootstrap")]

	public class Application extends LayoutGroup
	{
		public function Application()
		{
			super();
			this.autoSizeMode = LayoutGroup.AUTO_SIZE_MODE_STAGE;
		}
	}
}

All the bootstrapping happens behind the scenes in this feathers.core.StarlingBootstrap class, which serves a similar purpose as the Flex SystemManager. However, instead of initializing the Flex framework, it sets up Starling instead. It passes our subclass of feathers.core.Application to Starling to use as the root class. It listens for the native stage Event.RESIZE to resize the Starling view port and stage. It looks just like any normal startup class for a Starling project. Not much different than Starling’s Scaffold_Mobile sample or the Feathers ComponentsExplorer example.

The main difference between StarlingBootstrap and other startup classes is that StarlingBootstrap must have a method named info(). The compiler generates a subclass of StarlingBootstrap and overrides info() to make it return an object with a number of properties. This object stores things like the name of the Starling root class and, optionally, a Feathers theme. You can see a slightly simplified example of this generated subclass below:

public class _MyFeathersApp_feathers_core_StarlingBootstrap
	extends feathers.core.StarlingBootstrap
{
	public function _MyFeathersApp_feathers_core_StarlingBootstrap()
	{
		super();
	}

	private var _info:Object;

	override public function info():Object
	{
		if (!_info)
		{
			_info = {
				rootClassName: "MyFeathersApp",
				themeClassName: "feathers.themes.MetalWorksDesktopTheme"
			};
		}
		return _info;
	}
}

You can see that our main class was named MyFeathersApp. A string representation is stored in the rootClassName property returned by the info() function. StarlingBootstrap uses getDefinitionByName() to access the Class:

var rootClassName:String = info()["rootClassName"];
var rootClass:Class = Class(getDefinitionByName(rootClassName));

Once it has the Class reference, StarlingBootstrap can pass it to Starling to instantiate when Stage 3D is ready. The compiler will automatically ensure that MyFeathersApp is compiled into the SWF, even though it is not strictly imported here.

Anyone will be able to read the ActionScript code that gets generated by the Feathers MXML SDK compiler. Similar to the Flex SDK, we will be able to add the -keep compiler argument to include a folder of generated ActionScript files in the same place as the compiled SWF.

Additionally, using the StarlingBootstrap class to bootstrap a Feathers MXML application won’t be strictly required. Custom [Frame] metadata may be added to any subclass of feathers.core.Application that will override its default metadata. This will let us provide a different startup experience, if needed. We might want to customize the stage size to support contentScaleFactor, for instance. Ideally, the bootstrapping mechanism should provide acceptable defaults for most projects, while keeping things as flexible as possible for more advanced requirements.