VR-Forces 4.0.4 Class Documentation
Menu Manipulation Example

The Menu Manipulation example demonstrates the following:

The Menu Manipulation example demonstrates how to manipulate the menu, changing it from the system default.

/*******************************************************************************
** Copyright (c) 2012 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/

//\file menuManipulationPlugin.cxx

//This file defines the generic DT_DLL_VRF_PLUGIN_EXPORT_MACRO.  Use that macro when
//you want to export symbols.
#include <vrfGuiCore/vrfGuiExportPlugin.h>

//Include for task menu modifications
#include <vrfGuiCoreQt/DtTaskMenu.h>
//Include for set menu modifications
#include <vrfGuiCoreQt/DtSetMenu.h>
//Include for create menu modifications
#include <vrfGuiCoreQt/DtCreateMenu.h>
//Include for menu bar modifications that are not one of the above 3
#include <vrfGuiCoreQt/vrfMainMenu.h>
//Include for right click menu modifications
#include <vrfGuiCoreQt/vrfRightClickMenu.h>
//Included for this example to show direct entity mapping addition to menus
#include <vrfGuiCore/entityMapperKey.h>

using namespace makVrf;

//This method (called from below) will remove menu items from the configuration.  
//The task, set, command, entity and conditional menus are each handled separately
//from the rest of the menu bar, however, all are touched on in this method
void removeMenuItems(makVrv::DtDe& de)
{
   //Do not allow the user to save any terrains from the file menu.  This is an
   //example of how to remove an individual menu item.
   DtVrfMainMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtFileMenuId).item(DtSaveTerrainItemId));

   //Another example of removing a menu from this same menu
   DtVrfMainMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtFileMenuId).item(DtSaveTerrainAsItemId));

   //This is an example of how to remove an entire menu from the configuration
   DtVrfMainMenu::instance(de).menuConfiguration().removeMenuPath(makVrv::DtMenuPath::mainMenu(DtObserverMenuId));

   //Remove the DI-Guy task from the task menu.  Will effect any location that uses the task menu
   DtTaskMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).item(DtVrfTaskDIGuyAnimationActionId));

   //Now remove the radio sub-menus from the task menu
   DtTaskMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).menu(DtRadioSetMenuId));
   DtTaskMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).menu(DtRadioTaskMenuId));

   //Remove the DI-Guy set from the set menu.  Will effect any location that uses the set menu
   DtSetMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).item(DtVrfSetDIGuyAppearanceActionId));

   //Remove all fixed wings from the create menu
   DtCreateMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::menu("Fixed Wing"));

   //Re-add the entire opposing menu
   DtCreateMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::menu("Fixed Wing").menu("Opposing"));

   //Remove the M1A2
   DtCreateMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::menu("Ground").menu("Friendly").item("M1A2 Tank"));

   //Remove Route
   DtCreateMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::menu("CreateMenu").item("Route"));
}

//This function will take existing menu items and reorganize them.  Specifically putting some items on the task
//menu in sub-menu. This function only shows reorganization in the task menu, but you could apply this to
//many other menus. You can even move it across other menus entirely, but you will need to be sure to register
//those items to the menu class assuming it doesn't already have it.
void reorganizeTaskMenuItems(makVrv::DtDe& de)
{
   //To add a new sub-menu with text "Embark" that will be referenced as DtEmbarkSubmenu from now on.
   //This function at the base menu level creates and registers a simple menu with your choice
   //of text and your choice of a key to reference this menu in paths. It creates the menu, registers it
   //for use and then adds it to the path you specify all at once making it really simple to create
   //a series of sub-menus.
   DtTaskMenu::instance(de).createSimpleMenu("Embark", 
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).menu("DtEmbarkSubmenu"));

   //Now, remove the tasks we want to reorganize but don't unregister them since
   //we plan on re-adding them in the next step.
   DtTaskMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).item(DtVrfTaskEmbarkActionId));
   DtTaskMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).item(DtVrfTaskDisembarkAllActionId));
   DtTaskMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).item(DtVrfTaskDisembarkActionId));

   //And now re-add them to the new sub-menu we created earlier in this function
   DtTaskMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).menu("DtEmbarkSubmenu").item(DtVrfTaskEmbarkActionId));
   DtTaskMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).menu("DtEmbarkSubmenu").item(DtVrfTaskDisembarkAllActionId));
   DtTaskMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId).menu("DtEmbarkSubmenu").item(DtVrfTaskDisembarkActionId));
}

//This function will be used in our next function addToCreateMenu(). This function will be called
//when you click the newly created menu item. You can do whatever you like in this function but
//this sample just pops up a simple dialog. This function must be structured like this in terms of the
//function signature. The usr arg is an optional argument you would set to be your class object
//incase you wanted to register a class specific function and access real data members. You would need
//to cast the void* to your class pointer.
void exampleMenuItemTrigger(makVrv::DtDe& de, void* usr)
{
   QMessageBox::information(NULL, QObject::tr("Example Menu Item Pressed"), QObject::tr("Your menu item works!"));
}

//This function will add some new items to the create menu.  Will add an example menu item, 
//a menu item to create the removed M1A2, and a new sub-menu which contains a few items
void addToCreateMenu(makVrv::DtDe& de)
{
   //This is an example of creating a simple menu item and adding it to a specific location
   //in the menus. This also gives the menu an action which we defined in the function before this
   //called exampleMenuItemTrigger(). Notice that function gets called whenever you click this
   //menu item which is called "Example Menu Item..." in your menus but reference as "DtExampleMenuItem".
   //This works with any main menu (task, set, mainmenu, right click), but it is shown here in the create menu
   DtCreateMenu::instance(de).createSimpleMenuItemAfter("Example Menu Item...",      
      makVrv::DtMenuPath::mainMenu("CreateMenu").item("DtExampleMenuItem"),
      makVrv::DtMenuPath::mainMenu("CreateMenu").item("Obstacle"), &exampleMenuItemTrigger);

   //Now, add a sub-menu called example again. Similar to what we did in the task menu,
   //but with a different text and different string reference name.
   DtCreateMenu::instance(de).createSimpleMenu("Example", 
      makVrv::DtMenuPath::mainMenu("CreateMenu").menu("DtExampleMenu"));

   //Finally, we add the M1A2 creation option to that sub-menu. The create menu has this specialized
   //function that allows you to directly reference what entity mapper key you wish to make with the
   //string you wish to appear in the menu. 
   DtCreateMenu::instance(de).addItemToCreate(
      makVrv::DtMenuPath::menu("DtExampleMenu").item("M1A2"),
      DtEntityMapperKey(1, 1, 1, 225, 1, 1, 3, 0));
}

//This example will take existing menu items and reorganize them.  Specifically putting some items 
//from the set menu in to a sub-menu in the set menu. Similar to what we did with the task menu earlier.
void reorganizeSetMenuItems(makVrv::DtDe& de)
{
   //To add a new sub-menu, the text is "Positioning" and the reference is "DtPositioningSetSubmenu".
   //Again we are using this simple menu creation. It is very useful for creating submenus with no
   //real special functionality.
   DtSetMenu::instance(de).createSimpleMenuBefore("Positioning", 
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).menu("DtPositioningSetSubmenu"),
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).item(DtVrfSetLaserCodeActionId));

   //Now, remove these menu items from their current location
   DtSetMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).item(DtVrfSetLocationActionId));
   DtSetMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).item(DtVrfSetOrderedSpeedActionId));
   DtSetMenu::instance(de).menuConfiguration().removeMenuPath(
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).item(DtVrfSetHeadingActionId));

   //And add them to the new sub menu in the set menu
   DtSetMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).menu("DtPositioningSetSubmenu").item(DtVrfSetLocationActionId));
   DtSetMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).menu("DtPositioningSetSubmenu").item(DtVrfSetOrderedSpeedActionId));
   DtSetMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::mainMenu(DtSetMenuId).menu("DtPositioningSetSubmenu").item(DtVrfSetHeadingActionId));
}

//Adds a new menu called "Example" by using the simple menu creation and adds
//new menu items to it.
void addMenu(makVrv::DtDe& de)
{
   //Here we are using the simple menu creation to create a top level menu in the menu bar.
   //Notice the accessor is via DtVrfMainMenu which will reference any menu in the menu bar.
   //It's also important to notice that if you want to directly affect a specialized menu that
   //is in the menu bar, such as the task,set, or create menus, you need to use their accessors
   //as we have shown in previous functions. Here you are adding this new example menu before the
   //task menu in the menu bar.
   DtVrfMainMenu::instance(de).createSimpleMenuBefore("Example", 
      makVrv::DtMenuPath::mainMenu("DtExampleMenu"),
      makVrv::DtMenuPath::mainMenu(DtTaskMenuId));

   //Now we are creating a simple menu item in this example menu. Notice that even though
   //we created a similar menu in the create menu, each main menu has its own set of menus
   //that it keeps track of. This means that we had to recreate the simple menu for the main
   //menu in order for us to add it. We will reuse the same function we used for the create
   //menu where it pops up a dialog when you click this menu item.
   DtVrfMainMenu::instance(de).createSimpleMenuItem("Example Menu Item...", 
      makVrv::DtMenuPath::mainMenu("DtExampleMenu").item("DtExampleMenuItem"), 
      &exampleMenuItemTrigger);
}

//This function will modify the right click menu. Unlike other menus, the right click menu
//has a special "context sensitivity". What this means is that modifying the right click menu
//changes depending on what is being selected in the GUI. The right click menu allows you
//to specify a "context", which some are predefined and usable, or you can define contexts
//yourself, in which the selection meets your criteria and then you apply those changes.
//This example uses the built in "Entity" context. Here we make changes to the right click
//menu only when an entity is selected. All changes follow the context set so the right
//click menu knows what changes to apply to that context. If you wanted to make changes to
//other contexts, you would set the current context, current as in "working", and make
//modifications to that context.
void modifyRightClick(makVrv::DtDe& de)
{
   //First set the context where you want your changes to apply to. It's a boolean evaluated
   //function based on parameters supplied.
   DtVrfRightClickMenu::instance(de).setCurrentContext("Entity");

   //Now any changes I make to the right click will ONLY apply to the "Entity" context and use
   //that context name's evaluation function. Here I am adding the example menu item we created
   //in the main menu. Items registered in the main menu do not need to be re-registers in the
   //right click menu before you start adding/removing them from the menuConfig.
   DtVrfRightClickMenu::instance(de).menuConfiguration().addMenuPathBefore(
      makVrv::DtMenuPath::popupMenu(DtVrfRightClickContextMenuId).item("DtExampleMenuItem"),
      makVrv::DtMenuPath::popupMenu(DtVrfRightClickContextMenuId).item(DtVrfEditObjectActionId));

   //Add a menu separator. This can be done in any main menu. The name supplied is how you reference it
   //if you want to put other menu items before/after it.
   DtVrfRightClickMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::popupMenu(DtVrfRightClickContextMenuId).separator("DtExampleMenuSeparator"));
   //Adds the previously created example menu
   DtVrfRightClickMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::popupMenu(DtVrfRightClickContextMenuId).menu("DtExampleMenu"));
   //Adds the same menu item we already added to this sub-menu as well
   DtVrfRightClickMenu::instance(de).menuConfiguration().addMenuPath(
      makVrv::DtMenuPath::popupMenu(DtVrfRightClickContextMenuId).menu("DtExampleMenu").item("DtExampleMenuItem"));
}

//This function is called by our plugin structure to make changes to the front end. It goes through
//each function (as you may have already done) and makes modifications to each area of the menus in the GUI.
//Only return true if you are sure you want to continue. In this case, we are set to go once all the changes
//are made.
bool initDeModule(makVrv::DtDe* de)
{
   removeMenuItems(*de);
   reorganizeTaskMenuItems(*de);
   reorganizeSetMenuItems(*de);
   addToCreateMenu(*de);
   addMenu(*de);
   modifyRightClick(*de);
   return true;
}

//This function is also called by our plugin structure and prints out information about this plugin
//to the logs. It's a good indicator that the plugin loaded if you are looking at the logs. 
void DtPluginInformation(DtVrfPluginInformation& info)
{
   info.pluginName = "Menu Manipulation";
   info.pluginDescription = "This example shows how to manipulate menu items.";
   info.pluginVersion = "1.00";
   info.pluginCreator = "MAK Technologies";
   info.pluginCreatorEmail = "sales@mak.com";
   info.pluginContactWebPage = "www.mak.com";
   info.pluginContactMailingAddress = "68 Moulton Street - Cambridge, MA 02138";
   info.pluginContactPhone = "(617) 876 8085";
}

Document ID: Generated on Fri Jun 29 16:33:32 EDT 2012 from SVN revision 116588
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)