Question

below is our attempt to drag and drop list items within the same list-based control. we're trying to mirror the same functionality as "Dragging and dropping in the same control" using flex components: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7cfd.html.

as the user is re-sorting the list each index will be written to a file so that the re-sorted list will stay as is as the screen is refreshed.

although we can render an avatar and push the dragged object to the end of the list-based control we are unable to drag the object to a specific index within the list-based control.

what we can do: google -> msn -> yahoo -> google

what we can't do: google -> msn -> google -> yahoo

lastly, any ideas on how to store the re-sorted list for a screen refresh would be appreciated.

to build we took the advice about extending the list as well as the advice of others: mironcaius and Josh Tynjala: http://forum.starling-framework.org/topic/defaultlistitemrenderer-does-not-update-lables and http://wiki.starling-framework.org/feathers/drag-drop (see adding display object itself as drag data).

Main.as

package feathers.examples.dragDrop
{
import feathers.data.ListCollection;
import feathers.dragDrop.IDragSource;
import feathers.dragDrop.IDropTarget;
import feathers.themes.AeonDesktopTheme;

import starling.display.Sprite;
import starling.events.Event;

public class Main extends Sprite implements IDragSource, IDropTarget
{
    public static var listCollection:ListCollection = new ListCollection([{playerName:"yahoo"},{playerName:"msn"},{playerName:"google"}]);

    public function Main()
    {
        this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    }

    private function addedToStageHandler(event:Event):void
    {
        new AeonDesktopTheme();

        var listTeam1:DragDropList = new DragDropList();
        listTeam1.dataProvider = listCollection;
        listTeam1.itemRendererProperties.labelField = "playerName";
        listTeam1.itemRendererProperties.height = 38;
        this.addChild(listTeam1);
        //listTeam1.hasElasticEdges = false;
        //listTeam1.addEventListener("changeTeam", changeTeamHandler);
    }

    /*private function changeTeamHandler(event:Event):void
    {
        //trace(event.target.data);
    }*/
}
}

DragDropList.as

package feathers.examples.dragDrop
{
import feathers.controls.Label;
import feathers.controls.List;
import feathers.core.FeathersControl;
import feathers.dragDrop.DragData;
import feathers.dragDrop.DragDropManager;
import feathers.dragDrop.IDragSource;
import feathers.dragDrop.IDropTarget;
import feathers.events.DragDropEvent;

import starling.display.Quad;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;

//[Event(name="changeTeam", type="Event")]

public class DragDropList extends List implements IDropTarget, IDragSource
{
    public function DragDropList()
    {
        super();
        addEventListener(TouchEvent.TOUCH, touchHandler);
        addEventListener(DragDropEvent.DRAG_ENTER, dragEnterHandler);
        addEventListener(DragDropEvent.DRAG_DROP, dragDropHandler);
        addEventListener(DragDropEvent.DRAG_COMPLETE, dragCompleteHandler);
    }

    protected function touchHandler(event:TouchEvent):void
    {
        var touch:Touch = event.touches[0];
        if(touch.phase == TouchPhase.BEGAN)
        {
            if(selectedItem)
            {
                var fc:FeathersControl = new FeathersControl();
                fc.addChild(new Quad(150, 50, 0xFFFFFF));
                var lbl:Label = new Label();
                lbl.text = selectedItem["playerName"];
                fc.addChild(lbl);
                var dd:DragData = new DragData();
                dd.setDataForFormat("playerFormat", selectedItem);
                DragDropManager.startDrag(this, touch, dd, fc);
            }
        }
    }

    protected function dragEnterHandler(event:DragDropEvent, dragData:DragData):void
    {
        if(dragData.hasDataForFormat("playerFormat"))
        {
            DragDropManager.acceptDrag(this);
        }
    }

    protected function dragDropHandler(event:DragDropEvent, dragData:DragData):void
    {
        if(dragData.hasDataForFormat("playerFormat"))
        {
            var obj:Object = dragData.getDataForFormat("playerFormat");
            Main.listCollection.push(obj);
            //dispatchEventWith("changeTeam", false, obj);
        }
    }

    protected function dragCompleteHandler(event:DragDropEvent):void
    {
        if(event.isDropped)
        {
            Main.listCollection.removeItem(selectedItem);
        }
    }

}
}
Was it helpful?

Solution

I've now got a reasonable implementation of a drag sortable Feathers List working. I'm sure it could be improved, and as an AS3 / Starling / Feathers novice, I'm sure I'll have done some parts in a less than ideal way, but I'm pretty happy with how it works.

The scroll is controlled by detecting whether the drag is close to the top / bottom of the list, in the touchHandler, which initiates a slower scroll, or past the top / bottom of the list, which starts a faster scroll.

Hope it's still of some use for you, and feel free to come back with any questions on it, or advice on improving it!

Ted


Also, in case they're of interest, these are the two drag handle images I've used in the code: drag-handle.png drag-handle-down.png

Main.as

package feathers.examples.dragDrop
{
    import feathers.controls.Button;
    import feathers.controls.List;
    import feathers.data.ListCollection;
    import feathers.dragDrop.IDragSource;
    import feathers.dragDrop.IDropTarget;
    import feathers.themes.MetalWorksMobileTheme;

    import starling.core.Starling;
    import starling.display.Sprite;
    import starling.events.Event;

    public class Main extends Sprite implements IDragSource, IDropTarget
    {
        private var list:List;

        public function Main()
        {
            this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        private function addedToStageHandler(event:Event):void
        {
            new MetalWorksMobileTheme();

            const PADDING:int = 100;

            list = new List();
            list.width = Starling.current.viewPort.width - (PADDING * 2); 
            list.height = Starling.current.viewPort.height - (PADDING * 2);
            this.addChild( list );
            list.y = PADDING;
            list.x = PADDING;
            list.itemRendererType = DragDropItemRenderer;

            resetDefaultListData();

            var resetButton:Button = new Button();
            resetButton.label = "Reset List Data";
            resetButton.addEventListener(Event.TRIGGERED, resetButtonHandler);
            resetButton.nameList.add(Button.ALTERNATE_NAME_QUIET_BUTTON);
            this.addChild(resetButton);
            resetButton.validate();

            resetButton.x = (Starling.current.viewPort.width / 2) - (resetButton.width / 2);
            resetButton.y = Starling.current.viewPort.height - resetButton.height - (PADDING / 5);
        }


        private function resetButtonHandler(e:Event):void
        {
            resetDefaultListData();

        }

        private function resetDefaultListData():void
        {
            var defaultData:ListCollection = new ListCollection(
                [
                    {text: 'Test Item 1' },
                    {text: 'Test Item 2' },
                    {text: 'Test Item 3' },
                    {text: 'Test Item 4' },
                    {text: 'Test Item 5' },
                    {text: 'Test Item 6' },
                    {text: 'Test Item 7' },
                    {text: 'Test Item 8' },
                    {text: 'Test Item 9' },
                    {text: 'Test Item 10' },
                    {text: 'Test Item 11' },
                    {text: 'Test Item 12' },
                    {text: 'Test Item 13' },
                    {text: 'Test Item 14' },
                    {text: 'Test Item 15' },
                    {text: 'Test Item 16' },
                    {text: 'Test Item 17' },
                    {text: 'Test Item 18' },
                    {text: 'Test Item 19' },
                    {text: 'Test Item 20' },
                    {text: 'Test Item 21' },
                    {text: 'Test Item 22' },
                    {text: 'Test Item 23' },
                    {text: 'Test Item 24' },
                    {text: 'Test Item 25' },
                    {text: 'Test Item 26' },
                    {text: 'Test Item 27' },
                    {text: 'Test Item 28' },
                    {text: 'Test Item 29' },
                    {text: 'Test Item 30' },
                    {text: 'Test Item 31' },
                    {text: 'Test Item 32' },
                    {text: 'Test Item 33' },
                    {text: 'Test Item 34' },
                    {text: 'Test Item 35' },
                    {text: 'Test Item 36' },
                    {text: 'Test Item 37' },
                    {text: 'Test Item 38' },
                    {text: 'Test Item 39' },
                    {text: 'Test Item 40' },
                    {text: 'Test Item 41' },
                    {text: 'Test Item 42' },
                    {text: 'Test Item 43' },
                    {text: 'Test Item 44' },
                    {text: 'Test Item 45' },
                    {text: 'Test Item 46' },
                    {text: 'Test Item 47' },
                    {text: 'Test Item 48' },
                    {text: 'Test Item 49' },
                    {text: 'Test Item 50' },
                    {text: 'Test Item 51' },
                    {text: 'Test Item 52' },
                    {text: 'Test Item 53' },
                    {text: 'Test Item 54' },
                    {text: 'Test Item 55' },
                    {text: 'Test Item 56' },
                    {text: 'Test Item 57' },
                    {text: 'Test Item 58' },
                    {text: 'Test Item 59' },
                    {text: 'Test Item 60' },
                    {text: 'Test Item 61' },
                    {text: 'Test Item 62' },
                    {text: 'Test Item 63' },
                    {text: 'Test Item 64' },
                    {text: 'Test Item 65' },
                    {text: 'Test Item 66' },
                    {text: 'Test Item 67' },
                    {text: 'Test Item 68' },
                    {text: 'Test Item 69' },
                    {text: 'Test Item 70' },
                    {text: 'Test Item 71' },
                    {text: 'Test Item 72' },
                    {text: 'Test Item 73' },
                    {text: 'Test Item 74' },
                    {text: 'Test Item 75' },
                    {text: 'Test Item 76' },
                    {text: 'Test Item 77' },
                    {text: 'Test Item 78' },
                    {text: 'Test Item 79' },
                    {text: 'Test Item 80' },
                    {text: 'Test Item 81' },
                    {text: 'Test Item 82' },
                    {text: 'Test Item 83' },
                    {text: 'Test Item 84' },
                    {text: 'Test Item 85' },
                    {text: 'Test Item 86' },
                    {text: 'Test Item 87' },
                    {text: 'Test Item 88' },
                    {text: 'Test Item 89' },
                    {text: 'Test Item 90' },
                    {text: 'Test Item 91' },
                    {text: 'Test Item 92' },
                    {text: 'Test Item 93' },
                    {text: 'Test Item 94' },
                    {text: 'Test Item 95' },
                    {text: 'Test Item 96' },
                    {text: 'Test Item 97' },
                    {text: 'Test Item 98' },
                    {text: 'Test Item 99' },
                    {text: 'Test Item 100' },

                ]);
            list.dataProvider = defaultData;
        }


    }
}

DragDropItemRenderer.as

package feathers.examples.dragDrop
{
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    import feathers.controls.Label;
    import feathers.controls.List;
    import feathers.controls.renderers.IListItemRenderer;
    import feathers.core.FeathersControl;
    import feathers.dragDrop.DragData;
    import feathers.dragDrop.DragDropManager;
    import feathers.dragDrop.IDragSource;
    import feathers.dragDrop.IDropTarget;
    import feathers.events.DragDropEvent;

    import starling.display.Button;
    import starling.display.DisplayObject;
    import starling.display.Quad;
    import starling.display.Sprite;
    import starling.events.Event;
    import starling.events.Touch;
    import starling.events.TouchEvent;
    import starling.events.TouchPhase;
    import starling.textures.Texture;
    import starling.utils.Color;

    public class DragDropItemRenderer extends FeathersControl implements IListItemRenderer, IDragSource, IDropTarget
    {
        [Embed(source="drag-handle.png")]
        public static const DragHandle:Class;
        [Embed(source="drag-handle-down.png")]
        public static const DragHandleDown:Class;

        private const LIST_ITEM_DRAG:String = "LIST_ITEM_DRAG";

        public function DragDropItemRenderer()
        {   
            //drag
            this.addEventListener(DragDropEvent.DRAG_START, dragStartHandler);
            this.addEventListener(DragDropEvent.DRAG_COMPLETE, dragCompleteHandler);

            //drop
            this.addEventListener(DragDropEvent.DRAG_ENTER, dragEnterHandler);
            this.addEventListener(DragDropEvent.DRAG_EXIT, dragExitHandler);
            this.addEventListener(DragDropEvent.DRAG_MOVE, dragMoveHandler);            
            this.addEventListener(DragDropEvent.DRAG_DROP, dragDropHandler);
        }


        //================================================================================================
        //drag interface
        //================================================================================================
        private function dragStartHandler(event:DragDropEvent, dragData:DragData):void
        {
            //the drag was started with the call to DragDropManager.startDrag()         
        }

        private function dragCompleteHandler(event:DragDropEvent, dragData:DragData):void
        {
            if(event.isDropped)
            {
                //the object successfully dropped at a valid location
            }                       
            stopScrolling();
        }


        private var carryOnScrolling:Boolean=false;
        private var scrollDirection:String="";
        private var scrollSpeed:String="";
        private var scrollTimer:Timer;
        private var avatarContainer:Sprite;
        private var avatarBg:Quad;
        private var avatarLabel:Label;

        private const LIST_SCROLL_DETECT_HEIGHT:int = 30;

        private const SCROLL_SIZE:int = 25;

        private const SCROLL_SPEED_SLOW:String = "SLOW";
        private const SCROLL_SPEED_FAST:String = "FAST";

        private const SCROLL_DIRECTION_UP:String = "UP";
        private const SCROLL_DIRECTION_DOWN:String = "DOWN";

        private const SCROLL_TIME_MS_SLOW:int = 75;
        private const SCROLL_TIME_MS_FAST:int = 25;
        private var scrollSpeedMSToUse:int;

        private function startScrollingList(direction:String, speed:String):void
        {
            scrollDirection = direction;
            scrollSpeed = speed;
            carryOnScrolling = true;

            doScrollWorker();

            if(scrollTimer != null)
            {
                scrollTimer.stop();
                scrollTimer = null;
            }


            if(scrollSpeed == SCROLL_SPEED_FAST)
                scrollSpeedMSToUse = SCROLL_TIME_MS_FAST;
            else
                scrollSpeedMSToUse = SCROLL_TIME_MS_SLOW;

            scrollTimer = new Timer(scrollSpeedMSToUse);
            scrollTimer.addEventListener(TimerEvent.TIMER, onScrollTimerHandler);
            scrollTimer.start();
        }

        private function stopScrolling():void
        {           
            carryOnScrolling = false;
        }

        private function onScrollTimerHandler(e:TimerEvent):void
        {   
            if(carryOnScrolling)
            {
                doScrollWorker();
            }
            else
            {
                scrollTimer.stop();
                scrollTimer = null;
            }
        }

        private function doScrollWorker():void
        {
            const EXTRA_SCROLL_PADDING:int = 20;

            var scrollSizeToUse:int = SCROLL_SIZE;

            if(scrollDirection == SCROLL_DIRECTION_UP)
            {   
                if((this.owner.verticalScrollPosition + scrollSizeToUse) < (this.owner.maxVerticalScrollPosition + EXTRA_SCROLL_PADDING))
                {
                    this.owner.scrollToPosition(this.owner.horizontalScrollPosition, this.owner.verticalScrollPosition + scrollSizeToUse, (scrollSpeedMSToUse / 1000));
                }   
            }
            else
            {
                if((this.owner.verticalScrollPosition - scrollSizeToUse) > (this.owner.minVerticalScrollPosition - EXTRA_SCROLL_PADDING))
                {
                    this.owner.scrollToPosition(this.owner.horizontalScrollPosition, this.owner.verticalScrollPosition - scrollSizeToUse, (scrollSpeedMSToUse / 1000));
                }   
            }
        }



        private function touchHandler(event:TouchEvent):void
        {
            if(DragDropManager.isDragging)
            {
                //check if the drag is close enough to the top / bottom to start scrolling
                var touchScrollTest:Touch = event.getTouch(this);

                if(touchScrollTest)
                {   
                    if(touchScrollTest.globalY < this.owner.y)
                    {
                        startScrollingList(SCROLL_DIRECTION_DOWN, SCROLL_SPEED_FAST);       
                    }
                    else if(touchScrollTest.globalY < this.owner.y + LIST_SCROLL_DETECT_HEIGHT)
                    {                       
                        startScrollingList(SCROLL_DIRECTION_DOWN, SCROLL_SPEED_SLOW);
                    }
                    else if(touchScrollTest.globalY > this.owner.y + this.owner.height)
                    {
                        startScrollingList(SCROLL_DIRECTION_UP, SCROLL_SPEED_FAST);
                    }
                    else if(touchScrollTest.globalY > this.owner.y + this.owner.height - LIST_SCROLL_DETECT_HEIGHT)
                    {                       
                        startScrollingList(SCROLL_DIRECTION_UP, SCROLL_SPEED_SLOW);
                    }                   
                    else
                    {   
                        stopScrolling();        
                    }
                }

                //one drag at a time, please                
                return;
            }
            if(this._touchID >= 0)
            {
                var touch:Touch = event.getTouch(this._draggedObject, null, this._touchID);
                if(touch.phase == TouchPhase.MOVED)
                {
                    this._touchID = -1;

                    avatarContainer = new Sprite();

                    const AVATAR_X_OFFSET:int = 75;

                    avatarBg = new Quad(this.width - AVATAR_X_OFFSET, this.height, starling.utils.Color.LIME);
                    avatarBg.alpha = 0.25;

                    avatarLabel = new Label();                  
                    avatarLabel.x = this._label.x;
                    avatarLabel.y = this._label.y;
                    avatarLabel.width = this._label.width;
                    avatarLabel.height = this._label.height;
                    avatarLabel.text = this._label.text;

                    avatarContainer.addChild(avatarBg);
                    avatarContainer.addChild(avatarLabel);

                    var dragData:DragData = new DragData();
                    dragData.setDataForFormat(LIST_ITEM_DRAG, this._data);
                    DragDropManager.startDrag(this, touch, dragData, avatarContainer, -avatarLabel.width + 75, 0);
                }
                else if(touch.phase == TouchPhase.ENDED)
                {   
                    stopScrolling();
                    this._touchID = -1;
                    this._bgQuad.color = starling.utils.Color.RED;
                }
            }
            else
            {
                touch = event.getTouch(this, TouchPhase.BEGAN);
                if(!touch || touch.target == this || touch.target == this._background)
                {
                    return;
                }

                this._touchID = touch.id;
                this._draggedObject = touch.target;
            }
            event.stopPropagation();

        }


        private var _background:Quad;
        private var _touchID:int = -1;
        private var _draggedObject:DisplayObject;

        //================================================================================================



        //================================================================================================
        //drop interface
        //================================================================================================
        private function dragEnterHandler(event:DragDropEvent, dragData:DragData):void
        {
            if(!dragData.hasDataForFormat(LIST_ITEM_DRAG))
            {
                return;
            }
            DragDropManager.acceptDrag(this);
        }

        private function dragMoveHandler(event:DragDropEvent, dragData:DragData):void
        {
            var dataBeingDragged:Object = dragData.getDataForFormat(LIST_ITEM_DRAG);            
            if(dataBeingDragged != this._data)
            {
                if(event.localY < (this.height / 2))
                {
                    this._hiliteTop.visible = true;
                    this._hiliteBottom.visible = false;
                }
                else
                {
                    this._hiliteTop.visible = false;
                    this._hiliteBottom.visible = true;
                }               
            }
        }

        private function dragExitHandler(event:DragDropEvent, dragData:DragData):void
        {
            this._label.text = this._data.text; 
            this._hiliteTop.visible = false;
            this._hiliteBottom.visible = false;
        }

        private function dragDropHandler(event:DragDropEvent, dragData:DragData):void
        {
            var dataBeingDragged:Object = dragData.getDataForFormat(LIST_ITEM_DRAG);            
            if(dataBeingDragged != this._data)      
            {
                this.owner.dataProvider.removeItem(dataBeingDragged);

                var indexToDragTo:int = this.owner.dataProvider.getItemIndex(this.data);

                if(this._hiliteBottom.visible)
                    indexToDragTo++;

                this.owner.dataProvider.addItemAt(dataBeingDragged, indexToDragTo);

                this._hiliteTop.visible = false;
                this._hiliteBottom.visible = false;
            }

            stopScrolling();
        }
        //================================================================================================




        //================================================================================================
        //Item renderer code
        //================================================================================================              
        protected var _index:int = -1;

        public function get index():int
        {
            return this._index;
        }

        public function set index(value:int):void
        {
            if(this._index == value)
            {
                return;
            }
            this._index = value;
            this.invalidate(INVALIDATION_FLAG_DATA);
        }

        protected var _owner:List;

        public function get owner():List
        {
            return this._owner;
        }

        public function set owner(value:List):void
        {
            if(this._owner == value)
            {
                return;
            }
            this._owner = value;
            this.invalidate(INVALIDATION_FLAG_DATA);
        }

        protected var _data:Object;

        public function get data():Object
        {
            return this._data;
        }

        public function set data(value:Object):void
        {
            if(this._data == value)
            {
                return;
            }
            this._data = value;
            this.invalidate(INVALIDATION_FLAG_DATA);
        }

        protected var _isSelected:Boolean;

        public function get isSelected():Boolean
        {
            return this._isSelected;
        }

        public function set isSelected(value:Boolean):void
        {
            if(this._isSelected == value)
            {
                return;
            }
            this._isSelected = value;
            this.invalidate(INVALIDATION_FLAG_SELECTED);
            this.dispatchEventWith(Event.CHANGE);
        }
        protected var _label:Label;
        protected var _bgQuad:Quad;
        protected var _hiliteTop:Quad;
        protected var _hiliteBottom:Quad;
        protected var _dragHandle:Quad;
        protected var _dragHandleButton:starling.display.Button;

        override protected function initialize():void
        {   
            this._bgQuad = new Quad(1, 1, starling.utils.Color.SILVER);         
            this._bgQuad.alpha = 0.5;
            this.addChild(_bgQuad);

            this._label = new Label();
            this.addChild(this._label);

            this._hiliteTop = new Quad(100, 2, starling.utils.Color.YELLOW);
            this._hiliteTop.visible = false;
            this.addChild(_hiliteTop);
            this._hiliteBottom = new Quad(100, 2, starling.utils.Color.YELLOW);
            this._hiliteBottom.visible = false;         
            this.addChild(_hiliteBottom);

            var dragHandleTexture:Texture = Texture.fromBitmap(new DragHandle());
            var dragHandleDownTexture:Texture = Texture.fromBitmap(new DragHandleDown());
            _dragHandleButton = new starling.display.Button(dragHandleTexture, "", dragHandleDownTexture);
            this.addChild(_dragHandleButton);

            _dragHandleButton.addEventListener(TouchEvent.TOUCH, touchHandler);
        }

        protected function commitData():void
        {
            if(this._data)
            {
                this._label.text = this._data.text;
            }
            else
            {
                this._label.text = null;
            }
        }

        protected var _padding:Number = 5;

        public function get padding():Number
        {
            return this._padding;
        }

        public function set padding(value:Number):void
        {
            if(this._padding == value)
            {
                return;
            }
            this._padding = value;
            this.invalidate(INVALIDATION_FLAG_LAYOUT);
        }
        protected function autoSizeIfNeeded():Boolean
        {
            var needsWidth:Boolean = isNaN(this.explicitWidth);
            var needsHeight:Boolean = isNaN(this.explicitHeight);
            if(!needsWidth && !needsHeight)
            {
                return false;
            }

            this.explicitHeight = 50;
            this._label.width = this.explicitWidth - 2 * this._padding;
            this._label.height = this.explicitHeight - 2 * this._padding;
            this._label.validate();

            var newWidth:Number = this.explicitWidth;
            if(needsWidth)
            {
                newWidth = this._label.width + 2 * this._padding;
            }
            var newHeight:Number = this.explicitHeight;
            if(needsHeight)
            {
                newHeight = this._label.height + 2 * this._padding;
            }
            return this.setSizeInternal(newWidth, newHeight, false);
        }
        override protected function draw():void
        {
            var dataInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_DATA);

            if(dataInvalid)
            {
                this.commitData();
            }

            this.autoSizeIfNeeded();
            this.layoutChildren();
        }

        protected function layoutChildren():void
        {
            this._label.width = this.actualWidth - (2 * this._padding);
            this._label.height = this.actualHeight - (2 * this._padding);
            this._label.x = this._padding;
            this._label.y = 15;//(this.actualHeight / 2) - (this._label.height / 2);

            this._bgQuad.x = this._padding;
            this._bgQuad.y = this._padding;
            this._bgQuad.width = this.actualWidth - (2 * this._padding);
            this._bgQuad.height = this.actualHeight - (2 * this._padding);

            this._hiliteTop.x = 0;
            this._hiliteBottom.x = 0;
            this._hiliteTop.y = 0;
            this._hiliteBottom.y = this.height; //this.height - this._hiliteBottom.height;

            this._hiliteTop.width = this.width;
            this._hiliteBottom.width = this.width;

            this._dragHandleButton.x = this.width - this._dragHandleButton.width;
            this._dragHandleButton.y = (this.height / 2) - (this._dragHandleButton.height / 2);

        }

        //================================================================================================

    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top