Ver Fonte

interface improvements

Laserlicht há 2 anos atrás
pai
commit
9e508fe2c2

+ 68 - 14
client/widgets/MiscWidgets.cpp

@@ -18,6 +18,8 @@
 #include "../CPlayerInterface.h"
 #include "../CGameInfo.h"
 #include "../PlayerLocalState.h"
+#include "../gui/WindowHandler.h"
+#include "../windows/CTradeWindow.h"
 #include "../widgets/TextControls.h"
 #include "../widgets/CGarrisonInt.h"
 #include "../windows/CCastleInterface.h"
@@ -175,6 +177,24 @@ LRClickableAreaOpenTown::LRClickableAreaOpenTown(const Rect & Pos, const CGTownI
 {
 }
 
+void LRClickableArea::clickPressed(const Point & cursorPosition)
+{
+	if(onClick)
+		onClick();
+}
+
+void LRClickableArea::showPopupWindow(const Point & cursorPosition)
+{
+	if(onPopup)
+		onPopup();
+}
+
+LRClickableArea::LRClickableArea(const Rect & Pos, std::function<void()> onClick, std::function<void()> onPopup)
+	: CIntObject(LCLICK | SHOW_POPUP), onClick(onClick), onPopup(onPopup)
+{
+	pos = Pos + pos.topLeft();
+}
+
 void CMinorResDataBar::show(Canvas & to)
 {
 }
@@ -401,50 +421,84 @@ CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town)
 
 CInteractableTownTooltip::CInteractableTownTooltip(Point pos, const CGTownInstance * town)
 {
-	init(InfoAboutTown(town, true));
+	init(town);
 
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 	garrison = std::make_shared<CGarrisonInt>(pos + Point(0, 73), 4, Point(0, 0), town->getUpperArmy(), nullptr, true, true, CGarrisonInt::ESlotsLayout::REVERSED_TWO_ROWS);
 }
 
-void CInteractableTownTooltip::init(const InfoAboutTown & town)
+void CInteractableTownTooltip::init(const CGTownInstance * town)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 
+	const InfoAboutTown townInfo = InfoAboutTown(town, true);
+	int townId = town->id;
+
 	//order of icons in def: fort, citadel, castle, no fort
-	size_t fortIndex = town.fortLevel ? town.fortLevel - 1 : 3;
+	size_t fortIndex = townInfo.fortLevel ? townInfo.fortLevel - 1 : 3;
 
 	fort = std::make_shared<CAnimImage>(AnimationPath::builtin("ITMCLS"), fortIndex, 0, 105, 31);
+	fastArmyPurchase = std::make_shared<LRClickableArea>(Rect(105, 31, 34, 34), [townId]()
+	{
+		std::vector<const CGTownInstance*> towns = LOCPLINT->cb->getTownsInfo(true);
+		for(auto & town : towns)
+		{
+			if(town->id == townId)
+				std::make_shared<CCastleBuildings>(town)->enterToTheQuickRecruitmentWindow();
+		}
+	});
+	fastMarket = std::make_shared<LRClickableArea>(Rect(143, 31, 30, 34), [townId]()
+	{
+		std::vector<const CGTownInstance*> towns = LOCPLINT->cb->getTownsInfo(true);
+		for(auto & town : towns)
+		{
+			if(town->builtBuildings.count(BuildingID::MARKETPLACE))
+			{
+				GH.windows().createAndPushWindow<CMarketplaceWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
+				return;
+			}
+		}
+		LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithMarket"));
+	});
 
-	assert(town.tType);
+	assert(townInfo.tType);
 
-	size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
+	size_t iconIndex = townInfo.tType->clientInfo.icons[townInfo.fortLevel > 0][townInfo.built >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
 
 	build = std::make_shared<CAnimImage>(AnimationPath::builtin("itpt"), iconIndex, 0, 3, 2);
-	title = std::make_shared<CLabel>(66, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, town.name);
+	title = std::make_shared<CLabel>(66, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, townInfo.name);
 
-	if(town.details)
+	if(townInfo.details)
 	{
-		hall = std::make_shared<CAnimImage>(AnimationPath::builtin("ITMTLS"), town.details->hallLevel, 0, 67, 31);
+		hall = std::make_shared<CAnimImage>(AnimationPath::builtin("ITMTLS"), townInfo.details->hallLevel, 0, 67, 31);
+		fastTownHall = std::make_shared<LRClickableArea>(Rect(67, 31, 34, 34), [townId]()
+		{
+			std::vector<const CGTownInstance*> towns = LOCPLINT->cb->getTownsInfo(true);
+			for(auto & town : towns)
+			{
+				if(town->id == townId)
+					std::make_shared<CCastleBuildings>(town)->enterTownHall();
+			}
+		});
 
-		if(town.details->goldIncome)
+		if(townInfo.details->goldIncome)
 		{
 			income = std::make_shared<CLabel>(157, 58, FONT_TINY, ETextAlignment::CENTER, Colors::WHITE,
-											  std::to_string(town.details->goldIncome));
+											  std::to_string(townInfo.details->goldIncome));
 		}
-		if(town.details->garrisonedHero) //garrisoned hero icon
+		if(townInfo.details->garrisonedHero) //garrisoned hero icon
 			garrisonedHero = std::make_shared<CPicture>(ImagePath::builtin("TOWNQKGH"), 149, 76);
 
-		if(town.details->customRes)//silo is built
+		if(townInfo.details->customRes)//silo is built
 		{
-			if(town.tType->primaryRes == EGameResID::WOOD_AND_ORE )// wood & ore
+			if(townInfo.tType->primaryRes == EGameResID::WOOD_AND_ORE )// wood & ore
 			{
 				res1 = std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), GameResID(EGameResID::WOOD), 0, 7, 75);
 				res2 = std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), GameResID(EGameResID::ORE), 0, 7, 88);
 			}
 			else
 			{
-				res1 = std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), town.tType->primaryRes, 0, 7, 81);
+				res1 = std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), townInfo.tType->primaryRes, 0, 7, 81);
 			}
 		}
 	}

+ 17 - 1
client/widgets/MiscWidgets.h

@@ -31,6 +31,7 @@ class CGarrisonInt;
 class CCreatureAnim;
 class CComponent;
 class CAnimImage;
+class LRClickableArea;
 
 /// Shows a text by moving the mouse cursor over the object
 class CHoverableArea: public virtual CIntObject
@@ -133,8 +134,12 @@ class CInteractableTownTooltip : public CIntObject
 	std::shared_ptr<CAnimImage> res1;
 	std::shared_ptr<CAnimImage> res2;
 	std::shared_ptr<CGarrisonInt> garrison;
+	
+	std::shared_ptr<LRClickableArea> fastMarket;
+	std::shared_ptr<LRClickableArea> fastTownHall;
+	std::shared_ptr<LRClickableArea> fastArmyPurchase;
 
-	void init(const InfoAboutTown & town);
+	void init(const CGTownInstance * town);
 public:
 	CInteractableTownTooltip(Point pos, const CGTownInstance * town);
 };
@@ -215,6 +220,17 @@ public:
 	LRClickableAreaOpenTown(const Rect & Pos, const CGTownInstance * Town);
 };
 
+/// Can do action on click
+class LRClickableArea: public CIntObject
+{
+	std::function<void()> onClick;
+	std::function<void()> onPopup;
+public:
+	void clickPressed(const Point & cursorPosition) override;
+	void showPopupWindow(const Point & cursorPosition) override;
+	LRClickableArea(const Rect & Pos, std::function<void()> onClick = nullptr, std::function<void()> onPopup = nullptr);
+};
+
 class MoraleLuckBox : public LRClickableAreaWTextComp
 {
 	std::shared_ptr<CAnimImage> image;

+ 15 - 0
client/windows/CCastleInterface.cpp

@@ -1294,6 +1294,21 @@ void CCastleInterface::recreateIcons()
 	fastArmyPurchase->setImageOrder(town->fortLevel() - 1, town->fortLevel() - 1, town->fortLevel() - 1, town->fortLevel() - 1);
 	fastArmyPurchase->setAnimateLonelyFrame(true);
 
+	fastMarket = std::make_shared<LRClickableArea>(Rect(163, 410, 64, 42), [&]()
+	{
+		if(town->builtBuildings.count(BuildingID::MARKETPLACE))
+		{
+			if (town->getOwner() == LOCPLINT->playerID)
+				GH.windows().createAndPushWindow<CMarketplaceWindow>(town, town->visitingHero, nullptr, EMarketMode::RESOURCE_RESOURCE);
+		}
+	});
+	
+	fastTavern = std::make_shared<LRClickableArea>(Rect(15, 387, 58, 64), [&]()
+	{
+		if(town->builtBuildings.count(BuildingID::TAVERN))
+			LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
+	});
+
 	creainfo.clear();
 
 	bool compactCreatureInfo = useCompactCreatureBox();

+ 4 - 1
client/windows/CCastleInterface.h

@@ -36,6 +36,7 @@ class CTownList;
 class CGarrisonInt;
 class CComponent;
 class CComponentBox;
+class LRClickableArea;
 
 /// Building "button"
 class CBuildingRect : public CShowableAnim
@@ -154,7 +155,7 @@ class CCastleBuildings : public CIntObject
 	void enterCastleGate();
 	void enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades);//Rampart's fountains
 	void enterMagesGuild();
-
+	
 	void openMagesGuild();
 	void openTownHall();
 
@@ -228,6 +229,8 @@ class CCastleInterface : public CStatusbarWindow, public IGarrisonHolder
 	std::shared_ptr<CButton> split;
 	std::shared_ptr<CButton> fastTownHall;
 	std::shared_ptr<CButton> fastArmyPurchase;
+	std::shared_ptr<LRClickableArea> fastMarket;
+	std::shared_ptr<LRClickableArea> fastTavern;
 
 	std::vector<std::shared_ptr<CCreaInfo>> creainfo;//small icons of creatures (bottom-left corner);
 

+ 28 - 0
client/windows/CKingdomInterface.cpp

@@ -19,12 +19,14 @@
 #include "../adventureMap/CResDataBar.h"
 #include "../gui/CGuiHandler.h"
 #include "../gui/Shortcut.h"
+#include "../gui/WindowHandler.h"
 #include "../widgets/CComponent.h"
 #include "../widgets/CGarrisonInt.h"
 #include "../widgets/TextControls.h"
 #include "../widgets/MiscWidgets.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/ObjectLists.h"
+#include "../windows/CTradeWindow.h"
 
 #include "../../CCallback.h"
 
@@ -471,6 +473,8 @@ CKingdomInterface::CKingdomInterface()
 
 	statusbar = CGStatusBar::create(std::make_shared<CPicture>(ImagePath::builtin("KSTATBAR"), 10,pos.h - 45));
 	resdatabar = std::make_shared<CResDataBar>(ImagePath::builtin("KRESBAR"), 7, 111+footerPos, 29, 5, 76, 81);
+
+	activateTab(persistentStorage["gui"]["lastKindomInterface"].Integer());
 }
 
 void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects)
@@ -595,6 +599,20 @@ void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstan
 	incomeArea->pos = Rect(pos.x+580, pos.y+31+footerPos, 136, 68);
 	incomeArea->hoverText = CGI->generaltexth->allTexts[255];
 	incomeAmount = std::make_shared<CLabel>(628, footerPos + 70, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(totalIncome));
+
+	fastMarket = std::make_shared<LRClickableArea>(Rect(20, 31 + footerPos, 716, 68), []()
+	{
+		std::vector<const CGTownInstance*> towns = LOCPLINT->cb->getTownsInfo(true);
+		for(auto & town : towns)
+		{
+			if(town->builtBuildings.count(BuildingID::MARKETPLACE))
+			{
+				GH.windows().createAndPushWindow<CMarketplaceWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
+				return;
+			}
+		}
+		LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithMarket"));
+	});
 }
 
 void CKingdomInterface::generateButtons()
@@ -628,6 +646,9 @@ void CKingdomInterface::generateButtons()
 
 void CKingdomInterface::activateTab(size_t which)
 {
+	Settings s = persistentStorage.write["gui"]["lastKindomInterface"];
+	s->Integer() = which;
+
 	btnHeroes->block(which == 0);
 	btnTowns->block(which == 1);
 	tabArea->setActive(which);
@@ -772,6 +793,13 @@ CTownItem::CTownItem(const CGTownInstance * Town)
 	hall = std::make_shared<CTownInfo>( 69, 31, town, true);
 	fort = std::make_shared<CTownInfo>(111, 31, town, false);
 
+	fastTownHall = std::make_shared<CButton>(Point(69, 31), AnimationPath::builtin("ITMTL.def"), CButton::tooltip(), [&]() { std::make_shared<CCastleBuildings>(town)->enterTownHall(); });
+	fastTownHall->setImageOrder(town->hallLevel() - 1, town->hallLevel() - 1, town->hallLevel() - 1, town->hallLevel() - 1);
+	fastTownHall->setAnimateLonelyFrame(true);
+	fastArmyPurchase = std::make_shared<CButton>(Point(111, 31), AnimationPath::builtin("itmcl.def"), CButton::tooltip(), [&]() { std::make_shared<CCastleBuildings>(town)->enterToTheQuickRecruitmentWindow(); });
+	fastArmyPurchase->setImageOrder(town->fortLevel() - 1, town->fortLevel() - 1, town->fortLevel() - 1, town->fortLevel() - 1);
+	fastArmyPurchase->setAnimateLonelyFrame(true);
+
 	garr = std::make_shared<CGarrisonInt>(Point(313, 3), 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, CGarrisonInt::ESlotsLayout::TWO_ROWS);
 	heroes = std::make_shared<HeroSlots>(town, Point(244,6), Point(475,6), garr, false);
 

+ 4 - 0
client/windows/CKingdomInterface.h

@@ -233,6 +233,7 @@ private:
 
 	std::shared_ptr<CHoverableArea> incomeArea;
 	std::shared_ptr<CLabel> incomeAmount;
+	std::shared_ptr<LRClickableArea> fastMarket;
 
 	std::shared_ptr<CGStatusBar> statusbar;
 	std::shared_ptr<CResDataBar> resdatabar;
@@ -277,6 +278,9 @@ class CTownItem : public CIntObject, public IGarrisonHolder
 
 	std::shared_ptr<LRClickableAreaOpenTown> openTown;
 
+	std::shared_ptr<CButton> fastTownHall;
+	std::shared_ptr<CButton> fastArmyPurchase;
+
 public:
 	const CGTownInstance * town;