소스 검색

Merge pull request #4299 from Laserlicht/input_modi_detection

input mode detection
Ivan Savenko 1 년 전
부모
커밋
d59a5dad7d

+ 9 - 2
client/battle/BattleInterfaceClasses.cpp

@@ -425,7 +425,7 @@ QuickSpellPanel::QuickSpellPanel(BattleInterface & owner)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 
-	addUsedEvents(LCLICK | SHOW_POPUP | MOVE);
+	addUsedEvents(LCLICK | SHOW_POPUP | MOVE | INPUT_MODE_CHANGE);
 
 	pos = Rect(0, 0, 52, 600);
 	background = std::make_shared<CFilledTexture>(ImagePath::builtin("DIBOXBCK"), pos);
@@ -481,7 +481,8 @@ void QuickSpellPanel::create()
 		{
 			buttonsDisabled.push_back(std::make_shared<TransparentFilledRectangle>(Rect(2, 7 + 50 * i, 48, 36), ColorRGBA(0, 0, 0, 172)));
 		}
-		labels.push_back(std::make_shared<CLabel>(7, 10 + 50 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String()));
+		if(GH.input().getCurrentInputMode() == InputMode::KEYBOARD_AND_MOUSE)
+			labels.push_back(std::make_shared<CLabel>(7, 10 + 50 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String()));
 
 		buttons.push_back(button);
 	}
@@ -493,6 +494,12 @@ void QuickSpellPanel::show(Canvas & to)
 	CIntObject::show(to);
 }
 
+void QuickSpellPanel::inputModeChanged(InputMode modi)
+{
+	create();
+	redraw();
+}
+
 HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground)
 	: CIntObject(0)
 {

+ 1 - 0
client/battle/BattleInterfaceClasses.h

@@ -167,6 +167,7 @@ public:
 	void create();
 
 	void show(Canvas & to) override;
+	void inputModeChanged(InputMode modi) override;
 };
 
 class HeroInfoBasicPanel : public CIntObject //extracted from InfoWindow to fit better as non-popup embed element

+ 36 - 1
client/eventsSDL/InputHandler.cpp

@@ -37,6 +37,7 @@ InputHandler::InputHandler()
 	: enableMouse(settings["input"]["enableMouse"].Bool())
 	, enableTouch(settings["input"]["enableTouch"].Bool())
 	, enableController(settings["input"]["enableController"].Bool())
+	, currentInputMode(InputMode::KEYBOARD_AND_MOUSE)
 	, mouseHandler(std::make_unique<InputSourceMouse>())
 	, keyboardHandler(std::make_unique<InputSourceKeyboard>())
 	, fingerHandler(std::make_unique<InputSourceTouch>())
@@ -52,6 +53,7 @@ void InputHandler::handleCurrentEvent(const SDL_Event & current)
 	switch (current.type)
 	{
 		case SDL_KEYDOWN:
+			setCurrentInputMode(InputMode::KEYBOARD_AND_MOUSE);
 			keyboardHandler->handleEventKeyDown(current.key);
 			return;
 		case SDL_KEYUP:
@@ -60,11 +62,17 @@ void InputHandler::handleCurrentEvent(const SDL_Event & current)
 #ifndef VCMI_EMULATE_TOUCHSCREEN_WITH_MOUSE
 		case SDL_MOUSEMOTION:
 			if (enableMouse)
+			{
+				setCurrentInputMode(InputMode::KEYBOARD_AND_MOUSE);
 				mouseHandler->handleEventMouseMotion(current.motion);
+			}
 			return;
 		case SDL_MOUSEBUTTONDOWN:
 			if (enableMouse)
+			{
+				setCurrentInputMode(InputMode::KEYBOARD_AND_MOUSE);
 				mouseHandler->handleEventMouseButtonDown(current.button);
+			}
 			return;
 		case SDL_MOUSEBUTTONUP:
 			if (enableMouse)
@@ -83,11 +91,17 @@ void InputHandler::handleCurrentEvent(const SDL_Event & current)
 			return;
 		case SDL_FINGERMOTION:
 			if (enableTouch)
+			{
+				setCurrentInputMode(InputMode::TOUCH);
 				fingerHandler->handleEventFingerMotion(current.tfinger);
+			}
 			return;
 		case SDL_FINGERDOWN:
 			if (enableTouch)
+			{
+				setCurrentInputMode(InputMode::TOUCH);
 				fingerHandler->handleEventFingerDown(current.tfinger);
+			}
 			return;
 		case SDL_FINGERUP:
 			if (enableTouch)
@@ -95,11 +109,17 @@ void InputHandler::handleCurrentEvent(const SDL_Event & current)
 			return;
 		case SDL_CONTROLLERAXISMOTION:
 			if (enableController)
+			{
+				setCurrentInputMode(InputMode::CONTROLLER);
 				gameControllerHandler->handleEventAxisMotion(current.caxis);
+			}
 			return;
 		case SDL_CONTROLLERBUTTONDOWN:
 			if (enableController)
+			{
+				setCurrentInputMode(InputMode::CONTROLLER);
 				gameControllerHandler->handleEventButtonDown(current.cbutton);
+			}
 			return;
 		case SDL_CONTROLLERBUTTONUP:
 			if (enableController)
@@ -108,6 +128,20 @@ void InputHandler::handleCurrentEvent(const SDL_Event & current)
 	}
 }
 
+void InputHandler::setCurrentInputMode(InputMode modi)
+{
+	if(currentInputMode != modi)
+	{
+		currentInputMode = modi;
+		GH.events().dispatchInputModeChanged(modi);
+	}
+}
+
+InputMode InputHandler::getCurrentInputMode()
+{
+	return currentInputMode;
+}
+
 std::vector<SDL_Event> InputHandler::acquireEvents()
 {
 	boost::unique_lock<boost::mutex> lock(eventsMutex);
@@ -335,7 +369,8 @@ void InputHandler::stopTextInput()
 
 void InputHandler::hapticFeedback()
 {
-	fingerHandler->hapticFeedback();
+	if(currentInputMode == InputMode::TOUCH)
+		fingerHandler->hapticFeedback();
 }
 
 uint32_t InputHandler::getTicks()

+ 12 - 0
client/eventsSDL/InputHandler.h

@@ -23,6 +23,13 @@ class InputSourceTouch;
 class InputSourceText;
 class InputSourceGameController;
 
+enum class InputMode
+{
+	KEYBOARD_AND_MOUSE,
+	TOUCH,
+	CONTROLLER
+};
+
 class InputHandler
 {
 	std::vector<SDL_Event> eventsQueue;
@@ -34,6 +41,9 @@ class InputHandler
 	const bool enableTouch;
 	const bool enableController;
 
+	InputMode currentInputMode;
+	void setCurrentInputMode(InputMode modi);
+
 	std::vector<SDL_Event> acquireEvents();
 
 	void preprocessEvent(const SDL_Event & event);
@@ -91,4 +101,6 @@ public:
 	bool isKeyboardCmdDown() const;
 	bool isKeyboardCtrlDown() const;
 	bool isKeyboardShiftDown() const;
+
+	InputMode getCurrentInputMode();
 };

+ 10 - 0
client/gui/EventDispatcher.cpp

@@ -19,6 +19,7 @@
 
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/Rect.h"
+#include "../eventsSDL/InputHandler.h"
 
 template<typename Functor>
 void EventDispatcher::processLists(ui16 activityFlag, const Functor & cb)
@@ -40,6 +41,7 @@ void EventDispatcher::processLists(ui16 activityFlag, const Functor & cb)
 	processList(AEventsReceiver::DOUBLECLICK, doubleClickInterested);
 	processList(AEventsReceiver::TEXTINPUT, textInterested);
 	processList(AEventsReceiver::GESTURE, panningInterested);
+	processList(AEventsReceiver::INPUT_MODE_CHANGE, inputModeChangeInterested);
 }
 
 void EventDispatcher::activateElement(AEventsReceiver * elem, ui16 activityFlag)
@@ -316,6 +318,14 @@ void EventDispatcher::dispatchTextEditing(const std::string & text)
 	}
 }
 
+void EventDispatcher::dispatchInputModeChanged(const InputMode & modi)
+{
+	for(auto it : inputModeChangeInterested)
+	{
+		it->inputModeChanged(modi);
+	}
+}
+
 void EventDispatcher::dispatchGesturePanningStarted(const Point & initialPosition)
 {
 	auto copied = panningInterested;

+ 4 - 0
client/gui/EventDispatcher.h

@@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_END
 class AEventsReceiver;
 enum class MouseButton;
 enum class EShortcut;
+enum class InputMode;
 
 /// Class that receives events from event producers and dispatches it to UI elements that are interested in this event
 class EventDispatcher
@@ -34,6 +35,7 @@ class EventDispatcher
 	EventReceiversList doubleClickInterested;
 	EventReceiversList textInterested;
 	EventReceiversList panningInterested;
+	EventReceiversList inputModeChangeInterested;
 
 	void handleLeftButtonClick(const Point & position, int tolerance, bool isPressed);
 	void handleDoubleButtonClick(const Point & position, int tolerance);
@@ -76,4 +78,6 @@ public:
 	/// Text input events
 	void dispatchTextInput(const std::string & text);
 	void dispatchTextEditing(const std::string & text);
+
+	void dispatchInputModeChanged(const InputMode & modi);
 };

+ 4 - 0
client/gui/EventsReceiver.h

@@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_END
 
 class EventDispatcher;
 enum class EShortcut;
+enum class InputMode;
 
 /// Class that is capable of subscribing and receiving input events
 /// Acts as base class for all UI elements
@@ -75,6 +76,8 @@ public:
 
 	virtual void tick(uint32_t msPassed) {}
 
+	virtual void inputModeChanged(InputMode modi) {}
+
 public:
 	AEventsReceiver();
 	virtual ~AEventsReceiver() = default;
@@ -94,6 +97,7 @@ public:
 		TEXTINPUT = 512,
 		GESTURE = 1024,
 		DRAG = 2048,
+		INPUT_MODE_CHANGE = 4096
 	};
 
 	/// Returns true if element is currently hovered by mouse

+ 1 - 1
client/windows/CTutorialWindow.cpp

@@ -67,7 +67,7 @@ void CTutorialWindow::setContent()
 
 void CTutorialWindow::openWindowFirstTime(const TutorialMode & m)
 {
-	if(GH.input().hasTouchInputDevice() && !persistentStorage["gui"]["tutorialCompleted" + std::to_string(m)].Bool())
+	if(GH.input().getCurrentInputMode() == InputMode::TOUCH && !persistentStorage["gui"]["tutorialCompleted" + std::to_string(m)].Bool())
 	{
 		if(LOCPLINT)
 			LOCPLINT->showingDialog->setBusy();