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