浏览代码

icon drawing

Laserlicht 1 年之前
父节点
当前提交
5743f151a1

+ 4 - 0
Mods/vcmi/config/vcmi/english.json

@@ -189,6 +189,10 @@
 	"vcmi.statisticWindow.param.maxArmyStrength" : "Max total army strength",
 	"vcmi.statisticWindow.param.maxArmyStrength" : "Max total army strength",
 	"vcmi.statisticWindow.param.tradeVolume" : "Trade volume",
 	"vcmi.statisticWindow.param.tradeVolume" : "Trade volume",
 	"vcmi.statisticWindow.param.obeliskVisited" : "Obelisk visited",
 	"vcmi.statisticWindow.param.obeliskVisited" : "Obelisk visited",
+	"vcmi.statisticWindow.icon.townCaptured" : "Town captured",
+	"vcmi.statisticWindow.icon.strongestHeroDefeated" : "Strongest hero of opponent defeated",
+	"vcmi.statisticWindow.icon.grailFound" : "Grail found",
+	"vcmi.statisticWindow.icon.defeated" : "Defeated",
 
 
 	"vcmi.systemOptions.fullscreenBorderless.hover" : "Fullscreen (borderless)",
 	"vcmi.systemOptions.fullscreenBorderless.hover" : "Fullscreen (borderless)",
 	"vcmi.systemOptions.fullscreenBorderless.help"  : "{Borderless Fullscreen}\n\nIf selected, VCMI will run in borderless fullscreen mode. In this mode, game will always use same resolution as desktop, ignoring selected resolution.",
 	"vcmi.systemOptions.fullscreenBorderless.help"  : "{Borderless Fullscreen}\n\nIf selected, VCMI will run in borderless fullscreen mode. In this mode, game will always use same resolution as desktop, ignoring selected resolution.",

+ 4 - 0
Mods/vcmi/config/vcmi/german.json

@@ -189,6 +189,10 @@
 	"vcmi.statisticWindow.param.maxArmyStrength" : "Max Gesamt-Armeestärke",
 	"vcmi.statisticWindow.param.maxArmyStrength" : "Max Gesamt-Armeestärke",
 	"vcmi.statisticWindow.param.tradeVolume" : "Handelsvol.",
 	"vcmi.statisticWindow.param.tradeVolume" : "Handelsvol.",
 	"vcmi.statisticWindow.param.obeliskVisited" : "Obelisk besucht",
 	"vcmi.statisticWindow.param.obeliskVisited" : "Obelisk besucht",
+	"vcmi.statisticWindow.icon.townCaptured" : "Stadt erobert",
+	"vcmi.statisticWindow.icon.strongestHeroDefeated" : "Stärksten helden eines Gegners besiegt",
+	"vcmi.statisticWindow.icon.grailFound" : "Gral gefunden",
+	"vcmi.statisticWindow.icon.defeated" : "Besiegt",
 
 
 	"vcmi.systemOptions.fullscreenBorderless.hover" : "Vollbild (randlos)",
 	"vcmi.systemOptions.fullscreenBorderless.hover" : "Vollbild (randlos)",
 	"vcmi.systemOptions.fullscreenBorderless.help"  : "{Randloses Vollbild}\n\nWenn diese Option ausgewählt ist, wird VCMI im randlosen Vollbildmodus ausgeführt. In diesem Modus wird das Spiel immer dieselbe Auflösung wie der Desktop verwenden und die gewählte Auflösung ignorieren.",
 	"vcmi.systemOptions.fullscreenBorderless.help"  : "{Randloses Vollbild}\n\nWenn diese Option ausgewählt ist, wird VCMI im randlosen Vollbildmodus ausgeführt. In diesem Modus wird das Spiel immer dieselbe Auflösung wie der Desktop verwenden und die gewählte Auflösung ignorieren.",

+ 50 - 1
client/mainmenu/CStatisticScreen.cpp

@@ -20,6 +20,7 @@
 
 
 #include "../render/Graphics.h"
 #include "../render/Graphics.h"
 #include "../render/IImage.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 
 
 #include "../widgets/ComboBox.h"
 #include "../widgets/ComboBox.h"
 #include "../widgets/Images.h"
 #include "../widgets/Images.h"
@@ -119,10 +120,50 @@ TData CStatisticScreen::extractData(StatisticDataSet stat, std::function<float(S
 	return plotData;
 	return plotData;
 }
 }
 
 
+TIcons CStatisticScreen::extractIcons()
+{
+	TIcons icons;
+
+	auto tmpData = statistic.data;
+	std::sort(tmpData.begin(), tmpData.end(), [](StatisticDataSetEntry v1, StatisticDataSetEntry v2){ return v1.player == v2.player ? v1.day < v2.day : v1.player < v2.player; });
+
+	auto imageTown = GH.renderHandler().loadImage(AnimationPath::builtin("cradvntr"), 3, 0, EImageBlitMode::COLORKEY);
+	imageTown->scaleFast(Point(CHART_ICON_SIZE, CHART_ICON_SIZE));
+	auto imageBattle = GH.renderHandler().loadImage(AnimationPath::builtin("cradvntr"), 5, 0, EImageBlitMode::COLORKEY);
+	imageBattle->scaleFast(Point(CHART_ICON_SIZE, CHART_ICON_SIZE));
+	auto imageDefeated = GH.renderHandler().loadImage(AnimationPath::builtin("tpthchk"), 1, 0, EImageBlitMode::COLORKEY);
+	imageDefeated->scaleFast(Point(CHART_ICON_SIZE, CHART_ICON_SIZE));
+	auto imageGrail = GH.renderHandler().loadImage(AnimationPath::builtin("vwsymbol"), 2, 0, EImageBlitMode::COLORKEY);
+	imageGrail->scaleFast(Point(CHART_ICON_SIZE, CHART_ICON_SIZE));
+
+	std::map<PlayerColor, bool> foundDefeated;
+	std::map<PlayerColor, bool> foundGrail;
+
+	for(auto & val : tmpData)
+	{
+		if(val.eventCapturedTown)
+			icons.push_back({ graphics->playerColors[val.player], val.day, imageTown, CGI->generaltexth->translate("vcmi.statisticWindow.icon.townCaptured") });
+		if(val.eventDefeatedStrongestHero)
+			icons.push_back({ graphics->playerColors[val.player], val.day, imageBattle, CGI->generaltexth->translate("vcmi.statisticWindow.icon.strongestHeroDefeated") });
+		if(val.status == EPlayerStatus::LOSER && !foundDefeated[val.player])
+		{
+			foundDefeated[val.player] = true;
+			icons.push_back({ graphics->playerColors[val.player], val.day, imageDefeated, CGI->generaltexth->translate("vcmi.statisticWindow.icon.defeated") });
+		}
+		if(val.hasGrail && !foundGrail[val.player])
+		{
+			foundGrail[val.player] = true;
+			icons.push_back({ graphics->playerColors[val.player], val.day, imageGrail, CGI->generaltexth->translate("vcmi.statisticWindow.icon.grailFound") });
+		}
+	}
+
+	return icons;
+}
+
 std::shared_ptr<CIntObject> CStatisticScreen::getContent(Content c, EGameResID res)
 std::shared_ptr<CIntObject> CStatisticScreen::getContent(Content c, EGameResID res)
 {
 {
 	TData plotData;
 	TData plotData;
-	TIcons icons;
+	TIcons icons = extractIcons();;
 
 
 	switch (c)
 	switch (c)
 	{
 	{
@@ -424,6 +465,14 @@ LineChart::LineChart(Rect position, std::string title, TData data, TIcons icons,
 
 
 			if(lastPoint.x != -1)
 			if(lastPoint.x != -1)
 				canvas->addLine(lastPoint, p, line.first);
 				canvas->addLine(lastPoint, p, line.first);
+			
+			// icons
+			for(auto & icon : icons)
+				if(std::get<0>(icon) == line.first && std::get<1>(icon) == i + 1) // color && day
+				{
+					pictures.push_back(std::make_shared<CPicture>(std::get<2>(icon), Point(x - (CHART_ICON_SIZE / 2), y - (CHART_ICON_SIZE / 2)) + chartArea.topLeft()));
+					pictures.back()->addRClickCallback([icon](){ CRClickPopup::createAndPush(std::get<3>(icon)); });
+				}
 
 
 			lastPoint = p;
 			lastPoint = p;
 		}
 		}

+ 6 - 1
client/mainmenu/CStatisticScreen.h

@@ -19,9 +19,12 @@ class CGStatusBar;
 class ComboBox;
 class ComboBox;
 class CSlider;
 class CSlider;
 class IImage;
 class IImage;
+class CPicture;
 
 
 using TData = std::vector<std::pair<ColorRGBA, std::vector<float>>>;
 using TData = std::vector<std::pair<ColorRGBA, std::vector<float>>>;
-using TIcons = std::vector<std::pair<ColorRGBA, std::vector<std::pair<int, std::shared_ptr<IImage>>>>>;
+using TIcons = std::vector<std::tuple<ColorRGBA, int, std::shared_ptr<IImage>, std::string>>; // Color, Day, Image, Helptext
+
+const int CHART_ICON_SIZE = 32;
 
 
 class CStatisticScreen : public CWindowObject
 class CStatisticScreen : public CWindowObject
 {
 {
@@ -65,6 +68,7 @@ class CStatisticScreen : public CWindowObject
 	Rect contentArea;
 	Rect contentArea;
 
 
 	TData extractData(StatisticDataSet stat, std::function<float(StatisticDataSetEntry val)> selector);
 	TData extractData(StatisticDataSet stat, std::function<float(StatisticDataSetEntry val)> selector);
+	TIcons extractIcons();
 	std::shared_ptr<CIntObject> getContent(Content c, EGameResID res);
 	std::shared_ptr<CIntObject> getContent(Content c, EGameResID res);
 	void onSelectButton();
 	void onSelectButton();
 public:
 public:
@@ -114,6 +118,7 @@ class LineChart : public CIntObject
 	std::shared_ptr<GraphicalPrimitiveCanvas> canvas;
 	std::shared_ptr<GraphicalPrimitiveCanvas> canvas;
 	std::vector<std::shared_ptr<CIntObject>> layout;
 	std::vector<std::shared_ptr<CIntObject>> layout;
 	std::shared_ptr<CGStatusBar> statusBar;
 	std::shared_ptr<CGStatusBar> statusBar;
+	std::vector<std::shared_ptr<CPicture>> pictures;
 
 
 	Rect chartArea;
 	Rect chartArea;
 	float maxVal;
 	float maxVal;

+ 19 - 0
client/widgets/Images.cpp

@@ -39,6 +39,8 @@ CPicture::CPicture(std::shared_ptr<IImage> image, const Point & position)
 	pos += position;
 	pos += position;
 	pos.w = bg->width();
 	pos.w = bg->width();
 	pos.h = bg->height();
 	pos.h = bg->height();
+
+	addUsedEvents(SHOW_POPUP);
 }
 }
 
 
 CPicture::CPicture( const ImagePath &bmpname, int x, int y )
 CPicture::CPicture( const ImagePath &bmpname, int x, int y )
@@ -66,6 +68,8 @@ CPicture::CPicture( const ImagePath & bmpname, const Point & position )
 	{
 	{
 		pos.w = pos.h = 0;
 		pos.w = pos.h = 0;
 	}
 	}
+
+	addUsedEvents(SHOW_POPUP);
 }
 }
 
 
 CPicture::CPicture(const ImagePath & bmpname, const Rect &SrcRect, int x, int y)
 CPicture::CPicture(const ImagePath & bmpname, const Rect &SrcRect, int x, int y)
@@ -74,6 +78,8 @@ CPicture::CPicture(const ImagePath & bmpname, const Rect &SrcRect, int x, int y)
 	srcRect = SrcRect;
 	srcRect = SrcRect;
 	pos.w = srcRect->w;
 	pos.w = srcRect->w;
 	pos.h = srcRect->h;
 	pos.h = srcRect->h;
+
+	addUsedEvents(SHOW_POPUP);
 }
 }
 
 
 CPicture::CPicture(std::shared_ptr<IImage> image, const Rect &SrcRect, int x, int y)
 CPicture::CPicture(std::shared_ptr<IImage> image, const Rect &SrcRect, int x, int y)
@@ -82,6 +88,8 @@ CPicture::CPicture(std::shared_ptr<IImage> image, const Rect &SrcRect, int x, in
 	srcRect = SrcRect;
 	srcRect = SrcRect;
 	pos.w = srcRect->w;
 	pos.w = srcRect->w;
 	pos.h = srcRect->h;
 	pos.h = srcRect->h;
+
+	addUsedEvents(SHOW_POPUP);
 }
 }
 
 
 void CPicture::show(Canvas & to)
 void CPicture::show(Canvas & to)
@@ -119,6 +127,17 @@ void CPicture::setPlayerColor(PlayerColor player)
 	bg->playerColored(player);
 	bg->playerColored(player);
 }
 }
 
 
+void CPicture::addRClickCallback(std::function<void()> callback)
+{
+	rCallback = callback;
+}
+
+void CPicture::showPopupWindow(const Point & cursorPosition)
+{
+	if(rCallback)
+		rCallback();
+}
+
 CFilledTexture::CFilledTexture(const ImagePath & imageName, Rect position)
 CFilledTexture::CFilledTexture(const ImagePath & imageName, Rect position)
 	: CIntObject(0, position.topLeft())
 	: CIntObject(0, position.topLeft())
 	, texture(GH.renderHandler().loadImage(imageName, EImageBlitMode::COLORKEY))
 	, texture(GH.renderHandler().loadImage(imageName, EImageBlitMode::COLORKEY))

+ 4 - 0
client/widgets/Images.h

@@ -26,6 +26,7 @@ class IImage;
 class CPicture : public CIntObject
 class CPicture : public CIntObject
 {
 {
 	std::shared_ptr<IImage> bg;
 	std::shared_ptr<IImage> bg;
+	std::function<void()> rCallback;
 
 
 public:
 public:
 	/// if set, only specified section of internal image will be rendered
 	/// if set, only specified section of internal image will be rendered
@@ -57,8 +58,11 @@ public:
 	void scaleTo(Point size);
 	void scaleTo(Point size);
 	void setPlayerColor(PlayerColor player);
 	void setPlayerColor(PlayerColor player);
 
 
+	void addRClickCallback(std::function<void()> callback);
+
 	void show(Canvas & to) override;
 	void show(Canvas & to) override;
 	void showAll(Canvas & to) override;
 	void showAll(Canvas & to) override;
+	void showPopupWindow(const Point & cursorPosition) override;
 };
 };
 
 
 /// area filled with specific texture
 /// area filled with specific texture

+ 5 - 0
lib/Color.h

@@ -57,6 +57,11 @@ public:
 		h & b;
 		h & b;
 		h & a;
 		h & a;
 	}
 	}
+
+	bool operator==(ColorRGBA const& rhs) const
+	{
+		return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
+	}
 };
 };
 
 
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END