1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-23 21:29:13 +02:00

Refactoring. Regressions fixing.

This commit is contained in:
SoundSSGood 2024-03-02 20:30:29 +02:00
parent 433d55cac3
commit cc14f85445
33 changed files with 321 additions and 262 deletions

@ -130,7 +130,7 @@ set(client_SRCS
widgets/markets/CFreelancerGuild.cpp widgets/markets/CFreelancerGuild.cpp
widgets/markets/CMarketResources.cpp widgets/markets/CMarketResources.cpp
widgets/markets/CTransferResources.cpp widgets/markets/CTransferResources.cpp
widgets/markets/CTradeBase.cpp widgets/markets/CMarketBase.cpp
widgets/markets/TradePanels.cpp widgets/markets/TradePanels.cpp
windows/CCastleInterface.cpp windows/CCastleInterface.cpp
@ -318,7 +318,7 @@ set(client_HEADERS
widgets/markets/CFreelancerGuild.h widgets/markets/CFreelancerGuild.h
widgets/markets/CMarketResources.h widgets/markets/CMarketResources.h
widgets/markets/CTransferResources.h widgets/markets/CTransferResources.h
widgets/markets/CTradeBase.h widgets/markets/CMarketBase.h
widgets/markets/TradePanels.h widgets/markets/TradePanels.h
windows/CCastleInterface.h windows/CCastleInterface.h

@ -216,6 +216,12 @@ void CButton::setActOnDown(bool on)
actOnDown = on; actOnDown = on;
} }
void CButton::setHelp(const std::pair<std::string, std::string> & help)
{
hoverTexts[0] = help.first;
helpBox = help.second;
}
void CButton::block(bool on) void CButton::block(bool on)
{ {
if(on || getState() == EButtonState::BLOCKED) //dont change button state if unblock requested, but it's not blocked if(on || getState() == EButtonState::BLOCKED) //dont change button state if unblock requested, but it's not blocked

@ -98,6 +98,7 @@ public:
void setHoverable(bool on); void setHoverable(bool on);
void setSoundDisabled(bool on); void setSoundDisabled(bool on);
void setActOnDown(bool on); void setActOnDown(bool on);
void setHelp(const std::pair<std::string, std::string> & help);
/// State modifiers /// State modifiers
bool isBlocked(); bool isBlocked();

@ -56,11 +56,11 @@ void CArtifactsOfHeroBackpack::onSliderMoved(int newVal)
redraw(); redraw();
} }
void CArtifactsOfHeroBackpack::updateBackpackSlots() void CArtifactsOfHeroBackpack::updateBackpackSlots(const std::optional<const ArtifactPosition> & removedSlot)
{ {
if(backpackListBox) if(backpackListBox)
backpackListBox->resize(getActiveSlotRowsNum()); backpackListBox->resize(getActiveSlotRowsNum());
CArtifactsOfHeroBase::updateBackpackSlots(); CArtifactsOfHeroBase::updateBackpackSlots(removedSlot);
} }
size_t CArtifactsOfHeroBackpack::getActiveSlotRowsNum() size_t CArtifactsOfHeroBackpack::getActiveSlotRowsNum()

@ -24,8 +24,8 @@ class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase
public: public:
CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax); CArtifactsOfHeroBackpack(size_t slotsColumnsMax, size_t slotsRowsMax);
CArtifactsOfHeroBackpack(); CArtifactsOfHeroBackpack();
void onSliderMoved(int newVal); void onSliderMoved(int newVal);;
void updateBackpackSlots() override; void updateBackpackSlots(const std::optional<const ArtifactPosition> & removedSlot = std::nullopt) override;
size_t getActiveSlotRowsNum(); size_t getActiveSlotRowsNum();
size_t getSlotsNum(); size_t getSlotsNum();

@ -180,7 +180,7 @@ void CArtifactsOfHeroBase::updateWornSlots()
updateSlot(place.first); updateSlot(place.first);
} }
void CArtifactsOfHeroBase::updateBackpackSlots() void CArtifactsOfHeroBase::updateBackpackSlots(const std::optional<const ArtifactPosition> & removedSlot)
{ {
ArtifactPosition slot = ArtifactPosition::BACKPACK_START; ArtifactPosition slot = ArtifactPosition::BACKPACK_START;
for(const auto & artPlace : backpack) for(const auto & artPlace : backpack)

@ -41,7 +41,7 @@ public:
virtual void unmarkSlots(); virtual void unmarkSlots();
virtual ArtPlacePtr getArtPlace(const ArtifactPosition & slot); virtual ArtPlacePtr getArtPlace(const ArtifactPosition & slot);
virtual void updateWornSlots(); virtual void updateWornSlots();
virtual void updateBackpackSlots(); virtual void updateBackpackSlots(const std::optional<const ArtifactPosition> & removedSlot = std::nullopt);
virtual void updateSlot(const ArtifactPosition & slot); virtual void updateSlot(const ArtifactPosition & slot);
virtual const CArtifactInstance * getPickedArtifact(); virtual const CArtifactInstance * getPickedArtifact();
void addGestureCallback(CArtPlace::ClickFunctor callback); void addGestureCallback(CArtPlace::ClickFunctor callback);

@ -12,7 +12,7 @@
#include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/CGHeroInstance.h"
CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position) CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position, const int selectionWidth)
{ {
init( init(
std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2), std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2),
@ -21,9 +21,9 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position)
std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1)); std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1));
for(const auto & [slot, artPlace] : artWorn) for(const auto & [slot, artPlace] : artWorn)
artPlace->setSelectionWidth(2); artPlace->setSelectionWidth(selectionWidth);
for(auto artPlace : backpack) for(auto artPlace : backpack)
artPlace->setSelectionWidth(2); artPlace->setSelectionWidth(selectionWidth);
}; };
void CArtifactsOfHeroMarket::scrollBackpack(bool left) void CArtifactsOfHeroMarket::scrollBackpack(bool left)

@ -16,6 +16,6 @@ class CArtifactsOfHeroMarket : public CArtifactsOfHeroBase
public: public:
std::function<void(CArtPlace*)> selectArtCallback; std::function<void(CArtPlace*)> selectArtCallback;
CArtifactsOfHeroMarket(const Point & position); CArtifactsOfHeroMarket(const Point & position, const int selectionWidth);
void scrollBackpack(bool left) override; void scrollBackpack(bool left) override;
}; };

@ -277,7 +277,7 @@ void CWindowWithArtifacts::gestureArtPlaceHero(CArtifactsOfHeroBase & artsInst,
void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc) void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation & artLoc)
{ {
updateSlots(); updateSlots(artLoc.slot);
} }
void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
@ -361,14 +361,14 @@ void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation & artLoc)
updateSlots(); 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()) if(const auto artSetPtr = artSetWeak.lock())
{ {
artSetPtr->updateWornSlots(); artSetPtr->updateWornSlots();
artSetPtr->updateBackpackSlots(); artSetPtr->updateBackpackSlots(removedSlot);
artSetPtr->redraw(); artSetPtr->redraw();
} }
}; };

@ -46,7 +46,7 @@ protected:
std::vector<CArtifactsOfHeroPtr> artSets; std::vector<CArtifactsOfHeroPtr> artSets;
CloseCallback closeCallback; CloseCallback closeCallback;
void updateSlots(); void updateSlots(const ArtifactPosition & removedSlot = ArtifactPosition::PRE_FIRST);
std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> getState(); std::optional<std::tuple<const CGHeroInstance*, const CArtifactInstance*>> getState();
std::optional<CArtifactsOfHeroPtr> findAOHbyRef(CArtifactsOfHeroBase & artsInst); std::optional<CArtifactsOfHeroPtr> findAOHbyRef(CArtifactsOfHeroBase & artsInst);
void markPossibleSlots(); void markPossibleSlots();

@ -175,7 +175,7 @@ bool CSlider::receiveEvent(const Point &position, int eventType) const
return testTarget.isInside(position); return testTarget.isInside(position);
} }
CSlider::CSlider(Point position, int totalw, const std::function<void(int)> & 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 ), : Scrollable(LCLICK | DRAG, position, orientation ),
capacity(Capacity), capacity(Capacity),
amount(Amount), amount(Amount),

@ -75,13 +75,15 @@ public:
void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
void showAll(Canvas & to) override; void showAll(Canvas & to) override;
using SliderMovingFunctor = std::function<void(int)>;
/// @param position coordinates of slider /// @param position coordinates of slider
/// @param length length of slider ribbon, including left/right buttons /// @param length length of slider ribbon, including left/right buttons
/// @param Moved function that will be called whenever slider moves /// @param Moved function that will be called whenever slider moves
/// @param Capacity maximal number of visible at once elements /// @param Capacity maximal number of visible at once elements
/// @param Amount total amount of elements, including not visible /// @param Amount total amount of elements, including not visible
/// @param Value starting position /// @param Value starting position
CSlider(Point position, int length, const std::function<void(int)> & Moved, int Capacity, int Amount, CSlider(Point position, int length, const SliderMovingFunctor & Moved, int Capacity, int Amount,
int Value, Orientation orientation, EStyle style = BROWN); int Value, Orientation orientation, EStyle style = BROWN);
~CSlider(); ~CSlider();
}; };

@ -26,16 +26,16 @@
#include "../../../lib/mapObjects/CGMarket.h" #include "../../../lib/mapObjects/CGMarket.h"
CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * hero) 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); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
assert(market); assert(dynamic_cast<const CGArtifactsAltar*>(market));
auto altarObj = dynamic_cast<const CGArtifactsAltar*>(market); auto altarObj = dynamic_cast<const CGArtifactsAltar*>(market);
altarId = altarObj->id; altarId = altarObj->id;
altarArtifacts = altarObj; altarArtifacts = altarObj;
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("ALTSACR.DEF"), deal = std::make_shared<CButton>(Point(269, 520), AnimationPath::builtin("ALTSACR.DEF"),
CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); }); CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); });
labels.emplace_back(std::make_shared<CLabel>(450, 32, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477])); labels.emplace_back(std::make_shared<CLabel>(450, 32, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]));
labels.emplace_back(std::make_shared<CLabel>(302, 424, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478])); labels.emplace_back(std::make_shared<CLabel>(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->updateSlotsCallback = std::bind(&CAltarArtifacts::updateAltarSlots, this);
offerTradePanel->moveTo(pos.topLeft() + Point(315, 52)); offerTradePanel->moveTo(pos.topLeft() + Point(315, 52));
CTradeBase::updateSelected(); CMarketBase::updateSelected();
CAltarArtifacts::deselect(); CAltarArtifacts::deselect();
}; };
@ -75,8 +75,8 @@ TExpType CAltarArtifacts::calcExpAltarForHero()
void CAltarArtifacts::deselect() void CAltarArtifacts::deselect()
{ {
CTradeBase::deselect(); CMarketBase::deselect();
expForHero->setText(std::to_string(0)); CExperienceAltar::deselect();
tradeSlotsMap.clear(); tradeSlotsMap.clear();
// The event for removing artifacts from the altar will not be triggered. Therefore, we clean the altar immediately. // The event for removing artifacts from the altar will not be triggered. Therefore, we clean the altar immediately.
for(auto & slot : offerTradePanel->slots) 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)) if(const auto art = hero->getArt(ArtifactPosition::TRANSITION_POS))
{ {
hRight = offerTradePanel->selectedSlot; hRight = offerTradePanel->selectedSlot;
@ -189,7 +190,7 @@ void CAltarArtifacts::putBackArtifacts()
LOCPLINT->cb->bulkMoveArtifacts(altarId, heroArts->getHero()->id, false, true, true); LOCPLINT->cb->bulkMoveArtifacts(altarId, heroArts->getHero()->id, false, true, true);
} }
CTradeBase::SelectionParams CAltarArtifacts::getSelectionParams() const CMarketBase::SelectionParams CAltarArtifacts::getSelectionParams() const
{ {
if(hRight) if(hRight)
return std::make_tuple( return std::make_tuple(

@ -10,7 +10,7 @@
#pragma once #pragma once
#include "../CArtifactsOfHeroAltar.h" #include "../CArtifactsOfHeroAltar.h"
#include "CTradeBase.h" #include "CMarketBase.h"
class CAltarArtifacts : public CExperienceAltar class CAltarArtifacts : public CExperienceAltar
{ {
@ -19,7 +19,7 @@ public:
TExpType calcExpAltarForHero() override; TExpType calcExpAltarForHero() override;
void deselect() override; void deselect() override;
void makeDeal() override; void makeDeal() override;
void updateSlots() override; void update() override;
void sacrificeAll() override; void sacrificeAll() override;
void sacrificeBackpack(); void sacrificeBackpack();
std::shared_ptr<CArtifactsOfHeroAltar> getAOHset() const; std::shared_ptr<CArtifactsOfHeroAltar> getAOHset() const;
@ -33,7 +33,7 @@ private:
std::map<std::shared_ptr<CTradeableItem>, const CArtifactInstance*> tradeSlotsMap; std::map<std::shared_ptr<CTradeableItem>, const CArtifactInstance*> tradeSlotsMap;
void updateAltarSlots(); void updateAltarSlots();
CTradeBase::SelectionParams getSelectionParams() const override; CMarketBase::SelectionParams getSelectionParams() const override;
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & altarSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override; void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & altarSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
TExpType calcExpCost(ArtifactID id); TExpType calcExpCost(ArtifactID id);
}; };

@ -13,7 +13,6 @@
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h"
#include "../../widgets/TextControls.h" #include "../../widgets/TextControls.h"
#include "../../CGameInfo.h" #include "../../CGameInfo.h"
@ -26,18 +25,19 @@
#include "../../../lib/mapObjects/CGMarket.h" #include "../../../lib/mapObjects/CGMarket.h"
CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero) 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); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("ALTSACR.DEF"), deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("ALTSACR.DEF"),
CGI->generaltexth->zelp[584], [this]() {CAltarCreatures::makeDeal();}); CGI->generaltexth->zelp[584], [this]() {CAltarCreatures::makeDeal();});
labels.emplace_back(std::make_shared<CLabel>(155, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, labels.emplace_back(std::make_shared<CLabel>(155, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW,
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated()))); boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
labels.emplace_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479])); labels.emplace_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]));
texts.emplace_back(std::make_unique<CTextBox>(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW)); texts.emplace_back(std::make_unique<CTextBox>(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
offerSlider = std::make_shared<CSlider>(Point(231, 481), 137, std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL); offerSlider->moveTo(pos.topLeft() + Point(231, 481));
maxAmount = std::make_shared<CButton>(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, offerSlider)); maxAmount->setHelp(CGI->generaltexth->zelp[578]);
unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0); unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0);
expPerUnit.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; int sliderAmount = 0;
if(hLeft) if(hLeft)
@ -111,19 +111,21 @@ void CAltarCreatures::updateControls()
if(hLeft) if(hLeft)
offerSlider->scrollTo(unitsOnAltar[hLeft->serial]); offerSlider->scrollTo(unitsOnAltar[hLeft->serial]);
maxAmount->block(offerSlider->getAmount() == 0); 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()); assert(bidTradePanel->slots.size() == offerTradePanel->slots.size());
} }
void CAltarCreatures::deselect() void CAltarCreatures::deselect()
{ {
CTradeBase::deselect(); CMarketBase::deselect();
updateSelected(); CExperienceAltar::deselect();
expForHero->setText(std::to_string(0)); CMarketSlider::deselect();
} }
TExpType CAltarCreatures::calcExpAltarForHero() TExpType CAltarCreatures::calcExpAltarForHero()
@ -139,8 +141,6 @@ TExpType CAltarCreatures::calcExpAltarForHero()
void CAltarCreatures::makeDeal() void CAltarCreatures::makeDeal()
{ {
deselect();
std::vector<TradeItemSell> ids; std::vector<TradeItemSell> ids;
std::vector<ui32> toSacrifice; std::vector<ui32> toSacrifice;
@ -163,9 +163,10 @@ void CAltarCreatures::makeDeal()
heroSlot->setType(EType::CREATURE_PLACEHOLDER); heroSlot->setType(EType::CREATURE_PLACEHOLDER);
heroSlot->subtitle->clear(); heroSlot->subtitle->clear();
} }
deselect();
} }
CTradeBase::SelectionParams CAltarCreatures::getSelectionParams() const CMarketBase::SelectionParams CAltarCreatures::getSelectionParams() const
{ {
std::optional<SelectionParamOneSide> bidSelected = std::nullopt; std::optional<SelectionParamOneSide> bidSelected = std::nullopt;
std::optional<SelectionParamOneSide> offerSelected = std::nullopt; std::optional<SelectionParamOneSide> offerSelected = std::nullopt;
@ -197,7 +198,7 @@ void CAltarCreatures::sacrificeAll()
if(hRight) if(hRight)
offerSlider->scrollTo(unitsOnAltar[hRight->serial]); offerSlider->scrollTo(unitsOnAltar[hRight->serial]);
offerTradePanel->updateSlots(); offerTradePanel->update();
updateSelected(); updateSelected();
deal->block(calcExpAltarForHero() == 0); deal->block(calcExpAltarForHero() == 0);
@ -218,8 +219,7 @@ void CAltarCreatures::onOfferSliderMoved(int newVal)
if(hRight) if(hRight)
updateAltarSlot(hRight); updateAltarSlot(hRight);
deal->block(calcExpAltarForHero() == 0); deal->block(calcExpAltarForHero() == 0);
updateControls(); highlightingChanged();
updateSelected();
redraw(); redraw();
} }
@ -230,7 +230,7 @@ void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
auto * oppositeSlot = &hLeft; auto * oppositeSlot = &hLeft;
auto oppositePanel = bidTradePanel; auto oppositePanel = bidTradePanel;
CTradeBase::onSlotClickPressed(newSlot, hCurSlot); CMarketBase::onSlotClickPressed(newSlot, hCurSlot);
if(hCurSlot == hLeft) if(hCurSlot == hLeft)
{ {
oppositeSlot = &hRight; oppositeSlot = &hRight;
@ -244,8 +244,7 @@ void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
break; break;
} }
assert(oppositeNewSlot); assert(oppositeNewSlot);
CTradeBase::onSlotClickPressed(oppositeNewSlot, *oppositeSlot); CMarketBase::onSlotClickPressed(oppositeNewSlot, *oppositeSlot);
updateControls(); highlightingChanged();
updateSelected();
redraw(); redraw();
} }

@ -9,13 +9,13 @@
*/ */
#pragma once #pragma once
#include "CTradeBase.h" #include "CMarketBase.h"
class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling, public CMarketSlider
{ {
public: public:
CAltarCreatures(const IMarket * market, const CGHeroInstance * hero); CAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
void updateSlots() override; void update() override;
void deselect() override; void deselect() override;
TExpType calcExpAltarForHero() override; TExpType calcExpAltarForHero() override;
void makeDeal() override; void makeDeal() override;
@ -25,10 +25,10 @@ private:
std::vector<int> unitsOnAltar; std::vector<int> unitsOnAltar;
std::vector<int> expPerUnit; std::vector<int> expPerUnit;
CTradeBase::SelectionParams getSelectionParams() const override; CMarketBase::SelectionParams getSelectionParams() const override;
void updateAltarSlot(const std::shared_ptr<CTradeableItem> & slot); void updateAltarSlot(const std::shared_ptr<CTradeableItem> & slot);
void readExpValues(); void readExpValues();
void updateControls(); void highlightingChanged();
void onOfferSliderMoved(int newVal); void onOfferSliderMoved(int newVal) override;
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override; void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
}; };

@ -13,7 +13,6 @@
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h"
#include "../../widgets/TextControls.h" #include "../../widgets/TextControls.h"
#include "../../CGameInfo.h" #include "../../CGameInfo.h"
@ -26,15 +25,18 @@
#include "../../../lib/mapObjects/CGTownInstance.h" #include "../../../lib/mapObjects/CGTownInstance.h"
CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero) 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<CTradeableItem> & heroSlot){CArtifactsBuying::onSlotClickPressed(heroSlot, hLeft);}) , CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CArtifactsBuying::onSlotClickPressed(heroSlot, hLeft);})
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
assert(dynamic_cast<const CGTownInstance*>(market)); std::string title;
labels.emplace_back(std::make_shared<CLabel>(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, if(auto townMarket = dynamic_cast<const CGTownInstance*>(market))
(*CGI->townh)[dynamic_cast<const CGTownInstance*>(market)->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated())); title = (*CGI->townh)[townMarket->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
deal = std::make_shared<CButton>(Point(270, 520), AnimationPath::builtin("TPMRKB.DEF"), else
title = "Black market"; // find string allTexts!!
labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title));
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"),
CGI->generaltexth->zelp[595], [this](){CArtifactsBuying::makeDeal();}); CGI->generaltexth->zelp[595], [this](){CArtifactsBuying::makeDeal();});
labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168])); labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
@ -49,7 +51,7 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
CArtifactsBuying::onSlotClickPressed(newSlot, hRight); CArtifactsBuying::onSlotClickPressed(newSlot, hRight);
}, [this]() }, [this]()
{ {
CTradeBase::updateSubtitles(EMarketMode::RESOURCE_ARTIFACT); CMarketBase::updateSubtitles(EMarketMode::RESOURCE_ARTIFACT);
}, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT)); }, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT));
offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot) offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
{ {
@ -57,8 +59,8 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
}; };
offerTradePanel->moveTo(pos.topLeft() + Point(328, 181)); offerTradePanel->moveTo(pos.topLeft() + Point(328, 181));
CTradeBase::updateSlots(); CMarketBase::update();
CTradeBase::deselect(); CMarketBase::deselect();
} }
void CArtifactsBuying::makeDeal() void CArtifactsBuying::makeDeal()
@ -67,7 +69,7 @@ void CArtifactsBuying::makeDeal()
deselect(); deselect();
} }
CTradeBase::SelectionParams CArtifactsBuying::getSelectionParams() const CMarketBase::SelectionParams CArtifactsBuying::getSelectionParams() const
{ {
if(hLeft && hRight) if(hLeft && hRight)
return std::make_tuple( return std::make_tuple(
@ -77,12 +79,8 @@ CTradeBase::SelectionParams CArtifactsBuying::getSelectionParams() const
return std::make_tuple(std::nullopt, std::nullopt); return std::make_tuple(std::nullopt, std::nullopt);
} }
void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) void CArtifactsBuying::highlightingChanged()
{ {
if(newSlot == hCurSlot)
return;
CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
if(hLeft) if(hLeft)
{ {
if(hRight) if(hRight)
@ -90,8 +88,18 @@ void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::RESOURCE_ARTIFACT); market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::RESOURCE_ARTIFACT);
deal->block(LOCPLINT->cb->getResourceAmount(GameResID(hLeft->id)) >= bidQty ? false : true); deal->block(LOCPLINT->cb->getResourceAmount(GameResID(hLeft->id)) >= bidQty ? false : true);
} }
updateSelected(); offerTradePanel->update();
offerTradePanel->updateSlots();
} }
updateSelected();
}
void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
assert(newSlot);
if(newSlot == hCurSlot)
return;
CMarketBase::onSlotClickPressed(newSlot, hCurSlot);
highlightingChanged();
redraw(); redraw();
} }

@ -9,7 +9,7 @@
*/ */
#pragma once #pragma once
#include "CTradeBase.h" #include "CMarketBase.h"
class CArtifactsBuying : public CResourcesSelling class CArtifactsBuying : public CResourcesSelling
{ {
@ -18,6 +18,7 @@ public:
void makeDeal() override; void makeDeal() override;
private: private:
CTradeBase::SelectionParams getSelectionParams() const override; CMarketBase::SelectionParams getSelectionParams() const override;
void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot); void highlightingChanged();
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot);
}; };

@ -13,7 +13,6 @@
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h"
#include "../../widgets/TextControls.h" #include "../../widgets/TextControls.h"
#include "../../CGameInfo.h" #include "../../CGameInfo.h"
@ -25,21 +24,31 @@
#include "../../../lib/CGeneralTextHandler.h" #include "../../../lib/CGeneralTextHandler.h"
#include "../../../lib/mapObjects/CGHeroInstance.h" #include "../../../lib/mapObjects/CGHeroInstance.h"
#include "../../../lib/mapObjects/CGMarket.h" #include "../../../lib/mapObjects/CGMarket.h"
#include "../../../lib/mapObjects/CGTownInstance.h"
CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero) CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero, [this](){return CArtifactsSelling::getSelectionParams();}) : CMarketBase(market, hero, [this](){return CArtifactsSelling::getSelectionParams();})
, CResourcesBuying( , CResourcesBuying(
[this](const std::shared_ptr<CTradeableItem> & resSlot){CArtifactsSelling::onSlotClickPressed(resSlot, hRight);}, [this](const std::shared_ptr<CTradeableItem> & resSlot){CArtifactsSelling::onSlotClickPressed(resSlot, hRight);},
[this](){CTradeBase::updateSubtitles(EMarketMode::ARTIFACT_RESOURCE);}) [this](){CMarketBase::updateSubtitles(EMarketMode::ARTIFACT_RESOURCE);})
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
deal = std::make_shared<CButton>(Point(270, 520), AnimationPath::builtin("TPMRKB.DEF"), labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,
(*CGI->townh)[dynamic_cast<const CGTownInstance*>(market)->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated()));
labels.push_back(std::make_shared<CLabel>(155, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated())));
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"),
CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();}); CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();});
bidSelectedSlot = std::make_shared<CTradeableItem>(Rect(Point(123, 470), Point(69, 66)), EType::ARTIFACT_TYPE, 0, 0); bidSelectedSlot = std::make_shared<CTradeableItem>(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 // Hero's artifacts
heroArts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46)); heroArts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46), offerTradePanel->selectionWidth);
heroArts->setHero(hero); heroArts->setHero(hero);
heroArts->selectArtCallback = [this](CArtPlace * artPlace) heroArts->selectArtCallback = [this](CArtPlace * artPlace)
{ {
@ -49,29 +58,18 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc
bidSelectedSlot->setID(artForTrade->getTypeId().num); bidSelectedSlot->setID(artForTrade->getTypeId().num);
hLeft = bidSelectedSlot; hLeft = bidSelectedSlot;
selectedHeroSlot = artPlace->slot; selectedHeroSlot = artPlace->slot;
if(hRight) CArtifactsSelling::highlightingChanged();
{ // dublicate offerTradePanel->update();
this->market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
deal->block(false);
}
CArtifactsSelling::updateSelected();
offerTradePanel->updateSlots();
redraw(); 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::updateSelected();
CArtifactsSelling::deselect(); CArtifactsSelling::deselect();
} }
void CArtifactsSelling::deselect() void CArtifactsSelling::deselect()
{ {
CTradeBase::deselect(); CMarketBase::deselect();
selectedHeroSlot = ArtifactPosition::PRE_FIRST; selectedHeroSlot = ArtifactPosition::PRE_FIRST;
heroArts->unmarkSlots(); heroArts->unmarkSlots();
} }
@ -85,7 +83,7 @@ void CArtifactsSelling::makeDeal()
void CArtifactsSelling::updateSelected() void CArtifactsSelling::updateSelected()
{ {
CTradeBase::updateSelected(); CMarketBase::updateSelected();
if(hLeft && hRight) 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 != ArtifactPosition::PRE_FIRST)
{ {
if(selectedHeroSlot.num >= ArtifactPosition::BACKPACK_START + hero->artifactsInBackpack.size())
{
selectedHeroSlot = ArtifactPosition::BACKPACK_START;
deselect();
}
if(hero->getArt(selectedHeroSlot) == nullptr) if(hero->getArt(selectedHeroSlot) == nullptr)
deselect(); deselect();
} }
@ -116,7 +119,7 @@ std::shared_ptr<CArtifactsOfHeroMarket> CArtifactsSelling::getAOHset() const
return heroArts; return heroArts;
} }
CTradeBase::SelectionParams CArtifactsSelling::getSelectionParams() const CMarketBase::SelectionParams CArtifactsSelling::getSelectionParams() const
{ {
if(hLeft && hRight) if(hLeft && hRight)
return std::make_tuple( return std::make_tuple(
@ -127,21 +130,23 @@ CTradeBase::SelectionParams CArtifactsSelling::getSelectionParams() const
return std::make_tuple(std::nullopt, std::nullopt); return std::make_tuple(std::nullopt, std::nullopt);
} }
void CArtifactsSelling::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) void CArtifactsSelling::highlightingChanged()
{ {
assert(newSlot); if(hLeft && hRight)
if(newSlot == hCurSlot)
return;
CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
if(hLeft)
{
if(hRight)
{ {
market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE); market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
deal->block(false); deal->block(false);
} }
updateSelected(); updateSelected();
} }
void CArtifactsSelling::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
assert(newSlot);
if(newSlot == hCurSlot)
return;
CMarketBase::onSlotClickPressed(newSlot, hCurSlot);
highlightingChanged();
redraw(); redraw();
} }

@ -10,7 +10,7 @@
#pragma once #pragma once
#include "../CArtifactsOfHeroMarket.h" #include "../CArtifactsOfHeroMarket.h"
#include "CTradeBase.h" #include "CMarketBase.h"
class CArtifactsSelling : public CResourcesBuying class CArtifactsSelling : public CResourcesBuying
{ {
@ -19,7 +19,7 @@ public:
void deselect() override; void deselect() override;
void makeDeal() override; void makeDeal() override;
void updateSelected() override; void updateSelected() override;
void updateSlots() override; void update() override;
std::shared_ptr<CArtifactsOfHeroMarket> getAOHset() const; std::shared_ptr<CArtifactsOfHeroMarket> getAOHset() const;
private: private:
@ -28,6 +28,7 @@ private:
std::shared_ptr<CTradeableItem> bidSelectedSlot; std::shared_ptr<CTradeableItem> bidSelectedSlot;
ArtifactPosition selectedHeroSlot; ArtifactPosition selectedHeroSlot;
CTradeBase::SelectionParams getSelectionParams() const override; CMarketBase::SelectionParams getSelectionParams() const override;
void highlightingChanged();
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override; void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
}; };

@ -13,7 +13,6 @@
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h"
#include "../../widgets/TextControls.h" #include "../../widgets/TextControls.h"
#include "../../CGameInfo.h" #include "../../CGameInfo.h"
@ -27,25 +26,21 @@
#include "../../../lib/mapObjects/CGTownInstance.h" #include "../../../lib/mapObjects/CGTownInstance.h"
CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero) CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero, [this](){return CFreelancerGuild::getSelectionParams();}) : CMarketBase(market, hero, [this](){return CFreelancerGuild::getSelectionParams();})
, CResourcesBuying( , CResourcesBuying(
[this](const std::shared_ptr<CTradeableItem> & heroSlot){CFreelancerGuild::onSlotClickPressed(heroSlot, hLeft);}, [this](const std::shared_ptr<CTradeableItem> & 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); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
labels.emplace_back(std::make_shared<CLabel>(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,
(*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated())); (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated()));
labels.emplace_back(std::make_shared<CLabel>(155, 103, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, labels.emplace_back(std::make_shared<CLabel>(155, 103, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE,
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated()))); boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
deal = std::make_shared<CButton>(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"), deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();}); CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();});
maxAmount = std::make_shared<CButton>(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], offerSlider->moveTo(pos.topLeft() + Point(232, 489));
[this]() {offerSlider->scrollToMax();});
offerSlider = std::make_shared<CSlider>(Point(232, 489), 137, [this](int newVal)
{
CFreelancerGuild::onOfferSliderMoved(newVal);
}, 0, 0, 0, Orientation::HORIZONTAL);
// Hero creatures panel // Hero creatures panel
assert(bidTradePanel); 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() void CFreelancerGuild::makeDeal()
@ -82,7 +83,7 @@ void CFreelancerGuild::makeDeal()
} }
} }
CTradeBase::SelectionParams CFreelancerGuild::getSelectionParams() const CMarketBase::SelectionParams CFreelancerGuild::getSelectionParams() const
{ {
if(hLeft && hRight) if(hLeft && hRight)
return std::make_tuple( return std::make_tuple(
@ -92,22 +93,8 @@ CTradeBase::SelectionParams CFreelancerGuild::getSelectionParams() const
return std::make_tuple(std::nullopt, std::nullopt); 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<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
if(newSlot == hCurSlot)
return;
CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
if(hLeft) if(hLeft)
{ {
if(hRight) if(hRight)
@ -119,8 +106,18 @@ void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
maxAmount->block(false); maxAmount->block(false);
deal->block(false); deal->block(false);
} }
updateSelected(); offerTradePanel->update();
offerTradePanel->updateSlots();
} }
updateSelected();
}
void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
assert(newSlot);
if(newSlot == hCurSlot)
return;
CMarketBase::onSlotClickPressed(newSlot, hCurSlot);
highlightingChanged();
redraw(); redraw();
} }

@ -9,16 +9,17 @@
*/ */
#pragma once #pragma once
#include "CTradeBase.h" #include "CMarketBase.h"
class CFreelancerGuild : public CCreaturesSelling , public CResourcesBuying class CFreelancerGuild : public CCreaturesSelling , public CResourcesBuying, public CMarketSlider
{ {
public: public:
CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero); CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero);
void deselect() override;
void makeDeal() override; void makeDeal() override;
private: private:
CTradeBase::SelectionParams getSelectionParams() const override; CMarketBase::SelectionParams getSelectionParams() const override;
void onOfferSliderMoved(int newVal); void highlightingChanged();
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override; void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
}; };

@ -1,5 +1,5 @@
/* /*
* CTradeBase.cpp, part of VCMI engine * CMarketBase.cpp, part of VCMI engine
* *
* Authors: listed in file AUTHORS in main folder * Authors: listed in file AUTHORS in main folder
* *
@ -8,14 +8,13 @@
* *
*/ */
#include "StdInc.h" #include "StdInc.h"
#include "CTradeBase.h" #include "CMarketBase.h"
#include "../MiscWidgets.h" #include "../MiscWidgets.h"
#include "../Images.h" #include "../Images.h"
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h"
#include "../../widgets/TextControls.h" #include "../../widgets/TextControls.h"
#include "../../CGameInfo.h" #include "../../CGameInfo.h"
@ -28,14 +27,14 @@
#include "../../../lib/CHeroHandler.h" #include "../../../lib/CHeroHandler.h"
#include "../../../lib/mapObjects/CGMarket.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) : market(market)
, hero(hero) , hero(hero)
, selectionParamsCallback(getParamsCallback) , selectionParamsCallback(getParamsCallback)
{ {
} }
void CTradeBase::deselect() void CMarketBase::deselect()
{ {
if(hLeft) if(hLeft)
hLeft->selectSlot(false); hLeft->selectSlot(false);
@ -43,19 +42,12 @@ void CTradeBase::deselect()
hRight->selectSlot(false); hRight->selectSlot(false);
hLeft = hRight = nullptr; hLeft = hRight = nullptr;
deal->block(true); deal->block(true);
if(maxAmount)
maxAmount->block(true);
if(offerSlider)
{
offerSlider->scrollTo(0);
offerSlider->block(true);
}
bidQty = 0; bidQty = 0;
offerQty = 0; offerQty = 0;
updateSelected(); updateSelected();
} }
void CTradeBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) void CMarketBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{ {
if(newSlot == hCurSlot) if(newSlot == hCurSlot)
return; return;
@ -66,15 +58,15 @@ void CTradeBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newS
newSlot->selectSlot(true); newSlot->selectSlot(true);
} }
void CTradeBase::updateSlots() void CMarketBase::update()
{ {
if(bidTradePanel) if(bidTradePanel)
bidTradePanel->updateSlots(); bidTradePanel->update();
if(offerTradePanel) if(offerTradePanel)
offerTradePanel->updateSlots(); offerTradePanel->update();
} }
void CTradeBase::updateSubtitles(EMarketMode marketMode) void CMarketBase::updateSubtitles(EMarketMode marketMode)
{ {
if(hLeft) if(hLeft)
for(const auto & slot : offerTradePanel->slots) for(const auto & slot : offerTradePanel->slots)
@ -88,7 +80,7 @@ void CTradeBase::updateSubtitles(EMarketMode marketMode)
offerTradePanel->clearSubtitles(); offerTradePanel->clearSubtitles();
}; };
void CTradeBase::updateSelected() void CMarketBase::updateSelected()
{ {
const auto updateSelectedBody = [](std::shared_ptr<TradePanelBase> & tradePanel, const std::optional<const SelectionParamOneSide> & params) const auto updateSelectedBody = [](std::shared_ptr<TradePanelBase> & tradePanel, const std::optional<const SelectionParamOneSide> & params)
{ {
@ -125,9 +117,13 @@ CExperienceAltar::CExperienceAltar()
expForHero = std::make_shared<CLabel>(76, 545, FONT_SMALL, ETextAlignment::CENTER); expForHero = std::make_shared<CLabel>(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)); 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) for(const auto & slot : bidTradePanel->slots)
slot->subtitle->setText(std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)))); slot->subtitle->setText(std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial))));
} }
CMarketSlider::CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback)
{
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
offerSlider = std::make_shared<CSlider>(Point(230, 489), 137, movingCallback, 0, 0, 0, Orientation::HORIZONTAL);
maxAmount = std::make_shared<CButton>(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();
}
}

@ -1,5 +1,5 @@
/* /*
* CTradeBase.h, part of VCMI engine * CMarketBase.h, part of VCMI engine
* *
* Authors: listed in file AUTHORS in main folder * Authors: listed in file AUTHORS in main folder
* *
@ -10,6 +10,7 @@
#pragma once #pragma once
#include "TradePanels.h" #include "TradePanels.h"
#include "../../widgets/Slider.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@ -21,7 +22,7 @@ VCMI_LIB_NAMESPACE_END
class CButton; class CButton;
class CSlider; class CSlider;
class CTradeBase : public CIntObject class CMarketBase : public CIntObject
{ {
public: public:
struct SelectionParamOneSide struct SelectionParamOneSide
@ -42,42 +43,42 @@ public:
std::shared_ptr<CTradeableItem> hLeft; std::shared_ptr<CTradeableItem> hLeft;
std::shared_ptr<CTradeableItem> hRight; std::shared_ptr<CTradeableItem> hRight;
std::shared_ptr<CButton> deal; std::shared_ptr<CButton> deal;
std::shared_ptr<CSlider> offerSlider;
std::shared_ptr<CButton> maxAmount;
std::vector<std::shared_ptr<CLabel>> labels; std::vector<std::shared_ptr<CLabel>> labels;
std::vector<std::shared_ptr<CTextBox>> texts; std::vector<std::shared_ptr<CTextBox>> texts;
SelectionParamsFunctor selectionParamsCallback; SelectionParamsFunctor selectionParamsCallback;
int bidQty; int bidQty;
int offerQty; 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 makeDeal() = 0;
virtual void deselect(); virtual void deselect();
virtual void updateSlots(); virtual void update();
protected: protected:
virtual void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot); virtual void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot);
virtual void updateSubtitles(EMarketMode marketMode); virtual void updateSubtitles(EMarketMode marketMode);
virtual void updateSelected(); virtual void updateSelected();
virtual CTradeBase::SelectionParams getSelectionParams() const = 0; virtual CMarketBase::SelectionParams getSelectionParams() const = 0;
}; };
// Market subclasses // Market subclasses
class CExperienceAltar : virtual public CTradeBase class CExperienceAltar : virtual public CMarketBase
{ {
public: public:
std::shared_ptr<CLabel> expToLevel; std::shared_ptr<CLabel> expToLevel;
std::shared_ptr<CLabel> expForHero; std::shared_ptr<CLabel> expForHero;
std::shared_ptr<CButton> sacrificeAllButton; std::shared_ptr<CButton> sacrificeAllButton;
const Point dealButtonPos = Point(269, 520);
CExperienceAltar(); CExperienceAltar();
void updateSlots() override; void deselect() override;
void update() override;
virtual void sacrificeAll() = 0; virtual void sacrificeAll() = 0;
virtual TExpType calcExpAltarForHero() = 0; virtual TExpType calcExpAltarForHero() = 0;
}; };
class CCreaturesSelling : virtual public CTradeBase class CCreaturesSelling : virtual public CMarketBase
{ {
public: public:
CCreaturesSelling(); CCreaturesSelling();
@ -85,16 +86,28 @@ public:
void updateSubtitles(); void updateSubtitles();
}; };
class CResourcesBuying : virtual public CTradeBase class CResourcesBuying : virtual public CMarketBase
{ {
public: public:
CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback); const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback);
}; };
class CResourcesSelling : virtual public CTradeBase class CResourcesSelling : virtual public CMarketBase
{ {
public: public:
CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback); CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
void updateSubtitles(); void updateSubtitles();
}; };
class CMarketSlider : virtual public CMarketBase
{
public:
std::shared_ptr<CSlider> offerSlider;
std::shared_ptr<CButton> maxAmount;
const Point dealButtonPosWithSlider = Point(306, 520);
CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback);
void deselect() override;
virtual void onOfferSliderMoved(int newVal);
};

@ -13,7 +13,6 @@
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h"
#include "../../widgets/TextControls.h" #include "../../widgets/TextControls.h"
#include "../../CGameInfo.h" #include "../../CGameInfo.h"
@ -25,23 +24,18 @@
#include "../../../lib/mapObjects/CGMarket.h" #include "../../../lib/mapObjects/CGMarket.h"
CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero) CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero, [this](){return CMarketResources::getSelectionParams();}) : CMarketBase(market, hero, [this](){return CMarketResources::getSelectionParams();})
, CResourcesBuying( , CResourcesBuying(
[this](const std::shared_ptr<CTradeableItem> & resSlot){CMarketResources::onSlotClickPressed(resSlot, hRight);}, [this](const std::shared_ptr<CTradeableItem> & resSlot){CMarketResources::onSlotClickPressed(resSlot, hRight);},
[this](){CMarketResources::updateSubtitles();}) [this](){CMarketResources::updateSubtitles();})
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CMarketResources::onSlotClickPressed(heroSlot, hLeft);}) , CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CMarketResources::onSlotClickPressed(heroSlot, hLeft);})
, CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);})
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
labels.emplace_back(std::make_shared<CLabel>(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158])); labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158]));
deal = std::make_shared<CButton>(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"), deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
CGI->generaltexth->zelp[595], [this]() {CMarketResources::makeDeal(); }); CGI->generaltexth->zelp[595], [this]() {CMarketResources::makeDeal(); });
maxAmount = std::make_shared<CButton>(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596],
[this]() {offerSlider->scrollToMax(); });
offerSlider = std::make_shared<CSlider>(Point(230, 489), 137, [this](int newVal)
{
CMarketResources::onOfferSliderMoved(newVal);
}, 0, 0, 0, Orientation::HORIZONTAL);
// Player's resources // Player's resources
assert(bidTradePanel); assert(bidTradePanel);
@ -57,8 +51,14 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance
}; };
}); });
CTradeBase::updateSlots(); CMarketBase::update();
CTradeBase::deselect(); CMarketResources::deselect();
}
void CMarketResources::deselect()
{
CMarketBase::deselect();
CMarketSlider::deselect();
} }
void CMarketResources::makeDeal() 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) if(hLeft && hRight && hLeft->id != hRight->id)
return std::make_tuple( return std::make_tuple(
@ -80,22 +80,8 @@ CTradeBase::SelectionParams CMarketResources::getSelectionParams() const
return std::make_tuple(std::nullopt, std::nullopt); 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<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
if(newSlot == hCurSlot)
return;
CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
if(hLeft) if(hLeft)
{ {
if(hRight) if(hRight)
@ -108,15 +94,25 @@ void CMarketResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
maxAmount->block(isControlsBlocked); maxAmount->block(isControlsBlocked);
deal->block(isControlsBlocked); deal->block(isControlsBlocked);
} }
updateSelected(); offerTradePanel->update();
offerTradePanel->updateSlots();
} }
updateSelected();
}
void CMarketResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
assert(newSlot);
if(newSlot == hCurSlot)
return;
CMarketBase::onSlotClickPressed(newSlot, hCurSlot);
highlightingChanged();
redraw(); redraw();
} }
void CMarketResources::updateSubtitles() void CMarketResources::updateSubtitles()
{ {
CTradeBase::updateSubtitles(EMarketMode::RESOURCE_RESOURCE); CMarketBase::updateSubtitles(EMarketMode::RESOURCE_RESOURCE);
if(hLeft) if(hLeft)
offerTradePanel->slots[hLeft->serial]->subtitle->setText(CGI->generaltexth->allTexts[164]); // n/a offerTradePanel->slots[hLeft->serial]->subtitle->setText(CGI->generaltexth->allTexts[164]); // n/a
} }

@ -9,17 +9,18 @@
*/ */
#pragma once #pragma once
#include "CTradeBase.h" #include "CMarketBase.h"
class CMarketResources : public CResourcesSelling, public CResourcesBuying class CMarketResources : public CResourcesSelling, public CResourcesBuying, public CMarketSlider
{ {
public: public:
CMarketResources(const IMarket * market, const CGHeroInstance * hero); CMarketResources(const IMarket * market, const CGHeroInstance * hero);
void deselect() override;
void makeDeal() override; void makeDeal() override;
private: private:
CTradeBase::SelectionParams getSelectionParams() const override; CMarketBase::SelectionParams getSelectionParams() const override;
void onOfferSliderMoved(int newVal); void highlightingChanged();
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot); void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot);
void updateSubtitles(); void updateSubtitles();
}; };

@ -13,7 +13,6 @@
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h"
#include "../../widgets/TextControls.h" #include "../../widgets/TextControls.h"
#include "../../CGameInfo.h" #include "../../CGameInfo.h"
@ -24,21 +23,16 @@
#include "../../../lib/CGeneralTextHandler.h" #include "../../../lib/CGeneralTextHandler.h"
CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero) 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<CTradeableItem> & heroSlot){CTransferResources::onSlotClickPressed(heroSlot, hLeft);}) , CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CTransferResources::onSlotClickPressed(heroSlot, hLeft);})
, CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);})
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
labels.emplace_back(std::make_shared<CLabel>(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158])); labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158]));
labels.emplace_back(std::make_shared<CLabel>(445, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169])); labels.emplace_back(std::make_shared<CLabel>(445, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169]));
deal = std::make_shared<CButton>(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"), deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
CGI->generaltexth->zelp[595], [this]() {CTransferResources::makeDeal();}); CGI->generaltexth->zelp[595], [this]() {CTransferResources::makeDeal();});
maxAmount = std::make_shared<CButton>(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596],
[this]() {offerSlider->scrollToMax();});
offerSlider = std::make_shared<CSlider>(Point(230, 489), 137, [this](int newVal)
{
CTransferResources::onOfferSliderMoved(newVal);
}, 0, 0, 0, Orientation::HORIZONTAL);
// Player's resources // Player's resources
assert(bidTradePanel); assert(bidTradePanel);
@ -51,10 +45,16 @@ CTransferResources::CTransferResources(const IMarket * market, const CGHeroInsta
}); });
offerTradePanel->moveTo(pos.topLeft() + Point(333, 84)); offerTradePanel->moveTo(pos.topLeft() + Point(333, 84));
CTradeBase::updateSlots(); CMarketBase::update();
CTransferResources::deselect(); CTransferResources::deselect();
} }
void CTransferResources::deselect()
{
CMarketBase::deselect();
CMarketSlider::deselect();
}
void CTransferResources::makeDeal() void CTransferResources::makeDeal()
{ {
if(auto toTrade = offerSlider->getValue(); toTrade != 0) 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) if(hLeft && hRight)
return std::make_tuple( return std::make_tuple(
@ -74,22 +74,8 @@ CTradeBase::SelectionParams CTransferResources::getSelectionParams() const
return std::make_tuple(std::nullopt, std::nullopt); 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<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
if(newSlot == hCurSlot)
return;
CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
if(hLeft) if(hLeft)
{ {
if(hRight) if(hRight)
@ -100,8 +86,18 @@ void CTransferResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem
maxAmount->block(false); maxAmount->block(false);
deal->block(false); deal->block(false);
} }
updateSelected(); offerTradePanel->update();
offerTradePanel->updateSlots();
} }
updateSelected();
}
void CTransferResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{
assert(newSlot);
if(newSlot == hCurSlot)
return;
CMarketBase::onSlotClickPressed(newSlot, hCurSlot);
highlightingChanged();
redraw(); redraw();
} }

@ -9,16 +9,17 @@
*/ */
#pragma once #pragma once
#include "CTradeBase.h" #include "CMarketBase.h"
class CTransferResources : public CResourcesSelling class CTransferResources : public CResourcesSelling, public CMarketSlider
{ {
public: public:
CTransferResources(const IMarket * market, const CGHeroInstance * hero); CTransferResources(const IMarket * market, const CGHeroInstance * hero);
void deselect() override;
void makeDeal() override; void makeDeal() override;
private: private:
CTradeBase::SelectionParams getSelectionParams() const override; CMarketBase::SelectionParams getSelectionParams() const override;
void onOfferSliderMoved(int newVal); void highlightingChanged();
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot); void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot);
}; };

@ -196,7 +196,7 @@ void CTradeableItem::showPopupWindow(const Point & cursorPosition)
} }
} }
void TradePanelBase::updateSlots() void TradePanelBase::update()
{ {
if(deleteSlotsCheck) if(deleteSlotsCheck)
slots.erase(std::remove_if(slots.begin(), slots.end(), deleteSlotsCheck), slots.end()); slots.erase(std::remove_if(slots.begin(), slots.end(), deleteSlotsCheck), slots.end());

@ -51,11 +51,11 @@ public:
std::vector<std::shared_ptr<CTradeableItem>> slots; std::vector<std::shared_ptr<CTradeableItem>> slots;
UpdateSlotsFunctor updateSlotsCallback; UpdateSlotsFunctor updateSlotsCallback;
DeleteSlotsCheck deleteSlotsCheck; DeleteSlotsCheck deleteSlotsCheck;
std::shared_ptr<CTradeableItem> selected;
const int selectionWidth = 2; const int selectionWidth = 2;
std::shared_ptr<CTradeableItem> selectedSlot; std::shared_ptr<CTradeableItem> selectedSlot; // Separate slot that displays the contents of the highlighted slot
std::shared_ptr<CTradeableItem> highlightedSlot; // One of the slots highlighted by a frame
virtual void updateSlots(); virtual void update();
virtual void deselect(); virtual void deselect();
virtual void clearSubtitles(); virtual void clearSubtitles();
void updateOffer(CTradeableItem & slot, int, int); void updateOffer(CTradeableItem & slot, int, int);

@ -63,25 +63,25 @@ CMarketWindow::CMarketWindow(const IMarket * market, const CGHeroInstance * hero
void CMarketWindow::updateArtifacts() void CMarketWindow::updateArtifacts()
{ {
assert(marketWidget); assert(marketWidget);
marketWidget->updateSlots(); marketWidget->update();
} }
void CMarketWindow::updateGarrisons() void CMarketWindow::updateGarrisons()
{ {
assert(marketWidget); assert(marketWidget);
marketWidget->updateSlots(); marketWidget->update();
} }
void CMarketWindow::updateResource() void CMarketWindow::updateResource()
{ {
assert(marketWidget); assert(marketWidget);
marketWidget->updateSlots(); marketWidget->update();
} }
void CMarketWindow::updateHero() void CMarketWindow::updateHero()
{ {
assert(marketWidget); assert(marketWidget);
marketWidget->updateSlots(); marketWidget->update();
} }
void CMarketWindow::close() void CMarketWindow::close()
@ -100,7 +100,7 @@ bool CMarketWindow::holdsGarrison(const CArmedInstance * army)
void CMarketWindow::artifactRemoved(const ArtifactLocation & artLoc) void CMarketWindow::artifactRemoved(const ArtifactLocation & artLoc)
{ {
marketWidget->updateSlots(); marketWidget->update();
CWindowWithArtifacts::artifactRemoved(artLoc); CWindowWithArtifacts::artifactRemoved(artLoc);
} }
@ -109,7 +109,7 @@ void CMarketWindow::artifactMoved(const ArtifactLocation & srcLoc, const Artifac
if(!getState().has_value()) if(!getState().has_value())
return; return;
assert(marketWidget); assert(marketWidget);
marketWidget->updateSlots(); marketWidget->update();
CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw); CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw);
} }
@ -201,6 +201,8 @@ void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroI
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
background = createBg(ImagePath::builtin("TPMRKASS.bmp"), PLAYER_COLORED); 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<CPicture>(background->getSurface(), Rect(20, 187, 47, 47), 18, 339);
auto artsSellingMarket = std::make_shared<CArtifactsSelling>(market, hero); auto artsSellingMarket = std::make_shared<CArtifactsSelling>(market, hero);
artSets.clear(); artSets.clear();
addSetAndCallbacks(artsSellingMarket->getAOHset()); addSetAndCallbacks(artsSellingMarket->getAOHset());

@ -9,7 +9,7 @@
*/ */
#pragma once #pragma once
#include "../widgets/markets/CTradeBase.h" #include "../widgets/markets/CMarketBase.h"
#include "../widgets/CWindowWithArtifacts.h" #include "../widgets/CWindowWithArtifacts.h"
#include "CWindowObject.h" #include "CWindowObject.h"
@ -43,5 +43,8 @@ private:
std::shared_ptr<CButton> quitButton; std::shared_ptr<CButton> quitButton;
std::function<void()> windowClosedCallback; std::function<void()> windowClosedCallback;
const Point quitButtonPos = Point(516, 520); const Point quitButtonPos = Point(516, 520);
std::shared_ptr<CTradeBase> marketWidget; std::shared_ptr<CMarketBase> marketWidget;
// This is workaround for bug in H3 files where this slot for ragdoll on this screen is missing
std::shared_ptr<CPicture> artSlotBack;
}; };