Code walkthrough

This section contains code listings for the classes you need to create to build a custom presentation, including an extended menu, for Tiles document components:

You can also look at the code for the helper class TMenuHolder in the files
./TilesTutorial/05.Menus/Tiles/MenuHolder.h and MenuHolder.C.

TTilesPresenter: header

TTilesPresenter is declared in the file
./TilesTutorial/05.Menus/Tiles/TilesPresenter.h:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      class TTilesPresenter : public TGUIPresenterFor<TTilesView> {
      public:
          TaligentTypeExtensionDeclarationsMacro (TTilesPresenter)
          DynamicCastDeclarationsMacro();
      
                          // Constructor requires a TGUIBundle.
                          TTilesPresenter(const TGUIBundle&);
                          TTilesPresenter ();
          virtual         ~TTilesPresenter ();
          
          // These functions build and activate the Tiles menu..
          virtualvoid     HandleMenuActivate(TMenu& theMainMenu);
          virtualvoid     HandleMenuDeactivate(TMenu& theMainMenu);
      
      #ifdef USE_ARCHIVES
      
          // These functions handle menu actions and enabling items.
          virtual bool    HandleMenuAction(TMenuAction& action);
          virtual void    HandleCurrentSelectionChange(const TNotification& );
      
      protected:
          // Helper functions.
          void            DoCommand(TCommandOn<TTilesSelection>* command, 
                                   const TStandardText& label);
          virtual TMenu*  CopyArchivedMenu(const char* key) const;
          virtual TArchive* CopyDefaultArchive() const;
      
          // Constant menu item IDs.
          static const TMenuItemID kRedMenuItem;
          static const TMenuItemID kGreenMenuItem;
          static const TMenuItemID kBlueMenuItem;
      #endif // USE_ARCHIVES
      
      private:
          // Stores the Tiles menu.
          TMenuHolder     fMenuHolder;
          bool            fArchiveRead;
      };

TTilesPresenter: source

TTilesPresenter is implemented in the file
./TilesTutorial/05.Menus/Tiles/TilesPresenter.C:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      TaligentTypeExtensionMacro (TTilesPresenter);
      
      TTilesPresenter::TTilesPresenter()
          : fArchiveRead(false)
      {}
      
      TTilesPresenter::TTilesPresenter(const TGUIBundle& bundle)
          // Passes the GUI bundle to the parent class constructor.
          : TGUIPresenterFor<TTilesView>(bundle), fArchiveRead(false)
      {}
      
      TTilesPresenter::~TTilesPresenter()
      {}
      
      void TTilesPresenter::HandleMenuActivate(TMenu& theMainMenu )
      {
          // Activates the parent menus.
          TGUIPresenterFor<TTilesView>::HandleMenuActivate(theMainMenu);
      
      #ifdef USE_ARCHIVES
          // If using archives, ensures the archived menu is read into a TMenuHolder.
          if (!fArchiveRead) {
              fArchiveRead = TRUE;
              if (!fMenuHolder) fMenuHolder = CopyArchivedMenu("Menu");
          }
          
      #else
          // Only builds the menu the first time the function is called.
          if (!fMenuHolder) {
              TMomentaryMenuItem* item;
              TMenu* tilesMenu;
          
              // Creates a new menu and sets the layout.
              tilesMenu = new TMenu;
              tilesMenu->SetControlLayout(MControl::kTopToBottom);
              tilesMenu->SetItemLayout( MControl::kLeftToRight );
          
              // Creates a new menu item.
              item = new TMomentaryMenuItem();
      
              // Labels it "Red."
              item->AdoptLabel(new TTextLabel(TStandardText("Red")));
              
              // Adds a command control state.
              item->AdoptState(new TTilesControlState(GetGUIBundle(), 
                              TStandardText("Set To Red"), 
                              new TChangeColorCommand (TRGBColor(1,0,0)), true));
      
              // Adds the item to the menu.
              tilesMenu->AdoptLast(item);
          
              // Creates a menu item labeled "Green."
              item = new TMomentaryMenuItem();
              item->AdoptLabel(new TTextLabel(TStandardText("Green")));
              item->AdoptState(new TTilesControlState(GetGUIBundle(), 
                              TStandardText("Set To Green"),
                              new TChangeColorCommand (TRGBColor(0,1,0)), true));
              tilesMenu->AdoptLast(item);
          
              // Creates a menu item labeled "Blue."
              item = new TMomentaryMenuItem();
              item->AdoptLabel(new TTextLabel(TStandardText("Blue")));
              item->AdoptState(new TTilesControlState(GetGUIBundle(), 
                              TStandardText("Set To Blue"),
                              new TChangeColorCommand (TRGBColor(0,0,1)), true));
              tilesMenu->AdoptLast(item);
          
              // Creates a menu item labeled "Create Rock.."
              item = new TMomentaryMenuItem();
              item->AdoptLabel(new TTextLabel(TStandardText("Create Rock")));
              item->AdoptState(new TTilesControlState(GetGUIBundle(), 
                              TStandardText("Create Rock"),
                              new TCreateTileCommand(TTile::kRock, TGPoint(10,10),
                                                  TGPoint(50,50))));
              tilesMenu->AdoptLast(item);
          
              // Creates a menu item labeled "Create Paper."
              item = new TMomentaryMenuItem();
              item->AdoptLabel(new TTextLabel(TStandardText("Create Paper")));
              item->AdoptState(new TTilesControlState(GetGUIBundle(), 
                              TStandardText("Create Paper"),
                              new TCreateTileCommand(TTile::kPaper, TGPoint(70,10),
                                                  TGPoint(50,50))));
              tilesMenu->AdoptLast(item);
          
              // Creates a menu item labeled "Create Scissors."
              item = new TMomentaryMenuItem();
              item->AdoptLabel(new TTextLabel(TStandardText("Create Scissors")));
              item->AdoptState(new TTilesControlState(GetGUIBundle(), 
                              TStandardText("Create Scissors"),
                              new TCreateTileCommand(TTile::kScissors, TGPoint(130,10),
                                                  TGPoint(50,50))));
              tilesMenu->AdoptLast(item);
      
              // Adds the Tiles menu to the main menu, labeling it "Tiles."
              fMenuHolder = new TSubMenuItem(tilesMenu, 
                              new TTextLabel(TStandardText("Tiles")));
          }
      
      #endif // USE_ARCHIVES
      
          // Activates the Tiles menu.
          fMenuHolder.ActivateAfter(theMainMenu, kGUIPresenterDomainID, kEditMenu);
      }
      
      void TTilesPresenter::HandleMenuDeactivate(TMenu& theMainMenu )
      {
          // Deactivates the Tiles menu, then the inherited menus.
          if (fMenuHolder) fMenuHolder.Deactivate();
          TGUIPresenterFor<TTilesView>::HandleMenuDeactivate(theMainMenu);
      }
      
      #ifdef USE_ARCHIVES
      TMenu*
      TTilesPresenter::CopyArchivedMenu(const char* key) const
      {
          // Gets a copy of the archive for the Tiles program.
          TDeleterFor<TArchive> defaultArchive = CopyDefaultArchive();
      
          // Copies the menu from the archive.
          TArchiveEnvelope<TMenu> menu(defaultArchive);
          return menu.CopyObject(TStandardText(key));
      }
      
      TArchive*
      TTilesPresenter::CopyDefaultArchive() const
      {
          TArchive* defaultArchive;
          // Copies the archive associated with the Tiles program.
          try {
              defaultArchive = TArchive::CopyArchiveForSharedLibrary();
              Assertion(defaultArchive != NIL);
          } 
          // Throws an exception if it couldn't access the archive.
          catch (const TStandardException& e) {
              GetGUIBundle()->GetGUIMessageLog()->ReportException(e,
                  TStandardText("TTilesPresenter::CreateDefaultArchive - 
                               Can't open the archive \"TilesTutorialLib\""));
              throw;
          }
          return defaultArchive;
      }
      
      const TMenuItemID TTilesPresenter::kRedMenuItem = 1;
      const TMenuItemID TTilesPresenter::kGreenMenuItem = 2;
      const TMenuItemID TTilesPresenter::kBlueMenuItem = 3;
      
      // Return value indicates whether the action was handled.
      bool
      TTilesPresenter::HandleMenuAction(TMenuAction& action)
      {
          bool result = TRUE;
          
          // Gets the message encapsulated by the action.
          TStandardText message(action.GetMessage());
      
          // Issues the command that corresponds to the action.
          if (message == TStandardText("RedAction")) {
              DoCommand(new TChangeColorCommand(TRGBColor(1,0,0)), 
                          TStandardText("Set To Red"));
          }
          else if (message == TStandardText("GreenAction")) {
              DoCommand(new TChangeColorCommand (TRGBColor(0,1,0)), 
                          TStandardText("Set To Green"));
          }
          else if (message == TStandardText("BlueAction")) {
              DoCommand(new TChangeColorCommand (TRGBColor(0,0,1)), 
                          TStandardText("Set To Blue"));
          }
          else if (message == TStandardText("RockAction")) {
              DoCommand(new TCreateTileCommand(TTile::kRock, TGPoint(10,10), TGPoint(50,50)), 
                                                TStandardText("Create Rock"));
          }
          else if (message == TStandardText("PaperAction")) {
              DoCommand(new TCreateTileCommand(TTile::kPaper, TGPoint(70,10), TGPoint(50,50)), 
                                                TStandardText("Create Paper"));
          }
          else if (message == TStandardText("ScissorsAction")) {
              DoCommand(new TCreateTileCommand(TTile::kScissors, TGPoint(130,10),
                                          TGPoint(50,50)), TStandardText("Create Scissors"));
          }
          else {
              // Passes the action to the parent if it doesn't recognize it.
              result = TGUIPresenterFor<TTilesView>::HandleMenuAction(action);
          }
          return result;
      }
      
      void
      TTilesPresenter::DoCommand(TCommandOn<TTilesSelection>* command, 
                              const TStandardText& label)
      {
          TModelSelection* selection = ::CopyPointer(GetCurrentModelSelection());
          TTilesSelection* tilesSelection = NIL;
      
          // If the current selection is a TTilesSelection, binds it to the command and 
          // requests the document to execute it.
          if (DynamicTypeInfo(*selection) == StaticTypeInfo(TTilesSelection)) {
              tilesSelection = (TTilesSelection *)selection;
              TTilesCommandBinding* commandBinding =
                  new TTilesCommandBinding(command, tilesSelection, *GetGUIBundle(), label);
              AdoptAndDo (commandBinding);
          }
      };
      
      void 
      TTilesPresenter::HandleCurrentSelectionChange(const TNotification& notification)
      {
          TGUIPresenterFor<TTilesView>::HandleCurrentSelectionChange(notification);
      
          // Enables color items if the current selection is not empty.
          bool enabled = !GetCurrentModelSelection()->IsEmpty();
          fMenuHolder.SetEnabled(enabled, kRedMenuItem);
          fMenuHolder.SetEnabled(enabled, kGreenMenuItem);
          fMenuHolder.SetEnabled(enabled, kBlueMenuItem);
      }
      
      #endif // USE_ARCHIVES

TCreateTileCommand: header

TCreateTileCommand is declared in the file
./TilesTutorial/05.Menus/Tiles/TilesCommands.h:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      class TCreateTileCommand : public TCommandOn<TTilesSelection> {
      public:
          TaligentTypeExtensionDeclarationsMacro (TCreateTileCommand)
      
                          // Type of tile to add and its position are specified 
                          // in the constructor..
                          TCreateTileCommand(TTile::EType tileType, const TGPoint& position,
                                          const TGPoint& size);
                          TCreateTileCommand ();
          virtual         ~TCreateTileCommand ();
                          TCreateTileCommand (const TCreateTileCommand &copy);
          virtualTStream& operator>>= (TStream& toStream) const;
          virtualTStream& operator<<= (TStream& fromStream);
      
      protected:
          // TCommandOn<ATarget> overrides.
          virtual void    HandleDoBegin (TTilesSelection& target);
          virtual void    HandleUndo (TTilesSelection& target);
          virtual void    HandleRedo (TTilesSelection& target);
              
      private:
          enum            {kOriginalVersion};
          TTile::EType    fNewTileType; 
          TGPoint         fNewTilePosition, fNewTileSize;
          // TileIndex stores the index of the new created tile to support Undo.
          TileIndex       fNewTileIndex;
      
          TCreateTileCommand&operator= (const TCreateTileCommand& copy) {return *this;}
      };

TCreateTileCommand: source

TCreateTileCommand is implemented in the file
./TilesTutorial/05.Menus/Tiles/TilesCommands.C:

      // Copyright (C) 1995 Taligent, Inc. All rights reserved.
      TaligentTypeExtensionMacro(TCreateTileCommand);
      
      TCreateTileCommand::TCreateTileCommand(TTile::EType tileType, const TGPoint& position,
                                          const TGPoint& size) :
          // Specifies kSerialUndo in the base class constructor.
          TCommandOn<TTilesSelection>(TCommandOn<TTilesSelection>::kSerialUndo),
          fNewTileType(tileType), fNewTileIndex(-1), fNewTilePosition(position), 
          fNewTileSize(size)
      {}
      
      TCreateTileCommand::TCreateTileCommand() :
          TCommandOn<TTilesSelection>(TCommandOn<TTilesSelection>::kSerialUndo),
          // Until a model adopts the new tile, sets the tile index to -1.
          fNewTileType(TTile::kRock), fNewTileIndex(-1)
      {}
      
      TCreateTileCommand::TCreateTileCommand(const TCreateTileCommand &copy) :
          TCommandOn<TTilesSelection>(copy), fNewTileType(copy.fNewTileType),
          fNewTilePosition(copy.fNewTilePosition), fNewTileSize(copy.fNewTileSize),
          fNewTileIndex(copy.fNewTileIndex)
      {}
      
      TCreateTileCommand::~TCreateTileCommand()
      {}
          
      TStream&
      TCreateTileCommand::operator>>=(TStream& toStream) const
      {
          ::WriteVersion(toStream, kOriginalVersion);
          
          TCommandOn<TTilesSelection>::operator>>=(toStream);
          
          // Converts enum value to a short for streaming.
          (short) fNewTileType >>= toStream;
          fNewTilePosition >>= toStream;
          fNewTileSize >>= toStream;
          fNewTileIndex >>= toStream;
          
          return toStream;
      }
      
      TStream&
      TCreateTileCommand::operator<<=(TStream& fromStream)
      {
          VersionInfo version = ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion);
          
          switch (version) {
          case kOriginalVersion: {
              short temp;
              TCommandOn<TTilesSelection>::operator<<=(fromStream);
                              
              temp <<= fromStream;
              fNewTileType = (TTile::EType) temp;
              fNewTilePosition <<= fromStream;
              fNewTileSize <<= fromStream;
              fNewTileIndex <<= fromStream;
              break;
              }
          default:
              throw TInvalidVersionError();
          }
          return fromStream;
      }
      
      void
      TCreateTileCommand::HandleDoBegin(TTilesSelection& target)
      {
          // Creates a file of the specified type, size and position.
          TTile* newTile = new TTile(fNewTileType, TRGBColor(1,0,0), fNewTilePosition,
                                  fNewTileSize);
      
          // Requests the model to adopt the new tile and saves the index for Undo.
          fNewTileIndex = target.GetModelForWriting()->AdoptTile(newTile);
          // Selects the new tile.
          target.SelectTile(fNewTileIndex);
      }
          
      void
      TCreateTileCommand::HandleUndo(TTilesSelection& target)
      {
          // Requests the model to orphan the tile.
          TTile* newTile = target.GetModelForWriting()->OrphanTile(fNewTileIndex);
          delete newTile;
      
          // Resets the new tile index to -1.
          fNewTileIndex = -1;
      }
          
      void
      TCreateTileCommand::HandleRedo(TTilesSelection& target)
      {
          // Reissues the original command.
          HandleDoBegin(target);
      }

Stationery class instantiation

As in Step 1
, you need to instantiate the class template into a template class before using the stationery TGUIModelPresenterStationeryFor<TTilesModel, TTilesPresenter>. This code is in ./TilesTutorial/05.Menus/Tiles/TilesPresenter.C:

    static TGUIModelPresenterStationeryFor<TTilesModel, TTilesPresenter> theStationery;

[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