Rich UI drag and drop

You can write code so that a user is able to drag a widget from one location and drop it at another. More broadly, your code can respond to the following user events: a single mouse-down event when the user holds the position; subsequent mouse-move events; and a single mouse-up event. You can fulfill any runtime tasks that are represented by the drag and drop; Rich UI does not define the behavior.

You write the drag-and-drop code by specifying three properties in a widget declaration and by writing functions that are referenced in the corresponding property values. For example, here is the declaration of a button:
b1 Button { 
   text = "Button 1", position="absolute",	x=10, y=10,
   onStartDrag = start, onDrag = drag, onDropOnTarget = drop};

Here are the three properties that make drag-and-drop possible:

  • onStartDrag references a function that the EGL Runtime calls once, at the start of a drag operation. The function has characteristics that are shown in the following Delegate part:
    Delegate StartDragFunction(widget Widget in, 
                               x int in, y int in) returns (Boolean)

    The function receives a reference to the widget and receives the absolute x and y coordinates of the mouse pointer. The function returns a Boolean value that indicates whether to continue the drag operation.

  • onDrag references a function that the EGL Runtime calls repeatedly, as the drag operation proceeds; specifically, each time the browser records a mouse-move event. The function has characteristics that are shown in the following Delegate part:
    Delegate DragFunction(widget Widget in, 
                          dropTarget Widget in, 
                          x int in, y int in) 

    The function receives references to the widget being dragged and to the widget (if any) over which the mouse pointer is passing. If the mouse pointer is not passing over any widget, the second argument is null. The function also receives the absolute x and y coordinates of the mouse pointer and has no return value. The function itself should update the position of the widget (or some other image) in response to the mouse-move event.

  • onDropOnTarget references a function that the EGL Runtime calls once, when the user releases the mouse to end the drag operation. The function has characteristics that are shown in the following Delegate part:
    Delegate DropOnTargetFunction(widget Widget in,
                          dropTarget Widget in,
                          x int in, y int in) 

    The function receives references to the widget being dropped and to the widget (if any) under the mouse pointer. If no widget is under the mouse pointer, the second argument is null. The function also receives the absolute x and y coordinates of the mouse pointer and has no return value.

Here is an example you can bring into your workspace:.
import com.ibm.egl.rui.widgets.TextField;

handler MyHandler type RUIHandler{initialUI =[myTextField]}
   myTextField TextField{text = 
                   "What a drag!", position = "absolute", x = 110, y = 210, width = 120, 
                   onStartDrag = start, onDrag = drag, onDropOnTarget = drop};
   dx, dy int;

   function start(myWidget Widget in, x int in, y int in) returns(boolean)
      dx = x - myWidget.x;
      dy = y - myWidget.y;
      return(true);
   end

   function drag(myWidget Widget in, drop Widget in, x int in, y int in)
      myWidget.x = x - dx;
      myWidget.y = y - dy;
   end

   function drop(widget Widget in, drop Widget in, x int in, y int in)
   end
end  
The start function calculates the difference between the location of the mouse pointer and the top-left corner of the widget. The effect of using that calculation is that the mouse pointer is displayed at the same place on the widget throughout the operation. To see the effect, run the code twice, clicking the bottom-right corner of the widget to start the drag-and-drop operation each time:
  1. Run the code as shown
  2. Run the code only after replacing the statements in the drag function with the following assignments:
       myWidget.x = x;
       myWidget.y = y;
    

Additional examples are in Rich UI Shadow.