AppStats.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. #include "AppStats.hpp"
  2. #include "AssetManager.hpp"
  3. #include "Theme.hpp"
  4. #include "Util.hpp"
  5. #include "Config.hpp"
  6. #include "AppInfo.hpp"
  7. #include "States/StateIdentifiers.hpp"
  8. #include "States/DialogState.hpp"
  9. #include "States/SyncState.hpp"
  10. #include <cpp3ds/System/I18n.hpp>
  11. #include <cpp3ds/System/FileSystem.hpp>
  12. #include <TweenEngine/Tween.h>
  13. namespace FreeShop {
  14. AppStats::AppStats()
  15. : m_appItem(nullptr)
  16. , m_isVisible(false)
  17. , m_votes(0)
  18. , m_finalScore(0.f)
  19. , m_percentageGamers(0)
  20. , m_percentageEveryone(0)
  21. , m_percentageCasual(0)
  22. , m_percentageIntense(0)
  23. {
  24. m_overlay.setSize(cpp3ds::Vector2f(400.f, 240.f));
  25. m_overlay.setFillColor(cpp3ds::Color(0, 0, 0, 0));
  26. if (Theme::isTextThemed)
  27. m_topBackground.setOutlineColor(Theme::boxOutlineColor);
  28. else
  29. m_topBackground.setOutlineColor(cpp3ds::Color(158, 158, 158, 255));
  30. m_topBackground.setOutlineThickness(1);
  31. if (Theme::isTextThemed)
  32. m_topBackground.setFillColor(Theme::boxColor);
  33. else
  34. m_topBackground.setFillColor(cpp3ds::Color(245, 245, 245));
  35. m_topBackground.setSize(cpp3ds::Vector2f(400.f, 116.f));
  36. m_topBackground.setPosition(0.f, 124.f);
  37. m_botBackground = m_topBackground;
  38. m_botBackground.setSize(cpp3ds::Vector2f(320.f, 165.f));
  39. m_botBackground.setPosition(0.f, 0.f);
  40. m_statText.setPosition(200.f, 136.f);
  41. if (Theme::isTextThemed)
  42. m_statText.setFillColor(Theme::primaryTextColor);
  43. else
  44. m_statText.setFillColor(cpp3ds::Color::Black);
  45. m_statText.setCharacterSize(16);
  46. m_statText.setString(_("Ratings"));
  47. m_statText.setOrigin(std::round(m_statText.getLocalBounds().width / 2), std::round(m_statText.getLocalBounds().height / 2));
  48. m_preferenceText = m_statText;
  49. m_preferenceText.setString(_("Preferences"));
  50. m_preferenceText.setOrigin(std::round(m_preferenceText.getLocalBounds().width / 2), std::round(m_preferenceText.getLocalBounds().height / 2));
  51. m_preferenceText.setPosition(160.f, 15.f);
  52. m_stars.resize(5);
  53. m_starsText.resize(5);
  54. m_ratings.resize(5);
  55. m_progressRatings.resize(5);
  56. m_progressRatingsBackground.resize(5);
  57. for (int i = 0; i < 5; ++i) {
  58. util3ds::TweenText starText;
  59. starText.setFillColor(cpp3ds::Color(66, 66, 66));
  60. starText.setCharacterSize(12);
  61. starText.setFont(AssetManager<cpp3ds::Font>::get("fonts/fontawesome.ttf"));
  62. starText.setPosition(5.f, 220.f - 16.f * i);
  63. std::string starTextString;
  64. for (int j = 0; j <= i; ++j)
  65. starTextString += "\uf005";
  66. for (int j = i; j < 4; ++j)
  67. starTextString += "\uf006";
  68. starText.setString(starTextString);
  69. m_starsText[i] = starText;
  70. util3ds::TweenRectangleShape barRatingBackground;
  71. barRatingBackground.setFillColor(cpp3ds::Color(158, 158, 158, 150));
  72. barRatingBackground.setPosition(70.f, 226.f - 16.f * i);
  73. barRatingBackground.setSize(cpp3ds::Vector2f(115.f, 5.f));
  74. m_progressRatingsBackground[i] = barRatingBackground;
  75. }
  76. m_finalScoreText.setCharacterSize(32);
  77. m_finalScoreText.setPosition(395.f, 191.f);
  78. if (Theme::isTextThemed)
  79. m_finalScoreText.setFillColor(Theme::primaryTextColor);
  80. else
  81. m_finalScoreText.setFillColor(cpp3ds::Color::Black);
  82. m_voteCountUserIcon.setCharacterSize(11);
  83. m_voteCountUserIcon.setFont(AssetManager<cpp3ds::Font>::get("fonts/fontawesome.ttf"));
  84. m_voteCountUserIcon.setString("\uf007");
  85. m_voteCountUserIcon.setOrigin(m_voteCountUserIcon.getLocalBounds().width, 0);
  86. m_voteCountUserIcon.setPosition(395.f, 131.f);
  87. if (Theme::isTextThemed)
  88. m_voteCountUserIcon.setFillColor(Theme::secondaryTextColor);
  89. else
  90. m_voteCountUserIcon.setFillColor(cpp3ds::Color(66, 66, 66));
  91. m_voteCount.setCharacterSize(12);
  92. m_voteCount.setPosition(m_voteCountUserIcon.getPosition().x - m_voteCountUserIcon.getLocalBounds().width - 5.f, m_voteCountUserIcon.getPosition().y);
  93. if (Theme::isTextThemed)
  94. m_voteCount.setFillColor(Theme::secondaryTextColor);
  95. else
  96. m_voteCount.setFillColor(cpp3ds::Color(66, 66, 66));
  97. m_textAverageScore.setCharacterSize(12);
  98. m_textAverageScore.setString(_("Average score"));
  99. m_textAverageScore.setPosition(395.f, 191.f - m_textAverageScore.getLocalBounds().height - 5.f);
  100. m_textAverageScore.setOrigin(m_textAverageScore.getLocalBounds().width, 0.f);
  101. if (Theme::isTextThemed)
  102. m_textAverageScore.setFillColor(Theme::secondaryTextColor);
  103. else
  104. m_textAverageScore.setFillColor(cpp3ds::Color(66, 66, 66));
  105. m_textPlayerType.setCharacterSize(10);
  106. m_textPlayerType.setString(_("• Who do you think this title appeals to?"));
  107. m_textPlayerType.setPosition(5.f, 40.f);
  108. if (Theme::isTextThemed)
  109. m_textPlayerType.setFillColor(Theme::secondaryTextColor);
  110. else
  111. m_textPlayerType.setFillColor(cpp3ds::Color(66, 66, 66));
  112. m_textPlayStyle = m_textPlayerType;
  113. m_textPlayStyle.setString(_("• What kind of play style is this title more suited for?"));
  114. m_textPlayStyle.setPosition(5.f, 99.f);
  115. m_barEveryone.setFillColor(cpp3ds::Color(3, 169, 244));
  116. m_barEveryone.setPosition(20.f, 84.f);
  117. m_barGamers.setFillColor(cpp3ds::Color(255, 152, 0));
  118. m_barGamers.setPosition(20.f, 84.f);
  119. m_barGamers.setSize(cpp3ds::Vector2f(280.f, 5.f));
  120. m_barCasual.setFillColor(cpp3ds::Color(3, 169, 244));
  121. m_barCasual.setPosition(20.f, 143.f);
  122. m_barIntense.setFillColor(cpp3ds::Color(255, 152, 0));
  123. m_barIntense.setPosition(20.f, 143.f);
  124. m_barIntense.setSize(cpp3ds::Vector2f(280.f, 5.f));
  125. m_textEveryone.setCharacterSize(12);
  126. m_textEveryone.setPosition(20.f, 64.f);
  127. m_textEveryone.setFillColor(cpp3ds::Color(3, 169, 244));
  128. m_textGamers.setCharacterSize(12);
  129. m_textGamers.setPosition(300.f, 64.f);
  130. m_textGamers.setFillColor(cpp3ds::Color(255, 152, 0));
  131. m_textCasual = m_textEveryone;
  132. m_textCasual.setPosition(20.f, 123.f);
  133. m_textIntense = m_textGamers;
  134. m_textIntense.setPosition(300.f, 123.f);
  135. m_topView.setCenter(cpp3ds::Vector2f(200.f, 3.f));
  136. m_topView.setSize(cpp3ds::Vector2f(400.f, 240.f));
  137. m_bottomView.setCenter(cpp3ds::Vector2f(160.f, 286.f));
  138. m_bottomView.setSize(cpp3ds::Vector2f(320.f, 240.f));
  139. }
  140. AppStats::~AppStats()
  141. {
  142. }
  143. void AppStats::draw(cpp3ds::RenderTarget &target, cpp3ds::RenderStates states) const
  144. {
  145. if (!m_isVisible)
  146. return;
  147. target.draw(m_overlay);
  148. target.setView(m_bottomView);
  149. target.draw(m_botBackground);
  150. target.draw(m_preferenceText);
  151. // Type of player and play style stuff
  152. target.draw(m_textPlayerType);
  153. target.draw(m_textPlayStyle);
  154. target.draw(m_barGamers);
  155. target.draw(m_barEveryone);
  156. target.draw(m_barIntense);
  157. target.draw(m_barCasual);
  158. target.draw(m_textEveryone);
  159. target.draw(m_textGamers);
  160. target.draw(m_textCasual);
  161. target.draw(m_textIntense);
  162. target.setView(target.getDefaultView());
  163. }
  164. void AppStats::drawTop(cpp3ds::Window &window)
  165. {
  166. if (!m_isVisible)
  167. return;
  168. window.draw(m_overlay);
  169. window.setView(m_topView);
  170. window.draw(m_topBackground);
  171. window.draw(m_statText);
  172. window.draw(m_textAverageScore);
  173. // Rating related stuff
  174. for (int i = 0; i < 5; ++i) {
  175. window.draw(m_ratings.at(i));
  176. window.draw(m_starsText.at(i));
  177. window.draw(m_progressRatingsBackground.at(i));
  178. window.draw(m_progressRatings.at(i));
  179. }
  180. window.draw(m_finalScoreText);
  181. window.draw(m_voteCount);
  182. window.draw(m_voteCountUserIcon);
  183. window.setView(window.getDefaultView());
  184. }
  185. void AppStats::update(float delta)
  186. {
  187. m_tweenManager.update(delta);
  188. }
  189. bool AppStats::processEvent(const cpp3ds::Event &event)
  190. {
  191. if (isVisible()) {
  192. if (event.type == cpp3ds::Event::KeyPressed && (event.key.code == cpp3ds::Keyboard::Select || event.key.code == cpp3ds::Keyboard::B))
  193. setVisible(false);
  194. else if (event.type == cpp3ds::Event::TouchEnded)
  195. setVisible(false);
  196. } else {
  197. if (event.type == cpp3ds::Event::KeyReleased && event.key.code == cpp3ds::Keyboard::Select)
  198. setVisible(true);
  199. }
  200. #ifdef EMULATION
  201. if (event.type == cpp3ds::Event::KeyPressed && event.key.code == cpp3ds::Keyboard::Y)
  202. setVisible(!isVisible());
  203. #endif
  204. }
  205. void AppStats::loadApp(std::shared_ptr<AppItem> appItem, const rapidjson::Value &jsonStarRating)
  206. {
  207. m_appItem = appItem;
  208. // Rating related stuff
  209. if (jsonStarRating.HasMember("votes"))
  210. m_votes = jsonStarRating["votes"].GetInt();
  211. else
  212. m_votes = 0;
  213. m_voteCount.setString(_("%i", m_votes));
  214. m_voteCount.setOrigin(std::round(m_voteCount.getLocalBounds().width / 2), 0);
  215. if (jsonStarRating.HasMember("score"))
  216. m_finalScore = jsonStarRating["score"].GetDouble();
  217. else
  218. m_finalScore = 0;
  219. m_finalScoreText.setString(_("%.2f", m_finalScore));
  220. m_finalScoreText.setOrigin(m_finalScoreText.getLocalBounds().width, 0.f);
  221. for (int i = 0; i < 5; ++i) {
  222. util3ds::TweenText ratingText;
  223. ratingText.setCharacterSize(12);
  224. ratingText.setPosition(200.f, 221.f - 16.f * i);
  225. if (Theme::isTextThemed)
  226. ratingText.setFillColor(Theme::secondaryTextColor);
  227. else
  228. ratingText.setFillColor(cpp3ds::Color(66, 66, 66));
  229. util3ds::TweenRectangleShape barRating;
  230. barRating.setFillColor(cpp3ds::Color(158, 158, 158, 225));
  231. barRating.setPosition(70.f, 226.f - 16.f * i);
  232. if (jsonStarRating.HasMember(_("star%i", i + 1).toAnsiString().c_str())) {
  233. auto actualStar = _("star%i", i + 1).toAnsiString().c_str();
  234. int actualStarCount = jsonStarRating[actualStar].GetInt();
  235. m_stars[i] = actualStarCount;
  236. ratingText.setString(_("%i", actualStarCount));
  237. barRating.setSize(cpp3ds::Vector2f(actualStarCount * 115.f / m_votes, 5.f));
  238. } else {
  239. m_stars[i] = 0;
  240. ratingText.setString(_("%i", 0));
  241. barRating.setSize(cpp3ds::Vector2f(0.f, 5.f));
  242. }
  243. m_ratings[i] = ratingText;
  244. m_progressRatings[i] = barRating;
  245. }
  246. m_voteCount.setOrigin(m_voteCount.getLocalBounds().width, 0);
  247. }
  248. void AppStats::setVisible(bool isVisible)
  249. {
  250. m_tweenManager.killAll();
  251. if (isVisible) {
  252. m_isVisible = isVisible;
  253. TweenEngine::Tween::to(m_overlay, m_overlay.FILL_COLOR_ALPHA, 0.2f)
  254. .target(200.f)
  255. .start(m_tweenManager);
  256. TweenEngine::Tween::to(m_topView, m_topView.CENTER_Y, 0.4f)
  257. .target(120.f)
  258. .delay(0.2f)
  259. .start(m_tweenManager);
  260. TweenEngine::Tween::to(m_bottomView, m_bottomView.CENTER_Y, 0.4f)
  261. .target(120.f)
  262. .delay(0.2f)
  263. .start(m_tweenManager);
  264. } else {
  265. TweenEngine::Tween::to(m_overlay, m_overlay.FILL_COLOR_ALPHA, 0.4f)
  266. .target(0.f)
  267. .setCallback(TweenEngine::TweenCallback::COMPLETE, [=](TweenEngine::BaseTween* source) {
  268. m_isVisible = isVisible;
  269. })
  270. .start(m_tweenManager);
  271. TweenEngine::Tween::to(m_topView, m_topView.CENTER_Y, 0.2f)
  272. .target(3.f)
  273. .start(m_tweenManager);
  274. TweenEngine::Tween::to(m_bottomView, m_bottomView.CENTER_Y, 0.2f)
  275. .target(286.f)
  276. .start(m_tweenManager);
  277. }
  278. }
  279. bool AppStats::isVisible()
  280. {
  281. return m_isVisible;
  282. }
  283. void AppStats::loadPreferences(const rapidjson::Value &jsonPreferences)
  284. {
  285. // Type of player and play style stuff
  286. if (jsonPreferences.HasMember("target_player")) {
  287. if (jsonPreferences["target_player"].HasMember("everyone"))
  288. m_percentageEveryone = jsonPreferences["target_player"]["everyone"].GetInt();
  289. else
  290. m_percentageEveryone = 0;
  291. if (jsonPreferences["target_player"].HasMember("gamers"))
  292. m_percentageGamers = jsonPreferences["target_player"]["gamers"].GetInt();
  293. else
  294. m_percentageGamers = 0;
  295. }
  296. if (jsonPreferences.HasMember("play_style")) {
  297. if (jsonPreferences["play_style"].HasMember("casual"))
  298. m_percentageCasual = jsonPreferences["play_style"]["casual"].GetInt();
  299. else
  300. m_percentageCasual = 0;
  301. if (jsonPreferences["play_style"].HasMember("intense"))
  302. m_percentageIntense = jsonPreferences["play_style"]["intense"].GetInt();
  303. else
  304. m_percentageIntense = 0;
  305. }
  306. m_barEveryone.setSize(cpp3ds::Vector2f(m_percentageEveryone * 280.f / 100.f, 5.f));
  307. m_barCasual.setSize(cpp3ds::Vector2f(m_percentageCasual * 280.f / 100.f, 5.f));
  308. m_textEveryone.setString(_("Everyone - %i%%", m_percentageEveryone));
  309. m_textCasual.setString(_("Casual - %i%%", m_percentageCasual));
  310. m_textGamers.setString(_("%i%% - Gamers", m_percentageGamers));
  311. m_textGamers.setOrigin(m_textGamers.getLocalBounds().width, 0);
  312. m_textIntense.setString(_("%i%% - Intense", m_percentageIntense));
  313. m_textIntense.setOrigin(m_textIntense.getLocalBounds().width, 0);
  314. }
  315. }