Feathers UI
  • Docs
  • API
  • Showcase
  • Blog
  • Community

›Styles and Skins

Introduction

  • Getting Started
  • Installation
  • Create a new project in…

    • Command line terminal
    • HaxeDevelop
    • Moonshine IDE
    • Visual Studio Code

    Build a project targeting…

    • Android
    • Electron
    • HashLink VM
    • iOS
    • Linux
    • macOS
    • Neko VM
    • Web
    • Windows
  • Introduction to OpenFL

UI Components

  • Intro to UI components
  • Alert
  • Application
  • AssetLoader
  • Button
  • ButtonBar
  • Callout
  • Check
  • ComboBox
  • DatePicker
  • HDividedBox / VDividedBox
  • Drawer
  • Form / FormItem
  • GridView
  • GroupListView
  • Header
  • HierarchicalItemRenderer
  • ItemRenderer
  • Label
  • LayoutGroup
  • LayoutGroupItemRenderer
  • ListView
  • NumericStepper
  • PageIndicator
  • PageNavigator
  • Panel
  • PopUpDatePicker
  • PopUpListView
  • HProgressBar / VProgressBar
  • Radio
  • RouterNavigator
  • HScrollBar / VScrollBar
  • ScrollContainer
  • HSlider / VSlider
  • StackNavigator
  • TabBar
  • TabNavigator
  • TextArea
  • TextCallout
  • TextInput
  • ToggleButton
  • ToggleSwitch
  • TreeGridView
  • TreeView

Layouts

  • Intro to Layouts
  • AnchorLayout
  • FlowRowsLayout
  • HorizontalLayout
  • HorizontalListLayout
  • HorizontalDistributedLayout
  • ResponsiveGridLayout
  • TiledRowsLayout
  • TiledRowsListLayout
  • PagedTiledRowsListLayout
  • VerticalLayout
  • VerticalListFixedRowLayout
  • VerticalListLayout
  • VerticalDistributedLayout
  • Layout Data
  • Custom layouts

Styles and Skins

  • Intro to skins
  • Common shape skins
  • Custom programmatic skins
  • Intro to themes
  • Create a custom theme

Animation

  • Navigator animated transitions
  • Custom navigator transitions

Custom UI Components

  • Custom UI components
  • Component lifecycle
  • Custom item renderers
  • Class-based item renderers

Miscellaneous

  • CLI commands
  • Collections
  • Focus management
  • haxedef options
  • Displaying pop-ups
  • Semantic versioning
  • Tool-tips
  • Cookbook
  • Install Prerelease Builds
Edit

Create a custom Feathers UI theme

Feathers UI provides a system for styling all UI components in the same project by packaging all of the skins and styling code into single unit, called a theme. Many projects will a require custom look and feel that conveys a certain mood or integrates with established branding guidelines. The best way to add these styling requirements to a project is to create a custom theme.

The theme class

To start building a new theme from scratch, create a subclass of ClassVariantTheme. This base class makes it easy to register a function that sets styles on a particular type of UI component.

package com.example;

import feathers.themes.ClassVariantTheme;

class CustomTheme extends ClassVariantTheme {
    public function new() {
        super();

        initialize();
    }

    private function initialize():Void {

    }
}

Set UI component styles

Typically, a theme will define a number of functions to style different types of UI components. For example, the following function might be used to set the default styles for all Button components.

private function setButtonStyles(button:Button):Void {
    var backgroundSkin = new RectangleSkin();
    backgroundSkin.border = SolidColor(1.0, 0xff0000);
    backgroundSkin.fill = SolidColor(0xffffff);
    backgroundSkin.cornerRadius = 10.0;
    button.backgroundSkin = backgroundSkin;

    var downSkin = new RectangleSkin();
    downSkin.border = SolidColor(1.0, 0xcc0000);
    downSkin.fill = SolidColor(0xffeeee);
    downSkin.cornerRadius = 10.0;
    button.setSkinForState(ButtonState.DOWN, downSkin);

    var format = new TextFormat("_sans", 16, 0xff0000);
    button.textFormat = format;

    var downFormat = new TextFormat("_sans", 16, 0xcc0000);
    button.setTextFormatForState(ButtonState.DOWN, downFormat);

    button.paddingTop = 10.0;
    button.paddingBottom = 10.0;
    button.paddingLeft = 20.0;
    button.paddingRight = 20.0;
}

Inside the initialize() method of the theme class, register this function with the theme by adding the following call to setStyleFunction().

styleProvider.setStyleFunction(Button, null, setButtonStyles);

setStyleFunction() accepts three arguments.

  1. The UI component class that should be styled. In this case, it's Button.
  2. An optional variant. We aren't using a variant here, so we pass null.
  3. A function that will receive a UI component instance and set its styles.

Variants

If a project uses the same type of UI component in multiple places, but different instances need different appearances, a variant may be registered for that type of component. For example, a button that performs a destructive action (such as deleting data) might be given a red appearance.

Similar to above, here's another function that styles a Button with fancier styles.

private function setFancyButtonStyles(button:Button):Void {
    var backgroundSkin = new RectangleSkin();
    backgroundSkin.cornerRadius = 10.0;
    backgroundSkin.border = Gradient(2, GradientType.LINEAR, [0xff9999, 0xcc0000], [1.0, 1.0], [0, 255], 90 * Math.PI / 180);
    backgroundSkin.fill = Gradient(GradientType.LINEAR, [0xff9999, 0xff0000], [1.0, 1.0], [0, 255], 90 * Math.PI / 180);
    button.backgroundSkin = backgroundSkin;

    var downSkin = new RectangleSkin();
    downSkin.cornerRadius = 10.0;
    downSkin.border = Gradient(2, GradientType.LINEAR, [0xff0000, 0xcc0000], [1.0, 1.0], [0, 255], 90 * Math.PI / 180);
    downSkin.fill = Gradient(GradientType.LINEAR, [0xff9999, 0xff0000], [1.0, 1.0], [0, 255], 270 * Math.PI / 180);
    button.setSkinForState(ButtonState.DOWN, downSkin);

    var format = new TextFormat("_sans", 20, 0xffeeee, true, true);
    button.textFormat = format;

    button.paddingTop = 10.0;
    button.paddingBottom = 10.0;
    button.paddingLeft = 20.0;
    button.paddingRight = 20.0;
}

The call to setStyleFunction() will look similar, but this time, it should include a variant string.

styleProvider.setStyleFunction(Button, "fancy-button", setFancyButtonStyles);

This same string may be passed to the variant property of an individual UI component.

var button = new Button();
button.variant = "fancy-button";

As a best practice, it's a good idea to define custom variants as constants in the theme class.

public static final VARIANT_FANCY_BUTTON:String = "fancy-button";

Then, use the constant instead of the string value, for better compiler checking.

button.variant = CustomTheme.VARIANT_FANCY_BUTTON;

Related Links

  • Introduction to Feathers UI themes
Last updated on 2/1/2022
← Intro to themesNavigator animated transitions →
  • The theme class
  • Set UI component styles
    • Variants
  • Related Links
Feathers UI
Feathers UI
  • Downloads
  • Showcase
  • Testimonials
  • Premium Support
Documentation
  • Getting Started
  • API Reference
  • Samples
    Github
  • Source Code
  • Issue Tracker
Community
  • Forum
  • Discord
  • Stack Overflow
News & Updates
  • Blog (RSS, Atom)
  • Twitter
Make a Donation
  • Join Github Sponsors
  • Donate with PayPal
  • Buy a T-Shirt
Copyright © 2022 Bowler Hat LLC — Illustrations by unDraw.