Переглянути джерело

Enter popup await mode only if there is an active popup

Ivan Savenko 2 роки тому
батько
коміт
85a11c090e

+ 4 - 4
client/eventsSDL/InputSourceMouse.cpp

@@ -42,10 +42,10 @@ void InputSourceMouse::handleEventMouseButtonDown(const SDL_MouseButtonEvent & b
 			if(button.clicks > 1)
 				GH.events().dispatchMouseDoubleClick(position);
 			else
-				GH.events().dispatchMouseButtonPressed(MouseButton::LEFT, position);
+				GH.events().dispatchMouseLeftButtonPressed(position);
 			break;
 		case SDL_BUTTON_RIGHT:
-			GH.events().dispatchMouseButtonPressed(MouseButton::RIGHT, position);
+			GH.events().dispatchShowPopup(position);
 			break;
 		case SDL_BUTTON_MIDDLE:
 			middleClickPosition = position;
@@ -66,10 +66,10 @@ void InputSourceMouse::handleEventMouseButtonUp(const SDL_MouseButtonEvent & but
 	switch(button.button)
 	{
 		case SDL_BUTTON_LEFT:
-			GH.events().dispatchMouseButtonReleased(MouseButton::LEFT, position);
+			GH.events().dispatchMouseLeftButtonReleased(position);
 			break;
 		case SDL_BUTTON_RIGHT:
-			GH.events().dispatchMouseButtonReleased(MouseButton::RIGHT, position);
+			GH.events().dispatchClosePopup(position);
 			break;
 		case SDL_BUTTON_MIDDLE:
 			GH.events().dispatchGesturePanningEnded(middleClickPosition, position);

+ 16 - 9
client/eventsSDL/InputSourceTouch.cpp

@@ -20,6 +20,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../gui/EventDispatcher.h"
 #include "../gui/MouseButton.h"
+#include "../gui/WindowHandler.h"
 
 #include <SDL_events.h>
 #include <SDL_hints.h>
@@ -100,8 +101,10 @@ void InputSourceTouch::handleEventFingerDown(const SDL_TouchFingerEvent & tfinge
 		{
 			if(tfinger.x > 0.5)
 			{
-				MouseButton button =  tfinger.y < 0.5 ? MouseButton::RIGHT : MouseButton::LEFT;
-				GH.events().dispatchMouseButtonPressed(button, GH.getCursorPosition());
+				if (tfinger.y < 0.5)
+					GH.events().dispatchShowPopup(GH.getCursorPosition());
+				else
+					GH.events().dispatchMouseLeftButtonPressed(GH.getCursorPosition());
 			}
 			break;
 		}
@@ -138,8 +141,10 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 		{
 			if(tfinger.x > 0.5)
 			{
-				MouseButton button =  tfinger.y < 0.5 ? MouseButton::RIGHT : MouseButton::LEFT;
-				GH.events().dispatchMouseButtonReleased(button, GH.getCursorPosition());
+				if (tfinger.y < 0.5)
+					GH.events().dispatchClosePopup(GH.getCursorPosition());
+				else
+					GH.events().dispatchMouseLeftButtonReleased(GH.getCursorPosition());
 			}
 			break;
 		}
@@ -151,8 +156,8 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 		case TouchState::TAP_DOWN_SHORT:
 		{
 			GH.input().setCursorPosition(convertTouchToMouse(tfinger));
-			GH.events().dispatchMouseButtonPressed(MouseButton::LEFT, convertTouchToMouse(tfinger));
-			GH.events().dispatchMouseButtonReleased(MouseButton::LEFT, convertTouchToMouse(tfinger));
+			GH.events().dispatchMouseLeftButtonPressed(convertTouchToMouse(tfinger));
+			GH.events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger));
 			state = TouchState::IDLE;
 			break;
 		}
@@ -186,7 +191,7 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 			if (SDL_GetNumTouchFingers(tfinger.touchId) == 0)
 			{
 				GH.input().setCursorPosition(convertTouchToMouse(tfinger));
-				GH.events().dispatchMouseButtonReleased(MouseButton::RIGHT, convertTouchToMouse(tfinger));
+				GH.events().dispatchClosePopup(convertTouchToMouse(tfinger));
 				state = TouchState::IDLE;
 			}
 			break;
@@ -201,8 +206,10 @@ void InputSourceTouch::handleUpdate()
 		uint32_t currentTime = SDL_GetTicks();
 		if (currentTime > lastTapTimeTicks + params.longPressTimeMilliseconds)
 		{
-			state = TouchState::TAP_DOWN_LONG;
-			GH.events().dispatchMouseButtonPressed(MouseButton::RIGHT, GH.getCursorPosition());
+			GH.events().dispatchShowPopup(GH.getCursorPosition());
+
+			if (GH.windows().isTopWindowPopup())
+				state = TouchState::TAP_DOWN_LONG;
 		}
 	}
 }

+ 5 - 0
client/gui/CIntObject.cpp

@@ -239,6 +239,11 @@ void CIntObject::onScreenResize()
 	center(pos, true);
 }
 
+bool CIntObject::isPopupWindow() const
+{
+	return false;
+}
+
 const Rect & CIntObject::center( const Rect &r, bool propagate )
 {
 	pos.w = r.w;

+ 7 - 0
client/gui/CIntObject.h

@@ -34,6 +34,7 @@ public:
 	virtual void show(Canvas & to) = 0;
 	virtual void showAll(Canvas & to) = 0;
 
+	virtual bool isPopupWindow() const = 0;
 	virtual void onScreenResize() = 0;
 	virtual ~IShowActivatable() = default;
 };
@@ -93,10 +94,16 @@ public:
 	//request complete redraw of this object
 	void redraw() override;
 
+	/// returns true if this element is a popup window
+	/// called only for windows
+	bool isPopupWindow() const override;
+
 	/// called only for windows whenever screen size changes
 	/// default behavior is to re-center, can be overriden
 	void onScreenResize() override;
 
+	/// returns true if UI elements wants to handle event of specific type (LCLICK, RCLICK ...)
+	/// by default, usedEvents inside UI elements are always handled
 	bool receiveEvent(const Point & position, int eventType) const override;
 
 	const Rect & center(const Rect &r, bool propagate = true); //sets pos so that r will be in the center of screen, assigns sizes of r to pos, returns new position

+ 18 - 16
client/gui/EventDispatcher.cpp

@@ -14,6 +14,7 @@
 #include "FramerateManager.h"
 #include "CGuiHandler.h"
 #include "MouseButton.h"
+#include "WindowHandler.h"
 
 #include "../../lib/Point.h"
 
@@ -130,26 +131,20 @@ void EventDispatcher::dispatchMouseDoubleClick(const Point & position)
 	}
 
 	if(!doubleClicked)
-		dispatchMouseButtonPressed(MouseButton::LEFT, position);
+		handleLeftButtonClick(true);
 }
 
-void EventDispatcher::dispatchMouseButtonPressed(const MouseButton & button, const Point & position)
+void EventDispatcher::dispatchMouseLeftButtonPressed(const Point & position)
 {
-	if (button == MouseButton::LEFT)
-		handleLeftButtonClick(true);
-	if (button == MouseButton::RIGHT)
-		handleRightButtonClick(true);
+	handleLeftButtonClick(true);
 }
 
-void EventDispatcher::dispatchMouseButtonReleased(const MouseButton & button, const Point & position)
+void EventDispatcher::dispatchMouseLeftButtonReleased(const Point & position)
 {
-	if (button == MouseButton::LEFT)
-		handleLeftButtonClick(false);
-	if (button == MouseButton::RIGHT)
-		handleRightButtonClick(false);
+	handleLeftButtonClick(false);
 }
 
-void EventDispatcher::handleRightButtonClick(bool isPressed)
+void EventDispatcher::dispatchShowPopup(const Point & position)
 {
 	auto hlp = rclickable;
 	for(auto & i : hlp)
@@ -157,14 +152,21 @@ void EventDispatcher::handleRightButtonClick(bool isPressed)
 		if(!vstd::contains(rclickable, i))
 			continue;
 
-		if( isPressed && i->receiveEvent(GH.getCursorPosition(), AEventsReceiver::LCLICK))
-			i->showPopupWindow();
+		if( !i->receiveEvent(GH.getCursorPosition(), AEventsReceiver::LCLICK))
+			continue;
 
-		if(!isPressed)
-			i->closePopupWindow();
+		i->showPopupWindow();
 	}
 }
 
+void EventDispatcher::dispatchClosePopup(const Point & position)
+{
+	if (GH.windows().isTopWindowPopup())
+		GH.windows().popWindows(1);
+
+	assert(!GH.windows().isTopWindowPopup());
+}
+
 void EventDispatcher::handleLeftButtonClick(bool isPressed)
 {
 	auto hlp = lclickable;

+ 6 - 3
client/gui/EventDispatcher.h

@@ -35,7 +35,7 @@ class EventDispatcher
 	EventReceiversList panningInterested;
 
 	void handleLeftButtonClick(bool isPressed);
-	void handleRightButtonClick(bool isPressed);
+
 
 	template<typename Functor>
 	void processLists(ui16 activityFlag, const Functor & cb);
@@ -55,12 +55,15 @@ public:
 	void dispatchShortcutReleased(const std::vector<EShortcut> & shortcuts);
 
 	/// Mouse events
-	void dispatchMouseButtonPressed(const MouseButton & button, const Point & position);
-	void dispatchMouseButtonReleased(const MouseButton & button, const Point & position);
+	void dispatchMouseLeftButtonPressed(const Point & position);
+	void dispatchMouseLeftButtonReleased(const Point & position);
 	void dispatchMouseScrolled(const Point & distance, const Point & position);
 	void dispatchMouseDoubleClick(const Point & position);
 	void dispatchMouseMoved(const Point & distance);
 
+	void dispatchShowPopup(const Point & position);
+	void dispatchClosePopup(const Point & position);
+
 	void dispatchGesturePanningStarted(const Point & initialPosition);
 	void dispatchGesturePanningEnded(const Point & initialPosition, const Point & finalPosition);
 	void dispatchGesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance);

+ 0 - 1
client/gui/EventsReceiver.h

@@ -37,7 +37,6 @@ protected:
 
 	virtual void clickLeft(tribool down, bool previousState) {}
 	virtual void showPopupWindow() {}
-	virtual void closePopupWindow() {}
 	virtual void clickDouble() {}
 
 	/// Called when user pans screen by specified distance

+ 8 - 0
client/gui/WindowHandler.cpp

@@ -48,6 +48,14 @@ void WindowHandler::pushWindow(std::shared_ptr<IShowActivatable> newInt)
 	totalRedraw();
 }
 
+bool WindowHandler::isTopWindowPopup() const
+{
+	if (windowsStack.empty())
+		return false;
+
+	return windowsStack.back()->isPopupWindow();
+}
+
 void WindowHandler::popWindows(int howMany)
 {
 	if(!howMany)

+ 3 - 0
client/gui/WindowHandler.h

@@ -43,6 +43,9 @@ public:
 	/// pops one or more windows - deactivates top, deletes and removes given number of windows, activates new front
 	void popWindows(int howMany);
 
+	/// returns true if current top window is a right-click popup
+	bool isTopWindowPopup() const;
+
 	/// removes given windows from the top and activates next
 	void popWindow(std::shared_ptr<IShowActivatable> top);
 

+ 2 - 3
client/windows/CWindowObject.cpp

@@ -235,10 +235,9 @@ void CWindowObject::showAll(Canvas & to)
 		CMessage::drawBorder(color, to.getInternalSurface(), pos.w+28, pos.h+29, pos.x-14, pos.y-15);
 }
 
-void CWindowObject::closePopupWindow()
+bool CWindowObject::isPopupWindow() const
 {
-	close();
-	CCS->curh->show();
+	return options & RCLICK_POPUP;
 }
 
 CStatusbarWindow::CStatusbarWindow(int options, std::string imageName, Point centerAt) : CWindowObject(options, imageName, centerAt)

+ 1 - 1
client/windows/CWindowObject.h

@@ -28,7 +28,7 @@ protected:
 	std::shared_ptr<CPicture> background;
 
 	//Used only if RCLICK_POPUP was set
-	void closePopupWindow() override;
+	bool isPopupWindow() const override;
 	//To display border
 	void updateShadow();
 	void setBackground(std::string filename);

+ 4 - 6
client/windows/InfoWindows.cpp

@@ -288,10 +288,9 @@ void CInfoPopup::init(int x, int y)
 	vstd::amin(pos.y, GH.screenDimensions().y - bitmap->h);
 }
 
-
-void CRClickPopup::closePopupWindow()
+bool CRClickPopup::isPopupWindow() const
 {
-	close();
+	return true;
 }
 
 void CRClickPopup::close()
@@ -307,9 +306,8 @@ void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCom
 
 	auto temp = std::make_shared<CInfoWindow>(txt, player, comps);
 	temp->center(GH.getCursorPosition()); //center on mouse
-#ifdef VCMI_IOS
-    // TODO: enable also for android?
-    temp->moveBy({0, -temp->pos.h / 2});
+#ifdef VCMI_MOBILE
+	temp->moveBy({0, -temp->pos.h / 2});
 #endif
 	temp->fitToScreen(10);
 

+ 1 - 1
client/windows/InfoWindows.h

@@ -76,7 +76,7 @@ class CRClickPopup : public WindowBase
 {
 public:
 	virtual void close();
-	void closePopupWindow() override;
+	bool isPopupWindow() const override;
 
 	CRClickPopup();
 	virtual ~CRClickPopup();