diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 73f21b800..b7fe6167f 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -130,7 +130,7 @@ set(client_SRCS widgets/markets/CFreelancerGuild.cpp widgets/markets/CMarketResources.cpp widgets/markets/CTransferResources.cpp - widgets/markets/CTradeBase.cpp + widgets/markets/CMarketBase.cpp widgets/markets/TradePanels.cpp windows/CCastleInterface.cpp @@ -318,7 +318,7 @@ set(client_HEADERS widgets/markets/CFreelancerGuild.h widgets/markets/CMarketResources.h widgets/markets/CTransferResources.h - widgets/markets/CTradeBase.h + widgets/markets/CMarketBase.h widgets/markets/TradePanels.h windows/CCastleInterface.h diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 1666d9d72..b69cc6199 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -216,6 +216,12 @@ void CButton::setActOnDown(bool on) actOnDown = on; } +void CButton::setHelp(const std::pair & help) +{ + hoverTexts[0] = help.first; + helpBox = help.second; +} + void CButton::block(bool on) { if(on || getState() == EButtonState::BLOCKED) //dont change button state if unblock requested, but it's not blocked diff --git a/client/widgets/Buttons.h b/client/widgets/Buttons.h index 5a629c4c8..a3797d49b 100644 --- a/client/widgets/Buttons.h +++ b/client/widgets/Buttons.h @@ -98,6 +98,7 @@ public: void setHoverable(bool on); void setSoundDisabled(bool on); void setActOnDown(bool on); + void setHelp(const std::pair & help); /// State modifiers bool isBlocked(); diff --git a/client/widgets/CArtifactsOfHeroBackpack.cpp b/client/widgets/CArtifactsOfHeroBackpack.cpp index 88a82b2cb..5121c4f1f 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.cpp +++ b/client/widgets/CArtifactsOfHeroBackpack.cpp @@ -56,11 +56,11 @@ void CArtifactsOfHeroBackpack::onSliderMoved(int newVal) redraw(); } -void CArtifactsOfHeroBackpack::updateBackpackSlots() +void CArtifactsOfHeroBackpack::updateBackpackSlots(const std::optional & removedSlot) { if(backpackListBox) backpackListBox->resize(getActiveSlotRowsNum()); - CArtifactsOfHeroBase::updateBackpackSlots(); + CArtifactsOfHeroBase::updateBackpackSlots(removedSlot); } size_t CArtifactsOfHeroBackpack::getActiveSlotRowsNum() diff --git a/client/widgets/CArtifactsOfHeroBackpack.h b/client/widgets/CArtifactsOfHeroBackpack.h index 1f6b1cf20..598d99660 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.h +++ b/client/widgets/CArtifactsOfHeroBackpack.h @@ -24,8 +24,8 @@ class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase public: CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax); CArtifactsOfHeroBackpack(); - void onSliderMoved(int newVal); - void updateBackpackSlots() override; + void onSliderMoved(int newVal);; + void updateBackpackSlots(const std::optional & removedSlot = std::nullopt) override; size_t getActiveSlotRowsNum(); size_t getSlotsNum(); diff --git a/client/widgets/CArtifactsOfHeroBase.cpp b/client/widgets/CArtifactsOfHeroBase.cpp index fddddf73c..435b6fddb 100644 --- a/client/widgets/CArtifactsOfHeroBase.cpp +++ b/client/widgets/CArtifactsOfHeroBase.cpp @@ -180,7 +180,7 @@ void CArtifactsOfHeroBase::updateWornSlots() updateSlot(place.first); } -void CArtifactsOfHeroBase::updateBackpackSlots() +void CArtifactsOfHeroBase::updateBackpackSlots(const std::optional & removedSlot) { ArtifactPosition slot = ArtifactPosition::BACKPACK_START; for(const auto & artPlace : backpack) diff --git a/client/widgets/CArtifactsOfHeroBase.h b/client/widgets/CArtifactsOfHeroBase.h index 9a219000a..92c9dda58 100644 --- a/client/widgets/CArtifactsOfHeroBase.h +++ b/client/widgets/CArtifactsOfHeroBase.h @@ -41,7 +41,7 @@ public: virtual void unmarkSlots(); virtual ArtPlacePtr getArtPlace(const ArtifactPosition & slot); virtual void updateWornSlots(); - virtual void updateBackpackSlots(); + virtual void updateBackpackSlots(const std::optional & removedSlot = std::nullopt); virtual void updateSlot(const ArtifactPosition & slot); virtual const CArtifactInstance * getPickedArtifact(); void addGestureCallback(CArtPlace::ClickFunctor callback); diff --git a/client/widgets/CArtifactsOfHeroMarket.cpp b/client/widgets/CArtifactsOfHeroMarket.cpp index 3fccd62de..0d0f78f46 100644 --- a/client/widgets/CArtifactsOfHeroMarket.cpp +++ b/client/widgets/CArtifactsOfHeroMarket.cpp @@ -12,7 +12,7 @@ #include "../../lib/mapObjects/CGHeroInstance.h" -CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position) +CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position, const int selectionWidth) { init( std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), @@ -21,9 +21,9 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position) std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1)); for(const auto & [slot, artPlace] : artWorn) - artPlace->setSelectionWidth(2); + artPlace->setSelectionWidth(selectionWidth); for(auto artPlace : backpack) - artPlace->setSelectionWidth(2); + artPlace->setSelectionWidth(selectionWidth); }; void CArtifactsOfHeroMarket::scrollBackpack(bool left) diff --git a/client/widgets/CArtifactsOfHeroMarket.h b/client/widgets/CArtifactsOfHeroMarket.h index 68aee92e0..0c7d1fedd 100644 --- a/client/widgets/CArtifactsOfHeroMarket.h +++ b/client/widgets/CArtifactsOfHeroMarket.h @@ -16,6 +16,6 @@ class CArtifactsOfHeroMarket : public CArtifactsOfHeroBase public: std::function selectArtCallback; - CArtifactsOfHeroMarket(const Point & position); + CArtifactsOfHeroMarket(const Point & position, const int selectionWidth); void scrollBackpack(bool left) override; }; diff --git a/client/widgets/CWindowWithArtifacts.cpp b/client/widgets/CWindowWithArtifacts.cpp index 7d6979f5c..6fc1a49ff 100644 --- a/client/widgets/CWindowWithArtifacts.cpp +++ b/client/widgets/CWindowWithArtifacts.cpp @@ -277,7 +277,7 @@ void CWindowWithArtifacts::gestureArtPlaceHero(CArtifactsOfHeroBase & artsInst, void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc) { - updateSlots(); + updateSlots(artLoc.slot); } void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) @@ -361,14 +361,14 @@ void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation & artLoc) updateSlots(); } -void CWindowWithArtifacts::updateSlots() +void CWindowWithArtifacts::updateSlots(const ArtifactPosition & removedSlot) { - auto updateSlotBody = [](auto artSetWeak) -> void + auto updateSlotBody = [removedSlot](auto artSetWeak) -> void { if(const auto artSetPtr = artSetWeak.lock()) { artSetPtr->updateWornSlots(); - artSetPtr->updateBackpackSlots(); + artSetPtr->updateBackpackSlots(removedSlot); artSetPtr->redraw(); } }; diff --git a/client/widgets/CWindowWithArtifacts.h b/client/widgets/CWindowWithArtifacts.h index 6a1ca1841..66e55266a 100644 --- a/client/widgets/CWindowWithArtifacts.h +++ b/client/widgets/CWindowWithArtifacts.h @@ -46,7 +46,7 @@ protected: std::vector artSets; CloseCallback closeCallback; - void updateSlots(); + void updateSlots(const ArtifactPosition & removedSlot = ArtifactPosition::PRE_FIRST); std::optional> getState(); std::optional findAOHbyRef(CArtifactsOfHeroBase & artsInst); void markPossibleSlots(); diff --git a/client/widgets/Slider.cpp b/client/widgets/Slider.cpp index 68b81bbe8..2c866ff47 100644 --- a/client/widgets/Slider.cpp +++ b/client/widgets/Slider.cpp @@ -175,7 +175,7 @@ bool CSlider::receiveEvent(const Point &position, int eventType) const return testTarget.isInside(position); } -CSlider::CSlider(Point position, int totalw, const std::function & Moved, int Capacity, int Amount, int Value, Orientation orientation, CSlider::EStyle style) +CSlider::CSlider(Point position, int totalw, const SliderMovingFunctor & Moved, int Capacity, int Amount, int Value, Orientation orientation, CSlider::EStyle style) : Scrollable(LCLICK | DRAG, position, orientation ), capacity(Capacity), amount(Amount), diff --git a/client/widgets/Slider.h b/client/widgets/Slider.h index b6e8be677..88a580187 100644 --- a/client/widgets/Slider.h +++ b/client/widgets/Slider.h @@ -75,13 +75,15 @@ public: void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; void showAll(Canvas & to) override; + using SliderMovingFunctor = std::function; + /// @param position coordinates of slider /// @param length length of slider ribbon, including left/right buttons /// @param Moved function that will be called whenever slider moves /// @param Capacity maximal number of visible at once elements /// @param Amount total amount of elements, including not visible /// @param Value starting position - CSlider(Point position, int length, const std::function & Moved, int Capacity, int Amount, + CSlider(Point position, int length, const SliderMovingFunctor & Moved, int Capacity, int Amount, int Value, Orientation orientation, EStyle style = BROWN); ~CSlider(); }; diff --git a/client/widgets/markets/CAltarArtifacts.cpp b/client/widgets/markets/CAltarArtifacts.cpp index 12163c5a4..f9ced7550 100644 --- a/client/widgets/markets/CAltarArtifacts.cpp +++ b/client/widgets/markets/CAltarArtifacts.cpp @@ -26,16 +26,16 @@ #include "../../../lib/mapObjects/CGMarket.h" CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero, [this](){return CAltarArtifacts::getSelectionParams();}) + : CMarketBase(market, hero, [this](){return CAltarArtifacts::getSelectionParams();}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - assert(market); + assert(dynamic_cast(market)); auto altarObj = dynamic_cast(market); altarId = altarObj->id; altarArtifacts = altarObj; - deal = std::make_shared(dealButtonPos, AnimationPath::builtin("ALTSACR.DEF"), + deal = std::make_shared(Point(269, 520), AnimationPath::builtin("ALTSACR.DEF"), CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); }); labels.emplace_back(std::make_shared(450, 32, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477])); labels.emplace_back(std::make_shared(302, 424, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478])); @@ -60,7 +60,7 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * offerTradePanel->updateSlotsCallback = std::bind(&CAltarArtifacts::updateAltarSlots, this); offerTradePanel->moveTo(pos.topLeft() + Point(315, 52)); - CTradeBase::updateSelected(); + CMarketBase::updateSelected(); CAltarArtifacts::deselect(); }; @@ -75,8 +75,8 @@ TExpType CAltarArtifacts::calcExpAltarForHero() void CAltarArtifacts::deselect() { - CTradeBase::deselect(); - expForHero->setText(std::to_string(0)); + CMarketBase::deselect(); + CExperienceAltar::deselect(); tradeSlotsMap.clear(); // The event for removing artifacts from the altar will not be triggered. Therefore, we clean the altar immediately. for(auto & slot : offerTradePanel->slots) @@ -86,9 +86,10 @@ void CAltarArtifacts::deselect() } } -void CAltarArtifacts::updateSlots() +void CAltarArtifacts::update() { - CExperienceAltar::updateSlots(); + CMarketBase::update(); + CExperienceAltar::update(); if(const auto art = hero->getArt(ArtifactPosition::TRANSITION_POS)) { hRight = offerTradePanel->selectedSlot; @@ -189,7 +190,7 @@ void CAltarArtifacts::putBackArtifacts() LOCPLINT->cb->bulkMoveArtifacts(altarId, heroArts->getHero()->id, false, true, true); } -CTradeBase::SelectionParams CAltarArtifacts::getSelectionParams() const +CMarketBase::SelectionParams CAltarArtifacts::getSelectionParams() const { if(hRight) return std::make_tuple( diff --git a/client/widgets/markets/CAltarArtifacts.h b/client/widgets/markets/CAltarArtifacts.h index e7de8d7c6..2a9f61a85 100644 --- a/client/widgets/markets/CAltarArtifacts.h +++ b/client/widgets/markets/CAltarArtifacts.h @@ -10,7 +10,7 @@ #pragma once #include "../CArtifactsOfHeroAltar.h" -#include "CTradeBase.h" +#include "CMarketBase.h" class CAltarArtifacts : public CExperienceAltar { @@ -19,7 +19,7 @@ public: TExpType calcExpAltarForHero() override; void deselect() override; void makeDeal() override; - void updateSlots() override; + void update() override; void sacrificeAll() override; void sacrificeBackpack(); std::shared_ptr getAOHset() const; @@ -33,7 +33,7 @@ private: std::map, const CArtifactInstance*> tradeSlotsMap; void updateAltarSlots(); - CTradeBase::SelectionParams getSelectionParams() const override; + CMarketBase::SelectionParams getSelectionParams() const override; void onSlotClickPressed(const std::shared_ptr & altarSlot, std::shared_ptr & hCurSlot) override; TExpType calcExpCost(ArtifactID id); }; diff --git a/client/widgets/markets/CAltarCreatures.cpp b/client/widgets/markets/CAltarCreatures.cpp index 5d6fa6db1..61a7f3df5 100644 --- a/client/widgets/markets/CAltarCreatures.cpp +++ b/client/widgets/markets/CAltarCreatures.cpp @@ -13,7 +13,6 @@ #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" -#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" @@ -26,18 +25,19 @@ #include "../../../lib/mapObjects/CGMarket.h" CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero, [this](){return CAltarCreatures::getSelectionParams();}) + : CMarketBase(market, hero, [this](){return CAltarCreatures::getSelectionParams();}) + , CMarketSlider(std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1)) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); - deal = std::make_shared(dealButtonPos, AnimationPath::builtin("ALTSACR.DEF"), + deal = std::make_shared(dealButtonPosWithSlider, AnimationPath::builtin("ALTSACR.DEF"), CGI->generaltexth->zelp[584], [this]() {CAltarCreatures::makeDeal();}); labels.emplace_back(std::make_shared(155, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated()))); labels.emplace_back(std::make_shared(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479])); texts.emplace_back(std::make_unique(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW)); - offerSlider = std::make_shared(Point(231, 481), 137, std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL); - maxAmount = std::make_shared(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, offerSlider)); + offerSlider->moveTo(pos.topLeft() + Point(231, 481)); + maxAmount->setHelp(CGI->generaltexth->zelp[578]); unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0); expPerUnit.resize(GameConstants::ARMY_SIZE, 0); @@ -81,7 +81,7 @@ void CAltarCreatures::readExpValues() } } -void CAltarCreatures::updateControls() +void CAltarCreatures::highlightingChanged() { int sliderAmount = 0; if(hLeft) @@ -111,19 +111,21 @@ void CAltarCreatures::updateControls() if(hLeft) offerSlider->scrollTo(unitsOnAltar[hLeft->serial]); maxAmount->block(offerSlider->getAmount() == 0); + updateSelected(); } -void CAltarCreatures::updateSlots() +void CAltarCreatures::update() { - CExperienceAltar::updateSlots(); + CMarketBase::update(); + CExperienceAltar::update(); assert(bidTradePanel->slots.size() == offerTradePanel->slots.size()); } void CAltarCreatures::deselect() { - CTradeBase::deselect(); - updateSelected(); - expForHero->setText(std::to_string(0)); + CMarketBase::deselect(); + CExperienceAltar::deselect(); + CMarketSlider::deselect(); } TExpType CAltarCreatures::calcExpAltarForHero() @@ -139,8 +141,6 @@ TExpType CAltarCreatures::calcExpAltarForHero() void CAltarCreatures::makeDeal() { - deselect(); - std::vector ids; std::vector toSacrifice; @@ -163,9 +163,10 @@ void CAltarCreatures::makeDeal() heroSlot->setType(EType::CREATURE_PLACEHOLDER); heroSlot->subtitle->clear(); } + deselect(); } -CTradeBase::SelectionParams CAltarCreatures::getSelectionParams() const +CMarketBase::SelectionParams CAltarCreatures::getSelectionParams() const { std::optional bidSelected = std::nullopt; std::optional offerSelected = std::nullopt; @@ -197,7 +198,7 @@ void CAltarCreatures::sacrificeAll() if(hRight) offerSlider->scrollTo(unitsOnAltar[hRight->serial]); - offerTradePanel->updateSlots(); + offerTradePanel->update(); updateSelected(); deal->block(calcExpAltarForHero() == 0); @@ -218,8 +219,7 @@ void CAltarCreatures::onOfferSliderMoved(int newVal) if(hRight) updateAltarSlot(hRight); deal->block(calcExpAltarForHero() == 0); - updateControls(); - updateSelected(); + highlightingChanged(); redraw(); } @@ -230,7 +230,7 @@ void CAltarCreatures::onSlotClickPressed(const std::shared_ptr & auto * oppositeSlot = &hLeft; auto oppositePanel = bidTradePanel; - CTradeBase::onSlotClickPressed(newSlot, hCurSlot); + CMarketBase::onSlotClickPressed(newSlot, hCurSlot); if(hCurSlot == hLeft) { oppositeSlot = &hRight; @@ -244,8 +244,7 @@ void CAltarCreatures::onSlotClickPressed(const std::shared_ptr & break; } assert(oppositeNewSlot); - CTradeBase::onSlotClickPressed(oppositeNewSlot, *oppositeSlot); - updateControls(); - updateSelected(); + CMarketBase::onSlotClickPressed(oppositeNewSlot, *oppositeSlot); + highlightingChanged(); redraw(); } diff --git a/client/widgets/markets/CAltarCreatures.h b/client/widgets/markets/CAltarCreatures.h index 6e8d5ae26..08e9a3d1e 100644 --- a/client/widgets/markets/CAltarCreatures.h +++ b/client/widgets/markets/CAltarCreatures.h @@ -9,13 +9,13 @@ */ #pragma once -#include "CTradeBase.h" +#include "CMarketBase.h" -class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling +class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling, public CMarketSlider { public: CAltarCreatures(const IMarket * market, const CGHeroInstance * hero); - void updateSlots() override; + void update() override; void deselect() override; TExpType calcExpAltarForHero() override; void makeDeal() override; @@ -25,10 +25,10 @@ private: std::vector unitsOnAltar; std::vector expPerUnit; - CTradeBase::SelectionParams getSelectionParams() const override; + CMarketBase::SelectionParams getSelectionParams() const override; void updateAltarSlot(const std::shared_ptr & slot); void readExpValues(); - void updateControls(); - void onOfferSliderMoved(int newVal); + void highlightingChanged(); + void onOfferSliderMoved(int newVal) override; void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) override; }; diff --git a/client/widgets/markets/CArtifactsBuying.cpp b/client/widgets/markets/CArtifactsBuying.cpp index d7545110f..382fdf80c 100644 --- a/client/widgets/markets/CArtifactsBuying.cpp +++ b/client/widgets/markets/CArtifactsBuying.cpp @@ -13,7 +13,6 @@ #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" -#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" @@ -26,16 +25,19 @@ #include "../../../lib/mapObjects/CGTownInstance.h" CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero, [this](){return CArtifactsBuying::getSelectionParams();}) + : CMarketBase(market, hero, [this](){return CArtifactsBuying::getSelectionParams();}) , CResourcesSelling([this](const std::shared_ptr & heroSlot){CArtifactsBuying::onSlotClickPressed(heroSlot, hLeft);}) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); - assert(dynamic_cast(market)); - labels.emplace_back(std::make_shared(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, - (*CGI->townh)[dynamic_cast(market)->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated())); - deal = std::make_shared(Point(270, 520), AnimationPath::builtin("TPMRKB.DEF"), - CGI->generaltexth->zelp[595], [this]() {CArtifactsBuying::makeDeal(); }); + std::string title; + if(auto townMarket = dynamic_cast(market)) + title = (*CGI->townh)[townMarket->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated(); + else + title = "Black market"; // find string allTexts!! + labels.emplace_back(std::make_shared(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title)); + deal = std::make_shared(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"), + CGI->generaltexth->zelp[595], [this](){CArtifactsBuying::makeDeal();}); labels.emplace_back(std::make_shared(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168])); // Player's resources @@ -49,7 +51,7 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance CArtifactsBuying::onSlotClickPressed(newSlot, hRight); }, [this]() { - CTradeBase::updateSubtitles(EMarketMode::RESOURCE_ARTIFACT); + CMarketBase::updateSubtitles(EMarketMode::RESOURCE_ARTIFACT); }, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT)); offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr & slot) { @@ -57,8 +59,8 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance }; offerTradePanel->moveTo(pos.topLeft() + Point(328, 181)); - CTradeBase::updateSlots(); - CTradeBase::deselect(); + CMarketBase::update(); + CMarketBase::deselect(); } void CArtifactsBuying::makeDeal() @@ -67,7 +69,7 @@ void CArtifactsBuying::makeDeal() deselect(); } -CTradeBase::SelectionParams CArtifactsBuying::getSelectionParams() const +CMarketBase::SelectionParams CArtifactsBuying::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( @@ -77,12 +79,8 @@ CTradeBase::SelectionParams CArtifactsBuying::getSelectionParams() const return std::make_tuple(std::nullopt, std::nullopt); } -void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) +void CArtifactsBuying::highlightingChanged() { - if(newSlot == hCurSlot) - return; - - CTradeBase::onSlotClickPressed(newSlot, hCurSlot); if(hLeft) { if(hRight) @@ -90,8 +88,18 @@ void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::RESOURCE_ARTIFACT); deal->block(LOCPLINT->cb->getResourceAmount(GameResID(hLeft->id)) >= bidQty ? false : true); } - updateSelected(); - offerTradePanel->updateSlots(); + offerTradePanel->update(); } + updateSelected(); +} + +void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) +{ + assert(newSlot); + if(newSlot == hCurSlot) + return; + + CMarketBase::onSlotClickPressed(newSlot, hCurSlot); + highlightingChanged(); redraw(); } diff --git a/client/widgets/markets/CArtifactsBuying.h b/client/widgets/markets/CArtifactsBuying.h index 26f20b197..bcd8ec683 100644 --- a/client/widgets/markets/CArtifactsBuying.h +++ b/client/widgets/markets/CArtifactsBuying.h @@ -9,7 +9,7 @@ */ #pragma once -#include "CTradeBase.h" +#include "CMarketBase.h" class CArtifactsBuying : public CResourcesSelling { @@ -18,6 +18,7 @@ public: void makeDeal() override; private: - CTradeBase::SelectionParams getSelectionParams() const override; - void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); + CMarketBase::SelectionParams getSelectionParams() const override; + void highlightingChanged(); + void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); }; diff --git a/client/widgets/markets/CArtifactsSelling.cpp b/client/widgets/markets/CArtifactsSelling.cpp index c0e5d194d..d68e8b364 100644 --- a/client/widgets/markets/CArtifactsSelling.cpp +++ b/client/widgets/markets/CArtifactsSelling.cpp @@ -13,7 +13,6 @@ #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" -#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" @@ -25,21 +24,31 @@ #include "../../../lib/CGeneralTextHandler.h" #include "../../../lib/mapObjects/CGHeroInstance.h" #include "../../../lib/mapObjects/CGMarket.h" +#include "../../../lib/mapObjects/CGTownInstance.h" CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero, [this](){return CArtifactsSelling::getSelectionParams();}) + : CMarketBase(market, hero, [this](){return CArtifactsSelling::getSelectionParams();}) , CResourcesBuying( [this](const std::shared_ptr & resSlot){CArtifactsSelling::onSlotClickPressed(resSlot, hRight);}, - [this](){CTradeBase::updateSubtitles(EMarketMode::ARTIFACT_RESOURCE);}) + [this](){CMarketBase::updateSubtitles(EMarketMode::ARTIFACT_RESOURCE);}) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); - deal = std::make_shared(Point(270, 520), AnimationPath::builtin("TPMRKB.DEF"), + labels.emplace_back(std::make_shared(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, + (*CGI->townh)[dynamic_cast(market)->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated())); + labels.push_back(std::make_shared(155, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated()))); + deal = std::make_shared(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();}); bidSelectedSlot = std::make_shared(Rect(Point(123, 470), Point(69, 66)), EType::ARTIFACT_TYPE, 0, 0); + // Market resources panel + assert(offerTradePanel); + offerTradePanel->moveTo(pos.topLeft() + Point(326, 184)); + offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(409, 473)); + offerTradePanel->selectedSlot->subtitle->moveBy(Point(0, 1)); + // Hero's artifacts - heroArts = std::make_shared(Point(-361, 46)); + heroArts = std::make_shared(Point(-361, 46), offerTradePanel->selectionWidth); heroArts->setHero(hero); heroArts->selectArtCallback = [this](CArtPlace * artPlace) { @@ -49,29 +58,18 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc bidSelectedSlot->setID(artForTrade->getTypeId().num); hLeft = bidSelectedSlot; selectedHeroSlot = artPlace->slot; - if(hRight) - { // dublicate - this->market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE); - deal->block(false); - } - CArtifactsSelling::updateSelected(); - offerTradePanel->updateSlots(); + CArtifactsSelling::highlightingChanged(); + offerTradePanel->update(); redraw(); }; - // Market resources panel - assert(offerTradePanel); - offerTradePanel->moveTo(pos.topLeft() + Point(326, 184)); - offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(409, 473)); - offerTradePanel->selectedSlot->subtitle->moveBy(Point(0, 1)); - CArtifactsSelling::updateSelected(); CArtifactsSelling::deselect(); } void CArtifactsSelling::deselect() { - CTradeBase::deselect(); + CMarketBase::deselect(); selectedHeroSlot = ArtifactPosition::PRE_FIRST; heroArts->unmarkSlots(); } @@ -85,7 +83,7 @@ void CArtifactsSelling::makeDeal() void CArtifactsSelling::updateSelected() { - CTradeBase::updateSelected(); + CMarketBase::updateSelected(); if(hLeft && hRight) { @@ -101,11 +99,16 @@ void CArtifactsSelling::updateSelected() } } -void CArtifactsSelling::updateSlots() +void CArtifactsSelling::update() { - CTradeBase::updateSlots(); + CMarketBase::update(); if(selectedHeroSlot != ArtifactPosition::PRE_FIRST) { + if(selectedHeroSlot.num >= ArtifactPosition::BACKPACK_START + hero->artifactsInBackpack.size()) + { + selectedHeroSlot = ArtifactPosition::BACKPACK_START; + deselect(); + } if(hero->getArt(selectedHeroSlot) == nullptr) deselect(); } @@ -116,7 +119,7 @@ std::shared_ptr CArtifactsSelling::getAOHset() const return heroArts; } -CTradeBase::SelectionParams CArtifactsSelling::getSelectionParams() const +CMarketBase::SelectionParams CArtifactsSelling::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( @@ -127,21 +130,23 @@ CTradeBase::SelectionParams CArtifactsSelling::getSelectionParams() const return std::make_tuple(std::nullopt, std::nullopt); } +void CArtifactsSelling::highlightingChanged() +{ + if(hLeft && hRight) + { + market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE); + deal->block(false); + } + updateSelected(); +} + void CArtifactsSelling::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) { assert(newSlot); if(newSlot == hCurSlot) return; - CTradeBase::onSlotClickPressed(newSlot, hCurSlot); - if(hLeft) - { - if(hRight) - { - market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE); - deal->block(false); - } - updateSelected(); - } + CMarketBase::onSlotClickPressed(newSlot, hCurSlot); + highlightingChanged(); redraw(); } diff --git a/client/widgets/markets/CArtifactsSelling.h b/client/widgets/markets/CArtifactsSelling.h index f450c6906..f70ccad5e 100644 --- a/client/widgets/markets/CArtifactsSelling.h +++ b/client/widgets/markets/CArtifactsSelling.h @@ -10,7 +10,7 @@ #pragma once #include "../CArtifactsOfHeroMarket.h" -#include "CTradeBase.h" +#include "CMarketBase.h" class CArtifactsSelling : public CResourcesBuying { @@ -19,7 +19,7 @@ public: void deselect() override; void makeDeal() override; void updateSelected() override; - void updateSlots() override; + void update() override; std::shared_ptr getAOHset() const; private: @@ -28,6 +28,7 @@ private: std::shared_ptr bidSelectedSlot; ArtifactPosition selectedHeroSlot; - CTradeBase::SelectionParams getSelectionParams() const override; + CMarketBase::SelectionParams getSelectionParams() const override; + void highlightingChanged(); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) override; }; diff --git a/client/widgets/markets/CFreelancerGuild.cpp b/client/widgets/markets/CFreelancerGuild.cpp index f8e04da9d..b2530617e 100644 --- a/client/widgets/markets/CFreelancerGuild.cpp +++ b/client/widgets/markets/CFreelancerGuild.cpp @@ -13,7 +13,6 @@ #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" -#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" @@ -27,25 +26,21 @@ #include "../../../lib/mapObjects/CGTownInstance.h" CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero, [this](){return CFreelancerGuild::getSelectionParams();}) + : CMarketBase(market, hero, [this](){return CFreelancerGuild::getSelectionParams();}) , CResourcesBuying( [this](const std::shared_ptr & heroSlot){CFreelancerGuild::onSlotClickPressed(heroSlot, hLeft);}, - [this](){CTradeBase::updateSubtitles(EMarketMode::CREATURE_RESOURCE);}) + [this](){CMarketBase::updateSubtitles(EMarketMode::CREATURE_RESOURCE);}) + , CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - labels.emplace_back(std::make_shared(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, + labels.emplace_back(std::make_shared(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated())); labels.emplace_back(std::make_shared(155, 103, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated()))); - deal = std::make_shared(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"), + deal = std::make_shared(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();}); - maxAmount = std::make_shared(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], - [this]() {offerSlider->scrollToMax();}); - offerSlider = std::make_shared(Point(232, 489), 137, [this](int newVal) - { - CFreelancerGuild::onOfferSliderMoved(newVal); - }, 0, 0, 0, Orientation::HORIZONTAL); + offerSlider->moveTo(pos.topLeft() + Point(232, 489)); // Hero creatures panel assert(bidTradePanel); @@ -70,7 +65,13 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance }; }); - CTradeBase::deselect(); + CFreelancerGuild::deselect(); +} + +void CFreelancerGuild::deselect() +{ + CMarketBase::deselect(); + CMarketSlider::deselect(); } void CFreelancerGuild::makeDeal() @@ -82,7 +83,7 @@ void CFreelancerGuild::makeDeal() } } -CTradeBase::SelectionParams CFreelancerGuild::getSelectionParams() const +CMarketBase::SelectionParams CFreelancerGuild::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( @@ -92,22 +93,8 @@ CTradeBase::SelectionParams CFreelancerGuild::getSelectionParams() const return std::make_tuple(std::nullopt, std::nullopt); } -void CFreelancerGuild::onOfferSliderMoved(int newVal) +void CFreelancerGuild::highlightingChanged() { - if(hLeft && hRight) - { - offerSlider->scrollTo(newVal); - updateSelected(); - redraw(); - } -} - -void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) -{ - if(newSlot == hCurSlot) - return; - - CTradeBase::onSlotClickPressed(newSlot, hCurSlot); if(hLeft) { if(hRight) @@ -119,8 +106,18 @@ void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr maxAmount->block(false); deal->block(false); } - updateSelected(); - offerTradePanel->updateSlots(); + offerTradePanel->update(); } + updateSelected(); +} + +void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) +{ + assert(newSlot); + if(newSlot == hCurSlot) + return; + + CMarketBase::onSlotClickPressed(newSlot, hCurSlot); + highlightingChanged(); redraw(); } diff --git a/client/widgets/markets/CFreelancerGuild.h b/client/widgets/markets/CFreelancerGuild.h index 078044d5d..646ae6c91 100644 --- a/client/widgets/markets/CFreelancerGuild.h +++ b/client/widgets/markets/CFreelancerGuild.h @@ -9,16 +9,17 @@ */ #pragma once -#include "CTradeBase.h" +#include "CMarketBase.h" -class CFreelancerGuild : public CCreaturesSelling , public CResourcesBuying +class CFreelancerGuild : public CCreaturesSelling , public CResourcesBuying, public CMarketSlider { public: CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero); + void deselect() override; void makeDeal() override; private: - CTradeBase::SelectionParams getSelectionParams() const override; - void onOfferSliderMoved(int newVal); + CMarketBase::SelectionParams getSelectionParams() const override; + void highlightingChanged(); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) override; }; diff --git a/client/widgets/markets/CTradeBase.cpp b/client/widgets/markets/CMarketBase.cpp similarity index 78% rename from client/widgets/markets/CTradeBase.cpp rename to client/widgets/markets/CMarketBase.cpp index bcc368adc..2f4093f3a 100644 --- a/client/widgets/markets/CTradeBase.cpp +++ b/client/widgets/markets/CMarketBase.cpp @@ -1,5 +1,5 @@ /* - * CTradeBase.cpp, part of VCMI engine + * CMarketBase.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -8,14 +8,13 @@ * */ #include "StdInc.h" -#include "CTradeBase.h" +#include "CMarketBase.h" #include "../MiscWidgets.h" #include "../Images.h" #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" -#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" @@ -28,14 +27,14 @@ #include "../../../lib/CHeroHandler.h" #include "../../../lib/mapObjects/CGMarket.h" -CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero, const SelectionParamsFunctor & getParamsCallback) +CMarketBase::CMarketBase(const IMarket * market, const CGHeroInstance * hero, const SelectionParamsFunctor & getParamsCallback) : market(market) , hero(hero) , selectionParamsCallback(getParamsCallback) { } -void CTradeBase::deselect() +void CMarketBase::deselect() { if(hLeft) hLeft->selectSlot(false); @@ -43,19 +42,12 @@ void CTradeBase::deselect() hRight->selectSlot(false); hLeft = hRight = nullptr; deal->block(true); - if(maxAmount) - maxAmount->block(true); - if(offerSlider) - { - offerSlider->scrollTo(0); - offerSlider->block(true); - } bidQty = 0; offerQty = 0; updateSelected(); } -void CTradeBase::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) +void CMarketBase::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) { if(newSlot == hCurSlot) return; @@ -66,15 +58,15 @@ void CTradeBase::onSlotClickPressed(const std::shared_ptr & newS newSlot->selectSlot(true); } -void CTradeBase::updateSlots() +void CMarketBase::update() { if(bidTradePanel) - bidTradePanel->updateSlots(); + bidTradePanel->update(); if(offerTradePanel) - offerTradePanel->updateSlots(); + offerTradePanel->update(); } -void CTradeBase::updateSubtitles(EMarketMode marketMode) +void CMarketBase::updateSubtitles(EMarketMode marketMode) { if(hLeft) for(const auto & slot : offerTradePanel->slots) @@ -88,7 +80,7 @@ void CTradeBase::updateSubtitles(EMarketMode marketMode) offerTradePanel->clearSubtitles(); }; -void CTradeBase::updateSelected() +void CMarketBase::updateSelected() { const auto updateSelectedBody = [](std::shared_ptr & tradePanel, const std::optional & params) { @@ -125,9 +117,13 @@ CExperienceAltar::CExperienceAltar() expForHero = std::make_shared(76, 545, FONT_SMALL, ETextAlignment::CENTER); } -void CExperienceAltar::updateSlots() +void CExperienceAltar::deselect() +{ + expForHero->setText(std::to_string(0)); +} + +void CExperienceAltar::update() { - CTradeBase::updateSlots(); expToLevel->setText(std::to_string(CGI->heroh->reqExp(CGI->heroh->level(hero->exp) + 1) - hero->exp)); } @@ -180,3 +176,32 @@ void CResourcesSelling::updateSubtitles() for(const auto & slot : bidTradePanel->slots) slot->subtitle->setText(std::to_string(LOCPLINT->cb->getResourceAmount(static_cast(slot->serial)))); } + +CMarketSlider::CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback) +{ + OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); + + offerSlider = std::make_shared(Point(230, 489), 137, movingCallback, 0, 0, 0, Orientation::HORIZONTAL); + maxAmount = std::make_shared(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], + [this]() + { + offerSlider->scrollToMax(); + }); +} + +void CMarketSlider::deselect() +{ + maxAmount->block(true); + offerSlider->scrollTo(0); + offerSlider->block(true); +} + +void CMarketSlider::onOfferSliderMoved(int newVal) +{ + if(hLeft && hRight) + { + offerSlider->scrollTo(newVal); + updateSelected(); + redraw(); + } +} diff --git a/client/widgets/markets/CTradeBase.h b/client/widgets/markets/CMarketBase.h similarity index 69% rename from client/widgets/markets/CTradeBase.h rename to client/widgets/markets/CMarketBase.h index 8bca0cfd8..10467262a 100644 --- a/client/widgets/markets/CTradeBase.h +++ b/client/widgets/markets/CMarketBase.h @@ -1,5 +1,5 @@ /* - * CTradeBase.h, part of VCMI engine + * CMarketBase.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -10,6 +10,7 @@ #pragma once #include "TradePanels.h" +#include "../../widgets/Slider.h" VCMI_LIB_NAMESPACE_BEGIN @@ -21,7 +22,7 @@ VCMI_LIB_NAMESPACE_END class CButton; class CSlider; -class CTradeBase : public CIntObject +class CMarketBase : public CIntObject { public: struct SelectionParamOneSide @@ -42,42 +43,42 @@ public: std::shared_ptr hLeft; std::shared_ptr hRight; std::shared_ptr deal; - std::shared_ptr offerSlider; - std::shared_ptr maxAmount; std::vector> labels; std::vector> texts; SelectionParamsFunctor selectionParamsCallback; int bidQty; int offerQty; + const Point dealButtonPos = Point(270, 520); + const Point titlePos = Point(299, 27); - CTradeBase(const IMarket * market, const CGHeroInstance * hero, const SelectionParamsFunctor & getParamsCallback); + CMarketBase(const IMarket * market, const CGHeroInstance * hero, const SelectionParamsFunctor & getParamsCallback); virtual void makeDeal() = 0; virtual void deselect(); - virtual void updateSlots(); + virtual void update(); protected: virtual void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); virtual void updateSubtitles(EMarketMode marketMode); virtual void updateSelected(); - virtual CTradeBase::SelectionParams getSelectionParams() const = 0; + virtual CMarketBase::SelectionParams getSelectionParams() const = 0; }; // Market subclasses -class CExperienceAltar : virtual public CTradeBase +class CExperienceAltar : virtual public CMarketBase { public: std::shared_ptr expToLevel; std::shared_ptr expForHero; std::shared_ptr sacrificeAllButton; - const Point dealButtonPos = Point(269, 520); CExperienceAltar(); - void updateSlots() override; + void deselect() override; + void update() override; virtual void sacrificeAll() = 0; virtual TExpType calcExpAltarForHero() = 0; }; -class CCreaturesSelling : virtual public CTradeBase +class CCreaturesSelling : virtual public CMarketBase { public: CCreaturesSelling(); @@ -85,16 +86,28 @@ public: void updateSubtitles(); }; -class CResourcesBuying : virtual public CTradeBase +class CResourcesBuying : virtual public CMarketBase { public: CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback); }; -class CResourcesSelling : virtual public CTradeBase +class CResourcesSelling : virtual public CMarketBase { public: CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback); void updateSubtitles(); }; + +class CMarketSlider : virtual public CMarketBase +{ +public: + std::shared_ptr offerSlider; + std::shared_ptr maxAmount; + const Point dealButtonPosWithSlider = Point(306, 520); + + CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback); + void deselect() override; + virtual void onOfferSliderMoved(int newVal); +}; diff --git a/client/widgets/markets/CMarketResources.cpp b/client/widgets/markets/CMarketResources.cpp index 8ab982234..d36a636f5 100644 --- a/client/widgets/markets/CMarketResources.cpp +++ b/client/widgets/markets/CMarketResources.cpp @@ -13,7 +13,6 @@ #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" -#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" @@ -25,23 +24,18 @@ #include "../../../lib/mapObjects/CGMarket.h" CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero, [this](){return CMarketResources::getSelectionParams();}) + : CMarketBase(market, hero, [this](){return CMarketResources::getSelectionParams();}) , CResourcesBuying( [this](const std::shared_ptr & resSlot){CMarketResources::onSlotClickPressed(resSlot, hRight);}, [this](){CMarketResources::updateSubtitles();}) , CResourcesSelling([this](const std::shared_ptr & heroSlot){CMarketResources::onSlotClickPressed(heroSlot, hLeft);}) + , CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - labels.emplace_back(std::make_shared(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158])); - deal = std::make_shared(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"), + labels.emplace_back(std::make_shared(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158])); + deal = std::make_shared(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [this]() {CMarketResources::makeDeal(); }); - maxAmount = std::make_shared(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], - [this]() {offerSlider->scrollToMax(); }); - offerSlider = std::make_shared(Point(230, 489), 137, [this](int newVal) - { - CMarketResources::onOfferSliderMoved(newVal); - }, 0, 0, 0, Orientation::HORIZONTAL); // Player's resources assert(bidTradePanel); @@ -57,8 +51,14 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance }; }); - CTradeBase::updateSlots(); - CTradeBase::deselect(); + CMarketBase::update(); + CMarketResources::deselect(); +} + +void CMarketResources::deselect() +{ + CMarketBase::deselect(); + CMarketSlider::deselect(); } void CMarketResources::makeDeal() @@ -70,7 +70,7 @@ void CMarketResources::makeDeal() } } -CTradeBase::SelectionParams CMarketResources::getSelectionParams() const +CMarketBase::SelectionParams CMarketResources::getSelectionParams() const { if(hLeft && hRight && hLeft->id != hRight->id) return std::make_tuple( @@ -80,22 +80,8 @@ CTradeBase::SelectionParams CMarketResources::getSelectionParams() const return std::make_tuple(std::nullopt, std::nullopt); } -void CMarketResources::onOfferSliderMoved(int newVal) +void CMarketResources::highlightingChanged() { - if(hLeft && hRight) - { - offerSlider->scrollTo(newVal); - updateSelected(); - redraw(); - } -} - -void CMarketResources::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) -{ - if(newSlot == hCurSlot) - return; - - CTradeBase::onSlotClickPressed(newSlot, hCurSlot); if(hLeft) { if(hRight) @@ -108,15 +94,25 @@ void CMarketResources::onSlotClickPressed(const std::shared_ptr maxAmount->block(isControlsBlocked); deal->block(isControlsBlocked); } - updateSelected(); - offerTradePanel->updateSlots(); + offerTradePanel->update(); } + updateSelected(); +} + +void CMarketResources::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) +{ + assert(newSlot); + if(newSlot == hCurSlot) + return; + + CMarketBase::onSlotClickPressed(newSlot, hCurSlot); + highlightingChanged(); redraw(); } void CMarketResources::updateSubtitles() { - CTradeBase::updateSubtitles(EMarketMode::RESOURCE_RESOURCE); + CMarketBase::updateSubtitles(EMarketMode::RESOURCE_RESOURCE); if(hLeft) offerTradePanel->slots[hLeft->serial]->subtitle->setText(CGI->generaltexth->allTexts[164]); // n/a } diff --git a/client/widgets/markets/CMarketResources.h b/client/widgets/markets/CMarketResources.h index b70e9836b..63090d1ff 100644 --- a/client/widgets/markets/CMarketResources.h +++ b/client/widgets/markets/CMarketResources.h @@ -9,17 +9,18 @@ */ #pragma once -#include "CTradeBase.h" +#include "CMarketBase.h" -class CMarketResources : public CResourcesSelling, public CResourcesBuying +class CMarketResources : public CResourcesSelling, public CResourcesBuying, public CMarketSlider { public: CMarketResources(const IMarket * market, const CGHeroInstance * hero); + void deselect() override; void makeDeal() override; private: - CTradeBase::SelectionParams getSelectionParams() const override; - void onOfferSliderMoved(int newVal); + CMarketBase::SelectionParams getSelectionParams() const override; + void highlightingChanged(); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); void updateSubtitles(); }; diff --git a/client/widgets/markets/CTransferResources.cpp b/client/widgets/markets/CTransferResources.cpp index b747d47e7..8d7d5db1e 100644 --- a/client/widgets/markets/CTransferResources.cpp +++ b/client/widgets/markets/CTransferResources.cpp @@ -13,7 +13,6 @@ #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" -#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" @@ -24,21 +23,16 @@ #include "../../../lib/CGeneralTextHandler.h" CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero) - : CTradeBase(market, hero, [this](){return CTransferResources::getSelectionParams();}) + : CMarketBase(market, hero, [this](){return CTransferResources::getSelectionParams();}) , CResourcesSelling([this](const std::shared_ptr & heroSlot){CTransferResources::onSlotClickPressed(heroSlot, hLeft);}) + , CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - labels.emplace_back(std::make_shared(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158])); + labels.emplace_back(std::make_shared(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158])); labels.emplace_back(std::make_shared(445, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169])); - deal = std::make_shared(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"), + deal = std::make_shared(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [this]() {CTransferResources::makeDeal();}); - maxAmount = std::make_shared(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], - [this]() {offerSlider->scrollToMax();}); - offerSlider = std::make_shared(Point(230, 489), 137, [this](int newVal) - { - CTransferResources::onOfferSliderMoved(newVal); - }, 0, 0, 0, Orientation::HORIZONTAL); // Player's resources assert(bidTradePanel); @@ -51,10 +45,16 @@ CTransferResources::CTransferResources(const IMarket * market, const CGHeroInsta }); offerTradePanel->moveTo(pos.topLeft() + Point(333, 84)); - CTradeBase::updateSlots(); + CMarketBase::update(); CTransferResources::deselect(); } +void CTransferResources::deselect() +{ + CMarketBase::deselect(); + CMarketSlider::deselect(); +} + void CTransferResources::makeDeal() { if(auto toTrade = offerSlider->getValue(); toTrade != 0) @@ -64,7 +64,7 @@ void CTransferResources::makeDeal() } } -CTradeBase::SelectionParams CTransferResources::getSelectionParams() const +CMarketBase::SelectionParams CTransferResources::getSelectionParams() const { if(hLeft && hRight) return std::make_tuple( @@ -74,22 +74,8 @@ CTradeBase::SelectionParams CTransferResources::getSelectionParams() const return std::make_tuple(std::nullopt, std::nullopt); } -void CTransferResources::onOfferSliderMoved(int newVal) +void CTransferResources::highlightingChanged() { - if(hLeft && hRight) - { - offerSlider->scrollTo(newVal); - updateSelected(); - redraw(); - } -} - -void CTransferResources::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) -{ - if(newSlot == hCurSlot) - return; - - CTradeBase::onSlotClickPressed(newSlot, hCurSlot); if(hLeft) { if(hRight) @@ -100,8 +86,18 @@ void CTransferResources::onSlotClickPressed(const std::shared_ptrblock(false); deal->block(false); } - updateSelected(); - offerTradePanel->updateSlots(); + offerTradePanel->update(); } + updateSelected(); +} + +void CTransferResources::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) +{ + assert(newSlot); + if(newSlot == hCurSlot) + return; + + CMarketBase::onSlotClickPressed(newSlot, hCurSlot); + highlightingChanged(); redraw(); } diff --git a/client/widgets/markets/CTransferResources.h b/client/widgets/markets/CTransferResources.h index e26f98c40..ae21cb9f2 100644 --- a/client/widgets/markets/CTransferResources.h +++ b/client/widgets/markets/CTransferResources.h @@ -9,16 +9,17 @@ */ #pragma once -#include "CTradeBase.h" +#include "CMarketBase.h" -class CTransferResources : public CResourcesSelling +class CTransferResources : public CResourcesSelling, public CMarketSlider { public: CTransferResources(const IMarket * market, const CGHeroInstance * hero); + void deselect() override; void makeDeal() override; private: - CTradeBase::SelectionParams getSelectionParams() const override; - void onOfferSliderMoved(int newVal); + CMarketBase::SelectionParams getSelectionParams() const override; + void highlightingChanged(); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); }; diff --git a/client/widgets/markets/TradePanels.cpp b/client/widgets/markets/TradePanels.cpp index 959ea3747..6286afb57 100644 --- a/client/widgets/markets/TradePanels.cpp +++ b/client/widgets/markets/TradePanels.cpp @@ -196,7 +196,7 @@ void CTradeableItem::showPopupWindow(const Point & cursorPosition) } } -void TradePanelBase::updateSlots() +void TradePanelBase::update() { if(deleteSlotsCheck) slots.erase(std::remove_if(slots.begin(), slots.end(), deleteSlotsCheck), slots.end()); diff --git a/client/widgets/markets/TradePanels.h b/client/widgets/markets/TradePanels.h index 4a0516e72..d8b37210a 100644 --- a/client/widgets/markets/TradePanels.h +++ b/client/widgets/markets/TradePanels.h @@ -51,11 +51,11 @@ public: std::vector> slots; UpdateSlotsFunctor updateSlotsCallback; DeleteSlotsCheck deleteSlotsCheck; - std::shared_ptr selected; const int selectionWidth = 2; - std::shared_ptr selectedSlot; + std::shared_ptr selectedSlot; // Separate slot that displays the contents of the highlighted slot + std::shared_ptr highlightedSlot; // One of the slots highlighted by a frame - virtual void updateSlots(); + virtual void update(); virtual void deselect(); virtual void clearSubtitles(); void updateOffer(CTradeableItem & slot, int, int); diff --git a/client/windows/CMarketWindow.cpp b/client/windows/CMarketWindow.cpp index 75c708a03..400d9e947 100644 --- a/client/windows/CMarketWindow.cpp +++ b/client/windows/CMarketWindow.cpp @@ -63,25 +63,25 @@ CMarketWindow::CMarketWindow(const IMarket * market, const CGHeroInstance * hero void CMarketWindow::updateArtifacts() { assert(marketWidget); - marketWidget->updateSlots(); + marketWidget->update(); } void CMarketWindow::updateGarrisons() { assert(marketWidget); - marketWidget->updateSlots(); + marketWidget->update(); } void CMarketWindow::updateResource() { assert(marketWidget); - marketWidget->updateSlots(); + marketWidget->update(); } void CMarketWindow::updateHero() { assert(marketWidget); - marketWidget->updateSlots(); + marketWidget->update(); } void CMarketWindow::close() @@ -100,7 +100,7 @@ bool CMarketWindow::holdsGarrison(const CArmedInstance * army) void CMarketWindow::artifactRemoved(const ArtifactLocation & artLoc) { - marketWidget->updateSlots(); + marketWidget->update(); CWindowWithArtifacts::artifactRemoved(artLoc); } @@ -109,7 +109,7 @@ void CMarketWindow::artifactMoved(const ArtifactLocation & srcLoc, const Artifac if(!getState().has_value()) return; assert(marketWidget); - marketWidget->updateSlots(); + marketWidget->update(); CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw); } @@ -201,6 +201,8 @@ void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroI OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); background = createBg(ImagePath::builtin("TPMRKASS.bmp"), PLAYER_COLORED); + // Create image that copies part of background containing slot MISC_1 into position of slot MISC_5 + artSlotBack = std::make_shared(background->getSurface(), Rect(20, 187, 47, 47), 18, 339); auto artsSellingMarket = std::make_shared(market, hero); artSets.clear(); addSetAndCallbacks(artsSellingMarket->getAOHset()); diff --git a/client/windows/CMarketWindow.h b/client/windows/CMarketWindow.h index 0e404522d..73ca696dd 100644 --- a/client/windows/CMarketWindow.h +++ b/client/windows/CMarketWindow.h @@ -9,7 +9,7 @@ */ #pragma once -#include "../widgets/markets/CTradeBase.h" +#include "../widgets/markets/CMarketBase.h" #include "../widgets/CWindowWithArtifacts.h" #include "CWindowObject.h" @@ -43,5 +43,8 @@ private: std::shared_ptr quitButton; std::function windowClosedCallback; const Point quitButtonPos = Point(516, 520); - std::shared_ptr marketWidget; + std::shared_ptr marketWidget; + + // This is workaround for bug in H3 files where this slot for ragdoll on this screen is missing + std::shared_ptr artSlotBack; };