1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-23 21:29:13 +02:00

CIntObject now receives mouse position as point instead of SDL event

This commit is contained in:
Ivan Savenko 2023-02-02 15:49:23 +02:00
parent 58cfddccaa
commit 214fc19e74
16 changed files with 97 additions and 55 deletions

View File

@ -971,7 +971,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
heroList.redraw(); heroList.redraw();
} }
void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent ) void CAdvMapInt::mouseMoved( const Point & cursorPosition )
{ {
#if defined(VCMI_ANDROID) || defined(VCMI_IOS) #if defined(VCMI_ANDROID) || defined(VCMI_IOS)
if(swipeEnabled) if(swipeEnabled)
@ -980,9 +980,9 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
// adventure map scrolling with mouse // adventure map scrolling with mouse
// currently disabled in world view mode (as it is in OH3), but should work correctly if mode check is removed // currently disabled in world view mode (as it is in OH3), but should work correctly if mode check is removed
// don't scroll if there is no window in focus - these events don't seem to correspond to the actual mouse movement // don't scroll if there is no window in focus - these events don't seem to correspond to the actual mouse movement
if(!CSDL_Ext::isCtrlKeyDown() && isActive() && sEvent.windowID != 0 && mode == EAdvMapMode::NORMAL) if(!CSDL_Ext::isCtrlKeyDown() && isActive() && mode == EAdvMapMode::NORMAL)
{ {
if(sEvent.x<15) if(cursorPosition.x<15)
{ {
scrollingDir |= LEFT; scrollingDir |= LEFT;
} }
@ -990,7 +990,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{ {
scrollingDir &= ~LEFT; scrollingDir &= ~LEFT;
} }
if(sEvent.x>screen->w-15) if(cursorPosition.x>screen->w-15)
{ {
scrollingDir |= RIGHT; scrollingDir |= RIGHT;
} }
@ -998,7 +998,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{ {
scrollingDir &= ~RIGHT; scrollingDir &= ~RIGHT;
} }
if(sEvent.y<15) if(cursorPosition.y<15)
{ {
scrollingDir |= UP; scrollingDir |= UP;
} }
@ -1006,7 +1006,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{ {
scrollingDir &= ~UP; scrollingDir &= ~UP;
} }
if(sEvent.y>screen->h-15) if(cursorPosition.y>screen->h-15)
{ {
scrollingDir |= DOWN; scrollingDir |= DOWN;
} }

View File

@ -159,7 +159,7 @@ public:
int3 verifyPos(int3 ver); int3 verifyPos(int3 ver);
void handleRightClick(std::string text, tribool down); void handleRightClick(std::string text, tribool down);
void keyPressed(const SDL_KeyboardEvent & key) override; void keyPressed(const SDL_KeyboardEvent & key) override;
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override; void mouseMoved (const Point & cursorPosition) override;
bool isActive(); bool isActive();
bool isHeroSleeping(const CGHeroInstance *hero); bool isHeroSleeping(const CGHeroInstance *hero);

View File

@ -229,7 +229,7 @@ void CMinimap::hover(bool on)
GH.statusbar->clear(); GH.statusbar->clear();
} }
void CMinimap::mouseMoved(const SDL_MouseMotionEvent & sEvent) void CMinimap::mouseMoved(const Point & cursorPosition)
{ {
if(mouseState(EIntObjMouseBtnType::LEFT)) if(mouseState(EIntObjMouseBtnType::LEFT))
moveAdvMapSelection(); moveAdvMapSelection();

View File

@ -53,7 +53,7 @@ protected:
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void hover (bool on) override; void hover (bool on) override;
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override; void mouseMoved (const Point & cursorPosition) override;
void moveAdvMapSelection(); void moveAdvMapSelection();

View File

@ -110,32 +110,31 @@ void CTerrainRect::clickMiddle(tribool down, bool previousState)
handleSwipeStateChange((bool)down == true); handleSwipeStateChange((bool)down == true);
} }
void CTerrainRect::mouseMoved(const SDL_MouseMotionEvent & sEvent) void CTerrainRect::mouseMoved(const Point & cursorPosition)
{ {
handleHover(sEvent); handleHover(cursorPosition);
if(!adventureInt->swipeEnabled) if(!adventureInt->swipeEnabled)
return; return;
handleSwipeMove(sEvent); handleSwipeMove(cursorPosition);
} }
void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent) void CTerrainRect::handleSwipeMove(const Point & cursorPosition)
{ {
#if defined(VCMI_ANDROID) || defined(VCMI_IOS) #if defined(VCMI_ANDROID) || defined(VCMI_IOS)
if(sEvent.state == 0 || GH.multifinger) // any "button" is enough on mobile if(!GH.isMouseButtonPressed() || GH.multifinger) // any "button" is enough on mobile
#else
if((sEvent.state & SDL_BUTTON_MMASK) == 0) // swipe only works with middle mouse on other platforms
#endif
{
return; return;
} #else
if(!GH.isMouseButtonPressed(MouseButton::MIDDLE)) // swipe only works with middle mouse on other platforms
return;
#endif
if(!isSwiping) if(!isSwiping)
{ {
// try to distinguish if this touch was meant to be a swipe or just fat-fingering press // try to distinguish if this touch was meant to be a swipe or just fat-fingering press
if(abs(sEvent.x - swipeInitialRealPos.x) > SwipeTouchSlop || if(abs(cursorPosition.x - swipeInitialRealPos.x) > SwipeTouchSlop ||
abs(sEvent.y - swipeInitialRealPos.y) > SwipeTouchSlop) abs(cursorPosition.y - swipeInitialRealPos.y) > SwipeTouchSlop)
{ {
isSwiping = true; isSwiping = true;
} }
@ -144,9 +143,9 @@ void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent)
if(isSwiping) if(isSwiping)
{ {
adventureInt->swipeTargetPosition.x = adventureInt->swipeTargetPosition.x =
swipeInitialMapPos.x + static_cast<si32>(swipeInitialRealPos.x - sEvent.x) / 32; swipeInitialMapPos.x + static_cast<si32>(swipeInitialRealPos.x - cursorPosition.x) / 32;
adventureInt->swipeTargetPosition.y = adventureInt->swipeTargetPosition.y =
swipeInitialMapPos.y + static_cast<si32>(swipeInitialRealPos.y - sEvent.y) / 32; swipeInitialMapPos.y + static_cast<si32>(swipeInitialRealPos.y - cursorPosition.y) / 32;
adventureInt->swipeMovementRequested = true; adventureInt->swipeMovementRequested = true;
} }
} }
@ -155,7 +154,7 @@ bool CTerrainRect::handleSwipeStateChange(bool btnPressed)
{ {
if(btnPressed) if(btnPressed)
{ {
swipeInitialRealPos = int3(GH.getCursorPosition().x, GH.getCursorPosition().y, 0); swipeInitialRealPos = Point(GH.getCursorPosition().x, GH.getCursorPosition().y);
swipeInitialMapPos = int3(adventureInt->position); swipeInitialMapPos = int3(adventureInt->position);
return true; return true;
} }
@ -167,9 +166,9 @@ bool CTerrainRect::handleSwipeStateChange(bool btnPressed)
return false; return false;
} }
void CTerrainRect::handleHover(const SDL_MouseMotionEvent &sEvent) void CTerrainRect::handleHover(const Point & cursorPosition)
{ {
int3 tHovered = whichTileIsIt(sEvent.x, sEvent.y); int3 tHovered = whichTileIsIt(cursorPosition.x, cursorPosition.y);
int3 pom = adventureInt->verifyPos(tHovered); int3 pom = adventureInt->verifyPos(tHovered);
if(tHovered != pom) //tile outside the map if(tHovered != pom) //tile outside the map

View File

@ -27,12 +27,12 @@ class CTerrainRect : public CIntObject
std::shared_ptr<CFadeAnimation> fadeAnim; std::shared_ptr<CFadeAnimation> fadeAnim;
int3 swipeInitialMapPos; int3 swipeInitialMapPos;
int3 swipeInitialRealPos; Point swipeInitialRealPos;
bool isSwiping; bool isSwiping;
static constexpr float SwipeTouchSlop = 16.0f; static constexpr float SwipeTouchSlop = 16.0f;
void handleHover(const SDL_MouseMotionEvent & sEvent); void handleHover(const Point & cursorPosition);
void handleSwipeMove(const SDL_MouseMotionEvent & sEvent); void handleSwipeMove(const Point & cursorPosition);
/// handles start/finish of swipe (press/release of corresponding button); returns true if state change was handled /// handles start/finish of swipe (press/release of corresponding button); returns true if state change was handled
bool handleSwipeStateChange(bool btnPressed); bool handleSwipeStateChange(bool btnPressed);
public: public:
@ -48,7 +48,7 @@ public:
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void clickMiddle(tribool down, bool previousState) override; void clickMiddle(tribool down, bool previousState) override;
void hover(bool on) override; void hover(bool on) override;
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override; void mouseMoved (const Point & cursorPosition) override;
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
void showAnim(SDL_Surface * to); void showAnim(SDL_Surface * to);

View File

@ -98,9 +98,9 @@ void BattleFieldController::createHeroes()
owner.defendingHero = std::make_shared<BattleHero>(owner, owner.defendingHeroInstance, true); owner.defendingHero = std::make_shared<BattleHero>(owner, owner.defendingHeroInstance, true);
} }
void BattleFieldController::mouseMoved(const SDL_MouseMotionEvent &event) void BattleFieldController::mouseMoved(const Point & cursorPosition)
{ {
if (!pos.isInside(event.x, event.y)) if (!pos.isInside(cursorPosition))
{ {
owner.actionsController->onHoverEnded(); owner.actionsController->onHoverEnded();
return; return;

View File

@ -62,7 +62,7 @@ class BattleFieldController : public CIntObject
BattleHex::EDir selectAttackDirection(BattleHex myNumber, const Point & point); BattleHex::EDir selectAttackDirection(BattleHex myNumber, const Point & point);
void mouseMoved(const SDL_MouseMotionEvent &event) override; void mouseMoved(const Point & cursorPosition) override;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;

View File

@ -203,7 +203,12 @@ void CGuiHandler::handleEvents()
{ {
continueEventHandling = true; continueEventHandling = true;
SDL_Event currentEvent = SDLEventsQueue.front(); SDL_Event currentEvent = SDLEventsQueue.front();
if (currentEvent.type == SDL_MOUSEMOTION)
{
cursorPosition = Point(currentEvent.motion.x, currentEvent.motion.y); cursorPosition = Point(currentEvent.motion.x, currentEvent.motion.y);
mouseButtonsMask = currentEvent.motion.state;
}
SDLEventsQueue.pop(); SDLEventsQueue.pop();
// In a sequence of mouse motion events, skip all but the last one. // In a sequence of mouse motion events, skip all but the last one.
@ -546,6 +551,8 @@ void CGuiHandler::handleMouseMotion(const SDL_Event & current)
elem->hovered = true; elem->hovered = true;
} }
// do not send motion events for events outside our window
//if (current.motion.windowID == 0)
handleMoveInterested(current.motion); handleMoveInterested(current.motion);
} }
@ -566,7 +573,7 @@ void CGuiHandler::handleMoveInterested(const SDL_MouseMotionEvent & motion)
{ {
if(elem->strongInterest || Rect::createAround(elem->pos, 1).isInside( motion.x, motion.y)) //checking bounds including border fixes bug #2476 if(elem->strongInterest || Rect::createAround(elem->pos, 1).isInside( motion.x, motion.y)) //checking bounds including border fixes bug #2476
{ {
(elem)->mouseMoved(motion); (elem)->mouseMoved(Point(motion.x, motion.y));
} }
} }
} }
@ -612,13 +619,16 @@ void CGuiHandler::renderFrame()
CGuiHandler::CGuiHandler() CGuiHandler::CGuiHandler()
: lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false), : lastClick(-500, -500)
multifinger(false) , lastClickTime(0)
, defActionsDef(0)
, captureChildren(false)
, multifinger(false)
, mouseButtonsMask(0)
, continueEventHandling(true)
, curInt(nullptr)
, statusbar(nullptr)
{ {
continueEventHandling = true;
curInt = nullptr;
statusbar = nullptr;
// Creates the FPS manager and sets the framerate to 48 which is doubled the value of the original Heroes 3 FPS rate // Creates the FPS manager and sets the framerate to 48 which is doubled the value of the original Heroes 3 FPS rate
mainFPSmng = new CFramerateManager(60); mainFPSmng = new CFramerateManager(60);
//do not init CFramerateManager here --AVS //do not init CFramerateManager here --AVS
@ -642,6 +652,23 @@ const Point & CGuiHandler::getCursorPosition() const
return cursorPosition; return cursorPosition;
} }
bool CGuiHandler::isMouseButtonPressed() const
{
return mouseButtonsMask > 0;
}
bool CGuiHandler::isMouseButtonPressed(MouseButton button) const
{
static_assert(static_cast<uint32_t>(MouseButton::LEFT) == SDL_BUTTON_LEFT, "mismatch between VCMI and SDL enum!");
static_assert(static_cast<uint32_t>(MouseButton::MIDDLE) == SDL_BUTTON_MIDDLE, "mismatch between VCMI and SDL enum!");
static_assert(static_cast<uint32_t>(MouseButton::RIGHT) == SDL_BUTTON_RIGHT, "mismatch between VCMI and SDL enum!");
static_assert(static_cast<uint32_t>(MouseButton::EXTRA1) == SDL_BUTTON_X1, "mismatch between VCMI and SDL enum!");
static_assert(static_cast<uint32_t>(MouseButton::EXTRA2) == SDL_BUTTON_X2, "mismatch between VCMI and SDL enum!");
uint32_t index = static_cast<uint32_t>(button);
return mouseButtonsMask & SDL_BUTTON(index);
}
void CGuiHandler::drawFPSCounter() void CGuiHandler::drawFPSCounter()
{ {
static SDL_Rect overlay = { 0, 0, 64, 32}; static SDL_Rect overlay = { 0, 0, 64, 32};

View File

@ -43,6 +43,15 @@ enum EUserEvent
INTERFACE_CHANGED INTERFACE_CHANGED
}; };
enum class MouseButton
{
LEFT = 1,
MIDDLE = 2,
RIGHT = 3,
EXTRA1 = 4,
EXTRA2 = 5
};
// A fps manager which holds game updates at a constant rate // A fps manager which holds game updates at a constant rate
class CFramerateManager class CFramerateManager
{ {
@ -71,6 +80,7 @@ public:
private: private:
Point cursorPosition; Point cursorPosition;
uint32_t mouseButtonsMask;
std::vector<std::shared_ptr<IShowActivatable>> disposed; std::vector<std::shared_ptr<IShowActivatable>> disposed;
@ -107,8 +117,15 @@ public:
//objs to blit //objs to blit
std::vector<std::shared_ptr<IShowActivatable>> objsToBlit; std::vector<std::shared_ptr<IShowActivatable>> objsToBlit;
/// returns current position of mouse cursor, relative to vcmi window
const Point & getCursorPosition() const; const Point & getCursorPosition() const;
/// returns true if at least one mouse button is pressed
bool isMouseButtonPressed() const;
/// returns true if specified mouse button is pressed
bool isMouseButtonPressed(MouseButton button) const;
IUpdateable *curInt; IUpdateable *curInt;
Point lastClick; Point lastClick;

View File

@ -19,7 +19,6 @@ class CPicture;
struct SDL_KeyboardEvent; struct SDL_KeyboardEvent;
struct SDL_TextInputEvent; struct SDL_TextInputEvent;
struct SDL_TextEditingEvent; struct SDL_TextEditingEvent;
struct SDL_MouseMotionEvent;
using boost::logic::tribool; using boost::logic::tribool;
@ -130,7 +129,7 @@ public:
//mouse movement handling //mouse movement handling
bool strongInterest; //if true - report all mouse movements, if not - only when hovered bool strongInterest; //if true - report all mouse movements, if not - only when hovered
virtual void mouseMoved (const SDL_MouseMotionEvent & sEvent){} virtual void mouseMoved (const Point & cursorPosition){}
//time handling //time handling
void setTimer(int msToTrigger);//set timer delay and activate timer if needed. void setTimer(int msToTrigger);//set timer delay and activate timer if needed.

View File

@ -555,22 +555,22 @@ void CSlider::sliderClicked()
addUsedEvents(MOVE); addUsedEvents(MOVE);
} }
void CSlider::mouseMoved (const SDL_MouseMotionEvent & sEvent) void CSlider::mouseMoved (const Point & cursorPosition)
{ {
double v = 0; double v = 0;
if(horizontal) if(horizontal)
{ {
if( std::abs(sEvent.y-(pos.y+pos.h/2)) > pos.h/2+40 || std::abs(sEvent.x-(pos.x+pos.w/2)) > pos.w/2 ) if( std::abs(cursorPosition.y-(pos.y+pos.h/2)) > pos.h/2+40 || std::abs(cursorPosition.x-(pos.x+pos.w/2)) > pos.w/2 )
return; return;
v = sEvent.x - pos.x - 24; v = cursorPosition.x - pos.x - 24;
v *= positions; v *= positions;
v /= (pos.w - 48); v /= (pos.w - 48);
} }
else else
{ {
if(std::abs(sEvent.x-(pos.x+pos.w/2)) > pos.w/2+40 || std::abs(sEvent.y-(pos.y+pos.h/2)) > pos.h/2 ) if(std::abs(cursorPosition.x-(pos.x+pos.w/2)) > pos.w/2+40 || std::abs(cursorPosition.y-(pos.y+pos.h/2)) > pos.h/2 )
return; return;
v = sEvent.y - pos.y - 24; v = cursorPosition.y - pos.y - 24;
v *= positions; v *= positions;
v /= (pos.h - 48); v /= (pos.h - 48);
} }

View File

@ -273,7 +273,7 @@ public:
void keyPressed(const SDL_KeyboardEvent & key) override; void keyPressed(const SDL_KeyboardEvent & key) override;
void wheelScrolled(bool down, bool in) override; void wheelScrolled(bool down, bool in) override;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override; void mouseMoved (const Point & cursorPosition) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
/// @param position coordinates of slider /// @param position coordinates of slider

View File

@ -241,11 +241,11 @@ std::string CBuildingRect::getSubtitle()//hover text for building
} }
} }
void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent) void CBuildingRect::mouseMoved (const Point & cursorPosition)
{ {
if(area && pos.isInside(sEvent.x, sEvent.y)) if(area && pos.isInside(cursorPosition.x, cursorPosition.y))
{ {
if(area->isTransparent(GH.getCursorPosition() - pos.topLeft())) //hovered pixel is inside this building if(area->isTransparent(cursorPosition - pos.topLeft())) //hovered pixel is inside this building
{ {
if(parent->selectedBuilding == this) if(parent->selectedBuilding == this)
{ {

View File

@ -68,7 +68,7 @@ public:
void hover(bool on) override; void hover(bool on) override;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override; void mouseMoved (const Point & cursorPosition) override;
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
}; };

View File

@ -66,7 +66,7 @@ class CQuestMinimap : public CMinimap
void clickLeft(tribool down, bool previousState) override{}; //minimap ignores clicking on its surface void clickLeft(tribool down, bool previousState) override{}; //minimap ignores clicking on its surface
void iconClicked(); void iconClicked();
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override{}; void mouseMoved (const Point & cursorPosition) override{};
public: public:
const QuestInfo * currentQuest; const QuestInfo * currentQuest;