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

Removed pointer to current SDL_Event from GuiHandler

This commit is contained in:
Ivan Savenko 2023-01-27 00:27:06 +02:00
parent 4d1c338503
commit 50a0fc4fb2
11 changed files with 77 additions and 77 deletions

View File

@ -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<CIntObject*> 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<CIntObject*> 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<CIntObject*> 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};

View File

@ -70,26 +70,32 @@ public:
std::shared_ptr<IStatusBar> statusbar;
private:
Point cursorPosition;
std::vector<std::shared_ptr<IShowActivatable>> disposed;
std::atomic<bool> continueEventHandling;
typedef std::list<CIntObject*> 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<void (std::list<CIntObject*> *)> 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<std::shared_ptr<IShowActivatable>> 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

View File

@ -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<std::string> & 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)

View File

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

View File

@ -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);
}

View File

@ -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;

View File

@ -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();

View File

@ -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<double>(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<int>(px / static_cast<double>(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<double>(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)

View File

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

View File

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

View File

@ -306,7 +306,7 @@ void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCom
player = PlayerColor(1);
auto temp = std::make_shared<CInfoWindow>(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});