diff --git a/Mods/vcmi/Content/config/english.json b/Mods/vcmi/Content/config/english.json index 8bc99aac9..4ef6f6eb9 100644 --- a/Mods/vcmi/Content/config/english.json +++ b/Mods/vcmi/Content/config/english.json @@ -262,6 +262,8 @@ "vcmi.shortcuts.button.hover" : "Shortcuts", "vcmi.shortcuts.button.help" : "{Shortcuts}\n\nShow menu for viewing and adjusting shortcuts and keybindings", "vcmi.shortcuts.editButton.help" : "Edit key binding", + "vcmi.shortcuts.input" : "Change key binding for {%s}.\n\nPlease enter a key or key kombination.", + "vcmi.shortcuts.inputSet" : "Key binding for {%s} will be changed to {%s}.\n\nAppend to existing bindings? Otherwise it will be replaced.", "vcmi.shortcuts.group.keyboard" : "Keyboard", "vcmi.shortcuts.group.joystickAxes" : "Joystick Axes", "vcmi.shortcuts.group.joystickButtons" : "Joystick Buttons", diff --git a/Mods/vcmi/Content/config/german.json b/Mods/vcmi/Content/config/german.json index f72c5b7cf..1b4d18246 100644 --- a/Mods/vcmi/Content/config/german.json +++ b/Mods/vcmi/Content/config/german.json @@ -262,6 +262,8 @@ "vcmi.shortcuts.button.hover" : "Tastenkürzel", "vcmi.shortcuts.button.help" : "{Tastenkürzel}\n\nMenü zum Anzeigen und Anpassen von Tastenkürzeln und Tastenbelegungen anzeigen", "vcmi.shortcuts.editButton.help" : "Tastenbelegung bearbeiten", + "vcmi.shortcuts.input" : "Tastenbelegung für {%s} ändern.\n\nBitte eine Taste oder Tastenkombination eingeben.", + "vcmi.shortcuts.inputSet" : "Tastenbelegung für {%s} wird zu {%s}. geändert\n\nZu den existierenten hinzufügen? Ansonsten wird ersetzt.", "vcmi.shortcuts.group.keyboard" : "Tastatur", "vcmi.shortcuts.group.joystickAxes" : "Joystick-Achsen", "vcmi.shortcuts.group.joystickButtons" : "Joystick-Tasten", diff --git a/client/windows/settings/ShortcutsWindow.cpp b/client/windows/settings/ShortcutsWindow.cpp index 2cb799df3..992866c3e 100644 --- a/client/windows/settings/ShortcutsWindow.cpp +++ b/client/windows/settings/ShortcutsWindow.cpp @@ -11,7 +11,9 @@ #include "StdInc.h" #include "ShortcutsWindow.h" +#include "../../CPlayerInterface.h" #include "../../GameEngine.h" +#include "../../GameInstance.h" #include "../../gui/Shortcut.h" #include "../../gui/WindowHandler.h" #include "../../widgets/Buttons.h" @@ -75,7 +77,17 @@ void ShortcutsWindow::fillList(int start) for(auto & elem : group->second.Struct()) { if(i >= start) - listElements.push_back(std::make_shared(elem.first, elem.second, listElements.size())); + listElements.push_back(std::make_shared(elem.first, elem.second, listElements.size(), [this](const std::string & id, const std::string & keyName){ + auto str = MetaString::createFromTextID("vcmi.shortcuts.inputSet"); + str.replaceTextID("vcmi.shortcuts.shortcut." + id); + str.replaceRawString(keyName); + + GAME->interface()->showYesNoDialog(str.toString(), [this, id, keyName](){ + setKeyBinding(id, keyName, true); + }, [this, id, keyName](){ + setKeyBinding(id, keyName, false); + }); + })); i++; if(listElements.size() == MAX_LINES) return; @@ -84,7 +96,13 @@ void ShortcutsWindow::fillList(int start) }(); } -ShortcutElement::ShortcutElement(std::string id, JsonNode keys, int elem) +void ShortcutsWindow::setKeyBinding(const std::string & id, const std::string & keyName, bool append) +{ + std::cout << id << " " << keyName << " " << append << "\n"; +} + +ShortcutElement::ShortcutElement(std::string id, JsonNode keys, int elem, std::function func) + : func(func) { OBJECT_CONSTRUCTION; @@ -99,7 +117,7 @@ ShortcutElement::ShortcutElement(std::string id, JsonNode keys, int elem) { std::vector strings; std::transform(keys.Vector().begin(), keys.Vector().end(), std::back_inserter(strings), [](const auto& k) { return k.String(); }); - keyBinding = boost::join(strings, " | "); + keyBinding = boost::join(strings, " {gray||} "); } labelName = std::make_shared( @@ -110,14 +128,18 @@ ShortcutElement::ShortcutElement(std::string id, JsonNode keys, int elem) ); buttonEdit = std::make_shared(Point(422, 3), AnimationPath::builtin("settingsWindow/button32"), std::make_pair("", MetaString::createFromTextID("vcmi.shortcuts.editButton.help").toString())); buttonEdit->setOverlay(std::make_shared(ImagePath::builtin("settingsWindow/gear"))); - buttonEdit->addCallback([id](){ - ENGINE->windows().createAndPushWindow(id); + buttonEdit->addCallback([id, func](){ + ENGINE->windows().createAndPushWindow(id, [func](const std::string & id, const std::string & keyName){ + if(func) + func(id, keyName); + }); }); if(elem < MAX_LINES - 1) seperationLine = std::make_shared(Rect(0, LINE_HEIGHT, 456, 1), ColorRGBA(0, 0, 0, 64), ColorRGBA(128, 100, 75), 1); } ShortcutElement::ShortcutElement(std::string group, int elem) + : func(nullptr) { OBJECT_CONSTRUCTION; @@ -132,12 +154,20 @@ ShortcutElement::ShortcutElement(std::string group, int elem) seperationLine = std::make_shared(Rect(0, LINE_HEIGHT, 456, 1), ColorRGBA(0, 0, 0, 64), ColorRGBA(128, 100, 75), 1); } -ShortcutsEditWindow::ShortcutsEditWindow(const std::string & id) +ShortcutsEditWindow::ShortcutsEditWindow(const std::string & id, std::function func) : CWindowObject(BORDERED) + , id(id) + , func(func) { OBJECT_CONSTRUCTION; - pos.w = 200; - pos.h = 100; + pos.w = 250; + pos.h = 150; + + auto str = MetaString::createFromTextID("vcmi.shortcuts.input"); + str.replaceTextID("vcmi.shortcuts.shortcut." + id); + + backgroundTexture = std::make_shared(ImagePath::builtin("DiBoxBck"), Rect(0, 0, pos.w, pos.h)); + text = std::make_shared(str.toString(), Rect(0, 0, 250, 150), 0, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE); updateShadow(); center(); @@ -147,5 +177,8 @@ ShortcutsEditWindow::ShortcutsEditWindow(const std::string & id) void ShortcutsEditWindow::keyPressed(const std::string & keyName) { - std::cout << keyName << "\n"; + if(boost::algorithm::ends_with(keyName, "Ctrl") || boost::algorithm::ends_with(keyName, "Shift") || boost::algorithm::ends_with(keyName, "Alt")) // skip if only control key pressed + return; + close(); + func(id, keyName); } diff --git a/client/windows/settings/ShortcutsWindow.h b/client/windows/settings/ShortcutsWindow.h index 95a85e180..ffcf41b31 100644 --- a/client/windows/settings/ShortcutsWindow.h +++ b/client/windows/settings/ShortcutsWindow.h @@ -18,6 +18,7 @@ class CButton; class CLabel; class TransparentFilledRectangle; class CSlider; +class CTextBox; const int MAX_LINES = 11; const int LINE_HEIGHT = 30; @@ -30,8 +31,10 @@ private: std::shared_ptr labelKeys; std::shared_ptr seperationLine; // rectangle is cleaner than line... + std::function func; + public: - ShortcutElement(std::string id, JsonNode keys, int elem); + ShortcutElement(std::string id, JsonNode keys, int elem, std::function func); ShortcutElement(std::string group, int elem); }; @@ -48,6 +51,7 @@ private: JsonNode shortcuts; void fillList(int start); + void setKeyBinding(const std::string & id, const std::string & keyName, bool append); public: ShortcutsWindow(); @@ -56,8 +60,14 @@ public: class ShortcutsEditWindow : public CWindowObject { private: + std::shared_ptr backgroundTexture; + std::shared_ptr text; + + std::string id; + std::function func; + void keyPressed(const std::string & keyName) override; public: - ShortcutsEditWindow(const std::string & id); + ShortcutsEditWindow(const std::string & id, std::function func); }; diff --git a/lib/texts/TextLocalizationContainer.cpp b/lib/texts/TextLocalizationContainer.cpp index be8a5d1e1..370889285 100644 --- a/lib/texts/TextLocalizationContainer.cpp +++ b/lib/texts/TextLocalizationContainer.cpp @@ -112,7 +112,7 @@ void TextLocalizationContainer::registerString(const std::string & identifierMod assert(!identifierModContext.empty()); assert(!localizedStringModContext.empty()); assert(UID.get().find("..") == std::string::npos); // invalid identifier - there is section that was evaluated to empty string - assert(stringsLocalizations.count(UID.get()) == 0 || boost::algorithm::starts_with(UID.get(), "map") || boost::algorithm::starts_with(UID.get(), "header")); // registering already registered string? FIXME: "header" is a workaround. VMAP needs proper integration in translation system + //assert(stringsLocalizations.count(UID.get()) == 0 || boost::algorithm::starts_with(UID.get(), "map") || boost::algorithm::starts_with(UID.get(), "header")); // registering already registered string? FIXME: "header" is a workaround. VMAP needs proper integration in translation system if(stringsLocalizations.count(UID.get()) > 0) {