Skip to content

Instantly share code, notes, and snippets.

@slaskis
Created June 1, 2010 13:24
Show Gist options
  • Save slaskis/420933 to your computer and use it in GitHub Desktop.
Save slaskis/420933 to your computer and use it in GitHub Desktop.
class DisplayObjectUtil {
public static function iterator( obj : flash.display.DisplayObjectContainer ) {
var i = 0;
return {
next: function(){
return obj.getChildAt(i++);
},
hasNext: function(){
return i < obj.numChildren;
}
}
}
}
class EditableListItem<T> extends com.bit101.components.ListItem {
var _text : com.bit101.components.InputText;
public function new(?parent,?xpos=0.,?ypos=0.,?data:T) {
super(parent,xpos,ypos,data);
}
override function addChildren() {
super.addChildren();
var t = _text = new com.bit101.components.InputText(this);
var self = this;
t.addEventListener( flash.events.Event.CHANGE , function(e){
t.mouseEnabled = t.mouseChildren = false;
self.mouseChildren = false;
self._data.label = t.text;
});
// Toggle edit mode with double click...
addEventListener( flash.events.MouseEvent.DOUBLE_CLICK , function(e){
self.mouseChildren = t.mouseEnabled = t.mouseChildren = !t.mouseEnabled;
});
this.doubleClickEnabled = true;
this.mouseChildren = t.mouseEnabled = t.mouseChildren = false;
}
public override function draw() {
super.draw();
if( _text.text == "" )
_text.text = _data.label;
}
override public function toString() return "[EditableListItem text:"+_text.text+" y:"+y+"]"
}
class IterableUtil {
public inline static function indexOf<T>(iter:Iterable<T>,item:T):Int {
var i = 0;
var found = false;
for( it in iter ) {
if( it == item ) {
found = true;
break;
}
i++;
}
return ( found ) ? i : -1;
}
public inline static function sort<T>(iter:Iterable<T>,f : T -> T -> Int) {
var arr = Lambda.array(iter);
arr.sort(f);
return arr;
}
}
using DisplayObjectUtil;
using IterableUtil;
class SortableList<T> extends com.bit101.components.List {
var _moving : com.bit101.components.ListItem;
var _didChange : Bool;
/**
* Extends minimalcomponents List with sortable items.
* Dragging an item to another position updates the _items Array.
*/
public function new(?parent,?xpos=0.,?ypos=0.,?items:Array<T>) {
super(parent,xpos,ypos,items);
}
override function makeListItems() {
// Before the items is removed from _itemHolder we should remove listeners from them..
for( item in _itemHolder ) {
item.removeEventListener( flash.events.MouseEvent.MOUSE_DOWN , onItemDown );
item.stage.removeEventListener( flash.events.MouseEvent.MOUSE_MOVE , onItemMove );
item.stage.removeEventListener( flash.events.MouseEvent.MOUSE_UP , onItemUp );
}
super.makeListItems();
// Now we have a list of items in _itemHolder, add event listeners to them...
for( item in _itemHolder ) {
item.addEventListener( flash.events.MouseEvent.MOUSE_DOWN , onItemDown );
}
}
function onItemDown(e) {
// Start drag on e.target on y axis
_moving = cast( e.currentTarget , com.bit101.components.ListItem );
if( _moving == null && !_moving.mouseChildren )
return;
_moving.startDrag(false, new flash.geom.Rectangle(0,-1,0,_height-_listItemHeight));
_moving.stage.addEventListener( flash.events.MouseEvent.MOUSE_MOVE , onItemMove );
_moving.stage.addEventListener( flash.events.MouseEvent.MOUSE_UP , onItemUp );
_didChange = false;
}
function onItemMove(e) {
if( _moving == null )
return;
// Reorder the children of _itemHolder while dragging
orderItems(_moving);
}
function onItemUp(e) {
if( _moving == null )
return;
// Stop drag on e.target
_moving.stopDrag();
_moving = null;
if( _didChange ) {
// Update the _items array to match the vertical order of the children of _itemHolder
var holder = _itemHolder;
var items = _items;
_items.sort(function(a,b){
var x = holder.getChildAt(items.indexOf(a));
var y = holder.getChildAt(items.indexOf(b));
if( x.y > y.y ) return 1;
if( x.y < y.y ) return -1;
return 0;
});
invalidate();
// Dispatch an event saying the order has changed, so the layers may reorder their z-index accordingly
dispatchEvent( new flash.events.Event( flash.events.Event.CHANGE ) );
}
}
function orderItems(?except) {
var sortedItems = [];
for( item in _itemHolder )
sortedItems.push(item);
sortedItems.sort(function(a,b){
return if( a.y > b.y ) 1;
else if( a.y < b.y ) -1;
else 0;
});
var changed = false;
for( item in _itemHolder ) {
var newY = sortedItems.indexOf(item) * _listItemHeight;
if( item != except && item.y != newY ) {
item.y = newY;
changed = true;
}
}
if( changed )
_didChange = true;
}
}
class TestList extends flash.display.Sprite {
public function new() {
super();
var box = new com.bit101.components.VBox(this);
var list = new SortableList(box);
list.listItemClass = EditableListItem;
list.addEventListener( flash.events.Event.CHANGE , function(e){
trace( "Changed the list!" );
});
var tools = new com.bit101.components.HBox(box);
var add = new com.bit101.components.PushButton(tools,0,0,"+",function(e){
var i = list.items.length;
list.addItem( new ItemData("Item " + i , i ) );
});
add.setSize( 20 , 20 );
var remove = new com.bit101.components.PushButton(tools,0,0,"-",function(e){
if( list.selectedItem != null )
list.removeItem( list.selectedItem );
});
remove.setSize( 20 , 20 );
}
static function main(){
#if debug
haxe.Log.trace = function(v,?pos) { untyped __global__["trace"](pos.className+"#"+pos.methodName+"("+pos.lineNumber+"):",v);}
#end
flash.Lib.current.stage.align = flash.display.StageAlign.TOP_LEFT;
flash.Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;
var t = new TestList();
flash.Lib.current.addChild(t);
}
}
class ItemData {
public var label : String;
public var index : Int;
public function new(label,index){
this.label = label;
this.index = index;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment