mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
data to clipboard; simplify types
This commit is contained in:
@@ -163,8 +163,7 @@
|
|||||||
"vcmi.systemOptions.townsGroup" : "Town Screen",
|
"vcmi.systemOptions.townsGroup" : "Town Screen",
|
||||||
|
|
||||||
"vcmi.statisticWindow.statistic" : "Statistic",
|
"vcmi.statisticWindow.statistic" : "Statistic",
|
||||||
"vcmi.statisticWindow.csvSave" : "Save as CSV",
|
"vcmi.statisticWindow.tsvCopy" : "Data to clipboard",
|
||||||
"vcmi.statisticWindow.csvSaved" : "CSV saved!",
|
|
||||||
"vcmi.statisticWindow.selectView" : "Select view",
|
"vcmi.statisticWindow.selectView" : "Select view",
|
||||||
"vcmi.statisticWindow.value" : "Value",
|
"vcmi.statisticWindow.value" : "Value",
|
||||||
"vcmi.statisticWindow.title.overview" : "Overview",
|
"vcmi.statisticWindow.title.overview" : "Overview",
|
||||||
|
|||||||
@@ -163,8 +163,7 @@
|
|||||||
"vcmi.systemOptions.townsGroup" : "Stadt-Bildschirm",
|
"vcmi.systemOptions.townsGroup" : "Stadt-Bildschirm",
|
||||||
|
|
||||||
"vcmi.statisticWindow.statistic" : "Statistik",
|
"vcmi.statisticWindow.statistic" : "Statistik",
|
||||||
"vcmi.statisticWindow.csvSave" : "Speichere als CSV",
|
"vcmi.statisticWindow.tsvCopy" : "Daten in Zwischenabl.",
|
||||||
"vcmi.statisticWindow.csvSaved" : "CSV gespeichert!",
|
|
||||||
"vcmi.statisticWindow.selectView" : "Ansicht wählen",
|
"vcmi.statisticWindow.selectView" : "Ansicht wählen",
|
||||||
"vcmi.statisticWindow.value" : "Wert",
|
"vcmi.statisticWindow.value" : "Wert",
|
||||||
"vcmi.statisticWindow.title.overview" : "Überblick",
|
"vcmi.statisticWindow.title.overview" : "Überblick",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <SDL_events.h>
|
#include <SDL_events.h>
|
||||||
#include <SDL_timer.h>
|
#include <SDL_timer.h>
|
||||||
|
#include <SDL_clipboard.h>
|
||||||
|
|
||||||
InputHandler::InputHandler()
|
InputHandler::InputHandler()
|
||||||
: enableMouse(settings["input"]["enableMouse"].Bool())
|
: enableMouse(settings["input"]["enableMouse"].Bool())
|
||||||
@@ -142,6 +143,11 @@ InputMode InputHandler::getCurrentInputMode()
|
|||||||
return currentInputMode;
|
return currentInputMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputHandler::copyToClipBoard(std::string text)
|
||||||
|
{
|
||||||
|
SDL_SetClipboardText(text.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<SDL_Event> InputHandler::acquireEvents()
|
std::vector<SDL_Event> InputHandler::acquireEvents()
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::mutex> lock(eventsMutex);
|
boost::unique_lock<boost::mutex> lock(eventsMutex);
|
||||||
|
|||||||
@@ -103,4 +103,6 @@ public:
|
|||||||
bool isKeyboardShiftDown() const;
|
bool isKeyboardShiftDown() const;
|
||||||
|
|
||||||
InputMode getCurrentInputMode();
|
InputMode getCurrentInputMode();
|
||||||
|
|
||||||
|
void copyToClipBoard(std::string text);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../gui/WindowHandler.h"
|
#include "../gui/WindowHandler.h"
|
||||||
|
#include "../eventsSDL/InputHandler.h"
|
||||||
#include "../gui/Shortcut.h"
|
#include "../gui/Shortcut.h"
|
||||||
|
|
||||||
#include "../render/Graphics.h"
|
#include "../render/Graphics.h"
|
||||||
@@ -74,23 +75,20 @@ CStatisticScreen::CStatisticScreen(StatisticDataSet stat)
|
|||||||
});
|
});
|
||||||
buttonSelect->setTextOverlay(CGI->generaltexth->translate("vcmi.statisticWindow.selectView"), EFonts::FONT_SMALL, Colors::YELLOW);
|
buttonSelect->setTextOverlay(CGI->generaltexth->translate("vcmi.statisticWindow.selectView"), EFonts::FONT_SMALL, Colors::YELLOW);
|
||||||
|
|
||||||
buttonCsvSave = std::make_shared<CToggleButton>(Point(150, 564), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), [this](bool on){
|
buttonCsvSave = std::make_shared<CToggleButton>(Point(150, 564), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), [this](bool on){ GH.input().copyToClipBoard(statistic.toCsv("\t")); });
|
||||||
std::string path = statistic.writeCsv();
|
buttonCsvSave->setTextOverlay(CGI->generaltexth->translate("vcmi.statisticWindow.tsvCopy"), EFonts::FONT_SMALL, Colors::YELLOW);
|
||||||
CInfoWindow::showInfoDialog(CGI->generaltexth->translate("vcmi.statisticWindow.csvSaved") + "\n\n" + path, {});
|
|
||||||
});
|
|
||||||
buttonCsvSave->setTextOverlay(CGI->generaltexth->translate("vcmi.statisticWindow.csvSave"), EFonts::FONT_SMALL, Colors::YELLOW);
|
|
||||||
|
|
||||||
mainContent = getContent(OVERVIEW, EGameResID::NONE);
|
mainContent = getContent(OVERVIEW, EGameResID::NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<ColorRGBA, std::vector<float>> CStatisticScreen::extractData(StatisticDataSet stat, std::function<float(StatisticDataSetEntry val)> selector)
|
TData CStatisticScreen::extractData(StatisticDataSet stat, std::function<float(StatisticDataSetEntry val)> selector)
|
||||||
{
|
{
|
||||||
auto tmpData = stat.data;
|
auto tmpData = stat.data;
|
||||||
std::sort(tmpData.begin(), tmpData.end(), [](StatisticDataSetEntry v1, StatisticDataSetEntry v2){ return v1.player == v2.player ? v1.day < v2.day : v1.player < v2.player; });
|
std::sort(tmpData.begin(), tmpData.end(), [](StatisticDataSetEntry v1, StatisticDataSetEntry v2){ return v1.player == v2.player ? v1.day < v2.day : v1.player < v2.player; });
|
||||||
|
|
||||||
PlayerColor tmpColor = PlayerColor::NEUTRAL;
|
PlayerColor tmpColor = PlayerColor::NEUTRAL;
|
||||||
std::vector<float> tmpColorSet;
|
std::vector<float> tmpColorSet;
|
||||||
std::map<ColorRGBA, std::vector<float>> plotData;
|
TData plotData;
|
||||||
for(auto & val : tmpData)
|
for(auto & val : tmpData)
|
||||||
{
|
{
|
||||||
if(tmpColor != val.player)
|
if(tmpColor != val.player)
|
||||||
@@ -114,8 +112,8 @@ std::map<ColorRGBA, std::vector<float>> CStatisticScreen::extractData(StatisticD
|
|||||||
|
|
||||||
std::shared_ptr<CIntObject> CStatisticScreen::getContent(Content c, EGameResID res)
|
std::shared_ptr<CIntObject> CStatisticScreen::getContent(Content c, EGameResID res)
|
||||||
{
|
{
|
||||||
LineChart::TData plotData;
|
TData plotData;
|
||||||
LineChart::TIcons icons;
|
TIcons icons;
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ class ComboBox;
|
|||||||
class CSlider;
|
class CSlider;
|
||||||
class IImage;
|
class IImage;
|
||||||
|
|
||||||
|
using TData = std::map<ColorRGBA, std::vector<float>>;
|
||||||
|
using TIcons = std::map<ColorRGBA, std::vector<std::pair<int, std::shared_ptr<IImage>>>>;
|
||||||
|
|
||||||
class CStatisticScreen : public CWindowObject
|
class CStatisticScreen : public CWindowObject
|
||||||
{
|
{
|
||||||
enum Content {
|
enum Content {
|
||||||
@@ -61,7 +64,7 @@ class CStatisticScreen : public CWindowObject
|
|||||||
std::shared_ptr<CIntObject> mainContent;
|
std::shared_ptr<CIntObject> mainContent;
|
||||||
Rect contentArea;
|
Rect contentArea;
|
||||||
|
|
||||||
std::map<ColorRGBA, std::vector<float>> extractData(StatisticDataSet stat, std::function<float(StatisticDataSetEntry val)> selector);
|
TData extractData(StatisticDataSet stat, std::function<float(StatisticDataSetEntry val)> selector);
|
||||||
std::shared_ptr<CIntObject> getContent(Content c, EGameResID res);
|
std::shared_ptr<CIntObject> getContent(Content c, EGameResID res);
|
||||||
public:
|
public:
|
||||||
CStatisticScreen(StatisticDataSet stat);
|
CStatisticScreen(StatisticDataSet stat);
|
||||||
@@ -116,9 +119,6 @@ class LineChart : public CIntObject
|
|||||||
|
|
||||||
void updateStatusBar(const Point & cursorPosition);
|
void updateStatusBar(const Point & cursorPosition);
|
||||||
public:
|
public:
|
||||||
using TData = std::map<ColorRGBA, std::vector<float>>;
|
|
||||||
using TIcons = std::map<ColorRGBA, std::vector<std::pair<int, std::shared_ptr<IImage>>>>;
|
|
||||||
|
|
||||||
LineChart(Rect position, std::string title, TData data, TIcons icons, float maxY);
|
LineChart(Rect position, std::string title, TData data, TIcons icons, float maxY);
|
||||||
|
|
||||||
void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override;
|
void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override;
|
||||||
|
|||||||
@@ -81,98 +81,98 @@ StatisticDataSetEntry StatisticDataSet::createEntry(const PlayerState * ps, cons
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StatisticDataSet::toCsv()
|
std::string StatisticDataSet::toCsv(std::string sep)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
auto resources = std::vector<EGameResID>{EGameResID::GOLD, EGameResID::WOOD, EGameResID::MERCURY, EGameResID::ORE, EGameResID::SULFUR, EGameResID::CRYSTAL, EGameResID::GEMS};
|
auto resources = std::vector<EGameResID>{EGameResID::GOLD, EGameResID::WOOD, EGameResID::MERCURY, EGameResID::ORE, EGameResID::SULFUR, EGameResID::CRYSTAL, EGameResID::GEMS};
|
||||||
|
|
||||||
ss << "Map" << ";";
|
ss << "Map" << sep;
|
||||||
ss << "Timestamp" << ";";
|
ss << "Timestamp" << sep;
|
||||||
ss << "Day" << ";";
|
ss << "Day" << sep;
|
||||||
ss << "Player" << ";";
|
ss << "Player" << sep;
|
||||||
ss << "PlayerName" << ";";
|
ss << "PlayerName" << sep;
|
||||||
ss << "Team" << ";";
|
ss << "Team" << sep;
|
||||||
ss << "IsHuman" << ";";
|
ss << "IsHuman" << sep;
|
||||||
ss << "Status" << ";";
|
ss << "Status" << sep;
|
||||||
ss << "NumberHeroes" << ";";
|
ss << "NumberHeroes" << sep;
|
||||||
ss << "NumberTowns" << ";";
|
ss << "NumberTowns" << sep;
|
||||||
ss << "NumberArtifacts" << ";";
|
ss << "NumberArtifacts" << sep;
|
||||||
ss << "NumberDwellings" << ";";
|
ss << "NumberDwellings" << sep;
|
||||||
ss << "ArmyStrength" << ";";
|
ss << "ArmyStrength" << sep;
|
||||||
ss << "TotalExperience" << ";";
|
ss << "TotalExperience" << sep;
|
||||||
ss << "Income" << ";";
|
ss << "Income" << sep;
|
||||||
ss << "MapExploredRatio" << ";";
|
ss << "MapExploredRatio" << sep;
|
||||||
ss << "ObeliskVisitedRatio" << ";";
|
ss << "ObeliskVisitedRatio" << sep;
|
||||||
ss << "TownBuiltRatio" << ";";
|
ss << "TownBuiltRatio" << sep;
|
||||||
ss << "HasGrail" << ";";
|
ss << "HasGrail" << sep;
|
||||||
ss << "Score" << ";";
|
ss << "Score" << sep;
|
||||||
ss << "MaxHeroLevel" << ";";
|
ss << "MaxHeroLevel" << sep;
|
||||||
ss << "NumBattlesNeutral" << ";";
|
ss << "NumBattlesNeutral" << sep;
|
||||||
ss << "NumBattlesPlayer" << ";";
|
ss << "NumBattlesPlayer" << sep;
|
||||||
ss << "NumWinBattlesNeutral" << ";";
|
ss << "NumWinBattlesNeutral" << sep;
|
||||||
ss << "NumWinBattlesPlayer" << ";";
|
ss << "NumWinBattlesPlayer" << sep;
|
||||||
ss << "NumHeroSurrendered" << ";";
|
ss << "NumHeroSurrendered" << sep;
|
||||||
ss << "NumHeroEscaped" << ";";
|
ss << "NumHeroEscaped" << sep;
|
||||||
ss << "EventCapturedTown" << ";";
|
ss << "EventCapturedTown" << sep;
|
||||||
ss << "EventDefeatedStrongestHero" << ";";
|
ss << "EventDefeatedStrongestHero" << sep;
|
||||||
ss << "EventRansackingDragonUtopia" << ";";
|
ss << "EventRansackingDragonUtopia" << sep;
|
||||||
ss << "MovementPointsUsed";
|
ss << "MovementPointsUsed";
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << GameConstants::RESOURCE_NAMES[resource];
|
ss << sep << GameConstants::RESOURCE_NAMES[resource];
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << GameConstants::RESOURCE_NAMES[resource] + "Mines";
|
ss << sep << GameConstants::RESOURCE_NAMES[resource] + "Mines";
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << GameConstants::RESOURCE_NAMES[resource] + "SpentResourcesForArmy";
|
ss << sep << GameConstants::RESOURCE_NAMES[resource] + "SpentResourcesForArmy";
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << GameConstants::RESOURCE_NAMES[resource] + "SpentResourcesForBuildings";
|
ss << sep << GameConstants::RESOURCE_NAMES[resource] + "SpentResourcesForBuildings";
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << GameConstants::RESOURCE_NAMES[resource] + "TradeVolume";
|
ss << sep << GameConstants::RESOURCE_NAMES[resource] + "TradeVolume";
|
||||||
ss << "\r\n";
|
ss << "\r\n";
|
||||||
|
|
||||||
for(auto & entry : data)
|
for(auto & entry : data)
|
||||||
{
|
{
|
||||||
ss << entry.map << ";";
|
ss << entry.map << sep;
|
||||||
ss << vstd::getFormattedDateTime(entry.timestamp, "%Y-%m-%dT%H:%M:%S") << ";";
|
ss << vstd::getFormattedDateTime(entry.timestamp, "%Y-%m-%dT%H:%M:%S") << sep;
|
||||||
ss << entry.day << ";";
|
ss << entry.day << sep;
|
||||||
ss << GameConstants::PLAYER_COLOR_NAMES[entry.player] << ";";
|
ss << GameConstants::PLAYER_COLOR_NAMES[entry.player] << sep;
|
||||||
ss << entry.playerName << ";";
|
ss << entry.playerName << sep;
|
||||||
ss << entry.team.getNum() << ";";
|
ss << entry.team.getNum() << sep;
|
||||||
ss << entry.isHuman << ";";
|
ss << entry.isHuman << sep;
|
||||||
ss << static_cast<int>(entry.status) << ";";
|
ss << static_cast<int>(entry.status) << sep;
|
||||||
ss << entry.numberHeroes << ";";
|
ss << entry.numberHeroes << sep;
|
||||||
ss << entry.numberTowns << ";";
|
ss << entry.numberTowns << sep;
|
||||||
ss << entry.numberArtifacts << ";";
|
ss << entry.numberArtifacts << sep;
|
||||||
ss << entry.numberDwellings << ";";
|
ss << entry.numberDwellings << sep;
|
||||||
ss << entry.armyStrength << ";";
|
ss << entry.armyStrength << sep;
|
||||||
ss << entry.totalExperience << ";";
|
ss << entry.totalExperience << sep;
|
||||||
ss << entry.income << ";";
|
ss << entry.income << sep;
|
||||||
ss << entry.mapExploredRatio << ";";
|
ss << entry.mapExploredRatio << sep;
|
||||||
ss << entry.obeliskVisitedRatio << ";";
|
ss << entry.obeliskVisitedRatio << sep;
|
||||||
ss << entry.townBuiltRatio << ";";
|
ss << entry.townBuiltRatio << sep;
|
||||||
ss << entry.hasGrail << ";";
|
ss << entry.hasGrail << sep;
|
||||||
ss << entry.score << ";";
|
ss << entry.score << sep;
|
||||||
ss << entry.maxHeroLevel << ";";
|
ss << entry.maxHeroLevel << sep;
|
||||||
ss << entry.numBattlesNeutral << ";";
|
ss << entry.numBattlesNeutral << sep;
|
||||||
ss << entry.numBattlesPlayer << ";";
|
ss << entry.numBattlesPlayer << sep;
|
||||||
ss << entry.numWinBattlesNeutral << ";";
|
ss << entry.numWinBattlesNeutral << sep;
|
||||||
ss << entry.numWinBattlesPlayer << ";";
|
ss << entry.numWinBattlesPlayer << sep;
|
||||||
ss << entry.numHeroSurrendered << ";";
|
ss << entry.numHeroSurrendered << sep;
|
||||||
ss << entry.numHeroEscaped << ";";
|
ss << entry.numHeroEscaped << sep;
|
||||||
ss << entry.eventCapturedTown << ";";
|
ss << entry.eventCapturedTown << sep;
|
||||||
ss << entry.eventDefeatedStrongestHero << ";";
|
ss << entry.eventDefeatedStrongestHero << sep;
|
||||||
ss << entry.eventRansackingDragonUtopia << ";";
|
ss << entry.eventRansackingDragonUtopia << sep;
|
||||||
ss << entry.movementPointsUsed;
|
ss << entry.movementPointsUsed;
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << entry.resources[resource];
|
ss << sep << entry.resources[resource];
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << entry.numMines[resource];
|
ss << sep << entry.numMines[resource];
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << entry.spentResourcesForArmy[resource];
|
ss << sep << entry.spentResourcesForArmy[resource];
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << entry.spentResourcesForBuildings[resource];
|
ss << sep << entry.spentResourcesForBuildings[resource];
|
||||||
for(auto & resource : resources)
|
for(auto & resource : resources)
|
||||||
ss << ";" << entry.tradeVolume[resource];
|
ss << sep << entry.tradeVolume[resource];
|
||||||
ss << "\r\n";
|
ss << "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ std::string StatisticDataSet::writeCsv()
|
|||||||
|
|
||||||
const boost::filesystem::path filePath = outPath / (vstd::getDateTimeISO8601Basic(std::time(nullptr)) + ".csv");
|
const boost::filesystem::path filePath = outPath / (vstd::getDateTimeISO8601Basic(std::time(nullptr)) + ".csv");
|
||||||
std::ofstream file(filePath.c_str());
|
std::ofstream file(filePath.c_str());
|
||||||
std::string csv = toCsv();
|
std::string csv = toCsv(";");
|
||||||
file << csv;
|
file << csv;
|
||||||
|
|
||||||
return filePath.string();
|
return filePath.string();
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ class DLL_LINKAGE StatisticDataSet
|
|||||||
public:
|
public:
|
||||||
void add(StatisticDataSetEntry entry);
|
void add(StatisticDataSetEntry entry);
|
||||||
static StatisticDataSetEntry createEntry(const PlayerState * ps, const CGameState * gs);
|
static StatisticDataSetEntry createEntry(const PlayerState * ps, const CGameState * gs);
|
||||||
std::string toCsv();
|
std::string toCsv(std::string sep);
|
||||||
std::string writeCsv();
|
std::string writeCsv();
|
||||||
|
|
||||||
struct PlayerAccumulatedValueStorage // holds some actual values needed for stats
|
struct PlayerAccumulatedValueStorage // holds some actual values needed for stats
|
||||||
|
|||||||
Reference in New Issue
Block a user