Laserlicht преди 3 месеца
родител
ревизия
c40e1bae19

+ 2 - 0
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",

+ 2 - 0
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",

+ 42 - 9
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<ShortcutElement>(elem.first, elem.second, listElements.size()));
+					listElements.push_back(std::make_shared<ShortcutElement>(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<void(const std::string & id, const std::string & keyName)> func)
+	: func(func)
 {
 	OBJECT_CONSTRUCTION;
 
@@ -99,7 +117,7 @@ ShortcutElement::ShortcutElement(std::string id, JsonNode keys, int elem)
 	{
 		std::vector<std::string> 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<CLabel>(
@@ -110,14 +128,18 @@ ShortcutElement::ShortcutElement(std::string id, JsonNode keys, int elem)
 	);
 	buttonEdit = std::make_shared<CButton>(Point(422, 3), AnimationPath::builtin("settingsWindow/button32"), std::make_pair("", MetaString::createFromTextID("vcmi.shortcuts.editButton.help").toString()));
 	buttonEdit->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("settingsWindow/gear")));
-	buttonEdit->addCallback([id](){
-		ENGINE->windows().createAndPushWindow<ShortcutsEditWindow>(id);
+	buttonEdit->addCallback([id, func](){
+		ENGINE->windows().createAndPushWindow<ShortcutsEditWindow>(id, [func](const std::string & id, const std::string & keyName){
+			if(func)
+				func(id, keyName);
+		});
 	});
 	if(elem < MAX_LINES - 1)
 		seperationLine = std::make_shared<TransparentFilledRectangle>(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<TransparentFilledRectangle>(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<void(const std::string & id, const std::string & keyName)> 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<CFilledTexture>(ImagePath::builtin("DiBoxBck"), Rect(0, 0, pos.w, pos.h));
+	text = std::make_shared<CTextBox>(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);
 }

+ 12 - 2
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<CLabel> labelKeys;
 	std::shared_ptr<TransparentFilledRectangle> seperationLine; // rectangle is cleaner than line...
 
+	std::function<void(const std::string & id, const std::string & keyName)> func;
+
 public:
-	ShortcutElement(std::string id, JsonNode keys, int elem);
+	ShortcutElement(std::string id, JsonNode keys, int elem, std::function<void(const std::string & id, const std::string & keyName)> 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<CFilledTexture> backgroundTexture;
+	std::shared_ptr<CTextBox> text;
+
+	std::string id;
+	std::function<void(const std::string & id, const std::string & keyName)> func;
+
 	void keyPressed(const std::string & keyName) override;
 public:
-	ShortcutsEditWindow(const std::string & id);
+	ShortcutsEditWindow(const std::string & id, std::function<void(const std::string & id, const std::string & keyName)> func);
 };
 

+ 1 - 1
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)
 	{