adobe flex draggable panel

adobe flex draggable panel

Postby haretu » Thu Apr 07, 2011 10:01 am

Flex application to be able to move and resize components at runtime so that the user could lay out the components however they wanted. This application lets the user move, resize, and minimize Panel containers much in the way you can in any windowing environment. While this application uses Panel containers, you could generalize it to for any Flex components.

To use it:

- Click down in the header area of a Panel to drag it around the application. Release the mouse when it is where you want it.

- Click down on the lower-right corner of the Panel to resize it. Release the mouse when it is the size you want. You can not set it to a size smaller than 50 pixes high and 150 pixels wide.

- Click the Minimize/Restore icons to hide/show the body area of the Panel.

The following application shows this functionality:
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
   xmlns:myComp="myComponents.*"
   creationComplete="creationCompleteHandler();">

    <mx:Script>
        <![CDATA[
            import mx.managers.DragManager;
            import mx.core.DragSource;
            import mx.events.DragEvent;
            import flash.events.MouseEvent;
            import mx.containers.Canvas;
            import mx.containers.Panel;
         import myComponents.DragPanel;

         // Define static constant for event type.
         public static const RESIZE_CLICK:String = "resizeClick";

         // Creation complete event handler adds the resizing event.
         // resizeButtonClicked is a custom event type for this application.
         protected function creationCompleteHandler():void
         {
            addEventListener(RESIZE_CLICK, resizeHandler);
         }

//
// D&D event handlers.
//

            // Creation complete handler for each panel to add the
            // mouseMove event handler to the title bar.
            // Clicking the mouse button, then moving the mouse on the title bar
            // initiates the d&d operation.
            private function myPanelCCHandler(event:Event):void
            {
               event.currentTarget.myTitleBar.addEventListener(MouseEvent.MOUSE_DOWN, tbMouseMoveHandler);
            }

            // Variables used to hold the mouse pointer's location in the title bar.
            // Since the mouse pointer can be anywhere in the title bar, you have to
            // compensate for it when you drop the panel.
            public var xOff:Number;
            public var yOff:Number;
           
            // Function called by the canvas dragEnter event; enables dropping
            private function doDragEnter(event:DragEvent):void
            {
                DragManager.acceptDragDrop(Canvas(event.target));
            }

            // Drag initiator event handler for
            // the title bar's mouseMove event.
            private function tbMouseMoveHandler(event:MouseEvent):void
            {
                var dragInitiator:Panel=Panel(event.currentTarget.parent);
                var ds:DragSource = new DragSource();
                ds.addData(event.currentTarget.parent, 'panel');
               
               // Update the xOff and yOff variables to show the
               // current mouse location in the Panel. 
                xOff = event.currentTarget.mouseX;
                yOff = event.currentTarget.mouseY;
               
                // Initiate d&d.
                DragManager.doDrag(dragInitiator, ds, event);                   
            }           

            // Function called by the Canvas dragDrop event;
            // Sets the panel's position,
            // "dropping" it in its new location.
            private function doDragDrop(event:DragEvent):void
            {
            // Compensate for the mouse pointer's location in the title bar.
            var tempX:int = event.currentTarget.mouseX - xOff;
            event.dragInitiator.x = tempX;
            
            var tempY:int = event.currentTarget.mouseY - yOff;
            event.dragInitiator.y = tempY;
            
            // Put the dragged panel on top of all other components.
            v1.setChildIndex(Panel(event.dragInitiator), v1.numChildren-1);         
            }

//
// Resizing event handlers.
//

         // Save panel being resized.
         protected var resizingPanel:Panel;
         // Global coordinates of lower left corner of panel.
         protected var initX:Number;
         protected var initY:Number;

         // Resize area of panel clicked.
         protected function resizeHandler(event:MouseEvent):void
         {
            resizingPanel = Panel(event.target);
            initX = event.localX;
            initY = event.localY;
            
            // Place the rubber band over the panel.
            rbComp.x = event.target.x;
            rbComp.y = event.target.y;
            rbComp.height = event.target.height;
            rbComp.width = event.target.width;
            
            // Make sure rubber band is on top of all other components.
            v1.setChildIndex(rbComp, v1.numChildren-1);
            rbComp.visible=true;
            
            // Add event handlers so that the SystemManager handles
            // the mouseMove and mouseUp events.
            // Set useCapure flag to true to handle these events
            // during the capture phase so no other component tries to handle them.
            systemManager.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
            systemManager.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
         }
         
         // Resizes the rubber band as the user moves the cursor
         // with the mouse key down.
         protected function mouseMoveHandler(event:MouseEvent):void
         {
               event.stopImmediatePropagation();      
                  
               rbComp.height = rbComp.height + event.stageY - initY; 
               rbComp.width = rbComp.width + event.stageX - initX;
               
               initX = event.stageX;
               initY = event.stageY;                  
         }
         
         // Sizes the panel to the size of the rubber band when the
         // user releases the mouse key.
         // Also removes the event handlers from the SystemManager.
         protected function mouseUpHandler(event:MouseEvent):void
         {
            event.stopImmediatePropagation();      

            // Use a minimum panel size of 150 x 50.
            if (rbComp.height <= 50)
            {
               resizingPanel.height = 50; 
            }
            else
            {
               resizingPanel.height = rbComp.height;              
            }            
            
            if (rbComp.width <= 150)
            {
               resizingPanel.width = 150;            
            }
            else
            {
               resizingPanel.width = rbComp.width;            
            }            

            // Put the resized panel on top of all other components.
            v1.setChildIndex(resizingPanel, v1.numChildren-1);

            // Hide the rubber band until next time.
            rbComp.x = 0;
            rbComp.y = 0;
            rbComp.height = 0;
            rbComp.width = 0;
            rbComp.visible = false;
            
            systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
            systemManager.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true   );
         }
        ]]>
    </mx:Script>
   
    <!-- The Canvas is the drag target -->
    <mx:Canvas id="v1"
        width="500" height="500" 
        borderStyle="solid"
        backgroundColor="#DDDDDD"
        dragEnter="doDragEnter(event);"
        dragDrop="doDragDrop(event);">
               
    <myComp:DragPanel  id="dp1" title="Drag Panel 1"
       paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"
       x="19" y="10"
       creationComplete="myPanelCCHandler(event);">
      <mx:TextArea text="Location in Canvas: x = {String(dp1.x)}, and y = {String(dp1.y)}" width="90%"/>
    </myComp:DragPanel>

    <myComp:DragPanel  id="dp2"  title="Drag Panel 2"
       paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"
       x="149" y="149"
       creationComplete="myPanelCCHandler(event);">
      <mx:TextArea text="Location in Canvas: x = {String(dp2.x)}, and y = {String(dp2.y)}" width="90%"/>                   
    </myComp:DragPanel>

    <myComp:DragPanel id="dp3"  title="Drag Panel 3"
       paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"
        x="241" y="283"
       creationComplete="myPanelCCHandler(event);">
      <mx:TextArea text="Location in Canvas: x = {String(dp3.x)}, and y = {String(dp3.y)}" width="90%"/>                   
    </myComp:DragPanel>

    <myComp:RubberBandComp id="rbComp" x="0" y="0" height="0" width="0" visible="false"/>

    </mx:Canvas>
</mx:Application>

Code: Select all
package myComponents
{
   import mx.containers.Panel;
   import mx.core.UIComponent;
   import mx.core.SpriteAsset;
   import mx.events.FlexEvent;
   import flash.events.MouseEvent;
   import flash.events.Event;

   public class DragPanel extends Panel
   {
      // Add the creationCOmplete event handler.
      public function DragPanel()
      {
         super();
         addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
      }
      
      // Expose the title bar property for draggin and dropping.
      [Bindable]
      public var myTitleBar:UIComponent;
               
      private function creationCompleteHandler(event:Event):void
      {
         myTitleBar = titleBar;         
         // Add the resizing event handler.   
         addEventListener(MouseEvent.MOUSE_DOWN, resizeHandler);
      }

      protected var minShape:SpriteAsset;
      protected var restoreShape:SpriteAsset;

      override protected function createChildren():void
      {
            super.createChildren();
         
         // Create the SpriteAsset's for the min/restore icons and
         // add the event handlers for them.
         minShape = new SpriteAsset();
         minShape.addEventListener(MouseEvent.MOUSE_DOWN, minPanelSizeHandler);
         titleBar.addChild(minShape);

         restoreShape = new SpriteAsset();
         restoreShape.addEventListener(MouseEvent.MOUSE_DOWN, restorePanelSizeHandler);
         titleBar.addChild(restoreShape);
      }
         
      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
      {
         super.updateDisplayList(unscaledWidth, unscaledHeight);
         
         // Create invisible rectangle to increase the hit area of the min icon.
         minShape.graphics.clear();
         minShape.graphics.lineStyle(0, 0, 0);
         minShape.graphics.beginFill(0xFFFFFF, 0.0);
         minShape.graphics.drawRect(unscaledWidth - 35, 12, 8, 8);

         // Draw min icon.
         minShape.graphics.lineStyle(2);
         minShape.graphics.beginFill(0xFFFFFF, 0.0);
         minShape.graphics.drawRect(unscaledWidth - 35, 18, 8, 2);
            
         // Draw restore icon.
         restoreShape.graphics.clear();
         restoreShape.graphics.lineStyle(2);
         restoreShape.graphics.beginFill(0xFFFFFF, 0.0);
         restoreShape.graphics.drawRect(unscaledWidth - 20, 12, 8, 8);
         restoreShape.graphics.moveTo(unscaledWidth - 20, 15);
         restoreShape.graphics.lineTo(unscaledWidth - 12, 15);

         // Draw resize graphics if not minimzed.            
         graphics.clear()
         if (isMinimized == false)
         {
            graphics.lineStyle(2);
            graphics.moveTo(unscaledWidth - 6, unscaledHeight - 1)
            graphics.curveTo(unscaledWidth - 3, unscaledHeight - 3, unscaledWidth - 1, unscaledHeight - 6);                  
            graphics.moveTo(unscaledWidth - 6, unscaledHeight - 4)
            graphics.curveTo(unscaledWidth - 5, unscaledHeight - 5, unscaledWidth - 4, unscaledHeight - 6);                  
         }
      }
               
      private var myRestoreHeight:int;
      private var isMinimized:Boolean = false;
               
      // Minimize panel event handler.
      private function minPanelSizeHandler(event:Event):void
      {
         if (isMinimized != true)
         {
            myRestoreHeight = height;   
            height = titleBar.height;
            isMinimized = true;   
            // Don't allow resizing when in the minimized state.
            removeEventListener(MouseEvent.MOUSE_DOWN, resizeHandler);
         }            
      }
      
      // Restore panel event handler.
      private function restorePanelSizeHandler(event:Event):void
      {
         if (isMinimized == true)
         {
            height = myRestoreHeight;
            isMinimized = false;   
            // Allow resizing in restored state.            
            addEventListener(MouseEvent.MOUSE_DOWN, resizeHandler);
         }
      }

      // Define static constant for event type.
      public static const RESIZE_CLICK:String = "resizeClick";

      // Resize panel event handler.
      public  function resizeHandler(event:MouseEvent):void
      {
         // Determine if the mouse pointer is in the lower right 7x7 pixel
         // area of the panel. Initiate the resize if so.
         
         // Lower left corner of panel
         var lowerLeftX:Number = x + width;
         var lowerLeftY:Number = y + height;
            
         // Upper left corner of 7x7 hit area
         var upperLeftX:Number = lowerLeftX-7;
         var upperLeftY:Number = lowerLeftY-7;
            
         // Mouse positionin Canvas
         var panelRelX:Number = event.localX + x;
         var panelRelY:Number = event.localY + y;

         // See if the mousedown is in the lower right 7x7 pixel area
         // of the panel.
         if (upperLeftX <= panelRelX && panelRelX <= lowerLeftX)
         {
            if (upperLeftY <= panelRelY && panelRelY <= lowerLeftY)
            {      
               event.stopPropagation();      
               var rbEvent:MouseEvent = new MouseEvent(RESIZE_CLICK, true);
               // Pass stage coords to so all calculations using global coordinates.
               rbEvent.localX = event.stageX;
               rbEvent.localY = event.stageY;
               dispatchEvent(rbEvent);   
            }
         }            
      }      
   }
}

Code: Select all
package myComponents
{
   import mx.core.UIComponent;

   public class RubberBandComp extends UIComponent
   {
      public function RubberBandComp()
      {
         super();
      }

      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
      {
         super.updateDisplayList(unscaledWidth, unscaledHeight);
            
         // Draw rubber band with a 1 pixel border, and a grey fill.             
         graphics.clear();                        
         graphics.lineStyle(1);
         graphics.beginFill(0xCCCCCC, 0.5);
         graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
      }
      
   }
}
Attachments
Screen shot 2011-04-07 at 9.56.40 AM.jpg
Screen shot 2011-04-07 at 9.56.40 AM.jpg (25.91 KiB) Viewed 1190 times
haretu
 
Posts: 132
Joined: Sat Jan 08, 2011 9:56 pm

Return to Adobe FLEX Flash

Who is online

Users browsing this forum: No registered users and 1 guest

cron