瀏覽代碼

Minor fixes and cleanup

Ivan Savenko 2 年之前
父節點
當前提交
d5d0ca96a8

+ 0 - 1
client/CPlayerInterface.cpp

@@ -1513,7 +1513,6 @@ void CPlayerInterface::update()
 	assert(adventureInt);
 
 	// Handles mouse and key input
-	GH.updateTime();
 	GH.handleEvents();
 	GH.windows().simpleRedraw();
 }

+ 0 - 1
client/CPlayerInterface.h

@@ -47,7 +47,6 @@ class KeyInterested;
 class MotionInterested;
 class PlayerLocalState;
 class TimeInterested;
-class IShowable;
 
 namespace boost
 {

+ 9 - 13
client/gui/CGuiHandler.cpp

@@ -90,13 +90,10 @@ void CGuiHandler::init()
 	pointerSpeedMultiplier = settings["general"]["relativePointerSpeedMultiplier"].Float();
 }
 
-void CGuiHandler::updateTime()
-{
-	eventDispatcher().updateTime(framerateManager().getElapsedMilliseconds());
-}
-
 void CGuiHandler::handleEvents()
 {
+	eventDispatcher().dispatchTimer(framerateManager().getElapsedMilliseconds());
+
 	//player interface may want special event handling
 	if(nullptr != LOCPLINT && LOCPLINT->capturedAllEvents())
 		return;
@@ -104,7 +101,7 @@ void CGuiHandler::handleEvents()
 	boost::unique_lock<boost::mutex> lock(eventsM);
 	while(!SDLEventsQueue.empty())
 	{
-		continueEventHandling = true;
+		eventDispatcher().allowEventHandling(true);
 		SDL_Event currentEvent = SDLEventsQueue.front();
 
 		if (currentEvent.type == SDL_MOUSEMOTION)
@@ -349,7 +346,10 @@ void CGuiHandler::handleEventMouseButtonDown(SDL_Event & current)
 	switch(current.button.button)
 	{
 		case SDL_BUTTON_LEFT:
-			eventDispatcher().dispatchMouseButtonPressed(MouseButton::LEFT, Point(current.button.x, current.button.y));
+			if (current.button.clicks > 1)
+				eventDispatcher().dispatchMouseDoubleClick(Point(current.button.x, current.button.y));
+			else
+				eventDispatcher().dispatchMouseButtonPressed(MouseButton::LEFT, Point(current.button.x, current.button.y));
 			break;
 		case SDL_BUTTON_RIGHT:
 			eventDispatcher().dispatchMouseButtonPressed(MouseButton::RIGHT, Point(current.button.x, current.button.y));
@@ -460,7 +460,6 @@ void CGuiHandler::handleEventFingerUp(SDL_Event & current)
 
 void CGuiHandler::renderFrame()
 {
-
 	// Updating GUI requires locking pim mutex (that protects screen and GUI state).
 	// During game:
 	// When ending the game, the pim mutex might be hold by other thread,
@@ -498,13 +497,10 @@ void CGuiHandler::renderFrame()
 }
 
 CGuiHandler::CGuiHandler()
-	: lastClick(-500, -500)
-	, lastClickTime(0)
-	, defActionsDef(0)
+	: defActionsDef(0)
 	, captureChildren(false)
 	, multifinger(false)
 	, mouseButtonsMask(0)
-	, continueEventHandling(true)
 	, curInt(nullptr)
 	, fakeStatusBar(std::make_shared<EmptyStatusBar>())
 	, terminate_cond (new CondSh<bool>(false))
@@ -554,7 +550,7 @@ bool CGuiHandler::isKeyboardShiftDown() const
 
 void CGuiHandler::breakEventHandling()
 {
-	continueEventHandling = false;
+	eventDispatcher().allowEventHandling(false);
 }
 
 const Point & CGuiHandler::getCursorPosition() const

+ 0 - 8
client/gui/CGuiHandler.h

@@ -28,7 +28,6 @@ class IStatusBar;
 class CIntObject;
 class IUpdateable;
 class IShowActivatable;
-class IShowable;
 class IScreenHandler;
 class WindowHandler;
 class InterfaceEventDispatcher;
@@ -49,8 +48,6 @@ enum class EUserEvent
 // Handles GUI logic and drawing
 class CGuiHandler
 {
-	friend class InterfaceEventDispatcher;
-
 private:
 	/// Fake no-op version status bar, for use in windows that have no status bar
 	std::shared_ptr<IStatusBar> fakeStatusBar;
@@ -64,8 +61,6 @@ private:
 	std::unique_ptr<ShortcutHandler> shortcutsHandlerInstance;
 	std::unique_ptr<WindowHandler> windowHandlerInstance;
 
-	std::atomic<bool> continueEventHandling;
-
 	std::unique_ptr<IScreenHandler> screenHandlerInstance;
 	std::unique_ptr<FramerateManager> framerateManagerInstance;
 	std::unique_ptr<InterfaceEventDispatcher> eventDispatcherInstance;
@@ -129,8 +124,6 @@ public:
 
 	IUpdateable *curInt;
 
-	Point lastClick;
-	unsigned lastClickTime;
 	bool multifinger;
 	bool isPointerRelativeMode;
 	float pointerSpeedMultiplier;
@@ -148,7 +141,6 @@ public:
 	/// called whenever user selects different resolution, requiring to center/resize all windows
 	void onScreenResize();
 
-	void updateTime();
 	void handleEvents(); //takes events from queue and calls interested objects
 	void fakeMouseMove();
 	void breakEventHandling(); //current event won't be propagated anymore

+ 28 - 31
client/gui/CIntObject.cpp

@@ -67,6 +67,23 @@ void AEventsReceiver::deactivateEvents(ui16 what)
 	GH.eventDispatcher().handleElementDeActivate(this, what & activeState);
 }
 
+void AEventsReceiver::click(MouseButton btn, tribool down, bool previousState)
+{
+	switch(btn)
+	{
+	default:
+	case MouseButton::LEFT:
+		clickLeft(down, previousState);
+		break;
+	case MouseButton::MIDDLE:
+		clickMiddle(down, previousState);
+		break;
+	case MouseButton::RIGHT:
+		clickRight(down, previousState);
+		break;
+	}
+}
+
 CIntObject::CIntObject(int used_, Point pos_):
 	parent_m(nullptr),
 	parent(parent_m),
@@ -150,41 +167,14 @@ void CIntObject::deactivate()
 				elem->deactivate();
 }
 
-void CIntObject::click(MouseButton btn, tribool down, bool previousState)
-{
-	switch(btn)
-	{
-	default:
-	case MouseButton::LEFT:
-		clickLeft(down, previousState);
-		break;
-	case MouseButton::MIDDLE:
-		clickMiddle(down, previousState);
-		break;
-	case MouseButton::RIGHT:
-		clickRight(down, previousState);
-		break;
-	}
-}
-
-void CIntObject::printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst)
-{
-	graphics->fonts[font]->renderTextLeft(dst, text, kolor, Point(pos.x + x, pos.y + y));
-}
-
-void CIntObject::printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst)
-{
-	printAtMiddleLoc(text, Point(x,y), font, kolor, dst);
-}
-
 void CIntObject::printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color kolor, SDL_Surface * dst)
 {
 	graphics->fonts[font]->renderTextCenter(dst, text, kolor, pos.topLeft() + p);
 }
 
-void CIntObject::printAtMiddleWBLoc( const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst)
+void CIntObject::printAtMiddleWBLoc( const std::string & text, const Point &p, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst)
 {
-	graphics->fonts[font]->renderTextLinesCenter(dst, CMessage::breakText(text, charpr, font), kolor, Point(pos.x + x, pos.y + y));
+	graphics->fonts[font]->renderTextLinesCenter(dst, CMessage::breakText(text, charpr, font), kolor, pos.topLeft() + p);
 }
 
 void CIntObject::addUsedEvents(ui16 newActions)
@@ -347,6 +337,7 @@ bool CIntObject::captureThisKey(EShortcut key)
 
 CKeyShortcut::CKeyShortcut()
 	: assignedKey(EShortcut::NONE)
+	, shortcutPressed(false)
 {}
 
 CKeyShortcut::CKeyShortcut(EShortcut key)
@@ -356,14 +347,20 @@ CKeyShortcut::CKeyShortcut(EShortcut key)
 
 void CKeyShortcut::keyPressed(EShortcut key)
 {
-	if( assignedKey == key && assignedKey != EShortcut::NONE)
+	if( assignedKey == key && assignedKey != EShortcut::NONE && !shortcutPressed)
+	{
+		shortcutPressed = true;
 		clickLeft(true, false);
+	}
 }
 
 void CKeyShortcut::keyReleased(EShortcut key)
 {
-	if( assignedKey == key && assignedKey != EShortcut::NONE)
+	if( assignedKey == key && assignedKey != EShortcut::NONE && shortcutPressed)
+	{
+		shortcutPressed = false;
 		clickLeft(false, true);
+	}
 }
 
 WindowBase::WindowBase(int used_, Point pos_)

+ 34 - 91
client/gui/CIntObject.h

@@ -21,15 +21,6 @@ enum class EShortcut;
 
 using boost::logic::tribool;
 
-// Defines a activate/deactive method
-class IActivatable
-{
-public:
-	virtual void activate()=0;
-	virtual void deactivate()=0;
-	virtual ~IActivatable() = default;
-};
-
 class IUpdateable
 {
 public:
@@ -37,51 +28,21 @@ public:
 	virtual ~IUpdateable() = default;
 };
 
-// Defines a show method
-class IShowable
+class IShowActivatable
 {
 public:
+	virtual void activate()=0;
+	virtual void deactivate()=0;
+
 	virtual void redraw()=0;
 	virtual void show(SDL_Surface * to) = 0;
-	virtual void showAll(SDL_Surface * to)
-	{
-		show(to);
-	}
-	virtual ~IShowable() = default;
-};
+	virtual void showAll(SDL_Surface * to) = 0;
 
-class IShowActivatable : public IShowable, public IActivatable
-{
-public:
 	virtual void onScreenResize() = 0;
 	virtual ~IShowActivatable() = default;
 };
 
-class IEventsReceiver
-{
-public:
-	virtual void keyPressed(EShortcut key) = 0;
-	virtual void keyReleased(EShortcut key) = 0;
-	virtual bool captureThisKey(EShortcut key) = 0;
-
-	virtual void click(MouseButton btn, tribool down, bool previousState) = 0;
-	virtual void clickLeft(tribool down, bool previousState) = 0;
-	virtual void clickRight(tribool down, bool previousState) = 0;
-	virtual void clickMiddle(tribool down, bool previousState) = 0;
-
-	virtual void textInputed(const std::string & enteredText) = 0;
-	virtual void textEdited(const std::string & enteredText) = 0;
-
-	virtual void tick(uint32_t msPassed) = 0;
-	virtual void wheelScrolled(bool down, bool in) = 0;
-	virtual void mouseMoved(const Point & cursorPosition) = 0;
-	virtual void hover(bool on) = 0;
-	virtual void onDoubleClick() = 0;
-
-	virtual ~IEventsReceiver() = default;
-};
-
-class AEventsReceiver : public IEventsReceiver
+class AEventsReceiver
 {
 	friend class InterfaceEventDispatcher;
 
@@ -91,19 +52,39 @@ class AEventsReceiver : public IEventsReceiver
 	bool hoveredState; //for determining if object is hovered
 	bool strongInterestState; //if true - report all mouse movements, if not - only when hovered
 
+	void click(MouseButton btn, tribool down, bool previousState);
 protected:
 	void setMoveEventStrongInterest(bool on);
 
 	void activateEvents(ui16 what);
 	void deactivateEvents(ui16 what);
 
+	virtual void clickLeft(tribool down, bool previousState) {}
+	virtual void clickRight(tribool down, bool previousState) {}
+	virtual void clickMiddle(tribool down, bool previousState) {}
+
+	virtual void textInputed(const std::string & enteredText) {}
+	virtual void textEdited(const std::string & enteredText) {}
+
+	virtual void tick(uint32_t msPassed) {}
+	virtual void wheelScrolled(bool down, bool in) {}
+	virtual void mouseMoved(const Point & cursorPosition) {}
+	virtual void hover(bool on) {}
+	virtual void onDoubleClick() {}
+
+	virtual void keyPressed(EShortcut key) {}
+	virtual void keyReleased(EShortcut key) {}
+
+	virtual bool captureThisKey(EShortcut key) = 0;
+	virtual bool isInside(const Point & position) = 0;
+
 public:
 	AEventsReceiver();
+	virtual ~AEventsReceiver() = default;
 
 	// These are the arguments that can be used to determine what kind of input the CIntObject will receive
 	enum {LCLICK=1, RCLICK=2, HOVER=4, MOVE=8, KEYBOARD=16, TIME=32, GENERAL=64, WHEEL=128, DOUBLECLICK=256, TEXTINPUT=512, MCLICK=1024, ALL=0xffff};
 
-	virtual bool isInside(const Point & position) = 0;
 	bool isHovered() const;
 	bool isActive() const;
 	bool isActive(int flags) const;
@@ -113,7 +94,7 @@ public:
 // Base UI element
 class CIntObject : public IShowActivatable, public AEventsReceiver //interface object
 {
-	ui16 used;//change via addUsed() or delUsed
+	ui16 used;
 
 	//non-const versions of fields to allow changing them in CIntObject
 	CIntObject *parent_m; //parent object
@@ -122,16 +103,8 @@ public:
 	//redraw parent flag - this int may be semi-transparent and require redraw of parent window
 	enum {REDRAW_PARENT=8};
 	int type; //bin flags using etype
-/*
- * Functions and fields that supposed to be private but are not for now.
- * Don't use them unless you really know what they are for
- */
-	std::vector<CIntObject *> children;
-
 
-/*
- * Public interface
- */
+	std::vector<CIntObject *> children;
 
 	/// read-only parent access. May not be a "clean" solution but allows some compatibility
 	CIntObject * const & parent;
@@ -142,34 +115,13 @@ public:
 	CIntObject(int used=0, Point offset=Point());
 	virtual ~CIntObject();
 
-	void click(MouseButton btn, tribool down, bool previousState) final;
-	void clickLeft(tribool down, bool previousState) override {}
-	void clickRight(tribool down, bool previousState) override {}
-	void clickMiddle(tribool down, bool previousState) override {}
-
 	//hover handling
 	void hover (bool on) override{}
 
 	//keyboard handling
 	bool captureAllKeys; //if true, only this object should get info about pressed keys
-	void keyPressed(EShortcut key) override {}
-	void keyReleased(EShortcut key) override {}
-	bool captureThisKey(EShortcut key) override; //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
-
-	void textInputed(const std::string & enteredText) override{};
-	void textEdited(const std::string & enteredText) override{};
-
-	//mouse movement handling
-	void mouseMoved (const Point & cursorPosition) override{}
-
-	//time handling
-	void tick(uint32_t msPassed) override {}
-
-	//mouse wheel
-	void wheelScrolled(bool down, bool in) override {}
 
-	//double click
-	void onDoubleClick() override {}
+	bool captureThisKey(EShortcut key) override; //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
 
 	void addUsedEvents(ui16 newActions);
 	void removeUsedEvents(ui16 newActions);
@@ -185,7 +137,6 @@ public:
 	/// deactivates or activates UI element based on flag
 	void setEnabled(bool on);
 
-
 	// activate or deactivate object. Inactive object won't receive any input events (keyboard\mouse)
 	// usually used automatically by parent
 	void activate() override;
@@ -213,26 +164,18 @@ public:
 
 	void addChild(CIntObject *child, bool adjustPosition = false);
 	void removeChild(CIntObject *child, bool adjustPosition = false);
-	//delChild - not needed, use normal "delete child" instead
-	//delChildNull - not needed, use "vstd::clear_pointer(child)" instead
-
-/*
- * Functions that should be used only by specific GUI elements. Don't use them unless you really know why they are here
- */
 
-	//functions for printing text. Use CLabel where possible instead
-	void printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
-	void printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
+	/// functions for printing text.
+	/// Deprecated. Use CLabel where possible instead
 	void printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color color, SDL_Surface * dst);
-	void printAtMiddleWBLoc(const std::string & text, int x, int y, EFonts font, int charsPerLine, SDL_Color color, SDL_Surface * dst);
-
-	friend class CGuiHandler;
+	void printAtMiddleWBLoc(const std::string & text, const Point &p, EFonts font, int charsPerLine, SDL_Color color, SDL_Surface * dst);
 };
 
 /// Class for binding keys to left mouse button clicks
 /// Classes wanting use it should have it as one of their base classes
 class CKeyShortcut : public virtual CIntObject
 {
+	bool shortcutPressed;
 public:
 	EShortcut assignedKey;
 	CKeyShortcut();

+ 63 - 44
client/gui/InterfaceEventDispatcher.cpp

@@ -13,6 +13,11 @@
 #include "CGuiHandler.h"
 #include "FramerateManager.h"
 
+void InterfaceEventDispatcher::allowEventHandling(bool enable)
+{
+	eventHandlingAllowed = enable;
+}
+
 void InterfaceEventDispatcher::processList(const ui16 mask, const ui16 flag, CIntObjectList *lst, std::function<void (CIntObjectList *)> cb)
 {
 	if (mask & flag)
@@ -51,7 +56,7 @@ void InterfaceEventDispatcher::handleElementDeActivate(AEventsReceiver * elem, u
 	elem->activeState &= ~activityFlag;
 }
 
-void InterfaceEventDispatcher::updateTime(uint32_t msPassed)
+void InterfaceEventDispatcher::dispatchTimer(uint32_t msPassed)
 {
 	CIntObjectList hlp = timeinterested;
 	for (auto & elem : hlp)
@@ -65,34 +70,44 @@ void InterfaceEventDispatcher::dispatchShortcutPressed(const std::vector<EShortc
 {
 	bool keysCaptured = false;
 
-	for(auto i = keyinterested.begin(); i != keyinterested.end() && GH.continueEventHandling; i++)
+	for(auto & i : keyinterested)
 		for(EShortcut shortcut : shortcutsVector)
-			if((*i)->captureThisKey(shortcut))
+			if(i->captureThisKey(shortcut))
 				keysCaptured = true;
 
 	CIntObjectList miCopy = keyinterested;
 
-	for(auto i = miCopy.begin(); i != miCopy.end() && GH.continueEventHandling; i++)
+	for(auto & i : miCopy)
+	{
+		if (!eventHandlingAllowed)
+			break;
+
 		for(EShortcut shortcut : shortcutsVector)
-			if(vstd::contains(keyinterested, *i) && (!keysCaptured || (*i)->captureThisKey(shortcut)))
-					(**i).keyPressed(shortcut);
+			if(vstd::contains(keyinterested, i) && (!keysCaptured || i->captureThisKey(shortcut)))
+				i->keyPressed(shortcut);
+	}
 }
 
 void InterfaceEventDispatcher::dispatchShortcutReleased(const std::vector<EShortcut> & shortcutsVector)
 {
 	bool keysCaptured = false;
 
-	for(auto i = keyinterested.begin(); i != keyinterested.end() && GH.continueEventHandling; i++)
+	for(auto & i : keyinterested)
 		for(EShortcut shortcut : shortcutsVector)
-			if((*i)->captureThisKey(shortcut))
+			if(i->captureThisKey(shortcut))
 				keysCaptured = true;
 
 	CIntObjectList miCopy = keyinterested;
 
-	for(auto i = miCopy.begin(); i != miCopy.end() && GH.continueEventHandling; i++)
+	for(auto & i : miCopy)
+	{
+		if (!eventHandlingAllowed)
+			break;
+
 		for(EShortcut shortcut : shortcutsVector)
-			if(vstd::contains(keyinterested, *i) && (!keysCaptured || (*i)->captureThisKey(shortcut)))
-				(**i).keyReleased(shortcut);
+			if(vstd::contains(keyinterested, i) && (!keysCaptured || i->captureThisKey(shortcut)))
+				i->keyReleased(shortcut);
+	}
 }
 
 InterfaceEventDispatcher::CIntObjectList & InterfaceEventDispatcher::getListForMouseButton(MouseButton button)
@@ -109,32 +124,32 @@ InterfaceEventDispatcher::CIntObjectList & InterfaceEventDispatcher::getListForM
 	throw std::runtime_error("Invalid mouse button in getListForMouseButton");
 }
 
-void InterfaceEventDispatcher::dispatchMouseButtonPressed(const MouseButton & button, const Point & position)
+void InterfaceEventDispatcher::dispatchMouseDoubleClick(const Point & position)
 {
-//	if (button == MouseButton::LEFT)
-//	{
-//		auto doubleClicked = false;
-//		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))
-//				{
-//					(*i)->onDoubleClick();
-//					doubleClicked = true;
-//				}
-//			}
-//		}
-//
-//		lastClick = current.motion;
-//		lastClickTime = SDL_GetTicks();
-//
-//		if(doubleClicked)
-//			return;
-//	}
+	bool doubleClicked = false;
+	auto hlp = doubleClickInterested;
+
+	for(auto & i : hlp)
+	{
+		if(!vstd::contains(doubleClickInterested, i))
+			continue;
+
+		if (!eventHandlingAllowed)
+			break;
+
+		if(i->isInside(position))
+		{
+			i->onDoubleClick();
+			doubleClicked = true;
+		}
+	}
 
+	if(!doubleClicked)
+		dispatchMouseButtonPressed(MouseButton::LEFT, position);
+}
+
+void InterfaceEventDispatcher::dispatchMouseButtonPressed(const MouseButton & button, const Point & position)
+{
 	handleMouseButtonClick(getListForMouseButton(button), button, true);
 }
 
@@ -146,28 +161,32 @@ void InterfaceEventDispatcher::dispatchMouseButtonReleased(const MouseButton & b
 void InterfaceEventDispatcher::handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed)
 {
 	auto hlp = interestedObjs;
-	for(auto i = hlp.begin(); i != hlp.end() && GH.continueEventHandling; i++)
+	for(auto & i : hlp)
 	{
-		if(!vstd::contains(interestedObjs, *i)) continue;
+		if(!vstd::contains(interestedObjs, i))
+			continue;
+
+		if (!eventHandlingAllowed)
+			break;
 
-		auto prev = (*i)->isMouseButtonPressed(btn);
+		auto prev = i->isMouseButtonPressed(btn);
 		if(!isPressed)
-			(*i)->currentMouseState[btn] = isPressed;
-		if((*i)->isInside(GH.getCursorPosition()))
+			i->currentMouseState[btn] = isPressed;
+		if(i->isInside(GH.getCursorPosition()))
 		{
 			if(isPressed)
-				(*i)->currentMouseState[btn] = isPressed;
-			(*i)->click(btn, isPressed, prev);
+				i->currentMouseState[btn] = isPressed;
+			i->click(btn, isPressed, prev);
 		}
 		else if(!isPressed)
-			(*i)->click(btn, boost::logic::indeterminate, prev);
+			i->click(btn, boost::logic::indeterminate, prev);
 	}
 }
 
 void InterfaceEventDispatcher::dispatchMouseScrolled(const Point & distance, const Point & position)
 {
 	CIntObjectList hlp = wheelInterested;
-	for(auto i = hlp.begin(); i != hlp.end() && GH.continueEventHandling; i++)
+	for(auto i = hlp.begin(); i != hlp.end() && eventHandlingAllowed; i++)
 	{
 		if(!vstd::contains(wheelInterested,*i))
 			continue;

+ 6 - 1
client/gui/InterfaceEventDispatcher.h

@@ -33,6 +33,8 @@ class InterfaceEventDispatcher
 	CIntObjectList doubleClickInterested;
 	CIntObjectList textInterested;
 
+	std::atomic<bool> eventHandlingAllowed = true;
+
 	CIntObjectList & getListForMouseButton(MouseButton button);
 
 	void handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed);
@@ -41,10 +43,12 @@ class InterfaceEventDispatcher
 	void processLists(ui16 activityFlag, std::function<void(CIntObjectList *)> cb);
 
 public:
+	void allowEventHandling(bool enable);
+
 	void handleElementActivate(AEventsReceiver * elem, ui16 activityFlag);
 	void handleElementDeActivate(AEventsReceiver * elem, ui16 activityFlag);
 
-	void updateTime(uint32_t msPassed); //handles timeInterested
+	void dispatchTimer(uint32_t msPassed);
 
 	void dispatchShortcutPressed(const std::vector<EShortcut> & shortcuts);
 	void dispatchShortcutReleased(const std::vector<EShortcut> & shortcuts);
@@ -52,6 +56,7 @@ public:
 	void dispatchMouseButtonPressed(const MouseButton & button, const Point & position);
 	void dispatchMouseButtonReleased(const MouseButton & button, const Point & position);
 	void dispatchMouseScrolled(const Point & distance, const Point & position);
+	void dispatchMouseDoubleClick(const Point & position);
 	void dispatchMouseMoved(const Point & position);
 
 	void dispatchTextInput(const std::string & text);

+ 0 - 1
client/mainmenu/CMainMenu.cpp

@@ -333,7 +333,6 @@ void CMainMenu::update()
 	}
 
 	// Handles mouse and key input
-	GH.updateTime();
 	GH.handleEvents();
 
 	// check for null othervice crash on finishing a campaign

+ 1 - 1
client/windows/CTradeWindow.cpp

@@ -1479,7 +1479,7 @@ void CAltarWindow::showAll(SDL_Surface * to)
 			int dmp, val;
 			market->getOffer(pickedArt->getTypeId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP);
 			val = static_cast<int>(hero->calculateXp(val));
-			printAtMiddleLoc(std::to_string(val), 304, 498, FONT_SMALL, Colors::WHITE, to);
+			printAtMiddleLoc(std::to_string(val), Point(304, 498), FONT_SMALL, Colors::WHITE, to);
 		}
 	}
 }

+ 1 - 1
client/windows/GUIClasses.cpp

@@ -534,7 +534,7 @@ void CTavernWindow::show(SDL_Surface * to)
 			recruit->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->tavernInfo[3]) % sel->h->getNameTranslated() % sel->h->type->heroClass->getNameTranslated()));
 		}
 
-		printAtMiddleWBLoc(sel->description, 146, 395, FONT_SMALL, 200, Colors::WHITE, to);
+		printAtMiddleWBLoc(sel->description, Point(146, 395), FONT_SMALL, 200, Colors::WHITE, to);
 		CSDL_Ext::drawBorder(to,sel->pos.x-2,sel->pos.y-2,sel->pos.w+4,sel->pos.h+4,Colors::BRIGHT_YELLOW);
 	}
 }