1// This file can be included several times.
2
3#ifndef REGISTER_QUICK_ACTION
4// This helps IDEs properly syntax highlight the uses of the macro below.
5#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description)
6#endif
7
8#define ALWAYS_FALSE []() -> bool { return false; }
9#define DEFAULT_BTN []() -> int { return -1; }
10
11REGISTER_QUICK_ACTION(
12 ShowHelp,
13 "Show help",
14 [&]() { ShowHelp(); },
15 ALWAYS_FALSE,
16 ALWAYS_FALSE,
17 DEFAULT_BTN,
18 "[F1] Open the DDNet Wiki page for the map editor in a web browser.")
19REGISTER_QUICK_ACTION(
20 BrushPicker,
21 "Brush picker",
22 [&]() { m_ShowPickerToggle = !m_ShowPickerToggle; },
23 [&]() -> bool {
24 return m_Mode != MODE_LAYERS ||
25 Map()->m_vSelectedLayers.size() != 1 ||
26 Map()->SelectedLayer(0) == nullptr ||
27 (Map()->SelectedLayer(0)->m_Type != LAYERTYPE_TILES && Map()->SelectedLayer(0)->m_Type != LAYERTYPE_QUADS);
28 },
29 [&]() -> bool { return m_ShowPickerToggle; },
30 DEFAULT_BTN,
31 "[Ctrl+Space, Hold Space] Toggle brush picker.")
32REGISTER_QUICK_ACTION(
33 ToggleGrid,
34 "Toggle grid",
35 [&]() { MapView()->MapGrid()->Toggle(); },
36 ALWAYS_FALSE,
37 [&]() -> bool { return MapView()->MapGrid()->IsEnabled(); },
38 DEFAULT_BTN,
39 "[Ctrl+G] Toggle grid.")
40REGISTER_QUICK_ACTION(
41 GameTilesAir,
42 "Game tiles: Air",
43 [&]() { FillGameTiles(EGameTileOp::AIR); },
44 [&]() -> bool { return !CanFillGameTiles(); },
45 ALWAYS_FALSE,
46 DEFAULT_BTN,
47 "Construct game tiles from this layer.")
48REGISTER_QUICK_ACTION(
49 GameTilesHookable,
50 "Game tiles: Hookable",
51 [&]() { FillGameTiles(EGameTileOp::HOOKABLE); },
52 [&]() -> bool { return !CanFillGameTiles(); },
53 ALWAYS_FALSE,
54 DEFAULT_BTN,
55 "Construct game tiles from this layer.")
56REGISTER_QUICK_ACTION(
57 GameTilesDeath,
58 "Game tiles: Death",
59 [&]() { FillGameTiles(EGameTileOp::DEATH); },
60 [&]() -> bool { return !CanFillGameTiles(); },
61 ALWAYS_FALSE,
62 DEFAULT_BTN,
63 "Construct game tiles from this layer.")
64REGISTER_QUICK_ACTION(
65 GameTilesUnhookable,
66 "Game tiles: Unhookable",
67 [&]() { FillGameTiles(EGameTileOp::UNHOOKABLE); },
68 [&]() -> bool { return !CanFillGameTiles(); },
69 ALWAYS_FALSE,
70 DEFAULT_BTN,
71 "Construct game tiles from this layer.")
72REGISTER_QUICK_ACTION(
73 GameTilesHookthrough,
74 "Game tiles: Hookthrough",
75 [&]() { FillGameTiles(EGameTileOp::HOOKTHROUGH); },
76 [&]() -> bool { return !CanFillGameTiles(); },
77 ALWAYS_FALSE,
78 DEFAULT_BTN,
79 "Construct game tiles from this layer.")
80REGISTER_QUICK_ACTION(
81 GameTilesFreeze,
82 "Game tiles: Freeze",
83 [&]() { FillGameTiles(EGameTileOp::FREEZE); },
84 [&]() -> bool { return !CanFillGameTiles(); },
85 ALWAYS_FALSE,
86 DEFAULT_BTN,
87 "Construct game tiles from this layer.")
88REGISTER_QUICK_ACTION(
89 GameTilesUnfreeze,
90 "Game tiles: Unfreeze",
91 [&]() { FillGameTiles(EGameTileOp::UNFREEZE); },
92 [&]() -> bool { return !CanFillGameTiles(); },
93 ALWAYS_FALSE,
94 DEFAULT_BTN,
95 "Construct game tiles from this layer.")
96REGISTER_QUICK_ACTION(
97 GameTilesDeepFreeze,
98 "Game tiles: Deep Freeze",
99 [&]() { FillGameTiles(EGameTileOp::DEEP_FREEZE); },
100 [&]() -> bool { return !CanFillGameTiles(); },
101 ALWAYS_FALSE,
102 DEFAULT_BTN,
103 "Construct game tiles from this layer.")
104REGISTER_QUICK_ACTION(
105 GameTilesDeepUnfreeze,
106 "Game tiles: Deep Unfreeze",
107 [&]() { FillGameTiles(EGameTileOp::DEEP_UNFREEZE); },
108 [&]() -> bool { return !CanFillGameTiles(); },
109 ALWAYS_FALSE,
110 DEFAULT_BTN,
111 "Construct game tiles from this layer.")
112REGISTER_QUICK_ACTION(
113 GameTilesBlueCheckTele,
114 "Game tiles: Blue Check Tele",
115 [&]() { FillGameTiles(EGameTileOp::BLUE_CHECK_TELE); },
116 [&]() -> bool { return !CanFillGameTiles(); },
117 ALWAYS_FALSE,
118 DEFAULT_BTN,
119 "Construct game tiles from this layer.")
120REGISTER_QUICK_ACTION(
121 GameTilesRedCheckTele,
122 "Game tiles: Red Check Tele",
123 [&]() { FillGameTiles(EGameTileOp::RED_CHECK_TELE); },
124 [&]() -> bool { return !CanFillGameTiles(); },
125 ALWAYS_FALSE,
126 DEFAULT_BTN,
127 "Construct game tiles from this layer.")
128REGISTER_QUICK_ACTION(
129 GameTilesLiveFreeze,
130 "Game tiles: Live Freeze",
131 [&]() { FillGameTiles(EGameTileOp::LIVE_FREEZE); },
132 [&]() -> bool { return !CanFillGameTiles(); },
133 ALWAYS_FALSE,
134 DEFAULT_BTN,
135 "Construct game tiles from this layer.")
136REGISTER_QUICK_ACTION(
137 GameTilesLiveUnfreeze,
138 "Game tiles: Live Unfreeze",
139 [&]() { FillGameTiles(EGameTileOp::LIVE_UNFREEZE); },
140 [&]() -> bool { return !CanFillGameTiles(); },
141 ALWAYS_FALSE,
142 DEFAULT_BTN,
143 "Construct game tiles from this layer.")
144REGISTER_QUICK_ACTION(
145 AddGroup,
146 "Add group",
147 [&]() { AddGroup(); },
148 ALWAYS_FALSE,
149 ALWAYS_FALSE,
150 DEFAULT_BTN,
151 "Add a new group.")
152REGISTER_QUICK_ACTION(
153 ResetZoom,
154 "Reset zoom",
155 [&]() { MapView()->ResetZoom(); },
156 ALWAYS_FALSE,
157 ALWAYS_FALSE,
158 DEFAULT_BTN,
159 "[Numpad*] Zoom to normal and remove editor offset.")
160REGISTER_QUICK_ACTION(
161 ZoomOut,
162 "Zoom out",
163 [&]() { MapView()->Zoom()->ChangeValue(50.0f); },
164 ALWAYS_FALSE,
165 ALWAYS_FALSE,
166 DEFAULT_BTN,
167 "[Numpad-] Zoom out.")
168REGISTER_QUICK_ACTION(
169 ZoomIn,
170 "Zoom in",
171 [&]() { MapView()->Zoom()->ChangeValue(-50.0f); },
172 ALWAYS_FALSE,
173 ALWAYS_FALSE,
174 DEFAULT_BTN,
175 "[Numpad+] Zoom in.")
176REGISTER_QUICK_ACTION(
177 Refocus,
178 "Refocus",
179 [&]() { MapView()->Focus(); },
180 ALWAYS_FALSE,
181 ALWAYS_FALSE,
182 DEFAULT_BTN,
183 "[Home] Restore map focus.")
184REGISTER_QUICK_ACTION(
185 Proof,
186 "Proof",
187 [&]() { MapView()->ProofMode()->Toggle(); },
188 ALWAYS_FALSE,
189 [&]() -> bool { return MapView()->ProofMode()->IsEnabled(); },
190 DEFAULT_BTN,
191 "Toggle proof borders. These borders represent the area that a player can see with default zoom.")
192REGISTER_QUICK_ACTION(
193 AddTileLayer, "Add tile layer", [&]() { AddTileLayer(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Create a new tile layer.")
194REGISTER_QUICK_ACTION(
195 AddSwitchLayer,
196 "Add switch layer",
197 [&]() { AddSwitchLayer(); },
198 [&]() -> bool { return !Map()->SelectedGroup()->m_GameGroup || Map()->m_pSwitchLayer; },
199 ALWAYS_FALSE,
200 DEFAULT_BTN,
201 "Create a new switch layer.")
202REGISTER_QUICK_ACTION(
203 AddTuneLayer,
204 "Add tune layer",
205 [&]() { AddTuneLayer(); },
206 [&]() -> bool { return !Map()->SelectedGroup()->m_GameGroup || Map()->m_pTuneLayer; },
207 ALWAYS_FALSE,
208 DEFAULT_BTN,
209 "Create a new tuning layer.")
210REGISTER_QUICK_ACTION(
211 AddSpeedupLayer,
212 "Add speedup layer",
213 [&]() { AddSpeedupLayer(); },
214 [&]() -> bool { return !Map()->SelectedGroup()->m_GameGroup || Map()->m_pSpeedupLayer; },
215 ALWAYS_FALSE,
216 DEFAULT_BTN,
217 "Create a new speedup layer.")
218REGISTER_QUICK_ACTION(
219 AddTeleLayer,
220 "Add tele layer",
221 [&]() { AddTeleLayer(); },
222 [&]() -> bool { return !Map()->SelectedGroup()->m_GameGroup || Map()->m_pTeleLayer; },
223 ALWAYS_FALSE,
224 DEFAULT_BTN,
225 "Create a new tele layer.")
226REGISTER_QUICK_ACTION(
227 AddFrontLayer,
228 "Add front layer",
229 [&]() { AddFrontLayer(); },
230 [&]() -> bool { return !Map()->SelectedGroup()->m_GameGroup || Map()->m_pFrontLayer; },
231 ALWAYS_FALSE,
232 DEFAULT_BTN,
233 "Create a new item layer.")
234REGISTER_QUICK_ACTION(
235 AddQuadsLayer, "Add quads layer", [&]() { AddQuadsLayer(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Create a new quads layer.")
236REGISTER_QUICK_ACTION(
237 AddSoundLayer, "Add sound layer", [&]() { AddSoundLayer(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Create a new sound layer.")
238REGISTER_QUICK_ACTION(
239 SaveAs,
240 "Save as",
241 [&]() {
242 char aDefaultName[IO_MAX_PATH_LENGTH];
243 fs_split_file_extension(fs_filename(Map()->m_aFilename), aDefaultName, sizeof(aDefaultName));
244 m_FileBrowser.ShowFileDialog(IStorage::TYPE_SAVE, CFileBrowser::EFileType::MAP, "Save map", "Save as", "maps", aDefaultName, CallbackSaveMap, this);
245 },
246 ALWAYS_FALSE,
247 ALWAYS_FALSE,
248 DEFAULT_BTN,
249 "[Ctrl+Shift+S] Save the current map under a new name.")
250REGISTER_QUICK_ACTION(
251 LoadCurrentMap,
252 "Load current map",
253 [&]() {
254 if(HasUnsavedData())
255 {
256 if(!m_PopupEventWasActivated)
257 {
258 m_PopupEventType = POPEVENT_LOADCURRENT;
259 m_PopupEventActivated = true;
260 }
261 }
262 else
263 {
264 LoadCurrentMap();
265 }
266 },
267 [&]() -> bool { return Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK; },
268 ALWAYS_FALSE,
269 DEFAULT_BTN,
270 "[Ctrl+Shift+L] Open the current ingame map for editing.")
271REGISTER_QUICK_ACTION(
272 Envelopes,
273 "Envelopes",
274 [&]() { m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES ? EXTRAEDITOR_NONE : EXTRAEDITOR_ENVELOPES; },
275 ALWAYS_FALSE,
276 ALWAYS_FALSE,
277 [&]() -> int { return m_ShowPicker ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES; },
278 "Toggle the envelope editor.")
279REGISTER_QUICK_ACTION(
280 ServerSettings,
281 "Server settings",
282 [&]() { m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_SERVER_SETTINGS ? EXTRAEDITOR_NONE : EXTRAEDITOR_SERVER_SETTINGS; },
283 ALWAYS_FALSE,
284 ALWAYS_FALSE,
285 [&]() -> int { return m_ShowPicker ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_SERVER_SETTINGS; },
286 "Toggle the server settings editor.")
287REGISTER_QUICK_ACTION(
288 History,
289 "History",
290 [&]() { m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_HISTORY ? EXTRAEDITOR_NONE : EXTRAEDITOR_HISTORY; },
291 ALWAYS_FALSE,
292 ALWAYS_FALSE,
293 [&]() -> int { return m_ShowPicker ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_HISTORY; },
294 "Toggle the editor history view.")
295REGISTER_QUICK_ACTION(
296 AddImage,
297 "Add image",
298 [&]() { m_FileBrowser.ShowFileDialog(IStorage::TYPE_ALL, CFileBrowser::EFileType::IMAGE, "Add image", "Add", "mapres", "", AddImage, this); },
299 ALWAYS_FALSE,
300 ALWAYS_FALSE,
301 DEFAULT_BTN,
302 "Load a new image to use in the map.")
303REGISTER_QUICK_ACTION(
304 LayerPropAddImage,
305 "Layer: add image",
306 [&]() { LayerSelectImage(); },
307 [&]() -> bool { return !IsNonGameTileLayerSelected(); },
308 ALWAYS_FALSE,
309 DEFAULT_BTN,
310 "Pick mapres image for currently selected layer.")
311REGISTER_QUICK_ACTION(
312 ShowInfoOff,
313 "Show info: Off",
314 [&]() {
315 m_ShowTileInfo = SHOW_TILE_OFF;
316 },
317 ALWAYS_FALSE,
318 [&]() -> bool { return m_ShowTileInfo == SHOW_TILE_OFF; },
319 DEFAULT_BTN,
320 "Do not show tile information.")
321REGISTER_QUICK_ACTION(
322 ShowInfoDec,
323 "Show info: Dec",
324 [&]() {
325 m_ShowTileInfo = SHOW_TILE_DECIMAL;
326 },
327 ALWAYS_FALSE,
328 [&]() -> bool { return m_ShowTileInfo == SHOW_TILE_DECIMAL; },
329 DEFAULT_BTN,
330 "[Ctrl+I] Show tile information.")
331REGISTER_QUICK_ACTION(
332 ShowInfoHex,
333 "Show info: Hex",
334 [&]() {
335 m_ShowTileInfo = SHOW_TILE_HEXADECIMAL;
336 },
337 ALWAYS_FALSE,
338 [&]() -> bool { return m_ShowTileInfo == SHOW_TILE_HEXADECIMAL; },
339 DEFAULT_BTN,
340 "[Ctrl+Shift+I] Show tile information in hexadecimal.")
341REGISTER_QUICK_ACTION(
342 PreviewQuadEnvelopes,
343 "Preview quad envelopes",
344 [&]() {
345 m_ShowEnvelopePreview = !m_ShowEnvelopePreview;
346 m_ActiveEnvelopePreview = EEnvelopePreview::NONE;
347 },
348 ALWAYS_FALSE,
349 [&]() -> bool { return m_ShowEnvelopePreview; },
350 DEFAULT_BTN,
351 "Toggle previewing the paths of quads with a position envelope when a quad layer is selected.")
352REGISTER_QUICK_ACTION(
353 DeleteLayer,
354 "Delete layer",
355 [&]() { DeleteSelectedLayer(); },
356 [&]() -> bool {
357 std::shared_ptr<CLayer> pCurrentLayer = Map()->SelectedLayer(0);
358 if(!pCurrentLayer)
359 return true;
360 return Map()->m_pGameLayer == pCurrentLayer;
361 },
362 ALWAYS_FALSE,
363 DEFAULT_BTN,
364 "Delete the layer.")
365REGISTER_QUICK_ACTION(
366 Pipette,
367 "Pipette",
368 [&]() { m_ColorPipetteActive = !m_ColorPipetteActive; },
369 ALWAYS_FALSE,
370 [&]() -> bool { return m_ColorPipetteActive; },
371 DEFAULT_BTN,
372 "[Ctrl+Shift+C] Color pipette. Pick a color from the screen by clicking on it.")
373REGISTER_QUICK_ACTION(
374 MapDetails,
375 "Map details",
376 [&]() { MapDetails(); },
377 ALWAYS_FALSE,
378 ALWAYS_FALSE,
379 DEFAULT_BTN,
380 "Adjust the map details of the current map.")
381REGISTER_QUICK_ACTION(
382 AddQuad,
383 "Add quad",
384 [&]() { AddQuadOrSound(); },
385 [&]() -> bool {
386 std::shared_ptr<CLayer> pLayer = Map()->SelectedLayer(0);
387 if(!pLayer)
388 return false;
389 return pLayer->m_Type != LAYERTYPE_QUADS;
390 },
391 ALWAYS_FALSE,
392 DEFAULT_BTN,
393 "[Ctrl+Q] Add a new quad.")
394REGISTER_QUICK_ACTION(
395 AddSoundSource,
396 "Add sound source",
397 [&]() { AddQuadOrSound(); },
398 [&]() -> bool {
399 std::shared_ptr<CLayer> pLayer = Map()->SelectedLayer(0);
400 if(!pLayer)
401 return false;
402 return pLayer->m_Type != LAYERTYPE_SOUNDS;
403 },
404 ALWAYS_FALSE,
405 DEFAULT_BTN,
406 "[Ctrl+Q] Add a new sound source.")
407REGISTER_QUICK_ACTION(
408 TestMapLocally,
409 "Test map locally",
410 [&]() { TestMapLocally(); },
411 ALWAYS_FALSE,
412 ALWAYS_FALSE,
413 DEFAULT_BTN,
414 "Run a local server with the current map and connect you to it.")
415
416#undef ALWAYS_FALSE
417#undef DEFAULT_BTN
418