// Copyright 2007. Adobe Systems Incorporated. All Rights Reserved. package fl.controls { import fl.controls.BaseButton; import fl.controls.TextInput; //Only for ASDocs import fl.core.InvalidationType; import fl.core.UIComponent; import fl.events.ComponentEvent; import fl.managers.IFocusManagerComponent; import flash.display.DisplayObject; import flash.events.Event; import flash.events.FocusEvent; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.events.TextEvent; import flash.ui.Keyboard; //-------------------------------------- // Styles //-------------------------------------- /** * The class that provides the skin for the down arrow when it is disabled. * * @default NumericStepperDownArrow_disabledSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="downArrowDisabledSkin", type="Class")] /** * The class that provides the skin for the down arrow when it is in a down state. * * @default NumericStepperDownArrow_downSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="downArrowDownSkin", type="Class")] /** * The class that provides the skin for the down arrow when the mouse is over the component. * * @default NumericStepperDownArrow_overSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="downArrowOverSkin", type="Class")] /** * The class that provides the skin for the down arrow when it is in its default state. * * @default NumericStepperDownArrow_upSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="downArrowUpSkin", type="Class")] /** * The class that provides the skin for the up arrow when it is disabled. * * @default NumericStepperUpArrow_disabledSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="upArrowDisabledSkin", type="Class")] /** * The class that provides the skin for the up arrow when it is in the down state. * * @default NumericStepperUpArrow_downSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="upArrowDownSkin", type="Class")] /** * The class that provides the skin for the down arrow during mouse over. * * @default NumericStepperUpArrow_overSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="upArrowOverSkin", type="Class")] /** * The class that provides the skin for the up arrow when it is in the up state. * * @default NumericStepperUpArrow_upSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="upArrowUpSkin", type="Class")] /** * The class that provides the skin for the text input box. * * @default NumericStepper_upSkin * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="TextInput_upskin", type="Class")] /** * The skin used for the up arrow when it is in an up state. * * @default NumericStepper_disabledSkin * * @internal [kenos] Is this description correct? Most of the skins are provides by classes and this looks * more like some of the width or height specifiers. The style name also doesn't seem to * match the description. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="TextInput_disabledSkin", type="Number", format="Length")] /** * @copy fl.controls.BaseButton#style:repeatDelay * * @default 500 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="repeatDelay", type="Number", format="Time")] /** * @copy fl.controls.BaseButton#style:repeatInterval * * @default 35 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="repeatInterval", type="Number", format="Time")] /** * @copy fl.controls.LabelButton#style:embedFonts * * @default false * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Style(name="embedFonts", type="Boolean")] //-------------------------------------- // Events //-------------------------------------- /** * Dispatched when the user changes the value of the NumericStepper component. * *

Note: This event is not dispatched if ActionScript * is used to change the value.

* * @eventType flash.events.Event.CHANGE * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ [Event(name="change", type="flash.events.Event")] //-------------------------------------- // Class description //-------------------------------------- /** * The NumericStepper component displays an ordered set of numbers from which * the user can make a selection. This component includes a single-line field * for text input and a pair of arrow buttons that can be used to step through * the set of values. The Up and Down arrow keys can also be used to view the * set of values. The NumericStepper component dispatches a change * event after there is a change in its current value. This component also contains * the value property; you can use this property to obtain the current * value of the component. * * @includeExample examples/NumericStepperExample.as * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public class NumericStepper extends UIComponent implements IFocusManagerComponent { /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var inputField:TextInput; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var upArrow:BaseButton; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var downArrow:BaseButton; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var _maximum:Number = 10; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var _minimum:Number = 0; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var _value:Number = 1; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var _stepSize:Number = 1; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected var _precision:Number; /** * Creates a new NumericStepper component instance. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function NumericStepper() { super(); setStyles(); stepSize = _stepSize; } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ private static var defaultStyles:Object = { downArrowDisabledSkin:"NumericStepperDownArrow_disabledSkin", downArrowDownSkin:"NumericStepperDownArrow_downSkin", downArrowOverSkin:"NumericStepperDownArrow_overSkin", downArrowUpSkin:"NumericStepperDownArrow_upSkin", upArrowDisabledSkin:"NumericStepperUpArrow_disabledSkin", upArrowDownSkin:"NumericStepperUpArrow_downSkin", upArrowOverSkin:"NumericStepperUpArrow_overSkin", upArrowUpSkin:"NumericStepperUpArrow_upSkin", upSkin:"TextInput_upSkin", disabledSkin:"TextInput_disabledSkin", focusRect:null, focusRectSkin:null, focusRectPadding:null, repeatDelay:500,repeatInterval:35, embedFonts:false }; /** * @copy fl.core.UIComponent#getStyleDefinition() * * @includeExample ../core/examples/UIComponent.getStyleDefinition.1.as -noswf * * @see fl.core.UIComponent#getStyle() * @see fl.core.UIComponent#setStyle() * @see fl.managers.StyleManager * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public static function getStyleDefinition():Object { return defaultStyles; } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected static const DOWN_ARROW_STYLES:Object = { disabledSkin:"downArrowDisabledSkin", downSkin:"downArrowDownSkin", overSkin:"downArrowOverSkin", upSkin:"downArrowUpSkin", repeatDelay:"repeatDelay", repeatInterval:"repeatInterval" }; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected static const UP_ARROW_STYLES:Object = { disabledSkin:"upArrowDisabledSkin", downSkin:"upArrowDownSkin", overSkin:"upArrowOverSkin", upSkin:"upArrowUpSkin", repeatDelay:"repeatDelay", repeatInterval:"repeatInterval" }; /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected static const TEXT_INPUT_STYLES:Object = { upSkin:"upSkin", disabledSkin:"disabledSkin", textPadding:"textPadding", textFormat:"textFormat", disabledTextFormat:"disabledTextFormat", embedFonts:"embedFonts" }; [Inspectable(defaultValue=true)] /** * @copy fl.core.UIComponent#enabled * * @default true * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function get enabled():Boolean { return super.enabled; } /** * @private (setter) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function set enabled(value:Boolean):void { if (value == enabled) { return; } super.enabled = value; upArrow.enabled = downArrow.enabled = inputField.enabled = value; } [Inspectable(defaultValue=10)] /** * Gets or sets the maximum value in the sequence of numeric values. * * @default 10 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get maximum():Number { return _maximum; } /** * @private (setter) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function set maximum(value:Number):void { _maximum = value; if (_value > _maximum) { setValue(_maximum, false); } } [Inspectable(defaultValue=0)] /** * Gets or sets the minimum number in the sequence of numeric values. * * @default 0 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get minimum():Number { return _minimum; } /** * @private (setter) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function set minimum(value:Number):void { _minimum = value; if (_value < _minimum) { setValue(_minimum, false); } } /** * Gets the next value in the sequence of values. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get nextValue():Number { var val:Number = _value + _stepSize; return (inRange(val)) ? val : _value; } /** * Gets the previous value in the sequence of values. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get previousValue():Number { var val:Number = _value - _stepSize; return (inRange(val)) ? val : _value; } [Inspectable(defaultValue=1)] /** * Gets or sets a nonzero number that describes the unit of change between * values. The value property is a multiple of this number * less the minimum. The NumericStepper component rounds the resulting value to the * nearest step size. * * @default 1 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get stepSize():Number { return _stepSize; } /** * @private (setter) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function set stepSize(value:Number):void { _stepSize = value; _precision = getPrecision(); setValue(_value); } [Inspectable(defaultValue=1)] /** * Gets or sets the current value of the NumericStepper component. * * @default 1 * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get value():Number { return _value; } /** * @private (setter) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function set value(value:Number):void { setValue(value, false); } /** * Gets a reference to the TextInput component that the NumericStepper * component contains. Use this property to access and manipulate the * underlying TextInput component. For example, you can use this * property to change the current selection in the text box or to * restrict the characters that the text box accepts. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get textField():TextInput { return inputField; } /** * @copy fl.controls.TextArea#imeMode * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function get imeMode():String { return inputField.imeMode; } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ public function set imeMode(value:String):void { inputField.imeMode = value; } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function configUI():void { super.configUI(); upArrow = new BaseButton(); copyStylesToChild(upArrow, UP_ARROW_STYLES); upArrow.autoRepeat = true; upArrow.setSize(21, 12); upArrow.focusEnabled = false; addChild(upArrow); downArrow = new BaseButton(); copyStylesToChild(downArrow, DOWN_ARROW_STYLES); downArrow.autoRepeat = true; downArrow.setSize(21, 12); downArrow.focusEnabled = false; addChild(downArrow); inputField = new TextInput(); copyStylesToChild(inputField, TEXT_INPUT_STYLES); inputField.restrict = "0-9\\-\\.\\,"; inputField.text = _value.toString(); inputField.setSize(21, 24); inputField.focusTarget = this as IFocusManagerComponent; inputField.focusEnabled = false; inputField.addEventListener(FocusEvent.FOCUS_IN, passEvent); inputField.addEventListener(FocusEvent.FOCUS_OUT, passEvent); addChild(inputField); inputField.addEventListener(Event.CHANGE, onTextChange, false, 0, true); upArrow.addEventListener(ComponentEvent.BUTTON_DOWN, stepperPressHandler, false, 0, true); downArrow.addEventListener(ComponentEvent.BUTTON_DOWN, stepperPressHandler, false, 0, true); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function setValue(value:Number, fireEvent:Boolean=true):void { if (value == _value) { return; } var oldVal:Number = _value; _value = getValidValue(value); inputField.text = _value.toString(); if (fireEvent) { dispatchEvent(new Event(Event.CHANGE, true)); } } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function keyDownHandler(event:KeyboardEvent):void { if (!enabled) { return; } event.stopImmediatePropagation(); var val:Number = Number(inputField.text); switch (event.keyCode) { case Keyboard.END: setValue(maximum); break; case Keyboard.HOME: setValue(minimum); break; case Keyboard.UP: setValue(nextValue); break; case Keyboard.DOWN: setValue(previousValue); break; case Keyboard.ENTER: setValue(val); break; } } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function stepperPressHandler(event:ComponentEvent):void { setValue(Number(inputField.text), false); switch (event.currentTarget) { case upArrow: setValue(nextValue); break; case downArrow: setValue(previousValue); } inputField.setFocus(); inputField.textField.setSelection(0,0); } /** * @copy fl.core.UIComponent#drawFocus() * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function drawFocus(event:Boolean):void { super.drawFocus(event); if (event) { var focusPadding:Number = Number(getStyleValue('focusRectPadding')); uiFocusRect.width = width + (focusPadding*2); uiFocusRect.height = height + (focusPadding*2); } } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function focusOutHandler(event:FocusEvent):void { if (event.eventPhase == 3) { setValue(Number(inputField.text)); } super.focusOutHandler(event); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function draw():void { if (isInvalid(InvalidationType.STYLES,InvalidationType.STATE)) { setStyles(); invalidate(InvalidationType.SIZE, false); } if (isInvalid(InvalidationType.SIZE)) { drawLayout(); } if (isFocused && focusManager.showFocusIndicator) { drawFocus(true); } validate(); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function drawLayout():void { var w:Number = width - upArrow.width; var h:Number = height / 2; inputField.setSize(w, height); upArrow.height = h; downArrow.height = Math.floor(h); downArrow.move(w, h); upArrow.move(w, 0); downArrow.drawNow(); upArrow.drawNow(); inputField.drawNow(); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function onTextChange(event:Event):void { event.stopImmediatePropagation(); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function passEvent(event:Event):void { dispatchEvent(event); } /** * Sets focus to the component instance. * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override public function setFocus():void { if(stage) { stage.focus = inputField.textField; } } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ override protected function isOurFocus(target:DisplayObject):Boolean { return target == inputField || super.isOurFocus(target); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function setStyles():void { copyStylesToChild(downArrow, DOWN_ARROW_STYLES); copyStylesToChild(upArrow, UP_ARROW_STYLES); copyStylesToChild(inputField, TEXT_INPUT_STYLES); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function inRange(num:Number):Boolean { return (num >= _minimum && num <= _maximum); } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function inStep(num:Number):Boolean { return (num - _minimum) % _stepSize == 0; } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function getValidValue(num:Number):Number { if (isNaN(num)) { return _value; } var closest:Number = Number((_stepSize * Math.round(num / _stepSize)).toFixed(_precision)); if (closest > maximum) { return maximum; } else if (closest < minimum) { return minimum; } else { return closest } } /** * @private (protected) * * @langversion 3.0 * @playerversion Flash 9.0.28.0 */ protected function getPrecision():Number { var s:String = _stepSize.toString(); if (s.indexOf('.') == -1) { return 0; } return s.split('.').pop().length; } } }