]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - contrib/meshtex/GenericMainMenu.cpp
Merge commit '4645e19ce9e8f8034233ac965a4103a13b75714c' into garux-merge
[xonotic/netradiant.git] / contrib / meshtex / GenericMainMenu.cpp
diff --git a/contrib/meshtex/GenericMainMenu.cpp b/contrib/meshtex/GenericMainMenu.cpp
new file mode 100644 (file)
index 0000000..0cf4236
--- /dev/null
@@ -0,0 +1,218 @@
+/**
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+
+#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<GenericDialog>& dialog)
+{
+   // Create a new command callback specifically for summoning that dialog.
+   const CommandCallbackMethod
+      <GenericMainMenu, &GenericMainMenu::CommandDialogShow> 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);
+   }
+}