diff --git a/client/widgets/markets/CMarketBase.cpp b/client/widgets/markets/CMarketBase.cpp index f318ed566..b76edb0b9 100644 --- a/client/widgets/markets/CMarketBase.cpp +++ b/client/widgets/markets/CMarketBase.cpp @@ -46,7 +46,8 @@ void CMarketBase::deselect() offerTradePanel->highlightedSlot->selectSlot(false); offerTradePanel->highlightedSlot.reset(); } - deal->block(true); + if(deal) + deal->block(true); bidQty = 0; offerQty = 0; updateShowcases(); @@ -54,7 +55,12 @@ void CMarketBase::deselect() void CMarketBase::onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & curPanel) { - assert(newSlot); + if(!newSlot) + { + deselect(); + return; + } + assert(curPanel); if(newSlot == curPanel->highlightedSlot) return; @@ -81,13 +87,14 @@ void CMarketBase::updateSubtitlesForBid(EMarketMode marketMode, int bidId) } else { - for(const auto & slot : offerTradePanel->slots) - { - int slotBidQty = 0; - int slotOfferQty = 0; - market->getOffer(bidId, slot->id, slotBidQty, slotOfferQty, marketMode); - offerTradePanel->updateOffer(*slot, slotBidQty, slotOfferQty); - } + if(offerTradePanel) + for(const auto & slot : offerTradePanel->slots) + { + int slotBidQty = 0; + int slotOfferQty = 0; + market->getOffer(bidId, slot->id, slotBidQty, slotOfferQty, marketMode); + offerTradePanel->updateOffer(*slot, slotBidQty, slotOfferQty); + } } }; @@ -120,6 +127,11 @@ void CMarketBase::highlightingChanged() updateShowcases(); } +CMarketBase::MarketShowcasesParams CMarketBase::getShowcasesParams() const +{ + return {}; +} + CExperienceAltar::CExperienceAltar() { OBJECT_CONSTRUCTION; @@ -164,8 +176,9 @@ bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr void CCreaturesSelling::updateSubtitles() const { - for(const auto & heroSlot : bidTradePanel->slots) - heroSlot->subtitle->setText(std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial)))); + if(bidTradePanel) + for(const auto & heroSlot : bidTradePanel->slots) + heroSlot->subtitle->setText(std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial)))); } CResourcesBuying::CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, @@ -188,8 +201,9 @@ CResourcesSelling::CResourcesSelling(const CTradeableItem::ClickPressedFunctor & void CResourcesSelling::updateSubtitles() const { - for(const auto & slot : bidTradePanel->slots) - slot->subtitle->setText(std::to_string(GAME->interface()->cb->getResourceAmount(static_cast(slot->serial)))); + if(bidTradePanel) + for(const auto & slot : bidTradePanel->slots) + slot->subtitle->setText(std::to_string(GAME->interface()->cb->getResourceAmount(static_cast(slot->serial)))); } CMarketSlider::CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback) @@ -197,6 +211,7 @@ CMarketSlider::CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback OBJECT_CONSTRUCTION; offerSlider = std::make_shared(Point(230, 489), 137, movingCallback, 0, 0, 0, Orientation::HORIZONTAL); + offerSlider->setScrollBounds(Rect()); maxAmount = std::make_shared(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), LIBRARY->generaltexth->zelp[596], [this]() { diff --git a/client/widgets/markets/CMarketBase.h b/client/widgets/markets/CMarketBase.h index 7b3e7ede3..1a1019eaf 100644 --- a/client/widgets/markets/CMarketBase.h +++ b/client/widgets/markets/CMarketBase.h @@ -58,7 +58,7 @@ protected: virtual void onSlotClickPressed(const std::shared_ptr & newSlot, std::shared_ptr & curPanel); virtual void updateSubtitlesForBid(EMarketMode marketMode, int bidId); virtual void updateShowcases(); - virtual MarketShowcasesParams getShowcasesParams() const = 0; + virtual MarketShowcasesParams getShowcasesParams() const; virtual void highlightingChanged(); }; diff --git a/client/widgets/markets/CMarketResources.cpp b/client/widgets/markets/CMarketResources.cpp index 275ef31ca..f949685ea 100644 --- a/client/widgets/markets/CMarketResources.cpp +++ b/client/widgets/markets/CMarketResources.cpp @@ -98,8 +98,10 @@ void CMarketResources::highlightingChanged() void CMarketResources::updateSubtitles() { CMarketBase::updateSubtitlesForBid(EMarketMode::RESOURCE_RESOURCE, bidTradePanel->getHighlightedItemId()); - if(bidTradePanel->highlightedSlot) - offerTradePanel->slots[bidTradePanel->highlightedSlot->serial]->subtitle->setText(LIBRARY->generaltexth->allTexts[164]); // n/a + if(bidTradePanel && bidTradePanel->highlightedSlot) + for(auto & slot : offerTradePanel->slots) + if(slot->id == bidTradePanel->highlightedSlot->id) + slot->subtitle->setText(LIBRARY->generaltexth->allTexts[164]); // n/a } std::string CMarketResources::getTraderText() diff --git a/client/widgets/markets/TradePanels.cpp b/client/widgets/markets/TradePanels.cpp index c8dfc71b5..42bcc7ab9 100644 --- a/client/widgets/markets/TradePanels.cpp +++ b/client/widgets/markets/TradePanels.cpp @@ -13,6 +13,7 @@ #include "../../GameEngine.h" #include "../../GameInstance.h" #include "../../render/Canvas.h" +#include "../../widgets/Slider.h" #include "../../widgets/TextControls.h" #include "../../windows/InfoWindows.h" @@ -261,20 +262,59 @@ bool TradePanelBase::isHighlighted() const ResourcesPanel::ResourcesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const UpdateSlotsFunctor & updateSubtitles) + : clickPressedCallback(std::move(clickPressedCallback)) { - assert(resourcesForTrade.size() == slotsPos.size()); OBJECT_CONSTRUCTION; - for(const auto & res : resourcesForTrade) + // TODO: replace with LIBRARY->resourceTypeHandler->getAllObjects() -> also check order after doing this + resourcesForTrade = { - auto slot = slots.emplace_back(std::make_shared(Rect(slotsPos[res.num], slotDimension), EType::RESOURCE, res.num, res.num)); - slot->clickPressedCallback = clickPressedCallback; - slot->setSelectionWidth(selectionWidth); + GameResID::WOOD, GameResID::MERCURY, GameResID::ORE, + GameResID::SULFUR, GameResID::CRYSTAL, GameResID::GEMS, + GameResID::GOLD, + GameResID::GOLD, // TODO: remove + GameResID::GOLD, // TODO: remove + GameResID::GOLD // TODO: remove + }; + + int lines = vstd::divideAndCeil(resourcesForTrade.size(), 3); + if(lines > 3) + { + slider = std::make_shared(Point(240, 0), 224, [this](int to){ updateSlots(to); setRedrawParent(true); redraw(); }, 3, lines, 0, Orientation::VERTICAL, CSlider::BROWN); + slider->setPanningStep(72); + slider->setScrollBounds(Rect(-240, 0, 240, 224)); } - updateSlotsCallback = updateSubtitles; + + updateSlotsCallback = std::move(updateSubtitles); + + updateSlots(0); showcaseSlot = std::make_shared(Rect(selectedPos, slotDimension), EType::RESOURCE, 0, 0); } +void ResourcesPanel::updateSlots(int line) +{ + OBJECT_CONSTRUCTION; + + clickPressedCallback(nullptr); + + int offset = line * 3; + slots.clear(); + for (int i = 0; i < std::min(static_cast(resourcesForTrade.size() - offset), 9); i++) + { + const auto& res = resourcesForTrade[i + offset]; + auto slotPos = slotsPos[i]; + if(resourcesForTrade.size() == 7 && i == 6) // for 7 ressources place gold in the middle + slotPos = slotsPos[i + 1]; + + auto slotPtr = std::make_shared(Rect(slotPos, slotDimension), EType::RESOURCE, res.num, res.num); + slotPtr->clickPressedCallback = clickPressedCallback; + slotPtr->setSelectionWidth(selectionWidth); + slots.push_back(slotPtr); + } + + updateSlotsCallback(); +} + ArtifactsPanel::ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const UpdateSlotsFunctor & updateSubtitles, const std::vector & arts) { diff --git a/client/widgets/markets/TradePanels.h b/client/widgets/markets/TradePanels.h index 3e2610106..007f88d3f 100644 --- a/client/widgets/markets/TradePanels.h +++ b/client/widgets/markets/TradePanels.h @@ -14,6 +14,8 @@ #include "../../../lib/networkPacks/TradeItem.h" +class CSlider; + enum class EType { RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, ARTIFACT @@ -68,21 +70,21 @@ public: class ResourcesPanel : public TradePanelBase { - 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) + Point(0, 0), Point(83, 0), Point(166, 0), + Point(0, 79), Point(83, 79), Point(166, 79), + Point(0, 158), Point(83, 158), Point(166, 158) }; const Point slotDimension = Point(69, 66); const Point selectedPos = Point(83, 267); + CTradeableItem::ClickPressedFunctor clickPressedCallback; + + std::vector resourcesForTrade; + std::shared_ptr slider; + + void updateSlots(int line); public: ResourcesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const UpdateSlotsFunctor & updateSubtitles); }; diff --git a/client/windows/CMarketWindow.cpp b/client/windows/CMarketWindow.cpp index 95b567905..65aa26b62 100644 --- a/client/windows/CMarketWindow.cpp +++ b/client/windows/CMarketWindow.cpp @@ -200,11 +200,23 @@ std::string CMarketWindow::getMarketTitle(const ObjectInstanceID marketId, const return GAME->interface()->cb->getObj(marketId)->getObjectName(); } +ImagePath CMarketWindow::getImagePathBasedOnResources(std::string name) +{ + int res = 9; //TODO: replace with LIBRARY->resourceTypeHandler->getAllObjects(); + if(res == 8) + name += "-R8"; + else if(res > 8) + name += "-R9"; + return ImagePath::builtin(name); +} + void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero) { OBJECT_CONSTRUCTION; - background = createBg(ImagePath::builtin("TPMRKABS.bmp"), PLAYER_COLORED); + auto image = getImagePathBasedOnResources("TPMRKABS"); + + background = createBg(image, PLAYER_COLORED); marketWidget = std::make_shared(market, hero, getMarketTitle(market->getObjInstanceID(), EMarketMode::RESOURCE_ARTIFACT)); initWidgetInternals(EMarketMode::RESOURCE_ARTIFACT, LIBRARY->generaltexth->zelp[600]); } @@ -213,7 +225,9 @@ void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroI { OBJECT_CONSTRUCTION; - background = createBg(ImagePath::builtin("TPMRKASS.bmp"), PLAYER_COLORED); + auto image = getImagePathBasedOnResources("TPMRKASS"); + + background = createBg(image, 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), 0, 0); artSlotBack->moveTo(pos.topLeft() + Point(18, 339)); @@ -229,7 +243,9 @@ void CMarketWindow::createMarketResources(const IMarket * market, const CGHeroIn { OBJECT_CONSTRUCTION; - background = createBg(ImagePath::builtin("TPMRKRES.bmp"), PLAYER_COLORED); + auto image = getImagePathBasedOnResources("TPMRKRES"); + + background = createBg(image, PLAYER_COLORED); marketWidget = std::make_shared(market, hero); initWidgetInternals(EMarketMode::RESOURCE_RESOURCE, LIBRARY->generaltexth->zelp[600]); } @@ -238,7 +254,9 @@ void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroI { OBJECT_CONSTRUCTION; - background = createBg(ImagePath::builtin("TPMRKCRS.bmp"), PLAYER_COLORED); + auto image = getImagePathBasedOnResources("TPMRKCRS"); + + background = createBg(image, PLAYER_COLORED); marketWidget = std::make_shared(market, hero); initWidgetInternals(EMarketMode::CREATURE_RESOURCE, LIBRARY->generaltexth->zelp[600]); } @@ -247,7 +265,9 @@ void CMarketWindow::createTransferResources(const IMarket * market, const CGHero { OBJECT_CONSTRUCTION; - background = createBg(ImagePath::builtin("TPMRKPTS.bmp"), PLAYER_COLORED); + auto image = getImagePathBasedOnResources("TPMRKPTS"); + + background = createBg(image, PLAYER_COLORED); marketWidget = std::make_shared(market, hero); initWidgetInternals(EMarketMode::RESOURCE_PLAYER, LIBRARY->generaltexth->zelp[600]); } diff --git a/client/windows/CMarketWindow.h b/client/windows/CMarketWindow.h index f2874918e..6707aacdd 100644 --- a/client/windows/CMarketWindow.h +++ b/client/windows/CMarketWindow.h @@ -38,6 +38,8 @@ private: void createAltarArtifacts(const IMarket * market, const CGHeroInstance * hero); void createAltarCreatures(const IMarket * market, const CGHeroInstance * hero); + ImagePath getImagePathBasedOnResources(std::string name); + const int buttonHeightWithMargin = 32 + 3; std::vector> changeModeButtons; std::shared_ptr quitButton;