package com.rockabit.flex { import mx.collections.ArrayCollection; /** * List of items that allows for navigation. * The type of content can be specified with a class reference. */ [Bindable] public class NavigatableList extends ArrayCollection { private var _itemClass:Class; private var _curIndex:int; private var _source:Array; public var current:* = null; public var first:* = null; public var last:* = null; /** * Requires an array of Image objects */ public function NavigatableList(itemClass:Class, source:Array=null) { _itemClass = itemClass; _source = []; for each(var obj:Object in source) { addItem(obj as _itemClass); _source.push(obj as _itemClass); } if(length > 0) { defineFirstLast(); navigateTo(first); } } override public function addItem(item:Object):void { super.addItem(item as _itemClass); _source.push(item as _itemClass); defineFirstLast(); } override public function addItemAt(item:Object, index:int):void { super.addItemAt(item as _itemClass, index); var temp:Array = _source.slice(0, index); temp.push(item as _itemClass); temp.concat(_source.slice(index)); _source = temp.splice(0); defineFirstLast(); } override public function removeItemAt(index:int):Object { var obj:* = super.removeItemAt(index) as _itemClass; _source.splice(index, 1); defineFirstLast(); return obj; } override public function removeAll():void { super.removeAll(); _source.splice(0); } private function defineFirstLast():void { if(length > 0) { first = getItemAt(0); last = getItemAt(length - 1); } else { first = null; last = null; current = null; } } public function get previous():* { if(length < 1 || isNaN(_curIndex)) return null; var index:int = _curIndex - 1; if(index < 0) index += length; return getItemAt(index) as _itemClass; } public function get next():* { if(length < 1 || isNaN(_curIndex)) return null; var index:int = _curIndex + 1; if(index >= length) index -= length; return getItemAt(index) as _itemClass; } public function findItem(property:String, value:*):* { for each(var item:Object in this) { if(item.hasOwnProperty(property)) { if(item[property] == value) { return item as _itemClass; } } else { throw new Error("Property " + property + " does not exist in " + _itemClass.toString()); } } return null; } public function navigateTo(item:*):void { if(!item) { _curIndex = -1; current = null; } var index:int = getItemIndex(item as _itemClass); if(index < 0) return; _curIndex = index; current = getItemAt(_curIndex); } public function equals(list:NavigatableList, uniqueItemProperty:String = null):Boolean { if(!list || list.length != this.length) return false; if(!first.hasOwnProperty(uniqueItemProperty)) throw new Error("Property " + uniqueItemProperty + " does not exist in " + _itemClass.toString()); if(!list.first.hasOwnProperty(uniqueItemProperty)) throw new Error("Cannot compare with a list with a different item type."); for (var i:int = 0; i < length; i++) { if(Object(this.getItemAt(i))[uniqueItemProperty] != Object(list.getItemAt(i))[uniqueItemProperty]) return false; } return true; } override public function toString():String { return "[NavigatableList: length=" + length + ", type=" + _itemClass + "]"; } } }