[logo] JX Application Framework
   
Home     
* Cart

Introduction

Why use a framework?

Download

GitHub

Vision
    API stability

    Code optimization

    Bibliography

Features
    Object messaging

    Extensibility

    Drag-and-Drop

    Networking

    3D Graphics

    Powerful tables

    Styled text editor

    Memory leak debugger

    Tutorial
    Class tree

    Open protocols

    Known bugs

    Next release
    Future plans

    Projects

FAQ

Other software

Log in  

   
     

Drag-and-Drop

The JX Application Framework provides Drag-and-Drop via a set of virtual functions in JXWidget.

This screen shot shows how a JX widget responds when it can accept the drop. The mouse was dragged from the text editor at the left to the text editor at the right. Unfortunately, xv does not include the mouse in its screen capture, but the caret (the red vertical line) drawn inside the "trplunderline" text shows where the mouse was and where the dropped data would have been inserted.

(NEW) Iconified windows can also accept dropped data.

The JX Application Framework enforces the standard that the Escape key cancels any drag.


Implementing Drag-and-Drop

To understand the full power of the JX Drag-and-Drop API, it helps to read the XDND protocol description. It is also a good idea to study the examples. If you are going to drag or accept drops of files, you should also study the file dragging protocol.

Source

To prepare for Drag-and-Drop, the widget must call AddSelectionTarget() at least once for the selection name returned by JXDNDManager::GetDNDSelectionName(). This provides the list of data types that can be dropped.

To initiate Drag-and-Drop from a widget, call BeginDND() from either HandleMouseDown() or HandleMouseDrag(). If this returns kTrue, DND has begun, so the widget will not get any more HandleMouseDrag() messages, nor will it get a HandleMouseUp() message. Instead, DNDInit() is called to allow the widget to initialize any required data, etc.

While the user drags the mouse, GetDNDAction() will be called so the widget can translate the buttons and modifier keys into the action to be sent to the target. If the widget returns the action Ask (JXDNDManager::GetDNDActionAskXAtom()), GetDNDAskActions() will also be called to get the list of actions and descriptions that the target should present to the user when the drop occurs.

When the user drags the mouse over a target, HandleDNDResponse() will be called with the target's response so the source can change the cursor to show the action that the target will actually perform.

A pointer to the target is passed to both GetDNDAction() and HandleDNDResponse(). This allows the widget to recognize drops on itself and drops on other parts of a compound document. The pointer is NULL if the target is in a different program.

To support the Move action, one normally catches the type returned by JXSelectionManager::GetDeleteSelectionXAtom() inside ConvertSelection(), deletes the currently selected data, and returns an empty pointer of the type returned by JXSelectionManager::GetNULLXAtom().

Target

When the mouse enters a widget during a Drag-and-Drop session, WillAcceptDrop() is called to ask whether or not the widget will accept the drop. The list of available data types and the requested action are provided since each widget will only be able to accept certain data types and perform certain actions. The action is passed in as a pointer so it can be modified. (i.e. changed to either Copy or Private, as specified in the underlying protocol) A time stamp is also provided in case the actual data needs to be examined by calling JXSelectionManager::GetData() for the selection name returned by JXDNDManager::GetDNDSelectionName(). If the source is in the same program, a pointer to the widget is provided so the widget can detect itself or another part of a compound document.

If WillAcceptDrop() returns kTrue, HandleDNDEnter() is called, followed by HandleDNDHere() every time the mouse moves. If the mouse leaves the widget without being released, HandleDNDLeave() is called. If the mouse is released inside the widget, HandleDNDDrop() is called.

Inside HandleDNDDrop(), the widget must retrieve the data (if it didn't already do so in WillAcceptDrop()) by calling JXSelectionManager::GetData() for the selection name returned by JXDNDManager::GetDNDSelectionName(). If the action is Ask, it should then call JXDNDManager::GetAskActions(), filter the action list (if necessary), and then call JXDNDManager::ChooseDropAction(). The widget is now ready to perform the action on the data. (To implement the Move action, one normally calls JXSelectionManager::SendDeleteSelectionRequest() to delete the data on the source side.)

Notes

When you implement DND in your widgets, remember to do the following:

  • Use the delayed evaluation constructor for the derived class of JXSelectionManager::Data unless you know that there is very little data to transfer.

  • Debounce the mouse drag. If the user moves the mouse by only a couple of pixels while clicking to select something, then it is far more likely that the user is a bit clumsy than that the user intends to start a drag. A threshold of 3 pixels is typical.

Since the purpose of Drag-and-Drop is to allow users to drag data from any application to any other application, we encourage all other applications and libraries to support the same underlying X protocol.

Bombsight rules for dropping on tables

If the contents of the cell will be replaced, highlight the cell's border with a frame at least one pixel thicker than the normal cell borders.

If the dropped item will be inserted between two rows or columns, highlight the border between the items with a line at least one pixel thicker than the normal cell borders. The boundaries between drop regions must be the midpoints of the cells, not the cell boundaries.

If the cursor is outside the widget's frame, scroll automatically. If the widget can't scroll any further, the target is the item or location nearest the cursor.

If the table is actually a 1D list, then one often has items that can contain other items. In this case, the above rules are modified as follows:

  • Container cells act like "replace contents" cells above and display a border around themselves.
  • Item cells act normally with the threshold between "insert before" and "insert after" at the midpoint of the cell.
Dropping on a container cell appends to the container's content list rather than prepending.

Copyright © 2009 New Planet Software