1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

SDL relative pointer for android

This commit is contained in:
Andrii Danylchenko 2023-01-16 12:26:43 +02:00
parent 226668c428
commit 6c843bce0b
4 changed files with 127 additions and 21 deletions

View File

@ -374,7 +374,8 @@ int main(int argc, char * argv[])
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
#endif // VCMI_ANDROID
GH.mainFPSmng->init(); //(!)init here AFTER SDL_Init() while using SDL for FPS management
//(!)init here AFTER SDL_Init() while using SDL for FPS management
GH.init();
SDL_LogSetOutputFunction(&SDLLogCallback, nullptr);
@ -430,11 +431,18 @@ int main(int argc, char * argv[])
CCS->musich->setVolume((ui32)settings["general"]["music"].Float());
logGlobal->info("Initializing screen and sound handling: %d ms", pomtime.getDiff());
}
#ifdef VCMI_MAC
// Ctrl+click should be treated as a right click on Mac OS X
SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
#endif
if(GH.isPointerRelativeMode)
{
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
}
#ifndef VCMI_NO_THREADED_LOAD
//we can properly play intro only in the main thread, so we have to move loading to the separate thread
boost::thread loading(init);

View File

@ -78,6 +78,13 @@ void CGuiHandler::processLists(const ui16 activityFlag, std::function<void (std:
processList(CIntObject::TEXTINPUT,activityFlag,&textInterested,cb);
}
void CGuiHandler::init()
{
mainFPSmng->init();
isPointerRelativeMode = settings["general"]["userRelativePointer"].Bool();
pointerSpeedMultiplier = settings["general"]["relativePointerSpeedMultiplier"].Float();
}
void CGuiHandler::handleElementActivate(CIntObject * elem, ui16 activityFlag)
{
processLists(activityFlag,[&](std::list<CIntObject*> * lst){
@ -206,7 +213,7 @@ void CGuiHandler::handleEvents()
}
}
void convertTouch(SDL_Event * current)
void CGuiHandler::convertTouchToMouse(SDL_Event * current)
{
int rLogicalWidth, rLogicalHeight;
@ -221,6 +228,58 @@ void convertTouch(SDL_Event * current)
current->motion.y = adjustedMouseY;
}
void CGuiHandler::fakeMoveCursor(float dx, float dy)
{
int x, y, w, h;
SDL_Event event;
SDL_MouseMotionEvent sme = {SDL_MOUSEMOTION, 0, 0, 0, 0, 0, 0, 0, 0};
sme.state = SDL_GetMouseState(&x, &y);
SDL_GetWindowSize(mainWindow, &w, &h);
sme.x = CCS->curh->xpos + (int)(GH.pointerSpeedMultiplier * w * dx);
sme.y = CCS->curh->ypos + (int)(GH.pointerSpeedMultiplier * h * dy);
vstd::abetween(sme.x, 0, w);
vstd::abetween(sme.y, 0, h);
event.motion = sme;
SDL_PushEvent(&event);
}
void CGuiHandler::fakeMouseMove()
{
fakeMoveCursor(0, 0);
}
void CGuiHandler::fakeMouseButtonEventRelativeMode(bool down, bool right)
{
SDL_Event event;
SDL_MouseButtonEvent sme = {SDL_MOUSEBUTTONDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if(!down)
{
sme.type = SDL_MOUSEBUTTONUP;
}
sme.button = right ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT;
sme.x = CCS->curh->xpos;
sme.y = CCS->curh->ypos;
int windowX, windowY;
SDL_RenderLogicalToWindow(mainRenderer, sme.x, sme.y, &windowX, &windowY);
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
SDL_WarpMouse(windowX, windowY);
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
event.button = sme;
SDL_PushEvent(&event);
}
void CGuiHandler::handleCurrentEvent()
{
if(current->type == SDL_KEYDOWN || current->type == SDL_KEYUP)
@ -372,15 +431,31 @@ void CGuiHandler::handleCurrentEvent()
}
}
#ifndef VCMI_IOS
else if(current->type == SDL_FINGERMOTION)
{
if(isPointerRelativeMode)
{
fakeMoveCursor(current->tfinger.dx, current->tfinger.dy);
}
}
else if(current->type == SDL_FINGERDOWN)
{
auto fingerCount = SDL_GetNumTouchFingers(current->tfinger.touchId);
multifinger = fingerCount > 1;
if(fingerCount == 2)
if(isPointerRelativeMode)
{
convertTouch(current);
if(current->tfinger.x > 0.5)
{
bool isRightClick = current->tfinger.y < 0.5;
fakeMouseButtonEventRelativeMode(true, isRightClick);
}
}
else if(fingerCount == 2)
{
convertTouchToMouse(current);
handleMouseMotion();
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, true);
}
@ -389,9 +464,18 @@ void CGuiHandler::handleCurrentEvent()
{
auto fingerCount = SDL_GetNumTouchFingers(current->tfinger.touchId);
if(multifinger)
if(isPointerRelativeMode)
{
convertTouch(current);
if(current->tfinger.x > 0.5)
{
bool isRightClick = current->tfinger.y < 0.5;
fakeMouseButtonEventRelativeMode(false, isRightClick);
}
}
else if(multifinger)
{
convertTouchToMouse(current);
handleMouseMotion();
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
multifinger = fingerCount != 0;
@ -471,20 +555,6 @@ void CGuiHandler::handleMoveInterested(const SDL_MouseMotionEvent & motion)
}
}
void CGuiHandler::fakeMouseMove()
{
SDL_Event event;
SDL_MouseMotionEvent sme = {SDL_MOUSEMOTION, 0, 0, 0, 0, 0, 0, 0, 0};
int x, y;
sme.state = SDL_GetMouseState(&x, &y);
sme.x = x;
sme.y = y;
event.motion = sme;
SDL_PushEvent(&event);
}
void CGuiHandler::renderFrame()
{

View File

@ -88,6 +88,10 @@ private:
void handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed);
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
void convertTouchToMouse(SDL_Event * current);
void fakeMoveCursor(float dx, float dy);
void fakeMouseButtonEventRelativeMode(bool down, bool right);
public:
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
void handleElementDeActivate(CIntObject * elem, ui16 activityFlag);
@ -102,6 +106,8 @@ public:
Point lastClick;
unsigned lastClickTime;
bool multifinger;
bool isPointerRelativeMode;
float pointerSpeedMultiplier;
ui8 defActionsDef; //default auto actions
bool captureChildren; //all newly created objects will get their parents from stack and will be added to parents children list
@ -110,6 +116,7 @@ public:
CGuiHandler();
~CGuiHandler();
void init();
void renderFrame();
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering

View File

@ -17,7 +17,20 @@
"type" : "object",
"default": {},
"additionalProperties" : false,
"required" : [ "playerName", "showfps", "music", "sound", "encoding", "swipe", "saveRandomMaps", "saveFrequency", "notifications", "extraDump" ],
"required" : [
"playerName",
"showfps",
"music",
"sound",
"encoding",
"swipe",
"saveRandomMaps",
"saveFrequency",
"notifications",
"extraDump",
"userRelativePointer",
"relativePointerSpeedMultiplier"
],
"properties" : {
"playerName" : {
"type":"string",
@ -70,6 +83,14 @@
"extraDump" : {
"type" : "boolean",
"default" : false
},
"userRelativePointer" : {
"type" : "boolean",
"default" : false
},
"relativePointerSpeedMultiplier" : {
"type" : "number",
"default" : 1
}
}
},