Code walkthrough

This section contains code listings for the new and modified classes you need to create to implement a mouse interactor:

TMoveInteractor: header

TMoveInteractor is declared in
./TilesTutorial/TilesTutorial/06.MouseInteraction/Tiles/TilesInteractors.h.

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      class TMoveInteractor : public TInteractor, public MMouseEventHandler {
      public:
          TaligentTypeExtensionDeclarationsMacro(TMoveInteractor)
      
                                  // Constructor takes a pointer to the view in which 
                                  // this interactor will operate.
                                  TMoveInteractor(TTilesView *view);
                                  TMoveInteractor();
          virtual                 ~TMoveInteractor();
      
      
          // These functions provide interactive mouse handling and apply 
          // TMoveCommand incrementally.
          virtual bool            MouseDown(TMouseDownEvent& mouseDown);
          virtual bool            MouseMoved(TMouseMovedEvent& mouseMoved);
          virtual bool            MouseUp(TMouseUpEvent& mouseDown);
      
      
          // These functions are claled when a mouse moves in and out of the view.
          virtual bool            MouseEntered(TMouseMovedEvent& mouseEnter);
          virtual bool            MouseExited(TMouseMovedEvent& mouseExit);
              
      protected:
          virtual void            HandleException();
          
      private:
          // View to handle mouse events in.
          TTilesView*             fView;
      
          // Keeps track of command and current selection.
          TTilesCommandBinding*   fCommandBinding;
      
          // Position of original mouse event, used to calculate move delta.
          TGPoint                 fOrigin;
      };

TMoveInteractor: source

TMoveInteractor is implemented in
./TilesTutorial/06.MouseInteraction/Tiles/TilesInteractors.C.

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      TaligentTypeExtensionMacro(TMoveInteractor);
      
      TMoveInteractor::TMoveInteractor()
          : fView(), fCommandBinding(0), fOrigin(0, 0)
      {}
      
      TMoveInteractor::TMoveInteractor(TTilesView *view)
          : fView(view), fCommandBinding(0), fOrigin(0, 0)
      {
          // Sets coordinates to be relative to the view in which the interaction happens.
           SetCoordinateView(TViewHandle(*fView));
      }
      
      TMoveInteractor::~TMoveInteractor()
      {
          // This pointer is NIL if the interaction was successful (the document
          // adopts the command binding).
          delete fCommandBinding;
      }
      
      bool
      TMoveInteractor::MouseDown(TMouseDownEvent& mouseDown)
      {
          // Starts mouse event tracking.
          StartMouseMovedEvents(*mouseDown.GetMouseInputDevice());
          StartMouseEntryEvents();
          
          // Stores position of original mouse-down event.
          fOrigin = mouseDown.GetEventPosition();
          
          return TRUE;
      }
      
      bool
      TMoveInteractor::MouseMoved(TMouseMovedEvent& mouseMoved)
      {
          // Gets delta between original and current mouse positions.
          TGPoint delta = mouseMoved.GetEventPosition() - fOrigin;
          
          // If there is no command binding, this is the first movement since the mouse down.
          if (fCommandBinding || delta.VectorLength() > 3.0) {
              // If the mouse moved at least 3 units, creates a command binding 
              // and initializes command.
              try {
                  TMoveCommand* command;
                  if (fCommandBinding == 0) {
                      command = new TMoveCommand;
                      
                      fCommandBinding = new TTilesCommandBinding(command, 
                          ::CopyPointer(fView->GetTilesSelection()), *fView->GetGUIBundle(),
                          TStandardText("Move"));
                      
                      fView->DoBegin(*fCommandBinding);
                  }
                  
                  command = (TMoveCommand*)fCommandBinding->GetCommand();
                  
                  // Increments the delta and executes the command.
                  command->MoveBy(delta);
                  fView->DoIncrement(*fCommandBinding);
              }
              catch (const TStandardException &e) {
                  HandleException();
              }
          }
      
          return TRUE;
      }
      
      bool
      TMoveInteractor::MouseUp(TMouseUpEvent &mouseUp)
      {
          // Stops tracking mouse events.
          StopMouseEntryEvents();
          StopMouseMovedEvents();
          
      
          // If the mosue wasn't dragged, there is no command binding.
          if (fCommandBinding) {
              try {
                  // Requests the document to adopt and finish the command.
                  TMoveCommand* command = (TMoveCommand*) fCommandBinding->GetCommand();
                  fView->AdoptAndDoEnd(fCommandBinding);
                  fCommandBinding = NIL; 
              }
      
              catch (const TStandardException &e) {
                  HandleException();
              }
          }
      
          // Indicates this interaction is finished.
          SetDone(TRUE);
          return TRUE;
      }
      
      bool    
      TMoveInteractor::MouseExited(TMouseMovedEvent& mouseExit)
      {
          // Stops mouse event handling when mouse moves out of the view.
          StopMouseMovedEvents();
          return TRUE;
      }
      
      bool    
      TMoveInteractor::MouseEntered(TMouseMovedEvent& mouseEnter)
      {
          // Starts mouse event handling when mouse moves into the view.
          StartMouseMovedEvents(*mouseEnter.GetMouseInputDevice());
          return TRUE;
      }
      
      void
      TMoveInteractor::HandleException()
      {
          // If an exception is thrown, the command binding is not adopted by
          // the document and must be deleted. The interaction is then finished.
          delete fCommandBinding;
          fCommandBinding = NIL;
      
          SetDone(TRUE);
      }

TMoveCommand: header

TMoveCommand is declared in the file
./TilesTutorial/06.MouseInteraction/Tiles/TilesCommands.h:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      class TMoveCommand : public TCommandOn<TTilesSelection> {
      public:
          TaligentTypeExtensionDeclarationsMacro (TMoveCommand)
          // Required functions.
                          TMoveCommand ();
          virtual         ~TMoveCommand ();
                          TMoveCommand (const TMoveCommand &copy);
          TMoveCommand&   operator= (const TMoveCommand& copy);
          virtualTStream& operator>>= (TStream& toStream) const;
          virtualTStream& operator<<= (TStream& fromStream);
      
          // Changes delta position for this command to move the target tile.
          void            MoveBy (const TGPoint& delta);
      
      protected:
          virtual void    HandleDoBegin (TTilesSelection& target);
      
          // Executes incremental move steps.
          virtual void    HandleDoIncrement (TTilesSelection& target);
      
          // Undo and Redo are not done incrementally.
          virtual void    HandleUndo (TTilesSelection& target);
          virtual void    HandleRedo (TTilesSelection& target);
              
      private:
          enum            {kOriginalVersion};
      
          // Saves original position and new position as a delta from the original.
          TGPoint         fOldPosition;
          TGPoint         fDelta; 
      };

TMoveCommand: source

TMoveCommand is implemented in
./TilesTutorial/06.MouseInteraction/Tiles/TilesCommands.C.

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      TaligentTypeExtensionMacro(TMoveCommand);
      
      TMoveCommand::TMoveCommand() :
          // Specifies kSerialUndo to allow this command to be undone.
          TCommandOn<TTilesSelection>(TCommandOn<TTilesSelection>::kSerialUndo), 
          fOldPosition(0,0), fDelta(0,0) 
      {}
      
      TMoveCommand::~TMoveCommand()
      {}
      
      TMoveCommand::TMoveCommand(const TMoveCommand &copy) :
          TCommandOn<TTilesSelection>(copy), fOldPosition(copy.fOldPosition),
          fDelta(copy.fDelta)  
      {}
      
      TStream&
      TMoveCommand::operator>>=(TStream& toStream)const
      {
          ::WriteVersion(toStream, kOriginalVersion);
          
          TCommandOn<TTilesSelection>::operator>>=(toStream);
          
          fOldPosition >>= toStream;
          fDelta >>= toStream;
          
          return toStream;
      }
      
      TStream&
      TMoveCommand::operator<<=(TStream& fromStream)
      {
          VersionInfo version = ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion);
          
          switch (version) {
          case kOriginalVersion: {
              TCommandOn<TTilesSelection>::operator<<=(fromStream);
                  
              fOldPosition <<= fromStream;
              fDelta <<= fromStream;
              break;
          }
          default:
              throw TInvalidVersionError();
          }
          return fromStream;
      }
      
      void
      TMoveCommand::HandleDoBegin(TTilesSelection& target)
      {
          // Saves original position of the tile.
          fOldPosition = target.GetPosition();
      
          // Moves tile by any preset delta.
          target.SetPosition(fOldPosition + fDelta);
      }
      
      void
      TMoveCommand::HandleUndo(TTilesSelection& target)
      {
          // Moves tile back to original position. Not performed incrementally.
          target.SetPosition(fOldPosition);
      }
      
      void
      TMoveCommand::HandleRedo(TTilesSelection& target)
      {
          // Moves tile back to new position. Not performed incrementally.
          target.SetPosition(fOldPosition + fDelta);
      }
      
      void
      TMoveCommand::HandleDoIncrement(TTilesSelection& target)
      {
          // Moves tile by the current delta. Should be called after MoveBy.
          target.SetPosition(fOldPosition + fDelta);
      }
      
      void
      TMoveCommand::MoveBy (const TGPoint& delta)
      {
          // Sets the delta position for HandleDoIncrement to move the tile.
          fDelta = delta;
      }

TTilesSelection functions

Following is the declaration of the GetPosition and SetPosition functions, found in the header file ./TilesTutorial/06.MouseInteraction/Tiles/TilesSelections.h. GetPosition and SetPosition are public functions.

          void                SetPosition(const TGPoint&);
          TGPoint             GetPosition();
Following is the source for the GetPosition and SetPosition functions, found in the file ./TilesTutorial/06.MouseInteraction/Tiles/TilesSelections.C.

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      // These functions assume the caller has locked the model:
      void            
      TTilesSelection::SetPosition (const TGPoint& point)
      {
          // Verifies that only one tile is selected.
          if (!IsEmpty() && fLowBound == fHighBound) {
              GetModelForWriting()->GetTileForWriting(fLowBound)->SetPosition(point);
          }
      }
      
      TGPoint         
      TTilesSelection::GetPosition ()
      {
          // Verifies that only one tile is selected.
          if (!IsEmpty() && fLowBound == fHighBound) {
              return GetModelForReading()->GetTileForReading(fLowBound)->GetPosition();
          }
          else {
              return TGPoint(0,0);
          }
      }

TTilesView::MouseDown

Following are the changes to the MouseDown function, found in the file
./TilesTutorial/06.MouseInteraction/Tiles/TilesView.C. Changed 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) {
              selection->SelectTile (whichTile);
              AdoptCurrentModelSelection (selection);
      
              // After setting the current selection to the clicked-on tile, starts 
              // a mouse interactor to handle any dragging events. If the user releases 
              // the mouse without dragging, the tile interaction ends.
              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