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

scaffold.libs_as.starling.display.Button.as Maven / Gradle / Ivy

// =================================================================================================
//
//	Starling Framework
//	Copyright 2011-2015 Gamua. 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 starling.display
{
    import flash.geom.Rectangle;
    import flash.ui.Mouse;
    import flash.ui.MouseCursor;

    import starling.events.Event;
    import starling.events.Touch;
    import starling.events.TouchEvent;
    import starling.events.TouchPhase;
    import starling.text.TextField;
    import starling.text.TextFormat;
    import starling.textures.Texture;
    import starling.utils.RectangleUtil;

    /** Dispatched when the user triggers the button. Bubbles. */
    [Event(name="triggered", type="starling.events.Event")]
    
    /** A simple button composed of an image and, optionally, text.
     *  
     *  

You can use different textures for various states of the button. If you're providing * only an up state, the button is simply scaled a little when it is touched.

* *

In addition, you can overlay text on the button. To customize the text, you can use * properties equivalent to those of the TextField class. Move the text to a certain position * by updating the textBounds property.

* *

To react on touches on a button, there is special Event.TRIGGERED event. * Use this event instead of normal touch events. That way, users can cancel button * activation by moving the mouse/finger away from the button before releasing.

*/ public class Button extends DisplayObjectContainer { private static const MAX_DRAG_DIST:Number = 50; private var _upState:Texture; private var _downState:Texture; private var _overState:Texture; private var _disabledState:Texture; private var _contents:Sprite; private var _body:Image; private var _textField:TextField; private var _textBounds:Rectangle; private var _overlay:Sprite; private var _scaleWhenDown:Number; private var _scaleWhenOver:Number; private var _alphaWhenDown:Number; private var _alphaWhenDisabled:Number; private var _useHandCursor:Boolean; private var _enabled:Boolean; private var _state:String; private var _triggerBounds:Rectangle; /** Creates a button with a set of state-textures and (optionally) some text. * Any state that is left 'null' will display the up-state texture. Beware that all * state textures should have the same dimensions. */ public function Button(upState:Texture, text:String="", downState:Texture=null, overState:Texture=null, disabledState:Texture=null) { if (upState == null) throw new ArgumentError("Texture 'upState' cannot be null"); _upState = upState; _downState = downState; _overState = overState; _disabledState = disabledState; _state = ButtonState.UP; _body = new Image(upState); _scaleWhenDown = downState ? 1.0 : 0.9; _scaleWhenOver = _alphaWhenDown = 1.0; _alphaWhenDisabled = disabledState ? 1.0: 0.5; _enabled = true; _useHandCursor = true; _textBounds = new Rectangle(0, 0, _body.width, _body.height); _triggerBounds = new Rectangle(); _contents = new Sprite(); _contents.addChild(_body); addChild(_contents); addEventListener(TouchEvent.TOUCH, onTouch); this.touchGroup = true; this.text = text; } /** @inheritDoc */ public override function dispose():void { // text field might be disconnected from parent, so we have to dispose it manually if (_textField) _textField.dispose(); super.dispose(); } /** Readjusts the dimensions of the button according to its current state texture. * Call this method to synchronize button and texture size after assigning a texture * with a different size. */ public function readjustSize():void { var prevWidth:Number = _body.width; var prevHeight:Number = _body.height; _body.readjustSize(); var scaleX:Number = _body.width / prevWidth; var scaleY:Number = _body.height / prevHeight; _textBounds.x *= scaleX; _textBounds.y *= scaleY; _textBounds.width *= scaleX; _textBounds.height *= scaleY; if (_textField) createTextField(); } private function createTextField():void { if (_textField == null) { _textField = new TextField(_textBounds.width, _textBounds.height); _textField.touchable = false; _textField.autoScale = true; _textField.batchable = true; } _textField.width = _textBounds.width; _textField.height = _textBounds.height; _textField.x = _textBounds.x; _textField.y = _textBounds.y; } private function onTouch(event:TouchEvent):void { Mouse.cursor = (_useHandCursor && _enabled && event.interactsWith(this)) ? MouseCursor.BUTTON : MouseCursor.AUTO; var touch:Touch = event.getTouch(this); var isWithinBounds:Boolean; if (!_enabled) { return; } else if (touch == null) { state = ButtonState.UP; } else if (touch.phase == TouchPhase.HOVER) { state = ButtonState.OVER; } else if (touch.phase == TouchPhase.BEGAN && _state != ButtonState.DOWN) { _triggerBounds = getBounds(stage, _triggerBounds); _triggerBounds.inflate(MAX_DRAG_DIST, MAX_DRAG_DIST); state = ButtonState.DOWN; } else if (touch.phase == TouchPhase.MOVED) { isWithinBounds = _triggerBounds.contains(touch.globalX, touch.globalY); if (_state == ButtonState.DOWN && !isWithinBounds) { // reset button when finger is moved too far away ... state = ButtonState.UP; } else if (_state == ButtonState.UP && isWithinBounds) { // ... and reactivate when the finger moves back into the bounds. state = ButtonState.DOWN; } } else if (touch.phase == TouchPhase.ENDED && _state == ButtonState.DOWN) { state = ButtonState.UP; if (!touch.cancelled) dispatchEventWith(Event.TRIGGERED, true); } } /** The current state of the button. The corresponding strings are found * in the ButtonState class. */ public function get state():String { return _state; } public function set state(value:String):void { _state = value; _contents.x = _contents.y = 0; _contents.scaleX = _contents.scaleY = _contents.alpha = 1.0; switch (_state) { case ButtonState.DOWN: setStateTexture(_downState); _contents.alpha = _alphaWhenDown; _contents.scaleX = _contents.scaleY = _scaleWhenDown; _contents.x = (1.0 - _scaleWhenDown) / 2.0 * _body.width; _contents.y = (1.0 - _scaleWhenDown) / 2.0 * _body.height; break; case ButtonState.UP: setStateTexture(_upState); break; case ButtonState.OVER: setStateTexture(_overState); _contents.scaleX = _contents.scaleY = _scaleWhenOver; _contents.x = (1.0 - _scaleWhenOver) / 2.0 * _body.width; _contents.y = (1.0 - _scaleWhenOver) / 2.0 * _body.height; break; case ButtonState.DISABLED: setStateTexture(_disabledState); _contents.alpha = _alphaWhenDisabled; break; default: throw new ArgumentError("Invalid button state: " + _state); } } private function setStateTexture(texture:Texture):void { _body.texture = texture ? texture : _upState; } /** The scale factor of the button on touch. Per default, a button without a down state * texture will be made slightly smaller, while a button with a down state texture * remains unscaled. */ public function get scaleWhenDown():Number { return _scaleWhenDown; } public function set scaleWhenDown(value:Number):void { _scaleWhenDown = value; } /** The scale factor of the button while the mouse cursor hovers over it. @default 1.0 */ public function get scaleWhenOver():Number { return _scaleWhenOver; } public function set scaleWhenOver(value:Number):void { _scaleWhenOver = value; } /** The alpha value of the button on touch. @default 1.0 */ public function get alphaWhenDown():Number { return _alphaWhenDown; } public function set alphaWhenDown(value:Number):void { _alphaWhenDown = value; } /** The alpha value of the button when it is disabled. @default 0.5 */ public function get alphaWhenDisabled():Number { return _alphaWhenDisabled; } public function set alphaWhenDisabled(value:Number):void { _alphaWhenDisabled = value; } /** Indicates if the button can be triggered. */ public function get enabled():Boolean { return _enabled; } public function set enabled(value:Boolean):void { if (_enabled != value) { _enabled = value; state = value ? ButtonState.UP : ButtonState.DISABLED; } } /** The text that is displayed on the button. */ public function get text():String { return _textField ? _textField.text : ""; } public function set text(value:String):void { if (value.length == 0) { if (_textField) { _textField.text = value; _textField.removeFromParent(); } } else { createTextField(); _textField.text = value; if (_textField.parent == null) _contents.addChild(_textField); } } /** The format of the button's TextField. */ public function get textFormat():TextFormat { if (_textField == null) createTextField(); return _textField.format; } public function set textFormat(value:TextFormat):void { if (_textField == null) createTextField(); _textField.format = value; } /** The texture that is displayed when the button is not being touched. */ public function get upState():Texture { return _upState; } public function set upState(value:Texture):void { if (value == null) throw new ArgumentError("Texture 'upState' cannot be null"); if (_upState != value) { _upState = value; if ( _state == ButtonState.UP || (_state == ButtonState.DISABLED && _disabledState == null) || (_state == ButtonState.DOWN && _downState == null) || (_state == ButtonState.OVER && _overState == null)) { setStateTexture(value); } } } /** The texture that is displayed while the button is touched. */ public function get downState():Texture { return _downState; } public function set downState(value:Texture):void { if (_downState != value) { _downState = value; if (_state == ButtonState.DOWN) setStateTexture(value); } } /** The texture that is displayed while mouse hovers over the button. */ public function get overState():Texture { return _overState; } public function set overState(value:Texture):void { if (_overState != value) { _overState = value; if (_state == ButtonState.OVER) setStateTexture(value); } } /** The texture that is displayed when the button is disabled. */ public function get disabledState():Texture { return _disabledState; } public function set disabledState(value:Texture):void { if (_disabledState != value) { _disabledState = value; if (_state == ButtonState.DISABLED) setStateTexture(value); } } /** The bounds of the button's TextField. Allows moving the text to a custom position. * CAUTION: not a copy, but the actual object! Text will only update on re-assignment. */ public function get textBounds():Rectangle { return _textBounds; } public function set textBounds(value:Rectangle):void { _textBounds.copyFrom(value); createTextField(); } /** The color of the button's state image. Just like every image object, each pixel's * color is multiplied with this value. @default white */ public function get color():uint { return _body.color; } public function set color(value:uint):void { _body.color = value; } /** The smoothing type used for the button's state image. */ public function get textureSmoothing():String { return _body.textureSmoothing; } public function set textureSmoothing(value:String):void { _body.textureSmoothing = value; } /** The overlay sprite is displayed on top of the button contents. It scales with the * button when pressed. Use it to add additional objects to the button (e.g. an icon). */ public function get overlay():Sprite { if (_overlay == null) _overlay = new Sprite(); _contents.addChild(_overlay); // make sure it's always on top return _overlay; } /** Indicates if the mouse cursor should transform into a hand while it's over the button. * @default true */ public override function get useHandCursor():Boolean { return _useHandCursor; } public override function set useHandCursor(value:Boolean):void { _useHandCursor = value; } /** @private */ override public function set width(value:Number):void { var scaleX:Number = value / _body.width; _body.width = value; _textBounds.x *= scaleX; _textBounds.width *= scaleX; if (_textField) _textField.width = value; } override public function set height(value:Number):void { var scaleY:Number = value / _body.height; _body.height = value; _textBounds.y *= scaleY; _textBounds.height *= scaleY; if (_textField) _textField.height = value; } /** The current scaling grid used for the button's state image. Use this property to create * buttons that resize in a smart way, i.e. with the four corners keeping the same size * and only stretching the center area. * * @see Image#scale9Grid * @default null */ public function get scale9Grid():Rectangle { return _body.scale9Grid; } public function set scale9Grid(value:Rectangle):void { _body.scale9Grid = value; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy