diff --git a/client/gui/EventDispatcher.cpp b/client/gui/EventDispatcher.cpp index 94bbfcbe0..fddd847bb 100644 --- a/client/gui/EventDispatcher.cpp +++ b/client/gui/EventDispatcher.cpp @@ -201,10 +201,20 @@ void EventDispatcher::dispatchShowPopup(const Point & position, int tolerance) void EventDispatcher::dispatchClosePopup(const Point & position) { - if (GH.windows().isTopWindowPopup()) - GH.windows().popWindows(1); + bool popupOpen = GH.windows().isTopWindowPopup(); // popup can already be closed for mouse dragging with RMB - assert(!GH.windows().isTopWindowPopup()); + auto hlp = rclickable; + + for(auto & i : hlp) + { + if(!vstd::contains(rclickable, i)) + continue; + + i->closePopupWindow(!popupOpen); + } + + if(popupOpen) + GH.windows().popWindows(1); } void EventDispatcher::handleLeftButtonClick(const Point & position, int tolerance, bool isPressed) diff --git a/client/gui/EventsReceiver.h b/client/gui/EventsReceiver.h index 5e09d800c..5c5576ede 100644 --- a/client/gui/EventsReceiver.h +++ b/client/gui/EventsReceiver.h @@ -50,6 +50,7 @@ public: virtual void clickReleased(const Point & cursorPosition, bool lastActivated); virtual void clickCancel(const Point & cursorPosition) {} virtual void showPopupWindow(const Point & cursorPosition) {} + virtual void closePopupWindow(bool alreadyClosed) {} virtual void clickDouble(const Point & cursorPosition) {} virtual void notFocusedClick() {}; diff --git a/client/mapView/MapViewActions.cpp b/client/mapView/MapViewActions.cpp index 6b2041a57..96b5564f7 100644 --- a/client/mapView/MapViewActions.cpp +++ b/client/mapView/MapViewActions.cpp @@ -80,6 +80,12 @@ void MapViewActions::showPopupWindow(const Point & cursorPosition) adventureInt->onTileRightClicked(tile); } +void MapViewActions::closePopupWindow(bool alreadyClosed) +{ + if(alreadyClosed) + dragActive = false; +} + void MapViewActions::mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) { handleHover(cursorPosition); @@ -103,6 +109,7 @@ void MapViewActions::mouseDragged(const Point & cursorPosition, const Point & la void MapViewActions::mouseDraggedPopup(const Point & cursorPosition, const Point & lastUpdateDistance) { + dragActive = true; owner.onMapSwiped(lastUpdateDistance); } diff --git a/client/mapView/MapViewActions.h b/client/mapView/MapViewActions.h index 463f70780..89fdca3e9 100644 --- a/client/mapView/MapViewActions.h +++ b/client/mapView/MapViewActions.h @@ -36,6 +36,7 @@ public: void clickReleased(const Point & cursorPosition) override; void clickCancel(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override; + void closePopupWindow(bool alreadyClosed) override; void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; void gesturePinch(const Point & centerPosition, double lastUpdateFactor) override; void hover(bool on) override; diff --git a/client/windows/InfoWindows.cpp b/client/windows/InfoWindows.cpp index 7283a1968..6e8a20e86 100644 --- a/client/windows/InfoWindows.cpp +++ b/client/windows/InfoWindows.cpp @@ -269,7 +269,14 @@ void CRClickPopupInt::mouseDraggedPopup(const Point & cursorPosition, const Poin close(); } -void CInfoBoxPopup::mouseDraggedPopup(const Point & cursorPosition, const Point & lastUpdateDistance) +template +AdventureMapPopup::AdventureMapPopup(Args&&... args) : + CWindowObject(std::forward(args)...), dragDistance(Point(0, 0)) +{ + addUsedEvents(DRAG_POPUP); +} + +void AdventureMapPopup::mouseDraggedPopup(const Point & cursorPosition, const Point & lastUpdateDistance) { if(!settings["adventure"]["rightButtonDrag"].Bool()) return; @@ -282,7 +289,7 @@ void CInfoBoxPopup::mouseDraggedPopup(const Point & cursorPosition, const Point CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town) - : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("TOWNQVBK"), position) + : AdventureMapPopup(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("TOWNQVBK"), position) { InfoAboutTown iah; LOCPLINT->cb->getTownInfo(town, iah, LOCPLINT->localState->getCurrentArmy()); //todo: should this be nearest hero? @@ -296,7 +303,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town) } CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero) - : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("HEROQVBK"), position) + : AdventureMapPopup(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("HEROQVBK"), position) { InfoAboutHero iah; LOCPLINT->cb->getHeroInfo(hero, iah, LOCPLINT->localState->getCurrentArmy()); //todo: should this be nearest hero? @@ -310,7 +317,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero) } CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr) - : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("TOWNQVBK"), position) + : AdventureMapPopup(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("TOWNQVBK"), position) { InfoAboutTown iah; LOCPLINT->cb->getTownInfo(garr, iah); @@ -324,7 +331,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr) } CInfoBoxPopup::CInfoBoxPopup(Point position, const CGCreature * creature) - : CWindowObject(RCLICK_POPUP | BORDERED, ImagePath::builtin("DIBOXBCK"), position) + : AdventureMapPopup(RCLICK_POPUP | BORDERED, ImagePath::builtin("DIBOXBCK"), position) { OBJECT_CONSTRUCTION; tooltip = std::make_shared(Point(9, 10), creature); @@ -389,7 +396,7 @@ void MinimapWithIcons::addIcon(const int3 & coordinates, const ImagePath & image } TeleporterPopup::TeleporterPopup(const Point & position, const CGTeleport * teleporter) - : CWindowObject(BORDERED | RCLICK_POPUP) + : AdventureMapPopup(BORDERED | RCLICK_POPUP) { OBJECT_CONSTRUCTION; pos.w = 322; @@ -430,7 +437,7 @@ TeleporterPopup::TeleporterPopup(const Point & position, const CGTeleport * tele } KeymasterPopup::KeymasterPopup(const Point & position, const CGKeys * keymasterOrGuard) - : CWindowObject(BORDERED | RCLICK_POPUP) + : AdventureMapPopup(BORDERED | RCLICK_POPUP) { OBJECT_CONSTRUCTION; pos.w = 322; @@ -469,7 +476,7 @@ KeymasterPopup::KeymasterPopup(const Point & position, const CGKeys * keymasterO } ObeliskPopup::ObeliskPopup(const Point & position, const CGObelisk * obelisk) - : CWindowObject(BORDERED | RCLICK_POPUP) + : AdventureMapPopup(BORDERED | RCLICK_POPUP) { OBJECT_CONSTRUCTION; pos.w = 322; diff --git a/client/windows/InfoWindows.h b/client/windows/InfoWindows.h index ad171da8b..c1e7d1375 100644 --- a/client/windows/InfoWindows.h +++ b/client/windows/InfoWindows.h @@ -93,20 +93,27 @@ public: void mouseDraggedPopup(const Point & cursorPosition, const Point & lastUpdateDistance) override; }; +/// adventure map popup +class AdventureMapPopup : public CWindowObject +{ + Point dragDistance; + +public: + template + AdventureMapPopup(Args&&... args); + void mouseDraggedPopup(const Point & cursorPosition, const Point & lastUpdateDistance) override; +}; + /// popup on adventure map for town\hero and other objects with customized popup content -class CInfoBoxPopup : public CWindowObject +class CInfoBoxPopup : public AdventureMapPopup { std::shared_ptr tooltip; - Point dragDistance; - public: CInfoBoxPopup(Point position, const CGTownInstance * town); CInfoBoxPopup(Point position, const CGHeroInstance * hero); CInfoBoxPopup(Point position, const CGGarrison * garr); CInfoBoxPopup(Point position, const CGCreature * creature); - - void mouseDraggedPopup(const Point & cursorPosition, const Point & lastUpdateDistance) override; }; /// component selection window @@ -134,7 +141,7 @@ public: void addIcon(const int3 & coordinates, const ImagePath & image); }; -class TeleporterPopup : public CWindowObject +class TeleporterPopup : public AdventureMapPopup { std::shared_ptr filledBackground; std::shared_ptr minimap; @@ -144,7 +151,7 @@ public: TeleporterPopup(const Point & position, const CGTeleport * teleporter); }; -class KeymasterPopup : public CWindowObject +class KeymasterPopup : public AdventureMapPopup { std::shared_ptr filledBackground; std::shared_ptr minimap; @@ -155,7 +162,7 @@ public: KeymasterPopup(const Point & position, const CGKeys * keymasterOrGuard); }; -class ObeliskPopup : public CWindowObject +class ObeliskPopup : public AdventureMapPopup { std::shared_ptr filledBackground; std::shared_ptr minimap; diff --git a/config/widgets/settings/settingsMainContainer.json b/config/widgets/settings/settingsMainContainer.json index 714342400..6d470c604 100644 --- a/config/widgets/settings/settingsMainContainer.json +++ b/config/widgets/settings/settingsMainContainer.json @@ -134,7 +134,7 @@ "imageOrder": [1, 0, 2, 3], "help": "core.help.320", "callback": "returnToMainMenu", - "hotkey": "settingsMainMenu" + "hotkey": "settingsToMainMenu" }, { "name": "quitButton",