Flex Selection Rectangle

Selection Rectangles. Yup! Those things that come when you click and drag your mouse on your desktop. Well how do you implement them in a Flash/Flex environment? Pretty easy…

Click anywhere on the demo and drag to see the selection rectangle. On the top right, the number of items selected is displayed. Like it? Lets look at the code.

FlexSelectionRectangle.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="{init()}"
backgroundGradientAlphas="[1.0, 1.0]"
backgroundGradientColors="[#FFFFFF, #FFFFFF]" width="800" height="600">

<mx:Style>
.selectionRectangleStyle {
backgroundAlpha: 0.3;
backgroundColor: #067EE3;
borderColor: #FFFFFF;
borderStyle: inset;
borderThickness: 2;
cornerRadius: 0;
}
</mx:Style>

<mx:Script source="script.as"/>

<!-- A bunch of controls to play with -->
<mx:Button label="Button" horizontalCenter="26" verticalCenter="3"/>
<mx:Button label="Button" horizontalCenter="-197" verticalCenter="-193"/>
<mx:CheckBox label="Checkbox" horizontalCenter="166" verticalCenter="-218"/>
<mx:DataGrid horizontalCenter="219" verticalCenter="111">
<mx:columns>
<mx:DataGridColumn headerText="Column 1" dataField="col1"/>
<mx:DataGridColumn headerText="Column 2" dataField="col2"/>
<mx:DataGridColumn headerText="Column 3" dataField="col3"/>
</mx:columns>
</mx:DataGrid>
<mx:DateChooser horizontalCenter="-284" verticalCenter="6"/>
<mx:RadioButton label="Radio" horizontalCenter="155" verticalCenter="-157"/>
<mx:TextArea horizontalCenter="-39" verticalCenter="-181"/>
<mx:Label text="Click and drag to see a selection rectangle" fontSize="16"

horizontalCenter="3" verticalCenter="-72"/>
<mx:DateField horizontalCenter="-115" verticalCenter="36"/>
<mx:LinkButton label="LinkButton" horizontalCenter="-330" verticalCenter="-133"/>

<!-- To display some output -->
<mx:Label
id="output_txt"
right="10" top="10"
fontSize="14"
color="#00AED3" fontWeight="bold"/>
</mx:Application>

script.as

import mx.containers.Canvas;</span></span>

/* This canvas will act as the selection rectangle. */
private var selectionRectangle:Canvas;

/* A reference rectangle object to size my selection canvas */
private var r:Rectangle;

[Bindable] private var selectedItems:Array = new Array();

private function init():void {
/* Set the event listeners */
this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);

selectionRectangle = new Canvas();
selectionRectangle.setStyle("styleName", "selectionRectangleStyle");

r = new Rectangle(0,0,0,0);
}

private function onMouseDown(e:MouseEvent):void {
/* Instantiate the referece rectangle at the mouse-downed coordinates*/
r = new Rectangle(Number(e.stageX),Number(e.stageY),0,0);

//Apply the x,y,width and height properties to the canvas
selectionRectangle.x = r.x;
selectionRectangle.y = r.y;
selectionRectangle.width = r.width;
selectionRectangle.height = r.height;

//Add to stage
addChild(selectionRectangle);
}

private function onMouseUp(e:MouseEvent):void {
//Get an array of items on stage
var children:Array = this.getChildren();

selectedItems = new Array();

/* Find items that intersect with the selection rectangle */
for(var i:uint = 0; i< children.length; i++) {
if((children[i] as DisplayObject) != selectionRectangle)
if(selectionRectangle.getRect(this).intersects((children[i] as DisplayObject).getRect(this)))
selectedItems.push(children[i]);
}

//Remove the selection rectangle
removeChild(selectionRectangle);

//Show output
output_txt.text = selectedItems.length + " items selected";
}

private function onMouseMove(e:MouseEvent):void {
//Keep resizing the Rectangle object and the canva
r.bottomRight = new Point(e.stageX, e.stageY);

selectionRectangle.x = r.x;
selectionRectangle.y = r.y;
selectionRectangle.width = r.width;
selectionRectangle.height = r.height;
}

Lets start from the beginning. First, i set the event listeners for the MouseDown, MouseUp and MouseMove event. I’m using a Canvas object as the selection rectangle. It can be replaced with any custom component. And finally i have a Rectangle object.

On MouseDown, I instantiate the Rectangle object to the current mouse x and y co-ordinates. Then set the x, y, width and height of the canvas object to that of the rectangle object. Why am i doing this? Well you can try to do this without having a rectangle object. Try setting the Canvas’ properties directly from the MouseEvent.stageX and MouseEvent.localX values. It wont work. Try it out.

On MouseMove, the Rectangle object is resized and the values are reflected on the Canvas object.

On MouseDown, the selectedItems array is populated with all the children which came under the selection. Its done using the intersects() function of the Rectangle class. From here any function that implements some action to be taken on selection, can be called. The code might be kinda rough. I intend to polish it a bit and make it into a reusable component soon.

So there it is. Flex Selection Rectangle!

12 Comments

  1. arindam says:

    How can I do it in flash as2 or as3???

    Is you rectangular class it self drawing an rect object through drwaRect method??

  2. jeethu says:

    @arindam – The Rectangle class i’ve used above is only for reference. To obtain the width,height,x and y. The blue rectangle that appears is a Canvas. And btw try this link to do this in flash

    http://www.quasimondo.com/archives/000571.php

  3. Nicolas says:

    Legend. I wrote my own before finding this article, based on canvas as well, but missing one bit: I’ve been looking for this:

    if(selectionRectangle.getRect(this).intersects((children[i] as DisplayObject).getRect(this)))

    Cheers!

  4. jeethu says:

    Thanks Nicolas.

    If you found that useful, wait till you see a little selection rectangle swc that i’ll be posting in a couple of days… :)

  5. washington says:

    Hi Jeethu,

    Thanks for doing this. It’s amazing.

    Just wondering 2 things.

    1. How would I use it within a certain container? For example, another canvas. I tried changing the code from addChild(selectionRectangle) to canvas.addChild(selectionRectangle), however it doesn’t seem to be working. Any idea why?

    2. I’d like for the selectionRectangle to remain on the stage until the next mouseDown (so that the user knows the area that he/she has selected). Is there a way that that could be implemented?

    Thanks so much for everything. I’m still a beginner to Flex/AS3, so please forgive me if the answers to those questions seem obvious.

  6. parthiban says:

    Sir

    I want to know ” How to create or Make DESKTOP MARQUEE (i.e A NEWS CHANNEL SEE YOU, EXAMPLE : FLASH NEWS MOVING )

    please send the source code or exe file

    parthiban.k

  7. Elan says:

    Hi Jeethu,

    When i click my group button After selecting the items just i want to group them as single container and it should be revert when i click ungroup button.how do i do it give me some clue.

    Thanks,
    Elan.

  8. jeethu says:

    @Elan After the selection the selected items are available in the array called ’selectedItems’ as per my code. What you can do is, add these items to a container( a canvas maybe ) when the ‘group’ button is clicked on. The reverse applies for ‘ungroup’. Use the globalToLocal, localToGlobal, etc. functions to set the x and y of the items during both grouping and ungrouping… for a demo take a look at Stickies in Sync, http://blog.jeethukarthik.com/adobe-riathon-08/ .I built this app a long time ago….

  9. BlackScorp21 says:

    Hi!

    Es ist zwar schon ein wenig her das du das hier reingestellt hast. Hätte da aber trotzdem ne Frage zu.
    Habe mir das gerade mal angesehen. Wenn ich eine Ausgabe mache, welche Elemente ausgewählt wurden, schreibt er immer den Klassenamen davor.

    Also z.B. Klassename.Button1

    Sehe irgendwie nicht das du das programmiert hast. Ist das Standard in flex oder finde ich nur die Stelle im Code nicht.

    Ich bräuchte dann ja den Namen des Objektes (ohne Klassenamen) damit ich dieses ansprechen kann. Zum Beispiel das es sich nach Rechts bewegen soll.

    Kannst du mir da helfen? Oder jmd anders?
    Danke

  10. Baycik says:

    Thanks a lot. You saved much of my time.

  11. Sai says:

    Hey jeethu,

    Thanks for then nice post, it is helping me now, but when i try to draw a rect on the image i encounter a few problems, the x and y values will be greater than where i clicked on the image, always.

    is there a solution for this.

  12. @Sai You might be nesting the selection rectangle within some container. That may be the problem

Leave a Reply


Creative Commons License