Spark Spinner - Functional and Design Specification



Glossary


scale - the scale of a Spinner is the set of allowed numbers that the value property can take on. The allowed numbers are the multiples of the valueInterval property between the maximum and minimum, and also includes the maximum and minimum. For example, if

  • minimum = -1
  • maximum = 10
  • valueInterval = 3

Then, the scale would be {-1,3,6,9,10}.

value wrapping - When the current value is at the maximum, stepping to the next value will set the current value to the minimum and vice versa.

Summary and Background


This specification describes the proposed new Spinner class which extends Range in Gumbo.

Spinner extends from Range and adds two buttons that allows someone to step the current value through a set of allowed values. NumericStepper will extend from Spinner. The primary motivations for adding this new class were:

  1. To allow more generic display components and more complex behavior than the Halo NumericStepper allowed.
  2. To have NumericStepper adhere to accessibility standards.

By having the more abstract Spinner class, developers can be more flexible with the types of displays allowed. One can imagine having a Spinner controlling tabs or a menu by assigning different values to tabs or menu items. Also, NumericStepper was the only basic component that did not support accessibility. Spinner remedies this problem by allowing NumericStepper to be a spinner with the additional element of a [TextInput].

Usage Scenarios

  • Base class for some Gumbo controls such as NumericStepper.
  • Base class or separate part for custom controls that utilize selection from an ordered set. Use cases include:
    1. Modified NumericStepper with different input/display
    2. Tabbing control (assign tabs to values)
    3. Mobile menu (assign menu items to values)

Detailed Description


Behavior

Spinner controls a value through its two buttons, incrementButton and decrementButton. These buttons use stepSize to increment or decrement the values.

SkinParts

Spinner is composed of two buttons:

  1. incrementButton increases the value by stepSize, if possible, when pressed.
  2. decrementButton decreases the value by stepSize, if possible, when pressed.
Inherited Properties

value, minimum, maximum, valueInterval - See Range.

stepSize - When the step() method is called, whether programmatically or through the buttons, the value must be a multiple of stepSize. However, stepSize must be a multiple of valueInterval unless valueInterval is 0 as in Range.

  • Note: Correct behavior is only implemented for stepSize >= 0.
New Properties

valueWrap - enables or disables value wrapping. The default is false.

Methods

These are the methods to override to customize Spinner's behavior:

  1. roundValue() - To change the rounding calculation.
  2. step() - To change the stepping behavior.
Events

Whenever the value changes, a valueCommit event is dispatched (inherited from Range). Whenever the value changes because of user interaction, a change event is dispatched.

Keyboard Behavior
  • Up increments the value
  • Down decrements the value.


API Description


package spark.components
{

import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;

import mx.events.FlexEvent;
import mx.managers.IFocusManagerComponent;

/**
 *  Dispatched when the value of the Spinner control changes
 *  as a result of user interaction.
 *
 *  @eventType mx.events.Event
 */
[Event(name="change", type="mx.events.Event")]

/**
 *  A Spinner is used to select a value from an
 *  ordered set. It uses two buttons that increase or
 *  decrease the current value based on the current
 *  <code>stepSize</code>.
 *  
 *  <p>This control extends the Range class and
 *  is the base class for controls that select a value
 *  from an ordered set such as the NumericStepper control.</p>
 * 
 *  <p>A Spinner consists of two required buttons,
 *  one to increase the value and one to decrease the 
 *  value. </p>
 *
 *  <p>Spinner has the addition property of 
 *  <code>valueWrap</code> which enables value wrapping.</p>
 * 
 *  @see spark.components.supportClasses.Range
 *  @see spark.components.NumericStepper
 */
public class Spinner extends Range implements IFocusManagerComponent
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor. 
     */
    public function Spinner():void

    //--------------------------------------------------------------------------
    //
    // SkinParts
    //
    //--------------------------------------------------------------------------
    
    [SkinPart]
    
    /**
     *  <code>incrementButton</code> is a SkinPart that defines 
     *  a button that, when pressed, will cause <code>value</code>
     *  to increment by <code>stepSize</code>.
     */
    public var incrementButton:Button;
    
    [SkinPart]
    
    /**
     *  <code>decrementButton</code> is a SkinPart that defines
     *  a button that, when pressed, will cause <code>value</code>
     *  to decrement by <code>stepSize</code>.
     */
    public var decrementButton:Button;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden properties: UIComponent
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  enabled
    //----------------------------------

    /**
     *  Enable/disable this component. This also enables/disables any of the 
     *  skin parts for this component.
     */
    override public function set enabled(value:Boolean):void;

    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  valueWrap
    //----------------------------------

    /**
     *  <code>valueWrap</code> determines the behavior of stepping 
     *  beyond the maximum or minimum value. If 
     *  <code>valueWrap</code> is true when stepping beyond an 
     *  extreme, it will set <code>value</code> to the opposite
     *  extreme.
     * 
     *  @default false
     */
    public function get valueWrap():Boolean;

    public function set valueWrap(value:Boolean):void;
    
    //--------------------------------------------------------------------------
    //
    // Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function partAdded(partName:String, instance:*):void:

    /**
     *  @private
     */
    override protected function partRemoved(partName:String, instance:*):void;
    
    /**
     *  Make the skins reflect the enabled state of the Spinner.
     */
    protected function enableSkinParts(value:Boolean):void:
    
    /**
     *  @private
     *  Adds complex behavior to step in order to adhere to
     *  multiples of stepSize (including maximum and minimum).
     */
    override public function step(increase:Boolean = true):void;
    
    //--------------------------------------------------------------------------
    // 
    // Event Handlers
    //
    //--------------------------------------------------------------------------
    
    //--------------------------------- 
    // Mouse handlers
    //---------------------------------
   
    /**
     *  Handle a click on the incrementButton. This should
     *  increment <code>value</code> by <code>stepSize</code>.
     */
    protected function incrementButton_buttonDownHandler(event:Event):void;
    
    /**
     *  Handle a click on the decrementButton. This should
     *  decrement <code>value</code> by <code>stepSize</code>.
     */
    protected function decrementButton_buttonDownHandler(event:Event):void;
    
    /**
     *  Handles keyboard input. Up arrow increments. Down arrow
     *  decrements. Home and End keys set the value to maximum
     *  and minimum respectively.
     */
    override protected function keyDownHandler(event:KeyboardEvent):void;
}

}

B Features


none so far

Additional Implementation Details


none

Prototype Work


Prototype of Spinner has shown that it can be a very lightweight base class for NumericStepper and other custom controls.

Compiler Work


none

Web Tier Compiler Impact


none

Flex Feature Dependencies


Spinner depends on Range as its base class.

Backwards Compatibility


Syntax changes

None - New Class

Accessibility


Provides accessibility for NumericStepper and similar controls.

Issues and Recommendations


  1. Should there be more descriptive events? For distinguishing between keyboard and mouse?

You must be logged in to comment.