From 50a0fc4fb2d91db5816277ddc9b613c30a164256 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 27 Jan 2023 00:27:06 +0200 Subject: [PATCH] Removed pointer to current SDL_Event from GuiHandler --- client/gui/CGuiHandler.cpp | 61 ++++++++++++++------------ client/gui/CGuiHandler.h | 32 ++++++++------ client/gui/SDL_Extensions.cpp | 11 +++-- client/gui/SDL_Extensions.h | 4 +- client/lobby/CBonusSelection.cpp | 4 +- client/lobby/SelectionTab.cpp | 9 ++-- client/widgets/AdventureMapClasses.cpp | 8 ++-- client/widgets/Buttons.cpp | 8 ++-- client/windows/CAdvmapInterface.cpp | 9 ++-- client/windows/CCastleInterface.cpp | 6 +-- client/windows/InfoWindows.cpp | 2 +- 11 files changed, 77 insertions(+), 77 deletions(-) diff --git a/client/gui/CGuiHandler.cpp b/client/gui/CGuiHandler.cpp index fb7117e64..886e76f5a 100644 --- a/client/gui/CGuiHandler.cpp +++ b/client/gui/CGuiHandler.cpp @@ -192,27 +192,27 @@ void CGuiHandler::handleEvents() while(!SDLEventsQueue.empty()) { continueEventHandling = true; - auto ev = SDLEventsQueue.front(); - current = &ev; + SDL_Event currentEvent = SDLEventsQueue.front(); + cursorPosition = Point(currentEvent.motion.x, currentEvent.motion.y); SDLEventsQueue.pop(); // In a sequence of mouse motion events, skip all but the last one. // This prevents freezes when every motion event takes longer to handle than interval at which // the events arrive (like dragging on the minimap in world view, with redraw at every event) // so that the events would start piling up faster than they can be processed. - if ((ev.type == SDL_MOUSEMOTION) && !SDLEventsQueue.empty() && (SDLEventsQueue.front().type == SDL_MOUSEMOTION)) + if ((currentEvent.type == SDL_MOUSEMOTION) && !SDLEventsQueue.empty() && (SDLEventsQueue.front().type == SDL_MOUSEMOTION)) continue; - handleCurrentEvent(); + handleCurrentEvent(currentEvent); } } -void CGuiHandler::handleCurrentEvent() +void CGuiHandler::handleCurrentEvent(const SDL_Event & current ) { - if(current->type == SDL_KEYDOWN || current->type == SDL_KEYUP) + if(current.type == SDL_KEYDOWN || current.type == SDL_KEYUP) { - SDL_KeyboardEvent key = current->key; - if(current->type == SDL_KEYDOWN && key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool()) + SDL_KeyboardEvent key = current.key; + if(current.type == SDL_KEYDOWN && key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool()) { //TODO: we need some central place for all interface-independent hotkeys Settings s = settings.write["session"]; @@ -275,24 +275,24 @@ void CGuiHandler::handleCurrentEvent() if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisEvent(key))) (**i).keyPressed(key); } - else if(current->type == SDL_MOUSEMOTION) + else if(current.type == SDL_MOUSEMOTION) { - handleMouseMotion(); + handleMouseMotion(current); } - else if(current->type == SDL_MOUSEBUTTONDOWN) + else if(current.type == SDL_MOUSEBUTTONDOWN) { - switch(current->button.button) + switch(current.button.button) { case SDL_BUTTON_LEFT: { auto doubleClicked = false; - if(lastClick == current->motion && (SDL_GetTicks() - lastClickTime) < 300) + if(lastClick == getCursorPosition() && (SDL_GetTicks() - lastClickTime) < 300) { std::list hlp = doubleClickInterested; for(auto i = hlp.begin(); i != hlp.end() && continueEventHandling; i++) { if(!vstd::contains(doubleClickInterested, *i)) continue; - if((*i)->pos.isInside(current->motion.x, current->motion.y)) + if((*i)->pos.isInside(current.motion.x, current.motion.y)) { (*i)->onDoubleClick(); doubleClicked = true; @@ -301,7 +301,7 @@ void CGuiHandler::handleCurrentEvent() } - lastClick = current->motion; + lastClick = current.motion; lastClickTime = SDL_GetTicks(); if(!doubleClicked) @@ -318,7 +318,7 @@ void CGuiHandler::handleCurrentEvent() break; } } - else if(current->type == SDL_MOUSEWHEEL) + else if(current.type == SDL_MOUSEWHEEL) { std::list hlp = wheelInterested; for(auto i = hlp.begin(); i != hlp.end() && continueEventHandling; i++) @@ -327,27 +327,27 @@ void CGuiHandler::handleCurrentEvent() // SDL doesn't have the proper values for mouse positions on SDL_MOUSEWHEEL, refetch them int x = 0, y = 0; SDL_GetMouseState(&x, &y); - (*i)->wheelScrolled(current->wheel.y < 0, (*i)->pos.isInside(x, y)); + (*i)->wheelScrolled(current.wheel.y < 0, (*i)->pos.isInside(x, y)); } } - else if(current->type == SDL_TEXTINPUT) + else if(current.type == SDL_TEXTINPUT) { for(auto it : textInterested) { - it->textInputed(current->text); + it->textInputed(current.text); } } - else if(current->type == SDL_TEXTEDITING) + else if(current.type == SDL_TEXTEDITING) { for(auto it : textInterested) { - it->textEdited(current->edit); + it->textEdited(current.edit); } } //todo: muiltitouch - else if(current->type == SDL_MOUSEBUTTONUP) + else if(current.type == SDL_MOUSEBUTTONUP) { - switch(current->button.button) + switch(current.button.button) { case SDL_BUTTON_LEFT: handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, false); @@ -360,7 +360,6 @@ void CGuiHandler::handleCurrentEvent() break; } } - current = nullptr; } //event end void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed) @@ -373,7 +372,7 @@ void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntOb auto prev = (*i)->mouseState(btn); if(!isPressed) (*i)->updateMouseState(btn, isPressed); - if((*i)->pos.isInside(current->motion.x, current->motion.y)) + if((*i)->pos.isInside(getCursorPosition())) { if(isPressed) (*i)->updateMouseState(btn, isPressed); @@ -384,13 +383,13 @@ void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntOb } } -void CGuiHandler::handleMouseMotion() +void CGuiHandler::handleMouseMotion(const SDL_Event & current) { //sending active, hovered hoverable objects hover() call std::vector hlp; for(auto & elem : hoverable) { - if(elem->pos.isInside(current->motion.x, current->motion.y)) + if(elem->pos.isInside(getCursorPosition())) { if (!(elem)->hovered) hlp.push_back((elem)); @@ -407,7 +406,7 @@ void CGuiHandler::handleMouseMotion() elem->hovered = true; } - handleMoveInterested(current->motion); + handleMoveInterested(current.motion); } void CGuiHandler::simpleRedraw() @@ -491,7 +490,6 @@ CGuiHandler::CGuiHandler() { continueEventHandling = true; curInt = nullptr; - current = 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 @@ -512,6 +510,11 @@ void CGuiHandler::breakEventHandling() continueEventHandling = false; } +const Point & CGuiHandler::getCursorPosition() const +{ + return cursorPosition; +} + void CGuiHandler::drawFPSCounter() { const static SDL_Color yellow = {255, 255, 0, 0}; diff --git a/client/gui/CGuiHandler.h b/client/gui/CGuiHandler.h index 38f540185..625dee28b 100644 --- a/client/gui/CGuiHandler.h +++ b/client/gui/CGuiHandler.h @@ -70,26 +70,32 @@ public: std::shared_ptr statusbar; private: + Point cursorPosition; + std::vector> disposed; std::atomic continueEventHandling; typedef std::list CIntObjectList; //active GUI elements (listening for events - CIntObjectList lclickable, - rclickable, - mclickable, - hoverable, - keyinterested, - motioninterested, - timeinterested, - wheelInterested, - doubleClickInterested, - textInterested; + CIntObjectList lclickable; + CIntObjectList rclickable; + CIntObjectList mclickable; + CIntObjectList hoverable; + CIntObjectList keyinterested; + CIntObjectList motioninterested; + CIntObjectList timeinterested; + CIntObjectList wheelInterested; + CIntObjectList doubleClickInterested; + CIntObjectList textInterested; void handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed); void processLists(const ui16 activityFlag, std::function *)> cb); + void handleCurrentEvent(const SDL_Event & current); + void handleMouseMotion(const SDL_Event & current); + void handleMoveInterested( const SDL_MouseMotionEvent & motion ); + public: void handleElementActivate(CIntObject * elem, ui16 activityFlag); void handleElementDeActivate(CIntObject * elem, ui16 activityFlag); @@ -98,7 +104,8 @@ public: //objs to blit std::vector> objsToBlit; - SDL_Event * current; //current event - can be set to nullptr to stop handling event + const Point & getCursorPosition() const; + IUpdateable *curInt; Point lastClick; @@ -132,9 +139,6 @@ public: void updateTime(); //handles timeInterested void handleEvents(); //takes events from queue and calls interested objects - void handleCurrentEvent(); - void handleMouseMotion(); - void handleMoveInterested( const SDL_MouseMotionEvent & motion ); void fakeMouseMove(); void breakEventHandling(); //current event won't be propagated anymore void drawFPSCounter(); // draws the FPS to the upper left corner of the screen diff --git a/client/gui/SDL_Extensions.cpp b/client/gui/SDL_Extensions.cpp index 3f326146f..c5e3079b9 100644 --- a/client/gui/SDL_Extensions.cpp +++ b/client/gui/SDL_Extensions.cpp @@ -66,12 +66,6 @@ SDL_Rect CSDL_Ext::toSDL(const Rect & rect) return result; } -Point CSDL_Ext::fromSDL(const SDL_MouseMotionEvent & motion) -{ - return { motion.x, motion.y }; -} - - void CSDL_Ext::setColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors) { SDL_SetPaletteColors(surface->format->palette,colors,firstcolor,ncolors); @@ -583,6 +577,11 @@ std::string CSDL_Ext::processStr(std::string str, std::vector & tor return str; } +bool CSDL_Ext::isTransparent( SDL_Surface * srf, const Point & position ) +{ + return isTransparent(srf, position.x, position.y); +} + bool CSDL_Ext::isTransparent( SDL_Surface * srf, int x, int y ) { if (x < 0 || y < 0 || x >= srf->w || y >= srf->h) diff --git a/client/gui/SDL_Extensions.h b/client/gui/SDL_Extensions.h index 125ac8f8d..8d5ff8859 100644 --- a/client/gui/SDL_Extensions.h +++ b/client/gui/SDL_Extensions.h @@ -73,9 +73,6 @@ public: namespace CSDL_Ext { -/// creates Point using provided event -Point fromSDL(const SDL_MouseMotionEvent & motion); - /// creates Rect using provided rect Rect fromSDL(const SDL_Rect & rect); @@ -137,6 +134,7 @@ typedef void (*TColorPutterAlpha)(Uint8 *&ptr, const Uint8 & R, const Uint8 & G, SDL_Surface * horizontalFlip(SDL_Surface * toRot); //horizontal flip Uint32 getPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte = false); bool isTransparent(SDL_Surface * srf, int x, int y); //checks if surface is transparent at given position + bool isTransparent(SDL_Surface * srf, const Point & position); //checks if surface is transparent at given position Uint8 *getPxPtr(const SDL_Surface * const &srf, const int x, const int y); TColorPutter getPutterFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1 diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index 7c843c15a..f617c7a10 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -525,7 +525,7 @@ void CBonusSelection::CRegion::clickLeft(tribool down, bool previousState) if(indeterminate(down)) return; - if(!down && selectable && !CSDL_Ext::isTransparent(graphicsNotSelected->getSurface(), GH.current->motion.x - pos.x, GH.current->motion.y - pos.y)) + if(!down && selectable && !CSDL_Ext::isTransparent(graphicsNotSelected->getSurface(), GH.getCursorPosition() - pos.topLeft())) { CSH->setCampaignMap(idOfMapAndRegion); } @@ -535,7 +535,7 @@ void CBonusSelection::CRegion::clickRight(tribool down, bool previousState) { // FIXME: For some reason "down" is only ever contain indeterminate_value auto text = CSH->si->campState->camp->scenarios[idOfMapAndRegion].regionText; - if(!CSDL_Ext::isTransparent(graphicsNotSelected->getSurface(), GH.current->motion.x - pos.x, GH.current->motion.y - pos.y) && text.size()) + if(!CSDL_Ext::isTransparent(graphicsNotSelected->getSurface(), GH.getCursorPosition() - pos.topLeft()) && text.size()) { CRClickPopup::createAndPush(text); } diff --git a/client/lobby/SelectionTab.cpp b/client/lobby/SelectionTab.cpp index bf34f4429..9eaa83386 100644 --- a/client/lobby/SelectionTab.cpp +++ b/client/lobby/SelectionTab.cpp @@ -273,9 +273,9 @@ void SelectionTab::clickLeft(tribool down, bool previousState) select(line); } #ifdef VCMI_IOS - // focus input field if clicked inside it - else if(inputName && inputName->active && inputNameRect.isInside(GH.current->button.x, GH.current->button.y)) - inputName->giveFocus(); + // focus input field if clicked inside it + else if(inputName && inputName->active && inputNameRect.isInside(GH.getCursorPosition())) + inputName->giveFocus(); #endif } } @@ -454,8 +454,7 @@ void SelectionTab::updateListItems() int SelectionTab::getLine() { int line = -1; - Point clickPos(GH.current->button.x, GH.current->button.y); - clickPos = clickPos - pos.topLeft(); + Point clickPos = GH.getCursorPosition() - pos.topLeft(); // Ignore clicks on save name area int maxPosY; diff --git a/client/widgets/AdventureMapClasses.cpp b/client/widgets/AdventureMapClasses.cpp index 508ceb997..e507e99ff 100644 --- a/client/widgets/AdventureMapClasses.cpp +++ b/client/widgets/AdventureMapClasses.cpp @@ -229,7 +229,7 @@ void CHeroList::CHeroItem::open() void CHeroList::CHeroItem::showTooltip() { - CRClickPopup::createAndPush(hero, CSDL_Ext::fromSDL(GH.current->motion)); + CRClickPopup::createAndPush(hero, GH.getCursorPosition()); } std::string CHeroList::CHeroItem::getHoverText() @@ -321,7 +321,7 @@ void CTownList::CTownItem::open() void CTownList::CTownItem::showTooltip() { - CRClickPopup::createAndPush(town, CSDL_Ext::fromSDL(GH.current->motion)); + CRClickPopup::createAndPush(town, GH.getCursorPosition()); } std::string CTownList::CTownItem::getHoverText() @@ -531,8 +531,8 @@ CMinimap::CMinimap(const Rect & position) int3 CMinimap::translateMousePosition() { // 0 = top-left corner, 1 = bottom-right corner - double dx = double(GH.current->motion.x - pos.x) / pos.w; - double dy = double(GH.current->motion.y - pos.y) / pos.h; + double dx = double(GH.getCursorPosition().x - pos.x) / pos.w; + double dy = double(GH.getCursorPosition().y - pos.y) / pos.h; int3 mapSizes = LOCPLINT->cb->getMapSize(); diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 998f0ec2a..aa53ca7c1 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -503,7 +503,7 @@ void CVolumeSlider::clickLeft(tribool down, bool previousState) { if (down) { - double px = GH.current->motion.x - pos.x; + double px = GH.getCursorPosition().x - pos.x; double rx = px / static_cast(pos.w); // setVolume is out of 100 setVolume((int)(rx * 100)); @@ -522,7 +522,7 @@ void CVolumeSlider::clickRight(tribool down, bool previousState) { if (down) { - double px = GH.current->motion.x - pos.x; + double px = GH.getCursorPosition().x - pos.x; int index = static_cast(px / static_cast(pos.w) * animImage->size()); size_t helpIndex = index + (mode == MUSIC ? 326 : 336); @@ -664,12 +664,12 @@ void CSlider::clickLeft(tribool down, bool previousState) double rw = 0; if(horizontal) { - pw = GH.current->motion.x-pos.x-25; + pw = GH.getCursorPosition().x-pos.x-25; rw = pw / static_cast(pos.w - 48); } else { - pw = GH.current->motion.y-pos.y-24; + pw = GH.getCursorPosition().y-pos.y-24; rw = pw / (pos.h-48); } if(pw < -8 || pw > (horizontal ? pos.w : pos.h) - 40) diff --git a/client/windows/CAdvmapInterface.cpp b/client/windows/CAdvmapInterface.cpp index fcbba274c..5510b59a8 100644 --- a/client/windows/CAdvmapInterface.cpp +++ b/client/windows/CAdvmapInterface.cpp @@ -209,7 +209,7 @@ bool CTerrainRect::handleSwipeStateChange(bool btnPressed) { if(btnPressed) { - swipeInitialRealPos = int3(GH.current->motion.x, GH.current->motion.y, 0); + swipeInitialRealPos = int3(GH.getCursorPosition().x, GH.getCursorPosition().y, 0); swipeInitialMapPos = int3(adventureInt->position); return true; } @@ -431,10 +431,7 @@ int3 CTerrainRect::whichTileIsIt(const int x, const int y) int3 CTerrainRect::whichTileIsIt() { - if(GH.current) - return whichTileIsIt(GH.current->motion.x,GH.current->motion.y); - else - return int3(-1); + return whichTileIsIt(GH.getCursorPosition().x, GH.getCursorPosition().y); } int3 CTerrainRect::tileCountOnScreen() @@ -1833,7 +1830,7 @@ void CAdvMapInt::tileRClicked(const int3 &mapPos) return; } - CRClickPopup::createAndPush(obj, CSDL_Ext::fromSDL(GH.current->motion), ETextAlignment::CENTER); + CRClickPopup::createAndPush(obj, GH.getCursorPosition(), ETextAlignment::CENTER); } void CAdvMapInt::enterCastingMode(const CSpell * sp) diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 3e51d0af3..1dafce97f 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -127,7 +127,7 @@ void CBuildingRect::clickLeft(tribool down, bool previousState) { if(previousState && getBuilding() && area && !down && (parent->selectedBuilding==this)) { - if(!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y)) //inside building image + if(!CSDL_Ext::isTransparent(area, GH.getCursorPosition() - pos.topLeft())) //inside building image { auto building = getBuilding(); parent->buildingClicked(building->bid, building->subId, building->upgrade); @@ -139,7 +139,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState) { if((!area) || (!((bool)down)) || (this!=parent->selectedBuilding) || getBuilding() == nullptr) return; - if( !CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image + if( !CSDL_Ext::isTransparent(area, GH.getCursorPosition() - pos.topLeft()) ) //inside building image { BuildingID bid = getBuilding()->bid; const CBuilding *bld = town->town->buildings.at(bid); @@ -256,7 +256,7 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent) { if(area && pos.isInside(sEvent.x, sEvent.y)) { - if(CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y)) //hovered pixel is inside this building + if(CSDL_Ext::isTransparent(area, GH.getCursorPosition() - pos.topLeft())) //hovered pixel is inside this building { if(parent->selectedBuilding == this) { diff --git a/client/windows/InfoWindows.cpp b/client/windows/InfoWindows.cpp index 3641941dd..0d2a52532 100644 --- a/client/windows/InfoWindows.cpp +++ b/client/windows/InfoWindows.cpp @@ -306,7 +306,7 @@ void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCom player = PlayerColor(1); auto temp = std::make_shared(txt, player, comps); - temp->center(CSDL_Ext::fromSDL(GH.current->motion)); //center on mouse + temp->center(GH.getCursorPosition()); //center on mouse #ifdef VCMI_IOS // TODO: enable also for android? temp->moveBy({0, -temp->pos.h / 2});