Select multiple List items like in desktop application with selection rectangle(FLEX/AIR)
February 14th, 2010
Hi, guys. In Flex we often should use different kind of list and selection of multiple items little bit complex there, you should press CTRL(win) or COMMAND(mac os) button and then select items one by one. But what if you want select multiple items from list like you select icons on your desktop ?
For this we need our list, in this example i will use TileList and we need Canvas(we can customize it in whatever way we want). Canvas and TileList should be in one container.
Before starting i should admit that we can use two ways of items selection: first one is select all items that are inside our selection rectangle, second is select items when they intersects with selection rectangle. From experience for first one way, we should to reduce bounds of item to make it selection little bit easier, it will looks like on the picture below
But in demo you can see using of second way.
So every selection should start with mouse button down:
private function mouseDownS(event:MouseEvent):void{ // start selection only if we clicked on our List(not outside or it's items) if(event.target.parent != tileList) return; //storing point from where we will start selection selectionRectRightBottom = new Point(event.localX, event.localY); // disable interactions with all childrens(items) of list tileList.mouseChildren = false; // show our canvas rect selectRectCanvas.visible = true; selectRectCanvas.width = 0; selectRectCanvas.height = 0; // this is array for storing rectangles(bounds) of items for further comparing them and selection // but we will make them little bit smaller to make their selection easier animatedGridItemsRect = new Array(); // we should use this value if we will select items when they whole inside selection rectangle // if we will select items that will be selected just while intersection with selection rectangle this value should be 0 var RECT_PADDING_DELTA:Number = 0; var count:int = tileList.dataProvider.length; for(var i:int = 0; i < count; i++){ var data:Object = new Object(); var rendererRect:Rectangle = tileList.indexToItemRenderer(i).getRect(tileList); rendererRect.x += RECT_PADDING_DELTA; rendererRect.y += RECT_PADDING_DELTA; rendererRect.width -= RECT_PADDING_DELTA * 2; rendererRect.height -= RECT_PADDING_DELTA * 2; // here is we storing item data + item reducedd bounds data.rect = rendererRect; data.item = tileList.indexToItemRenderer(i).data; animatedGridItemsRect.push(data); } }
then continue selection when mouse moving:
private function mouseMoveS(e:MouseEvent):void{ if(!selectionRectRightBottom) return; // end-poing of our selection rectangle selectionRectLeftTop = new Point(tileList.mouseX, tileList.mouseY); // calculating selection rectangle height and width var selectionRectWidth:Number = -selectionRectRightBottom.x + selectionRectLeftTop.x; var selectionRectHeight:Number = -selectionRectRightBottom.y + selectionRectLeftTop.y; // set selection rect canvas size and position selectRectCanvas.width = selectionRectWidth; selectRectCanvas.height = selectionRectHeight; selectRectCanvas.x = selectionRectRightBottom.x + tileList.x; selectRectCanvas.y = selectionRectRightBottom.y + tileList.y; // getting Rectangle instance of selection canvas var selectRect:Rectangle = selectRectCanvas.getRect(tileList); // actually array that will contain indecies of newly selected items var newSelectedIndicies:Array = new Array(); var i:int = 0; for each(var itemData:Object in animatedGridItemsRect){ // we should use this line if we will select items when they whole inside selection rectangle //if(selectRect.containsRect(Rectangle(itemData.rect))) // we should use this line if we will select items that will be selected just while intersection with selection rectangle if(selectRect.intersects(Rectangle(itemData.rect))) newSelectedIndicies.push(i); i++; } tileList.selectedIndices = newSelectedIndicies; // force list to refresh tileList.invalidateDisplayList(); // call this for forcing flash to handle all stuff above after every mouse move e.updateAfterEvent(); }
and ends when mouse up:
private function mouseUpS():void{ // if mouse up, then restore all states selectionRectRightBottom = null; selectionRectLeftTop = null; tileList.mouseChildren = true; selectRectCanvas.visible = false; animatedGridItemsRect = null; }




