InstalledOptions.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #include "InstalledOptions.hpp"
  2. #include "InstalledItem.hpp"
  3. #include "AssetManager.hpp"
  4. #include "DownloadQueue.hpp"
  5. #include "Notification.hpp"
  6. #include "InstalledList.hpp"
  7. #include "States/StateIdentifiers.hpp"
  8. #include "States/DialogState.hpp"
  9. #include <cpp3ds/System/I18n.hpp>
  10. namespace FreeShop {
  11. InstalledOptions::InstalledOptions()
  12. : m_installedItem(nullptr)
  13. {
  14. m_textGame.setString(_("Game"));
  15. m_textGame.setFillColor(cpp3ds::Color(100, 100, 100));
  16. m_textGame.setCharacterSize(10);
  17. m_textGame.setPosition(20.f, 0.f);
  18. m_textGame.useSystemFont();
  19. m_textUpdates = m_textGame;
  20. m_textUpdates.setString(_("Updates"));
  21. m_textUpdates.move(m_textGame.getLocalBounds().width + 40.f, 0.f);
  22. m_textDLC = m_textUpdates;
  23. m_textDLC.setString(_("DLC"));
  24. m_textDLC.move(m_textUpdates.getLocalBounds().width + 40.f, 0.f);
  25. m_textIconGame.setFont(AssetManager<cpp3ds::Font>::get("fonts/fontawesome.ttf"));
  26. m_textIconGame.setString(L"\uf1f8");
  27. m_textIconGame.setFillColor(cpp3ds::Color(50, 100, 50));
  28. m_textIconGame.setCharacterSize(18);
  29. m_textIconGame.setPosition(m_textGame.getPosition().x + m_textGame.getLocalBounds().width + 5.f, -5.f);
  30. m_textIconUpdates = m_textIconGame;
  31. m_textIconUpdates.setPosition(m_textUpdates.getPosition().x + m_textUpdates.getLocalBounds().width + 5.f, -5.f);
  32. m_textIconDLC = m_textIconGame;
  33. m_textIconDLC.setPosition(m_textDLC.getPosition().x + m_textDLC.getLocalBounds().width + 5.f, -5.f);
  34. }
  35. void InstalledOptions::draw(cpp3ds::RenderTarget &target, cpp3ds::RenderStates states) const
  36. {
  37. states.transform *= getTransform();
  38. target.draw(m_textGame, states);
  39. target.draw(m_textIconGame, states);
  40. if (m_updatesAvailable)
  41. {
  42. target.draw(m_textUpdates, states);
  43. target.draw(m_textIconUpdates, states);
  44. }
  45. if (m_dlcAvailable)
  46. {
  47. target.draw(m_textDLC, states);
  48. target.draw(m_textIconDLC, states);
  49. }
  50. }
  51. #define SET_ALPHA(obj, alpha) \
  52. color = obj.getFillColor(); \
  53. color.a = alpha; \
  54. obj.setFillColor(color);
  55. void InstalledOptions::setValues(int tweenType, float *newValues)
  56. {
  57. switch (tweenType) {
  58. case ALPHA: {
  59. cpp3ds::Color color;
  60. auto alpha = static_cast<cpp3ds::Uint8>(newValues[0]);
  61. SET_ALPHA(m_textGame, alpha);
  62. SET_ALPHA(m_textUpdates, alpha);
  63. SET_ALPHA(m_textDLC, alpha);
  64. SET_ALPHA(m_textIconGame, alpha);
  65. SET_ALPHA(m_textIconUpdates, alpha);
  66. SET_ALPHA(m_textIconDLC, alpha);
  67. break;
  68. }
  69. default:
  70. TweenTransformable::setValues(tweenType, newValues);
  71. }
  72. }
  73. int InstalledOptions::getValues(int tweenType, float *returnValues)
  74. {
  75. switch (tweenType) {
  76. case ALPHA:
  77. returnValues[0] = m_textGame.getFillColor().a;
  78. return 1;
  79. default:
  80. return TweenTransformable::getValues(tweenType, returnValues);
  81. }
  82. }
  83. void InstalledOptions::processTouchEvent(const cpp3ds::Event &event)
  84. {
  85. cpp3ds::String appTitle = m_installedItem->getAppItem()->getTitle();
  86. cpp3ds::Vector2f touchPos(event.touch.x - getPosition().x, event.touch.y - getPosition().y);
  87. if (m_textIconGame.getGlobalBounds().contains(touchPos))
  88. {
  89. cpp3ds::Uint64 titleId = m_installedItem->getTitleId();
  90. g_browseState->requestStackPush(States::Dialog, false, [=](void *data) mutable {
  91. auto event = reinterpret_cast<DialogState::Event*>(data);
  92. if (event->type == DialogState::GetText)
  93. {
  94. auto str = reinterpret_cast<cpp3ds::String*>(event->data);
  95. *str = _("You are deleting this game,\nincluding all save data:\n\n%s", appTitle.toAnsiString().c_str());
  96. return true;
  97. }
  98. else if (event->type == DialogState::Response)
  99. {
  100. bool *accepted = reinterpret_cast<bool*>(event->data);
  101. if (*accepted)
  102. {
  103. #ifdef _3DS
  104. FS_MediaType mediaType = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD;
  105. AM_DeleteTitle(m_mediaType, titleId);
  106. #endif
  107. m_installedItem->getAppItem()->setInstalled(false);
  108. Notification::spawn(_("Deleted: %s", appTitle.toAnsiString().c_str()));
  109. InstalledList::getInstance().refresh();
  110. }
  111. return true;
  112. }
  113. return false;
  114. });
  115. }
  116. else if (m_textIconUpdates.getGlobalBounds().contains(touchPos))
  117. {
  118. if (m_updatesInstalled)
  119. {
  120. g_browseState->requestStackPush(States::Dialog, false, [=](void *data) mutable {
  121. auto event = reinterpret_cast<DialogState::Event*>(data);
  122. if (event->type == DialogState::GetText)
  123. {
  124. auto str = reinterpret_cast<cpp3ds::String*>(event->data);
  125. *str = _("You are deleting updates for\nthis title:\n\n%s", appTitle.toAnsiString().c_str());
  126. return true;
  127. }
  128. else if (event->type == DialogState::Response)
  129. {
  130. bool *accepted = reinterpret_cast<bool*>(event->data);
  131. if (*accepted)
  132. {
  133. for (auto &id : m_installedItem->getAppItem()->getUpdates()) {
  134. #ifdef _3DS
  135. AM_DeleteTitle(m_mediaType, id);
  136. #endif
  137. m_installedItem->setUpdateStatus(id, false);
  138. }
  139. m_updatesInstalled = false;
  140. Notification::spawn(_("Deleted update: %s", appTitle.toAnsiString().c_str()));
  141. update();
  142. }
  143. return true;
  144. }
  145. return false;
  146. });
  147. }
  148. else
  149. {
  150. for (auto &id : m_installedItem->getAppItem()->getUpdates())
  151. if (!m_installedItem->getUpdateStatus(id))
  152. DownloadQueue::getInstance().addDownload(m_installedItem->getAppItem(), id, [=](bool succeeded){
  153. if (!succeeded) {
  154. m_updatesAvailable = true;
  155. update();
  156. }
  157. });
  158. m_updatesAvailable = false;
  159. Notification::spawn(_("Queued update: %s", appTitle.toAnsiString().c_str()));
  160. update();
  161. }
  162. }
  163. else if (m_textIconDLC.getGlobalBounds().contains(touchPos))
  164. {
  165. if (m_dlcInstalled)
  166. {
  167. g_browseState->requestStackPush(States::Dialog, false, [=](void *data) mutable {
  168. auto event = reinterpret_cast<DialogState::Event*>(data);
  169. if (event->type == DialogState::GetText)
  170. {
  171. auto str = reinterpret_cast<cpp3ds::String*>(event->data);
  172. *str = _("You are deleting DLC for\nthis title:\n\n%s", appTitle.toAnsiString().c_str());
  173. return true;
  174. }
  175. else if (event->type == DialogState::Response)
  176. {
  177. bool *accepted = reinterpret_cast<bool*>(event->data);
  178. if (*accepted)
  179. {
  180. for (auto &id : m_installedItem->getAppItem()->getDLC()) {
  181. #ifdef _3DS
  182. AM_DeleteTitle(m_mediaType, id);
  183. #endif
  184. m_installedItem->setDLCStatus(id, false);
  185. }
  186. m_dlcInstalled = false;
  187. Notification::spawn(_("Deleted DLC: %s", appTitle.toAnsiString().c_str()));
  188. update();
  189. }
  190. return true;
  191. }
  192. return false;
  193. });
  194. }
  195. else
  196. {
  197. for (auto &id : m_installedItem->getAppItem()->getDLC())
  198. if (!m_installedItem->getDLCStatus(id))
  199. DownloadQueue::getInstance().addDownload(m_installedItem->getAppItem(), id, [=](bool succeeded){
  200. if (!succeeded) {
  201. m_dlcAvailable = true;
  202. update();
  203. }
  204. });
  205. m_dlcAvailable = false;
  206. Notification::spawn(_("Queued DLC: %s", appTitle.toAnsiString().c_str()));
  207. update();
  208. }
  209. }
  210. }
  211. void InstalledOptions::setInstalledItem(InstalledItem *installedItem)
  212. {
  213. m_installedItem = installedItem;
  214. m_updatesAvailable = installedItem->getUpdates().size() > 0;
  215. m_dlcAvailable = installedItem->getDLC().size() > 0;
  216. for (auto &id : m_installedItem->getAppItem()->getUpdates())
  217. if (DownloadQueue::getInstance().isDownloading(id))
  218. m_updatesAvailable = false;
  219. for (auto &id : m_installedItem->getAppItem()->getDLC())
  220. if (DownloadQueue::getInstance().isDownloading(id))
  221. m_dlcAvailable = false;
  222. update();
  223. #ifdef _3DS
  224. m_mediaType = ((installedItem->getTitleId() >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD;
  225. #endif
  226. }
  227. InstalledItem *InstalledOptions::getInstalledItem() const
  228. {
  229. return m_installedItem;
  230. }
  231. void InstalledOptions::update()
  232. {
  233. m_updatesInstalled = true;
  234. for (auto &update : m_installedItem->getUpdates())
  235. if (!update.second)
  236. {
  237. m_updatesInstalled = false;
  238. break;
  239. }
  240. m_dlcInstalled = true;
  241. for (auto &dlc : m_installedItem->getDLC())
  242. if (!dlc.second)
  243. {
  244. m_dlcInstalled = false;
  245. break;
  246. }
  247. m_textIconUpdates.setString(m_updatesInstalled ? L"\uf1f8" : L"\uf019");
  248. m_textIconDLC.setString(m_dlcInstalled ? L"\uf1f8" : L"\uf019");
  249. }
  250. } // namespace FreeShop