-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGenericMainMenu.cpp
218 lines (204 loc) · 7.08 KB
/
GenericMainMenu.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
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);
}
}