Code walkthrough

This section contains code listings for the changes you need to make to the Tiles program to implement drag and drop:

Mixing in MDropAcceptor

To implement the Tiles document component as a drop acceptor, TTilesView now also mixes in MDropAcceptor and overrides the inherited functions ChoosePreferredType and AcceptDrop.

The new code in the TTilesView declaration, in the file
./TilesTutorial/08.DragAndDrop/Tiles/TilesView.h, is shown in bold:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      class TTilesView : public TGUIEmbedderModelView, public MDropAcceptor {
      public:
          //  TTilesView public constructor, destructor, and macro call unchanged.
          
              virtual boolMouseDown (TMouseDownEvent&);
      
              // MDropAcceptor overrides.
              virtual boolChoosePreferredType(const TGPoint& whereDropped,
                              const TSequenceOf<TTypeDescription>& availableTypes,
                              TTypeDescription& chosenType) const;
      
              virtualbool AcceptDrop(const TGPoint& whereDropped, 
                              const TTypeDescription& theType, const TScrapItem &theItem);
              
              const TTilesSelection*GetTilesSelection () const;
              
      protected:
          //  TTilesView drawing functions and protected constructors unchanged.
              
      private: 
          //  Data members unchanged.
      };
TTilesView::ChoosePreferredType and AcceptDrop are implemented in the file
./TilesTutorial/08.DragAndDrop/Tiles/TilesView.C:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      
      // Takes the drop location and a list of available types. The drop location 
      // doesn't matter to TTilesView because it only takes colors.
      bool
      TTilesView::ChoosePreferredType(const TGPoint& whereDropped,
                      const TSequenceOf<TTypeDescription>& availableTypes,
                      TTypeDescription& chosenType) const
      {
          // Iterates until an acceptable type is found. TTilesView only accepts TColor items.
          bool result = false;
          TTypeDescription acceptableType;
          TScrapItemOn<TColor>::GetScrapItemType(acceptableType);
          TIteratorOver<TTypeDescription>* iterator = availableTypes.CreateIterator();
          
          for (TTypeDescription* td = iterator->First(); td; td = iterator->Next()) {
              if (*td == acceptableType) {
                  chosenType = TTypeDescription(*td);
                  result = true;
                  break;
              }
          }
          delete iterator;
          return result;
      }
      
      // Receives the type chosen by ChoosePreferredType.
      bool
      TTilesView::AcceptDrop(const TGPoint& dropLocation, const TTypeDescription& theType,
                  const TScrapItem &theItem)
      {
          // Verifies the items is a TColor item.
          bool result = false;
          if (theType == TScrapItemOn<TColor>::GetScrapItemType()) {
              TScrapItemOn<TColor>& colorItem = (TScrapItemOn<TColor>&) theItem;
      
              TileIndex whichTile = 0;
      
              TModelPointerTo<TTilesModel> model(GetModelReference());
      
              // Determines which tiles was clicked on.
              for (whichTile = model->GetNumTiles() - 1; whichTile >= 0; whichTile--) {
                  if (model->GetTileForReading(whichTile)->ContainsPoint(dropLocation)) {
                      break;
                  }
              }
      
              // If a tile was clicked on, selects it.
              if (whichTile < model->GetNumTiles()) {
      
                  TTilesSelection* selection = (TTilesSelection*) model->CreateSelection ();
                  selection->SelectTile(whichTile);
      
                  
      
      
      
      
                  // Creates a command to change the tile to the color of the dragged 
                  // item and has the document adopt it.
                  TChangeColorCommand* command = 
                      new TChangeColorCommand(*colorItem.GetObject());
                  TTilesCommandBinding* commandBinding =
                      new TTilesCommandBinding(command, selection, *GetGUIBundle(),
                                              TStandardText("Change Color"));
                  AdoptAndDo (commandBinding);
              }
          }
          return TRUE;
      }

TTilesView::MouseDown

To implement the Tiles document component as a drag source, the TTilesView::MouseDown function needs to be modified so that it starts a drag and drop interactor if the user clicks on a tile while pressing the Shift key.

The new code is in the file ./TilesTutorial/08.DragAndDrop/Tiles/TilesView.C. New code is shown in bold:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      bool
      TTilesView::MouseDown (TMouseDownEvent& mouseDownEvent)
      {
          TRGBColor newColor;
          TileIndex whichTile;
          TGPoint mousePoint = mouseDownEvent.GetEventPosition();
          const TModelPointerTo<TTilesModel> model(GetModelReference());
          
          for (whichTile = model->GetNumTiles() - 1; whichTile >= 0; whichTile--) {
              if (model->GetTileForReading(whichTile)->ContainsPoint(mousePoint)) {
                  break;
              }
          }
          
          TTilesSelection* selection = (TTilesSelection*) model->CreateSelection ();
          if (whichTile >= 0) {
              // Finds out if the Shift key was pressed when the mouse down occurred. If so:
              if(TKeyboardInputDevice::GetDefaultKeyboardInputDevice(mouseDownEvent)
                      ->GetModifierKeys().IsShiftKeyDown()) {
      
                  // Gets the color of the clicked-on tile and uses it to create a 
                  // drag appearance.
                  TColor* color = 
                      new TRGBColor(model->GetTileForReading(whichTile)->GetColor());
              
                  TGrafBundle* bundle = new TGrafBundle(*color, TRGBColor(0,0,0));
                  bundle->AdoptFramePen(new TSolidPen(1));
                  MGraphic* dragAppearance = new TPolygon(TGRect(7,3,16,-6), bundle);
      
                  // Creates a scrap item with the color.
                  TScrapItemOn<TColor>* scrapItem = 
                      new TScrapItemOn<TColor>(color, TGPoint::kOrigin);
                  
                  // Creates a drag and drop item with the scrap item.
                  TDragAndDropItem* dragAndDropItem = 
                      new TGeneralDragAndDropItem(TViewHandle(*this), scrapItem);
                  
                  // Creates and starts a drag and drop interactor.
                  TMouseDragAndDropInteractor* interactor = 
                          new TMouseDragAndDropInteractor(dragAndDropItem, dragAppearance,
                              ViewHandle(*this));
                  mouseDownEvent.StartInteractor(interactor); 
              }
              else{
                  selection->SelectTile (whichTile);
                  AdoptCurrentModelSelection (selection);
                  mouseDownEvent.StartInteractor(new TMoveInteractor(this));
              }
          }
          else {
              selection->DeselectAll();
              AdoptCurrentModelSelection (selection);
          }
          return TRUE;
      }


[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker