mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Simplified text input handling, fixes hotkeys on windows with text input
This commit is contained in:
		| @@ -96,7 +96,7 @@ void CInGameConsole::print(const std::string & txt) | ||||
|  | ||||
| 		auto splitText = CMessage::breakText(txt, maxWidth, FONT_MEDIUM); | ||||
|  | ||||
| 		for (auto const & entry : splitText) | ||||
| 		for(const auto & entry : splitText) | ||||
| 			texts.push_back({entry, 0}); | ||||
|  | ||||
| 		while(texts.size() > maxDisplayedTexts) | ||||
| @@ -107,23 +107,43 @@ void CInGameConsole::print(const std::string & txt) | ||||
| 	CCS->soundh->playSound("CHAT"); | ||||
| } | ||||
|  | ||||
| bool CInGameConsole::captureThisKey(EShortcut key) | ||||
| { | ||||
| 	if (enteredText.empty()) | ||||
| 		return false; | ||||
|  | ||||
| 	switch (key) | ||||
| 	{ | ||||
| 		case EShortcut::GLOBAL_ACCEPT: | ||||
| 		case EShortcut::GLOBAL_CANCEL: | ||||
| 		case EShortcut::GAME_ACTIVATE_CONSOLE: | ||||
| 		case EShortcut::GLOBAL_BACKSPACE: | ||||
| 		case EShortcut::MOVE_UP: | ||||
| 		case EShortcut::MOVE_DOWN: | ||||
| 			return true; | ||||
|  | ||||
| 		default: | ||||
| 			return false; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CInGameConsole::keyPressed (EShortcut key) | ||||
| { | ||||
| 	if (LOCPLINT->cingconsole != this) | ||||
| 		return; | ||||
|  | ||||
| 	if(!captureAllKeys && key != EShortcut::GAME_ACTIVATE_CONSOLE) | ||||
| 	if(enteredText.empty() && key != EShortcut::GAME_ACTIVATE_CONSOLE) | ||||
| 		return; //because user is not entering any text | ||||
|  | ||||
| 	switch(key) | ||||
| 	{ | ||||
| 	case EShortcut::GLOBAL_CANCEL: | ||||
| 		if(captureAllKeys) | ||||
| 		if(!enteredText.empty()) | ||||
| 			endEnteringText(false); | ||||
| 		break; | ||||
|  | ||||
| 	case EShortcut::GAME_ACTIVATE_CONSOLE: | ||||
| 		if(captureAllKeys) | ||||
| 		if(!enteredText.empty()) | ||||
| 			endEnteringText(false); | ||||
| 		else | ||||
| 			startEnteringText(); | ||||
| @@ -131,7 +151,7 @@ void CInGameConsole::keyPressed (EShortcut key) | ||||
|  | ||||
| 	case EShortcut::GLOBAL_ACCEPT: | ||||
| 		{ | ||||
| 			if(!enteredText.empty() && captureAllKeys) | ||||
| 			if(!enteredText.empty()) | ||||
| 			{ | ||||
| 				bool anyTextExceptCaret = enteredText.size() > 1; | ||||
| 				endEnteringText(anyTextExceptCaret); | ||||
| @@ -191,8 +211,9 @@ void CInGameConsole::textInputed(const std::string & inputtedText) | ||||
| 	if (LOCPLINT->cingconsole != this) | ||||
| 		return; | ||||
|  | ||||
| 	if(!captureAllKeys || enteredText.empty()) | ||||
| 	if(enteredText.empty()) | ||||
| 		return; | ||||
|  | ||||
| 	enteredText.resize(enteredText.size()-1); | ||||
|  | ||||
| 	enteredText += inputtedText; | ||||
| @@ -211,14 +232,10 @@ void CInGameConsole::startEnteringText() | ||||
| 	if (!isActive()) | ||||
| 		return; | ||||
|  | ||||
| 	if (captureAllKeys) | ||||
| 		return; | ||||
|  | ||||
| 	assert(currentStatusBar.expired());//effectively, nullptr check | ||||
|  | ||||
| 	currentStatusBar = GH.statusbar(); | ||||
|  | ||||
| 	captureAllKeys = true; | ||||
| 	enteredText = "_"; | ||||
|  | ||||
| 	GH.statusbar()->setEnteringMode(true); | ||||
| @@ -227,7 +244,6 @@ void CInGameConsole::startEnteringText() | ||||
|  | ||||
| void CInGameConsole::endEnteringText(bool processEnteredText) | ||||
| { | ||||
| 	captureAllKeys = false; | ||||
| 	prevEntDisp = -1; | ||||
| 	if(processEnteredText) | ||||
| 	{ | ||||
|   | ||||
| @@ -50,6 +50,7 @@ public: | ||||
| 	void keyPressed(EShortcut key) override; | ||||
| 	void textInputed(const std::string & enteredText) override; | ||||
| 	void textEdited(const std::string & enteredText) override; | ||||
| 	bool captureThisKey(EShortcut key) override; | ||||
|  | ||||
| 	void startEnteringText(); | ||||
| 	void endEnteringText(bool processEnteredText); | ||||
|   | ||||
| @@ -33,6 +33,12 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key) | ||||
| 	if(key.repeat != 0) | ||||
| 		return; // ignore periodic event resends | ||||
|  | ||||
| 	if (SDL_IsTextInputActive() == SDL_TRUE) | ||||
| 	{ | ||||
| 		if (key.keysym.sym >= ' ' && key.keysym.sym < 0x80) | ||||
| 			return; // printable character - will be handled as text input | ||||
| 	} | ||||
|  | ||||
| 	assert(key.state == SDL_PRESSED); | ||||
|  | ||||
| 	if(key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool()) | ||||
| @@ -77,6 +83,12 @@ void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key) | ||||
| 	if(key.repeat != 0) | ||||
| 		return; // ignore periodic event resends | ||||
|  | ||||
| 	if (SDL_IsTextInputActive() == SDL_TRUE) | ||||
| 	{ | ||||
| 		if (key.keysym.sym >= ' ' && key.keysym.sym < 0x80) | ||||
| 			return; // printable character - will be handled as text input | ||||
| 	} | ||||
|  | ||||
| 	assert(key.state == SDL_RELEASED); | ||||
|  | ||||
| 	auto shortcutsVector = GH.shortcuts().translateKeycode(key.keysym.sym); | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
|  | ||||
| #include "CGuiHandler.h" | ||||
| #include "WindowHandler.h" | ||||
| #include "EventDispatcher.h" | ||||
| #include "Shortcut.h" | ||||
| #include "../render/Canvas.h" | ||||
| #include "../windows/CMessage.h" | ||||
| @@ -22,7 +23,6 @@ CIntObject::CIntObject(int used_, Point pos_): | ||||
| 	parent(parent_m), | ||||
| 	redrawParent(false), | ||||
| 	inputEnabled(true), | ||||
| 	captureAllKeys(false), | ||||
| 	used(used_), | ||||
| 	recActions(GH.defActionsDef), | ||||
| 	defActions(GH.defActionsDef), | ||||
| @@ -37,6 +37,8 @@ CIntObject::~CIntObject() | ||||
| 	if(isActive()) | ||||
| 		deactivate(); | ||||
|  | ||||
| 	GH.events().assertElementInactive(this); | ||||
|  | ||||
| 	while(!children.empty()) | ||||
| 	{ | ||||
| 		if((defActions & DISPOSE) && (children.front()->recActions & DISPOSE)) | ||||
| @@ -148,15 +150,15 @@ void CIntObject::setInputEnabled(bool on) | ||||
|  | ||||
| 	inputEnabled = on; | ||||
|  | ||||
| 	if (!isActive()) | ||||
| 		return; | ||||
|  | ||||
| 	if (isActive()) | ||||
| 	{ | ||||
| 		assert((used & GENERAL) == 0); | ||||
|  | ||||
| 		if (on) | ||||
| 			activateEvents(used); | ||||
| 		else | ||||
| 			deactivateEvents(used); | ||||
| 	} | ||||
|  | ||||
| 	for(auto & elem : children) | ||||
| 		elem->setInputEnabled(on); | ||||
| @@ -207,6 +209,9 @@ void CIntObject::addChild(CIntObject * child, bool adjustPosition) | ||||
| 	if(adjustPosition) | ||||
| 		child->moveBy(pos.topLeft(), adjustPosition); | ||||
|  | ||||
| 	if (inputEnabled != child->inputEnabled) | ||||
| 		child->setInputEnabled(inputEnabled); | ||||
|  | ||||
| 	if (!isActive() && child->isActive()) | ||||
| 		child->deactivate(); | ||||
| 	if (isActive()&& !child->isActive()) | ||||
| @@ -292,7 +297,7 @@ const Rect & CIntObject::center(const Point & p, bool propagate) | ||||
|  | ||||
| bool CIntObject::captureThisKey(EShortcut key) | ||||
| { | ||||
| 	return captureAllKeys; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| CKeyShortcut::CKeyShortcut() | ||||
|   | ||||
| @@ -62,10 +62,8 @@ public: | ||||
| 	CIntObject(int used=0, Point offset=Point()); | ||||
| 	virtual ~CIntObject(); | ||||
|  | ||||
| 	//keyboard handling | ||||
| 	bool captureAllKeys; //if true, only this object should get info about pressed keys | ||||
|  | ||||
| 	bool captureThisKey(EShortcut key) override; //allows refining captureAllKeys against specific events (eg. don't capture ENTER) | ||||
| 	/// allows capturing key input so it will be delivered only to this element | ||||
| 	bool captureThisKey(EShortcut key) override; | ||||
|  | ||||
| 	void addUsedEvents(ui16 newActions); | ||||
| 	void removeUsedEvents(ui16 newActions); | ||||
|   | ||||
| @@ -310,7 +310,6 @@ CChatBox::CChatBox(const Rect & rect) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION; | ||||
| 	pos += rect.topLeft(); | ||||
| 	captureAllKeys = true; | ||||
| 	setRedrawParent(true); | ||||
|  | ||||
| 	const int height = static_cast<int>(graphics->fonts[FONT_SMALL]->getLineHeight()); | ||||
|   | ||||
| @@ -495,7 +495,6 @@ CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList<void(c | ||||
| 	setRedrawParent(true); | ||||
| 	pos.h = Pos.h; | ||||
| 	pos.w = Pos.w; | ||||
| 	captureAllKeys = true; | ||||
| 	background.reset(); | ||||
| 	addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT); | ||||
|  | ||||
| @@ -511,7 +510,6 @@ CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const std::stri | ||||
| 	pos.h = Pos.h; | ||||
| 	pos.w = Pos.w; | ||||
|  | ||||
| 	captureAllKeys = true; | ||||
| 	OBJ_CONSTRUCTION; | ||||
| 	background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y); | ||||
| 	addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT); | ||||
| @@ -525,7 +523,6 @@ CTextInput::CTextInput(const Rect & Pos, std::shared_ptr<IImage> srf) | ||||
| 	:CFocusable(std::make_shared<CKeyboardFocusListener>(this)) | ||||
| { | ||||
| 	pos += Pos.topLeft(); | ||||
| 	captureAllKeys = true; | ||||
| 	OBJ_CONSTRUCTION; | ||||
| 	background = std::make_shared<CPicture>(srf, Pos); | ||||
| 	pos.w = background->pos.w; | ||||
| @@ -620,17 +617,6 @@ void CTextInput::setText(const std::string & nText, bool callCb) | ||||
| 		cb(text); | ||||
| } | ||||
|  | ||||
| bool CTextInput::captureThisKey(EShortcut key) | ||||
| { | ||||
| 	if(key == EShortcut::GLOBAL_RETURN) | ||||
| 		return false; | ||||
|  | ||||
| 	if (!focus) | ||||
| 		return false; | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void CTextInput::textInputed(const std::string & enteredText) | ||||
| { | ||||
| 	if(!focus) | ||||
|   | ||||
| @@ -227,7 +227,7 @@ public: | ||||
| 	void clickLeft(tribool down, bool previousState) override; | ||||
| 	void keyPressed(EShortcut key) override; | ||||
|  | ||||
| 	bool captureThisKey(EShortcut key) override; | ||||
| 	//bool captureThisKey(EShortcut key) override; | ||||
|  | ||||
| 	void textInputed(const std::string & enteredText) override; | ||||
| 	void textEdited(const std::string & enteredText) override; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user