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