Browse Source

CTradeBase initial commit

SoundSSGood 1 year ago
parent
commit
9f9317a8a0

+ 2 - 0
client/CMakeLists.txt

@@ -99,6 +99,7 @@ set(client_SRCS
 	widgets/CGarrisonInt.cpp
 	widgets/CreatureCostBox.cpp
 	widgets/ComboBox.cpp
+	widgets/CTradeBase.cpp
 	widgets/Images.cpp
 	widgets/MiscWidgets.cpp
 	widgets/ObjectLists.cpp
@@ -265,6 +266,7 @@ set(client_HEADERS
 	widgets/CGarrisonInt.h
 	widgets/CreatureCostBox.h
 	widgets/ComboBox.h
+	widgets/CTradeBase.h
 	widgets/Images.h
 	widgets/MiscWidgets.h
 	widgets/ObjectLists.h

+ 280 - 0
client/widgets/CTradeBase.cpp

@@ -0,0 +1,280 @@
+/*
+ * CTradeBase.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "CTradeBase.h"
+
+#include "../gui/CGuiHandler.h"
+#include "../render/Canvas.h"
+#include "../widgets/TextControls.h"
+#include "../windows/InfoWindows.h"
+
+#include "../CGameInfo.h"
+
+#include "../../lib/CGeneralTextHandler.h"
+#include "../../lib/mapObjects/CGHeroInstance.h"
+
+CTradeBase::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)
+	, serial(Serial)
+	, left(Left)
+{
+	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
+	downSelection = false;
+	hlp = nullptr;
+	setType(Type);
+}
+
+void CTradeBase::CTradeableItem::setType(EType newType)
+{
+	if(type != newType)
+	{
+		OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
+		type = newType;
+
+		if(getIndex() < 0)
+		{
+			image = std::make_shared<CAnimImage>(getFilename(), 0);
+			image->disable();
+		}
+		else
+		{
+			image = std::make_shared<CAnimImage>(getFilename(), getIndex());
+		}
+	}
+}
+
+void CTradeBase::CTradeableItem::setID(int newID)
+{
+	if(id != newID)
+	{
+		id = newID;
+		if(image)
+		{
+			int index = getIndex();
+			if(index < 0)
+				image->disable();
+			else
+			{
+				image->enable();
+				image->setFrame(index);
+			}
+		}
+	}
+}
+
+AnimationPath CTradeBase::CTradeableItem::getFilename()
+{
+	switch(type)
+	{
+	case RESOURCE:
+		return AnimationPath::builtin("RESOURCE");
+	case PLAYER:
+		return AnimationPath::builtin("CREST58");
+	case ARTIFACT_TYPE:
+	case ARTIFACT_PLACEHOLDER:
+	case ARTIFACT_INSTANCE:
+		return AnimationPath::builtin("artifact");
+	case CREATURE:
+		return AnimationPath::builtin("TWCRPORT");
+	default:
+		return {};
+	}
+}
+
+int CTradeBase::CTradeableItem::getIndex()
+{
+	if(id < 0)
+		return -1;
+
+	switch(type)
+	{
+	case RESOURCE:
+	case PLAYER:
+		return id;
+	case ARTIFACT_TYPE:
+	case ARTIFACT_INSTANCE:
+	case ARTIFACT_PLACEHOLDER:
+		return CGI->artifacts()->getByIndex(id)->getIconIndex();
+	case CREATURE:
+		return CGI->creatures()->getByIndex(id)->getIconIndex();
+	default:
+		return -1;
+	}
+}
+
+void CTradeBase::CTradeableItem::showAll(Canvas & to)
+{
+	Point posToBitmap;
+	Point posToSubCenter;
+
+	switch (type)
+	{
+	case RESOURCE:
+		posToBitmap = Point(19, 9);
+		posToSubCenter = Point(36, 59);
+		break;
+	case CREATURE_PLACEHOLDER:
+	case CREATURE:
+		posToSubCenter = Point(29, 76);
+		break;
+	case PLAYER:
+		posToSubCenter = Point(31, 76);
+		break;
+	case ARTIFACT_PLACEHOLDER:
+	case ARTIFACT_INSTANCE:
+		posToSubCenter = Point(19, 55);
+		if (downSelection)
+			posToSubCenter.y += 8;
+		break;
+	case ARTIFACT_TYPE:
+		posToSubCenter = Point(19, 58);
+		break;
+	}
+
+	if(image)
+	{
+		image->moveTo(pos.topLeft() + posToBitmap);
+		CIntObject::showAll(to);
+	}
+
+	to.drawText(pos.topLeft() + posToSubCenter, FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, subtitle);
+}
+
+void CTradeBase::CTradeableItem::clickPressed(const Point& cursorPosition)
+{
+	if(clickPressedCallback)
+		clickPressedCallback(shared_from_this());
+}
+
+void CTradeBase::CTradeableItem::showAllAt(const Point& dstPos, const std::string& customSub, Canvas& to)
+{
+	Rect oldPos = pos;
+	std::string oldSub = subtitle;
+	downSelection = true;
+
+	moveTo(dstPos);
+	subtitle = customSub;
+	showAll(to);
+
+	downSelection = false;
+	moveTo(oldPos.topLeft());
+	subtitle = oldSub;
+}
+
+void CTradeBase::CTradeableItem::hover(bool on)
+{
+	if(!on)
+	{
+		GH.statusbar()->clear();
+		return;
+	}
+
+	switch(type)
+	{
+	case CREATURE:
+	case CREATURE_PLACEHOLDER:
+		GH.statusbar()->write(boost::str(boost::format(CGI->generaltexth->allTexts[481]) % CGI->creh->objects[id]->getNamePluralTranslated()));
+		break;
+	case ARTIFACT_PLACEHOLDER:
+		if(id < 0)
+			GH.statusbar()->write(CGI->generaltexth->zelp[582].first);
+		else
+			GH.statusbar()->write(CGI->artifacts()->getByIndex(id)->getNameTranslated());
+		break;
+	}
+}
+
+void CTradeBase::CTradeableItem::showPopupWindow(const Point& cursorPosition)
+{
+	switch(type)
+	{
+	case CREATURE:
+	case CREATURE_PLACEHOLDER:
+		break;
+	case ARTIFACT_TYPE:
+	case ARTIFACT_PLACEHOLDER:
+		//TODO: it's would be better for market to contain actual CArtifactInstance and not just ids of certain artifact type so we can use getEffectiveDescription.
+		if (id >= 0)
+			CRClickPopup::createAndPush(CGI->artifacts()->getByIndex(id)->getDescriptionTranslated());
+		break;
+	}
+}
+
+std::string CTradeBase::CTradeableItem::getName(int number) const
+{
+	switch(type)
+	{
+	case PLAYER:
+		return CGI->generaltexth->capColors[id];
+	case RESOURCE:
+		return CGI->generaltexth->restypes[id];
+	case CREATURE:
+		if (number == 1)
+			return CGI->creh->objects[id]->getNameSingularTranslated();
+		else
+			return CGI->creh->objects[id]->getNamePluralTranslated();
+	case ARTIFACT_TYPE:
+	case ARTIFACT_INSTANCE:
+		return CGI->artifacts()->getByIndex(id)->getNameTranslated();
+	}
+	logGlobal->error("Invalid trade item type: %d", (int)type);
+	return "";
+}
+
+const CArtifactInstance* CTradeBase::CTradeableItem::getArtInstance() const
+{
+	switch(type)
+	{
+	case ARTIFACT_PLACEHOLDER:
+	case ARTIFACT_INSTANCE:
+		return hlp;
+	default:
+		return nullptr;
+	}
+}
+
+void CTradeBase::CTradeableItem::setArtInstance(const CArtifactInstance * art)
+{
+	assert(type == ARTIFACT_PLACEHOLDER || type == ARTIFACT_INSTANCE);
+	hlp = art;
+	if(art)
+		setID(art->artType->getId());
+	else
+		setID(-1);
+}
+
+CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero)
+	: market(market)
+	, hero(hero)
+{
+}
+
+void CTradeBase::removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove)
+{
+	for(auto item : toRemove)
+		removeItem(item);
+}
+
+void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
+{
+	items[item->left] -= item;
+
+	if(hRight == item)
+		hRight.reset();
+}
+
+void CTradeBase::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
+{
+	for(auto item : items[1])
+		if(!hero->getStackCount(SlotID(item->serial)))
+			toRemove.insert(item);
+}

+ 88 - 0
client/widgets/CTradeBase.h

@@ -0,0 +1,88 @@
+/*
+ * CTradeBase.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+#include "Images.h"
+
+#include "../../lib/FunctionList.h"
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+class IMarket;
+class CGHeroInstance;
+
+VCMI_LIB_NAMESPACE_END
+
+class CButton;
+class CTextBox;
+
+class CTradeBase
+{
+public:
+	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:
+		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);
+	};
+
+	const IMarket * market;
+	const CGHeroInstance * hero;
+
+	//all indexes: 1 = left, 0 = right
+	std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
+
+	//highlighted items (nullptr if no highlight)
+	std::shared_ptr<CTradeableItem> hLeft;
+	std::shared_ptr<CTradeableItem> hRight;
+	std::shared_ptr<CButton> deal;
+
+	CTradeBase(const IMarket * market, const CGHeroInstance * hero);
+	void removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove);
+	void removeItem(std::shared_ptr<CTradeableItem> item);
+	void getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove);
+	virtual void makeDeal() = 0;
+
+protected:
+	std::vector<std::shared_ptr<CLabel>> labels;
+	std::vector<std::shared_ptr<CButton>> buttons;
+	std::vector<std::shared_ptr<CTextBox>> texts;
+};

+ 21 - 314
client/windows/CTradeWindow.cpp

@@ -12,317 +12,28 @@
 
 #include "../gui/CGuiHandler.h"
 #include "../gui/CursorHandler.h"
-#include "../widgets/Images.h"
 #include "../render/Canvas.h"
-#include "../gui/TextAlignment.h"
 #include "../gui/Shortcut.h"
 #include "../gui/WindowHandler.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/Slider.h"
 #include "../widgets/TextControls.h"
-#include "../windows/InfoWindows.h"
 
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 
 #include "../../CCallback.h"
 
-#include "../../lib/VCMI_Lib.h"
-#include "../../lib/CArtHandler.h"
-#include "../../lib/CCreatureHandler.h"
 #include "../../lib/CGeneralTextHandler.h"
 #include "../../lib/CHeroHandler.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
 #include "../../lib/mapObjects/CGMarket.h"
-#include "../../lib/networkPacks/ArtifactLocation.h"
-
-CTradeWindow::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),
-	serial(Serial),
-	left(Left)
-{
-	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
-	downSelection = false;
-	hlp = nullptr;
-	setType(Type);
-}
-
-void CTradeWindow::CTradeableItem::setType(EType newType)
-{
-	if(type != newType)
-	{
-		OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
-		type = newType;
-
-		if(getIndex() < 0)
-		{
-			image = std::make_shared<CAnimImage>(getFilename(), 0);
-			image->disable();
-		}
-		else
-		{
-			image = std::make_shared<CAnimImage>(getFilename(), getIndex());
-		}
-	}
-}
-
-void CTradeWindow::CTradeableItem::setID(int newID)
-{
-	if (id != newID)
-	{
-		id = newID;
-		if (image)
-		{
-			int index = getIndex();
-			if (index < 0)
-				image->disable();
-			else
-			{
-				image->enable();
-				image->setFrame(index);
-			}
-		}
-	}
-}
-
-AnimationPath CTradeWindow::CTradeableItem::getFilename()
-{
-	switch(type)
-	{
-	case RESOURCE:
-		return AnimationPath::builtin("RESOURCE");
-	case PLAYER:
-		return AnimationPath::builtin("CREST58");
-	case ARTIFACT_TYPE:
-	case ARTIFACT_PLACEHOLDER:
-	case ARTIFACT_INSTANCE:
-		return AnimationPath::builtin("artifact");
-	case CREATURE:
-		return AnimationPath::builtin("TWCRPORT");
-	default:
-		return {};
-	}
-}
-
-int CTradeWindow::CTradeableItem::getIndex()
-{
-	if (id < 0)
-		return -1;
-
-	switch(type)
-	{
-	case RESOURCE:
-	case PLAYER:
-		return id;
-	case ARTIFACT_TYPE:
-	case ARTIFACT_INSTANCE:
-	case ARTIFACT_PLACEHOLDER:
-		return CGI->artifacts()->getByIndex(id)->getIconIndex();
-	case CREATURE:
-		return CGI->creatures()->getByIndex(id)->getIconIndex();
-	default:
-		return -1;
-	}
-}
-
-void CTradeWindow::CTradeableItem::showAll(Canvas & to)
-{
-	CTradeWindow *mw = dynamic_cast<CTradeWindow *>(parent);
-	assert(mw);
-
-	Point posToBitmap;
-	Point posToSubCenter;
-
-	switch(type)
-	{
-	case RESOURCE:
-		posToBitmap = Point(19,9);
-		posToSubCenter = Point(36, 59);
-		break;
-	case CREATURE_PLACEHOLDER:
-	case CREATURE:
-		posToSubCenter = Point(29, 76);
-		// Positing of unit count is different in Altar of Sacrifice and Freelancer's Guild
-		if(mw->mode == EMarketMode::CREATURE_EXP && downSelection)
-			posToSubCenter.y += 5;
-		break;
-	case PLAYER:
-		posToSubCenter = Point(31, 76);
-		break;
-	case ARTIFACT_PLACEHOLDER:
-	case ARTIFACT_INSTANCE:
-		posToSubCenter = Point(19, 55);
-		if(downSelection)
-			posToSubCenter.y += 8;
-		break;
-	case ARTIFACT_TYPE:
-		posToSubCenter = Point(19, 58);
-		break;
-	}
-
-	if (image)
-	{
-		image->moveTo(pos.topLeft() + posToBitmap);
-		CIntObject::showAll(to);
-	}
-
-	to.drawText(pos.topLeft() + posToSubCenter, FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, subtitle);
-}
-
-void CTradeWindow::CTradeableItem::clickPressed(const Point & cursorPosition)
-{
-	CTradeWindow *mw = dynamic_cast<CTradeWindow *>(parent);
-	assert(mw);
-		if(type == ARTIFACT_PLACEHOLDER)
-		{
-			CAltarWindow *aw = static_cast<CAltarWindow *>(mw);
-			const auto pickedArtInst = aw->getPickedArtifact();
-
-			if(pickedArtInst)
-			{
-				aw->arts->pickedArtMoveToAltar(ArtifactPosition::TRANSITION_POS);
-				aw->moveArtToAltar(this->shared_from_this(), pickedArtInst);
-			}
-			else if(const CArtifactInstance *art = getArtInstance())
-			{
-				const auto hero = aw->arts->getHero();
-				const auto slot = hero->getSlotByInstance(art);
-				assert(slot != ArtifactPosition::PRE_FIRST);
-				LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero->id, slot),
-					ArtifactLocation(hero->id, ArtifactPosition::TRANSITION_POS));
-				aw->arts->pickedArtFromSlot = slot;
-				aw->arts->artifactsOnAltar.erase(art);
-				setID(-1);
-				subtitle.clear();
-				aw->deal->block(!aw->arts->artifactsOnAltar.size());
-			}
-
-			aw->calcTotalExp();
-			return;
-		}
-		if(left)
-		{
-			if(mw->hLeft != this->shared_from_this())
-				mw->hLeft = this->shared_from_this();
-			else
-				return;
-		}
-		else
-		{
-			if(mw->hRight != this->shared_from_this())
-				mw->hRight = this->shared_from_this();
-			else
-				return;
-		}
-		mw->selectionChanged(left);
-}
-
-void CTradeWindow::CTradeableItem::showAllAt(const Point &dstPos, const std::string &customSub, Canvas & to)
-{
-	Rect oldPos = pos;
-	std::string oldSub = subtitle;
-	downSelection = true;
-
-	moveTo(dstPos);
-	subtitle = customSub;
-	showAll(to);
-
-	downSelection = false;
-	moveTo(oldPos.topLeft());
-	subtitle = oldSub;
-}
-
-void CTradeWindow::CTradeableItem::hover(bool on)
-{
-	if(!on)
-	{
-		GH.statusbar()->clear();
-		return;
-	}
-
-	switch(type)
-	{
-	case CREATURE:
-	case CREATURE_PLACEHOLDER:
-		GH.statusbar()->write(boost::str(boost::format(CGI->generaltexth->allTexts[481]) % CGI->creh->objects[id]->getNamePluralTranslated()));
-		break;
-	case ARTIFACT_PLACEHOLDER:
-		if(id < 0)
-			GH.statusbar()->write(CGI->generaltexth->zelp[582].first);
-		else
-			GH.statusbar()->write(CGI->artifacts()->getByIndex(id)->getNameTranslated());
-		break;
-	}
-}
-
-void CTradeWindow::CTradeableItem::showPopupWindow(const Point & cursorPosition)
-{
-	switch(type)
-	{
-		case CREATURE:
-		case CREATURE_PLACEHOLDER:
-			//GH.statusbar->print(boost::str(boost::format(CGI->generaltexth->allTexts[481]) % CGI->creh->objects[id]->namePl));
-			break;
-		case ARTIFACT_TYPE:
-		case ARTIFACT_PLACEHOLDER:
-			//TODO: it's would be better for market to contain actual CArtifactInstance and not just ids of certain artifact type so we can use getEffectiveDescription.
-			if(id >= 0)
-				CRClickPopup::createAndPush(CGI->artifacts()->getByIndex(id)->getDescriptionTranslated());
-			break;
-	}
-}
-
-std::string CTradeWindow::CTradeableItem::getName(int number) const
-{
-	switch(type)
-	{
-	case PLAYER:
-		return CGI->generaltexth->capColors[id];
-	case RESOURCE:
-		return CGI->generaltexth->restypes[id];
-	case CREATURE:
-		if(number == 1)
-			return CGI->creh->objects[id]->getNameSingularTranslated();
-		else
-			return CGI->creh->objects[id]->getNamePluralTranslated();
-	case ARTIFACT_TYPE:
-	case ARTIFACT_INSTANCE:
-		return CGI->artifacts()->getByIndex(id)->getNameTranslated();
-	}
-	logGlobal->error("Invalid trade item type: %d", (int)type);
-	return "";
-}
-
-const CArtifactInstance * CTradeWindow::CTradeableItem::getArtInstance() const
-{
-	switch(type)
-	{
-	case ARTIFACT_PLACEHOLDER:
-	case ARTIFACT_INSTANCE:
-		return hlp;
-	default:
-		return nullptr;
-	}
-}
-
-void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art)
-{
-	assert(type == ARTIFACT_PLACEHOLDER || type == ARTIFACT_INSTANCE);
-	hlp = art;
-	if(art)
-		setID(art->artType->getId());
-	else
-		setID(-1);
-}
 
 CTradeWindow::CTradeWindow(const ImagePath & bgName, const IMarket *Market, const CGHeroInstance *Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode):
+	CTradeBase(Market, Hero),
 	CWindowObject(PLAYER_COLORED, bgName),
-	market(Market),
 	onWindowClosed(onWindowClosed),
-	hero(Hero),
 	readyToTrade(false)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
@@ -403,6 +114,26 @@ void CTradeWindow::initItems(bool Left)
 
 			auto item = std::make_shared<CTradeableItem>(pos[j].topLeft(), itemsType[Left], id, Left, j);
 			item->pos = pos[j] + this->pos.topLeft();
+			if(mode != EMarketMode::ARTIFACT_EXP)
+				item->clickPressedCallback = [this](std::shared_ptr<CTradeableItem> altarSlot) -> void
+				{
+					if(altarSlot->left)
+					{
+						if(hLeft != altarSlot)
+							hLeft = altarSlot;
+						else
+							return;
+					}
+					else
+					{
+						if(hRight != altarSlot)
+							hRight = altarSlot;
+						else
+							return;
+					}
+					selectionChanged(altarSlot->left);
+				};
+
 			items[Left].push_back(item);
 		}
 		vstd::clear_pointer(ids);
@@ -571,30 +302,6 @@ void CTradeWindow::close()
 	CWindowObject::close();
 }
 
-void CTradeWindow::removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove)
-{
-	for(auto item : toRemove)
-		removeItem(item);
-}
-
-void CTradeWindow::removeItem(std::shared_ptr<CTradeableItem> item)
-{
-	items[item->left] -= item;
-
-	if(hRight == item)
-	{
-		hRight.reset();
-		selectionChanged(false);
-	}
-}
-
-void CTradeWindow::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
-{
-	for(auto item : items[1])
-		if(!hero->getStackCount(SlotID(item->serial)))
-			toRemove.insert(item);
-}
-
 void CTradeWindow::setMode(EMarketMode Mode)
 {
 	const IMarket *m = market;

+ 4 - 62
client/windows/CTradeWindow.h

@@ -9,76 +9,21 @@
  */
 #pragma once
 
+#include "../widgets/CTradeBase.h"
 #include "../widgets/CWindowWithArtifacts.h"
 #include "CWindowObject.h"
-#include "../../lib/FunctionList.h"
-
-VCMI_LIB_NAMESPACE_BEGIN
-
-class IMarket;
-
-VCMI_LIB_NAMESPACE_END
 
 class CSlider;
-class CTextBox;
-class CPicture;
 class CGStatusBar;
 
-class CTradeWindow : public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice
+class CTradeWindow : public CTradeBase, public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice
 {
 public:
-	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:
-		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
-
-		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);
-	};
-
-	const IMarket * market;
-	const CGHeroInstance * hero;
-
-	//all indexes: 1 = left, 0 = right
-	std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
-
-	//highlighted items (nullptr if no highlight)
-	std::shared_ptr<CTradeableItem> hLeft;
-	std::shared_ptr<CTradeableItem> hRight;
 	EType itemsType[2];
 
 	EMarketMode mode;
 	std::shared_ptr<CButton> ok;
 	std::shared_ptr<CButton> max;
-	std::shared_ptr<CButton> deal;
 
 	std::shared_ptr<CSlider> slider; //for choosing amount to be exchanged
 	bool readyToTrade;
@@ -93,9 +38,6 @@ public:
 	void initItems(bool Left);
 	std::vector<int> *getItemsIds(bool Left); //nullptr if default
 	void getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const;
-	void removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove);
-	void removeItem(std::shared_ptr<CTradeableItem> item);
-	void getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove);
 	void setMode(EMarketMode Mode); //mode setter
 
 	void artifactSelected(CHeroArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot
@@ -130,7 +72,7 @@ public:
 
 	void setMax();
 	void sliderMoved(int to);
-	void makeDeal();
+	void makeDeal() override;
 	void selectionChanged(bool side) override; //true == left
 	CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode);
 	~CMarketplaceWindow();
@@ -171,7 +113,7 @@ public:
 
 	void putOnAltar(int backpackIndex);
 	bool putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance * art);
-	void makeDeal();
+	void makeDeal() override;
 	void showAll(Canvas & to) override;
 
 	void blockTrade();