From 6c828d1be9e45a1cf14253a0018e8cf9fc534a9b Mon Sep 17 00:00:00 2001 From: SoundSSGood <87084363+SoundSSGood@users.noreply.github.com> Date: Sun, 19 Nov 2023 02:05:10 +0200 Subject: [PATCH] Resources trade panel --- client/widgets/CTradeBase.cpp | 46 ++++++++++---- client/widgets/CTradeBase.h | 103 ++++++++++++++++++++------------ client/windows/CTradeWindow.cpp | 97 +++++++++++++++++++++--------- 3 files changed, 167 insertions(+), 79 deletions(-) diff --git a/client/widgets/CTradeBase.cpp b/client/widgets/CTradeBase.cpp index e1e7aacde..b195d6990 100644 --- a/client/widgets/CTradeBase.cpp +++ b/client/widgets/CTradeBase.cpp @@ -20,7 +20,7 @@ #include "../../lib/CGeneralTextHandler.h" #include "../../lib/mapObjects/CGHeroInstance.h" -CTradeBase::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial) +CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial) : CIntObject(LCLICK | HOVER | SHOW_POPUP, pos) , type(EType(-1)) // set to invalid, will be corrected in setType , id(ID) @@ -38,7 +38,7 @@ CTradeBase::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool L } } -void CTradeBase::CTradeableItem::setType(EType newType) +void CTradeableItem::setType(EType newType) { if(type != newType) { @@ -57,7 +57,7 @@ void CTradeBase::CTradeableItem::setType(EType newType) } } -void CTradeBase::CTradeableItem::setID(int newID) +void CTradeableItem::setID(int newID) { if(id != newID) { @@ -76,7 +76,7 @@ void CTradeBase::CTradeableItem::setID(int newID) } } -AnimationPath CTradeBase::CTradeableItem::getFilename() +AnimationPath CTradeableItem::getFilename() { switch(type) { @@ -95,7 +95,7 @@ AnimationPath CTradeBase::CTradeableItem::getFilename() } } -int CTradeBase::CTradeableItem::getIndex() +int CTradeableItem::getIndex() { if(id < 0) return -1; @@ -116,7 +116,7 @@ int CTradeBase::CTradeableItem::getIndex() } } -void CTradeBase::CTradeableItem::showAll(Canvas & to) +void CTradeableItem::showAll(Canvas & to) { Point posToBitmap; Point posToSubCenter; @@ -154,13 +154,13 @@ void CTradeBase::CTradeableItem::showAll(Canvas & to) to.drawText(pos.topLeft() + posToSubCenter, FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, subtitle); } -void CTradeBase::CTradeableItem::clickPressed(const Point& cursorPosition) +void CTradeableItem::clickPressed(const Point & cursorPosition) { if(clickPressedCallback) clickPressedCallback(shared_from_this()); } -void CTradeBase::CTradeableItem::showAllAt(const Point& dstPos, const std::string& customSub, Canvas& to) +void CTradeableItem::showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to) { Rect oldPos = pos; std::string oldSub = subtitle; @@ -175,7 +175,7 @@ void CTradeBase::CTradeableItem::showAllAt(const Point& dstPos, const std::strin subtitle = oldSub; } -void CTradeBase::CTradeableItem::hover(bool on) +void CTradeableItem::hover(bool on) { if(!on) { @@ -198,7 +198,7 @@ void CTradeBase::CTradeableItem::hover(bool on) } } -void CTradeBase::CTradeableItem::showPopupWindow(const Point& cursorPosition) +void CTradeableItem::showPopupWindow(const Point & cursorPosition) { switch(type) { @@ -214,7 +214,7 @@ void CTradeBase::CTradeableItem::showPopupWindow(const Point& cursorPosition) } } -std::string CTradeBase::CTradeableItem::getName(int number) const +std::string CTradeableItem::getName(int number) const { switch(type) { @@ -235,7 +235,7 @@ std::string CTradeBase::CTradeableItem::getName(int number) const return ""; } -const CArtifactInstance* CTradeBase::CTradeableItem::getArtInstance() const +const CArtifactInstance * CTradeableItem::getArtInstance() const { switch(type) { @@ -247,7 +247,7 @@ const CArtifactInstance* CTradeBase::CTradeableItem::getArtInstance() const } } -void CTradeBase::CTradeableItem::setArtInstance(const CArtifactInstance * art) +void CTradeableItem::setArtInstance(const CArtifactInstance * art) { assert(type == ARTIFACT_PLACEHOLDER || type == ARTIFACT_INSTANCE); hlp = art; @@ -257,6 +257,26 @@ void CTradeBase::CTradeableItem::setArtInstance(const CArtifactInstance * art) setID(-1); } +SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updatePanelFunctor updateSubtitles) + : updateSubtitles(updateSubtitles) +{ + assert(resourcesForTrade.size() == slotsPos.size()); + OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); + + for(const auto & res : resourcesForTrade) + { + slots.emplace_back(std::make_shared(slotsPos[res.num], EType::RESOURCE, res.num, true, res.num)); + slots.back()->clickPressedCallback = clickPressedCallback; + slots.back()->pos.w = 69; slots.back()->pos.h = 66; + } +} + +void SResourcesPanel::updateSlots() +{ + if(updateSubtitles) + updateSubtitles(); +} + CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero) : market(market) , hero(hero) diff --git a/client/widgets/CTradeBase.h b/client/widgets/CTradeBase.h index 75079fe0f..79e3313a5 100644 --- a/client/widgets/CTradeBase.h +++ b/client/widgets/CTradeBase.h @@ -23,52 +23,79 @@ VCMI_LIB_NAMESPACE_END class CButton; class CTextBox; +enum EType +{ + RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE +}; + +class CTradeableItem : public CIntObject, public std::enable_shared_from_this +{ + std::shared_ptr image; + AnimationPath getFilename(); + int getIndex(); +public: + using ClickPressedFunctor = std::function)>; + + const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact + EType type; + int id; + const int serial; + const bool left; + std::string subtitle; //empty if default + ClickPressedFunctor clickPressedCallback; + + void setType(EType newType); + void setID(int newID); + + const CArtifactInstance * getArtInstance() const; + void setArtInstance(const CArtifactInstance * art); + + CFunctionList callback; + bool downSelection; + + void showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to); + + void showPopupWindow(const Point & cursorPosition) override; + void hover(bool on) override; + void showAll(Canvas & to) override; + void clickPressed(const Point & cursorPosition) override; + std::string getName(int number = -1) const; + CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial); +}; + +struct SResourcesPanel : public CIntObject +{ + using updatePanelFunctor = std::function; + + const std::vector resourcesForTrade = + { + GameResID::WOOD, GameResID::MERCURY, GameResID::ORE, + GameResID::SULFUR, GameResID::CRYSTAL, GameResID::GEMS, + GameResID::GOLD + }; + const std::vector slotsPos = + { + Point(0, 0), Point(83, 0), Point(166, 0), + Point(0, 79), Point(83, 79), Point(166, 79), + Point(83, 158) + }; + std::vector> slots; + std::function updateSubtitles; + + SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updatePanelFunctor updateSubtitles); + void updateSlots(); +}; + class CTradeBase { public: - enum EType - { - RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE - }; - - class CTradeableItem : public CIntObject, public std::enable_shared_from_this - { - std::shared_ptr image; - AnimationPath getFilename(); - int getIndex(); - public: - const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact - EType type; - int id; - const int serial; - const bool left; - std::string subtitle; //empty if default - std::function altarSlot)> clickPressedCallback; - - void setType(EType newType); - void setID(int newID); - - const CArtifactInstance* getArtInstance() const; - void setArtInstance(const CArtifactInstance * art); - - CFunctionList callback; - bool downSelection; - - void showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to); - - void showPopupWindow(const Point & cursorPosition) override; - void hover(bool on) override; - void showAll(Canvas & to) override; - void clickPressed(const Point & cursorPosition) override; - std::string getName(int number = -1) const; - CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial); - }; - const IMarket * market; const CGHeroInstance * hero; //all indexes: 1 = left, 0 = right std::array>, 2> items; + std::shared_ptr resoursesPanelPlayer; + std::shared_ptr resoursesPanelMarket; //highlighted items (nullptr if no highlight) std::shared_ptr hLeft; diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index c27ec0775..77a7af5bc 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -84,6 +84,66 @@ void CTradeWindow::initItems(bool Left) } else { + if(Left && itemsType[1] == RESOURCE) + { + resoursesPanelPlayer = std::make_shared( + [this](std::shared_ptr marketSlot) -> void + { + if(hLeft != marketSlot) + hLeft = marketSlot; + else + return; + selectionChanged(true); + }, + [this]() -> void + { + for(auto & slot : resoursesPanelPlayer->slots) + slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast(slot->serial))); + }); + resoursesPanelPlayer->moveBy(Point(39, 182)); + resoursesPanelPlayer->updateSlots(); + return; + } + if(!Left && itemsType[0] == RESOURCE) + { + resoursesPanelMarket = std::make_shared( + [this](std::shared_ptr marketSlot) -> void + { + if(hRight != marketSlot) + hRight = marketSlot; + else + return; + selectionChanged(false); + initSubs(false); + }, + [this]() -> void + { + for(auto & slot : resoursesPanelMarket->slots) + { + if(hLeft) //artifact, creature + { + int h1, h2; //hlp variables for getting offer + market->getOffer(hLeft->id, slot->id, h1, h2, mode); + if(slot->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources + { + std::ostringstream oss; + oss << h2; + if(h1 != 1) + oss << "/" << h1; + slot->subtitle = oss.str(); + } + else + slot->subtitle = CGI->generaltexth->allTexts[164]; // n/a + } + else + slot->subtitle = ""; + } + }); + resoursesPanelMarket->moveBy(Point(327, 182)); + return; + } + + std::vector *ids = getItemsIds(Left); std::vector pos; int amount = -1; @@ -185,14 +245,6 @@ void CTradeWindow::getPositionsFor(std::vector &poss, bool Left, EType typ switch(type) { - case RESOURCE: - dx = 82; - dy = 79; - x = 39; - y = 180; - h = 68; - w = 70; - break; case PLAYER: dx = 83; dy = 118; @@ -244,6 +296,15 @@ void CTradeWindow::getPositionsFor(std::vector &poss, bool Left, EType typ void CTradeWindow::initSubs(bool Left) { + if(itemsType[Left] == RESOURCE) + { + if(Left) + resoursesPanelPlayer->updateSlots(); + else + resoursesPanelMarket->updateSlots(); + return; + } + for(auto item : items[Left]) { if(Left) @@ -253,9 +314,6 @@ void CTradeWindow::initSubs(bool Left) case CREATURE: item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial))); break; - case RESOURCE: - item->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast(item->serial))); - break; } } else //right side @@ -264,23 +322,6 @@ void CTradeWindow::initSubs(bool Left) { item->subtitle = CGI->generaltexth->capColors[item->id]; } - else if(hLeft)//artifact, creature - { - int h1, h2; //hlp variables for getting offer - market->getOffer(hLeft->id, item->id, h1, h2, mode); - if(item->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources - { - std::ostringstream oss; - oss << h2; - if(h1!=1) - oss << "/" << h1; - item->subtitle = oss.str(); - } - else - item->subtitle = CGI->generaltexth->allTexts[164]; // n/a - } - else - item->subtitle = ""; } } }