Overview

Get quickly up-and-running with dmc_dragdrop.

It is modeled closely after the functionality of the Adobe Flex Drag Manager, but adds two more levels to the drag and drop cycle and simplifies some of the calls.

Adobe-Flex-Drag-Manager
More information about the Adobe Flex Drag Manager and Drag and Drop operations can be found on the Adobe website: http://livedocs.adobe.com/flex/3/html/help.html?content=dragdrop_2.html

Table of Contents

{toc:style=disc|indent=20px|minLevel=2|exclude=Table of Contents|printable=false}

dmc_dragdrop Basics

Here is a short overview of a Drag and Drop operation.

Setup

You import the drag and drop library like any other by using the require() statement.

Import dmc_dragdrop

local DragMgr = require( "dmc_dragdrop" )

The import of dmc-dragdrop returns the Drag Manager - a single object which coordinates any drag and drop operations in the application. In object-oriented design parlance this means that the Drag Manager is a singleton, i.e., there is only one which exists. So, you won't create instances of the Drag Manager, but instead you will notify this one instance about important Drag and Drop things, namely Drag Operations and Drop Targets.

Now we'll go over the main components of a drag operation

  • Drag Initiators
  • Drag operations
  • Drag Proxy
  • Drop Targets

Drag Initiators

A Drag Initiator is the item on the screen which is reponsible for the very beginning of a Drag Operation. There's nothing special about the initiator - it'll typically be a regular Corona display object with an attached event listener watching for the touch event.

It's within this touch event that you will notify the Drag Manager about the Drag Operation which is happening. This is covered in more detail below.

Drag Operations

You notify the Drag Manager about the drag operation by using the method doDrag(). It's a straight-forward call, and in its simpest form only requires a reference to the Drag Initiator and the Corona touch event.

doDrag()

DragMgr:doDrag( initiator, event )

There is an optional argument that doDrag() accepts which is a table of options. In it you can define more information about drag operation - eg, the type, any data to pass along, the Drag Proxy, etc.

Drag Proxy

The Drag Proxy is the item which is dragged around the screen. This is not the object itself (the Initiator), but just a representation of the object. Drag Proxies can look similar to the original item, but that's not necessary.

By default the Drag Manager will create a simple Drag Proxy for you. This is just a simple grey square that has the same dimensions as the Drag Initiator.

Drop Targets

Drop Targets are the areas on the screen to which things are dragged. Just like Drag Initiators, these don't have to be anything more than a simple Corona display object.

Any Drop Targets on the screen which want to be notified about drag operations need to be registered with the Drag Manager.

The bulk of the code for the Drag and Drop process will be inside of the Drop Target. The implementation requires that a callback be defined for any Drag Events in which the Drop Target is interested.

Drag Initiators - A deeper look

As mentioned before a Drag Initiator is the object on the screen which is responsible for starting the Drag Operation. In its simplest form, the Drag Initiator is just a regular Corona Display Object which has been setup to receive touch events.

It's inside of the touch event where the Drag Manager should be notified about the drag event.

The following code shows a simple example of setting up a Drag Initiator. You can see the very simple call to the Drag Manager in the function dragItemTouchHandler.

Simple Drag Initiator Setup

local DragMgr = require 'dmc_dragdrop'

local function dragItemTouchHandler( event )

    local target = event.target

    if event.phase == "began" then

        -- now tell the Drag Manager about it
        DragMgr:doDrag( target, event )
    end

    return true
end

-- this is the Drag Initiator
-- ie, the location from which we start a drag
--
local dragItem = display.newRect( 0, 0, 75, 75 )
dragItem:setFillColor( 90, 170, 255 )
dragItem.x = 160 ; dragItem.y = 400

dragItem:addEventListener( 'touch', dragItemTouchHandler )
This code example can be found in the folder examples/dmc_dragdrop/DMC-dragdrop-basic/ which is included with the DMC Corona Library.

In this basic example, the item that is dragged around the screen, the Drag Proxy, will be created for you. There are options which can be passed in to the doDrag() method call to modify the drag operation. For instance, you can pass in your own Drag Proxy, if you want something other than the default grey square.

doDrag() Method options

An optional third parameter can be sent into doDrag(). This is a plain Lua table which will hold information related to the drag parameters. The following is a listing of all of the items which can be sent in as table attributes.

Option Description
proxy The Drag Proxy is the item which is actually dragged around the screen.This should be a Corona display object or an object created using dmc_objects.

The default is a grey square, with dimensions equal to that of the Drag Initiator.
format The format is typically a string which describes the data being passed around. It is given to Drop Targets so they can determine if they're interested in the current Drag Operation. Examples could be "database-record", "food", "red", etc. For simple drag/drop operations, this might be all of the data you need. If you need more, then use the data item.

The default is nil.
data The data item should be used when the drag operation needs more information than the format item can convey. This can be anything, from an integer, to a string, to a full Corona or Lua object.
xOffset The offset of the Drag Proxy in the x-direction measured from the coordinates of the Corona touch event.

The default is 0.
yOffset The offset of the Drag Proxy in the y-direction measured from the coordinates of the Corona touch event.

The default is 0.
alpha The alpha of the Drag Proxy.

The default is 0.5.

Here is another Drag/Drop example which sends in the optional parameter to doDrag().

Example of doDrag() Options

local function dragItemTouchHandler( event )

    if event.phase == "began" then

        local target = event.target

        -- create Drag Proxy - item dragged around the screen
        local dragProxy = display.newRect( 0, 0, 75, 75 )
        s.strokeWidth = 3
        s:setFillColor( 90, 170, 255 )
        s:setStrokeColor( 180, 180, 180 )

        -- setup info about the drag operation
        local drag_info = {
            proxy = dragProxy,
            format = "red",
            yOffset = -30,
        }

        -- now tell the Drag Manager about it
        DragMgr:doDrag( target, event, drag_info )
    end

    return true
end

Drop Targets

Drop Target Callbacks

The role of the Drag Manager is to notify Drop Targets about different stages in the drag/drop cycle. This communication is carried out via event callbacks.

The following are the callbacks for different stages in the drag/drop cycle:

Drop Target Event Description
dragStart Dispatched at the beginning of the drag/drop cycle.

You can use this event to give visual feedback to users letting them know which targets on the screen will accept the drag. With this event visual feedback can be given notifying the user that this Drop Target will accept the drag without having to be directly over the Drop Target.

The dragStop event is the inverse of this event, ie, any visual changes done here can be undone in dragStop.
dragEnter Dispatched when a drag proxy moves over the drop target from outside the drop target.

A component must define this event handler for the component to be a drop target. Within this event handler the code will determine whether the data being dragged is an accepted format. To accept the drop call the DragManager.acceptDragDrop() method inside of the event handler. You must call the DragManager.acceptDragDrop() method for the drop target to receive any further events - i.e., dragOver, dragExit, and dragDrop events.

The dragExit event is the inverse of this event, ie, any visual changes done here in dragEnter can be undone in dragExit.
dragOver Dispatched while the user moves the mouse over the target, after the dragEnter event.

You can use this event to perform additional logic before allowing the drop operation, such as dropping data to various locations within the drop target, reading other input to determine if the drag-and-drop operation is a move or copy of the drag data, or providing different types of visual feedback based on the type of drag-and-drop operation.
dragDrop Dispatched when the user releases the touch event over the drop target.

This is the main part of the drag drop cycle. Use this event handler to "perform the drop", perhaps by adding records to a database or a shopping cart.
dragExit Dispatched when the user moves the drag proxy off of the drop target, but does not drop the data onto the target.

You can use this event to restore the drop target to its normal appearance if you modified its appearance in response to a dragEnter event or other event.
dragStop Dispatched at the beginning of the drag/drop cycle, whether an item has been accepted by a Drop Target or not.

You can use this event to restore the drop target to its normal appearance if you modified its appearance in response to a dragStart event or other event.

Drop Target Example

The complete code for the following example can be found in the folder examples/dmc_dragdrop/DMC-dragdrop-basic/ which is included with the DMC Corona Library.

Simple Drop Target Example

local DragMgr = require 'dmc_dragdrop'

--== Setup Our Drop Target Callbacks

local dragStartHandler = function( event )

    local o = event.target
    o:setStrokeColor( 1, 0.2, 0.2 )

    return true
end

-- This one is required !!
local dragEnterHandler = function( event )

    local o = event.target
    o:setFillColor( 0.5, 0.7, 0.5 )

    DragMgr:acceptDragDrop()

    return true
end

... (implement the rest of the callbacks as needed)


--== Create Our Drop Target

local dropTarget = display.newRect( 0, 0, 125, 125 )
dropTarget:setFillColor( 0.1, 0.5, 1 )
dropTarget.x = 160 ; dropTarget.y = 200


--== Tell the Drag Manager about it

DragMgr:register( dropTarget, {
    dragStart=dragStartHandler,
    dragEnter=dragEnterHandler,

    ... (add the rest according to your implementation)
})

Drop Target Callback Event

Here is the structure of the event given to a callback:

Drop Target Event

{
    target = <the Drop Target object>,
    format = <String>, -- the user-supplied format of the data passed around
    data = <user-defined data format>
}
Name Description
target This is always a reference to the Drop Target. Of course, if the Drag Manager is given a Drop Target object in the register() method, then you can use self to get to the Drop Target. In this case target is a duplicate of self.

This attribute is useful for changing the appearance of the Drop Target as needed.
format This is generally a simple string which describes the drag operation, eg, "food", "database-record", etc.

This attribute is useful in Drop Target event handlers to determine if a the Drop Target is interested in the current Drag Operation.
data User-defined data format. This can be anything - a string, a table, an object, (eg, "Nancy", 42, Display Object, database record, etc).

It's useful for the Drop Target if it requires any extra information (beyond the event.format) to do data processing. This would most likely be in the dragDrop callback, when the drop has been accepted.
There is a Drag and Drop example using event.format in the folder examples/dmc_dragdrop/DMC-dragdrop-OOP/ which is included with the DMC Corona Library.