mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Merge pull request #1461 from vcmi/sdl-relative-pointer
SDL relative pointer for android
This commit is contained in:
@@ -374,7 +374,8 @@ int main(int argc, char * argv[])
|
|||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
|
||||||
#endif // VCMI_ANDROID
|
#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);
|
SDL_LogSetOutputFunction(&SDLLogCallback, nullptr);
|
||||||
|
|
||||||
@@ -430,11 +431,20 @@ int main(int argc, char * argv[])
|
|||||||
CCS->musich->setVolume((ui32)settings["general"]["music"].Float());
|
CCS->musich->setVolume((ui32)settings["general"]["music"].Float());
|
||||||
logGlobal->info("Initializing screen and sound handling: %d ms", pomtime.getDiff());
|
logGlobal->info("Initializing screen and sound handling: %d ms", pomtime.getDiff());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VCMI_MAC
|
#ifdef VCMI_MAC
|
||||||
// Ctrl+click should be treated as a right click on Mac OS X
|
// Ctrl+click should be treated as a right click on Mac OS X
|
||||||
SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
|
SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDL_HINT_MOUSE_TOUCH_EVENTS
|
||||||
|
if(GH.isPointerRelativeMode)
|
||||||
|
{
|
||||||
|
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
|
||||||
|
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef VCMI_NO_THREADED_LOAD
|
#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
|
//we can properly play intro only in the main thread, so we have to move loading to the separate thread
|
||||||
boost::thread loading(init);
|
boost::thread loading(init);
|
||||||
|
@@ -78,6 +78,13 @@ void CGuiHandler::processLists(const ui16 activityFlag, std::function<void (std:
|
|||||||
processList(CIntObject::TEXTINPUT,activityFlag,&textInterested,cb);
|
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)
|
void CGuiHandler::handleElementActivate(CIntObject * elem, ui16 activityFlag)
|
||||||
{
|
{
|
||||||
processLists(activityFlag,[&](std::list<CIntObject*> * lst){
|
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;
|
int rLogicalWidth, rLogicalHeight;
|
||||||
|
|
||||||
@@ -221,6 +228,63 @@ void convertTouch(SDL_Event * current)
|
|||||||
current->motion.y = adjustedMouseY;
|
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;
|
||||||
|
|
||||||
|
float xScale, yScale;
|
||||||
|
int w, h, rLogicalWidth, rLogicalHeight;
|
||||||
|
|
||||||
|
SDL_GetWindowSize(mainWindow, &w, &h);
|
||||||
|
SDL_RenderGetLogicalSize(mainRenderer, &rLogicalWidth, &rLogicalHeight);
|
||||||
|
SDL_RenderGetScale(mainRenderer, &xScale, &yScale);
|
||||||
|
|
||||||
|
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
|
||||||
|
SDL_WarpMouse(
|
||||||
|
(int)(sme.x * xScale) + (w - rLogicalWidth * xScale) / 2,
|
||||||
|
(int)(sme.y * yScale + (h - rLogicalHeight * yScale) / 2));
|
||||||
|
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
|
||||||
|
|
||||||
|
event.button = sme;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
void CGuiHandler::handleCurrentEvent()
|
void CGuiHandler::handleCurrentEvent()
|
||||||
{
|
{
|
||||||
if(current->type == SDL_KEYDOWN || current->type == SDL_KEYUP)
|
if(current->type == SDL_KEYDOWN || current->type == SDL_KEYUP)
|
||||||
@@ -371,33 +435,60 @@ 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)
|
else if(current->type == SDL_FINGERDOWN)
|
||||||
{
|
{
|
||||||
auto fingerCount = SDL_GetNumTouchFingers(current->tfinger.touchId);
|
auto fingerCount = SDL_GetNumTouchFingers(current->tfinger.touchId);
|
||||||
|
|
||||||
multifinger = fingerCount > 1;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef VCMI_IOS
|
||||||
|
else if(fingerCount == 2)
|
||||||
|
{
|
||||||
|
convertTouchToMouse(current);
|
||||||
handleMouseMotion();
|
handleMouseMotion();
|
||||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, true);
|
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, true);
|
||||||
}
|
}
|
||||||
|
#endif //VCMI_IOS
|
||||||
}
|
}
|
||||||
else if(current->type == SDL_FINGERUP)
|
else if(current->type == SDL_FINGERUP)
|
||||||
{
|
{
|
||||||
auto fingerCount = SDL_GetNumTouchFingers(current->tfinger.touchId);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef VCMI_IOS
|
||||||
|
else if(multifinger)
|
||||||
|
{
|
||||||
|
convertTouchToMouse(current);
|
||||||
handleMouseMotion();
|
handleMouseMotion();
|
||||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
||||||
multifinger = fingerCount != 0;
|
multifinger = fingerCount != 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif //VCMI_IOS
|
#endif //VCMI_IOS
|
||||||
|
}
|
||||||
|
|
||||||
current = nullptr;
|
current = nullptr;
|
||||||
} //event end
|
} //event end
|
||||||
@@ -471,20 +562,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()
|
void CGuiHandler::renderFrame()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -88,6 +88,10 @@ private:
|
|||||||
|
|
||||||
void handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed);
|
void handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed);
|
||||||
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
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:
|
public:
|
||||||
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
|
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
|
||||||
void handleElementDeActivate(CIntObject * elem, ui16 activityFlag);
|
void handleElementDeActivate(CIntObject * elem, ui16 activityFlag);
|
||||||
@@ -102,6 +106,8 @@ public:
|
|||||||
Point lastClick;
|
Point lastClick;
|
||||||
unsigned lastClickTime;
|
unsigned lastClickTime;
|
||||||
bool multifinger;
|
bool multifinger;
|
||||||
|
bool isPointerRelativeMode;
|
||||||
|
float pointerSpeedMultiplier;
|
||||||
|
|
||||||
ui8 defActionsDef; //default auto actions
|
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
|
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();
|
||||||
~CGuiHandler();
|
~CGuiHandler();
|
||||||
|
|
||||||
|
void init();
|
||||||
void renderFrame();
|
void renderFrame();
|
||||||
|
|
||||||
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
|
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
|
||||||
|
@@ -17,7 +17,20 @@
|
|||||||
"type" : "object",
|
"type" : "object",
|
||||||
"default": {},
|
"default": {},
|
||||||
"additionalProperties" : false,
|
"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" : {
|
"properties" : {
|
||||||
"playerName" : {
|
"playerName" : {
|
||||||
"type":"string",
|
"type":"string",
|
||||||
@@ -70,6 +83,14 @@
|
|||||||
"extraDump" : {
|
"extraDump" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"default" : false
|
"default" : false
|
||||||
|
},
|
||||||
|
"userRelativePointer" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"default" : false
|
||||||
|
},
|
||||||
|
"relativePointerSpeedMultiplier" : {
|
||||||
|
"type" : "number",
|
||||||
|
"default" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user