BIS Lightweight Application Development Engine

components.plugins.dragdrop documentation


Namespace: http://blade.cellexchange.com/plugins/drag-drop
Common Prefix: dd

The drag and drop plugin provides a framework for drag-and-drop interfaces. Currently it only supports dragging and dropping images, although the capability to drag and drop text or other HTML elements can be trivially added. Each element to be dragged around the screen has a Draggable object associated with it. These draggables are docked onto a Surface, which defines how the draggable can be placed (e.g. is it snapped to a grid?). Managing the interaction between the draggables and surfaces is a Container. Draggables generally get produced by a factory before they are added to the screen; the only reason that draggable images are the only thing supported is that DraggableImageFactory is the only factory implementation currently built.

The draggable handles all of its interactions with the mouse (i.e. it captures the onclick and onmousemove events). When released, it gives the container its coordinates and asks to dock. The container releases the draggable from the surface it was originally docked at (it does this first to avoid internal issues) and tells its top-level surface to attempt to dock the draggable. The container only has one top-level surface, but after that each surface can have an arbitrary number of subsurfaces, so long as those subsurfaces are within the bounds of their parent surfaces. As each surface gets the dock request, it first checks with its subsurfaces, and then checks whether the draggable can drop onto itself. By the end of the process, the container has a response. If the draggable can dock, the container updates it's copy of the draggable's state, and then gives the draggable its new coordinates. If draggable can't dock, the container re-docks the draggable onto its old surface and tells the draggable it can not dock anywhere.

Because of the interactions described above, the container and surfaces occupy an essentially virtual space. All the draggables have a CSS position of absolute and sit inside a div with CSS position relative, but the div that contains them can be arbitrarly large or small.

Now lets start building an example drag-and-drop instance, using the standard plugin create tag. Inside the create tag, we'll create several surfaces: a static (draggable is docked wherever it is dropped) root surface, a grid (draggable is snapped to a grid) surface, and a snap (draggables are aligned in a row) surface. Inside, of each surface, we can set attributes.

<dd:create>
 <dd:surface type="static" clipRegion="new blade.core.screen.ClipRegion(0,0,400,400)">
  <dd:surface type="snap" clipRegion="new blade.core.screen.ClipRegion(200,200,400,400)">
   <dd:attribute name="vectorX" value="16"/>
  </dd:surface>
  <dd:surface type="grid" clipRegion="new blade.core.screen.ClipRegion(0,0,200,200)">
   <dd:attribute name="gridSize" value="16"/>
  </dd:surface>
 </dd:surface>
</dd:create>

For each surface, the type specifies what type of surface it is, and the clipRegion specifies what its boundaries are. All clipRegions are absolute, relative to the upper left corner of the root surface. The following attributes can be set:

GridSnap
gridSizevectorX / vectorY - defines how the line moves
originX / originY - defines where the line starts

Now its time to display the drag and drop environment. First, we need something to generate new draggables and place them in the container. This is done with a display type of "image". The tag attribute defines the text that shows up on the generation button.

<dd:display type="image" tag="dot" src="red-dot.gif"/>
We also have to display the containers and surfaces. We do this with a display type of "canvas". Inside the canvas tag, we can put any arbitrary html/xsl we want, so lets also put a table in there with 200px by 200px cells to show where the edges of the surfaces are. The final result looks like this.