Преглед на файлове

Most of buttons created in cpp now have assigned shortcut

Ivan Savenko преди 1 година
родител
ревизия
88fbb7ee71
променени са 30 файла, в които са добавени 166 реда и са изтрити 98 реда
  1. 1 1
      client/adventureMap/AdventureMapShortcuts.cpp
  2. 1 1
      client/adventureMap/AdventureOptions.cpp
  3. 1 1
      client/eventsSDL/InputSourceKeyboard.cpp
  4. 2 1
      client/globalLobby/GlobalLobbyInviteWindow.cpp
  5. 3 4
      client/globalLobby/GlobalLobbyLoginWindow.cpp
  6. 3 5
      client/globalLobby/GlobalLobbyRoomWindow.cpp
  7. 3 2
      client/globalLobby/GlobalLobbyServerSetup.cpp
  8. 57 1
      client/gui/Shortcut.h
  9. 1 1
      client/gui/ShortcutHandler.cpp
  10. 17 5
      client/lobby/CBonusSelection.cpp
  11. 2 2
      client/lobby/CLobbyScreen.cpp
  12. 5 5
      client/lobby/CSelectionBase.cpp
  13. 12 13
      client/lobby/SelectionTab.cpp
  14. 4 4
      client/mainmenu/CHighScoreScreen.cpp
  15. 4 4
      client/mainmenu/CMainMenu.cpp
  16. 4 3
      client/widgets/markets/CAltarArtifacts.cpp
  17. 3 2
      client/widgets/markets/CAltarCreatures.cpp
  18. 2 1
      client/widgets/markets/CArtifactsBuying.cpp
  19. 2 1
      client/widgets/markets/CArtifactsSelling.cpp
  20. 2 1
      client/widgets/markets/CFreelancerGuild.cpp
  21. 2 1
      client/widgets/markets/CMarketBase.cpp
  22. 2 1
      client/widgets/markets/CMarketResources.cpp
  23. 2 1
      client/widgets/markets/CTransferResources.cpp
  24. 5 11
      client/windows/CCastleInterface.cpp
  25. 1 1
      client/windows/CHeroWindow.cpp
  26. 9 9
      client/windows/CMarketWindow.cpp
  27. 1 1
      client/windows/CQuestLog.cpp
  28. 1 1
      client/windows/CTutorialWindow.cpp
  29. 1 1
      client/windows/CreaturePurchaseCard.cpp
  30. 13 13
      client/windows/GUIClasses.cpp

+ 1 - 1
client/adventureMap/AdventureMapShortcuts.cpp

@@ -494,7 +494,7 @@ bool AdventureMapShortcuts::optionInWorldView()
 
 bool AdventureMapShortcuts::optionSidePanelActive()
 {
-	return state == EAdventureState::MAKING_TURN || state == EAdventureState::WORLD_VIEW || state == EAdventureState::OTHER_HUMAN_PLAYER_TURN;
+return state == EAdventureState::MAKING_TURN || state == EAdventureState::WORLD_VIEW || state == EAdventureState::OTHER_HUMAN_PLAYER_TURN;
 }
 
 bool AdventureMapShortcuts::optionMapScrollingActive()

+ 1 - 1
client/adventureMap/AdventureOptions.cpp

@@ -45,7 +45,7 @@ AdventureOptions::AdventureOptions()
 	scenInfo = std::make_shared<CButton>(Point(24, 198), AnimationPath::builtin("ADVINFO.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_SCENARIO);
 	scenInfo->addCallback(AdventureOptions::showScenarioInfo);
 	
-	replay = std::make_shared<CButton>(Point(24, 257), AnimationPath::builtin("ADVTURN.DEF"), CButton::tooltip(), [&](){ close(); });
+	replay = std::make_shared<CButton>(Point(24, 257), AnimationPath::builtin("ADVTURN.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_REPLAY_TURN);
 	replay->addCallback([]{ LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.replayOpponentTurnNotImplemented")); });
 
 	exit = std::make_shared<CButton>(Point(203, 313), AnimationPath::builtin("IOK6432.DEF"), CButton::tooltip(), std::bind(&AdventureOptions::close, this), EShortcut::GLOBAL_RETURN);

+ 1 - 1
client/eventsSDL/InputSourceKeyboard.cpp

@@ -75,7 +75,7 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
 
 	auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
 
-	if (vstd::contains(shortcutsVector, EShortcut::LOBBY_ACTIVATE_INTERFACE))
+	if (vstd::contains(shortcutsVector, EShortcut::MAIN_MENU_LOBBY))
 		CSH->getGlobalLobby().activateInterface();
 
 	if (vstd::contains(shortcutsVector, EShortcut::SPECTATE_TRACK_HERO))

+ 2 - 1
client/globalLobby/GlobalLobbyInviteWindow.cpp

@@ -15,6 +15,7 @@
 
 #include "../CServerHandler.h"
 #include "../gui/CGuiHandler.h"
+#include "../gui/Shortcut.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/Images.h"
@@ -95,7 +96,7 @@ GlobalLobbyInviteWindow::GlobalLobbyInviteWindow()
 	listBackground = std::make_shared<TransparentFilledRectangle>(Rect(8, 48, 220, 324), ColorRGBA(0, 0, 0, 64), ColorRGBA(64, 80, 128, 255), 1);
 	accountList = std::make_shared<CListBox>(createAccountCardCallback, Point(10, 50), Point(0, 40), 8, 0, 0, 1 | 4, Rect(200, 0, 320, 320));
 
-	buttonClose = std::make_shared<CButton>(Point(86, 384), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this]() { close(); } );
+	buttonClose = std::make_shared<CButton>(Point(86, 384), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this]() { close(); }, EShortcut::GLOBAL_RETURN );
 
 	center();
 }

+ 3 - 4
client/globalLobby/GlobalLobbyLoginWindow.cpp

@@ -12,12 +12,11 @@
 #include "GlobalLobbyLoginWindow.h"
 
 #include "GlobalLobbyClient.h"
-#include "GlobalLobbyWindow.h"
 
 #include "../CGameInfo.h"
 #include "../CServerHandler.h"
 #include "../gui/CGuiHandler.h"
-#include "../gui/WindowHandler.h"
+#include "../gui/Shortcut.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/CTextInput.h"
 #include "../widgets/Images.h"
@@ -47,8 +46,8 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
 	labelUsername = std::make_shared<CLabel>( 10, 65, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, loginAs.toString());
 	backgroundUsername = std::make_shared<TransparentFilledRectangle>(Rect(10, 90, 264, 20), ColorRGBA(0,0,0,128), ColorRGBA(64,64,64,64));
 	inputUsername = std::make_shared<CTextInput>(Rect(15, 93, 260, 16), FONT_SMALL, ETextAlignment::CENTERLEFT, true);
-	buttonLogin = std::make_shared<CButton>(Point(10, 180), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onLogin(); });
-	buttonClose = std::make_shared<CButton>(Point(210, 180), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); });
+	buttonLogin = std::make_shared<CButton>(Point(10, 180), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onLogin(); }, EShortcut::GLOBAL_ACCEPT);
+	buttonClose = std::make_shared<CButton>(Point(210, 180), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); }, EShortcut::GLOBAL_CANCEL);
 	labelStatus = std::make_shared<CTextBox>( "", Rect(15, 115, 255, 60), 1, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
 
 	auto buttonRegister = std::make_shared<CToggleButton>(Point(10, 40),  AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);

+ 3 - 5
client/globalLobby/GlobalLobbyRoomWindow.cpp

@@ -18,6 +18,7 @@
 #include "../CGameInfo.h"
 #include "../CServerHandler.h"
 #include "../gui/CGuiHandler.h"
+#include "../gui/Shortcut.h"
 #include "../mainmenu/CMainMenu.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/Images.h"
@@ -25,10 +26,7 @@
 #include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/ObjectLists.h"
 
-#include "../../lib/CConfigHandler.h"
-#include "../../lib/CGeneralTextHandler.h"
 #include "../../lib/MetaString.h"
-#include "../../lib/VCMI_Lib.h"
 #include "../../lib/modding/CModHandler.h"
 #include "../../lib/modding/CModInfo.h"
 
@@ -148,8 +146,8 @@ GlobalLobbyRoomWindow::GlobalLobbyRoomWindow(GlobalLobbyWindow * window, const s
 	labelVersionTitle = std::make_shared<CLabel>( 10, 60, FONT_MEDIUM, ETextAlignment::CENTERLEFT, Colors::YELLOW, MetaString::createFromTextID("vcmi.lobby.preview.version").toString());
 	labelVersionValue = std::make_shared<CLabel>( 10, 80, FONT_MEDIUM, ETextAlignment::CENTERLEFT, Colors::WHITE, roomDescription.gameVersion);
 
-	buttonJoin = std::make_shared<CButton>(Point(10, 360), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onJoin(); });
-	buttonClose = std::make_shared<CButton>(Point(100, 360), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); });
+	buttonJoin = std::make_shared<CButton>(Point(10, 360), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onJoin(); }, EShortcut::GLOBAL_ACCEPT);
+	buttonClose = std::make_shared<CButton>(Point(100, 360), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); }, EShortcut::GLOBAL_CANCEL);
 
 	MetaString joinStatusText;
 	std::string errorMessage = getJoinRoomErrorMessage(roomDescription, modVerificationList);

+ 3 - 2
client/globalLobby/GlobalLobbyServerSetup.cpp

@@ -16,6 +16,7 @@
 #include "../CGameInfo.h"
 #include "../CServerHandler.h"
 #include "../gui/CGuiHandler.h"
+#include "../gui/Shortcut.h"
 #include "../mainmenu/CMainMenu.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/Images.h"
@@ -74,8 +75,8 @@ GlobalLobbyServerSetup::GlobalLobbyServerSetup()
 
 	labelDescription = std::make_shared<CTextBox>("", Rect(10, 195, pos.w - 20, 80), 1, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
 
-	buttonCreate = std::make_shared<CButton>(Point(10, 300), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onCreate(); });
-	buttonClose = std::make_shared<CButton>(Point(210, 300), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); });
+	buttonCreate = std::make_shared<CButton>(Point(10, 300), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onCreate(); }, EShortcut::GLOBAL_ACCEPT);
+	buttonClose = std::make_shared<CButton>(Point(210, 300), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); }, EShortcut::GLOBAL_CANCEL);
 
 	filledBackground->playerColored(PlayerColor(1));
 

+ 57 - 1
client/gui/Shortcut.h

@@ -66,6 +66,15 @@ enum class EShortcut
 	MAIN_MENU_CAMPAIGN_AB,
 	MAIN_MENU_CAMPAIGN_CUSTOM,
 
+	MAIN_MENU_HOTSEAT,
+	MAIN_MENU_LOBBY,
+	MAIN_MENU_HOST_GAME,
+	MAIN_MENU_JOIN_GAME,
+
+	HIGH_SCORES_CAMPAIGNS,
+	HIGH_SCORES_SCENARIOS,
+	HIGH_SCORES_RESET,
+
 	// Game lobby / scenario selection
 	LOBBY_BEGIN_STANDARD_GAME, // b
 	LOBBY_BEGIN_CAMPAIGN, // Return
@@ -75,6 +84,28 @@ enum class EShortcut
 	LOBBY_HIDE_CHAT,
 	LOBBY_ADDITIONAL_OPTIONS, // Open additional options tab
 	LOBBY_SELECT_SCENARIO,    // Open map list tab
+	LOBBY_REPLAY_VIDEO,
+	LOBBY_EXTRA_OPTIONS,
+	LOBBY_TURN_OPTIONS,
+	LOBBY_INVITE_PLAYERS,
+	LOBBY_FLIP_COIN,
+	LOBBY_RANDOM_TOWN,
+	LOBBY_RANDOM_TOWN_VS,
+
+	MAPS_SIZE_S,
+	MAPS_SIZE_M,
+	MAPS_SIZE_L,
+	MAPS_SIZE_XL,
+	MAPS_SIZE_ALL,
+
+	MAPS_SORT_PLAYERS,
+	MAPS_SORT_SIZE,
+	MAPS_SORT_FORMAT,
+	MAPS_SORT_NAME,
+	MAPS_SORT_VICTORY,
+	MAPS_SORT_DEFEAT,
+	MAPS_SORT_MAPS,
+	MAPS_SORT_CHANGEDATE,
 
 	// In-game hotkeys, require game state but may be available in windows other than adventure map
 	GAME_END_TURN,
@@ -102,6 +133,7 @@ enum class EShortcut
 	ADVENTURE_FIRST_TOWN,   // TODO: select first available town in the list
 	ADVENTURE_FIRST_HERO,   // TODO: select first available hero in the list
 	ADVENTURE_VIEW_SCENARIO,// View Scenario Information window
+	ADVENTURE_REPLAY_TURN,
 	ADVENTURE_DIG_GRAIL,
 	ADVENTURE_VIEW_PUZZLE,
 	ADVENTURE_VIEW_WORLD,
@@ -146,7 +178,17 @@ enum class EShortcut
 	BATTLE_SELECT_ACTION, // Alternative actions toggle
 	BATTLE_TOGGLE_HEROES_STATS,
 
-	LOBBY_ACTIVATE_INTERFACE,
+	MARKET_DEAL,
+	MARKET_MAX_AMOUNT,
+	MARKET_SACRIFICE_ALL,
+	MARKET_SACRIFICE_BACKPACK,
+	MARKET_MODE_RESOURCE_PLAYER,
+	MARKET_MODE_ARTIFACT_RESOURCE,
+	MARKET_MODE_RESOURCE_ARTIFACT,
+	MARKET_MODE_CREATURE_RESOURCE,
+	MARKET_MODE_RESOURCE_RESOURCE,
+	MARKET_MODE_CREATURE_EXPERIENCE,
+	MARKET_MODE_ARTIFACT_EXPERIENCE,
 
 	SPECTATE_TRACK_HERO,
 	SPECTATE_SKIP_BATTLE,
@@ -154,11 +196,15 @@ enum class EShortcut
 
 	// Town screen
 	TOWN_OPEN_TAVERN,
+	TOWN_OPEN_HALL,
+	TOWN_OPEN_FORT,
+	TOWN_OPEN_RECRUITMENT,
 	TOWN_SWAP_ARMIES, // Swap garrisoned and visiting armies
 
 	// Creature & creature recruitment screen
 	RECRUITMENT_MAX, // Set number of creatures to recruit to max
 	RECRUITMENT_MIN, // Set number of creatures to recruit to min (1)
+	RECRUITMENT_SWITCH_LEVEL,
 	RECRUITMENT_UPGRADE, // Upgrade current creature
 	RECRUITMENT_UPGRADE_ALL, // Upgrade all creatures (Hill Fort / Skeleton Transformer)
 
@@ -172,6 +218,7 @@ enum class EShortcut
 	HERO_LOOSE_FORMATION,
 	HERO_TIGHT_FORMATION,
 	HERO_TOGGLE_TACTICS, // b
+	HERO_ARMY_SPLIT,
 	HERO_BACKPACK,
 	HERO_COSTUME_SAVE_0,
 	HERO_COSTUME_SAVE_1,
@@ -195,6 +242,15 @@ enum class EShortcut
 	HERO_COSTUME_LOAD_8,
 	HERO_COSTUME_LOAD_9,
 
+	EXCHANGE_ARMY_TO_LEFT,
+	EXCHANGE_ARMY_TO_RIGHT,
+	EXCHANGE_ARMY_SWAP,
+	EXCHANGE_ARTIFACTS_TO_LEFT,
+	EXCHANGE_ARTIFACTS_TO_RIGHT,
+	EXCHANGE_ARTIFACTS_SWAP,
+	EXCHANGE_BACKPACK_LEFT,
+	EXCHANGE_BACKPACK_RIGHT,
+
 	// Spellbook screen
 	SPELLBOOK_TAB_ADVENTURE,
 	SPELLBOOK_TAB_COMBAT,

+ 1 - 1
client/gui/ShortcutHandler.cpp

@@ -131,6 +131,7 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const
 		{"mainMenuCampaignRoe",      EShortcut::MAIN_MENU_CAMPAIGN_ROE    },
 		{"mainMenuCampaignAb",       EShortcut::MAIN_MENU_CAMPAIGN_AB     },
 		{"mainMenuCampaignCustom",   EShortcut::MAIN_MENU_CAMPAIGN_CUSTOM },
+		{"mainMenuLobby",            EShortcut::MAIN_MENU_LOBBY           },
 		{"lobbyBeginStandardGame",   EShortcut::LOBBY_BEGIN_STANDARD_GAME },
 		{"lobbyBeginCampaign",       EShortcut::LOBBY_BEGIN_CAMPAIGN      },
 		{"lobbyLoadGame",            EShortcut::LOBBY_LOAD_GAME           },
@@ -201,7 +202,6 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const
 		{"battleTacticsNext",        EShortcut::BATTLE_TACTICS_NEXT       },
 		{"battleTacticsEnd",         EShortcut::BATTLE_TACTICS_END        },
 		{"battleSelectAction",       EShortcut::BATTLE_SELECT_ACTION      },
-		{"lobbyActivateInterface",   EShortcut::LOBBY_ACTIVATE_INTERFACE  },
 		{"spectateTrackHero",        EShortcut::SPECTATE_TRACK_HERO       },
 		{"spectateSkipBattle",       EShortcut::SPECTATE_SKIP_BATTLE      },
 		{"spectateSkipBattleResult", EShortcut::SPECTATE_SKIP_BATTLE_RESULT },

+ 17 - 5
client/lobby/CBonusSelection.cpp

@@ -71,9 +71,18 @@ CBonusSelection::CBonusSelection()
 
 	panelBackground = std::make_shared<CPicture>(ImagePath::builtin("CAMPBRF.BMP"), 456, 6);
 
-	buttonStart = std::make_shared<CButton>(Point(475, 536), AnimationPath::builtin("CBBEGIB.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::startMap, this), EShortcut::GLOBAL_ACCEPT);
+	const auto & playVideo = [this]()
+	{
+		GH.windows().createAndPushWindow<CPrologEpilogVideo>(
+			getCampaign()->scenario(CSH->campaignMap).prolog,
+			[this]() { redraw(); } );
+	};
+
+	buttonStart = std::make_shared<CButton>(
+		Point(475, 536), AnimationPath::builtin("CBBEGIB.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::startMap, this), EShortcut::GLOBAL_ACCEPT
+		);
 	buttonRestart = std::make_shared<CButton>(Point(475, 536), AnimationPath::builtin("CBRESTB.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::restartMap, this), EShortcut::GLOBAL_ACCEPT);
-	buttonVideo = std::make_shared<CButton>(Point(705, 214), AnimationPath::builtin("CBVIDEB.DEF"), CButton::tooltip(), [this](){ GH.windows().createAndPushWindow<CPrologEpilogVideo>(getCampaign()->scenario(CSH->campaignMap).prolog, [this](){ redraw(); }); });
+	buttonVideo = std::make_shared<CButton>(Point(705, 214), AnimationPath::builtin("CBVIDEB.DEF"), CButton::tooltip(), playVideo, EShortcut::LOBBY_REPLAY_VIDEO);
 	buttonBack = std::make_shared<CButton>(Point(624, 536), AnimationPath::builtin("CBCANCB.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::goBack, this), EShortcut::GLOBAL_CANCEL);
 
 	campaignName = std::make_shared<CLabel>(481, 28, FONT_BIG, ETextAlignment::TOPLEFT, Colors::YELLOW, CSH->si->getCampaignName());
@@ -104,8 +113,11 @@ CBonusSelection::CBonusSelection()
 
 	if(getCampaign()->playerSelectedDifficulty())
 	{
-		buttonDifficultyLeft = std::make_shared<CButton>(settings["general"]["enableUiEnhancements"].Bool() ? Point(693, 495) : Point(694, 508), AnimationPath::builtin("SCNRBLF.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::decreaseDifficulty, this));
-		buttonDifficultyRight = std::make_shared<CButton>(settings["general"]["enableUiEnhancements"].Bool() ? Point(739, 495) : Point(738, 508), AnimationPath::builtin("SCNRBRT.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::increaseDifficulty, this));
+		Point posLeft = settings["general"]["enableUiEnhancements"].Bool() ? Point(693, 495) : Point(694, 508);
+		Point posRight = settings["general"]["enableUiEnhancements"].Bool() ? Point(739, 495) : Point(738, 508);
+
+		buttonDifficultyLeft = std::make_shared<CButton>(posLeft, AnimationPath::builtin("SCNRBLF.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::decreaseDifficulty, this), EShortcut::MOVE_LEFT);
+		buttonDifficultyRight = std::make_shared<CButton>(posRight, AnimationPath::builtin("SCNRBRT.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::increaseDifficulty, this), EShortcut::MOVE_RIGHT);
 	}
 
 	for(auto scenarioID : getCampaign()->allScenarios())
@@ -125,7 +137,7 @@ CBonusSelection::CBonusSelection()
 		tabExtraOptions->recActions = UPDATE | SHOWALL | LCLICK | RCLICK_POPUP;
 		tabExtraOptions->recreate(true);
 		tabExtraOptions->setEnabled(false);
-		buttonExtraOptions = std::make_shared<CButton>(Point(643, 431), AnimationPath::builtin("GSPBUT2.DEF"), CGI->generaltexth->zelp[46], [this]{ tabExtraOptions->setEnabled(!tabExtraOptions->isActive()); GH.windows().totalRedraw(); }, EShortcut::NONE);
+		buttonExtraOptions = std::make_shared<CButton>(Point(643, 431), AnimationPath::builtin("GSPBUT2.DEF"), CGI->generaltexth->zelp[46], [this]{ tabExtraOptions->setEnabled(!tabExtraOptions->isActive()); GH.windows().totalRedraw(); }, EShortcut::LOBBY_EXTRA_OPTIONS);
 		buttonExtraOptions->setTextOverlay(CGI->generaltexth->translate("vcmi.optionsTab.extraOptions.hover"), FONT_SMALL, Colors::WHITE);
 	}
 }

+ 2 - 2
client/lobby/CLobbyScreen.cpp

@@ -57,8 +57,8 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
 		buttonOptions = std::make_shared<CButton>(Point(411, 510), AnimationPath::builtin("GSPBUTT.DEF"), CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabOpt), EShortcut::LOBBY_ADDITIONAL_OPTIONS);
 		if(settings["general"]["enableUiEnhancements"].Bool())
 		{
-			buttonTurnOptions = std::make_shared<CButton>(Point(619, 105), AnimationPath::builtin("GSPBUT2.DEF"), CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabTurnOptions), EShortcut::NONE);
-			buttonExtraOptions = std::make_shared<CButton>(Point(619, 510), AnimationPath::builtin("GSPBUT2.DEF"), CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabExtraOptions), EShortcut::NONE);
+			buttonTurnOptions = std::make_shared<CButton>(Point(619, 105), AnimationPath::builtin("GSPBUT2.DEF"), CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabTurnOptions), EShortcut::LOBBY_TURN_OPTIONS);
+			buttonExtraOptions = std::make_shared<CButton>(Point(619, 510), AnimationPath::builtin("GSPBUT2.DEF"), CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabExtraOptions), EShortcut::LOBBY_EXTRA_OPTIONS);
 		}
 	};
 

+ 5 - 5
client/lobby/CSelectionBase.cpp

@@ -143,8 +143,8 @@ InfoCard::InfoCard()
 	chat = std::make_shared<CChatBox>(Rect(18, 126, 335, 143));
 	pvpBox = std::make_shared<PvPBox>(Rect(17, 396, 338, 105));
 
-	buttonInvitePlayers = std::make_shared<CButton>(Point(20, 365), AnimationPath::builtin("pregameInvitePlayers"), CGI->generaltexth->zelp[105], [](){ CSH->getGlobalLobby().activateRoomInviteInterface(); } );
-	buttonOpenGlobalLobby = std::make_shared<CButton>(Point(188, 365), AnimationPath::builtin("pregameReturnToLobby"), CGI->generaltexth->zelp[105], [](){ CSH->getGlobalLobby().activateInterface(); });
+	buttonInvitePlayers = std::make_shared<CButton>(Point(20, 365), AnimationPath::builtin("pregameInvitePlayers"), CGI->generaltexth->zelp[105], [](){ CSH->getGlobalLobby().activateRoomInviteInterface(); }, EShortcut::LOBBY_INVITE_PLAYERS );
+	buttonOpenGlobalLobby = std::make_shared<CButton>(Point(188, 365), AnimationPath::builtin("pregameReturnToLobby"), CGI->generaltexth->zelp[105], [](){ CSH->getGlobalLobby().activateInterface(); }, EShortcut::MAIN_MENU_LOBBY );
 
 	buttonInvitePlayers->setTextOverlay  (MetaString::createFromTextID("vcmi.lobby.invite.header").toString(), EFonts::FONT_SMALL, Colors::WHITE);
 	buttonOpenGlobalLobby->setTextOverlay(MetaString::createFromTextID("vcmi.lobby.backToLobby").toString(), EFonts::FONT_SMALL, Colors::WHITE);
@@ -418,7 +418,7 @@ PvPBox::PvPBox(const Rect & rect)
 		LobbyPvPAction lpa;
 		lpa.action = LobbyPvPAction::COIN;
 		CSH->sendLobbyPack(lpa);
-	}, EShortcut::NONE);
+	}, EShortcut::LOBBY_FLIP_COIN);
 	buttonFlipCoin->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.pvp.coin.hover"), EFonts::FONT_SMALL, Colors::WHITE);
 
 	buttonRandomTown = std::make_shared<CButton>(Point(190, 31), AnimationPath::builtin("GSPBUT2.DEF"), CButton::tooltip("", CGI->generaltexth->translate("vcmi.lobby.pvp.randomTown.help")), [getBannedTowns](){
@@ -426,7 +426,7 @@ PvPBox::PvPBox(const Rect & rect)
 		lpa.action = LobbyPvPAction::RANDOM_TOWN;
 		lpa.bannedTowns = getBannedTowns();
 		CSH->sendLobbyPack(lpa);
-	}, EShortcut::NONE);
+	}, EShortcut::LOBBY_RANDOM_TOWN);
 	buttonRandomTown->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.pvp.randomTown.hover"), EFonts::FONT_SMALL, Colors::WHITE);
 
 	buttonRandomTownVs = std::make_shared<CButton>(Point(190, 56), AnimationPath::builtin("GSPBUT2.DEF"), CButton::tooltip("", CGI->generaltexth->translate("vcmi.lobby.pvp.randomTownVs.help")), [getBannedTowns](){
@@ -434,7 +434,7 @@ PvPBox::PvPBox(const Rect & rect)
 		lpa.action = LobbyPvPAction::RANDOM_TOWN_VS;
 		lpa.bannedTowns = getBannedTowns();
 		CSH->sendLobbyPack(lpa);
-	}, EShortcut::NONE);
+	}, EShortcut::LOBBY_RANDOM_TOWN_VS);
 	buttonRandomTownVs->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.pvp.randomTownVs.hover"), EFonts::FONT_SMALL, Colors::WHITE);
 }
 

+ 12 - 13
client/lobby/SelectionTab.cpp

@@ -169,24 +169,23 @@ SelectionTab::SelectionTab(ESelectionScreen Type)
 		labelMapSizes = std::make_shared<CLabel>(87, 62, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[510]);
 
 		// TODO: Global constants?
-		int sizes[] = {CMapHeader::MAP_SIZE_SMALL,
-						CMapHeader::MAP_SIZE_MIDDLE,
-						CMapHeader::MAP_SIZE_LARGE,
-						CMapHeader::MAP_SIZE_XLARGE,
-						0};
-		const char * filterIconNmes[] = {"SCSMBUT.DEF", "SCMDBUT.DEF", "SCLGBUT.DEF", "SCXLBUT.DEF", "SCALBUT.DEF"};
+		constexpr std::array sizes = {CMapHeader::MAP_SIZE_SMALL, CMapHeader::MAP_SIZE_MIDDLE, CMapHeader::MAP_SIZE_LARGE, CMapHeader::MAP_SIZE_XLARGE, 0};
+		constexpr std::array filterIconNmes = {"SCSMBUT.DEF", "SCMDBUT.DEF", "SCLGBUT.DEF", "SCXLBUT.DEF", "SCALBUT.DEF"};
+		constexpr std::array filterShortcuts = { EShortcut::MAPS_SIZE_S, EShortcut::MAPS_SIZE_M, EShortcut::MAPS_SIZE_L, EShortcut::MAPS_SIZE_XL, EShortcut::MAPS_SIZE_ALL };
+
 		for(int i = 0; i < 5; i++)
-			buttonsSortBy.push_back(std::make_shared<CButton>(Point(158 + 47 * i, 46), AnimationPath::builtin(filterIconNmes[i]), CGI->generaltexth->zelp[54 + i], std::bind(&SelectionTab::filter, this, sizes[i], true)));
+			buttonsSortBy.push_back(std::make_shared<CButton>(Point(158 + 47 * i, 46), AnimationPath::builtin(filterIconNmes[i]), CGI->generaltexth->zelp[54 + i], std::bind(&SelectionTab::filter, this, sizes[i], true), filterShortcuts[i]));
 
-		int xpos[] = {23, 55, 88, 121, 306, 339};
-		const char * sortIconNames[] = {"SCBUTT1.DEF", "SCBUTT2.DEF", "SCBUTCP.DEF", "SCBUTT3.DEF", "SCBUTT4.DEF", "SCBUTT5.DEF"};
+		constexpr std::array xpos = {23, 55, 88, 121, 306, 339};
+		constexpr std::array sortIconNames = {"SCBUTT1.DEF", "SCBUTT2.DEF", "SCBUTCP.DEF", "SCBUTT3.DEF", "SCBUTT4.DEF", "SCBUTT5.DEF"};
+		constexpr std::array sortShortcuts = { EShortcut::MAPS_SORT_PLAYERS, EShortcut::MAPS_SORT_SIZE, EShortcut::MAPS_SORT_FORMAT, EShortcut::MAPS_SORT_NAME, EShortcut::MAPS_SORT_VICTORY, EShortcut::MAPS_SORT_DEFEAT };
 		for(int i = 0; i < 6; i++)
 		{
 			ESortBy criteria = (ESortBy)i;
 			if(criteria == _name)
 				criteria = generalSortingBy;
 
-			buttonsSortBy.push_back(std::make_shared<CButton>(Point(xpos[i], 86), AnimationPath::builtin(sortIconNames[i]), CGI->generaltexth->zelp[107 + i], std::bind(&SelectionTab::sortBy, this, criteria)));
+			buttonsSortBy.push_back(std::make_shared<CButton>(Point(xpos[i], 86), AnimationPath::builtin(sortIconNames[i]), CGI->generaltexth->zelp[107 + i], std::bind(&SelectionTab::sortBy, this, criteria), sortShortcuts[i]));
 		}
 	}
 
@@ -212,8 +211,8 @@ SelectionTab::SelectionTab(ESelectionScreen Type)
 		pos.x += 3;
 		pos.y += 6;
 
-		buttonsSortBy.push_back(std::make_shared<CButton>(Point(23, 86), AnimationPath::builtin("CamCusM.DEF"), CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _numOfMaps)));
-		buttonsSortBy.push_back(std::make_shared<CButton>(Point(55, 86), AnimationPath::builtin("CamCusL.DEF"), CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _name)));
+		buttonsSortBy.push_back(std::make_shared<CButton>(Point(23, 86), AnimationPath::builtin("CamCusM.DEF"), CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _numOfMaps), EShortcut::MAPS_SORT_MAPS));
+		buttonsSortBy.push_back(std::make_shared<CButton>(Point(55, 86), AnimationPath::builtin("CamCusL.DEF"), CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _name), EShortcut::MAPS_SORT_NAME));
 		break;
 	default:
 		assert(0);
@@ -222,7 +221,7 @@ SelectionTab::SelectionTab(ESelectionScreen Type)
 
 	if(enableUiEnhancements)
 	{
-		auto sortByDate = std::make_shared<CButton>(Point(371, 85), AnimationPath::builtin("selectionTabSortDate"), CButton::tooltip("", CGI->generaltexth->translate("vcmi.lobby.sortDate")), std::bind(&SelectionTab::sortBy, this, ESortBy::_changeDate));
+		auto sortByDate = std::make_shared<CButton>(Point(371, 85), AnimationPath::builtin("selectionTabSortDate"), CButton::tooltip("", CGI->generaltexth->translate("vcmi.lobby.sortDate")), std::bind(&SelectionTab::sortBy, this, ESortBy::_changeDate), EShortcut::MAPS_SORT_CHANGEDATE);
 		sortByDate->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/selectionTabSortDate")));
 		buttonsSortBy.push_back(sortByDate);
 	}

+ 4 - 4
client/mainmenu/CHighScoreScreen.cpp

@@ -109,10 +109,10 @@ void CHighScoreScreen::addButtons()
 	
 	buttons.clear();
 
-	buttons.push_back(std::make_shared<CButton>(Point(31, 113), AnimationPath::builtin("HISCCAM.DEF"), CButton::tooltip(), [&](){ buttonCampaignClick(); }));
-	buttons.push_back(std::make_shared<CButton>(Point(31, 345), AnimationPath::builtin("HISCSTA.DEF"), CButton::tooltip(), [&](){ buttonScenarioClick(); }));
-	buttons.push_back(std::make_shared<CButton>(Point(726, 113), AnimationPath::builtin("HISCRES.DEF"), CButton::tooltip(), [&](){ buttonResetClick(); }));
-	buttons.push_back(std::make_shared<CButton>(Point(726, 345), AnimationPath::builtin("HISCEXT.DEF"), CButton::tooltip(), [&](){ buttonExitClick(); }));
+	buttons.push_back(std::make_shared<CButton>(Point(31, 113), AnimationPath::builtin("HISCCAM.DEF"), CButton::tooltip(), [&](){ buttonCampaignClick(); }, EShortcut::HIGH_SCORES_CAMPAIGNS));
+	buttons.push_back(std::make_shared<CButton>(Point(31, 345), AnimationPath::builtin("HISCSTA.DEF"), CButton::tooltip(), [&](){ buttonScenarioClick(); }, EShortcut::HIGH_SCORES_SCENARIOS));
+	buttons.push_back(std::make_shared<CButton>(Point(726, 113), AnimationPath::builtin("HISCRES.DEF"), CButton::tooltip(), [&](){ buttonResetClick(); }, EShortcut::HIGH_SCORES_RESET));
+	buttons.push_back(std::make_shared<CButton>(Point(726, 345), AnimationPath::builtin("HISCEXT.DEF"), CButton::tooltip(), [&](){ buttonExitClick(); }, EShortcut::GLOBAL_RETURN));
 }
 
 void CHighScoreScreen::addHighScores()

+ 4 - 4
client/mainmenu/CMainMenu.cpp

@@ -457,11 +457,11 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
 	playerName->setText(getPlayerName());
 	playerName->setCallback(std::bind(&CMultiMode::onNameChange, this, _1));
 
-	buttonHotseat = std::make_shared<CButton>(Point(373, 78 + 57 * 0), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this));
-	buttonLobby = std::make_shared<CButton>(Point(373, 78 + 57 * 1), AnimationPath::builtin("MUBONL.DEF"), CGI->generaltexth->zelp[265], std::bind(&CMultiMode::openLobby, this));
+	buttonHotseat = std::make_shared<CButton>(Point(373, 78 + 57 * 0), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this), EShortcut::MAIN_MENU_HOTSEAT);
+	buttonLobby = std::make_shared<CButton>(Point(373, 78 + 57 * 1), AnimationPath::builtin("MUBONL.DEF"), CGI->generaltexth->zelp[265], std::bind(&CMultiMode::openLobby, this), EShortcut::MAIN_MENU_LOBBY);
 
-	buttonHost = std::make_shared<CButton>(Point(373, 78 + 57 * 3), AnimationPath::builtin("MUBHOST.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this));
-	buttonJoin = std::make_shared<CButton>(Point(373, 78 + 57 * 4), AnimationPath::builtin("MUBJOIN.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.joinTCP"), ""), std::bind(&CMultiMode::joinTCP, this));
+	buttonHost = std::make_shared<CButton>(Point(373, 78 + 57 * 3), AnimationPath::builtin("MUBHOST.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this), EShortcut::MAIN_MENU_HOST_GAME);
+	buttonJoin = std::make_shared<CButton>(Point(373, 78 + 57 * 4), AnimationPath::builtin("MUBJOIN.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.joinTCP"), ""), std::bind(&CMultiMode::joinTCP, this), EShortcut::MAIN_MENU_JOIN_GAME);
 
 	buttonCancel = std::make_shared<CButton>(Point(373, 424), AnimationPath::builtin("MUBCANC.DEF"), CGI->generaltexth->zelp[288], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
 }

+ 4 - 3
client/widgets/markets/CAltarArtifacts.cpp

@@ -12,6 +12,7 @@
 #include "CAltarArtifacts.h"
 
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -36,16 +37,16 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance *
 	altarArtifacts = altarObj;
 
 	deal = std::make_shared<CButton>(Point(269, 520), AnimationPath::builtin("ALTSACR.DEF"),
-		CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); });
+		CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); }, EShortcut::MARKET_DEAL);
 	labels.emplace_back(std::make_shared<CLabel>(450, 32, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]));
 	labels.emplace_back(std::make_shared<CLabel>(302, 424, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478]));
 
 	sacrificeAllButton = std::make_shared<CButton>(Point(393, 520), AnimationPath::builtin("ALTFILL.DEF"),
-		CGI->generaltexth->zelp[571], std::bind(&CExperienceAltar::sacrificeAll, this));
+		CGI->generaltexth->zelp[571], std::bind(&CExperienceAltar::sacrificeAll, this), EShortcut::MARKET_SACRIFICE_ALL);
 	sacrificeAllButton->block(hero->artifactsInBackpack.empty() && hero->artifactsWorn.empty());
 
 	sacrificeBackpackButton = std::make_shared<CButton>(Point(147, 520), AnimationPath::builtin("ALTEMBK.DEF"),
-		CGI->generaltexth->zelp[570], std::bind(&CAltarArtifacts::sacrificeBackpack, this));
+		CGI->generaltexth->zelp[570], std::bind(&CAltarArtifacts::sacrificeBackpack, this), EShortcut::MARKET_SACRIFICE_BACKPACK);
 	sacrificeBackpackButton->block(hero->artifactsInBackpack.empty());
 
 	// Hero's artifacts

+ 3 - 2
client/widgets/markets/CAltarCreatures.cpp

@@ -12,6 +12,7 @@
 #include "CAltarCreatures.h"
 
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -33,7 +34,7 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
 
 	deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("ALTSACR.DEF"),
-		CGI->generaltexth->zelp[584], [this]() {CAltarCreatures::makeDeal();});
+		CGI->generaltexth->zelp[584], [this]() {CAltarCreatures::makeDeal();}, EShortcut::MARKET_DEAL);
 	labels.emplace_back(std::make_shared<CLabel>(155, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW,
 		boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
 	labels.emplace_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]));
@@ -44,7 +45,7 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
 	unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0);
 	expPerUnit.resize(GameConstants::ARMY_SIZE, 0);
 	sacrificeAllButton = std::make_shared<CButton>(
-		Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CExperienceAltar::sacrificeAll, this));
+		Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CExperienceAltar::sacrificeAll, this), EShortcut::MARKET_SACRIFICE_ALL);
 
 	// Hero creatures panel
 	assert(bidTradePanel);

+ 2 - 1
client/widgets/markets/CArtifactsBuying.cpp

@@ -12,6 +12,7 @@
 #include "CArtifactsBuying.h"
 
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -38,7 +39,7 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
 		title = CGI->generaltexth->allTexts[349];
 	labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title));
 	deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"),
-		CGI->generaltexth->zelp[595], [this](){CArtifactsBuying::makeDeal();});
+		CGI->generaltexth->zelp[595], [this](){CArtifactsBuying::makeDeal();}, EShortcut::MARKET_DEAL);
 	labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
 
 	// Player's resources

+ 2 - 1
client/widgets/markets/CArtifactsSelling.cpp

@@ -12,6 +12,7 @@
 #include "CArtifactsSelling.h"
 
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -43,7 +44,7 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc
 	labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title));
 	labels.push_back(std::make_shared<CLabel>(155, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated())));
 	deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"),
-		CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();});
+		CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();}, EShortcut::MARKET_DEAL);
 	bidSelectedSlot = std::make_shared<CTradeableItem>(Rect(Point(123, 470), Point(69, 66)), EType::ARTIFACT_TYPE, 0, 0);
 
 	// Market resources panel

+ 2 - 1
client/widgets/markets/CFreelancerGuild.cpp

@@ -12,6 +12,7 @@
 #include "CFreelancerGuild.h"
 
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -39,7 +40,7 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance
 	labels.emplace_back(std::make_shared<CLabel>(155, 103, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE,
 		boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
 	deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
-		CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();});
+		CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();}, EShortcut::MARKET_DEAL);
 	offerSlider->moveTo(pos.topLeft() + Point(232, 489));
 
 	// Hero creatures panel

+ 2 - 1
client/widgets/markets/CMarketBase.cpp

@@ -14,6 +14,7 @@
 
 #include "../Images.h"
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -200,7 +201,7 @@ CMarketSlider::CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback
 		[this]()
 		{
 			offerSlider->scrollToMax();
-		});
+		}, EShortcut::MARKET_MAX_AMOUNT);
 }
 
 void CMarketSlider::deselect()

+ 2 - 1
client/widgets/markets/CMarketResources.cpp

@@ -12,6 +12,7 @@
 #include "CMarketResources.h"
 
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -36,7 +37,7 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance
 
 	labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158]));
 	deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
-		CGI->generaltexth->zelp[595], [this]() {CMarketResources::makeDeal(); });
+		CGI->generaltexth->zelp[595], [this]() {CMarketResources::makeDeal(); }, EShortcut::MARKET_DEAL);
 
 	// Player's resources
 	assert(bidTradePanel);

+ 2 - 1
client/widgets/markets/CTransferResources.cpp

@@ -12,6 +12,7 @@
 #include "CTransferResources.h"
 
 #include "../../gui/CGuiHandler.h"
+#include "../../gui/Shortcut.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/TextControls.h"
 
@@ -34,7 +35,7 @@ CTransferResources::CTransferResources(const IMarket * market, const CGHeroInsta
 	labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158]));
 	labels.emplace_back(std::make_shared<CLabel>(445, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169]));
 	deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
-		CGI->generaltexth->zelp[595], [this](){CTransferResources::makeDeal();});
+		CGI->generaltexth->zelp[595], [this](){CTransferResources::makeDeal();}, EShortcut::MARKET_DEAL);
 
 	// Player's resources
 	assert(bidTradePanel);

+ 5 - 11
client/windows/CCastleInterface.cpp

@@ -1215,7 +1215,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
 	exit = std::make_shared<CButton>(Point(744, 544), AnimationPath::builtin("TSBTNS"), CButton::tooltip(CGI->generaltexth->tcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN);
 	exit->setImageOrder(4, 5, 6, 7);
 
-	auto split = std::make_shared<CButton>(Point(744, 382), AnimationPath::builtin("TSBTNS"), CButton::tooltip(CGI->generaltexth->tcommands[3]), [this]() { garr->splitClick(); });
+	auto split = std::make_shared<CButton>(Point(744, 382), AnimationPath::builtin("TSBTNS"), CButton::tooltip(CGI->generaltexth->tcommands[3]), [this]() { garr->splitClick(); }, EShortcut::HERO_ARMY_SPLIT);
 	garr->addSplitBtn(split);
 
 	Rect barRect(9, 182, 732, 18);
@@ -1224,8 +1224,8 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
 	resdatabar = std::make_shared<CResDataBar>(ImagePath::builtin("ARESBAR"), 3, 575, 37, 3, 84, 78);
 
 	townlist = std::make_shared<CTownList>(3, Rect(Point(743, 414), Point(48, 128)), Point(1,16), Point(0, 32), LOCPLINT->localState->getOwnedTowns().size() );
-	townlist->setScrollUpButton( std::make_shared<CButton>( Point(744, 414), AnimationPath::builtin("IAM014"), CButton::tooltipLocalized("core.help.306")));
-	townlist->setScrollDownButton( std::make_shared<CButton>( Point(744, 526), AnimationPath::builtin("IAM015"), CButton::tooltipLocalized("core.help.307")));
+	townlist->setScrollUpButton( std::make_shared<CButton>( Point(744, 414), AnimationPath::builtin("IAM014"), CButton::tooltipLocalized("core.help.306"), 0, EShortcut::MOVE_UP));
+	townlist->setScrollDownButton( std::make_shared<CButton>( Point(744, 526), AnimationPath::builtin("IAM015"), CButton::tooltipLocalized("core.help.307"), 0, EShortcut::MOVE_DOWN));
 
 	if(from)
 		townlist->select(from);
@@ -1326,11 +1326,11 @@ void CCastleInterface::recreateIcons()
 	hall = std::make_shared<CTownInfo>(80, 413, town, true);
 	fort = std::make_shared<CTownInfo>(122, 413, town, false);
 
-	fastTownHall = std::make_shared<CButton>(Point(80, 413), AnimationPath::builtin("castleInterfaceQuickAccess"), CButton::tooltip(), [this](){ builds->enterTownHall(); });
+	fastTownHall = std::make_shared<CButton>(Point(80, 413), AnimationPath::builtin("castleInterfaceQuickAccess"), CButton::tooltip(), [this](){ builds->enterTownHall(); }, EShortcut::TOWN_OPEN_HALL);
 	fastTownHall->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("ITMTL"), town->hallLevel()));
 
 	int imageIndex = town->fortLevel() == CGTownInstance::EFortLevel::NONE ? 3 : town->fortLevel() - 1;
-	fastArmyPurchase = std::make_shared<CButton>(Point(122, 413), AnimationPath::builtin("castleInterfaceQuickAccess"), CButton::tooltip(), [this](){ builds->enterToTheQuickRecruitmentWindow(); });
+	fastArmyPurchase = std::make_shared<CButton>(Point(122, 413), AnimationPath::builtin("castleInterfaceQuickAccess"), CButton::tooltip(), [this](){ builds->enterToTheQuickRecruitmentWindow(); }, EShortcut::TOWN_OPEN_RECRUITMENT);
 	fastArmyPurchase->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("itmcl"), imageIndex));
 
 	fastMarket = std::make_shared<LRClickableArea>(Rect(163, 410, 64, 42), [&]()
@@ -1374,12 +1374,6 @@ void CCastleInterface::keyPressed(EShortcut key)
 {
 	switch(key)
 	{
-	case EShortcut::MOVE_UP:
-		townlist->selectPrev();
-		break;
-	case EShortcut::MOVE_DOWN:
-		townlist->selectNext();
-		break;
 	case EShortcut::TOWN_SWAP_ARMIES:
 		heroes->swapArmies();
 		break;

+ 1 - 1
client/windows/CHeroWindow.cpp

@@ -213,7 +213,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
 			boost::algorithm::replace_first(helpBox, "%s", CGI->generaltexth->allTexts[43]);
 
 			garr = std::make_shared<CGarrisonInt>(Point(15, 485), 8, Point(), curHero);
-			auto split = std::make_shared<CButton>(Point(539, 519), AnimationPath::builtin("hsbtns9.def"), CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); });
+			auto split = std::make_shared<CButton>(Point(539, 519), AnimationPath::builtin("hsbtns9.def"), CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); }, EShortcut::HERO_ARMY_SPLIT);
 			garr->addSplitBtn(split);
 		}
 		if(!arts)

+ 9 - 9
client/windows/CMarketWindow.cpp

@@ -140,35 +140,35 @@ void CMarketWindow::createChangeModeButtons(EMarketMode currentMode, const IMark
 	auto buttonPos = Point(18, 520);
 
 	auto addButton = [this, &buttonPos](const AnimationPath & picPath, const std::pair<std::string, std::string> & buttonHelpContainer,
-		const std::function<void()> & pressButtonFunctor)
+		const std::function<void()> & pressButtonFunctor, EShortcut shortcut)
 	{
-		changeModeButtons.emplace_back(std::make_shared<CButton>(buttonPos, picPath, buttonHelpContainer, pressButtonFunctor));
+		changeModeButtons.emplace_back(std::make_shared<CButton>(buttonPos, picPath, buttonHelpContainer, pressButtonFunctor, shortcut));
 		buttonPos -= Point(0, buttonHeightWithMargin);
 	};
 
 	if(isButtonVisible(EMarketMode::RESOURCE_PLAYER))
-		addButton(AnimationPath::builtin("TPMRKBU1.DEF"), CGI->generaltexth->zelp[612], std::bind(&CMarketWindow::createTransferResources, this, market, hero));
+		addButton(AnimationPath::builtin("TPMRKBU1.DEF"), CGI->generaltexth->zelp[612], std::bind(&CMarketWindow::createTransferResources, this, market, hero), EShortcut::MARKET_MODE_RESOURCE_PLAYER);
 	if(isButtonVisible(EMarketMode::ARTIFACT_RESOURCE))
-		addButton(AnimationPath::builtin("TPMRKBU3.DEF"), CGI->generaltexth->zelp[613], std::bind(&CMarketWindow::createArtifactsSelling, this, market, hero));
+		addButton(AnimationPath::builtin("TPMRKBU3.DEF"), CGI->generaltexth->zelp[613], std::bind(&CMarketWindow::createArtifactsSelling, this, market, hero), EShortcut::MARKET_MODE_ARTIFACT_RESOURCE);
 	if(isButtonVisible(EMarketMode::RESOURCE_ARTIFACT))
-		addButton(AnimationPath::builtin("TPMRKBU2.DEF"), CGI->generaltexth->zelp[598], std::bind(&CMarketWindow::createArtifactsBuying, this, market, hero));
+		addButton(AnimationPath::builtin("TPMRKBU2.DEF"), CGI->generaltexth->zelp[598], std::bind(&CMarketWindow::createArtifactsBuying, this, market, hero), EShortcut::MARKET_MODE_RESOURCE_ARTIFACT);
 
 	buttonPos = Point(516, 520 - buttonHeightWithMargin);
 	if(isButtonVisible(EMarketMode::CREATURE_RESOURCE))
-		addButton(AnimationPath::builtin("TPMRKBU4.DEF"), CGI->generaltexth->zelp[599], std::bind(&CMarketWindow::createFreelancersGuild, this, market, hero));
+		addButton(AnimationPath::builtin("TPMRKBU4.DEF"), CGI->generaltexth->zelp[599], std::bind(&CMarketWindow::createFreelancersGuild, this, market, hero), EShortcut::MARKET_MODE_CREATURE_RESOURCE);
 	if(isButtonVisible(EMarketMode::RESOURCE_RESOURCE))
-		addButton(AnimationPath::builtin("TPMRKBU5.DEF"), CGI->generaltexth->zelp[605], std::bind(&CMarketWindow::createMarketResources, this, market, hero));
+		addButton(AnimationPath::builtin("TPMRKBU5.DEF"), CGI->generaltexth->zelp[605], std::bind(&CMarketWindow::createMarketResources, this, market, hero), EShortcut::MARKET_MODE_RESOURCE_RESOURCE);
 	
 	buttonPos = Point(516, 421);
 	if(isButtonVisible(EMarketMode::CREATURE_EXP))
 	{
-		addButton(AnimationPath::builtin("ALTSACC.DEF"), CGI->generaltexth->zelp[572], std::bind(&CMarketWindow::createAltarCreatures, this, market, hero));
+		addButton(AnimationPath::builtin("ALTSACC.DEF"), CGI->generaltexth->zelp[572], std::bind(&CMarketWindow::createAltarCreatures, this, market, hero), EShortcut::MARKET_MODE_CREATURE_EXPERIENCE);
 		if(marketWidget->hero->getAlignment() == EAlignment::GOOD)
 			changeModeButtons.back()->block(true);
 	}
 	if(isButtonVisible(EMarketMode::ARTIFACT_EXP))
 	{
-		addButton(AnimationPath::builtin("ALTART.DEF"), CGI->generaltexth->zelp[580], std::bind(&CMarketWindow::createAltarArtifacts, this, market, hero));
+		addButton(AnimationPath::builtin("ALTART.DEF"), CGI->generaltexth->zelp[580], std::bind(&CMarketWindow::createAltarArtifacts, this, market, hero), EShortcut::MARKET_MODE_ARTIFACT_EXPERIENCE);
 		if(marketWidget->hero->getAlignment() == EAlignment::EVIL)
 			changeModeButtons.back()->block(true);
 	}

+ 1 - 1
client/windows/CQuestLog.cpp

@@ -128,7 +128,7 @@ CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests)
 	minimap = std::make_shared<CQuestMinimap>(Rect(12, 12, 169, 169));
 	// TextBox have it's own 4 pixel padding from top at least for English. To achieve 10px from both left and top only add 6px margin
 	description = std::make_shared<CTextBox>("", Rect(205, 18, 385, DESCRIPTION_HEIGHT_MAX), CSlider::BROWN, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE);
-	ok = std::make_shared<CButton>(Point(539, 398), AnimationPath::builtin("IOKAY.DEF"), CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close, this), EShortcut::GLOBAL_ACCEPT);
+	ok = std::make_shared<CButton>(Point(539, 398), AnimationPath::builtin("IOKAY.DEF"), CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close, this), EShortcut::GLOBAL_RETURN);
 	// Both button and lable are shifted to -2px by x and y to not make them actually look like they're on same line with quests list and ok button
 	hideCompleteButton = std::make_shared<CToggleButton>(Point(10, 396), AnimationPath::builtin("sysopchk.def"), CButton::tooltipLocalized("vcmi.questLog.hideComplete"), std::bind(&CQuestLog::toggleComplete, this, _1));
 	hideCompleteLabel = std::make_shared<CLabel>(46, 398, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->translate("vcmi.questLog.hideComplete.hover"));

+ 1 - 1
client/windows/CTutorialWindow.cpp

@@ -45,7 +45,7 @@ CTutorialWindow::CTutorialWindow(const TutorialMode & m)
 
 	labelTitle = std::make_shared<CLabel>(190, 15, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.tutorialWindow.title"));
 	labelInformation = std::make_shared<CMultiLineLabel>(Rect(5, 40, 370, 60), EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, "");
-	buttonOk = std::make_shared<CButton>(Point(159, 367), AnimationPath::builtin("IOKAY"), CButton::tooltip(), std::bind(&CTutorialWindow::exit, this), EShortcut::GLOBAL_ACCEPT); //62x28
+	buttonOk = std::make_shared<CButton>(Point(159, 367), AnimationPath::builtin("IOKAY"), CButton::tooltip(), std::bind(&CTutorialWindow::exit, this), EShortcut::GLOBAL_RETURN); //62x28
 	buttonLeft = std::make_shared<CButton>(Point(5, 217), AnimationPath::builtin("HSBTNS3"), CButton::tooltip(), std::bind(&CTutorialWindow::previous, this), EShortcut::MOVE_LEFT); //22x46
 	buttonRight = std::make_shared<CButton>(Point(352, 217), AnimationPath::builtin("HSBTNS5"), CButton::tooltip(), std::bind(&CTutorialWindow::next, this), EShortcut::MOVE_RIGHT); //22x46
 

+ 1 - 1
client/windows/CreaturePurchaseCard.cpp

@@ -45,7 +45,7 @@ void CreaturePurchaseCard::initMinButton()
 
 void CreaturePurchaseCard::initCreatureSwitcherButton()
 {
-	creatureSwitcher = std::make_shared<CButton>(Point(pos.x + 18, pos.y-37), AnimationPath::builtin("iDv6432.def"), CButton::tooltip(), [&](){ switchCreatureLevel(); });
+	creatureSwitcher = std::make_shared<CButton>(Point(pos.x + 18, pos.y-37), AnimationPath::builtin("iDv6432.def"), CButton::tooltip(), [&](){ switchCreatureLevel(); }, EShortcut::RECRUITMENT_SWITCH_LEVEL);
 }
 
 void CreaturePurchaseCard::switchCreatureLevel()

+ 13 - 13
client/windows/GUIClasses.cpp

@@ -835,8 +835,8 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 	if(queryID.getNum() > 0)
 		quit->addCallback([=](){ LOCPLINT->cb->selectionMade(0, queryID); });
 
-	questlogButton[0] = std::make_shared<CButton>(Point( 10, qeLayout ? 39 : 44), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 0));
-	questlogButton[1] = std::make_shared<CButton>(Point(740, qeLayout ? 39 : 44), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 1));
+	questlogButton[0] = std::make_shared<CButton>(Point( 10, qeLayout ? 39 : 44), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 0), EShortcut::ADVENTURE_QUEST_LOG);
+	questlogButton[1] = std::make_shared<CButton>(Point(740, qeLayout ? 39 : 44), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 1), EShortcut::ADVENTURE_QUEST_LOG);
 
 	Rect barRect(5, 578, 725, 18);
 	statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), barRect, 5, 578));
@@ -845,8 +845,8 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 
 	garr = std::make_shared<CGarrisonInt>(Point(69, qeLayout ? 122 : 131), 4, Point(418,0), heroInst[0], heroInst[1], true, true);
 	auto splitButtonCallback = [&](){ garr->splitClick(); };
-	garr->addSplitBtn(std::make_shared<CButton>( Point( 10, qeLayout ? 122 : 132), AnimationPath::builtin("TSBTNS.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback));
-	garr->addSplitBtn(std::make_shared<CButton>( Point(744, qeLayout ? 122 : 132), AnimationPath::builtin("TSBTNS.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback));
+	garr->addSplitBtn(std::make_shared<CButton>( Point( 10, qeLayout ? 122 : 132), AnimationPath::builtin("TSBTNS.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback), EShortcut::HERO_ARMY_SPLIT);
+	garr->addSplitBtn(std::make_shared<CButton>( Point(744, qeLayout ? 122 : 132), AnimationPath::builtin("TSBTNS.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback), EShortcut::HERO_ARMY_SPLIT);
 
 	if(qeLayout)
 	{
@@ -876,22 +876,22 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 		};
 
 		moveAllGarrButtonLeft    = std::make_shared<CButton>(Point(325, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]),
-			std::bind(moveArmy, true));
+			std::bind(moveArmy, true), EShortcut::EXCHANGE_ARMY_TO_LEFT);
 		exchangeGarrButton       = std::make_shared<CButton>(Point(377, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[2]),
-			std::bind(&CExchangeController::swapArmy, &controller));
+			std::bind(&CExchangeController::swapArmy, &controller), EShortcut::EXCHANGE_ARMY_SWAP);
 		moveAllGarrButtonRight   = std::make_shared<CButton>(Point(425, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]),
-			std::bind(moveArmy, false));
+			std::bind(moveArmy, false), EShortcut::EXCHANGE_ARMY_TO_RIGHT);
 		moveArtifactsButtonLeft  = std::make_shared<CButton>(Point(325, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]),
-			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.moveArtifacts(true, equipped, baclpack);}));
+			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.moveArtifacts(true, equipped, baclpack);}), EShortcut::EXCHANGE_ARTIFACTS_TO_LEFT);
 		exchangeArtifactsButton  = std::make_shared<CButton>(Point(377, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[4]),
-			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.swapArtifacts(equipped, baclpack);}));
+			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.swapArtifacts(equipped, baclpack);}), EShortcut::EXCHANGE_ARTIFACTS_SWAP);
 		moveArtifactsButtonRight = std::make_shared<CButton>(Point(425, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]),
-			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.moveArtifacts(false, equipped, baclpack);}));
+			std::bind(moveArtifacts, [this](bool equipped, bool baclpack) -> void {controller.moveArtifacts(false, equipped, baclpack);}), EShortcut::EXCHANGE_ARTIFACTS_TO_RIGHT);
 		backpackButtonLeft       = std::make_shared<CButton>(Point(325, 518), AnimationPath::builtin("heroBackpack"), CButton::tooltipLocalized("vcmi.heroWindow.openBackpack"),
-			std::bind(openBackpack, heroInst[0]));
+			std::bind(openBackpack, heroInst[0]), EShortcut::EXCHANGE_BACKPACK_LEFT);
 		backpackButtonLeft->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("heroWindow/backpackButtonIcon")));
 		backpackButtonRight      = std::make_shared<CButton>(Point(419, 518), AnimationPath::builtin("heroBackpack"), CButton::tooltipLocalized("vcmi.heroWindow.openBackpack"),
-			std::bind(openBackpack, heroInst[1]));
+			std::bind(openBackpack, heroInst[1]), EShortcut::EXCHANGE_BACKPACK_RIGHT);
 		backpackButtonRight->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("heroWindow/backpackButtonIcon")));
 
 		auto leftHeroBlock = heroInst[0]->tempOwner != LOCPLINT->cb->getPlayerID();
@@ -1306,7 +1306,7 @@ CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance
 
 	garr = std::make_shared<CGarrisonInt>(Point(92, 127), 4, Point(0,96), up, down, removableUnits);
 	{
-		auto split = std::make_shared<CButton>(Point(88, 314), AnimationPath::builtin("IDV6432.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3], ""), [&](){ garr->splitClick(); } );
+		auto split = std::make_shared<CButton>(Point(88, 314), AnimationPath::builtin("IDV6432.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3], ""), [&](){ garr->splitClick(); }, EShortcut::HERO_ARMY_SPLIT );
 		garr->addSplitBtn(split);
 	}
 	quit = std::make_shared<CButton>(Point(399, 314), AnimationPath::builtin("IOK6432.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[8], ""), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT);