All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.feathers.controls.Button.as Maven / Gradle / Ivy

/*
Feathers
Copyright 2012-2015 Bowler Hat LLC. All Rights Reserved.

This program is free software. You can redistribute and/or modify it in
accordance with the terms of the accompanying license agreement.
*/
package feathers.controls
{
	import feathers.core.FeathersControl;
	import feathers.core.IFeathersControl;
	import feathers.core.IFocusDisplayObject;
	import feathers.core.IStateObserver;
	import feathers.core.ITextBaselineControl;
	import feathers.core.ITextRenderer;
	import feathers.core.IValidating;
	import feathers.core.PropertyProxy;
	import feathers.events.FeathersEventType;
	import feathers.layout.HorizontalAlign;
	import feathers.layout.RelativePosition;
	import feathers.layout.VerticalAlign;
	import feathers.skins.IStyleProvider;
	import feathers.utils.keyboard.KeyToTrigger;
	import feathers.utils.touch.LongPress;

	import flash.geom.Matrix;

	import flash.geom.Point;
	import flash.ui.Keyboard;

	import starling.display.DisplayObject;
	import starling.events.Event;
	import starling.events.KeyboardEvent;
	import starling.rendering.Painter;

	/**
	 * Dispatched when the button is pressed for a long time. The property
	 * isLongPressEnabled must be set to true before
	 * this event will be dispatched.
	 *
	 * 

The following example enables long presses:

* * * button.isLongPressEnabled = true; * button.addEventListener( FeathersEventType.LONG_PRESS, function( event:Event ):void * { * // long press * }); * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
datanull
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @eventType feathers.events.FeathersEventType.LONG_PRESS * @see #isLongPressEnabled * @see #longPressDuration */ [Event(name="longPress",type="starling.events.Event")] /** * A push button control that may be triggered when pressed and released. * *

The following example creates a button, gives it a label and listens * for when the button is triggered:

* * * var button:Button = new Button(); * button.label = "Click Me"; * button.addEventListener( Event.TRIGGERED, button_triggeredHandler ); * this.addChild( button ); * * @see ../../../help/button.html How to use the Feathers Button component */ public class Button extends BasicButton implements IFocusDisplayObject, ITextBaselineControl { /** * @private */ private static const HELPER_POINT:Point = new Point(); /** * The default value added to the styleNameList of the label. * * @see feathers.core.FeathersControl#styleNameList */ public static const DEFAULT_CHILD_STYLE_NAME_LABEL:String = "feathers-button-label"; /** * An alternate style name to use with Button to allow a * theme to give it a more prominent, "call-to-action" style. If a theme * does not provide a style for a call-to-action button, the theme will * automatically fall back to using the default button style. * *

An alternate style name should always be added to a component's * styleNameList before the component is initialized. If * the style name is added later, it will be ignored.

* *

In the following example, the call-to-action style is applied to * a button:

* * * var button:Button = new Button(); * button.styleNameList.add( Button.ALTERNATE_STYLE_NAME_CALL_TO_ACTION_BUTTON ); * this.addChild( button ); * * @see feathers.core.FeathersControl#styleNameList */ public static const ALTERNATE_STYLE_NAME_CALL_TO_ACTION_BUTTON:String = "feathers-call-to-action-button"; /** * An alternate style name to use with Button to allow a * theme to give it a less prominent, "quiet" style. If a theme does not * provide a style for a quiet button, the theme will automatically fall * back to using the default button style. * *

An alternate style name should always be added to a component's * styleNameList before the component is initialized. If * the style name is added later, it will be ignored.

* *

In the following example, the quiet button style is applied to * a button:

* * * var button:Button = new Button(); * button.styleNameList.add( Button.ALTERNATE_STYLE_NAME_QUIET_BUTTON ); * this.addChild( button ); * * @see feathers.core.FeathersControl#styleNameList */ public static const ALTERNATE_STYLE_NAME_QUIET_BUTTON:String = "feathers-quiet-button"; /** * An alternate style name to use with Button to allow a * theme to give it a highly prominent, "danger" style. An example would * be a delete button or some other button that has a destructive action * that cannot be undone if the button is triggered. If a theme does not * provide a style for the danger button, the theme will automatically * fall back to using the default button style. * *

An alternate style name should always be added to a component's * styleNameList before the component is initialized. If * the style name is added later, it will be ignored.

* *

In the following example, the danger button style is applied to * a button:

* * * var button:Button = new Button(); * button.styleNameList.add( Button.ALTERNATE_STYLE_NAME_DANGER_BUTTON ); * this.addChild( button ); * * @see feathers.core.FeathersControl#styleNameList */ public static const ALTERNATE_STYLE_NAME_DANGER_BUTTON:String = "feathers-danger-button"; /** * An alternate style name to use with Button to allow a * theme to give it a "back button" style, perhaps with an arrow * pointing backward. If a theme does not provide a style for a back * button, the theme will automatically fall back to using the default * button skin. * *

An alternate style name should always be added to a component's * styleNameList before the component is initialized. If * the style name is added later, it will be ignored.

* *

In the following example, the back button style is applied to * a button:

* * * var button:Button = new Button(); * button.styleNameList.add( Button.ALTERNATE_STYLE_NAME_BACK_BUTTON ); * this.addChild( button ); * * @see feathers.core.FeathersControl#styleNameList */ public static const ALTERNATE_STYLE_NAME_BACK_BUTTON:String = "feathers-back-button"; /** * An alternate style name to use with Button to allow a * theme to give it a "forward" button style, perhaps with an arrow * pointing forward. If a theme does not provide a style for a forward * button, the theme will automatically fall back to using the default * button style. * *

An alternate style name should always be added to a component's * styleNameList before the component is initialized. If * the style name is added later, it will be ignored.

* *

In the following example, the forward button style is applied to * a button:

* * * var button:Button = new Button(); * button.styleNameList.add( Button.ALTERNATE_STYLE_NAME_FORWARD_BUTTON ); * this.addChild( button ); * * @see feathers.core.FeathersControl#styleNameList */ public static const ALTERNATE_STYLE_NAME_FORWARD_BUTTON:String = "feathers-forward-button"; /** * @private * DEPRECATED: Replaced by feathers.controls.ButtonState.UP. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const STATE_UP:String = "up"; /** * @private * DEPRECATED: Replaced by feathers.controls.ButtonState.DOWN. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const STATE_DOWN:String = "down"; /** * @private * DEPRECATED: Replaced by feathers.controls.ButtonState.HOVER. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const STATE_HOVER:String = "hover"; /** * @private * DEPRECATED: Replaced by feathers.controls.ButtonState.DISABLED. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const STATE_DISABLED:String = "disabled"; /** * @private * DEPRECATED: Replaced by feathers.layout.RelativePosition.TOP. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const ICON_POSITION_TOP:String = "top"; /** * @private * DEPRECATED: Replaced by feathers.layout.RelativePosition.RIGHT. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const ICON_POSITION_RIGHT:String = "right"; /** * @private * DEPRECATED: Replaced by feathers.layout.RelativePosition.BOTTOM. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const ICON_POSITION_BOTTOM:String = "bottom"; /** * @private * DEPRECATED: Replaced by feathers.layout.RelativePosition.LEFT. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const ICON_POSITION_LEFT:String = "left"; /** * @private * DEPRECATED: Replaced by feathers.layout.RelativePosition.MANUAL. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const ICON_POSITION_MANUAL:String = "manual"; /** * @private * DEPRECATED: Replaced by feathers.layout.RelativePosition.LEFT_BASELINE. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const ICON_POSITION_LEFT_BASELINE:String = "leftBaseline"; /** * @private * DEPRECATED: Replaced by feathers.layout.RelativePosition.RIGHT_BASELINE. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const ICON_POSITION_RIGHT_BASELINE:String = "rightBaseline"; /** * @private * DEPRECATED: Replaced by feathers.layout.HorizontalAlign.LEFT. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const HORIZONTAL_ALIGN_LEFT:String = "left"; /** * @private * DEPRECATED: Replaced by feathers.layout.HorizontalAlign.CENTER. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const HORIZONTAL_ALIGN_CENTER:String = "center"; /** * @private * DEPRECATED: Replaced by feathers.layout.HorizontalAlign.RIGHT. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const HORIZONTAL_ALIGN_RIGHT:String = "right"; /** * @private * DEPRECATED: Replaced by feathers.layout.VerticalAlign.TOP. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const VERTICAL_ALIGN_TOP:String = "top"; /** * @private * DEPRECATED: Replaced by feathers.layout.VerticalAlign.MIDDLE. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const VERTICAL_ALIGN_MIDDLE:String = "middle"; /** * @private * DEPRECATED: Replaced by feathers.layout.VerticalAlign.BOTTOM. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const VERTICAL_ALIGN_BOTTOM:String = "bottom"; /** * The default IStyleProvider for all Button * components. * * @default null * @see feathers.core.FeathersControl#styleProvider */ public static var globalStyleProvider:IStyleProvider; /** * Constructor. */ public function Button() { super(); } /** * The value added to the styleNameList of the label text * renderer. This variable is protected so that sub-classes * can customize the label text renderer style name in their * constructors instead of using the default style name defined by * DEFAULT_CHILD_STYLE_NAME_LABEL. * * @see feathers.core.FeathersControl#styleNameList */ protected var labelStyleName:String = DEFAULT_CHILD_STYLE_NAME_LABEL; /** * The text renderer for the button's label. * *

For internal use in subclasses.

* * @see #label * @see #labelFactory * @see #createLabel() */ protected var labelTextRenderer:ITextRenderer; /** * The currently visible icon. The value will be null if * there is no currently visible icon. * *

For internal use in subclasses.

*/ protected var currentIcon:DisplayObject; /** * @private */ override protected function get defaultStyleProvider():IStyleProvider { return Button.globalStyleProvider; } /** * @private */ protected var keyToTrigger:KeyToTrigger; /** * @private */ protected var longPress:LongPress; /** * @private */ protected var _scaleMatrix:Matrix; /** * @private */ protected var _label:String = null; /** * The text displayed on the button. * *

The following example gives the button some label text:

* * * button.label = "Click Me"; * * @default null */ public function get label():String { return this._label; } /** * @private */ public function set label(value:String):void { if(this._label == value) { return; } this._label = value; this.invalidate(INVALIDATION_FLAG_DATA); } /** * @private */ protected var _hasLabelTextRenderer:Boolean = true; /** * Determines if the button's label text renderer is created or not. * Useful for button sub-components that may not display text, like * slider thumbs and tracks, or similar sub-components on scroll bars. * *

The following example removed the label text renderer:

* * * button.hasLabelTextRenderer = false; * * @default true */ public function get hasLabelTextRenderer():Boolean { return this._hasLabelTextRenderer; } /** * @private */ public function set hasLabelTextRenderer(value:Boolean):void { if(this._hasLabelTextRenderer == value) { return; } this._hasLabelTextRenderer = value; this.invalidate(INVALIDATION_FLAG_TEXT_RENDERER); } /** * @private */ protected var _iconPosition:String = RelativePosition.LEFT; [Inspectable(type="String",enumeration="top,right,bottom,left,rightBaseline,leftBaseline,manual")] /** * The location of the icon, relative to the label. * *

The following example positions the icon to the right of the * label:

* * * button.label = "Click Me"; * button.defaultIcon = new Image( texture ); * button.iconPosition = RelativePosition.RIGHT; * * @default feathers.layout.RelativePosition.LEFT * * @see feathers.layout.RelativePosition#TOP * @see feathers.layout.RelativePosition#RIGHT * @see feathers.layout.RelativePosition#BOTTOM * @see feathers.layout.RelativePosition#LEFT * @see feathers.layout.RelativePosition#RIGHT_BASELINE * @see feathers.layout.RelativePosition#LEFT_BASELINE * @see feathers.layout.RelativePosition#MANUAL */ public function get iconPosition():String { return this._iconPosition; } /** * @private */ public function set iconPosition(value:String):void { if(this._iconPosition == value) { return; } this._iconPosition = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _gap:Number = 0; /** * The space, in pixels, between the icon and the label. Applies to * either horizontal or vertical spacing, depending on the value of * iconPosition. * *

If gap is set to Number.POSITIVE_INFINITY, * the label and icon will be positioned as far apart as possible. In * other words, they will be positioned at the edges of the button, * adjusted for padding.

* *

The following example creates a gap of 50 pixels between the label * and the icon:

* * * button.label = "Click Me"; * button.defaultIcon = new Image( texture ); * button.gap = 50; * * @default 0 * * @see #iconPosition * @see #minGap */ public function get gap():Number { return this._gap; } /** * @private */ public function set gap(value:Number):void { if(this._gap == value) { return; } this._gap = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _minGap:Number = 0; /** * If the value of the gap property is * Number.POSITIVE_INFINITY, meaning that the gap will * fill as much space as possible, the final calculated value will not be * smaller than the value of the minGap property. * *

The following example ensures that the gap is never smaller than * 20 pixels:

* * * button.gap = Number.POSITIVE_INFINITY; * button.minGap = 20; * * @default 0 * * @see #gap */ public function get minGap():Number { return this._minGap; } /** * @private */ public function set minGap(value:Number):void { if(this._minGap == value) { return; } this._minGap = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _horizontalAlign:String = HorizontalAlign.CENTER; [Inspectable(type="String",enumeration="left,center,right")] /** * The location where the button's content is aligned horizontally (on * the x-axis). * *

The following example aligns the button's content to the left:

* * * button.horizontalAlign = HorizontalAlign.LEFT; * * @default feathers.layout.HorizontalAlign.CENTER * * @see feathers.layout.HorizontalAlign#LEFT * @see feathers.layout.HorizontalAlign#CENTER * @see feathers.layout.HorizontalAlign#RIGHT */ public function get horizontalAlign():String { return this._horizontalAlign; } /** * @private */ public function set horizontalAlign(value:String):void { if(this._horizontalAlign == value) { return; } this._horizontalAlign = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _verticalAlign:String = VerticalAlign.MIDDLE; [Inspectable(type="String",enumeration="top,middle,bottom")] /** * The location where the button's content is aligned vertically (on * the y-axis). * *

The following example aligns the button's content to the top:

* * * button.verticalAlign = VerticalAlign.TOP; * * @default feathers.layout.VerticalAlign.MIDDLE * * @see feathers.layout.VerticalAlign#TOP * @see feathers.layout.VerticalAlign#MIDDLE * @see feathers.layout.VerticalAlign#BOTTOM */ public function get verticalAlign():String { return _verticalAlign; } /** * @private */ public function set verticalAlign(value:String):void { if(this._verticalAlign == value) { return; } this._verticalAlign = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * Quickly sets all padding properties to the same value. The * padding getter always returns the value of * paddingTop, but the other padding values may be * different. * *

The following example gives the button 20 pixels of padding on all * sides:

* * * button.padding = 20; * * @default 0 * * @see #paddingTop * @see #paddingRight * @see #paddingBottom * @see #paddingLeft */ public function get padding():Number { return this._paddingTop; } /** * @private */ public function set padding(value:Number):void { this.paddingTop = value; this.paddingRight = value; this.paddingBottom = value; this.paddingLeft = value; } /** * @private */ protected var _paddingTop:Number = 0; /** * The minimum space, in pixels, between the button's top edge and the * button's content. * *

The following example gives the button 20 pixels of padding on the * top edge only:

* * * button.paddingTop = 20; * * @default 0 */ public function get paddingTop():Number { return this._paddingTop; } /** * @private */ public function set paddingTop(value:Number):void { if(this._paddingTop == value) { return; } this._paddingTop = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _paddingRight:Number = 0; /** * The minimum space, in pixels, between the button's right edge and the * button's content. * *

The following example gives the button 20 pixels of padding on the * right edge only:

* * * button.paddingRight = 20; * * @default 0 */ public function get paddingRight():Number { return this._paddingRight; } /** * @private */ public function set paddingRight(value:Number):void { if(this._paddingRight == value) { return; } this._paddingRight = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _paddingBottom:Number = 0; /** * The minimum space, in pixels, between the button's bottom edge and * the button's content. * *

The following example gives the button 20 pixels of padding on the * bottom edge only:

* * * button.paddingBottom = 20; * * @default 0 */ public function get paddingBottom():Number { return this._paddingBottom; } /** * @private */ public function set paddingBottom(value:Number):void { if(this._paddingBottom == value) { return; } this._paddingBottom = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _paddingLeft:Number = 0; /** * The minimum space, in pixels, between the button's left edge and the * button's content. * *

The following example gives the button 20 pixels of padding on the * left edge only:

* * * button.paddingLeft = 20; * * @default 0 */ public function get paddingLeft():Number { return this._paddingLeft; } /** * @private */ public function set paddingLeft(value:Number):void { if(this._paddingLeft == value) { return; } this._paddingLeft = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _labelOffsetX:Number = 0; /** * Offsets the x position of the label by a certain number of pixels. * This does not affect the measurement of the button. The button will * measure itself as if the label were not offset from its original * position. * *

The following example offsets the x position of the button's label * by 20 pixels:

* * * button.labelOffsetX = 20; * * @default 0 * * @see #labelOffsetY */ public function get labelOffsetX():Number { return this._labelOffsetX; } /** * @private */ public function set labelOffsetX(value:Number):void { if(this._labelOffsetX == value) { return; } this._labelOffsetX = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _labelOffsetY:Number = 0; /** * Offsets the y position of the label by a certain number of pixels. * This does not affect the measurement of the button. The button will * measure itself as if the label were not offset from its original * position. * *

The following example offsets the y position of the button's label * by 20 pixels:

* * * button.labelOffsetY = 20; * * @default 0 * * @see #labelOffsetX */ public function get labelOffsetY():Number { return this._labelOffsetY; } /** * @private */ public function set labelOffsetY(value:Number):void { if(this._labelOffsetY == value) { return; } this._labelOffsetY = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _iconOffsetX:Number = 0; /** * Offsets the x position of the icon by a certain number of pixels. * This does not affect the measurement of the button. The button will * measure itself as if the icon were not offset from its original * position. * *

The following example offsets the x position of the button's icon * by 20 pixels:

* * * button.iconOffsetX = 20; * * @default 0 * * @see #iconOffsetY */ public function get iconOffsetX():Number { return this._iconOffsetX; } /** * @private */ public function set iconOffsetX(value:Number):void { if(this._iconOffsetX == value) { return; } this._iconOffsetX = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _iconOffsetY:Number = 0; /** * Offsets the y position of the icon by a certain number of pixels. * This does not affect the measurement of the button. The button will * measure itself as if the icon were not offset from its original * position. * *

The following example offsets the y position of the button's icon * by 20 pixels:

* * * button.iconOffsetY = 20; * * @default 0 * * @see #iconOffsetX */ public function get iconOffsetY():Number { return this._iconOffsetY; } /** * @private */ public function set iconOffsetY(value:Number):void { if(this._iconOffsetY == value) { return; } this._iconOffsetY = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _stateToIconFunction:Function; /** * DEPRECATED: Create a feathers.skins.ImageSkin instead, * and pass to the defaultIcon property. * *

DEPRECATION WARNING: This property is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public function get stateToIconFunction():Function { return this._stateToIconFunction; } /** * @private */ public function set stateToIconFunction(value:Function):void { if(this._stateToIconFunction == value) { return; } this._stateToIconFunction = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _stateToLabelPropertiesFunction:Function; /** * DEPRECATED: Call the appropriate function on the text renderer to set * different font styles for each state. * *

DEPRECATION WARNING: This property is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public function get stateToLabelPropertiesFunction():Function { return this._stateToLabelPropertiesFunction; } /** * @private */ public function set stateToLabelPropertiesFunction(value:Function):void { if(this._stateToLabelPropertiesFunction == value) { return; } this._stateToLabelPropertiesFunction = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * The skin used for the button's up state. If null, then * defaultSkin is used instead. * *

This property will be ignored if a function is passed to the * stateToSkinFunction property.

* *

The following example gives the button a skin for the up state:

* * * button.upSkin = new Image( texture ); * * @default null * * @see #defaultSkin * @see #setSkinForState() * @see feathers.controls.ButtonState.UP */ public function get upSkin():DisplayObject { return this.getSkinForState(ButtonState.UP); } /** * @private */ public function set upSkin(value:DisplayObject):void { this.setSkinForState(ButtonState.UP, value); } /** * The skin used for the button's down state. If null, then * defaultSkin is used instead. * *

This property will be ignored if a function is passed to the * stateToSkinFunction property.

* *

The following example gives the button a skin for the down state:

* * * button.downSkin = new Image( texture ); * * @default null * * @see #defaultSkin * @see #setSkinForState() * @see feathers.controls.ButtonState.DOWN */ public function get downSkin():DisplayObject { return this.getSkinForState(ButtonState.DOWN); } /** * @private */ public function set downSkin(value:DisplayObject):void { this.setSkinForState(ButtonState.DOWN, value); } /** * The skin used for the button's hover state. If null, then * defaultSkin is used instead. * *

This property will be ignored if a function is passed to the * stateToSkinFunction property.

* *

The following example gives the button a skin for the hover state:

* * * button.hoverSkin = new Image( texture ); * * @default null * * @see #defaultSkin * @see #setSkinForState() * @see feathers.controls.ButtonState.HOVER */ public function get hoverSkin():DisplayObject { return this.getSkinForState(ButtonState.HOVER); } /** * @private */ public function set hoverSkin(value:DisplayObject):void { this.setSkinForState(ButtonState.HOVER, value); } /** * The skin used for the button's disabled state. If null, * then defaultSkin is used instead. * *

This property will be ignored if a function is passed to the * stateToSkinFunction property.

* *

The following example gives the button a skin for the disabled state:

* * * button.disabledSkin = new Image( texture ); * * @default null * * @see #defaultSkin * @see #setSkinForState() * @see feathers.controls.ButtonState.DISABLED */ public function get disabledSkin():DisplayObject { return this.getSkinForState(ButtonState.DISABLED); } /** * @private */ public function set disabledSkin(value:DisplayObject):void { this.setSkinForState(ButtonState.DISABLED, value); } /** * @private */ protected var _stateToSkinFunction:Function; /** * DEPRECATED: Create a feathers.skins.ImageSkin instead, * and pass to the defaultSkin property. * *

DEPRECATION WARNING: This property is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public function get stateToSkinFunction():Function { return this._stateToSkinFunction; } /** * @private */ public function set stateToSkinFunction(value:Function):void { if(this._stateToSkinFunction == value) { return; } this._stateToSkinFunction = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _labelFactory:Function; /** * A function used to instantiate the button's label text renderer * sub-component. By default, the button will use the global text * renderer factory, FeathersControl.defaultTextRendererFactory(), * to create the label text renderer. The label text renderer must be an * instance of ITextRenderer. To change properties on the * label text renderer, see defaultLabelProperties and the * other "LabelProperties" properties for each button * state. * *

The factory should have the following function signature:

*
function():ITextRenderer
* *

The following example gives the button a custom factory for the * label text renderer:

* * * button.labelFactory = function():ITextRenderer * { * return new TextFieldTextRenderer(); * } * * @default null * * @see feathers.core.ITextRenderer * @see feathers.core.FeathersControl#defaultTextRendererFactory */ public function get labelFactory():Function { return this._labelFactory; } /** * @private */ public function set labelFactory(value:Function):void { if(this._labelFactory == value) { return; } this._labelFactory = value; this.invalidate(INVALIDATION_FLAG_TEXT_RENDERER); } /** * @private */ protected var _customLabelStyleName:String; /** * A style name to add to the button's label text renderer * sub-component. Typically used by a theme to provide different styles * to different buttons. * *

In the following example, a custom label style name is passed to * the button:

* * * button.customLabelStyleName = "my-custom-button-label"; * *

In your theme, you can target this sub-component style name to * provide different styles than the default:

* * * getStyleProviderForClass( BitmapFontTextRenderer ).setFunctionForStyleName( "my-custom-button-label", setCustomButtonLabelStyles ); * * @default null * * @see #DEFAULT_CHILD_STYLE_NAME_LABEL * @see feathers.core.FeathersControl#styleNameList * @see #labelFactory */ public function get customLabelStyleName():String { return this._customLabelStyleName; } /** * @private */ public function set customLabelStyleName(value:String):void { if(this._customLabelStyleName == value) { return; } this._customLabelStyleName = value; this.invalidate(INVALIDATION_FLAG_TEXT_RENDERER); } /** * @private */ protected var _defaultLabelProperties:PropertyProxy; /** * An object that stores properties for the button's label text renderer * when no specific properties are defined for the button's current * state, and the properties will be passed down to the label text * renderer when the button validates. The available properties depend * on which ITextRenderer implementation is returned by * labelFactory. Refer to * feathers.core.ITextRenderer * for a list of available text renderer implementations. * *

The following example gives the button default label properties to * use for all states when no specific label properties are available * (this example assumes that the label text renderer is a * BitmapFontTextRenderer):

* * * button.defaultLabelProperties.textFormat = new BitmapFontTextFormat( bitmapFont ); * button.defaultLabelProperties.wordWrap = true; * * @default null * * @see feathers.core.ITextRenderer */ public function get defaultLabelProperties():Object { if(this._defaultLabelProperties === null) { this._defaultLabelProperties = new PropertyProxy(childProperties_onChange); } return this._defaultLabelProperties; } /** * @private */ public function set defaultLabelProperties(value:Object):void { if(!(value is PropertyProxy)) { value = PropertyProxy.fromObject(value); } if(this._defaultLabelProperties !== null) { this._defaultLabelProperties.removeOnChangeCallback(childProperties_onChange); } this._defaultLabelProperties = PropertyProxy(value); if(this._defaultLabelProperties !== null) { this._defaultLabelProperties.addOnChangeCallback(childProperties_onChange); } this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _stateToLabelProperties:Object = {}; /** * DEPRECATED: Use the appropriate API on the label text renderer to set * font styles for a particular state. * *

DEPRECATION WARNING: This property is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public function get upLabelProperties():Object { var value:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.UP]); if(!value) { value = new PropertyProxy(childProperties_onChange); this._stateToLabelProperties[ButtonState.UP] = value; } return value; } /** * @private */ public function set upLabelProperties(value:Object):void { if(!(value is PropertyProxy)) { value = PropertyProxy.fromObject(value); } var oldValue:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.UP]); if(oldValue) { oldValue.removeOnChangeCallback(childProperties_onChange); } this._stateToLabelProperties[ButtonState.UP] = value; if(value) { PropertyProxy(value).addOnChangeCallback(childProperties_onChange); } this.invalidate(INVALIDATION_FLAG_STYLES); } /** * DEPRECATED: Use the appropriate API on the label text renderer to set * font styles for a particular state. * *

DEPRECATION WARNING: This property is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public function get downLabelProperties():Object { var value:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.DOWN]); if(!value) { value = new PropertyProxy(childProperties_onChange); this._stateToLabelProperties[ButtonState.DOWN] = value; } return value; } /** * @private */ public function set downLabelProperties(value:Object):void { if(!(value is PropertyProxy)) { value = PropertyProxy.fromObject(value); } var oldValue:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.DOWN]); if(oldValue) { oldValue.removeOnChangeCallback(childProperties_onChange); } this._stateToLabelProperties[ButtonState.DOWN] = value; if(value) { PropertyProxy(value).addOnChangeCallback(childProperties_onChange); } this.invalidate(INVALIDATION_FLAG_STYLES); } /** * DEPRECATED: Use the appropriate API on the label text renderer to set * font styles for a particular state. * *

DEPRECATION WARNING: This property is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public function get hoverLabelProperties():Object { var value:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.HOVER]); if(!value) { value = new PropertyProxy(childProperties_onChange); this._stateToLabelProperties[ButtonState.HOVER] = value; } return value; } /** * @private */ public function set hoverLabelProperties(value:Object):void { if(!(value is PropertyProxy)) { value = PropertyProxy.fromObject(value); } var oldValue:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.HOVER]); if(oldValue) { oldValue.removeOnChangeCallback(childProperties_onChange); } this._stateToLabelProperties[ButtonState.HOVER] = value; if(value) { PropertyProxy(value).addOnChangeCallback(childProperties_onChange); } this.invalidate(INVALIDATION_FLAG_STYLES); } /** * DEPRECATED: Use the appropriate API on the label text renderer to set * font styles for a particular state. * *

DEPRECATION WARNING: This property is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public function get disabledLabelProperties():Object { var value:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.DISABLED]); if(!value) { value = new PropertyProxy(childProperties_onChange); this._stateToLabelProperties[ButtonState.DISABLED] = value; } return value; } /** * @private */ public function set disabledLabelProperties(value:Object):void { if(!(value is PropertyProxy)) { value = PropertyProxy.fromObject(value); } var oldValue:PropertyProxy = PropertyProxy(this._stateToLabelProperties[ButtonState.DISABLED]); if(oldValue) { oldValue.removeOnChangeCallback(childProperties_onChange); } this._stateToLabelProperties[ButtonState.DISABLED] = value; if(value) { PropertyProxy(value).addOnChangeCallback(childProperties_onChange); } this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _defaultIcon:DisplayObject; /** * The icon used when no other icon is defined for the current state. * Intended to be used when multiple states should share the same icon. * *

This property will be ignored if a function is passed to the * stateToIconFunction property.

* *

The following example gives the button a default icon to use for * all states when no specific icon is available:

* * * button.defaultIcon = new Image( texture ); * * @default null * * @see #setIconForState() */ public function get defaultIcon():DisplayObject { return this._defaultIcon; } /** * @private */ public function set defaultIcon(value:DisplayObject):void { if(this._defaultIcon === value) { return; } this._defaultIcon = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _stateToIcon:Object = {}; /** * The icon used for the button's up state. If null, then * defaultIcon is used instead. * *

This property will be ignored if a function is passed to the * stateToIconFunction property.

* *

The following example gives the button an icon for the up state:

* * * button.upIcon = new Image( texture ); * * @default null * * @see #defaultIcon * @see #setIconForState() * @see feathers.controls.ButtonState.UP */ public function get upIcon():DisplayObject { return this.getIconForState(ButtonState.UP); } /** * @private */ public function set upIcon(value:DisplayObject):void { return this.setIconForState(ButtonState.UP, value); } /** * The icon used for the button's down state. If null, then * defaultIcon is used instead. * *

This property will be ignored if a function is passed to the * stateToIconFunction property.

* *

The following example gives the button an icon for the down state:

* * * button.downIcon = new Image( texture ); * * @default null * * @see #defaultIcon * @see #setIconForState() * @see feathers.controls.ButtonState.DOWN */ public function get downIcon():DisplayObject { return this.getIconForState(ButtonState.DOWN); } /** * @private */ public function set downIcon(value:DisplayObject):void { return this.setIconForState(ButtonState.DOWN, value); } /** * The icon used for the button's hover state. If null, then * defaultIcon is used instead. * *

This property will be ignored if a function is passed to the * stateToIconFunction property.

* *

The following example gives the button an icon for the hover state:

* * * button.hoverIcon = new Image( texture ); * * @default null * * @see #defaultIcon * @see #setIconForState() * @see feathers.controls.ButtonState.HOVER */ public function get hoverIcon():DisplayObject { return this.getIconForState(ButtonState.HOVER); } /** * @private */ public function set hoverIcon(value:DisplayObject):void { return this.setIconForState(ButtonState.HOVER, value); } /** * The icon used for the button's disabled state. If null, then * defaultIcon is used instead. * *

This property will be ignored if a function is passed to the * stateToIconFunction property.

* *

The following example gives the button an icon for the disabled state:

* * * button.disabledIcon = new Image( texture ); * * @default null * * @see #defaultIcon * @see #setIconForState() * @see feathers.controls.ButtonState.DISABLED */ public function get disabledIcon():DisplayObject { return this.getIconForState(ButtonState.DISABLED); } /** * @private */ public function set disabledIcon(value:DisplayObject):void { return this.setIconForState(ButtonState.DISABLED, value); } /** * @private */ protected var _longPressDuration:Number = 0.5; /** * The duration, in seconds, of a long press. * *

The following example changes the long press duration to one full second:

* * * button.longPressDuration = 1.0; * * @default 0.5 * * @see #event:longPress * @see #isLongPressEnabled */ public function get longPressDuration():Number { return this._longPressDuration; } /** * @private */ public function set longPressDuration(value:Number):void { if(this._longPressDuration === value) { return; } this._longPressDuration = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _isLongPressEnabled:Boolean = false; /** * Determines if FeathersEventType.LONG_PRESS will be * dispatched. * *

The following example enables long presses:

* * * button.isLongPressEnabled = true; * button.addEventListener( FeathersEventType.LONG_PRESS, function( event:Event ):void * { * // long press * }); * * @default false * * @see #event:longPress * @see #longPressDuration */ public function get isLongPressEnabled():Boolean { return this._isLongPressEnabled; } /** * @private */ public function set isLongPressEnabled(value:Boolean):void { if(this._isLongPressEnabled === value) { return; } this._isLongPressEnabled = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _scaleWhenDown:Number = 1; /** * The button renders at this scale in the down state. * *

The following example scales the button in the down state:

* * * button.scaleWhenDown = 0.9; * * @default 1 */ public function get scaleWhenDown():Number { return this._scaleWhenDown; } /** * @private */ public function set scaleWhenDown(value:Number):void { this._scaleWhenDown = value; } /** * @private */ protected var _scaleWhenHovering:Number = 1; /** * The button renders at this scale in the hover state. * *

The following example scales the button in the hover state:

* * * button.scaleWhenHovering = 0.9; * * @default 1 */ public function get scaleWhenHovering():Number { return this._scaleWhenHovering; } /** * @private */ public function set scaleWhenHovering(value:Number):void { this._scaleWhenHovering = value; } /** * @inheritDoc */ public function get baseline():Number { if(!this.labelTextRenderer) { return this.scaledActualHeight; } return this.scaleY * (this.labelTextRenderer.y + this.labelTextRenderer.baseline); } /** * @private */ protected var _ignoreIconResizes:Boolean = false; /** * @private */ override public function render(painter:Painter):void { var scale:Number = 1; if(this._currentState === ButtonState.DOWN) { scale = this._scaleWhenDown; } else if(this._currentState === ButtonState.HOVER) { scale = this._scaleWhenHovering; } if(scale !== 1) { if(this._scaleMatrix === null) { this._scaleMatrix = new Matrix(); } else { this._scaleMatrix.identity(); } this._scaleMatrix.translate(Math.round((1 - scale) / 2 * this.actualWidth), Math.round((1 - scale) / 2 * this.actualHeight)); this._scaleMatrix.scale(scale, scale); painter.state.transformModelviewMatrix(this._scaleMatrix); } super.render(painter); } /** * @private */ override public function dispose():void { //we don't dispose it if the button is the parent because it'll //already get disposed in super.dispose() if(this._defaultIcon !== null && this._defaultIcon.parent !== this) { this._defaultIcon.dispose(); } for(var state:String in this._stateToIcon) { var icon:DisplayObject = this._stateToIcon[state] as DisplayObject; if(icon !== null && icon.parent !== this) { icon.dispose(); } } super.dispose(); } /** * Gets the icon to be used by the button when its * currentState property matches the specified state value. * *

If a icon is not defined for a specific state, returns * null.

* * @see #setIconForState() */ public function getIconForState(state:String):DisplayObject { return this._stateToIcon[state] as DisplayObject; } /** * Sets the icon to be used by the button when its * currentState property matches the specified state value. * *

If an icon is not defined for a specific state, the value of the * defaultIcon property will be used instead.

* * @see #defaultIcon * @see #getIconForState() * @see feathers.controls.ButtonState */ public function setIconForState(state:String, icon:DisplayObject):void { if(icon !== null) { this._stateToIcon[state] = icon; } else { delete this._stateToIcon[state]; } this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ override protected function initialize():void { super.initialize(); if(!this.keyToTrigger) { this.keyToTrigger = new KeyToTrigger(this); } if(!this.longPress) { this.longPress = new LongPress(this); this.longPress.tapToTrigger = this.tapToTrigger; } } /** * @private */ override protected function draw():void { var dataInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_DATA); var stylesInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_STYLES); var sizeInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SIZE); var stateInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_STATE); var textRendererInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_TEXT_RENDERER); var focusInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_FOCUS); if(textRendererInvalid) { this.createLabel(); } if(textRendererInvalid || stateInvalid || dataInvalid) { this.refreshLabel(); } if(stylesInvalid || stateInvalid) { this.longPress.isEnabled = this._isEnabled && this._isLongPressEnabled; this.longPress.longPressDuration = this._longPressDuration; this.keyToTrigger.isEnabled = this._isEnabled; this.refreshIcon(); } if(textRendererInvalid || stylesInvalid || stateInvalid) { this.refreshLabelStyles(); } super.draw(); if(textRendererInvalid || stylesInvalid || stateInvalid || dataInvalid || sizeInvalid) { this.layoutContent(); } if(sizeInvalid || focusInvalid) { this.refreshFocusIndicator(); } } /** * @private */ override protected function autoSizeIfNeeded():Boolean { var needsWidth:Boolean = this._explicitWidth !== this._explicitWidth; //isNaN var needsHeight:Boolean = this._explicitHeight !== this._explicitHeight; //isNaN var needsMinWidth:Boolean = this._explicitMinWidth !== this._explicitMinWidth; //isNaN var needsMinHeight:Boolean = this._explicitMinHeight !== this._explicitMinHeight; //isNaN if(!needsWidth && !needsHeight && !needsMinWidth && !needsMinHeight) { return false; } var labelRenderer:ITextRenderer = null; if(this._label !== null && this.labelTextRenderer) { labelRenderer = this.labelTextRenderer; this.refreshMaxLabelSize(true); this.labelTextRenderer.measureText(HELPER_POINT); } var adjustedGap:Number = this._gap; if(adjustedGap === Number.POSITIVE_INFINITY) { adjustedGap = this._minGap; } if(this.currentIcon is IValidating) { IValidating(this.currentIcon).validate(); } if(this.currentSkin is IValidating) { IValidating(this.currentSkin).validate(); } var newMinWidth:Number = this._explicitMinWidth; if(needsMinWidth) { if(labelRenderer) { newMinWidth = HELPER_POINT.x; } else { newMinWidth = 0; } if(this.currentIcon) { if(labelRenderer) //both label and icon { if(this._iconPosition !== RelativePosition.TOP && this._iconPosition !== RelativePosition.BOTTOM && this._iconPosition !== RelativePosition.MANUAL) { newMinWidth += adjustedGap; if(this.currentIcon is IFeathersControl) { newMinWidth += IFeathersControl(this.currentIcon).minWidth; } else { newMinWidth += this.currentIcon.width; } } else //top, bottom, or manual { if(this.currentIcon is IFeathersControl) { var iconMinWidth:Number = IFeathersControl(this.currentIcon).minWidth; if(iconMinWidth > newMinWidth) { newMinWidth = iconMinWidth; } } else if(this.currentIcon.width > newMinWidth) { newMinWidth = this.currentIcon.width; } } } else //no label { if(this.currentIcon is IFeathersControl) { newMinWidth = IFeathersControl(this.currentIcon).minWidth; } else { newMinWidth = this.currentIcon.width; } } } newMinWidth += this._paddingLeft + this._paddingRight; if(this.currentSkin is IFeathersControl) { var skinMinWidth:Number = IFeathersControl(this.currentSkin).minWidth; if(skinMinWidth > newMinWidth) { newMinWidth = skinMinWidth; } } else if(this._originalSkinWidth === this._originalSkinWidth && //!isNaN this._originalSkinWidth > newMinWidth) { newMinWidth = this._originalSkinWidth; } } var newMinHeight:Number = this._explicitMinHeight; if(needsMinHeight) { if(labelRenderer) { newMinHeight = HELPER_POINT.y; } else { newMinHeight = 0; } if(this.currentIcon) { if(labelRenderer) //both label and icon { if(this._iconPosition === RelativePosition.TOP || this._iconPosition === RelativePosition.BOTTOM) { newMinHeight += adjustedGap; if(this.currentIcon is IFeathersControl) { newMinHeight += IFeathersControl(this.currentIcon).minHeight; } else { newMinHeight += this.currentIcon.height; } } else //left, right, manual { if(this.currentIcon is IFeathersControl) { var iconMinHeight:Number = IFeathersControl(this.currentIcon).minHeight; if(iconMinHeight > newMinHeight) { newMinHeight = iconMinHeight; } } else if(this.currentIcon.height > newMinHeight) { newMinHeight = this.currentIcon.height; } } } else //no label { if(this.currentIcon is IFeathersControl) { newMinHeight = IFeathersControl(this.currentIcon).minHeight; } else { newMinHeight = this.currentIcon.height; } } } newMinHeight += this._paddingTop + this._paddingBottom; if(this.currentSkin is IFeathersControl) { var skinMinHeight:Number = IFeathersControl(this.currentSkin).minHeight; if(skinMinHeight > newMinHeight) { newMinHeight = skinMinHeight; } } else if(this._originalSkinHeight === this._originalSkinHeight && //!isNaN this._originalSkinHeight > newMinHeight) { newMinHeight = this._originalSkinHeight; } } var newWidth:Number = this._explicitWidth; if(needsWidth) { if(labelRenderer) { newWidth = HELPER_POINT.x; } else { newWidth = 0; } if(this.currentIcon) { if(labelRenderer) //both label and icon { if(this._iconPosition !== RelativePosition.TOP && this._iconPosition !== RelativePosition.BOTTOM && this._iconPosition !== RelativePosition.MANUAL) { newWidth += adjustedGap + this.currentIcon.width; } else if(this.currentIcon.width > newWidth) //top, bottom, or manual { newWidth = this.currentIcon.width; } } else //no label { newWidth = this.currentIcon.width; } } newWidth += this._paddingLeft + this._paddingRight; if(this._originalSkinWidth === this._originalSkinWidth && //!isNaN this._originalSkinWidth > newWidth) { newWidth = this._originalSkinWidth; } } var newHeight:Number = this._explicitHeight; if(needsHeight) { if(labelRenderer) { newHeight = HELPER_POINT.y; } else { newHeight = 0; } if(this.currentIcon) { if(labelRenderer) //both label and icon { if(this._iconPosition === RelativePosition.TOP || this._iconPosition === RelativePosition.BOTTOM) { newHeight += adjustedGap + this.currentIcon.height; } else if(this.currentIcon.height > newHeight) //left, right, manual { newHeight = this.currentIcon.height; } } else //no label { newHeight = this.currentIcon.height; } } newHeight += this._paddingTop + this._paddingBottom; if(this._originalSkinHeight === this._originalSkinHeight && //!isNaN this._originalSkinHeight > newHeight) { newHeight = this._originalSkinHeight; } } return this.saveMeasurements(newWidth, newHeight, newMinWidth, newMinHeight); } /** * @private */ override protected function changeState(state:String):void { var oldState:String = this._currentState; if(oldState === state) { return; } super.changeState(state); if(this._scaleWhenHovering !== 1 && (state === ButtonState.HOVER || oldState === ButtonState.HOVER)) { this.setRequiresRedraw(); } else if(this._scaleWhenDown !== 1 && (state === ButtonState.DOWN || oldState === ButtonState.DOWN)) { this.setRequiresRedraw(); } } /** * Creates the label text renderer sub-component and * removes the old instance, if one exists. * *

Meant for internal use, and subclasses may override this function * with a custom implementation.

* * @see #labelTextRenderer * @see #labelFactory */ protected function createLabel():void { if(this.labelTextRenderer) { this.removeChild(DisplayObject(this.labelTextRenderer), true); this.labelTextRenderer = null; } if(this._hasLabelTextRenderer) { var factory:Function = this._labelFactory != null ? this._labelFactory : FeathersControl.defaultTextRendererFactory; this.labelTextRenderer = ITextRenderer(factory()); var labelStyleName:String = this._customLabelStyleName != null ? this._customLabelStyleName : this.labelStyleName; this.labelTextRenderer.styleNameList.add(labelStyleName); if(this.labelTextRenderer is IStateObserver) { IStateObserver(this.labelTextRenderer).stateContext = this; } this.addChild(DisplayObject(this.labelTextRenderer)); } } /** * @private */ protected function refreshLabel():void { if(!this.labelTextRenderer) { return; } this.labelTextRenderer.text = this._label; this.labelTextRenderer.visible = this._label !== null && this._label.length > 0; this.labelTextRenderer.isEnabled = this._isEnabled; } /** * Sets the currentIcon property. * *

For internal use in subclasses.

*/ protected function refreshIcon():void { var oldIcon:DisplayObject = this.currentIcon; this.currentIcon = this.getCurrentIcon(); if(this.currentIcon is IFeathersControl) { IFeathersControl(this.currentIcon).isEnabled = this._isEnabled; } if(this.currentIcon !== oldIcon) { if(oldIcon) { if(oldIcon is IFeathersControl) { IFeathersControl(oldIcon).removeEventListener(FeathersEventType.RESIZE, currentIcon_resizeHandler); } if(oldIcon is IStateObserver) { IStateObserver(oldIcon).stateContext = null; } this.removeChild(oldIcon, false); } if(this.currentIcon) { if(this.currentIcon is IStateObserver) { IStateObserver(this.currentIcon).stateContext = this; } //we want the icon to appear below the label text renderer var index:int = this.numChildren; if(this.labelTextRenderer) { index = this.getChildIndex(DisplayObject(this.labelTextRenderer)); } this.addChildAt(this.currentIcon, index); if(this.currentIcon is IFeathersControl) { IFeathersControl(this.currentIcon).addEventListener(FeathersEventType.RESIZE, currentIcon_resizeHandler); } } } } /** * @private */ override protected function getCurrentSkin():DisplayObject { if(this._stateToSkinFunction !== null) { return DisplayObject(this._stateToSkinFunction(this, this._currentState, this.currentSkin)); } return super.getCurrentSkin(); } /** * @private */ protected function getCurrentIcon():DisplayObject { if(this._stateToIconFunction !== null) { return DisplayObject(this._stateToIconFunction(this, this._currentState, this.currentIcon)); } var result:DisplayObject = this._stateToIcon[this._currentState] as DisplayObject; if(result !== null) { return result; } return this._defaultIcon; } /** * @private */ protected function refreshLabelStyles():void { if(!this.labelTextRenderer) { return; } var properties:Object = this.getCurrentLabelProperties(); for(var propertyName:String in properties) { var propertyValue:Object = properties[propertyName]; this.labelTextRenderer[propertyName] = propertyValue; } } /** * @private */ protected function getCurrentLabelProperties():Object { if(this._stateToLabelPropertiesFunction !== null) { return this._stateToLabelPropertiesFunction(this, this._currentState); } var result:Object = this._stateToLabelProperties[this._currentState]; if(result !== null) { return result; } return this._defaultLabelProperties; } /** * Positions and sizes the button's content. * *

For internal use in subclasses.

*/ protected function layoutContent():void { var oldIgnoreIconResizes:Boolean = this._ignoreIconResizes; this._ignoreIconResizes = true; this.refreshMaxLabelSize(false); var labelRenderer:DisplayObject = null; if(this._label !== null && this.labelTextRenderer) { this.labelTextRenderer.validate(); labelRenderer = DisplayObject(this.labelTextRenderer); } var iconIsInLayout:Boolean = this.currentIcon && this._iconPosition != RelativePosition.MANUAL; if(labelRenderer && iconIsInLayout) { this.positionSingleChild(labelRenderer); this.positionLabelAndIcon(); } else if(labelRenderer) { this.positionSingleChild(labelRenderer); } else if(iconIsInLayout) { this.positionSingleChild(this.currentIcon); } if(this.currentIcon) { if(this._iconPosition == RelativePosition.MANUAL) { this.currentIcon.x = this._paddingLeft; this.currentIcon.y = this._paddingTop; } this.currentIcon.x += this._iconOffsetX; this.currentIcon.y += this._iconOffsetY; } if(labelRenderer) { this.labelTextRenderer.x += this._labelOffsetX; this.labelTextRenderer.y += this._labelOffsetY; } this._ignoreIconResizes = oldIgnoreIconResizes; } /** * @private */ protected function refreshMaxLabelSize(forMeasurement:Boolean):void { if(this.currentIcon is IValidating) { IValidating(this.currentIcon).validate(); } var calculatedWidth:Number = this.actualWidth; var calculatedHeight:Number = this.actualHeight; if(forMeasurement) { calculatedWidth = this._explicitWidth; if(calculatedWidth !== calculatedWidth) //isNaN { calculatedWidth = this._maxWidth; } calculatedHeight = this._explicitHeight; if(calculatedHeight !== calculatedHeight) //isNaN { calculatedHeight = this._maxHeight; } } if(this._label != null && this.labelTextRenderer) { this.labelTextRenderer.maxWidth = calculatedWidth - this._paddingLeft - this._paddingRight; this.labelTextRenderer.maxHeight = calculatedHeight - this._paddingTop - this._paddingBottom; if(this.currentIcon) { var adjustedGap:Number = this._gap; if(adjustedGap == Number.POSITIVE_INFINITY) { adjustedGap = this._minGap; } if(this._iconPosition == RelativePosition.LEFT || this._iconPosition == RelativePosition.LEFT_BASELINE || this._iconPosition == RelativePosition.RIGHT || this._iconPosition == RelativePosition.RIGHT_BASELINE) { this.labelTextRenderer.maxWidth -= (this.currentIcon.width + adjustedGap); } if(this._iconPosition == RelativePosition.TOP || this._iconPosition == RelativePosition.BOTTOM) { this.labelTextRenderer.maxHeight -= (this.currentIcon.height + adjustedGap); } } } } /** * @private */ protected function positionSingleChild(displayObject:DisplayObject):void { if(this._horizontalAlign == HorizontalAlign.LEFT) { displayObject.x = this._paddingLeft; } else if(this._horizontalAlign == HorizontalAlign.RIGHT) { displayObject.x = this.actualWidth - this._paddingRight - displayObject.width; } else //center { displayObject.x = this._paddingLeft + Math.round((this.actualWidth - this._paddingLeft - this._paddingRight - displayObject.width) / 2); } if(this._verticalAlign == VerticalAlign.TOP) { displayObject.y = this._paddingTop; } else if(this._verticalAlign == VerticalAlign.BOTTOM) { displayObject.y = this.actualHeight - this._paddingBottom - displayObject.height; } else //middle { displayObject.y = this._paddingTop + Math.round((this.actualHeight - this._paddingTop - this._paddingBottom - displayObject.height) / 2); } } /** * @private */ protected function positionLabelAndIcon():void { if(this._iconPosition == RelativePosition.TOP) { if(this._gap == Number.POSITIVE_INFINITY) { this.currentIcon.y = this._paddingTop; this.labelTextRenderer.y = this.actualHeight - this._paddingBottom - this.labelTextRenderer.height; } else { if(this._verticalAlign == VerticalAlign.TOP) { this.labelTextRenderer.y += this.currentIcon.height + this._gap; } else if(this._verticalAlign == VerticalAlign.MIDDLE) { this.labelTextRenderer.y += Math.round((this.currentIcon.height + this._gap) / 2); } this.currentIcon.y = this.labelTextRenderer.y - this.currentIcon.height - this._gap; } } else if(this._iconPosition == RelativePosition.RIGHT || this._iconPosition == RelativePosition.RIGHT_BASELINE) { if(this._gap == Number.POSITIVE_INFINITY) { this.labelTextRenderer.x = this._paddingLeft; this.currentIcon.x = this.actualWidth - this._paddingRight - this.currentIcon.width; } else { if(this._horizontalAlign == HorizontalAlign.RIGHT) { this.labelTextRenderer.x -= this.currentIcon.width + this._gap; } else if(this._horizontalAlign == HorizontalAlign.CENTER) { this.labelTextRenderer.x -= Math.round((this.currentIcon.width + this._gap) / 2); } this.currentIcon.x = this.labelTextRenderer.x + this.labelTextRenderer.width + this._gap; } } else if(this._iconPosition == RelativePosition.BOTTOM) { if(this._gap == Number.POSITIVE_INFINITY) { this.labelTextRenderer.y = this._paddingTop; this.currentIcon.y = this.actualHeight - this._paddingBottom - this.currentIcon.height; } else { if(this._verticalAlign == VerticalAlign.BOTTOM) { this.labelTextRenderer.y -= this.currentIcon.height + this._gap; } else if(this._verticalAlign == VerticalAlign.MIDDLE) { this.labelTextRenderer.y -= Math.round((this.currentIcon.height + this._gap) / 2); } this.currentIcon.y = this.labelTextRenderer.y + this.labelTextRenderer.height + this._gap; } } else if(this._iconPosition == RelativePosition.LEFT || this._iconPosition == RelativePosition.LEFT_BASELINE) { if(this._gap == Number.POSITIVE_INFINITY) { this.currentIcon.x = this._paddingLeft; this.labelTextRenderer.x = this.actualWidth - this._paddingRight - this.labelTextRenderer.width; } else { if(this._horizontalAlign == HorizontalAlign.LEFT) { this.labelTextRenderer.x += this._gap + this.currentIcon.width; } else if(this._horizontalAlign == HorizontalAlign.CENTER) { this.labelTextRenderer.x += Math.round((this._gap + this.currentIcon.width) / 2); } this.currentIcon.x = this.labelTextRenderer.x - this._gap - this.currentIcon.width; } } if(this._iconPosition == RelativePosition.LEFT || this._iconPosition == RelativePosition.RIGHT) { if(this._verticalAlign == VerticalAlign.TOP) { this.currentIcon.y = this._paddingTop; } else if(this._verticalAlign == VerticalAlign.BOTTOM) { this.currentIcon.y = this.actualHeight - this._paddingBottom - this.currentIcon.height; } else { this.currentIcon.y = this._paddingTop + Math.round((this.actualHeight - this._paddingTop - this._paddingBottom - this.currentIcon.height) / 2); } } else if(this._iconPosition == RelativePosition.LEFT_BASELINE || this._iconPosition == RelativePosition.RIGHT_BASELINE) { this.currentIcon.y = this.labelTextRenderer.y + (this.labelTextRenderer.baseline) - this.currentIcon.height; } else //top or bottom { if(this._horizontalAlign == HorizontalAlign.LEFT) { this.currentIcon.x = this._paddingLeft; } else if(this._horizontalAlign == HorizontalAlign.RIGHT) { this.currentIcon.x = this.actualWidth - this._paddingRight - this.currentIcon.width; } else { this.currentIcon.x = this._paddingLeft + Math.round((this.actualWidth - this._paddingLeft - this._paddingRight - this.currentIcon.width) / 2); } } } /** * @private */ protected function childProperties_onChange(proxy:PropertyProxy, name:Object):void { this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ override protected function focusInHandler(event:Event):void { super.focusInHandler(event); this.stage.addEventListener(KeyboardEvent.KEY_DOWN, stage_keyDownHandler); this.stage.addEventListener(KeyboardEvent.KEY_UP, stage_keyUpHandler); } /** * @private */ override protected function focusOutHandler(event:Event):void { super.focusOutHandler(event); this.stage.removeEventListener(KeyboardEvent.KEY_DOWN, stage_keyDownHandler); this.stage.removeEventListener(KeyboardEvent.KEY_UP, stage_keyUpHandler); if(this.touchPointID >= 0) { this.touchPointID = -1; if(this._isEnabled) { this.changeState(ButtonState.UP); } else { this.changeState(ButtonState.DISABLED); } } } /** * @private */ protected function stage_keyDownHandler(event:KeyboardEvent):void { if(event.keyCode === Keyboard.ESCAPE) { this.touchPointID = -1; this.changeState(ButtonState.UP); } if(this.touchPointID >= 0 || event.keyCode !== Keyboard.SPACE) { return; } this.touchPointID = int.MAX_VALUE; this.changeState(ButtonState.DOWN); } /** * @private */ protected function stage_keyUpHandler(event:KeyboardEvent):void { if(this.touchPointID !== int.MAX_VALUE || event.keyCode !== Keyboard.SPACE) { return; } this.resetTouchState(); } /** * @private */ protected function currentIcon_resizeHandler():void { if(this._ignoreIconResizes) { return; } this.invalidate(INVALIDATION_FLAG_SIZE); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy