浏览代码

Resources trade panel

SoundSSGood 1 年之前
父节点
当前提交
6c828d1be9
共有 3 个文件被更改,包括 163 次插入75 次删除
  1. 33 13
      client/widgets/CTradeBase.cpp
  2. 61 34
      client/widgets/CTradeBase.h
  3. 69 28
      client/windows/CTradeWindow.cpp

+ 33 - 13
client/widgets/CTradeBase.cpp

@@ -20,7 +20,7 @@
 #include "../../lib/CGeneralTextHandler.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)
 	, type(EType(-1)) // set to invalid, will be corrected in setType
 	, 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)
 	{
@@ -57,7 +57,7 @@ void CTradeBase::CTradeableItem::setType(EType newType)
 	}
 }
 
-void CTradeBase::CTradeableItem::setID(int newID)
+void CTradeableItem::setID(int newID)
 {
 	if(id != newID)
 	{
@@ -76,7 +76,7 @@ void CTradeBase::CTradeableItem::setID(int newID)
 	}
 }
 
-AnimationPath CTradeBase::CTradeableItem::getFilename()
+AnimationPath CTradeableItem::getFilename()
 {
 	switch(type)
 	{
@@ -95,7 +95,7 @@ AnimationPath CTradeBase::CTradeableItem::getFilename()
 	}
 }
 
-int CTradeBase::CTradeableItem::getIndex()
+int CTradeableItem::getIndex()
 {
 	if(id < 0)
 		return -1;
@@ -116,7 +116,7 @@ int CTradeBase::CTradeableItem::getIndex()
 	}
 }
 
-void CTradeBase::CTradeableItem::showAll(Canvas & to)
+void CTradeableItem::showAll(Canvas & to)
 {
 	Point posToBitmap;
 	Point posToSubCenter;
@@ -154,13 +154,13 @@ void CTradeBase::CTradeableItem::showAll(Canvas & to)
 	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)
 		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;
 	std::string oldSub = subtitle;
@@ -175,7 +175,7 @@ void CTradeBase::CTradeableItem::showAllAt(const Point& dstPos, const std::strin
 	subtitle = oldSub;
 }
 
-void CTradeBase::CTradeableItem::hover(bool on)
+void CTradeableItem::hover(bool 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)
 	{
@@ -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)
 	{
@@ -235,7 +235,7 @@ std::string CTradeBase::CTradeableItem::getName(int number) const
 	return "";
 }
 
-const CArtifactInstance* CTradeBase::CTradeableItem::getArtInstance() const
+const CArtifactInstance * CTradeableItem::getArtInstance() const
 {
 	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);
 	hlp = art;
@@ -257,6 +257,26 @@ void CTradeBase::CTradeableItem::setArtInstance(const CArtifactInstance * art)
 		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)
 	: market(market)
 	, hero(hero)

+ 61 - 34
client/widgets/CTradeBase.h

@@ -23,52 +23,79 @@ VCMI_LIB_NAMESPACE_END
 class CButton;
 class CTextBox;
 
-class CTradeBase
+enum EType
 {
+	RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE
+};
+
+class CTradeableItem : public CIntObject, public std::enable_shared_from_this<CTradeableItem>
+{
+	std::shared_ptr<CAnimImage> image;
+	AnimationPath getFilename();
+	int getIndex();
 public:
-	enum EType
+	using ClickPressedFunctor = std::function<void(std::shared_ptr<CTradeableItem>)>;
+
+	const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact
+	EType type;
+	int id;
+	const int serial;
+	const bool left;
+	std::string subtitle; //empty if default
+	ClickPressedFunctor clickPressedCallback;
+
+	void setType(EType newType);
+	void setID(int newID);
+
+	const CArtifactInstance * getArtInstance() const;
+	void setArtInstance(const CArtifactInstance * art);
+
+	CFunctionList<void()> callback;
+	bool downSelection;
+
+	void showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to);
+
+	void showPopupWindow(const Point & cursorPosition) override;
+	void hover(bool on) override;
+	void showAll(Canvas & to) override;
+	void clickPressed(const Point & cursorPosition) override;
+	std::string getName(int number = -1) const;
+	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 =
 	{
-		RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE
+		GameResID::WOOD, GameResID::MERCURY, GameResID::ORE,
+		GameResID::SULFUR, GameResID::CRYSTAL, GameResID::GEMS,
+		GameResID::GOLD
 	};
-
-	class CTradeableItem : public CIntObject, public std::enable_shared_from_this<CTradeableItem>
+	const std::vector<Point> slotsPos =
 	{
-		std::shared_ptr<CAnimImage> image;
-		AnimationPath getFilename();
-		int getIndex();
-	public:
-		const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact
-		EType type;
-		int id;
-		const int serial;
-		const bool left;
-		std::string subtitle; //empty if default
-		std::function<void(std::shared_ptr<CTradeableItem> altarSlot)> clickPressedCallback;
-
-		void setType(EType newType);
-		void setID(int newID);
-
-		const CArtifactInstance* getArtInstance() const;
-		void setArtInstance(const CArtifactInstance * art);
-
-		CFunctionList<void()> callback;
-		bool downSelection;
-
-		void showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to);
-
-		void showPopupWindow(const Point & cursorPosition) override;
-		void hover(bool on) override;
-		void showAll(Canvas & to) override;
-		void clickPressed(const Point & cursorPosition) override;
-		std::string getName(int number = -1) const;
-		CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial);
+		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 CGHeroInstance * hero;
 
 	//all indexes: 1 = left, 0 = right
 	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)
 	std::shared_ptr<CTradeableItem> hLeft;

+ 69 - 28
client/windows/CTradeWindow.cpp

@@ -84,6 +84,66 @@ void CTradeWindow::initItems(bool Left)
 	}
 	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<Rect> pos;
 		int amount = -1;
@@ -185,14 +245,6 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
 
 	switch(type)
 	{
-	case RESOURCE:
-		dx = 82;
-		dy = 79;
-		x = 39;
-		y = 180;
-		h = 68;
-		w = 70;
-		break;
 	case PLAYER:
 		dx = 83;
 		dy = 118;
@@ -244,6 +296,15 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
 
 void CTradeWindow::initSubs(bool Left)
 {
+	if(itemsType[Left] == RESOURCE)
+	{ 
+		if(Left)
+			resoursesPanelPlayer->updateSlots();
+		else
+			resoursesPanelMarket->updateSlots();
+		return;
+	}
+
 	for(auto item : items[Left])
 	{
 		if(Left)
@@ -253,9 +314,6 @@ void CTradeWindow::initSubs(bool Left)
 			case CREATURE:
 				item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial)));
 				break;
-			case RESOURCE:
-				item->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(item->serial)));
-				break;
 			}
 		}
 		else //right side
@@ -264,23 +322,6 @@ void CTradeWindow::initSubs(bool Left)
 			{
 				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 = "";
 		}
 	}
 }