/** * @file GenericMainMenu.cpp * Implements the GenericMainMenu class. * @ingroup generic-ui */ /* * Copyright 2012 Joel Baxter * * This file is part of MeshTex. * * MeshTex is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MeshTex is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MeshTex. If not, see . */ #include "GenericMainMenu.h" #include "GenericPluginUI.h" #include "GenericPluginUIMessages.h" #include "PluginProperties.h" /** * Default constructor. Note that as this is a protected method, * GenericMainMenu objects cannot be created directly; only subclasses of * GenericMainMenu can be created. */ GenericMainMenu::GenericMainMenu() { } /** * Virtual destructor. */ GenericMainMenu::~GenericMainMenu() { } /** * Invoke the handler for the given command token. * * @param command The command token. */ void GenericMainMenu::Dispatch(const char *command) { // Convert token to string. std::string commandString(command); // Invoke the function from the dispatch map that corresponds to the command. // The command key should always be in the map, since the set of commands // advertised to Radiant is the same as the set used to make the map. #if defined(_DEBUG) ASSERT_MESSAGE(_dispatchMap.find(commandString) != _dispatchMap.end(), "dispatched plugin command unknown"); #endif _dispatchMap[commandString](commandString); } /** * Handle a command that summons a dialog window. * * @param commandString The command token. */ void GenericMainMenu::CommandDialogShow(const std::string& commandString) { // Look up the dialog window for this command. DialogMap::const_iterator dialogMapIter = _dialogMap.find(commandString); // Seems somewhat more plausible that we could hit an error condition here // where there is no associated dialog, so handle that more gracefully // than an assert. GenericDialog *dialog; if (dialogMapIter == _dialogMap.end() || (dialog = dialogMapIter->second) == NULL) { std::string message(commandString + ": " + DIALOG_INTERNAL_ERROR); GenericPluginUI::ErrorReportDialog(DIALOG_ERROR_TITLE, message.c_str()); return; } // If we have the dialog though, let's summon it. dialog->Show(commandString); } /** * Get the command list for the plugin menu, as a semicolon-separated string * of tokens representing each command. * * @return The command list string. */ const std::string& GenericMainMenu::GetCommandList() const { return _menuCommands; } /** * Get the command label list for the plugin menu, as a semicolon-separated * string of labels to appear in the menu. * * @return The command label list string. */ const std::string& GenericMainMenu::GetCommandLabelList() const { return _menuCommandLabels; } /** * Invoked before beginning construction of the command list (by subsequent * Add* invocations). In this base class, BeginEntries does nothing. */ void GenericMainMenu::BeginEntries() { } /** * Append a command-group separator to the command list. This should be done * between an invocation of BeginEntries and EndEntries. (And presumably in * the neighborhood of invocations of AddEntry and/or AddDialogShowEntry.) */ void GenericMainMenu::AddSeparator() { // Our internal command and command-label strings actually grow backwards, // so prepend the separator to them. static std::string separatorString(MENU_SEPARATOR); _menuCommandLabels = separatorString + ";" + _menuCommandLabels; _menuCommands = separatorString + ";" + _menuCommands; } /** * Append a command to the command list that will trigger a callback function * when the menu entry is selected. Invoking AddEntry should be done between * an invocation of BeginEntries and EndEntries. * * @param commandLabel The command label. * @param command The command token, unique for this plugin. * Emptystring is interpreted as: re-use the label * for the token. * @param commandCallback The command callback function. * * @return The globally-unique command token: plugin name + "." + command. */ std::string GenericMainMenu::AddEntry(const char *commandLabel, const char *command, const CommandCallback& commandCallback) { // Our internal command-label string actually grows backwards, so prepend the // command label to it. std::string commandLabelString(commandLabel); _menuCommandLabels = commandLabelString + ";" + _menuCommandLabels; // Use the label for the token if no token specified. std::string commandString(command); if (commandString.empty()) { commandString = commandLabelString; } // Add the plugin name in front of the command token to globally uniquify it. commandString = std::string(PLUGIN_NAME) + "." + commandString; // Our internal command string actually grows backwards, so prepend the // command token to it. _menuCommands = commandString + ";" + _menuCommands; // Save the association between the globally-unique token and callback. _dispatchMap[commandString] = commandCallback; // Return the globally-unique command token. return commandString; } /** * Append a command to the command list that will summon a dialog when the * menu entry is selected. Invoking AddDialogShowEntry should be done between * an invocation of BeginEntries and EndEntries. * * @param commandLabel The command label. * @param command The command token, unique for this plugin. Emptystring * is interpreted as: re-use the label for the token. * @param dialog The dialog this command should summon. */ void GenericMainMenu::AddDialogShowEntry(const char *commandLabel, const char *command, const SmartPointer& dialog) { // Create a new command callback specifically for summoning that dialog. const CommandCallbackMethod commandDialogShow(*this); // Register the command and its callback via AddEntry, and save the // association between the globally-unique token and dialog. _dialogMap.insert( std::make_pair(AddEntry(commandLabel, command, commandDialogShow), dialog)); } /** * Invoked after ending construction of the command list. In this base class, * EndEntries only removes spurious semicolons left behind by the way we * constructed the lists. */ void GenericMainMenu::EndEntries() { if (_menuCommandLabels.length() > 0) { _menuCommandLabels.resize(_menuCommandLabels.length() - 1); _menuCommands.resize(_menuCommands.length() - 1); } }