Feathers (formely Foxhole) is a light-weight, skinnable and extensible UI components for mobile and desktop built on the top of Starling framework. Below is a list of available UI controls:

  • Button
    • Appearance may be customized for each touch/mouse state, including up, hover, down, and disabled.
    • Optional toggle/selection behavior. Doubles the number of states.
    • Customizable skins, icons, and label properties for each state, including the ability to specify defaults when some states will not be uniquely skinned.
  • TextInput
    • Uses the operating system’s native input controls for seamless selection and copy/paste behavior.
  • ScrollContainer
    • Provides scrolling for any kind of content.
    • Supports a variety of built-in layouts, plus your own custom layouts.
  • List
    • A scrolling list of items with optional selection.
    • Swappable, customizable, layout algorithms.
    • Layout virtualization for improved performance (creates and reuses renderers only for visible data).
    • Variable item renderer dimensions.
    • Custom item renderers.
    • A robust default item renderer with label, icon, and “accessory” views with all the states that buttons provide.
    • A ListCollection class with data descriptors to support any type of data. Supports Array, Vector, and XMLList out of the box.
  • GroupedList
    • Everything that List provides, plus more.
    • Groups or sections with optional headers and footers.
    • Separate renderer types/factories for headers, footers, and items.
    • Multi-dimensional HierarchicalCollection with data descriptors.
  • ScreenNavigator
    • Use events or signals to trigger navigation between screens (such as game menus).
    • Pass properties into screens, such as a shared settings object or other assets.
    • Specify animated transitions for switching screens.

Sample

package feathers.examples.helloWorld
{
	import feathers.controls.Button;
	import feathers.text.BitmapFontTextFormat;

	import starling.display.Image;
	import starling.display.Sprite;
	import starling.events.Event;
	import starling.text.BitmapFont;
	import starling.textures.Texture;
	import starling.textures.TextureAtlas;

	/**
	 * A very basic example to create a Button with Feathers.
	 */
	public class Main extends Sprite
	{
		/**
		 * This is the XML created by Texture Packer.
		 */
		[Embed(source="/../assets/images/atlas.xml",mimeType="application/octet-stream")]
		public static const ATLAS_XML:Class;

		/**
		 * This is the PNG image created by Texture Packer. It includes the
		 * button skins and the font bitmap created by BMFont.
		 */
		[Embed(source="/../assets/images/atlas.png")]
		public static const ATLAS_IMAGE:Class;

		/**
		 * This is the XML created by BMFont.
		 */
		[Embed(source="/../assets/images/tahoma30.fnt",mimeType="application/octet-stream")]
		public static const FONT_XML:Class;

		/**
		 * When the button is clicked, it's label changes.
		 */
		protected static const LABELS:Vector. = new 
		[
			"Hi. I'm Feathers!",
			"Have a nice day."
		];

		/**
		 * Constructor.
		 */
		public function Main()
		{
			//we'll initialize things after we've been added to the stage
			this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
		}

		/**
		 * The Feathers Button control that we'll be creating.
		 */
		protected var button:Button;

		/**
		 * The texture atlas that contains the button's skins.
		 */
		protected var atlas:TextureAtlas;

		/**
		 * The bitmap font used to display the button's text.
		 */
		protected var font:BitmapFont;

		/**
		 * The index used to pick a label from the LABELS defined above.
		 */
		protected var labelIndex:int = 0;

		/**
		 * Where the magic happens.
		 */
		protected function addedToStageHandler(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);

			//first create the atlas and the font from the assets embedded above
			this.atlas = new TextureAtlas(Texture.fromBitmap(new ATLAS_IMAGE(), false), XML(new ATLAS_XML()));

			//notice that the font's texture comes from the atlas
			this.font = new BitmapFont(this.atlas.getTexture("tahoma30_0"), XML(new FONT_XML()));

			//finally, the Button control is created!
			this.button = new Button();
			this.button.label = "Click Me";

			//if no skin is defined for a specific state, the button will use
			//the default skin. it's usually smart to use the up skin as the
			//default. can be any Starling display object.
			this.button.defaultSkin = new Image(this.atlas.getTexture("button-up-skin"));

			//here's a specific skin for the down state
			this.button.downSkin = new Image(this.atlas.getTexture("button-down-skin"));

			//the button's defaultLabelProperties works similarly to the
			//defaultSkin. Any of the text renderer's properties may be set,
			//but we'll only set the textFormat.
			//The default text renderer is BitmapFontTextRenderer, so we pass in
			//a BitmapFontTextFormat object.
			this.button.defaultLabelProperties.textFormat = new BitmapFontTextFormat(this.font, 30, 0x000000);

			//onRelease is an as3-signal that tells us when the user has tapped
			//the button
			this.button.onRelease.add(button_onRelease);

			this.addChild(this.button);

			//the button will validate on its own before the next render, but
			//we want to position it immediately. tell it to validate now.
			this.button.validate();
			this.button.x = (this.stage.stageWidth - this.button.width) / 2;
			this.button.y = (this.stage.stageHeight - this.button.height) / 2;
		}

		/**
		 * Listener for the Button's onRelease signal.
		 */
		protected function button_onRelease(button:Button):void
		{
			//the button's label is rotated among the values defined above
			this.button.label = LABELS[this.labelIndex];
			this.labelIndex++;
			if(this.labelIndex >= LABELS.length)
			{
				this.labelIndex = 0;
			}
		}
	}
}
UI . URL.