home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / uicldd.zip / DRAGDROP.DOC < prev    next >
Text File  |  1993-09-03  |  12KB  |  305 lines

  1.   September 3, 1993
  2.  
  3.   DIRECT MANIPULATION
  4.   ___________________
  5.  
  6.   The User Interface Class Library provides four types of objects to support
  7.   direct manipulation:
  8.  
  9.   o   An event handler (IDMSourceHandler or IDMTargetHandler)
  10.  
  11.   o   A renderer (IDMSourceRenderer or IDMTargetRenderer)
  12.  
  13.   o   A drag item (IDMItem)
  14.  
  15.   o   A drag item provider (IDMItemProvider)
  16.  
  17.   IDMSourceHandler and IDMTargetHandler are derived from IHandler.  They handle
  18.   the Presentation Manager direct manipulation window messages.  Objects from
  19.   these classes pick off the WM_* and DM_* messages for the source and target
  20.   windows and translate them to virtual function calls to the handler.
  21.  
  22.   In addition to translating messages to virtual function calls, these handlers
  23.   also manage the second type of objects, the renderers.  Renderers transfer
  24.   the representation of the object being manipulated between the source and
  25.   target windows.  Direct manipulation renderers are objects of classes
  26.   IDMSourceRenderer and IDMTargetRenderer.
  27.  
  28.   The third type of objects are the drag items, represented by objects of class
  29.   IDMItem.  These objects encapsulate the logic that serves as the bridge
  30.   between the context-insensitive handlers and renderers and the
  31.   application-specific behavior of particular source and target windows.  Put
  32.   another way, the drag items provide the application-specific semantics of the
  33.   direct manipulation operation.  For example, the handler and renderer classes
  34.   can manipulate IString objects, but the entry field items know how to extract
  35.   the source IString from the source entry field and convert it to a customer
  36.   object in the target window.
  37.  
  38.   Objects of the IDMItemProvider class allow generic controls like an entry
  39.   field to generate context-sensitive drag items; for example, an entry field
  40.   that contains customer names can generate a "customer" item; a bit map can
  41.   provide an item that can extract the picture from a .bmp file.
  42.  
  43.   User Interface Class Library provides direct manipulation for:
  44.  
  45.   o   Entry field
  46.   o   Multiple-line edit
  47.  
  48.  
  49.  
  50.  
  51.   ENABLING DIRECT MANIPULATION
  52.   ____________________________
  53.  
  54.   To enable direct manipulation for an entry field or multiple-line edit
  55.   control, create instances of IDMSourceHandler and IDMTargetHandler and attach
  56.   each to a control.
  57.  
  58.   The following sample code enables direct manipulation of text between two
  59.   entry fields in the same process.
  60.  
  61.     .
  62.     .
  63.     .
  64.      9 void main()
  65.     10 {
  66.     11   IFrameWindow
  67.     12    frame( "ICLUI Direct Manipulation Sample 1" );
  68.     13
  69.     14   IEntryField                     //Create window with two
  70.     15     client( 0, &frame, &frame ),  //entry fields, client and ext.
  71.     16     ext   ( 0, &frame, &frame );
  72.     17
  73.     18   IDMSOURCEHANDLER                //DEFINE A SOURCE HANDLER FOR
  74.     19     SRCHANDLER( &CLIENT );        //THE ENTRY FIELD CLIENT.
  75.     20   IDMTARGETHANDLER                //DEFINE A TARGET HANDLER FOR
  76.     21     TGTHANDLER( &CLIENT );        //THE ENTRY FIELD CLIENT.
  77.     22
  78.     23   EXT.SETITEMPROVIDER(CLIENT.ITEMPROVIDER(-));//ADD DRAG ITEM
  79.     24                                              //PROVIDER FOR EXT.
  80.     25   SRCHANDLER.HANDLEEVENTSFOR(&EXT);//ADD SOURCE HANDLER FOR EXT.
  81.     26   TGTHANDLER.HANDLEEVENTSFOR(&EXT);//ADD TARGET HANDLER FOR EXT.
  82.     27
  83.     28   frame
  84.     29     .setClient( &client )
  85.     30     .addExtension( &ext, IFrameWindow::belowClient, 0.5 )
  86.     31     .setFocus()
  87.     32     .show();
  88.     33
  89.     34   IApplication::current().run();
  90.     35
  91.     36 }
  92.  
  93.   Lines 18 and 19 create an instance of IDMSourceHandler and attach it to the
  94.   CLIENT entry field.  IDMSourceHandler creates a drag item provider for the
  95.   entry field if one has not already been created.
  96.  
  97.   Lines 20 and 21 create an instance of IDMTargetHandler and attach it to the
  98.   CLIENT entry field.
  99.  
  100.   Line 23 attaches the drag item provider to the EXT entry field.  The drag
  101.   item provider was created by the IDMSourceHandler constructor that was
  102.   invoked on lines 18 and 19.
  103.  
  104.   Lines 25 and 26 attach the source and target handlers that were created on
  105.   lines 18 through 20 to the EXT entry field.
  106.  
  107.  
  108.  
  109.   ADDING DIRECT MANIPULATION TO AN OBJECT
  110.   _______________________________________
  111.  
  112.   To add direct manipulation to other controls, you must specifically create
  113.   the handlers, renderers, and item providers that IBM Class Library generates
  114.   automatically for entry field  and multiple-line edit controls.  You must:
  115.  
  116.   o   Add IDMItem as the base class for the current application object and
  117.       override the member function "dropped".
  118.  
  119.   o   Write a drag item provider for the customized object using
  120.       IDMItemProvider.
  121.  
  122.   o   Create the drag item providers, the renderers, and the handlers for the
  123.       customized object.
  124.  
  125.   The following example adds drop support to a bit-map control.  The header
  126.   file defines two classes, ABitmapItem and ABitmapProvider, and overrides the
  127.   member functions "dropped" and "provideTargetItemFor".  The .cpp file adds
  128.   the drag item provider, the target handler, and the target renderer.
  129.  
  130.     01 #include <idmprov.hpp>
  131.     02
  132.     03 #include <idmitem.hpp>
  133.     04
  134.     05 class ABitmapItem : public IDMItem {
  135.     06 public:
  136.     07   ABitmapItem ( const IDMItemHandle &item );
  137.     08
  138.     09 virtual Boolean
  139.     10   dropped ( IWindow *target, IDMTargetDropEvent & );
  140.     11 };
  141.     12
  142.     13 class ABitmapProvider : public IDMItemProvider {
  143.     14 public:
  144.     15 virtual IDMItemHandle
  145.     16   provideTargetItemFor ( const IDMItemHandle item );
  146.     17 };
  147.  
  148.   Lines 5 through 11 declare IDMItem as the base class for objects of a
  149.   specialized class named ABitmapItem.  Objects of this class provide bit-map
  150.   control drop behavior when a source bit-map file is dropped on a bit-map
  151.   control that is properly configured with a target handler and an
  152.   ABitmapProvider.
  153.  
  154.   Lines 12 through 17 define a drag item provider for a bit-map control and
  155.   override "provideTargetItemFor" so it returns an ABitmapItem to replace the
  156.   argument item.
  157.     .
  158.     .
  159.     19 void main()
  160.     20   {
  161.     21   IFrameWindow
  162.     22     frame ( "C Set ++ Direct Manipulation - Sample 2" );
  163.     23
  164.     24   IBitmapControl         // Create an empty bit-map control.
  165.     25     bmpControl ( 0, &frame, &frame );
  166.     26
  167.     27   IDMTargetHandler       // Create target handler
  168.     28     handler;             // for the bit-map control.
  169.     29
  170.     30   handler.handleEventsFor( &bmpControl );// Add target handler on bit-map control.
  171.     31
  172.     32   ABitmapProvider        // Create a bit-map drag item provider.
  173.     33     itemProvider;
  174.     34
  175.     35  bmpControl.setDragItemProvider( &itemProvider );// Attach provider to the bit-map control.
  176.     36
  177.     37  IDMTargetRenderer       //Create renderer to render items.
  178.     38     renderer;
  179.     39
  180.     40   renderer.setSupportedRMFs( "<DRM_OS2FILE,DRF_TEXT>" )// Set up renderer
  181.     41           .setSupportedTypes( "Bitmap" );                 // to accept .bmp files.
  182.     42
  183.     43   handler.addRenderer( &renderer );
  184.     44
  185.     45   bmpControl.setText( "Drop .bmp files here." );// Set the bit-map control
  186.     46   frame.setClient( &bmpControl )                // as the frame's client and
  187.     47        .showModally();                          // display the frame.
  188.     48   }
  189.  
  190.   First, the .cpp file creates an empty bit-map control object called
  191.   BMPCONTROL and then creates and attaches the handler, provider, and renderer.
  192.  
  193.   Lines 24 and 25 create the bit-map control object.
  194.  
  195.   Lines 27 and 28 construct a target handler without passing a parameter.  The
  196.   constructor for IDMTargetHandler accepts one parameter, a pointer to an
  197.   instance of IEntryField or IMultiLineEdit or NULL.  The default is NULL.
  198.  
  199.   Line 30 attaches the target handler created on line 27 to BMPCONTROL.
  200.  
  201.   Lines 32 and 33 construct a drag item provider named ITEMPROVIDER.
  202.  
  203.   Line 35 attaches the drag item provider to BMPCONTROL.
  204.  
  205.   Line 37 constructs a renderer.
  206.  
  207.   Lines 40 and 41 define the rendering mechanisms and formats (RMFs) and the
  208.   type that the renderer will support.
  209.  
  210.   Line 43 attaches the renderer to the target handler.
  211.       .
  212.       .
  213.      49
  214.      50 ABitmapItem :: ABitmapItem ( const IDMItemHandle &item )
  215.      51   : IDMItem( *item )
  216.      52   {
  217.      53   }
  218.      54
  219.      55 Boolean ABitmapItem :: dropped ( IWindow *target, IDMTargetDropEvent & )
  220.      56   {
  221.      57   IBitmapControl                              // Get pointer to target bitmap control.
  222.      58    *bmpControl = (IBitmapControl*)target;
  223.      59
  224.      60   IString                                     // Construct dropped .bmp file name from this item.
  225.      61     fname = this->containerName() + "\\" + this->sourceName();
  226.      62
  227.      63   struct stat                                 // Get file size.
  228.      64     buf;
  229.      65   stat( fname, &buf);
  230.      66
  231.      67   FILE                                        // Open and read the file.
  232.      68    *fileptr = fopen( fname, "rb" );
  233.      69   char
  234.      70    *buffer = new char[ buf.st_size ];
  235.      71   fread( buffer, sizeof(char), buf.st_size, fileptr );
  236.      72
  237.      73   BITMAPARRAYFILEHEADER2                      // Construct the bitmap from the file.
  238.      74    *array = ( BITMAPARRAYFILEHEADER2 * )buffer;
  239.      75   BITMAPFILEHEADER2
  240.      76    *header;
  241.      77
  242.      78   if ( array->usType == BFT_BITMAPARRAY ) {   // First, see if file holds array of bitmaps.
  243.      79     header = &array->bfh2;                    // It is, point to first file header in array.
  244.      80   } else {
  245.      81     header = ( BITMAPFILEHEADER2 * )buffer;   // It isn't, point to file header at start of file.
  246.      82   }
  247.      83   if ( header->usType == BFT_BMAP) {          // Now check to see if this is a bitmap.
  248.      84
  249.      85     IPresSpaceHandle                          // We can proceed, first get a presentation space.
  250.      86       hps = bmpControl -> presSpace();
  251.      87
  252.      88     if ( hps ) {
  253.      89       IBitmapHandle                           // Now create the bit map from the file contents.
  254.      90         hbm = GpiCreateBitmap( hps,
  255.      91                                &header->bmp2,
  256.      92                                CBM_INIT,
  257.      93                                buffer + header->offBits,
  258.      94                                (BITMAPINFO2*)&header->bmp2 );
  259.      95       if ( hbm ) {
  260.      96         IBitmapHandle                     // Get previously dropped bit map.
  261.      97           old = bmpControl -> bitmap();
  262.      98
  263.      99         bmpControl -> setBitmap( hbm );   // Set new one.
  264.     100
  265.     101         GpiDeleteBitmap( old );           // Destroy old because we no longer need it.
  266.     102
  267.     103         bmpControl -> setText( fname );   // Indicate name of dropped file.
  268.     104       } else {
  269.     105         bmpControl -> setText( "Couldn't create bit map!" );
  270.     106       }
  271.     107       bmpControl -> releasePresSpace(hps);// Release the presentation space.
  272.     108     } else {
  273.     109       bmpControl -> setText ( "Couldn't get PS!" );
  274.     110     }
  275.     111   } else {
  276.     112     bmpControl -> setText( fname + " isn't a bit map!" );
  277.     113   }
  278.     114
  279.     115   delete [] buffer;                       // Free buffer.
  280.     116
  281.     117   return true;
  282.     118   }
  283.     119
  284.     120 IDMItemHandle ABitmapProvider :: provideTargetItemFor ( const IDMItemHandle item )
  285.     121   {
  286.     122   return new ABitmapItem ( item );
  287.     123   }
  288.  
  289.   The rest of the .cpp file defines the overridden member functions, "dropped"
  290.   and "provideTargetItemFor", for the classes that were declared in the .hpp
  291.   file.
  292.  
  293.   Lines 50 through 118 define "dropped".  This member function gets the dropped
  294.   file, creates the bitmap, and displays the bitmap in the new space.
  295.  
  296.   Lines 120 through 122 use "provideTargetItemFor" to replace the generic
  297.   IDMItem that was created during the initial target enter event
  298.   (IDMTargetEnterEvent) with the derived class.  This function is called when a
  299.   drop event (IDMTargetDropEvent) occurs on a target window.
  300.  
  301.   6  User Interface Class Library Guide
  302.  
  303.  
  304.  
  305.