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