r10 - 27 Mar 2007 - 14:30:16 - PhilippeBossutYou are here: OSAF >  Projects Web  >  DevelopmentHome > ApplicationProject > CpiaFramework > DnDImplementation

DnD Implementation

Purpose

This is an overview of the implementation of Drag and Drop within the CPIA framework. Programmers that use CPIA blocks can add Drag and Drop capabilities with minimal programming effort. The CPIA Drag and Drop features are layered on top of the wxWidgets support for Drag and Drop. Drag and Drop has a huge overlap with the standard editing features (Cut, Copy, and Paste) so those capabilities are also integrated into this framework.

Goals

  • Programmers using existing blocks should get a rich set of drag and drop capabilities already built in.
  • Programmers adding new blocks should have to add minimal new code to gain DnD functionality
  • Chandler should interact well with the system level drag and drop
  • The Edit features (Cut, Copy, and Paste) should be integrated with little additional overhead

Overview

Drag and Drop capabilities are associated with a block's widget, so the widget defines when data can be moved in or out of itself. In fact, the wxWidgets implementation for TextCtrl (editable text) comes with Drag and Drop support built-in. The CPIA implementation of Drag and Drop extends this support to other widgets, including tables and lists, and adds an additional kind of data that can be dragged - an Item. Essentially, each widget decides what kind of data it can import or export, and how to access that data, and CPIA does the rest.

A set of classes is provided by CPIA to make it easy for the various widget classes to implement their Drag and Drop and Editing behavior. Widgets that support data export inherit their drag capability from DraggableWidget, and those that support data import inherit from DropReceiveWidget. Widgets that organize their information using Items use the ItemClipboardHandler, and those that contain Text use the TextClipboardHandler. Many widgets act as both a DraggableWidget and a DropReceiveWidget to allow data to be moved both in and out of those widgets. Additionally, when an item is dropped onto a widget, the widget can decide whether the item should be dropped into a sub-portion of itself. This allows us to drop items onto specific rows in a table such as the Sidebar instead of dropping into the Sidebar itself.

The ClipboardHandler classes perform two functions: they handle the Edit menu items, and they determine the interface to the widget's data. All menu control under CPIA is implemented at the Block level, but the RectangularChild block delegates the Editing control back to the widget. This allows the various kinds of ClipboardHandlers to automatically handle the Edit menu items for Cut, Copy and Paste. So choosing an appropriate ClipboardHandler automatically gives you Cut and Paste support. But the main job of the ClipboardHandler is to get data into and out of the widget. For Item-based data, there are four methods that you need to implement: AddItems to put data into the widget, SelectedItems to get data out of the widget, DeleteSelection to remove the items, and ClipboardDataFormat to define that kind of data you accept.

Most widgets can add Drag and Drop capability by simply inheriting from several of these CPIA classes, and defining a few methods that actually access the data within their widget. The classes are mixed in to the base capability of your widget, and you can override the default behavior to provide additional features if needed. Feedback with the cursor is done automatically based on the compatibility of the type of data being dragged and the capabilities of the location being dragged to.

DraggableWidget

A draggable widget in Chandler is anything which can be dragged. In order to give a widget the ability to be dragged, that widget must do several things to define itself (or pieces of itself) as a drop source.
  • The widget must declare DraggableWidget as a mixin
  • The widget must declare a ClipboardHandler as a mixin, usually ItemClipboardHandler
  • The widget must call its DoDragAndDrop method to initiate the drag (or move) action

DropReceiveWidget

A DropReceiveWidget in Chandler is anything which can receive a drop (can have something dropped onto it). In order to have a widget be able to receive drops, that widget must do several things.
  • The widget must declare DropReceiveWidget as a mixin
  • The widget must declare a ClipboardHandler as a mixin, usually ItemClipboardHandler
  • The widget may override the OnRequestDrop method to decide whether or not to accept the drop.
  • The widget may override the OnEnter and OnLeave give cursor feedback for this specific drop target.
  • The widget may override the OnHover and OnHoverLeave methods to continuous feedback while the mouse moves over this widget.

ItemClipboardHandler

A widget that inherits from ItemClipboardHandler is a widget that has Item-based data. In order to access that data the ItemCliboardHandler will call back into the widget:
  • The widget must implement SelectedItems if it's being used as a DraggableWidget.
  • The widget may implement DeleteSelection if it also allows Cut and the drag-move operation.
  • The widget must implement AddItems if it's being used as a DropRecieveWidget.
  • The widget may override the ClipboardDataFormat to specify what kind of data it accepts (the default for ItemClipboardHandler is "Note")

The ItemClipboardHandler uses the Trash.ContentModel to export data of various Kinds. All Items are exported as "Item", but Notes are also exported as "Note" and ItemCollections as "ItemCollection". This enables a DropReceiveWidget to choose whether it will accept only Notes (and their sub-classes), or any Item at all.

TextClipboardHandler

A widget that inherits from TextClipboardHandler is a widget that has Text-based data. In order to access that data the TextClipboardHandler will call back into the widget:
  • The widget must implement GetStringSelection to get the selection
  • The widget must implement WriteText to paste the selection

CustomClipboardHandler

If you want to write your own ClipboardHandler to handle your own kind of data, here's what you need to do:
  • You must implement CopyData to export data from the widget
  • You must implement PasteData to import data into the widget
  • You must implement ClipboardDataFormat to return the kind of data you manipulate
  • You must implement ClipboardDataObject to create an appropriate kind of Data Object
  • You must implement CanCut, CanCopy, CanPaste to do the menu enabling.
  • You must implement Cut, Copy, and Paste to do the actual edit operations.

Implementation Issues

The current implementation of Drag & Drop has a few limitations due to our implementation in Chandler, or due to wxWidgets itself. * Currently Cut & Paste of Items doesn't work on the Mac
  • UI elements that accept a drop can only specify a single format for the data accepted
  • Cursor feedback for "special" drop targets has not been tested. We anticipate that implementing the Trash in the Sidebar will be a case where we'll want to do this.
  • When drag-move is not allowed, wxWidgets still requires the user to press a modifier key to do a drag-copy. This seems like a big problem, so under the covers we actually map both drag-move and drag-copy, so the user need not press the key.

Open issues

  • What does it mean to drag an Item outside of Chandler? We can drag standard data, like text and files to and from Chandler, but our items are dragged using their UUID. So it's unclear what sense could be made of this information when dragging an Item to another application, or even dragging Items between different instances of Chandler.
  • In the current implementation a widget that allows a drop may only specify one kind of data that it accepts. We'll need to revisit this if we want to allow dropping of both Items and Text onto the calendar for example.

References

PageInfo
PageType DevDocPage
MaintainedBy DonnDenman
PageStatus Source of truth -- this page reflects current OSAF thinking? go.png
Trash.CommentsWelcome2 Feel free to contribute comments?, either by adding to the Comments Welcome section of this page, or by posting to the dev list, or by sending mail directly to the person listed as maintaining the page.
Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r10 < r9 < r8 < r7 < r6 | More topic actions
 
Open Source Applications Foundation
Except where otherwise noted, this site and its content are licensed by OSAF under an Creative Commons License, Attribution Only 3.0.
See list of page contributors for attributions.