1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-21 21:17:49 +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

@ -971,7 +971,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
heroList.redraw();
}
void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
void CAdvMapInt::mouseMoved( const Point & cursorPosition )
{
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
if(swipeEnabled)
@ -980,9 +980,9 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
// 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
// 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;
}
@ -990,7 +990,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{
scrollingDir &= ~LEFT;
}
if(sEvent.x>screen->w-15)
if(cursorPosition.x>screen->w-15)
{
scrollingDir |= RIGHT;
}
@ -998,7 +998,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{
scrollingDir &= ~RIGHT;
}
if(sEvent.y<15)
if(cursorPosition.y<15)
{
scrollingDir |= UP;
}
@ -1006,7 +1006,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{
scrollingDir &= ~UP;
}
if(sEvent.y>screen->h-15)
if(cursorPosition.y>screen->h-15)
{
scrollingDir |= DOWN;
}

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

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

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

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

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

@ -98,9 +98,9 @@ void BattleFieldController::createHeroes()
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();
return;

@ -62,7 +62,7 @@ class BattleFieldController : public CIntObject
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 clickRight(tribool down, bool previousState) override;

@ -203,7 +203,12 @@ void CGuiHandler::handleEvents()
{
continueEventHandling = true;
SDL_Event currentEvent = SDLEventsQueue.front();
cursorPosition = Point(currentEvent.motion.x, currentEvent.motion.y);
if (currentEvent.type == SDL_MOUSEMOTION)
{
cursorPosition = Point(currentEvent.motion.x, currentEvent.motion.y);
mouseButtonsMask = currentEvent.motion.state;
}
SDLEventsQueue.pop();
// In a sequence of mouse motion events, skip all but the last one.
@ -546,7 +551,9 @@ void CGuiHandler::handleMouseMotion(const SDL_Event & current)
elem->hovered = true;
}
handleMoveInterested(current.motion);
// do not send motion events for events outside our window
//if (current.motion.windowID == 0)
handleMoveInterested(current.motion);
}
void CGuiHandler::simpleRedraw()
@ -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
{
(elem)->mouseMoved(motion);
(elem)->mouseMoved(Point(motion.x, motion.y));
}
}
}
@ -612,13 +619,16 @@ void CGuiHandler::renderFrame()
CGuiHandler::CGuiHandler()
: lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false),
multifinger(false)
: lastClick(-500, -500)
, 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
mainFPSmng = new CFramerateManager(60);
//do not init CFramerateManager here --AVS
@ -642,6 +652,23 @@ const Point & CGuiHandler::getCursorPosition() const
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()
{
static SDL_Rect overlay = { 0, 0, 64, 32};

@ -43,6 +43,15 @@ enum EUserEvent
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
class CFramerateManager
{
@ -71,6 +80,7 @@ public:
private:
Point cursorPosition;
uint32_t mouseButtonsMask;
std::vector<std::shared_ptr<IShowActivatable>> disposed;
@ -107,8 +117,15 @@ public:
//objs to blit
std::vector<std::shared_ptr<IShowActivatable>> objsToBlit;
/// returns current position of mouse cursor, relative to vcmi window
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;
Point lastClick;

@ -19,7 +19,6 @@ class CPicture;
struct SDL_KeyboardEvent;
struct SDL_TextInputEvent;
struct SDL_TextEditingEvent;
struct SDL_MouseMotionEvent;
using boost::logic::tribool;
@ -130,7 +129,7 @@ public:
//mouse movement handling
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
void setTimer(int msToTrigger);//set timer delay and activate timer if needed.

@ -555,22 +555,22 @@ void CSlider::sliderClicked()
addUsedEvents(MOVE);
}
void CSlider::mouseMoved (const SDL_MouseMotionEvent & sEvent)
void CSlider::mouseMoved (const Point & cursorPosition)
{
double v = 0;
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;
v = sEvent.x - pos.x - 24;
v = cursorPosition.x - pos.x - 24;
v *= positions;
v /= (pos.w - 48);
}
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;
v = sEvent.y - pos.y - 24;
v = cursorPosition.y - pos.y - 24;
v *= positions;
v /= (pos.h - 48);
}

@ -273,7 +273,7 @@ public:
void keyPressed(const SDL_KeyboardEvent & key) override;
void wheelScrolled(bool down, bool in) 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;
/// @param position coordinates of slider

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

@ -68,7 +68,7 @@ public:
void hover(bool on) override;
void clickLeft(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 showAll(SDL_Surface * to) override;
};

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