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

Enter popup await mode only if there is an active popup

This commit is contained in:
Ivan Savenko 2023-06-11 20:38:42 +03:00
parent e9788e2904
commit 85a11c090e
13 changed files with 77 additions and 46 deletions

View File

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

View File

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

View File

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

View File

@ -34,6 +34,7 @@ public:
virtual void show(Canvas & to) = 0; virtual void show(Canvas & to) = 0;
virtual void showAll(Canvas & to) = 0; virtual void showAll(Canvas & to) = 0;
virtual bool isPopupWindow() const = 0;
virtual void onScreenResize() = 0; virtual void onScreenResize() = 0;
virtual ~IShowActivatable() = default; virtual ~IShowActivatable() = default;
}; };
@ -93,10 +94,16 @@ public:
//request complete redraw of this object //request complete redraw of this object
void redraw() override; 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 /// called only for windows whenever screen size changes
/// default behavior is to re-center, can be overriden /// default behavior is to re-center, can be overriden
void onScreenResize() override; 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; 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 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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,6 +43,9 @@ public:
/// pops one or more windows - deactivates top, deletes and removes given number of windows, activates new front /// pops one or more windows - deactivates top, deletes and removes given number of windows, activates new front
void popWindows(int howMany); 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 /// removes given windows from the top and activates next
void popWindow(std::shared_ptr<IShowActivatable> top); void popWindow(std::shared_ptr<IShowActivatable> top);

View File

@ -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); 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(); return options & RCLICK_POPUP;
CCS->curh->show();
} }
CStatusbarWindow::CStatusbarWindow(int options, std::string imageName, Point centerAt) : CWindowObject(options, imageName, centerAt) CStatusbarWindow::CStatusbarWindow(int options, std::string imageName, Point centerAt) : CWindowObject(options, imageName, centerAt)

View File

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

View File

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

View File

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