From 29b61081f383e67874e062e856bde0c3b93dfd20 Mon Sep 17 00:00:00 2001 From: SoundSSGood <87084363+SoundSSGood@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:17:34 +0200 Subject: [PATCH 1/4] Quick backpack --- client/widgets/CArtifactsOfHeroBackpack.cpp | 140 ++++++++++++++------ client/widgets/CArtifactsOfHeroBackpack.h | 23 +++- client/widgets/CWindowWithArtifacts.cpp | 11 +- client/widgets/CWindowWithArtifacts.h | 3 +- client/windows/CHeroBackpackWindow.cpp | 55 ++++++-- client/windows/CHeroBackpackWindow.h | 15 ++- 6 files changed, 184 insertions(+), 63 deletions(-) diff --git a/client/widgets/CArtifactsOfHeroBackpack.cpp b/client/widgets/CArtifactsOfHeroBackpack.cpp index 6a487799c..4c18714f1 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.cpp +++ b/client/widgets/CArtifactsOfHeroBackpack.cpp @@ -17,60 +17,28 @@ #include "ObjectLists.h" #include "../CPlayerInterface.h" +#include "../../lib/ArtifactUtils.h" #include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/networkPacks/ArtifactLocation.h" #include "../../CCallback.h" -CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(const Point & position) +CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack() { - OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - pos += position; setRedrawParent(true); +} + +CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(const Point & position) + : CArtifactsOfHeroBackpack() +{ + pos += position; const auto backpackCap = VLC->settings()->getInteger(EGameSettings::HEROES_BACKPACK_CAP); - auto visibleCapacityMax = HERO_BACKPACK_WINDOW_SLOT_ROWS * HERO_BACKPACK_WINDOW_SLOT_COLUMNS; + auto visibleCapacityMax = slots_rows_max * slots_columns_max; if(backpackCap >= 0) visibleCapacityMax = visibleCapacityMax > backpackCap ? backpackCap : visibleCapacityMax; - backpack.resize(visibleCapacityMax); - size_t artPlaceIdx = 0; - for(auto & artPlace : backpack) - { - const auto pos = Point(slotSizeWithMargin * (artPlaceIdx % HERO_BACKPACK_WINDOW_SLOT_COLUMNS), - slotSizeWithMargin * (artPlaceIdx / HERO_BACKPACK_WINDOW_SLOT_COLUMNS)); - backpackSlotsBackgrounds.emplace_back(std::make_shared(ImagePath::builtin("heroWindow/artifactSlotEmpty"), pos)); - artPlace = std::make_shared(pos); - artPlace->setArtifact(nullptr); - artPlace->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); - artPlace->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); - artPlaceIdx++; - } - - if(backpackCap < 0 || visibleCapacityMax < backpackCap) - { - auto onCreate = [](size_t index) -> std::shared_ptr - { - return std::make_shared(); - }; - CListBoxWithCallback::MovedPosCallback posMoved = [this](size_t pos) -> void - { - scrollBackpack(static_cast(pos) * HERO_BACKPACK_WINDOW_SLOT_COLUMNS - backpackPos); - }; - backpackListBox = std::make_shared( - posMoved, onCreate, Point(0, 0), Point(0, 0), HERO_BACKPACK_WINDOW_SLOT_ROWS, 0, 0, 1, - Rect(HERO_BACKPACK_WINDOW_SLOT_COLUMNS * slotSizeWithMargin + sliderPosOffsetX, 0, HERO_BACKPACK_WINDOW_SLOT_ROWS * slotSizeWithMargin - 2, 0)); - } - - pos.w = visibleCapacityMax > HERO_BACKPACK_WINDOW_SLOT_COLUMNS ? HERO_BACKPACK_WINDOW_SLOT_COLUMNS : visibleCapacityMax; - pos.w *= slotSizeWithMargin; - if(backpackListBox) - pos.w += sliderPosOffsetX + 16; // 16 is slider width. TODO: get it from CListBox directly; - - pos.h = (visibleCapacityMax / HERO_BACKPACK_WINDOW_SLOT_COLUMNS); - if(visibleCapacityMax % HERO_BACKPACK_WINDOW_SLOT_COLUMNS != 0) - pos.h += 1; - pos.h *= slotSizeWithMargin; + initAOHbackpack(visibleCapacityMax, backpackCap < 0 || visibleCapacityMax < backpackCap); } void CArtifactsOfHeroBackpack::swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc) @@ -107,5 +75,91 @@ void CArtifactsOfHeroBackpack::updateBackpackSlots() size_t CArtifactsOfHeroBackpack::getActiveSlotRowsNum() { - return (curHero->artifactsInBackpack.size() + HERO_BACKPACK_WINDOW_SLOT_COLUMNS - 1) / HERO_BACKPACK_WINDOW_SLOT_COLUMNS; + return (curHero->artifactsInBackpack.size() + slots_columns_max - 1) / slots_columns_max; +} + +size_t CArtifactsOfHeroBackpack::getSlotsNum() +{ + return backpack.size(); +} + +void CArtifactsOfHeroBackpack::initAOHbackpack(size_t slots, bool slider) +{ + OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); + + backpack.resize(slots); + size_t artPlaceIdx = 0; + for(auto & artPlace : backpack) + { + const auto pos = Point(slotSizeWithMargin * (artPlaceIdx % slots_columns_max), + slotSizeWithMargin * (artPlaceIdx / slots_columns_max)); + backpackSlotsBackgrounds.emplace_back(std::make_shared(ImagePath::builtin("heroWindow/artifactSlotEmpty"), pos)); + artPlace = std::make_shared(pos); + artPlace->setArtifact(nullptr); + artPlace->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); + artPlace->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); + artPlaceIdx++; + } + + if(slider) + { + auto onCreate = [](size_t index) -> std::shared_ptr + { + return std::make_shared(); + }; + CListBoxWithCallback::MovedPosCallback posMoved = [this](size_t pos) -> void + { + scrollBackpack(static_cast(pos) * slots_columns_max - backpackPos); + }; + backpackListBox = std::make_shared( + posMoved, onCreate, Point(0, 0), Point(0, 0), slots_rows_max, 0, 0, 1, + Rect(slots_columns_max * slotSizeWithMargin + sliderPosOffsetX, 0, slots_rows_max * slotSizeWithMargin - 2, 0)); + } + + pos.w = slots > slots_columns_max ? slots_columns_max : slots; + pos.w *= slotSizeWithMargin; + if(slider) + pos.w += sliderPosOffsetX + 16; // 16 is slider width. TODO: get it from CListBox directly; + + pos.h = slots / slots_columns_max; + if(slots % slots_columns_max != 0) + pos.h += 1; + pos.h *= slotSizeWithMargin; +} + +CArtifactsOfHeroQuickBackpack::CArtifactsOfHeroQuickBackpack(const Point & position, const ArtifactPosition filterBySlot) +{ + pos += position; + + if(!ArtifactUtils::isSlotEquipment(filterBySlot)) + return; + + this->filterBySlot = filterBySlot; +} + +void CArtifactsOfHeroQuickBackpack::setHero(const CGHeroInstance * hero) +{ + if(curHero == hero) + return; + + curHero = hero; + if(curHero) + { + std::map filteredArts; + for(auto & slotInfo : curHero->artifactsInBackpack) + { + if(slotInfo.artifact->artType->canBePutAt(curHero, filterBySlot, true)) + filteredArts.insert(std::pair(slotInfo.artifact->artType, slotInfo.artifact)); + } + backpack.clear(); + initAOHbackpack(filteredArts.size(), false); + auto artPlace = backpack.begin(); + for(auto & art : filteredArts) + setSlotData(*artPlace++, curHero->getSlotByInstance(art.second), *curHero); + } +} + +ArtifactPosition CArtifactsOfHeroQuickBackpack::getFilterSlot() +{ + return filterBySlot; } diff --git a/client/widgets/CArtifactsOfHeroBackpack.h b/client/widgets/CArtifactsOfHeroBackpack.h index ce51531ef..35de923d1 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.h +++ b/client/widgets/CArtifactsOfHeroBackpack.h @@ -22,18 +22,33 @@ class CListBoxWithCallback; class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase { public: + CArtifactsOfHeroBackpack(); CArtifactsOfHeroBackpack(const Point & position); void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc); void pickUpArtifact(CHeroArtPlace & artPlace); void scrollBackpack(int offset) override; void updateBackpackSlots() override; size_t getActiveSlotRowsNum(); + size_t getSlotsNum(); -private: +protected: std::shared_ptr backpackListBox; std::vector> backpackSlotsBackgrounds; - const size_t HERO_BACKPACK_WINDOW_SLOT_COLUMNS = 8; - const size_t HERO_BACKPACK_WINDOW_SLOT_ROWS = 8; + const size_t slots_columns_max = 8; + const size_t slots_rows_max = 8; const int slotSizeWithMargin = 46; - const int sliderPosOffsetX = 10; + const int sliderPosOffsetX = 5; + + void initAOHbackpack(size_t slots, bool slider); +}; + +class CArtifactsOfHeroQuickBackpack : public CArtifactsOfHeroBackpack +{ +public: + CArtifactsOfHeroQuickBackpack(const Point & position, const ArtifactPosition filterBySlot); + void setHero(const CGHeroInstance * hero); + ArtifactPosition getFilterSlot(); + +private: + ArtifactPosition filterBySlot; }; diff --git a/client/widgets/CWindowWithArtifacts.cpp b/client/widgets/CWindowWithArtifacts.cpp index bf5ca043e..eab1bfccb 100644 --- a/client/widgets/CWindowWithArtifacts.cpp +++ b/client/widgets/CWindowWithArtifacts.cpp @@ -206,6 +206,14 @@ void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst } } } + else if constexpr(std::is_same_v>) + { + const auto hero = artSetPtr->getHero(); + artSetPtr->swapArtifacts(ArtifactLocation(hero->id, artPlace.slot), + ArtifactLocation(hero->id, artSetPtr->getFilterSlot())); + if(closeCallback) + closeCallback(); + } }, artSetWeak.value()); } @@ -245,7 +253,8 @@ void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsIns // Altar window, Market window right click handler else if constexpr( std::is_same_v> || - std::is_same_v>) + std::is_same_v> || + std::is_same_v>) { if(artPlace.getArt() && artPlace.text.size()) artPlace.LRClickableAreaWTextComp::showPopupWindow(GH.getCursorPosition()); diff --git a/client/widgets/CWindowWithArtifacts.h b/client/widgets/CWindowWithArtifacts.h index 777e4537d..804ae2e3e 100644 --- a/client/widgets/CWindowWithArtifacts.h +++ b/client/widgets/CWindowWithArtifacts.h @@ -24,7 +24,8 @@ public: std::weak_ptr, std::weak_ptr, std::weak_ptr, - std::weak_ptr>; + std::weak_ptr, + std::weak_ptr>; using CloseCallback = std::function; void addSet(CArtifactsOfHeroPtr artSet); diff --git a/client/windows/CHeroBackpackWindow.cpp b/client/windows/CHeroBackpackWindow.cpp index a4ff6d1c8..7e66d09f9 100644 --- a/client/windows/CHeroBackpackWindow.cpp +++ b/client/windows/CHeroBackpackWindow.cpp @@ -19,28 +19,34 @@ #include "render/Canvas.h" #include "CPlayerInterface.h" -CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero) +CHeroBackpackWindow::CHeroBackpackWindow() : CWindowObject((EOptions)0) { - OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); + OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - stretchedBackground = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, 410, 425)); + stretchedBackground = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, 0, 0)); +} + +CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero) + : CHeroBackpackWindow() +{ + OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); arts = std::make_shared(Point(windowMargin, windowMargin)); - arts->setHero(hero); addSetAndCallbacks(arts); - + arts->setHero(hero); addCloseCallback(std::bind(&CHeroBackpackWindow::close, this)); - quitButton = std::make_shared(Point(), AnimationPath::builtin("IOKAY32.def"), CButton::tooltip(""), [this]() { close(); }, EShortcut::GLOBAL_RETURN); - - stretchedBackground->pos.w = arts->pos.w + 2 * windowMargin; - stretchedBackground->pos.h = arts->pos.h + quitButton->pos.h + 3 * windowMargin; - pos.w = stretchedBackground->pos.w; - pos.h = stretchedBackground->pos.h; + init(); center(); +} - quitButton->moveBy(Point(GH.screenDimensions().x / 2 - quitButton->pos.w / 2 - quitButton->pos.x, arts->pos.h + 2 * windowMargin)); +void CHeroBackpackWindow::init() +{ + quitButton = std::make_shared(Point(), AnimationPath::builtin("IOKAY32.def"), CButton::tooltip(""), [this]() { close(); }, EShortcut::GLOBAL_RETURN); + pos.w = stretchedBackground->pos.w = arts->pos.w + 2 * windowMargin; + pos.h = stretchedBackground->pos.h = arts->pos.h + quitButton->pos.h + 3 * windowMargin; + quitButton->moveTo(Point(pos.x + pos.w / 2 - quitButton->pos.w / 2, pos.y + arts->pos.h + 2 * windowMargin)); } void CHeroBackpackWindow::showAll(Canvas & to) @@ -48,3 +54,28 @@ void CHeroBackpackWindow::showAll(Canvas & to) CIntObject::showAll(to); CMessage::drawBorder(PlayerColor(LOCPLINT->playerID), to.getInternalSurface(), pos.w+28, pos.h+29, pos.x-14, pos.y-15); } + +CHeroQuickBackpackWindow::CHeroQuickBackpackWindow(const CGHeroInstance * hero, ArtifactPosition targetSlot) + : CHeroBackpackWindow() +{ + OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); + + auto artsQuickBp = std::make_shared(Point(windowMargin, windowMargin), targetSlot); + addSetAndCallbacks(static_cast>(artsQuickBp)); + arts = artsQuickBp; + arts->setHero(hero); + addCloseCallback(std::bind(&CHeroQuickBackpackWindow::close, this)); + + init(); +} + +void CHeroQuickBackpackWindow::showAll(Canvas & to) +{ + if(arts->getSlotsNum() == 0) + { + close(); + return; + } + + CHeroBackpackWindow::showAll(to); +} diff --git a/client/windows/CHeroBackpackWindow.h b/client/windows/CHeroBackpackWindow.h index 73d736b0a..b8998867a 100644 --- a/client/windows/CHeroBackpackWindow.h +++ b/client/windows/CHeroBackpackWindow.h @@ -17,13 +17,24 @@ class CFilledTexture; class CHeroBackpackWindow : public CWindowObject, public CWindowWithArtifacts { public: + CHeroBackpackWindow(); CHeroBackpackWindow(const CGHeroInstance * hero); -private: +protected: std::shared_ptr arts; std::shared_ptr quitButton; std::shared_ptr stretchedBackground; - const int windowMargin = 10; + const int windowMargin = 5; + void init(); + void showAll(Canvas & to) override; +}; + +class CHeroQuickBackpackWindow : public CHeroBackpackWindow +{ +public: + CHeroQuickBackpackWindow(const CGHeroInstance * hero, ArtifactPosition targetSlot); + +private: void showAll(Canvas & to) override; }; From 21b02414bf33fd41948157f47fe83585be736888 Mon Sep 17 00:00:00 2001 From: SoundSSGood <87084363+SoundSSGood@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:43:02 +0200 Subject: [PATCH 2/4] Refactoring. Callbacks have been encapsulated. Added cursorPosition --- client/widgets/CArtifactHolder.cpp | 22 +++++++++++++++------ client/widgets/CArtifactHolder.h | 20 ++++++++++--------- client/widgets/CArtifactsOfHeroAltar.cpp | 6 +++--- client/widgets/CArtifactsOfHeroAltar.h | 2 +- client/widgets/CArtifactsOfHeroBackpack.cpp | 6 +++--- client/widgets/CArtifactsOfHeroBackpack.h | 2 +- client/widgets/CArtifactsOfHeroBase.cpp | 20 +++++++++---------- client/widgets/CArtifactsOfHeroBase.h | 6 +++--- client/widgets/CArtifactsOfHeroKingdom.cpp | 10 +++++----- client/widgets/CArtifactsOfHeroKingdom.h | 2 +- client/widgets/CArtifactsOfHeroMain.cpp | 6 +++--- client/widgets/CArtifactsOfHeroMain.h | 2 +- client/widgets/CArtifactsOfHeroMarket.cpp | 4 ++-- client/widgets/CArtifactsOfHeroMarket.h | 2 +- client/widgets/CWindowWithArtifacts.cpp | 16 +++++++-------- client/widgets/CWindowWithArtifacts.h | 4 ++-- client/windows/CHeroWindow.h | 1 - client/windows/CTradeWindow.cpp | 2 +- client/windows/CTradeWindow.h | 2 +- 19 files changed, 73 insertions(+), 62 deletions(-) diff --git a/client/widgets/CArtifactHolder.cpp b/client/widgets/CArtifactHolder.cpp index 334cd9f6e..162cfdff5 100644 --- a/client/widgets/CArtifactHolder.cpp +++ b/client/widgets/CArtifactHolder.cpp @@ -139,7 +139,7 @@ void CCommanderArtPlace::clickPressed(const Point & cursorPosition) LOCPLINT->showYesNoDialog(CGI->generaltexth->translate("vcmi.commanderWindow.artifactMessage"), [this]() { returnArtToHeroCallback(); }, []() {}); } -void CCommanderArtPlace::showPopupWindow(const Point & cursorPosition) +void CCommanderArtPlace::showPopupWindow(const Point& cursorPosition) { if(ourArt && text.size()) CArtPlace::showPopupWindow(cursorPosition); @@ -180,16 +180,16 @@ bool CArtPlace::isSelected() const return selection->visible; } -void CHeroArtPlace::clickPressed(const Point & cursorPosition) +void CArtPlace::clickPressed(const Point & cursorPosition) { - if(leftClickCallback) - leftClickCallback(*this); + if(clickPressedCallback) + clickPressedCallback(*this, cursorPosition); } -void CHeroArtPlace::showPopupWindow(const Point & cursorPosition) +void CArtPlace::showPopupWindow(const Point & cursorPosition) { if(showPopupCallback) - showPopupCallback(*this); + showPopupCallback(*this, cursorPosition); } void CArtPlace::showAll(Canvas & to) @@ -216,6 +216,16 @@ void CArtPlace::setArtifact(const CArtifactInstance * art) } } +void CArtPlace::setClickPressedCallback(ClickFunctor callback) +{ + clickPressedCallback = callback; +} + +void CArtPlace::setShowPopupCallback(ClickFunctor callback) +{ + showPopupCallback = callback; +} + void CHeroArtPlace::addCombinedArtInfo(std::map & arts) { for(const auto & combinedArt : arts) diff --git a/client/widgets/CArtifactHolder.h b/client/widgets/CArtifactHolder.h index 43bc4e729..4acfe86b8 100644 --- a/client/widgets/CArtifactHolder.h +++ b/client/widgets/CArtifactHolder.h @@ -32,14 +32,22 @@ public: class CArtPlace : public LRClickableAreaWTextComp { public: + using ClickFunctor = std::function; + + ArtifactPosition slot; + CArtPlace(Point position, const CArtifactInstance * art = nullptr); - const CArtifactInstance* getArt(); + const CArtifactInstance * getArt(); void lockSlot(bool on); bool isLocked() const; void selectSlot(bool on); bool isSelected() const; void showAll(Canvas & to) override; void setArtifact(const CArtifactInstance * art); + void setClickPressedCallback(ClickFunctor callback); + void setShowPopupCallback(ClickFunctor callback); + void clickPressed(const Point & cursorPosition) override; + void showPopupWindow(const Point & cursorPosition) override; protected: std::shared_ptr image; @@ -47,6 +55,8 @@ protected: int imageIndex; std::shared_ptr selection; bool locked; + ClickFunctor clickPressedCallback; + ClickFunctor showPopupCallback; void setInternals(const CArtifactInstance * artInst); }; @@ -68,15 +78,7 @@ public: class CHeroArtPlace: public CArtPlace { public: - using ClickFunctor = std::function; - - ArtifactPosition slot; - ClickFunctor leftClickCallback; - ClickFunctor showPopupCallback; - CHeroArtPlace(Point position, const CArtifactInstance * art = nullptr); - void clickPressed(const Point & cursorPosition) override; - void showPopupWindow(const Point & cursorPosition) override; void addCombinedArtInfo(std::map & arts); }; diff --git a/client/widgets/CArtifactsOfHeroAltar.cpp b/client/widgets/CArtifactsOfHeroAltar.cpp index a104974a2..e5eda3c3d 100644 --- a/client/widgets/CArtifactsOfHeroAltar.cpp +++ b/client/widgets/CArtifactsOfHeroAltar.cpp @@ -23,8 +23,8 @@ CArtifactsOfHeroAltar::CArtifactsOfHeroAltar(const Point & position) : visibleArtSet(ArtBearer::ArtBearer::HERO) { init( - std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1), - std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1), + std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2), position, std::bind(&CArtifactsOfHeroAltar::scrollBackpack, this, _1)); pickedArtFromSlot = ArtifactPosition::PRE_FIRST; @@ -69,7 +69,7 @@ void CArtifactsOfHeroAltar::scrollBackpack(int offset) redraw(); } -void CArtifactsOfHeroAltar::pickUpArtifact(CHeroArtPlace & artPlace) +void CArtifactsOfHeroAltar::pickUpArtifact(CArtPlace & artPlace) { if(const auto art = artPlace.getArt()) { diff --git a/client/widgets/CArtifactsOfHeroAltar.h b/client/widgets/CArtifactsOfHeroAltar.h index 83fd2b6f4..2dd81d68c 100644 --- a/client/widgets/CArtifactsOfHeroAltar.h +++ b/client/widgets/CArtifactsOfHeroAltar.h @@ -26,7 +26,7 @@ public: void updateWornSlots() override; void updateBackpackSlots() override; void scrollBackpack(int offset) override; - void pickUpArtifact(CHeroArtPlace & artPlace); + void pickUpArtifact(CArtPlace & artPlace); void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc); void pickedArtMoveToAltar(const ArtifactPosition & slot); void deleteFromVisible(const CArtifactInstance * artInst); diff --git a/client/widgets/CArtifactsOfHeroBackpack.cpp b/client/widgets/CArtifactsOfHeroBackpack.cpp index 4c18714f1..e16224b40 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.cpp +++ b/client/widgets/CArtifactsOfHeroBackpack.cpp @@ -46,7 +46,7 @@ void CArtifactsOfHeroBackpack::swapArtifacts(const ArtifactLocation & srcLoc, co LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc); } -void CArtifactsOfHeroBackpack::pickUpArtifact(CHeroArtPlace & artPlace) +void CArtifactsOfHeroBackpack::pickUpArtifact(CArtPlace & artPlace) { LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, artPlace.slot), ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); @@ -96,8 +96,8 @@ void CArtifactsOfHeroBackpack::initAOHbackpack(size_t slots, bool slider) backpackSlotsBackgrounds.emplace_back(std::make_shared(ImagePath::builtin("heroWindow/artifactSlotEmpty"), pos)); artPlace = std::make_shared(pos); artPlace->setArtifact(nullptr); - artPlace->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); - artPlace->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); + artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2)); + artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2)); artPlaceIdx++; } diff --git a/client/widgets/CArtifactsOfHeroBackpack.h b/client/widgets/CArtifactsOfHeroBackpack.h index 35de923d1..7e1850f10 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.h +++ b/client/widgets/CArtifactsOfHeroBackpack.h @@ -25,7 +25,7 @@ public: CArtifactsOfHeroBackpack(); CArtifactsOfHeroBackpack(const Point & position); void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc); - void pickUpArtifact(CHeroArtPlace & artPlace); + void pickUpArtifact(CArtPlace & artPlace); void scrollBackpack(int offset) override; void updateBackpackSlots() override; size_t getActiveSlotRowsNum(); diff --git a/client/widgets/CArtifactsOfHeroBase.cpp b/client/widgets/CArtifactsOfHeroBase.cpp index 319c40e2f..9c3d7665c 100644 --- a/client/widgets/CArtifactsOfHeroBase.cpp +++ b/client/widgets/CArtifactsOfHeroBase.cpp @@ -56,8 +56,8 @@ void CArtifactsOfHeroBase::setPutBackPickedArtifactCallback(PutBackPickedArtCall } void CArtifactsOfHeroBase::init( - CHeroArtPlace::ClickFunctor lClickCallback, - CHeroArtPlace::ClickFunctor showPopupCallback, + CArtPlace::ClickFunctor lClickCallback, + CArtPlace::ClickFunctor showPopupCallback, const Point & position, BpackScrollFunctor scrollCallback) { @@ -78,14 +78,14 @@ void CArtifactsOfHeroBase::init( { artPlace.second->slot = artPlace.first; artPlace.second->setArtifact(nullptr); - artPlace.second->leftClickCallback = lClickCallback; - artPlace.second->showPopupCallback = showPopupCallback; + artPlace.second->setClickPressedCallback(lClickCallback); + artPlace.second->setShowPopupCallback(showPopupCallback); } for(auto artPlace : backpack) { artPlace->setArtifact(nullptr); - artPlace->leftClickCallback = lClickCallback; - artPlace->showPopupCallback = showPopupCallback; + artPlace->setClickPressedCallback(lClickCallback); + artPlace->setShowPopupCallback(showPopupCallback); } leftBackpackRoll = std::make_shared(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(), [scrollCallback]() {scrollCallback(-1);}, EShortcut::MOVE_LEFT); rightBackpackRoll = std::make_shared(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(), [scrollCallback]() {scrollCallback(+1);}, EShortcut::MOVE_RIGHT); @@ -95,16 +95,16 @@ void CArtifactsOfHeroBase::init( setRedrawParent(true); } -void CArtifactsOfHeroBase::leftClickArtPlace(CHeroArtPlace & artPlace) +void CArtifactsOfHeroBase::leftClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition) { if(leftClickCallback) - leftClickCallback(*this, artPlace); + leftClickCallback(*this, artPlace, cursorPosition); } -void CArtifactsOfHeroBase::rightClickArtPlace(CHeroArtPlace & artPlace) +void CArtifactsOfHeroBase::rightClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition) { if(showPopupCallback) - showPopupCallback(*this, artPlace); + showPopupCallback(*this, artPlace, cursorPosition); } void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero) diff --git a/client/widgets/CArtifactsOfHeroBase.h b/client/widgets/CArtifactsOfHeroBase.h index a85b8ebff..aba6b152e 100644 --- a/client/widgets/CArtifactsOfHeroBase.h +++ b/client/widgets/CArtifactsOfHeroBase.h @@ -21,7 +21,7 @@ protected: public: using ArtPlaceMap = std::map; - using ClickFunctor = std::function; + using ClickFunctor = std::function; using PutBackPickedArtCallback = std::function; ClickFunctor leftClickCallback; @@ -30,8 +30,8 @@ public: CArtifactsOfHeroBase(); virtual void putBackPickedArtifact(); virtual void setPutBackPickedArtifactCallback(PutBackPickedArtCallback callback); - virtual void leftClickArtPlace(CHeroArtPlace & artPlace); - virtual void rightClickArtPlace(CHeroArtPlace & artPlace); + virtual void leftClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition); + virtual void rightClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition); virtual void setHero(const CGHeroInstance * hero); virtual const CGHeroInstance * getHero() const; virtual void scrollBackpack(int offset); diff --git a/client/widgets/CArtifactsOfHeroKingdom.cpp b/client/widgets/CArtifactsOfHeroKingdom.cpp index 14fd222f4..e174650c6 100644 --- a/client/widgets/CArtifactsOfHeroKingdom.cpp +++ b/client/widgets/CArtifactsOfHeroKingdom.cpp @@ -30,14 +30,14 @@ CArtifactsOfHeroKingdom::CArtifactsOfHeroKingdom(ArtPlaceMap ArtWorn, std::vecto { artPlace.second->slot = artPlace.first; artPlace.second->setArtifact(nullptr); - artPlace.second->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); - artPlace.second->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); + artPlace.second->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2)); + artPlace.second->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2)); } for(auto artPlace : backpack) { artPlace->setArtifact(nullptr); - artPlace->leftClickCallback = std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1); - artPlace->showPopupCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1); + artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2)); + artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2)); } leftBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, -1)); rightBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, +1)); @@ -55,7 +55,7 @@ void CArtifactsOfHeroKingdom::swapArtifacts(const ArtifactLocation & srcLoc, con LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc); } -void CArtifactsOfHeroKingdom::pickUpArtifact(CHeroArtPlace & artPlace) +void CArtifactsOfHeroKingdom::pickUpArtifact(CArtPlace & artPlace) { LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, artPlace.slot), ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); diff --git a/client/widgets/CArtifactsOfHeroKingdom.h b/client/widgets/CArtifactsOfHeroKingdom.h index 84f6ad185..738b21074 100644 --- a/client/widgets/CArtifactsOfHeroKingdom.h +++ b/client/widgets/CArtifactsOfHeroKingdom.h @@ -24,5 +24,5 @@ public: std::shared_ptr leftScroll, std::shared_ptr rightScroll); ~CArtifactsOfHeroKingdom(); void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc); - void pickUpArtifact(CHeroArtPlace & artPlace); + void pickUpArtifact(CArtPlace & artPlace); }; \ No newline at end of file diff --git a/client/widgets/CArtifactsOfHeroMain.cpp b/client/widgets/CArtifactsOfHeroMain.cpp index b4ac981b0..af834a1e0 100644 --- a/client/widgets/CArtifactsOfHeroMain.cpp +++ b/client/widgets/CArtifactsOfHeroMain.cpp @@ -19,8 +19,8 @@ CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position) { init( - std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1), - std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1), + std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2), position, std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1)); } @@ -35,7 +35,7 @@ void CArtifactsOfHeroMain::swapArtifacts(const ArtifactLocation & srcLoc, const LOCPLINT->cb->swapArtifacts(srcLoc, dstLoc); } -void CArtifactsOfHeroMain::pickUpArtifact(CHeroArtPlace & artPlace) +void CArtifactsOfHeroMain::pickUpArtifact(CArtPlace & artPlace) { LOCPLINT->cb->swapArtifacts(ArtifactLocation(curHero->id, artPlace.slot), ArtifactLocation(curHero->id, ArtifactPosition::TRANSITION_POS)); diff --git a/client/widgets/CArtifactsOfHeroMain.h b/client/widgets/CArtifactsOfHeroMain.h index 6e7253bbe..9e7f318dd 100644 --- a/client/widgets/CArtifactsOfHeroMain.h +++ b/client/widgets/CArtifactsOfHeroMain.h @@ -23,5 +23,5 @@ public: CArtifactsOfHeroMain(const Point & position); ~CArtifactsOfHeroMain(); void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc); - void pickUpArtifact(CHeroArtPlace & artPlace); + void pickUpArtifact(CArtPlace & artPlace); }; diff --git a/client/widgets/CArtifactsOfHeroMarket.cpp b/client/widgets/CArtifactsOfHeroMarket.cpp index 94d04f512..b172e4e77 100644 --- a/client/widgets/CArtifactsOfHeroMarket.cpp +++ b/client/widgets/CArtifactsOfHeroMarket.cpp @@ -15,8 +15,8 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position) { init( - std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1), - std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1), + std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2), position, std::bind(&CArtifactsOfHeroMarket::scrollBackpack, this, _1)); }; diff --git a/client/widgets/CArtifactsOfHeroMarket.h b/client/widgets/CArtifactsOfHeroMarket.h index c88ff0494..c8d34c399 100644 --- a/client/widgets/CArtifactsOfHeroMarket.h +++ b/client/widgets/CArtifactsOfHeroMarket.h @@ -14,7 +14,7 @@ class CArtifactsOfHeroMarket : public CArtifactsOfHeroBase { public: - std::function selectArtCallback; + std::function selectArtCallback; CArtifactsOfHeroMarket(const Point & position); void scrollBackpack(int offset) override; diff --git a/client/widgets/CWindowWithArtifacts.cpp b/client/widgets/CWindowWithArtifacts.cpp index eab1bfccb..360013438 100644 --- a/client/widgets/CWindowWithArtifacts.cpp +++ b/client/widgets/CWindowWithArtifacts.cpp @@ -48,8 +48,8 @@ void CWindowWithArtifacts::addSetAndCallbacks(CArtifactsOfHeroPtr artSet) std::visit([this, artPutBackHandler](auto artSetWeak) { auto artSet = artSetWeak.lock(); - artSet->leftClickCallback = std::bind(&CWindowWithArtifacts::leftClickArtPlaceHero, this, _1, _2); - artSet->showPopupCallback = std::bind(&CWindowWithArtifacts::rightClickArtPlaceHero, this, _1, _2); + artSet->leftClickCallback = std::bind(&CWindowWithArtifacts::leftClickArtPlaceHero, this, _1, _2, _3); + artSet->showPopupCallback = std::bind(&CWindowWithArtifacts::rightClickArtPlaceHero, this, _1, _2, _3); artSet->setPutBackPickedArtifactCallback(artPutBackHandler); }, artSet); } @@ -77,7 +77,7 @@ const CArtifactInstance * CWindowWithArtifacts::getPickedArtifact() return nullptr; } -void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace) +void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) { const auto artSetWeak = findAOHbyRef(artsInst); assert(artSetWeak.has_value()); @@ -85,7 +85,7 @@ void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst if(artPlace.isLocked()) return; - const auto checkSpecialArts = [](const CGHeroInstance * hero, CHeroArtPlace & artPlace) -> bool + const auto checkSpecialArts = [](const CGHeroInstance * hero, CArtPlace & artPlace) -> bool { if(artPlace.getArt()->getTypeId() == ArtifactID::SPELLBOOK) { @@ -217,7 +217,7 @@ void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst }, artSetWeak.value()); } -void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace) +void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) { const auto artSetWeak = findAOHbyRef(artsInst); assert(artSetWeak.has_value()); @@ -226,7 +226,7 @@ void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsIns return; std::visit( - [&artPlace](auto artSetWeak) -> void + [&artPlace, &cursorPosition](auto artSetWeak) -> void { const auto artSetPtr = artSetWeak.lock(); @@ -247,7 +247,7 @@ void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsIns return; } if(artPlace.text.size()) - artPlace.LRClickableAreaWTextComp::showPopupWindow(GH.getCursorPosition()); + artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition); } } // Altar window, Market window right click handler @@ -257,7 +257,7 @@ void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsIns std::is_same_v>) { if(artPlace.getArt() && artPlace.text.size()) - artPlace.LRClickableAreaWTextComp::showPopupWindow(GH.getCursorPosition()); + artPlace.LRClickableAreaWTextComp::showPopupWindow(cursorPosition); } }, artSetWeak.value()); } diff --git a/client/widgets/CWindowWithArtifacts.h b/client/widgets/CWindowWithArtifacts.h index 804ae2e3e..5645c8221 100644 --- a/client/widgets/CWindowWithArtifacts.h +++ b/client/widgets/CWindowWithArtifacts.h @@ -33,8 +33,8 @@ public: void addCloseCallback(CloseCallback callback); const CGHeroInstance * getHeroPickedArtifact(); const CArtifactInstance * getPickedArtifact(); - void leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace); - void rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CHeroArtPlace & artPlace); + void leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); + void rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); void artifactRemoved(const ArtifactLocation & artLoc) override; void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) override; diff --git a/client/windows/CHeroWindow.h b/client/windows/CHeroWindow.h index 94e91ad33..b8ead7a20 100644 --- a/client/windows/CHeroWindow.h +++ b/client/windows/CHeroWindow.h @@ -111,6 +111,5 @@ public: void createBackpackWindow(); //friends - friend void CHeroArtPlace::clickPressed(const Point & cursorPosition); friend class CPlayerInterface; }; diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index d5a728dcb..c27ec0775 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -331,7 +331,7 @@ void CTradeWindow::setMode(EMarketMode Mode) } } -void CTradeWindow::artifactSelected(CHeroArtPlace *slot) +void CTradeWindow::artifactSelected(CArtPlace * slot) { assert(mode == EMarketMode::ARTIFACT_RESOURCE); items[1][0]->setArtInstance(slot->getArt()); diff --git a/client/windows/CTradeWindow.h b/client/windows/CTradeWindow.h index 04ea7529c..85698c295 100644 --- a/client/windows/CTradeWindow.h +++ b/client/windows/CTradeWindow.h @@ -40,7 +40,7 @@ public: void getPositionsFor(std::vector &poss, bool Left, EType type) const; void setMode(EMarketMode Mode); //mode setter - void artifactSelected(CHeroArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot + void artifactSelected(CArtPlace * slot); //used when selling artifacts -> called when user clicked on artifact slot virtual void selectionChanged(bool side) = 0; //true == left virtual Point selectionOffset(bool Left) const = 0; virtual std::string updateSlotSubtitle(bool Left) const = 0; From 5099b52a4f4e0d870a959f57f89043b59f6580ce Mon Sep 17 00:00:00 2001 From: SoundSSGood <87084363+SoundSSGood@users.noreply.github.com> Date: Mon, 13 Nov 2023 23:16:02 +0200 Subject: [PATCH 3/4] Quick backpack. Spells on scrolls view --- client/widgets/CArtifactsOfHeroBackpack.cpp | 29 ++++++++++++++++++--- lib/CArtifactInstance.cpp | 5 ++++ lib/CArtifactInstance.h | 1 + 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/client/widgets/CArtifactsOfHeroBackpack.cpp b/client/widgets/CArtifactsOfHeroBackpack.cpp index e16224b40..4353c0ff8 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.cpp +++ b/client/widgets/CArtifactsOfHeroBackpack.cpp @@ -145,17 +145,40 @@ void CArtifactsOfHeroQuickBackpack::setHero(const CGHeroInstance * hero) curHero = hero; if(curHero) { + ArtifactID artInSlotId = ArtifactID::NONE; + SpellID scrollInSlotSpellId = SpellID::NONE; + if(auto artInSlot = curHero->getArt(filterBySlot)) + { + artInSlotId = artInSlot->getTypeId(); + scrollInSlotSpellId = artInSlot->getScrollSpellID(); + } + std::map filteredArts; for(auto & slotInfo : curHero->artifactsInBackpack) - { - if(slotInfo.artifact->artType->canBePutAt(curHero, filterBySlot, true)) + if(slotInfo.artifact->getTypeId() != artInSlotId && !slotInfo.artifact->isScroll() && + slotInfo.artifact->artType->canBePutAt(curHero, filterBySlot, true)) + { filteredArts.insert(std::pair(slotInfo.artifact->artType, slotInfo.artifact)); + } + + std::map filteredScrolls; + if(filterBySlot == ArtifactPosition::MISC1 || filterBySlot == ArtifactPosition::MISC2 || filterBySlot == ArtifactPosition::MISC3 || + filterBySlot == ArtifactPosition::MISC4 || filterBySlot == ArtifactPosition::MISC5) + { + for(auto & slotInfo : curHero->artifactsInBackpack) + { + if(slotInfo.artifact->isScroll() && slotInfo.artifact->getScrollSpellID() != scrollInSlotSpellId) + filteredScrolls.insert(std::pair(slotInfo.artifact->getScrollSpellID(), slotInfo.artifact)); + } } + backpack.clear(); - initAOHbackpack(filteredArts.size(), false); + initAOHbackpack(filteredArts.size() + filteredScrolls.size(), false); auto artPlace = backpack.begin(); for(auto & art : filteredArts) setSlotData(*artPlace++, curHero->getSlotByInstance(art.second), *curHero); + for(auto & art : filteredScrolls) + setSlotData(*artPlace++, curHero->getSlotByInstance(art.second), *curHero); } } diff --git a/lib/CArtifactInstance.cpp b/lib/CArtifactInstance.cpp index c790ca379..5c2f7a31b 100644 --- a/lib/CArtifactInstance.cpp +++ b/lib/CArtifactInstance.cpp @@ -165,6 +165,11 @@ bool CArtifactInstance::isCombined() const return artType->isCombined(); } +bool CArtifactInstance::isScroll() const +{ + return artType->isScroll(); +} + void CArtifactInstance::putAt(CArtifactSet & set, const ArtifactPosition slot) { auto placementMap = set.putArtifact(slot, this); diff --git a/lib/CArtifactInstance.h b/lib/CArtifactInstance.h index d72397afe..fbee8c8fc 100644 --- a/lib/CArtifactInstance.h +++ b/lib/CArtifactInstance.h @@ -87,6 +87,7 @@ public: bool canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot = ArtifactPosition::FIRST_AVAILABLE, bool assumeDestRemoved = false) const; bool isCombined() const; + bool isScroll() const; void putAt(CArtifactSet & set, const ArtifactPosition slot); void removeFrom(CArtifactSet & set, const ArtifactPosition slot); void move(CArtifactSet & srcSet, const ArtifactPosition srcSlot, CArtifactSet & dstSet, const ArtifactPosition dstSlot); From e5c532beb4e0b372ad72b39b955609db6bf71435 Mon Sep 17 00:00:00 2001 From: SoundSSGood <87084363+SoundSSGood@users.noreply.github.com> Date: Sun, 17 Dec 2023 16:30:19 +0200 Subject: [PATCH 4/4] gesture for quick backpack window --- client/widgets/CArtifactHolder.cpp | 14 ++++ client/widgets/CArtifactHolder.h | 3 + client/widgets/CArtifactsOfHeroAltar.cpp | 4 +- client/widgets/CArtifactsOfHeroBackpack.cpp | 81 ++++++++++++++------- client/widgets/CArtifactsOfHeroBackpack.h | 11 ++- client/widgets/CArtifactsOfHeroBase.cpp | 23 +++++- client/widgets/CArtifactsOfHeroBase.h | 9 ++- client/widgets/CArtifactsOfHeroKingdom.cpp | 9 ++- client/widgets/CArtifactsOfHeroMain.cpp | 5 +- client/widgets/CArtifactsOfHeroMarket.cpp | 4 +- client/widgets/CWindowWithArtifacts.cpp | 39 ++++++++-- client/widgets/CWindowWithArtifacts.h | 5 +- client/windows/CHeroBackpackWindow.cpp | 52 +++++++------ client/windows/CHeroBackpackWindow.h | 10 ++- lib/CArtifactInstance.cpp | 3 - 15 files changed, 188 insertions(+), 84 deletions(-) diff --git a/client/widgets/CArtifactHolder.cpp b/client/widgets/CArtifactHolder.cpp index 162cfdff5..544b6adff 100644 --- a/client/widgets/CArtifactHolder.cpp +++ b/client/widgets/CArtifactHolder.cpp @@ -192,6 +192,15 @@ void CArtPlace::showPopupWindow(const Point & cursorPosition) showPopupCallback(*this, cursorPosition); } +void CArtPlace::gesture(bool on, const Point & initialPosition, const Point & finalPosition) +{ + if(!on) + return; + + if(gestureCallback) + gestureCallback(*this, initialPosition); +} + void CArtPlace::showAll(Canvas & to) { CIntObject::showAll(to); @@ -226,6 +235,11 @@ void CArtPlace::setShowPopupCallback(ClickFunctor callback) showPopupCallback = callback; } +void CArtPlace::setGestureCallback(ClickFunctor callback) +{ + gestureCallback = callback; +} + void CHeroArtPlace::addCombinedArtInfo(std::map & arts) { for(const auto & combinedArt : arts) diff --git a/client/widgets/CArtifactHolder.h b/client/widgets/CArtifactHolder.h index 4acfe86b8..fafc50e50 100644 --- a/client/widgets/CArtifactHolder.h +++ b/client/widgets/CArtifactHolder.h @@ -46,8 +46,10 @@ public: void setArtifact(const CArtifactInstance * art); void setClickPressedCallback(ClickFunctor callback); void setShowPopupCallback(ClickFunctor callback); + void setGestureCallback(ClickFunctor callback); void clickPressed(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override; + void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; protected: std::shared_ptr image; @@ -57,6 +59,7 @@ protected: bool locked; ClickFunctor clickPressedCallback; ClickFunctor showPopupCallback; + ClickFunctor gestureCallback; void setInternals(const CArtifactInstance * artInst); }; diff --git a/client/widgets/CArtifactsOfHeroAltar.cpp b/client/widgets/CArtifactsOfHeroAltar.cpp index e5eda3c3d..bda990634 100644 --- a/client/widgets/CArtifactsOfHeroAltar.cpp +++ b/client/widgets/CArtifactsOfHeroAltar.cpp @@ -23,8 +23,8 @@ CArtifactsOfHeroAltar::CArtifactsOfHeroAltar(const Point & position) : visibleArtSet(ArtBearer::ArtBearer::HERO) { init( - std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2), - std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2), position, std::bind(&CArtifactsOfHeroAltar::scrollBackpack, this, _1)); pickedArtFromSlot = ArtifactPosition::PRE_FIRST; diff --git a/client/widgets/CArtifactsOfHeroBackpack.cpp b/client/widgets/CArtifactsOfHeroBackpack.cpp index 4353c0ff8..e8387528a 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.cpp +++ b/client/widgets/CArtifactsOfHeroBackpack.cpp @@ -23,18 +23,18 @@ #include "../../CCallback.h" -CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack() +CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax) + : slotsColumnsMax(slotsColumnsMax) + , slotsRowsMax(slotsRowsMax) { setRedrawParent(true); } -CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(const Point & position) - : CArtifactsOfHeroBackpack() +CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack() + : CArtifactsOfHeroBackpack(8, 8) { - pos += position; - const auto backpackCap = VLC->settings()->getInteger(EGameSettings::HEROES_BACKPACK_CAP); - auto visibleCapacityMax = slots_rows_max * slots_columns_max; + auto visibleCapacityMax = slotsRowsMax * slotsColumnsMax; if(backpackCap >= 0) visibleCapacityMax = visibleCapacityMax > backpackCap ? backpackCap : visibleCapacityMax; @@ -75,7 +75,7 @@ void CArtifactsOfHeroBackpack::updateBackpackSlots() size_t CArtifactsOfHeroBackpack::getActiveSlotRowsNum() { - return (curHero->artifactsInBackpack.size() + slots_columns_max - 1) / slots_columns_max; + return (curHero->artifactsInBackpack.size() + slotsColumnsMax - 1) / slotsColumnsMax; } size_t CArtifactsOfHeroBackpack::getSlotsNum() @@ -91,13 +91,13 @@ void CArtifactsOfHeroBackpack::initAOHbackpack(size_t slots, bool slider) size_t artPlaceIdx = 0; for(auto & artPlace : backpack) { - const auto pos = Point(slotSizeWithMargin * (artPlaceIdx % slots_columns_max), - slotSizeWithMargin * (artPlaceIdx / slots_columns_max)); + const auto pos = Point(slotSizeWithMargin * (artPlaceIdx % slotsColumnsMax), + slotSizeWithMargin * (artPlaceIdx / slotsColumnsMax)); backpackSlotsBackgrounds.emplace_back(std::make_shared(ImagePath::builtin("heroWindow/artifactSlotEmpty"), pos)); artPlace = std::make_shared(pos); artPlace->setArtifact(nullptr); - artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2)); - artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2)); + artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2)); + artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2)); artPlaceIdx++; } @@ -109,27 +109,36 @@ void CArtifactsOfHeroBackpack::initAOHbackpack(size_t slots, bool slider) }; CListBoxWithCallback::MovedPosCallback posMoved = [this](size_t pos) -> void { - scrollBackpack(static_cast(pos) * slots_columns_max - backpackPos); + scrollBackpack(static_cast(pos) * slotsColumnsMax - backpackPos); }; backpackListBox = std::make_shared( - posMoved, onCreate, Point(0, 0), Point(0, 0), slots_rows_max, 0, 0, 1, - Rect(slots_columns_max * slotSizeWithMargin + sliderPosOffsetX, 0, slots_rows_max * slotSizeWithMargin - 2, 0)); + posMoved, onCreate, Point(0, 0), Point(0, 0), slotsRowsMax, 0, 0, 1, + Rect(slotsColumnsMax * slotSizeWithMargin + sliderPosOffsetX, 0, slotsRowsMax * slotSizeWithMargin - 2, 0)); } - pos.w = slots > slots_columns_max ? slots_columns_max : slots; + pos.w = slots > slotsColumnsMax ? slotsColumnsMax : slots; pos.w *= slotSizeWithMargin; if(slider) pos.w += sliderPosOffsetX + 16; // 16 is slider width. TODO: get it from CListBox directly; - - pos.h = slots / slots_columns_max; - if(slots % slots_columns_max != 0) - pos.h += 1; - pos.h *= slotSizeWithMargin; + pos.h = calcRows(slots) * slotSizeWithMargin; } -CArtifactsOfHeroQuickBackpack::CArtifactsOfHeroQuickBackpack(const Point & position, const ArtifactPosition filterBySlot) +size_t CArtifactsOfHeroBackpack::calcRows(size_t slots) { - pos += position; + size_t rows = 0; + if(slotsColumnsMax != 0) + { + rows = slots / slotsColumnsMax; + if(slots % slotsColumnsMax != 0) + rows += 1; + } + return rows; +} + +CArtifactsOfHeroQuickBackpack::CArtifactsOfHeroQuickBackpack(const ArtifactPosition filterBySlot) + : CArtifactsOfHeroBackpack(0, 0) +{ + assert(filterBySlot != ArtifactPosition::FIRST_AVAILABLE); if(!ArtifactUtils::isSlotEquipment(filterBySlot)) return; @@ -153,12 +162,12 @@ void CArtifactsOfHeroQuickBackpack::setHero(const CGHeroInstance * hero) scrollInSlotSpellId = artInSlot->getScrollSpellID(); } - std::map filteredArts; + std::map filteredArts; for(auto & slotInfo : curHero->artifactsInBackpack) if(slotInfo.artifact->getTypeId() != artInSlotId && !slotInfo.artifact->isScroll() && slotInfo.artifact->artType->canBePutAt(curHero, filterBySlot, true)) { - filteredArts.insert(std::pair(slotInfo.artifact->artType, slotInfo.artifact)); + filteredArts.insert(std::pair(slotInfo.artifact->getTypeId(), slotInfo.artifact)); } std::map filteredScrolls; @@ -173,7 +182,10 @@ void CArtifactsOfHeroQuickBackpack::setHero(const CGHeroInstance * hero) } backpack.clear(); - initAOHbackpack(filteredArts.size() + filteredScrolls.size(), false); + auto requiredSlots = filteredArts.size() + filteredScrolls.size(); + slotsColumnsMax = ceilf(sqrtf(requiredSlots)); + slotsRowsMax = calcRows(requiredSlots); + initAOHbackpack(requiredSlots, false); auto artPlace = backpack.begin(); for(auto & art : filteredArts) setSlotData(*artPlace++, curHero->getSlotByInstance(art.second), *curHero); @@ -186,3 +198,22 @@ ArtifactPosition CArtifactsOfHeroQuickBackpack::getFilterSlot() { return filterBySlot; } + +void CArtifactsOfHeroQuickBackpack::selectSlotAt(const Point & position) +{ + for(auto & artPlace : backpack) + artPlace->selectSlot(artPlace->pos.isInside(position)); +} + +void CArtifactsOfHeroQuickBackpack::swapSelected() +{ + ArtifactLocation backpackLoc(curHero->id, ArtifactPosition::PRE_FIRST); + for(auto & artPlace : backpack) + if(artPlace->isSelected()) + { + backpackLoc.slot = artPlace->slot; + break; + } + if(backpackLoc.slot != ArtifactPosition::PRE_FIRST && filterBySlot != ArtifactPosition::PRE_FIRST && curHero) + swapArtifacts(backpackLoc, ArtifactLocation(curHero->id, filterBySlot)); +} \ No newline at end of file diff --git a/client/widgets/CArtifactsOfHeroBackpack.h b/client/widgets/CArtifactsOfHeroBackpack.h index 7e1850f10..f8598fcd9 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.h +++ b/client/widgets/CArtifactsOfHeroBackpack.h @@ -22,8 +22,8 @@ class CListBoxWithCallback; class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase { public: + CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax); CArtifactsOfHeroBackpack(); - CArtifactsOfHeroBackpack(const Point & position); void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc); void pickUpArtifact(CArtPlace & artPlace); void scrollBackpack(int offset) override; @@ -34,20 +34,23 @@ public: protected: std::shared_ptr backpackListBox; std::vector> backpackSlotsBackgrounds; - const size_t slots_columns_max = 8; - const size_t slots_rows_max = 8; + size_t slotsColumnsMax; + size_t slotsRowsMax; const int slotSizeWithMargin = 46; const int sliderPosOffsetX = 5; void initAOHbackpack(size_t slots, bool slider); + size_t calcRows(size_t slots); }; class CArtifactsOfHeroQuickBackpack : public CArtifactsOfHeroBackpack { public: - CArtifactsOfHeroQuickBackpack(const Point & position, const ArtifactPosition filterBySlot); + CArtifactsOfHeroQuickBackpack(const ArtifactPosition filterBySlot); void setHero(const CGHeroInstance * hero); ArtifactPosition getFilterSlot(); + void selectSlotAt(const Point & position); + void swapSelected(); private: ArtifactPosition filterBySlot; diff --git a/client/widgets/CArtifactsOfHeroBase.cpp b/client/widgets/CArtifactsOfHeroBase.cpp index 9c3d7665c..520e3b1a1 100644 --- a/client/widgets/CArtifactsOfHeroBase.cpp +++ b/client/widgets/CArtifactsOfHeroBase.cpp @@ -95,18 +95,24 @@ void CArtifactsOfHeroBase::init( setRedrawParent(true); } -void CArtifactsOfHeroBase::leftClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition) +void CArtifactsOfHeroBase::clickPrassedArtPlace(CArtPlace & artPlace, const Point & cursorPosition) { - if(leftClickCallback) - leftClickCallback(*this, artPlace, cursorPosition); + if(clickPressedCallback) + clickPressedCallback(*this, artPlace, cursorPosition); } -void CArtifactsOfHeroBase::rightClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition) +void CArtifactsOfHeroBase::showPopupArtPlace(CArtPlace & artPlace, const Point & cursorPosition) { if(showPopupCallback) showPopupCallback(*this, artPlace, cursorPosition); } +void CArtifactsOfHeroBase::gestureArtPlace(CArtPlace & artPlace, const Point & cursorPosition) +{ + if(gestureCallback) + gestureCallback(*this, artPlace, cursorPosition); +} + void CArtifactsOfHeroBase::setHero(const CGHeroInstance * hero) { curHero = hero; @@ -241,6 +247,15 @@ const CArtifactInstance * CArtifactsOfHeroBase::getPickedArtifact() return curHero->getArt(ArtifactPosition::TRANSITION_POS); } +void CArtifactsOfHeroBase::addGestureCallback(CArtPlace::ClickFunctor callback) +{ + for(auto & artPlace : artWorn) + { + artPlace.second->setGestureCallback(callback); + artPlace.second->addUsedEvents(GESTURE); + } +} + void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosition & slot, const CArtifactSet & artSet) { // Spurious call from artifactMoved in attempt to update hidden backpack slot diff --git a/client/widgets/CArtifactsOfHeroBase.h b/client/widgets/CArtifactsOfHeroBase.h index aba6b152e..f124146ef 100644 --- a/client/widgets/CArtifactsOfHeroBase.h +++ b/client/widgets/CArtifactsOfHeroBase.h @@ -24,14 +24,16 @@ public: using ClickFunctor = std::function; using PutBackPickedArtCallback = std::function; - ClickFunctor leftClickCallback; + ClickFunctor clickPressedCallback; ClickFunctor showPopupCallback; + ClickFunctor gestureCallback; CArtifactsOfHeroBase(); virtual void putBackPickedArtifact(); virtual void setPutBackPickedArtifactCallback(PutBackPickedArtCallback callback); - virtual void leftClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition); - virtual void rightClickArtPlace(CArtPlace & artPlace, const Point & cursorPosition); + virtual void clickPrassedArtPlace(CArtPlace & artPlace, const Point & cursorPosition); + virtual void showPopupArtPlace(CArtPlace & artPlace, const Point & cursorPosition); + virtual void gestureArtPlace(CArtPlace & artPlace, const Point & cursorPosition); virtual void setHero(const CGHeroInstance * hero); virtual const CGHeroInstance * getHero() const; virtual void scrollBackpack(int offset); @@ -42,6 +44,7 @@ public: virtual void updateBackpackSlots(); virtual void updateSlot(const ArtifactPosition & slot); virtual const CArtifactInstance * getPickedArtifact(); + void addGestureCallback(CArtPlace::ClickFunctor callback); protected: const CGHeroInstance * curHero; diff --git a/client/widgets/CArtifactsOfHeroKingdom.cpp b/client/widgets/CArtifactsOfHeroKingdom.cpp index e174650c6..5d6e1e02b 100644 --- a/client/widgets/CArtifactsOfHeroKingdom.cpp +++ b/client/widgets/CArtifactsOfHeroKingdom.cpp @@ -30,14 +30,15 @@ CArtifactsOfHeroKingdom::CArtifactsOfHeroKingdom(ArtPlaceMap ArtWorn, std::vecto { artPlace.second->slot = artPlace.first; artPlace.second->setArtifact(nullptr); - artPlace.second->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2)); - artPlace.second->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2)); + artPlace.second->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2)); + artPlace.second->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2)); } + addGestureCallback(std::bind(&CArtifactsOfHeroBase::gestureArtPlace, this, _1, _2)); for(auto artPlace : backpack) { artPlace->setArtifact(nullptr); - artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2)); - artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2)); + artPlace->setClickPressedCallback(std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2)); + artPlace->setShowPopupCallback(std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2)); } leftBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, -1)); rightBackpackRoll->addCallback(std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, +1)); diff --git a/client/widgets/CArtifactsOfHeroMain.cpp b/client/widgets/CArtifactsOfHeroMain.cpp index af834a1e0..326eff818 100644 --- a/client/widgets/CArtifactsOfHeroMain.cpp +++ b/client/widgets/CArtifactsOfHeroMain.cpp @@ -19,10 +19,11 @@ CArtifactsOfHeroMain::CArtifactsOfHeroMain(const Point & position) { init( - std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2), - std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2), position, std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1)); + addGestureCallback(std::bind(&CArtifactsOfHeroBase::gestureArtPlace, this, _1, _2)); } CArtifactsOfHeroMain::~CArtifactsOfHeroMain() diff --git a/client/widgets/CArtifactsOfHeroMarket.cpp b/client/widgets/CArtifactsOfHeroMarket.cpp index b172e4e77..0f71aca12 100644 --- a/client/widgets/CArtifactsOfHeroMarket.cpp +++ b/client/widgets/CArtifactsOfHeroMarket.cpp @@ -15,8 +15,8 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position) { init( - std::bind(&CArtifactsOfHeroBase::leftClickArtPlace, this, _1, _2), - std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), + std::bind(&CArtifactsOfHeroBase::showPopupArtPlace, this, _1, _2), position, std::bind(&CArtifactsOfHeroMarket::scrollBackpack, this, _1)); }; diff --git a/client/widgets/CWindowWithArtifacts.cpp b/client/widgets/CWindowWithArtifacts.cpp index 360013438..360d896de 100644 --- a/client/widgets/CWindowWithArtifacts.cpp +++ b/client/widgets/CWindowWithArtifacts.cpp @@ -23,6 +23,7 @@ #include "../windows/CHeroWindow.h" #include "../windows/CSpellWindow.h" #include "../windows/GUIClasses.h" +#include "../windows/CHeroBackpackWindow.h" #include "../CPlayerInterface.h" #include "../CGameInfo.h" @@ -39,18 +40,19 @@ void CWindowWithArtifacts::addSet(CArtifactsOfHeroPtr artSet) void CWindowWithArtifacts::addSetAndCallbacks(CArtifactsOfHeroPtr artSet) { - CArtifactsOfHeroBase::PutBackPickedArtCallback artPutBackHandler = []() -> void + CArtifactsOfHeroBase::PutBackPickedArtCallback artPutBackFunctor = []() -> void { CCS->curh->dragAndDropCursor(nullptr); }; addSet(artSet); - std::visit([this, artPutBackHandler](auto artSetWeak) + std::visit([this, artPutBackFunctor](auto artSetWeak) { auto artSet = artSetWeak.lock(); - artSet->leftClickCallback = std::bind(&CWindowWithArtifacts::leftClickArtPlaceHero, this, _1, _2, _3); - artSet->showPopupCallback = std::bind(&CWindowWithArtifacts::rightClickArtPlaceHero, this, _1, _2, _3); - artSet->setPutBackPickedArtifactCallback(artPutBackHandler); + artSet->clickPressedCallback = std::bind(&CWindowWithArtifacts::clickPressedArtPlaceHero, this, _1, _2, _3); + artSet->showPopupCallback = std::bind(&CWindowWithArtifacts::showPopupArtPlaceHero, this, _1, _2, _3); + artSet->gestureCallback = std::bind(&CWindowWithArtifacts::gestureArtPlaceHero, this, _1, _2, _3); + artSet->setPutBackPickedArtifactCallback(artPutBackFunctor); }, artSet); } @@ -77,7 +79,7 @@ const CArtifactInstance * CWindowWithArtifacts::getPickedArtifact() return nullptr; } -void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) +void CWindowWithArtifacts::clickPressedArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) { const auto artSetWeak = findAOHbyRef(artsInst); assert(artSetWeak.has_value()); @@ -217,7 +219,7 @@ void CWindowWithArtifacts::leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst }, artSetWeak.value()); } -void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) +void CWindowWithArtifacts::showPopupArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) { const auto artSetWeak = findAOHbyRef(artsInst); assert(artSetWeak.has_value()); @@ -262,6 +264,29 @@ void CWindowWithArtifacts::rightClickArtPlaceHero(CArtifactsOfHeroBase & artsIns }, artSetWeak.value()); } +void CWindowWithArtifacts::gestureArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition) +{ + const auto artSetWeak = findAOHbyRef(artsInst); + assert(artSetWeak.has_value()); + if(artPlace.isLocked()) + return; + + std::visit( + [&artPlace, cursorPosition](auto artSetWeak) -> void + { + const auto artSetPtr = artSetWeak.lock(); + if constexpr( + std::is_same_v> || + std::is_same_v>) + { + GH.windows().createAndPushWindow(artSetPtr->getHero(), artPlace.slot); + auto backpackWindow = GH.windows().topWindow(); + backpackWindow->moveTo(cursorPosition - Point(1, 1)); + backpackWindow->fitToScreen(15); + } + }, artSetWeak.value()); +} + void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc) { updateSlots(); diff --git a/client/widgets/CWindowWithArtifacts.h b/client/widgets/CWindowWithArtifacts.h index 5645c8221..2cd2ddea4 100644 --- a/client/widgets/CWindowWithArtifacts.h +++ b/client/widgets/CWindowWithArtifacts.h @@ -33,8 +33,9 @@ public: void addCloseCallback(CloseCallback callback); const CGHeroInstance * getHeroPickedArtifact(); const CArtifactInstance * getPickedArtifact(); - void leftClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); - void rightClickArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); + void clickPressedArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); + void showPopupArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); + void gestureArtPlaceHero(CArtifactsOfHeroBase & artsInst, CArtPlace & artPlace, const Point & cursorPosition); void artifactRemoved(const ArtifactLocation & artLoc) override; void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) override; diff --git a/client/windows/CHeroBackpackWindow.cpp b/client/windows/CHeroBackpackWindow.cpp index 7e66d09f9..82186774d 100644 --- a/client/windows/CHeroBackpackWindow.cpp +++ b/client/windows/CHeroBackpackWindow.cpp @@ -19,34 +19,22 @@ #include "render/Canvas.h" #include "CPlayerInterface.h" -CHeroBackpackWindow::CHeroBackpackWindow() +CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero) : CWindowObject((EOptions)0) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); stretchedBackground = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, 0, 0)); -} - -CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero) - : CHeroBackpackWindow() -{ - OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - - arts = std::make_shared(Point(windowMargin, windowMargin)); + arts = std::make_shared(); + arts->moveBy(Point(windowMargin, windowMargin)); addSetAndCallbacks(arts); arts->setHero(hero); addCloseCallback(std::bind(&CHeroBackpackWindow::close, this)); - - init(); - center(); -} - -void CHeroBackpackWindow::init() -{ quitButton = std::make_shared(Point(), AnimationPath::builtin("IOKAY32.def"), CButton::tooltip(""), [this]() { close(); }, EShortcut::GLOBAL_RETURN); pos.w = stretchedBackground->pos.w = arts->pos.w + 2 * windowMargin; pos.h = stretchedBackground->pos.h = arts->pos.h + quitButton->pos.h + 3 * windowMargin; quitButton->moveTo(Point(pos.x + pos.w / 2 - quitButton->pos.w / 2, pos.y + arts->pos.h + 2 * windowMargin)); + center(); } void CHeroBackpackWindow::showAll(Canvas & to) @@ -56,26 +44,44 @@ void CHeroBackpackWindow::showAll(Canvas & to) } CHeroQuickBackpackWindow::CHeroQuickBackpackWindow(const CGHeroInstance * hero, ArtifactPosition targetSlot) - : CHeroBackpackWindow() + : CWindowObject((EOptions)0) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - auto artsQuickBp = std::make_shared(Point(windowMargin, windowMargin), targetSlot); - addSetAndCallbacks(static_cast>(artsQuickBp)); - arts = artsQuickBp; + stretchedBackground = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, 0, 0)); + arts = std::make_shared(targetSlot); + arts->moveBy(Point(windowMargin, windowMargin)); + addSetAndCallbacks(static_cast>(arts)); arts->setHero(hero); addCloseCallback(std::bind(&CHeroQuickBackpackWindow::close, this)); + addUsedEvents(GESTURE); + pos.w = stretchedBackground->pos.w = arts->pos.w + 2 * windowMargin; + pos.h = stretchedBackground->pos.h = arts->pos.h + windowMargin; +} - init(); +void CHeroQuickBackpackWindow::gesture(bool on, const Point & initialPosition, const Point & finalPosition) +{ + if(on) + return; + + arts->swapSelected(); + close(); +} + +void CHeroQuickBackpackWindow::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +{ + arts->selectSlotAt(currentPosition); + redraw(); } void CHeroQuickBackpackWindow::showAll(Canvas & to) { if(arts->getSlotsNum() == 0) { + // Dirty solution for closing that window close(); return; } - - CHeroBackpackWindow::showAll(to); + CMessage::drawBorder(PlayerColor(LOCPLINT->playerID), to.getInternalSurface(), pos.w + 28, pos.h + 29, pos.x - 14, pos.y - 15); + CIntObject::showAll(to); } diff --git a/client/windows/CHeroBackpackWindow.h b/client/windows/CHeroBackpackWindow.h index b8998867a..894d13343 100644 --- a/client/windows/CHeroBackpackWindow.h +++ b/client/windows/CHeroBackpackWindow.h @@ -17,7 +17,6 @@ class CFilledTexture; class CHeroBackpackWindow : public CWindowObject, public CWindowWithArtifacts { public: - CHeroBackpackWindow(); CHeroBackpackWindow(const CGHeroInstance * hero); protected: @@ -26,15 +25,20 @@ protected: std::shared_ptr stretchedBackground; const int windowMargin = 5; - void init(); void showAll(Canvas & to) override; }; -class CHeroQuickBackpackWindow : public CHeroBackpackWindow +class CHeroQuickBackpackWindow : public CWindowObject, public CWindowWithArtifacts { public: CHeroQuickBackpackWindow(const CGHeroInstance * hero, ArtifactPosition targetSlot); + void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; + void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; private: + std::shared_ptr arts; + std::shared_ptr stretchedBackground; + const int windowMargin = 5; + void showAll(Canvas & to) override; }; diff --git a/lib/CArtifactInstance.cpp b/lib/CArtifactInstance.cpp index 5c2f7a31b..0928b2308 100644 --- a/lib/CArtifactInstance.cpp +++ b/lib/CArtifactInstance.cpp @@ -64,10 +64,7 @@ SpellID CScrollArtifactInstance::getScrollSpellID() const auto artInst = static_cast(this); const auto bonus = artInst->getBonusLocalFirst(Selector::type()(BonusType::SPELL)); if(!bonus) - { - logMod->warn("Warning: %s doesn't bear any spell!", artInst->nodeName()); return SpellID::NONE; - } return bonus->subtype.as(); }