scaffold.libs_as.feathers.data.ListCollection.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.data
{
import feathers.events.CollectionEventType;
import starling.events.Event;
import starling.events.EventDispatcher;
/**
* Dispatched when the underlying data source changes and the ui will
* need to redraw the data.
*
* The properties of the event object have the following values:
*
* Property Value
* bubbles
false
* currentTarget
The 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
.
* data
null
* target
The 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 starling.events.Event.CHANGE
*/
[Event(name="change",type="starling.events.Event")]
/**
* Dispatched when the collection has changed drastically, such as when
* the underlying data source is replaced completely.
*
* The properties of the event object have the following values:
*
* Property Value
* bubbles
false
* currentTarget
The 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
.
* data
null
* target
The 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.CollectionEventType.RESET
*/
[Event(name="reset",type="starling.events.Event")]
/**
* Dispatched when an item is added to the collection.
*
* The properties of the event object have the following values:
*
* Property Value
* bubbles
false
* currentTarget
The 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
.
* data
The index of the item that has been
* added. It is of type int
.
* target
The 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.CollectionEventType.ADD_ITEM
*/
[Event(name="addItem",type="starling.events.Event")]
/**
* Dispatched when an item is removed from the collection.
*
* The properties of the event object have the following values:
*
* Property Value
* bubbles
false
* currentTarget
The 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
.
* data
The index of the item that has been
* removed. It is of type int
.
* target
The 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.CollectionEventType.REMOVE_ITEM
*/
[Event(name="removeItem",type="starling.events.Event")]
/**
* Dispatched when an item is replaced in the collection.
*
* The properties of the event object have the following values:
*
* Property Value
* bubbles
false
* currentTarget
The 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
.
* data
The index of the item that has been
* replaced. It is of type int
.
* target
The 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.CollectionEventType.REPLACE_ITEM
*/
[Event(name="replaceItem",type="starling.events.Event")]
/**
* Dispatched when the updateItemAt()
function is called on the
* ListCollection
.
*
* The properties of the event object have the following values:
*
* Property Value
* bubbles
false
* currentTarget
The 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
.
* data
The index of the item that has been
* updated. It is of type int
.
* target
The 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.
*
*
* @see #updateItemAt()
*
* @eventType feathers.events.CollectionEventType.UPDATE_ITEM
*/
[Event(name="updateItem",type="starling.events.Event")]
/**
* Dispatched when the updateAll()
function is called on the
* ListCollection
.
*
* The properties of the event object have the following values:
*
* Property Value
* bubbles
false
* currentTarget
The 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
.
* data
null
* target
The 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.
*
*
* @see #updateAll()
*
* @eventType feathers.events.CollectionEventType.UPDATE_ALL
*/
[Event(name="updateAll",type="starling.events.Event")]
/**
* Wraps a data source with a common API for use with UI controls, like
* lists, that support one dimensional collections of data. Supports custom
* "data descriptors" so that unexpected data sources may be used. Supports
* Arrays, Vectors, and XMLLists automatically.
*
* @see ArrayListCollectionDataDescriptor
* @see VectorListCollectionDataDescriptor
* @see XMLListListCollectionDataDescriptor
*/
public class ListCollection extends EventDispatcher
{
/**
* Constructor
*/
public function ListCollection(data:Object = null)
{
if(!data)
{
//default to an array if no data is provided
data = [];
}
this.data = data;
}
/**
* @private
*/
protected var _data:Object;
/**
* The data source for this collection. May be any type of data, but a
* dataDescriptor
needs to be provided to translate from
* the data source's APIs to something that can be understood by
* ListCollection
.
*
* Data sources of type Array, Vector, and XMLList are automatically
* detected, and no dataDescriptor
needs to be set if the
* ListCollection
uses one of these types.
*/
public function get data():Object
{
return _data;
}
/**
* @private
*/
public function set data(value:Object):void
{
if(this._data == value)
{
return;
}
this._data = value;
//we'll automatically detect an array, vector, or xmllist for convenience
if(this._data is Array && !(this._dataDescriptor is ArrayListCollectionDataDescriptor))
{
this._dataDescriptor = new ArrayListCollectionDataDescriptor();
}
else if(this._data is Vector. && !(this._dataDescriptor is VectorNumberListCollectionDataDescriptor))
{
this._dataDescriptor = new VectorNumberListCollectionDataDescriptor();
}
else if(this._data is Vector. && !(this._dataDescriptor is VectorIntListCollectionDataDescriptor))
{
this._dataDescriptor = new VectorIntListCollectionDataDescriptor();
}
else if(this._data is Vector. && !(this._dataDescriptor is VectorUintListCollectionDataDescriptor))
{
this._dataDescriptor = new VectorUintListCollectionDataDescriptor();
}
else if(this._data is Vector.<*> && !(this._dataDescriptor is VectorListCollectionDataDescriptor))
{
this._dataDescriptor = new VectorListCollectionDataDescriptor();
}
else if(this._data is XMLList && !(this._dataDescriptor is XMLListListCollectionDataDescriptor))
{
this._dataDescriptor = new XMLListListCollectionDataDescriptor();
}
if(this._data === null)
{
this._dataDescriptor = null;
}
this.dispatchEventWith(CollectionEventType.RESET);
this.dispatchEventWith(Event.CHANGE);
}
/**
* @private
*/
protected var _dataDescriptor:IListCollectionDataDescriptor;
/**
* Describes the underlying data source by translating APIs.
*
* @see IListCollectionDataDescriptor
*/
public function get dataDescriptor():IListCollectionDataDescriptor
{
return this._dataDescriptor;
}
/**
* @private
*/
public function set dataDescriptor(value:IListCollectionDataDescriptor):void
{
if(this._dataDescriptor == value)
{
return;
}
this._dataDescriptor = value;
this.dispatchEventWith(CollectionEventType.RESET);
this.dispatchEventWith(Event.CHANGE);
}
/**
* The number of items in the collection.
*/
public function get length():int
{
if(!this._dataDescriptor)
{
return 0;
}
return this._dataDescriptor.getLength(this._data);
}
/**
* Call updateItemAt()
to manually inform any component
* rendering the ListCollection
that the properties of a
* single item in the collection have changed, and that any views
* associated with the item should be updated. The collection will
* dispatch the CollectionEventType.UPDATE_ITEM
event.
*
* Alternatively, the item can dispatch an event when one of its
* properties has changed, and item renderers can listen for that event
* and update themselves automatically.
*
* @see #updateAll()
*/
public function updateItemAt(index:int):void
{
this.dispatchEventWith(CollectionEventType.UPDATE_ITEM, false, index);
}
/**
* Call updateAll()
to manually inform any component
* rendering the ListCollection
that the properties of all,
* or many, of the collection's items have changed, and that any
* rendered views should be updated. The collection will dispatch the
* CollectionEventType.UPDATE_ALL
event.
*
* Alternatively, the item can dispatch an event when one of its
* properties has changed, and item renderers can listen for that event
* and update themselves automatically.
*
* @see #updateItemAt()
*/
public function updateAll():void
{
this.dispatchEventWith(CollectionEventType.UPDATE_ALL);
}
/**
* Returns the item at the specified index in the collection.
*/
public function getItemAt(index:int):Object
{
return this._dataDescriptor.getItemAt(this._data, index);
}
/**
* Determines which index the item appears at within the collection. If
* the item isn't in the collection, returns -1
.
*/
public function getItemIndex(item:Object):int
{
return this._dataDescriptor.getItemIndex(this._data, item);
}
/**
* Adds an item to the collection, at the specified index.
*/
public function addItemAt(item:Object, index:int):void
{
this._dataDescriptor.addItemAt(this._data, item, index);
this.dispatchEventWith(Event.CHANGE);
this.dispatchEventWith(CollectionEventType.ADD_ITEM, false, index);
}
/**
* Removes the item at the specified index from the collection and
* returns it.
*/
public function removeItemAt(index:int):Object
{
var item:Object = this._dataDescriptor.removeItemAt(this._data, index);
this.dispatchEventWith(Event.CHANGE);
this.dispatchEventWith(CollectionEventType.REMOVE_ITEM, false, index);
return item;
}
/**
* Removes a specific item from the collection.
*/
public function removeItem(item:Object):void
{
var index:int = this.getItemIndex(item);
if(index >= 0)
{
this.removeItemAt(index);
}
}
/**
* Removes all items from the collection.
*/
public function removeAll():void
{
if(this.length == 0)
{
return;
}
this._dataDescriptor.removeAll(this._data);
this.dispatchEventWith(Event.CHANGE);
this.dispatchEventWith(CollectionEventType.RESET, false);
}
/**
* Replaces the item at the specified index with a new item.
*/
public function setItemAt(item:Object, index:int):void
{
this._dataDescriptor.setItemAt(this._data, item, index);
this.dispatchEventWith(Event.CHANGE);
this.dispatchEventWith(CollectionEventType.REPLACE_ITEM, false, index);
}
/**
* Adds an item to the end of the collection.
*/
public function addItem(item:Object):void
{
this.addItemAt(item, this.length);
}
/**
* Adds an item to the end of the collection.
*/
public function push(item:Object):void
{
this.addItemAt(item, this.length);
}
/**
* Adds all items from another collection.
*/
public function addAll(collection:ListCollection):void
{
var otherCollectionLength:int = collection.length;
for(var i:int = 0; i < otherCollectionLength; i++)
{
var item:Object = collection.getItemAt(i);
this.addItem(item);
}
}
/**
* Adds all items from another collection, placing the items at a
* specific index in this collection.
*/
public function addAllAt(collection:ListCollection, index:int):void
{
var otherCollectionLength:int = collection.length;
var currentIndex:int = index;
for(var i:int = 0; i < otherCollectionLength; i++)
{
var item:Object = collection.getItemAt(i);
this.addItemAt(item, currentIndex);
currentIndex++;
}
}
/**
* Removes the item from the end of the collection and returns it.
*/
public function pop():Object
{
return this.removeItemAt(this.length - 1);
}
/**
* Adds an item to the beginning of the collection.
*/
public function unshift(item:Object):void
{
this.addItemAt(item, 0);
}
/**
* Removed the item from the beginning of the collection and returns it.
*/
public function shift():Object
{
return this.removeItemAt(0);
}
/**
* Determines if the specified item is in the collection.
*/
public function contains(item:Object):Boolean
{
return this.getItemIndex(item) >= 0;
}
/**
* Calls a function for each item in the collection that may be used
* to dispose any properties on the item. For example, display objects
* or textures may need to be disposed.
*
* The function is expected to have the following signature:
* function( item:Object ):void
*
* In the following example, the items in the collection are disposed:
*
*
* collection.dispose( function( item:Object ):void
* {
* var accessory:DisplayObject = DisplayObject(item.accessory);
* accessory.dispose();
* }
*
* @see http://doc.starling-framework.org/core/starling/display/DisplayObject.html#dispose() starling.display.DisplayObject.dispose()
* @see http://doc.starling-framework.org/core/starling/textures/Texture.html#dispose() starling.textures.Texture.dispose()
*/
public function dispose(disposeItem:Function):void
{
var itemCount:int = this.length;
for(var i:int = 0; i < itemCount; i++)
{
var item:Object = this.getItemAt(i);
disposeItem(item);
}
}
}
}