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

scaffold.libs_as.feathers.controls.SpinnerList.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.IValidating;
	import feathers.data.ListCollection;
	import feathers.events.FeathersEventType;
	import feathers.layout.HorizontalAlign;
	import feathers.layout.ILayout;
	import feathers.layout.ISpinnerLayout;
	import feathers.layout.VerticalSpinnerLayout;
	import feathers.skins.IStyleProvider;

	import flash.ui.Keyboard;

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

	/**
	 * A customized List component where scrolling updates the
	 * the selected item. Layouts may loop infinitely.
	 *
	 * 

The following example creates a list, gives it a data provider, tells * the item renderer how to interpret the data, and listens for when the * selection changes:

* * * var list:SpinnerList = new SpinnerList(); * * list.dataProvider = new ListCollection( * [ * { text: "Milk", thumbnail: textureAtlas.getTexture( "milk" ) }, * { text: "Eggs", thumbnail: textureAtlas.getTexture( "eggs" ) }, * { text: "Bread", thumbnail: textureAtlas.getTexture( "bread" ) }, * { text: "Chicken", thumbnail: textureAtlas.getTexture( "chicken" ) }, * ]); * * list.itemRendererFactory = function():IListItemRenderer * { * var renderer:DefaultListItemRenderer = new DefaultListItemRenderer(); * renderer.labelField = "text"; * renderer.iconSourceField = "thumbnail"; * return renderer; * }; * * list.addEventListener( Event.CHANGE, list_changeHandler ); * * this.addChild( list ); * * @see ../../../help/spinner-list.html How to use the Feathers SpinnerList component */ public class SpinnerList extends List { /** * The default IStyleProvider for all SpinnerList * components. * * @default null * @see feathers.core.FeathersControl#styleProvider */ public static var globalStyleProvider:IStyleProvider; /** * Constructor. */ public function SpinnerList() { super(); this._scrollBarDisplayMode = ScrollBarDisplayMode.NONE; this._snapToPages = true; this._snapOnComplete = true; this.decelerationRate = DecelerationRate.FAST; this.addEventListener(Event.TRIGGERED, spinnerList_triggeredHandler); this.addEventListener(FeathersEventType.SCROLL_COMPLETE, spinnerList_scrollCompleteHandler); } /** * @private */ override protected function get defaultStyleProvider():IStyleProvider { if(SpinnerList.globalStyleProvider) { return SpinnerList.globalStyleProvider; } return List.globalStyleProvider; } /** * SpinnerList requires that the snapToPages * property is set to true. Attempts to set it to * false will result in a runtime error. * * @throws ArgumentError SpinnerList requires snapToPages to be true. */ override public function set snapToPages(value:Boolean):void { if(!value) { throw new ArgumentError("SpinnerList requires snapToPages to be true."); } super.snapToPages = value; } /** * SpinnerList requires that the allowMultipleSelection * property is set to false. Attempts to set it to * true will result in a runtime error. * * @throws ArgumentError SpinnerList requires allowMultipleSelection to be false. */ override public function set allowMultipleSelection(value:Boolean):void { if(value) { throw new ArgumentError("SpinnerList requires allowMultipleSelection to be false."); } super.allowMultipleSelection = value; } /** * SpinnerList requires that the isSelectable * property is set to true. Attempts to set it to * false will result in a runtime error. * * @throws ArgumentError SpinnerList requires isSelectable to be true. */ override public function set isSelectable(value:Boolean):void { if(!value) { throw new ArgumentError("SpinnerList requires isSelectable to be true."); } super.snapToPages = value; } /** * @private */ override public function set layout(value:ILayout):void { if(value && !(value is ISpinnerLayout)) { throw new ArgumentError("SpinnerList requires layouts to implement the ISpinnerLayout interface."); } super.layout = value; } /** * @private */ override public function set selectedIndex(value:int):void { if(this._selectedIndex != value) { this.scrollToDisplayIndex(value, 0); } super.selectedIndex = value; } /** * @private */ override public function set dataProvider(value:ListCollection):void { if(this._dataProvider == value) { return; } super.dataProvider = value; if(!this._dataProvider || this._dataProvider.length == 0) { this.selectedIndex = -1; } else { this.selectedIndex = 0; } } /** * @private */ protected var _selectionOverlaySkin:DisplayObject; /** * An optional skin to display in the horizontal or vertical center of * the list to highlight the currently selected item. If the list * scrolls vertically, the selectionOverlaySkin will fill * the entire width of the list, and it will be positioned in the * vertical center. If the list scrolls horizontally, the * selectionOverlaySkin will fill the entire height of the * list, and it will be positioned in the horizontal center. * *

The following example gives the spinner list a selection overlay * skin:

* * * list.selectionOverlaySkin = new Image( texture ); * * @default null */ public function get selectionOverlaySkin():DisplayObject { return this._selectionOverlaySkin; } /** * @private */ public function set selectionOverlaySkin(value:DisplayObject):void { if(this._selectionOverlaySkin == value) { return; } if(this._selectionOverlaySkin && this._selectionOverlaySkin.parent == this) { this.removeRawChildInternal(this._selectionOverlaySkin); } this._selectionOverlaySkin = value; if(this._selectionOverlaySkin) { this.addRawChildInternal(this._selectionOverlaySkin); } this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ override protected function initialize():void { if(this._layout == null) { if(this._hasElasticEdges && this._verticalScrollPolicy === ScrollPolicy.AUTO && this._scrollBarDisplayMode !== ScrollBarDisplayMode.FIXED) { //so that the elastic edges work even when the max scroll //position is 0, similar to iOS. this.verticalScrollPolicy = ScrollPolicy.ON; } var layout:VerticalSpinnerLayout = new VerticalSpinnerLayout(); layout.useVirtualLayout = true; layout.padding = 0; layout.gap = 0; layout.horizontalAlign = HorizontalAlign.JUSTIFY; layout.requestedRowCount = 4; this.layout = layout; } super.initialize(); } /** * @private */ override protected function refreshMinAndMaxScrollPositions():void { super.refreshMinAndMaxScrollPositions(); if(this._maxVerticalScrollPosition != this._minVerticalScrollPosition) { this.actualPageHeight = ISpinnerLayout(this._layout).snapInterval; } else if(this._maxHorizontalScrollPosition != this._minHorizontalScrollPosition) { this.actualPageWidth = ISpinnerLayout(this._layout).snapInterval; } } /** * @private */ override protected function handlePendingScroll():void { if(this.pendingItemIndex >= 0) { var itemIndex:int = this.pendingItemIndex; this.pendingItemIndex = -1; if(this._maxVerticalPageIndex != this._minVerticalPageIndex) { this.pendingVerticalPageIndex = this.calculateNearestPageIndexForItem(itemIndex, this._verticalPageIndex, this._maxVerticalPageIndex); this.hasPendingVerticalPageIndex = this.pendingVerticalPageIndex !== this._verticalPageIndex; } else if(this._maxHorizontalPageIndex != this._minHorizontalPageIndex) { this.pendingHorizontalPageIndex = this.calculateNearestPageIndexForItem(itemIndex, this._horizontalPageIndex, this._maxHorizontalPageIndex); this.hasPendingHorizontalPageIndex = this.pendingHorizontalPageIndex !== this._horizontalPageIndex; } } super.handlePendingScroll(); } /** * @private */ override protected function layoutChildren():void { super.layoutChildren(); if(this._selectionOverlaySkin) { if(this._selectionOverlaySkin is IValidating) { IValidating(this._selectionOverlaySkin).validate(); } if(this._maxVerticalPageIndex != this._minVerticalPageIndex) { this._selectionOverlaySkin.width = this.actualWidth - this._leftViewPortOffset - this._rightViewPortOffset; var overlayHeight:Number = this.actualPageHeight; if(overlayHeight > this.actualHeight) { overlayHeight = this.actualHeight; } this._selectionOverlaySkin.height = overlayHeight; this._selectionOverlaySkin.x = this._leftViewPortOffset; this._selectionOverlaySkin.y = Math.round(this._topViewPortOffset + (this.actualHeight - this._topViewPortOffset - this._bottomViewPortOffset - overlayHeight) / 2); } else if(this._maxHorizontalPageIndex != this._minHorizontalPageIndex) { var overlayWidth:Number = this.actualPageWidth; if(overlayWidth > this.actualWidth) { overlayWidth = this.actualWidth; } this._selectionOverlaySkin.width = overlayWidth; this._selectionOverlaySkin.height = this.actualHeight - this._topViewPortOffset - this._bottomViewPortOffset; this._selectionOverlaySkin.x = Math.round(this._leftViewPortOffset + (this.actualWidth - this._leftViewPortOffset - this._rightViewPortOffset - overlayWidth) / 2); this._selectionOverlaySkin.y = this._topViewPortOffset; } } } /** * @private */ protected function calculateNearestPageIndexForItem(itemIndex:int, currentPageIndex:int, maxPageIndex:int):int { if(maxPageIndex != int.MAX_VALUE) { return itemIndex; } var itemCount:int = this._dataProvider.length; var fullDataProviderOffsets:int = currentPageIndex / itemCount; var currentItemIndex:int = currentPageIndex % itemCount; if(itemIndex < currentItemIndex) { var previousPageIndex:Number = fullDataProviderOffsets * itemCount + itemIndex; var nextPageIndex:Number = (fullDataProviderOffsets + 1) * itemCount + itemIndex; } else { previousPageIndex = (fullDataProviderOffsets - 1) * itemCount + itemIndex; nextPageIndex = fullDataProviderOffsets * itemCount + itemIndex; } if((nextPageIndex - currentPageIndex) < (currentPageIndex - previousPageIndex)) { return nextPageIndex; } return previousPageIndex; } /** * @private */ protected function spinnerList_scrollCompleteHandler(event:Event):void { var itemCount:int = this._dataProvider.length; if(this._maxVerticalPageIndex != this._minVerticalPageIndex) { var pageIndex:int = this._verticalPageIndex % itemCount; } else if(this._maxHorizontalPageIndex != this._minHorizontalPageIndex) { pageIndex = this._horizontalPageIndex % itemCount; } if(pageIndex < 0) { pageIndex = itemCount + pageIndex; } this.selectedIndex = pageIndex; } /** * @private */ protected function spinnerList_triggeredHandler(event:Event, item:Object):void { var itemIndex:int = this._dataProvider.getItemIndex(item); if(this._maxVerticalPageIndex != this._minVerticalPageIndex) { itemIndex = this.calculateNearestPageIndexForItem(itemIndex, this._verticalPageIndex, this._maxVerticalPageIndex); this.throwToPage(this._horizontalPageIndex, itemIndex, this._pageThrowDuration); } else if(this._maxHorizontalPageIndex != this._minHorizontalPageIndex) { itemIndex = this.calculateNearestPageIndexForItem(itemIndex, this._horizontalPageIndex, this._maxHorizontalPageIndex); this.throwToPage(itemIndex, this._verticalPageIndex); } } /** * @private */ override protected function stage_keyDownHandler(event:KeyboardEvent):void { if(!this._dataProvider) { return; } var changedSelection:Boolean = false; if(event.keyCode == Keyboard.HOME) { if(this._dataProvider.length > 0) { this.selectedIndex = 0; changedSelection = true; } } else if(event.keyCode == Keyboard.END) { this.selectedIndex = this._dataProvider.length - 1; changedSelection = true; } else if(event.keyCode == Keyboard.UP) { var newIndex:int = this._selectedIndex - 1; if(newIndex < 0) { newIndex = this._dataProvider.length + newIndex; } this.selectedIndex = newIndex; changedSelection = true; } else if(event.keyCode == Keyboard.DOWN) { newIndex = this._selectedIndex + 1; if(newIndex >= this._dataProvider.length) { newIndex -= this._dataProvider.length; } this.selectedIndex = newIndex; changedSelection = true; } if(changedSelection) { if(this._maxVerticalPageIndex != this._minVerticalPageIndex) { var pageIndex:int = this.calculateNearestPageIndexForItem(this._selectedIndex, this._verticalPageIndex, this._maxVerticalPageIndex); this.throwToPage(this._horizontalPageIndex, pageIndex, this._pageThrowDuration); } else if(this._maxHorizontalPageIndex != this._minHorizontalPageIndex) { pageIndex = this.calculateNearestPageIndexForItem(this._selectedIndex, this._horizontalPageIndex, this._maxHorizontalPageIndex); this.throwToPage(pageIndex, this._verticalPageIndex); } } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy