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

View File

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

View File

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

View File

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

View File

@ -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);
}
void EventDispatcher::dispatchMouseButtonPressed(const MouseButton & button, const Point & position)
{
if (button == MouseButton::LEFT)
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(false);
if (button == MouseButton::RIGHT)
handleRightButtonClick(false);
handleLeftButtonClick(true);
}
void EventDispatcher::handleRightButtonClick(bool isPressed)
void EventDispatcher::dispatchMouseLeftButtonReleased(const Point & position)
{
handleLeftButtonClick(false);
}
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;

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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