From 4d3bf882ed2f63d689c896ae1a65b9cd1bb2286b Mon Sep 17 00:00:00 2001 From: SoundSSGood <87084363+SoundSSGood@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:40:43 +0200 Subject: [PATCH] market resources widget --- client/CMakeLists.txt | 2 + client/widgets/markets/CAltarArtifacts.cpp | 8 +- client/widgets/markets/CAltarArtifacts.h | 1 + client/widgets/markets/CAltarCreatures.cpp | 40 +++--- client/widgets/markets/CAltarCreatures.h | 1 - client/widgets/markets/CFreelancerGuild.cpp | 65 ++++----- client/widgets/markets/CFreelancerGuild.h | 6 +- client/widgets/markets/CMarketResources.cpp | 145 ++++++++++++++++++++ client/widgets/markets/CMarketResources.h | 26 ++++ client/widgets/markets/CTradeBase.cpp | 48 ++++++- client/widgets/markets/CTradeBase.h | 22 ++- client/widgets/markets/TradePanels.cpp | 9 +- client/widgets/markets/TradePanels.h | 5 + client/windows/CMarketWindow.cpp | 19 ++- client/windows/CMarketWindow.h | 2 + client/windows/CTradeWindow.cpp | 19 +-- 16 files changed, 310 insertions(+), 108 deletions(-) create mode 100644 client/widgets/markets/CMarketResources.cpp create mode 100644 client/widgets/markets/CMarketResources.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index f0b6f377d..e90d1fc03 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -126,6 +126,7 @@ set(client_SRCS widgets/markets/CAltarArtifacts.cpp widgets/markets/CAltarCreatures.cpp widgets/markets/CFreelancerGuild.cpp + widgets/markets/CMarketResources.cpp widgets/markets/CTradeBase.cpp widgets/markets/TradePanels.cpp @@ -312,6 +313,7 @@ set(client_HEADERS widgets/markets/CAltarArtifacts.h widgets/markets/CAltarCreatures.h widgets/markets/CFreelancerGuild.h + widgets/markets/CMarketResources.h widgets/markets/CTradeBase.h widgets/markets/TradePanels.h diff --git a/client/widgets/markets/CAltarArtifacts.cpp b/client/widgets/markets/CAltarArtifacts.cpp index 5fbb37c1d..8395eaab5 100644 --- a/client/widgets/markets/CAltarArtifacts.cpp +++ b/client/widgets/markets/CAltarArtifacts.cpp @@ -39,7 +39,7 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); }); labels.emplace_back(std::make_shared(450, 34, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477])); labels.emplace_back(std::make_shared(302, 423, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478])); - lSubtitle = std::make_shared(302, 501, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); + selectedSubtitle = std::make_shared(302, 501, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); selectedArt = std::make_shared(Point(280, 442)); sacrificeAllButton = std::make_shared(Point(393, 520), AnimationPath::builtin("ALTFILL.DEF"), @@ -109,7 +109,7 @@ void CAltarArtifacts::sacrificeBackpack() void CAltarArtifacts::setSelectedArtifact(const CArtifactInstance * art) { selectedArt->setArtifact(art); - lSubtitle->setText(art == nullptr ? "" : std::to_string(calcExpCost(art))); + selectedSubtitle->setText(art == nullptr ? "" : std::to_string(calcExpCost(art))); } std::shared_ptr CAltarArtifacts::getAOHset() const @@ -210,8 +210,8 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr & TExpType CAltarArtifacts::calcExpCost(const CArtifactInstance * art) { - int dmp = 0; + int bidQty = 0; int expOfArt = 0; - market->getOffer(art->getTypeId(), 0, dmp, expOfArt, EMarketMode::ARTIFACT_EXP); + market->getOffer(art->getTypeId(), 0, bidQty, expOfArt, EMarketMode::ARTIFACT_EXP); return hero->calculateXp(expOfArt); } diff --git a/client/widgets/markets/CAltarArtifacts.h b/client/widgets/markets/CAltarArtifacts.h index ccb6613b4..0715950dd 100644 --- a/client/widgets/markets/CAltarArtifacts.h +++ b/client/widgets/markets/CAltarArtifacts.h @@ -30,6 +30,7 @@ private: ObjectInstanceID altarId; const CArtifactSet * altarArtifacts; std::shared_ptr selectedArt; + std::shared_ptr selectedSubtitle; std::shared_ptr sacrificeBackpackButton; std::shared_ptr heroArts; std::map> tradeSlotsMap; diff --git a/client/widgets/markets/CAltarCreatures.cpp b/client/widgets/markets/CAltarCreatures.cpp index 2ddb9cf0c..baa6f082d 100644 --- a/client/widgets/markets/CAltarCreatures.cpp +++ b/client/widgets/markets/CAltarCreatures.cpp @@ -36,11 +36,8 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * 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)); - lSubtitle = std::make_shared(180, 503, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); - rSubtitle = std::make_shared(426, 503, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); - offerSlider = std::make_shared(Point(231, 481), 137, std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL); - maxUnits = std::make_shared(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, offerSlider)); + maxAmount = std::make_shared(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, offerSlider)); unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0); expPerUnit.resize(GameConstants::ARMY_SIZE, 0); @@ -49,9 +46,9 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * // Hero creatures panel assert(leftTradePanel); - leftTradePanel->selectedImage->moveTo(pos.topLeft() + Point(104, 312)); - - leftTradePanel->moveBy(Point(45, 110)); + leftTradePanel->moveTo(pos.topLeft() + Point(45, 110)); + leftTradePanel->selectedImage->moveTo(pos.topLeft() + Point(149, 422)); + leftTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(180, 503)); for(const auto & slot : leftTradePanel->slots) slot->clickPressedCallback = [this](const std::shared_ptr & heroSlot) {CAltarCreatures::onSlotClickPressed(heroSlot, hLeft);}; @@ -60,22 +57,22 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * { CAltarCreatures::onSlotClickPressed(altarSlot, hRight); }, leftTradePanel->slots); - rightTradePanel->selectedImage->moveTo(pos.topLeft() + Point(61, 312)); - rightTradePanel->moveBy(Point(334, 110)); - + rightTradePanel->moveTo(pos.topLeft() + Point(334, 110)); + rightTradePanel->selectedImage->moveTo(pos.topLeft() + Point(395, 422)); + rightTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(426, 503)); leftTradePanel->deleteSlotsCheck = rightTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1); + readExpValues(); - expForHero->setText(std::to_string(0)); CAltarCreatures::deselect(); }; void CAltarCreatures::readExpValues() { - int dump; + int bidQty = 0; for(auto heroSlot : leftTradePanel->slots) { if(heroSlot->id >= 0) - market->getOffer(heroSlot->id, 0, dump, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP); + market->getOffer(heroSlot->id, 0, bidQty, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP); } } @@ -108,7 +105,7 @@ void CAltarCreatures::updateControls() offerSlider->block(!offerSlider->getAmount()); if(hLeft) offerSlider->scrollTo(unitsOnAltar[hLeft->serial]); - maxUnits->block(offerSlider->getAmount() == 0); + maxAmount->block(offerSlider->getAmount() == 0); } void CAltarCreatures::updateSelected() @@ -118,26 +115,25 @@ void CAltarCreatures::updateSelected() if(hLeft) { - lSubtitle->setText(std::to_string(offerSlider->getValue())); + leftTradePanel->selectedSubtitle->setText(std::to_string(offerSlider->getValue())); lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex(); } else { - lSubtitle->setText(""); + leftTradePanel->selectedSubtitle->setText(""); } if(hRight) { - rSubtitle->setText(hRight->subtitle); + rightTradePanel->selectedSubtitle->setText(hRight->subtitle); if(offerSlider->getValue() != 0) rImageIndex = CGI->creatures()->getByIndex(hRight->id)->getIconIndex(); } else { - rSubtitle->setText(""); + rightTradePanel->selectedSubtitle->setText(""); } leftTradePanel->setSelectedFrameIndex(lImageIndex); rightTradePanel->setSelectedFrameIndex(rImageIndex); - rightTradePanel->selectedImage->redraw(); } void CAltarCreatures::updateSlots() @@ -151,10 +147,8 @@ void CAltarCreatures::updateSlots() void CAltarCreatures::deselect() { CTradeBase::deselect(); - offerSlider->block(true); - maxUnits->block(true); - offerSlider->scrollTo(0); updateSelected(); + expForHero->setText(std::to_string(0)); } TExpType CAltarCreatures::calcExpAltarForHero() @@ -171,7 +165,6 @@ TExpType CAltarCreatures::calcExpAltarForHero() void CAltarCreatures::makeDeal() { deselect(); - expForHero->setText(std::to_string(0)); std::vector ids; std::vector toSacrifice; @@ -242,6 +235,7 @@ void CAltarCreatures::onOfferSliderMoved(int newVal) deal->block(calcExpAltarForHero() == 0); updateControls(); updateSelected(); + redraw(); } void CAltarCreatures::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) diff --git a/client/widgets/markets/CAltarCreatures.h b/client/widgets/markets/CAltarCreatures.h index 48169a31c..eb266be97 100644 --- a/client/widgets/markets/CAltarCreatures.h +++ b/client/widgets/markets/CAltarCreatures.h @@ -23,7 +23,6 @@ public: void updateAltarSlot(std::shared_ptr slot); private: - std::shared_ptr maxUnits; std::vector unitsOnAltar; std::vector expPerUnit; diff --git a/client/widgets/markets/CFreelancerGuild.cpp b/client/widgets/markets/CFreelancerGuild.cpp index 123904a26..3602c3db6 100644 --- a/client/widgets/markets/CFreelancerGuild.cpp +++ b/client/widgets/markets/CFreelancerGuild.cpp @@ -28,29 +28,27 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero) : CTradeBase(market, hero) - , CResourcesMarket(EMarketMode::CREATURE_RESOURCE) + , CResourcesPurchasing([this](){CResourcesPurchasing::updateSubtitles(EMarketMode::CREATURE_RESOURCE);}) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - labels.emplace_back(std::make_shared(254, -96, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, + labels.emplace_back(std::make_shared(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated())); - labels.emplace_back(std::make_shared(110, -20, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, + 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(262, 397), AnimationPath::builtin("ALTSACR.DEF"), + deal = std::make_shared(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();}); - deal->block(true); - maxUnits = std::make_shared(Point(183, 397), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], + maxAmount = std::make_shared(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], [this]() {offerSlider->scrollToMax();}); - maxUnits->block(true); - lSubtitle = std::make_shared(113, 403, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); - rSubtitle = std::make_shared(400, 382, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); + offerSlider = std::make_shared(Point(232, 489), 137, [this](int newVal) + { + CFreelancerGuild::onOfferSliderMoved(newVal); + }, 0, 0, 0, Orientation::HORIZONTAL); // Hero creatures panel assert(leftTradePanel); - leftTradePanel->deleteSlotsCheck = [this, hero](const std::shared_ptr & slot) - { - return hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false; - }; + leftTradePanel->moveTo(pos.topLeft() + Point(45, 123)); + leftTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1); std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot) { slot->clickPressedCallback = [this](const std::shared_ptr & heroSlot) @@ -58,11 +56,10 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance CFreelancerGuild::onSlotClickPressed(heroSlot, hLeft); }; }); - leftTradePanel->selectedImage->moveTo(pos.topLeft() + Point(83, 327)); // Guild resources panel assert(rightTradePanel); - rightTradePanel->moveBy(Point(282, 58)); + rightTradePanel->moveBy(Point(327, 181)); std::for_each(rightTradePanel->slots.cbegin(), rightTradePanel->slots.cend(), [this](auto & slot) { slot->clickPressedCallback = [this](const std::shared_ptr & heroSlot) @@ -70,12 +67,6 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance CFreelancerGuild::onSlotClickPressed(heroSlot, hRight); }; }); - rightTradePanel->selectedImage->moveTo(pos.topLeft() + Point(383, 335)); - - offerSlider = std::make_shared(Point(187, 366), 137, [this](int newVal) - { - CFreelancerGuild::onOfferSliderMoved(newVal); - }, 0, 0, 0, Orientation::HORIZONTAL); CFreelancerGuild::deselect(); } @@ -87,15 +78,15 @@ void CFreelancerGuild::updateSelected() if(hLeft && hRight) { - lSubtitle->setText(std::to_string(qtyPerPrice * offerSlider->getValue())); - rSubtitle->setText(std::to_string(price * offerSlider->getValue())); + leftTradePanel->selectedSubtitle->setText(std::to_string(bidQty * offerSlider->getValue())); + rightTradePanel->selectedSubtitle->setText(std::to_string(offerQty * offerSlider->getValue())); lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex(); rImageIndex = hRight->id; } else { - lSubtitle->setText(""); - rSubtitle->setText(""); + leftTradePanel->selectedSubtitle->setText(""); + rightTradePanel->selectedSubtitle->setText(""); } leftTradePanel->setSelectedFrameIndex(lImageIndex); rightTradePanel->setSelectedFrameIndex(rImageIndex); @@ -103,18 +94,17 @@ void CFreelancerGuild::updateSelected() void CFreelancerGuild::makeDeal() { - LOCPLINT->cb->trade(market, EMarketMode::CREATURE_RESOURCE, SlotID(hLeft->serial), GameResID(hRight->id), qtyPerPrice * offerSlider->getValue(), hero); - deselect(); + if(auto toTrade = offerSlider->getValue(); toTrade != 0) + { + LOCPLINT->cb->trade(market, EMarketMode::CREATURE_RESOURCE, SlotID(hLeft->serial), GameResID(hRight->id), bidQty * toTrade, hero); + deselect(); + } } void CFreelancerGuild::deselect() { - CTradeBase::deselect(); - maxUnits->block(true); + CResourcesPurchasing::deselect(); updateSelected(); - qtyPerPrice = 0; - price = 0; - offerSlider->scrollTo(0); } void CFreelancerGuild::onOfferSliderMoved(int newVal) @@ -129,16 +119,19 @@ void CFreelancerGuild::onOfferSliderMoved(int newVal) void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) { + if(newSlot == hCurSlot) + return; + CTradeBase::onSlotClickPressed(newSlot, hCurSlot); - if(hLeft) { if(hRight) { - market->getOffer(hLeft->id, hRight->id, qtyPerPrice, price, EMarketMode::CREATURE_RESOURCE); - offerSlider->setAmount((hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack() ? 1 : 0)) / qtyPerPrice); + market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::CREATURE_RESOURCE); + offerSlider->setAmount((hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack() ? 1 : 0)) / bidQty); offerSlider->scrollTo(0); - maxUnits->block(false); + offerSlider->block(false); + maxAmount->block(false); deal->block(false); } updateSelected(); diff --git a/client/widgets/markets/CFreelancerGuild.h b/client/widgets/markets/CFreelancerGuild.h index c842f4784..b85168e48 100644 --- a/client/widgets/markets/CFreelancerGuild.h +++ b/client/widgets/markets/CFreelancerGuild.h @@ -11,7 +11,7 @@ #include "CTradeBase.h" -class CFreelancerGuild : public CCreaturesSelling , public CResourcesMarket +class CFreelancerGuild : public CCreaturesSelling , public CResourcesPurchasing { public: CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero); @@ -19,10 +19,6 @@ public: void deselect() override; private: - std::shared_ptr maxUnits; - int qtyPerPrice; - int price; - void updateSelected(); void onOfferSliderMoved(int newVal); void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) override; diff --git a/client/widgets/markets/CMarketResources.cpp b/client/widgets/markets/CMarketResources.cpp new file mode 100644 index 000000000..a2d565fbc --- /dev/null +++ b/client/widgets/markets/CMarketResources.cpp @@ -0,0 +1,145 @@ +/* + * CMarketResources.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +#include "StdInc.h" +#include "CMarketResources.h" + +#include "../../gui/CGuiHandler.h" +#include "../../widgets/Buttons.h" +#include "../../widgets/Slider.h" +#include "../../widgets/TextControls.h" + +#include "../../CGameInfo.h" +#include "../../CPlayerInterface.h" + +#include "../../../CCallback.h" + +#include "../../../lib/CGeneralTextHandler.h" +#include "../../../lib/mapObjects/CGHeroInstance.h" +#include "../../../lib/mapObjects/CGMarket.h" + +CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero) + : CTradeBase(market, hero) + , CResourcesPurchasing([this](){CMarketResources::updateSubtitles();}) +{ + 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"), + 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(leftTradePanel); + std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot) + { + slot->clickPressedCallback = [this](const std::shared_ptr & heroSlot) + { + CMarketResources::onSlotClickPressed(heroSlot, hLeft); + }; + }); + leftTradePanel->moveTo(pos.topLeft() + Point(39, 181)); + + // Market resources panel + assert(rightTradePanel); + rightTradePanel->moveTo(pos.topLeft() + Point(327, 181)); + std::for_each(rightTradePanel->slots.cbegin(), rightTradePanel->slots.cend(), [this](auto & slot) + { + slot->clickPressedCallback = [this](const std::shared_ptr & resSlot) + { + CMarketResources::onSlotClickPressed(resSlot, hRight); + }; + }); + + CResourcesSelling::updateSlots(); + CMarketResources::deselect(); +} + +void CMarketResources::makeDeal() +{ + if(auto toTrade = offerSlider->getValue(); toTrade != 0) + { + LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_RESOURCE, GameResID(hLeft->id), GameResID(hRight->id), bidQty * toTrade, hero); + deselect(); + } +} + +void CMarketResources::deselect() +{ + CResourcesPurchasing::deselect(); + updateSelected(); +} + +void CMarketResources::updateSelected() +{ + std::optional lImageIndex = std::nullopt; + std::optional rImageIndex = std::nullopt; + + if(hLeft && hRight && hLeft->id != hRight->id) + { + leftTradePanel->selectedSubtitle->setText(std::to_string(bidQty * offerSlider->getValue())); + rightTradePanel->selectedSubtitle->setText(std::to_string(offerQty * offerSlider->getValue())); + lImageIndex = hLeft->id; + rImageIndex = hRight->id; + } + else + { + leftTradePanel->selectedSubtitle->setText(""); + rightTradePanel->selectedSubtitle->setText(""); + } + leftTradePanel->setSelectedFrameIndex(lImageIndex); + rightTradePanel->setSelectedFrameIndex(rImageIndex); +} + +void CMarketResources::onOfferSliderMoved(int newVal) +{ + 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) + { + market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::RESOURCE_RESOURCE); + offerSlider->setAmount(LOCPLINT->cb->getResourceAmount(GameResID(hLeft->id)) / bidQty); + offerSlider->scrollTo(0); + const bool isControlsBlocked = hLeft->id != hRight->id ? false : true; + offerSlider->block(isControlsBlocked); + maxAmount->block(isControlsBlocked); + deal->block(isControlsBlocked); + } + updateSelected(); + rightTradePanel->updateSlots(); + } + redraw(); +} + +void CMarketResources::updateSubtitles() +{ + CResourcesPurchasing::updateSubtitles(EMarketMode::RESOURCE_RESOURCE); + if(hLeft) + rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a +} diff --git a/client/widgets/markets/CMarketResources.h b/client/widgets/markets/CMarketResources.h new file mode 100644 index 000000000..38074b39d --- /dev/null +++ b/client/widgets/markets/CMarketResources.h @@ -0,0 +1,26 @@ +/* + * CMarketResources.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +#include "CTradeBase.h" + +class CMarketResources : public CResourcesSelling, public CResourcesPurchasing +{ +public: + CMarketResources(const IMarket * market, const CGHeroInstance * hero); + void makeDeal() override; + void deselect() override; + +private: + void updateSelected(); + void onOfferSliderMoved(int newVal); + void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot); + void updateSubtitles(); +}; diff --git a/client/widgets/markets/CTradeBase.cpp b/client/widgets/markets/CTradeBase.cpp index d91541920..34c8dcd0a 100644 --- a/client/widgets/markets/CTradeBase.cpp +++ b/client/widgets/markets/CTradeBase.cpp @@ -14,9 +14,13 @@ #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" +#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../CGameInfo.h" +#include "../../CPlayerInterface.h" + +#include "../../../CCallback.h" #include "../../../lib/CGeneralTextHandler.h" #include "../../../lib/mapObjects/CGHeroInstance.h" @@ -57,6 +61,13 @@ 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); + } } void CTradeBase::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & hCurSlot) @@ -114,19 +125,18 @@ void CCreaturesSelling::updateSlots() leftTradePanel->updateSlots(); } -CResourcesMarket::CResourcesMarket(EMarketMode marketMode) +CResourcesPurchasing::CResourcesPurchasing(TradePanelBase::UpdateSlotsFunctor callback) { OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); - rightTradePanel = std::make_shared([](const std::shared_ptr&) {}, [this, marketMode]() - { - updateSubtitles(marketMode); - }); - labels.emplace_back(std::make_shared(400, 25, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168])); + rightTradePanel = std::make_shared([](const std::shared_ptr&) {}, callback); + labels.emplace_back(std::make_shared(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168])); } -void CResourcesMarket::updateSubtitles(EMarketMode marketMode) +void CResourcesPurchasing::updateSubtitles(EMarketMode marketMode) { + assert(marketMode == EMarketMode::RESOURCE_RESOURCE || marketMode == EMarketMode::CREATURE_RESOURCE || marketMode == EMarketMode::ARTIFACT_RESOURCE); + if(hLeft) for(const auto & slot : rightTradePanel->slots) { @@ -138,3 +148,27 @@ void CResourcesMarket::updateSubtitles(EMarketMode marketMode) else rightTradePanel->clearSubtitles(); }; + +void CResourcesPurchasing::deselect() +{ + CTradeBase::deselect(); + bidQty = 0; + offerQty = 0; +} + +CResourcesSelling::CResourcesSelling() +{ + OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); + + leftTradePanel = std::make_shared([](const std::shared_ptr&) {}, [this]() + { + for(const auto & slot : leftTradePanel->slots) + slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast(slot->serial))); + }); + labels.emplace_back(std::make_shared(156, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270])); +} + +void CResourcesSelling::updateSlots() +{ + leftTradePanel->updateSlots(); +} diff --git a/client/widgets/markets/CTradeBase.h b/client/widgets/markets/CTradeBase.h index b61b4f6fa..b067266b7 100644 --- a/client/widgets/markets/CTradeBase.h +++ b/client/widgets/markets/CTradeBase.h @@ -35,13 +35,11 @@ public: //highlighted items (nullptr if no highlight) std::shared_ptr hLeft; std::shared_ptr hRight; - std::shared_ptr lSubtitle; - std::shared_ptr rSubtitle; std::shared_ptr deal; std::shared_ptr offerSlider; + std::shared_ptr maxAmount; std::vector> labels; - std::vector> buttons; std::vector> texts; CTradeBase(const IMarket * market, const CGHeroInstance * hero); @@ -77,11 +75,21 @@ public: void updateSlots() override; }; -class CResourcesMarket : virtual public CTradeBase, virtual public CIntObject +class CResourcesPurchasing : virtual public CTradeBase, virtual public CIntObject { public: - CResourcesMarket(EMarketMode marketMode); - -private: + CResourcesPurchasing(TradePanelBase::UpdateSlotsFunctor callback); void updateSubtitles(EMarketMode marketMode); + void deselect() override; + +protected: + int bidQty; + int offerQty; +}; + +class CResourcesSelling : virtual public CTradeBase, virtual public CIntObject +{ +public: + CResourcesSelling(); + void updateSlots() override; }; diff --git a/client/widgets/markets/TradePanels.cpp b/client/widgets/markets/TradePanels.cpp index 9debeef14..2a5032d62 100644 --- a/client/widgets/markets/TradePanels.cpp +++ b/client/widgets/markets/TradePanels.cpp @@ -325,7 +325,8 @@ ResourcesPanel::ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedC slot->setSelectionWidth(selectionWidth); } updateSlotsCallback = updateSubtitles; - selectedImage = std::make_shared(AnimationPath::builtin("RESOURCE"), 0); + selectedImage = std::make_shared(AnimationPath::builtin("RESOURCE"), 0, 0, selectedImagePos.x, selectedImagePos.y); + selectedSubtitle = std::make_shared(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); } ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles, @@ -388,7 +389,8 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC slot->subtitle = std::to_string(creaturesNum); slot->setSelectionWidth(selectionWidth); } - selectedImage = std::make_shared(AnimationPath::builtin("TWCRPORT"), 0); + selectedImage = std::make_shared(AnimationPath::builtin("TWCRPORT"), 0, 0, selectedImagePos.x, selectedImagePos.y); + selectedSubtitle = std::make_shared(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); } CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, @@ -405,5 +407,6 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC slot->subtitle = emptySlots ? "" : srcSlot->subtitle; slot->setSelectionWidth(selectionWidth); } - selectedImage = std::make_shared(AnimationPath::builtin("TWCRPORT"), 0); + selectedImage = std::make_shared(AnimationPath::builtin("TWCRPORT"), 0, 0, selectedImagePos.x, selectedImagePos.y); + selectedSubtitle = std::make_shared(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); } diff --git a/client/widgets/markets/TradePanels.h b/client/widgets/markets/TradePanels.h index 761d42a68..79aceb320 100644 --- a/client/widgets/markets/TradePanels.h +++ b/client/widgets/markets/TradePanels.h @@ -65,6 +65,7 @@ public: std::shared_ptr selected; const int selectionWidth = 2; std::shared_ptr selectedImage; + std::shared_ptr selectedSubtitle; virtual void updateSlots(); virtual void deselect(); @@ -89,6 +90,8 @@ class ResourcesPanel : public TradePanelBase Point(83, 158) }; const Point slotDimension = Point(69, 66); + const Point selectedImagePos = Point(102, 276); + const Point selectedSubtitlePos = Point(118, 324); public: ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles); @@ -133,6 +136,8 @@ class CreaturesPanel : public TradePanelBase Point(83, 196) }; const Point slotDimension = Point(58, 64); + const Point selectedImagePos = Point(83, 327); + const Point selectedSubtitlePos = Point(113, 403); public: using slotsData = std::vector>; diff --git a/client/windows/CMarketWindow.cpp b/client/windows/CMarketWindow.cpp index edb8bd12d..0ca5f6aba 100644 --- a/client/windows/CMarketWindow.cpp +++ b/client/windows/CMarketWindow.cpp @@ -17,6 +17,7 @@ #include "../widgets/Buttons.h" #include "../widgets/TextControls.h" #include "../widgets/markets/CFreelancerGuild.h" +#include "../widgets/markets/CMarketResources.h" #include "../CGameInfo.h" #include "../CPlayerInterface.h" @@ -69,7 +70,8 @@ void CMarketWindow::updateGarrisons() void CMarketWindow::resourceChanged() { - //market->initSubs(true); + if(resRes) + resRes->updateSlots(); } void CMarketWindow::close() @@ -181,8 +183,17 @@ void CMarketWindow::createMarketResources(const IMarket * market, const CGHeroIn OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); background = createBg(ImagePath::builtin("TPMRKRES.bmp"), PLAYER_COLORED); - this->market = std::make_shared(market, hero, []() {}, EMarketMode::RESOURCE_RESOURCE); - createInternals(EMarketMode::RESOURCE_RESOURCE, market, hero); + resRes = std::make_shared(market, hero); + + background->center(); + pos = background->pos; + resRes->setRedrawParent(true); + resRes->moveTo(pos.topLeft()); + + createChangeModeButtons(EMarketMode::RESOURCE_RESOURCE, market, hero); + quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), + CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN); + redraw(); } void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroInstance * hero) @@ -195,7 +206,7 @@ void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroI background->center(); pos = background->pos; guild->setRedrawParent(true); - guild->moveTo(Point(257, 211)); + guild->moveTo(pos.topLeft()); createChangeModeButtons(EMarketMode::CREATURE_RESOURCE, market, hero); quitButton = std::make_shared(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"), diff --git a/client/windows/CMarketWindow.h b/client/windows/CMarketWindow.h index 66097f453..efd5cf08d 100644 --- a/client/windows/CMarketWindow.h +++ b/client/windows/CMarketWindow.h @@ -13,6 +13,7 @@ #include "CAltarWindow.h" class CFreelancerGuild; +class CMarketResources; class CMarketWindow : public CStatusbarWindow, public CAltarWindow // TODO remove CAltarWindow { @@ -45,4 +46,5 @@ private: std::shared_ptr market; std::shared_ptr guild; + std::shared_ptr resRes; }; diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index 2fbbec960..54dd09114 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -103,7 +103,7 @@ void CTradeWindow::initItems(bool Left) CTradeBase::onSlotClickPressed(newSlot, left ? hLeft : hRight); selectionChanged(left); }; - if(Left && (mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER)) + if(Left && (mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER)) { leftTradePanel = std::make_shared( [clickPressedTradePanel](const std::shared_ptr & newSlot) @@ -118,21 +118,6 @@ void CTradeWindow::initItems(bool Left) leftTradePanel->moveBy(Point(39, 182)); leftTradePanel->updateSlots(); } - else if(!Left && mode == EMarketMode::RESOURCE_RESOURCE) - { - rightTradePanel = std::make_shared( - [clickPressedTradePanel](const std::shared_ptr & newSlot) - { - clickPressedTradePanel(newSlot, false); - }, - [this, updRightSub]() - { - updRightSub(EMarketMode::RESOURCE_RESOURCE); - if(hLeft) - rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a - }); - rightTradePanel->moveBy(Point(327, 181)); - } else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE)) { rightTradePanel = std::make_shared(std::bind(clickPressedTradePanel, _1, false), @@ -216,8 +201,6 @@ ImagePath CMarketplaceWindow::getBackgroundForMode(EMarketMode mode) { switch(mode) { - case EMarketMode::RESOURCE_RESOURCE: - return ImagePath::builtin("TPMRKRES.bmp"); case EMarketMode::RESOURCE_PLAYER: return ImagePath::builtin("TPMRKPTS.bmp"); case EMarketMode::RESOURCE_ARTIFACT: