Menu

List DragDrop Specification

SourceForge Editorial Staff

List DragDrop Specification

Functional and Design Specification


Glossary


  • DND - Drag and Drop
  • Drag initiator - the component that initiates the drag operation. For example the List monitors the mouse gestures and upon detecting mouse down, mouse move it may start a drag operation if specific conditions are met.
  • Potential drop target - the component under the mouse pointer during a drag operation.
  • Drop target - the potential drop target which has signaled that it can accept the drop operation. The drop target signals in response to events dispatched by the drag proxy via APIs on the drag manager.
  • Drag proxy - the component instance that monitors the mouse gestures during the drag operation and positions itself to indicate the dragged items. The drag proxy is created by the drag manager when the DND process is started by the initiator.
  • Drag indicator - the component which displays the dragged items, it is a child of the drag proxy. Usually created by the drag initiator as part of the DND start.
  • Drag manager - a manager class used by the drag initiator to start the dragging process and also used by the drop target to signal accept/reject of the dragged items.
  • Drop indicator - a component that is positioned and displayed by the drop target to indicate the insertion index if the dragged items are dropped.
  • Drag scrolling - auto-scrolling of the drop target's viewport in response to the mouse pointer being close to the container borders during DND.

Summary and Background


The MX architecture has drag and drop support. Components extending mx:ListBase have default implementation with suitable APIs and user hooks.

This feature deals with leveraging the MX DND architecture to provide implementation for default DND support for the Spark List component. In addition, new DND related APIs will be introduced to support the Spark's pillar principles of skinning and modularity.

Goals
  • Consistency - DND support on par with mx:ListBase - Spark List should provide same public APIs (dragEnabled, dropEnabled, dragMoveEnabled, drag event handlers, etc.)
  • Interoperability - seamless cross-architecture DND between Halo and Spark components. No additional efforts to enable cross-architecture DND scenarios.
  • Modularity - spark layout APIs should be extended and default implementations should be provided to allow the spark List DND implementation to work seamlessly with custom layouts that implement the appropriate APIs.
  • Skinning - allow customization of the drag indicator and drop indicator look. Should not require subclassing for most common tasks and should fit well within the Spark skinning architecture.
Non-goals
  • DND support for spark components other than List.
  • Live preview of the drop (layout data effects).
  • Customizations to the drop indicator behaviors (animations, sizing, positioning).
  • Highly customizable drag-scroll behavior (anything beyond 'number of items' and 'delay' is a non-goal).
  • Exact same behavior as the mx:ListBase implementation - there's no need to match all the details - default proxy may look different, mouse gestures may have subtle differences, etc.
B Features
  • Specify / turn off the default animation effects (zoom on drop, move on cancel) for the drag proxy.
  • Control drag-scroll behavior - delay, duration, number of rows scrolled, etc.
  • A new property "dragReorderEnabled" added to List.

Usage Scenarios


Primary

1. DND between Halo/Spark Lists with same data format.

  • The user sets the following properties on the containers: dragEnabled="true", dropEnabled="true". Same as with MX List.

2. DND between Halo/Spark Lists with different data formats.

  • The user overrides the "dragDrop" event to perform the conversion.
  • The user call the preventDefault() method on the event.
  • The user needs to appropriately hide the drop feedback and reset drag scrolling.
    • The user calls fooList.layout.hideDropIndicator() public API to do so.
    • The user calls DragManager.showFeedback() public API to reset the feedback.

3. DND between multiple Halo/Spark Lists where only particular components have compatible data formats.

  • The user overrides both "dragEnter" and "dragOver" events to validate data format compatibility and set the appropriate feedback on the DragManager.
  • The user calls preventDefault() on the events.
  • The user needs to appropriately show/hide the drop feedback and reset drag scrolling.
    • The user calls fooList.layout.showDropIndicator() / hideDropIndicator() to do so.

4. Customizing the drag indicator (the appearance of the item renderers for the dragged items)

  • The user creates a custom ItemRenderer and fleshes out the optional "dragging" state.

6. Specifying the default dragIndicator Class

  • For example a desired behavior may be to display a static image for a dragProxy when dragging from particular drag initiator.
  • For Spark List - the user sets the style "dragIndicatorClass".
    • By default the static image is aligned with the top-left corner of the Spark List. To override this, the user will have to either add a startDrag handler in mxml or subclass and override the default startDrag handler. Details further below in "issues and Recommendations" section.
  • For MX Lists - the user subclasses the MX component and override the public function get dragImage() method to return the desired class instance.

7. Subclassing the default drag indicator class

  • For example a desired behavior may be to see the item renderers for the dragged items, but arrange/size them differently, perhaps the dragged items stacked on top of each other.
  • The user subclasses the spark.components.supportClasses.ListItemDragProxy class and overrides the createChildren() method to modify/arrange the item renderers.
  • The user sets the "dragIndicatorClass" style for the spark List.

8. Customizing the drop indicator.

  • The user specifies the optional skin part "dropIndicator" in the drop target's skin.
  • The part is specified in <fx:declarations> tag since it's dynamic, similarly to the dataTip skin part in the HSliderSkin.</fx:declarations>
  • Drop indicator sizing rules and user control
    • The size of the drop indicator is always determined by the layout
    • If the drop indicator implements the ILayoutManagerClient, then it will be validated after its width, height, x, y are set by the layout.
    • For example, the user can specify a Group container with visuals for the dropIndicator and use the Group's layout to configure the visuals of the drop indicator.

9. Add DND support for a custom layout class.

  • The user implements the DND API methods on the layout to calculate the drop index, size and position the drop indicator and control drag-scrolling.
  • The user sets an instance of their custom layout class as the layout of the List that's going to act as a drop target.

Detailed Description


Spark List DND support

The Spark List will implement the familiar DND APIs from the MX ListBase. These APIs will be hidden/unavailable for the DropDownList class. The APIs will pretty much follow the MX ListBase class DND related APIs, more detail in the API section.

Customizing the Drag Indicator
  • One new optional skin state will be added to the ItemRenderer class - the "dragging" state.
    • The IItemRenderer interface will be extended with a new boolean property "dragging".
    • If the "dragging" property is set, but an item renderer doesn't define the optional state, it will default to its "normal" state.
  • A new spark ListItemDragProxy class will be created: spark.components.supportClasses.ListItemDragProxy extends Group.
    • Default implementation of the ListItemDragProxy createChildren() method will create duplicate IItemRenderer instances for all dragInitiator ItemRenderers that are selected and visible (within the bounds of the viewport).
    • ListItemDragProxy will size and position the IItemRenderer instances the same way as the originals.
    • The default implementation of the ListItemDragProxy will not clip to the bounds of the drag initiator.
    • The items from the original ItemRenderers will be also set as data for the new ListItemDragProxy ItemRenderers.
  • A new style "dragIndicatorClass" will be introduces for Spark List. The style will default to the "spark.components.supportClasses.ListItemDragProxy" class.
  • In the default dragStart handler the spark List will create an instance of the class specified by the "dragIndicatorClass" style.
    • If the class specified by the dragIndicatorClass style implements IVisualElement, then the List sets the instance's owner property to the the List itself.
    • The List then passes the dragIndicatorClass instance to the DragManager. The DragManager adds the drag indicator as a child of the DragProxy and validates it.
    • When the ListItemDragProxy instance is validated its createChildren() method is called. it looks up its owner List, its selection, etc. to create the item renderer copies as described above.

Two cases to note with the default implementation of the ListItemDragProxy:

  • If there's a very large item that is partially visible in the drag initiator, then it will be fully visible in the drag indicator.
  • When dragging multiple selected items where not all of them are visible in the drag initiator, only those that were visible will be shown in the drag indicator. The user will have no indication that there are additional items being dragged (the ones that were scrolled out of view when the drag was initiated).
Customizing the DropIndicator
  • A new optional dynamic skin part "dropIndicator" will be added to the Spark List class.
    • Minimum required type is DisplayObject.
    • The default Spark skin will be updated to include that part.
    • The default Wireframe skin will be updated to include that part.
  • The default implementation of the Spark List will respond to "dragEnter", "dragOver" and "dragExit" events by creating, moving and destroying the dropIndicator part.
    • The calculations where to show and how to position/resize the part will be delegated to the layout as described further below.
    • The auto-scroll behavior will be delegated to the layout.
GroupBase Overlay APIs

GroupBase will define overlay APIs. The overlay is a virtual display list of DisplayObjects that always render on top of the rest of the group's elements. This feature is required for the display of a drop indicator. It will also be used internally for mask, focus. Other use cases could be additional decorations like watermark for example.

  • A new property "overlay" will be added to GroupBase which will give access to the overlay list.
  • The primary way to order the objects in the overlay list will be by specifying "depth" for each object. The list will be automatically sorted based on "depth" and the objects will be rendered on top of the Group's content.
  • There will be pre-defined depth constants for objects that the SDK adds such as focus, mask, drop indicator.
  • Unlike the content, the objects in the overlay list will not be managed by the regular layout measure(), updateDisplayList().
  • Objects in the overlay list will not be accounted for by the Group content APIs (numElements, getElementAt(), etc.)
Layout APIs and communication with the DropTarget

The BasicLayout defines two sets of DND related APIs. To minimize the calculations for multiple calls between the List and the layouts a DropLOcation class is introduced.
When a List receives an event, it calls the layout to compute the DropLocation, examines the location and passes back the to the layout to request subsequent operations like displaying the drop indicator.

Public layout APIs, used by the Spark List, as well as other custom components that rely on layouts for DND functionality.

  • Get information related to a DragEvent
    • Fills in an instance of the DropLocation class.
    • The information contained is drop index, related elements, point in target coordinates space.
    • Caller examines information and passes it along to other DND APIs
  • Show the drop indicator for particular DropLocation instance (drag-scrolling is started if necessary).
  • Hide the drop indicator (drag-scrolling is stopped if underway).

Protected layoutAPIs, used by the concrete Spark Layouts, as well as custom layouts to implement the DND functionality.

  • Calculate the insertion index for the drop target from a DragEvent.
    • VerticalLayout
    • If the mouse is over an element with index "i", then the dropIndex is "i" if the mouse point is in the upper half of the element, else the dropIndex is "i+1"
    • If the mouse is not over an element, then the dropIndex is "i", where "i" is the index of the closest, in vertical direction, element below the mouse pointer, or numElements if no such element is found.
    • HorizontalLayout
    • Same as VerticalLayout, but in the horizontal direction respectively.
    • TileLayout, orientation = "rows", mouse pointer is within a cell(row, column) with index "i"
    • If the mouse pointer is to the left of the mid-column, then the insertion index is "i", else "i+1"
    • TileLayout, orientation = "columns" - similarly to orientation = "row", but in the vertical direction.
  • Calculate the size and position of a drop indicator for a particular DropLocation. For VerticalLayout, HorizontalLayout, TileLayout:
    • DropIndicator is sized as big as the gap between the elements, corresponding to the dropIndex.
    • The min and max size settings of the dropIndicator are respected in the major axis only. For example the dorpIndicator for a VerticalLayout will have its minHeight, maxHeight respected, but minWidth, maxWidth ignored.
    • The drop indicator is positioned so that it's centered on the gap, or if the gap is negative, it's centered on the bottom/right edge of the preceding element.
    • When the drop indicator is being positioned between an element and the container edge, it is nudged so that it overlaps only 1 pixel with the container edge.
  • Calculate the scroll position delta for dragScrolling for a particular DropLocation. For Vertical/Horizontal/Tile:
    • When the mouse pointer is within a predefined region of the container edge, then drag scrolling delta is calculated. Scrolling delta is variable to provide scrolling acceleration:
    • Acceleration with time - the drag-scroll delta gradually increases with the square of the time during the first 2 seconds of scrolling.
    • Acceleration with distance - the drag-scroll delta gradually increases with the square of the distance to the container edge.

Note that some custom layouts may choose to override the method that instantiates the DropLocation in order to subclass it and add additional data.

Drag and Drop data format

The default Halo DND data format is "items". It is represented by a handler that returns and Array of the selected items in reverse order of their selection.

The default Spark DND data format is going to be "orderedItems", and "orderedItemsCaretIndex"

  • "orderedItems" will be represented by a handler that returns a Vector.<object> of the selected items, preserving their order as it was in the source container.
  • "orderedItemsCaretIndex" will be represented by the index of item that was clicked with the mouse. The index is relative to the "orderedItems" Vector.
  • Upon drop, the items will be inserted in the order they appear in the "orderedItems" Vector.
  • When dropping in Spark container, the selection and scroll position are adjusted:
    • If the target supports multiple selection, then the selection is changed to the dropped items.
    • If the target doesn't support multiple selection, then the item that was clicked with the mouse becomes the new selection.
    • The scroll position is adjusted so that the item that was clicked with the mouse is made fully visible within the target container.
  • Compatibility:

    • The Halo legacy data format and behavior will continue to function unchanged.
    • The Halo ListBase container will be extended to support the new format (both during dragging and dropping).
    • The Spark List container will support only the new format.

    API Description


    Spark List
    // SparkList alaredy extends UIComponent, so it inherits the DragEvent metadata:
    // <a href="Event%28name%3D%26quot%3BdragEnter%26quot%3B%2C%20type%3D%26quot%3Bmx.events.DragEvent%26quot%3B%29">Event(name="dragEnter", type="mx.events.DragEvent")</a>
    // <a href="Event%28name%3D%26quot%3BdragOver%26quot%3B%2C%20type%3D%26quot%3Bmx.events.DragEvent%26quot%3B%29">Event(name="dragOver", type="mx.events.DragEvent")</a>
    // <a href="Event%28name%3D%26quot%3BdragExit%26quot%3B%2C%20type%3D%26quot%3Bmx.events.DragEvent%26quot%3B%29">Event(name="dragExit", type="mx.events.DragEvent")</a>
    // <a href="Event%28name%3D%26quot%3BdragDrop%26quot%3B%2C%20type%3D%26quot%3Bmx.events.DragEvent%26quot%3B%29">Event(name="dragDrop", type="mx.events.DragEvent")</a>
    // <a href="Event%28name%3D%26quot%3BdragComplete%26quot%3B%2C%20type%3D%26quot%3Bmx.events.DragEvent%26quot%3B%29">Event(name="dragComplete", type="mx.events.DragEvent")</a>
    // <a href="Event%28name%3D%26quot%3BdragStart%26quot%3B%2C%20type%3D%26quot%3Bmx.events.DragEvent%26quot%3B%29">Event(name="dragStart", type="mx.events.DragEvent")</a>
    
    
    //--------------------------------------
    //  Styles
    //--------------------------------------
    
    /**
     *  The class to create instance of for the drag proxy during drag
     *  and drop operations initiated by the List.
     *
     *  Must be of type <code>IFlexDisplayObject</code>.
     *
     *  If the class implements the <code>ILayoutManagerClient</code> interface,
     *  then the instance will be validated by the DragManager.
     *
     *  If the class implements the <code>IVisualElement</code> interface,
     *  then the instance's <code>owner</code> property will be set to the List
     *  that initiates the drag.
     *
     *  The AIR DragManager takes a snapshot of the instance, while
     *  the non-AIR DragManager uses the instance directly.
     *
     *  @default spark.components.supportClasses.ListItemDragProxy
     *
     */
    <a href="Style%28name%3D%26quot%3BdragIndicatorClass%26quot%3B%2C%20type%3D%26quot%3BClass%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="dragIndicatorClass", type="Class", inherit="no")</a>
    
    
    
    
    public class List extends ListBase implements IFocusManagerComponent
    {
    
        ...
    
        <a href="SkinPart%28required%3D%26quot%3Bfalse%26quot%3B%2C%20type%3D%26quot%3Bmx.core.IVisualElement%26quot%3B%29">SkinPart(required="false", type="mx.core.IVisualElement")</a>
        // Should this be also a DisplayObject?
    
        /**
         *  A skin part that defines a drop indicator that shows where the drag items
         *  will be inserted if the user releases the mouse to complete the drag drop operation.
         *
         *  This is a dynamic skin part and must be of type IFactory.
         */
        public var dropIndicator:IFactory;
    
    
        //--------------------------------------------------------------------------
        //
        //  Properties
        //
        //--------------------------------------------------------------------------
    
    
        public function get dragEnabled():Boolean;
        public function set dragEnabled(value:Boolean):void;
    
        /**
         *  A flag that indicates whether items can be moved instead
         *  of just copied from the control as part of a drag-and-drop
         *  operation.
         *  If <code>true</code>, and the <code>dragEnabled</code> property
         *  is <code>true</code>, items can be moved.
         *  Often the data provider cannot or should not have items removed
         *  from it, so a MOVE operation should not be allowed during
         *  drag-and-drop.
         *
         *  @default false
         */
        public function get dragMoveEnabled():Boolean;
        public function set dragMoveEnabled(value:Boolean):void;
    
        public function get dropEnabled():Boolean;
        public function set dropEnabled(value:Boolean):void;
    
    
        //--------------------------------------------------------------------------
        //
        //  Methods: Drag and drop
        //
        //--------------------------------------------------------------------------
    
    
        /**
         *  Adds the selected items to the DragSource object as part of a
         *  drag-and-drop operation.
         *  Override this method to add other data to the drag source.
         * 
         *  @param dragSource The DragSource object to which to add the data.
         */
        public function addDragData(dragSource:DragSource):void;
    
    
        /**
         *  The default handler for the <code>dragStart</code> event.
         *
         *  @param event The DragEvent object.
         */
        protected function dragStartHandler(event:DragEvent):void
    
    
        /**
         *  Handles <code>DragEvent.DRAG_COMPLETE</code> events.  This method
         *  removes the item from the data provider.
         *
         *  @param event The DragEvent object.
         */
        protected function dragCompleteHandler(event:DragEvent):void
    
        /**
         *  Handles <code>DragEvent.DRAG_ENTER</code> events.  This method
         *  determines if the DragSource object contains valid elements and uses
         *  the <code>DragManager.showDropFeedback()</code> method to set up the 
         *  UI feedback as well as the <code>layout.showDropIndicator()</code> method
         *  to display the drop indicator and initiate drag scrolling.
         *
         *  @param event The DragEvent object.
         */
        protected function dragEnterHandler(event:DragEvent):void
    
    
        /**
         *  Handles <code>DragEvent.DRAG_OVER</code> events. This method
         *  determines if the DragSource object contains valid elements and uses
         *  the <code>showDropFeedback()</code> method to set up the UI feedback 
         *  as well as the layout's <code>showDropIndicator()</code> method
         *  to display the drop indicator and initiate drag scrolling.
         *
         *  @param event The DragEvent object.
         */
        protected function dragOverHandler(event:DragEvent):void
    
        /**
         *  Handles <code>DragEvent.DRAG_EXIT</code> events. This method hides
         *  the UI feedback by calling the <code>hideDropFeedback()</code> method
         *  and also hides the drop indicator by calling the layout's 
         *  <code>hideDropIndicator()</code> method.
         *
         *  @param event The DragEvent object.
         *  
         */
        protected function dragExitHandler(event:DragEvent):void
    
        /**
         *  Handles <code>DragEvent.DRAG_DROP events</code>. This method  hides
         *  the drop feedback by calling the <code>hideDropFeedback()</code> method.
         *
         *  <p>If the action is a <code>COPY</code>, 
         *  then this method makes a deep copy of the object 
         *  by calling the <code>ObjectUtil.copy()</code> method, 
         *  and replaces the copy's <code>uid</code> property (if present) 
         *  with a new value by calling the <code>UIDUtil.createUID()</code> method.</p>
         * 
         *  @param event The DragEvent object.
         *
         *  @see mx.utils.ObjectUtil
         *  @see mx.utils.UIDUtil
         *  
         */
        protected function dragDropHandler(event:DragEvent):void
    
        ...
    
    }
    
    IItemRenderer
    public interface IItemRenderer extends IDataRenderer, IVisualElement
    {
    
        ...
    
        /**
         *  True, when the ItemRenderer is displaying the item in
         *  a drag proxy, while the item is being dragged.
         *
         */
        function get dragging():Boolean;
        function set dragging(value:Boolean):void;
    
        ...
    
    }
    
    
    // And the resulting states are:
    
    
    <s:ItemRenderer focusEnabled="false" 
            xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark">
        <s:states>
            <s:State name="normal" />            
            <s:State name="hovered" />
            <s:State name="selected" />
            <s:State name="normalAndShowsCaret" />
            <s:State name="hoveredAndShowsCaret" />
            <s:State name="selectedAndShowsCaret" />
            <s:State name="dragging" />
        </s:states>
    
        ...
    
    </s:ItemRenderer>
    
    ListItemDragProxy
    package spark.components.supportClasses
    {
    
    /**
     *  The default drag proxy used when dragging from a list-based control.
     *  A drag proxy is a component that parents the objects
     *  or copies of the objects being dragged.
     *
     *  <p><code>List</code> instantiates this class and sets the owner property
     *  to point back to the <code>List</code>.
     *  This class, when validated by the DragManager, looks up its <code>owner</code>
     *  property and creates item renderers for all the selected visible items in
     *  the owner <code>List</code>.</p>
     *
     *  <p>Creates copies of the item renderers and adds them as children in createChildren().
     *  Override the createChildren() method to insert additional initialization logic.</p>
     *
     *  <p>The drag initiator component creates an instance of the ListItemDragProxy.
     *  The owner property is set to the drag initiator component.</p>
     */
    public class ListItemDragProxy extends Group
    {
        include "../../core/Version.as";
    
        //--------------------------------------------------------------------------
        //
        //  Constructor
        //
        //--------------------------------------------------------------------------
    
        public function ListItemDragProxy();
    }
    
    }
    
    DropLocation
    package spark.layouts.supportClasses
    {
    import flash.geom.Point;
    
    import mx.core.IVisualElement;
    import mx.events.DragEvent;
    
    /**
     *  This class is used to store information related to a <code>DragEvent</code>
     *  in order to minimize calculations as a <code>DragEvent</code>
     *  related requests are passed back and forth between the <code>List</code> and
     *  its layout.
     * 
     *  The <code>DropLocation</code> is created by the <code>LayoutBase</code>
     *  class when the <code>List</code> calls the layout's
     *  <code>calculateDropLocation()</code> method in response to a <code>DragEvent</code>.
     * 
     *  The DropLocation is used by the layout for operations such as
     *  calculating the drop indicator bounds and drag-scroll deltas.
     * 
     */
    public class DropLocation
    {
        /**
         *  Constructor.
         */
        public function DropLocation()
        {
        }
    
        /**
         *  The <code>DragEvent</code> associated with this location. 
         */
        public var dragEvent:DragEvent = null;
    
        /**
         *  The drop index corresponding to the event.
         */
        public var dropIndex:int = -1;
    
        /**
         *  The event point in local coordinates of the layout's target.
         */
        public var dropPoint:Point = null;
    
        /**
         *  The element appearing immediately before the dropIndicator.
         *  This is usually used by the layout to calculate drag-scrolling
         *  deltas.
         *  Note that even when an element exists, this field may still be null
         *  in cases where the layout can't scroll in that direction. 
         */
        public var elementBefore:IVisualElement = null;
    
        /**
         *  The element appearing immediately after the dropIndicator.
         *  This is usually used by the layout to calculate drag-scrolling
         *  deltas.
         *  Note that even when an element exists, this field may still be null
         *  in cases where the layout can't scroll in that direction. 
         */
        public var elementAfter:IVisualElement = null;
    }
    }
    
    LayoutBase
    package spark.layouts.supportClasses
    {
    
    public class LayoutBase
    {
    
        ...
    
        //--------------------------------------------------------------------------
        //
        //  Methods: Drag and drop, public APIs
        //
        //--------------------------------------------------------------------------
    
         /**
          *  Sets the DisplayObject for this layout to use when
          *  displaying the drop indicator during drag and drop operation.
          *
          *  Typically developers don't access this property directly,
          *  but instead rely on the List's default <code>DragEvent</code>
          *  handlers.
          * 
          *  <p>The <code>List</code> sets this property in response to a
          *  <code>DragEvent.DRAG_ENTER</code> event.
          *  The <code>List</code> initializes this property with an
          *  instance of its <code>dropIndicator</code> skin part.
          *  The <code>List</code> clears this property in response to a
          *  <code>DragEvent.DRAG_EXIT</code> event.</p>
          */
         public function get dropIndicator():DisplayObject;
         public function set dropIndicator(value:DisplayObject):void;
    
        /**
         *  CAlculates the <code>DropLocation</code> for the specified
         *  <code>dragEvent</code>.
         *
         *  @param dragEvent The dragEvent dispatched by the DragManager.
         *
         *  @return Returns the DropLocation for this event, or null if the drop 
         *  operation is not possible.
         * 
         *  @see #showDropIndicator
         *  @see #hideDropIndicator
         */
        public function calculateDropLocation(dragEvent:DragEvent):DropLocation;
    
        /**
         *  Sizes, positions and parents the dropIndicator for the specified
         *  DropLocation.
         *
         *  Starts/stops drag-scrolling when necessary conditions are met.
         * 
         *  The <code>dorpIndicator</code> must be previously set.
         *
         *  @param dropLocation <p> The DropLocation must be 
         *  previously calculated through the calculateDropLocation() method.</p>
         * 
         *  @return Returns whether the drop indicator is visible.
         * 
         *  @see #hideDropIndicator
         *  @see #calculateDropLocation
         *  @see #dropIndicator
         */
        public function showDropIndicator(dropLocation:DropLocation):Boolean;
    
        /**
         *  Hides the previously shown <code>dropIndicator</code>,
         *  removes it from the display list and also stops the drag-scrolling.
         *
         *  @see #showDropIndicator
         *  @see #dropIndicator
         */
        public function hideDropIndicator():void;
    
        //--------------------------------------------------------------------------
        //
        //  Methods: Protected APIs for easier custom layout DND support
        //
        //--------------------------------------------------------------------------
    
        /**
         *  Returns the index where a new item should be inserted if
         *  the user releases the mouse at the specified coordinates
         *  while completing a drag and drop gesture.
         * 
         *  Called by the <code>calculatedDropLocation()</code> method.
         *
         *  @param x The x coordinate of the drag and drop gesture, in target's
         *  local coordinates.
         * 
         *  @param y The y coordinate of the drag and drop gesture, in target's
         *  local coordinates.
         *
         *  @return The drop index or -1 if the drop operation is to available
         *  at the specified coordinates.
         * 
         *  @see #calculateDropLocation
         */
        protected function calculateDropIndex(x:Number, y:Number):int;
    
        /**
         *  Calculates the bounds for the drop indicator UI that provides visual feedback
         *  to the user of where the items will be inserted at the end of a drag and drop
         *  gesture.
         * 
         *  Called by the <code>showDropIndicator()</code> method.
         * 
         *  @param dropLocation A valid <code>DropLocation</code> previously calculated
         *  through the <code>calculateDropLocation</code> method.
         * 
         *  @return The bounds for the drop indicator or null.
         * 
         *  @see spark.layouts.supportClasses.DropLocation
         *  @see #calculateDropIndex
         *  @see #calculateDragScrollDelta
         */
        protected function calculateDropIndicatorBounds(dropLocation:DropLocation):Rectangle;
    
        /**
         *  Calculates how much to scroll for the specified DropLocation during a drag and drop gesture.
         *
         *  Called by the <code>showDropIndicator()</code> method, as well as during drag-scrolling.
         *
         *  @param dropLocation A valid <code>DropLocation</code> previously calculated
         *  through the <code>calculateDropLocation</code> method.
         *
         *  @return The scroll delta point or null if there's no need to drag-scroll.
         * 
         *  @see spark.layouts.supportClasses.DropLocation
         *  @see #calculateDropIndex
         *  @see #calculateDropIndicatorBounds
         */
        protected function calculateDragScrollDelta(dropLocation:DropLocation):Point;
    }
    
    }
    
    Overlays
    package spark.components.supportClasses
    {
    
    
    public class GroupBase extends UIComponent implements IViewport
    {
    
        ...
        /**
         *  The overlay plane for this Group.
         *  All objects of the overlay plane render on top of the Group elements.
         *  Don't hold on to this object, as Group destroys and creates it on demand.
         */
        public function get overlay():DisplayPlane
    
    }
    }
    
    
    /**
     *  A DisplayPlane class maintains ordered list of DisplayObjects sorted on
     *  depth.
     *  Developers don't instantiate this class, but use the <code>overlay</code>
     *  property of <code>Group</code> and <code>DataGroup</code>.
     *
     *  @see spark.components.Group#overlay
     *  @see spark.components.DataGroup#overlay
     */
    public class DisplayPlane extends EventDispatcher
    {
        public function DisplayPlane()
    
        //--------------------------------------------------------------------------
        //
        //  Properties
        //
        //--------------------------------------------------------------------------
    
        /**
         *  Number of objects in the DisplayPlane. 
         */
        public function get numDisplayObjects():int
    
        //--------------------------------------------------------------------------
        //
        //  Methods
        //
        //--------------------------------------------------------------------------
    
        /**
         *  Returns the requested object with the specified index in the
         *  ordered list. 
         */
        public function getDisplayObjectAt(index:int):DisplayObject
    
        /**
         *  Adds a <code>displayObject</code> with the specified depth to the ordered list.
         *  The position of the <code>displayObject</code> in the sorted lists is based on
         *  its depth, the object will be inserted after all objects with less than or equal
         *  depth value.
         * 
         *  @return Returns the index of the object.
         */
        public function addDisplayObject(displayObject:DisplayObject, depth:Number = OverlayDepth.TOPMOST):int
    
        /**
         *  Removes the specified <code>displayObject</code> from the sorted list.
         */
        public function removeDisplayObject(displayObject:DisplayObject):void
    }
    
    
    package spark.components.supportClasses
    {
    /**
     *  The OverlayDepth class defines the default depth values for 
     *  various overlay elements.
     * 
     *  @see spark.components.Group#overlay
     *  @see spark.components.DataGroup#overlay
     */
    public final class OverlayDepth
    {
        /**
         *  The overlay depth for a drop indicator.
         */
        public static const DROP_INDICATOR_DEPTH:Number = 100;
    
        /**
         *  The overlay depth for a mask object.
         */
        public static const MASK_DEPTH:Number = 200;
    
        /**
         *  The overlay depth for a focus object.
         */
        public static const FOCUS_DEPTH:Number = 300;
    
        /**
         *  The default top most overlay depth.
         */
        public static const TOPMOST:Number = 10000;
    }
    }
    
    
    }
    
    </object>

Related

Wiki: Flex 4

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.