1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Merge pull request #4299 from Laserlicht/input_modi_detection

input mode detection
This commit is contained in:
Ivan Savenko 2024-07-20 12:51:08 +03:00 committed by GitHub
commit d59a5dad7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 77 additions and 4 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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()

View File

@ -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();
};

View File

@ -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;

View File

@ -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);
};

View File

@ -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

View File

@ -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();