Bladeren bron

Merge pull request #1513 from IvanSavenko/gui_handler_remove_current_event

Removed pointer to current SDL_Event from GuiHandler
Ivan Savenko 2 jaren geleden
bovenliggende
commit
c2c08a46bf

+ 32 - 29
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<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};

+ 18 - 14
client/gui/CGuiHandler.h

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

+ 5 - 6
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<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)

+ 1 - 3
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

+ 2 - 2
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);
 	}

+ 4 - 5
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;

+ 4 - 4
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();
 

+ 4 - 4
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<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)

+ 3 - 6
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)

+ 3 - 3
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)
 			{

+ 1 - 1
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<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});