Notification.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <TweenEngine/Tween.h>
  2. #include <cmath>
  3. #include "Notification.hpp"
  4. #include "Theme.hpp"
  5. #ifndef EMULATION
  6. #include <3ds.h>
  7. #endif
  8. namespace FreeShop {
  9. // Static members
  10. cpp3ds::Texture Notification::m_texture;
  11. float Notification::m_spawnPositionY = 240.f;
  12. std::vector<std::unique_ptr<Notification>> Notification::notifications;
  13. Notification::Notification()
  14. : m_markForDelete(false)
  15. {
  16. if (m_texture.getSize().x == 0) {
  17. if (Theme::isNotification9Themed)
  18. m_texture.loadFromFile(FREESHOP_DIR "/theme/images/notification.9.png");
  19. else
  20. m_texture.loadFromFile("images/notification.9.png");
  21. }
  22. setTexture(&m_texture);
  23. getText().setCharacterSize(12);
  24. }
  25. Notification::~Notification()
  26. {
  27. m_tweenManager.killAll();
  28. }
  29. void Notification::update(float delta)
  30. {
  31. for (auto i = notifications.begin(); i != notifications.end();) {
  32. if ((*i)->m_markForDelete) {
  33. float offsetY = (*i)->getSize().y + NOTIFICATION_SPACING;
  34. m_spawnPositionY += offsetY;
  35. for (auto j = i+1; j != notifications.end(); j++) {
  36. auto notification = j->get();
  37. notification->m_destinationY += offsetY;
  38. TweenEngine::Tween::to(*notification, POSITION_Y, 0.3f)
  39. .target(notification->m_destinationY)
  40. .start(notification->m_tweenManager);
  41. }
  42. notifications.erase(i);
  43. } else {
  44. ++i;
  45. }
  46. }
  47. for (auto& notification : notifications)
  48. notification->m_tweenManager.update(delta);
  49. }
  50. void Notification::spawn(cpp3ds::String message)
  51. {
  52. std::unique_ptr<Notification> notification(new Notification());
  53. notification->setString(message);
  54. notification->setPosition(std::round(200.f - notification->getSize().x / 2.f),
  55. std::round(m_spawnPositionY - notification->getSize().y - 4.f));
  56. m_spawnPositionY -= NOTIFICATION_SPACING + notification->getSize().y;
  57. notification->animate();
  58. notifications.emplace_back(std::move(notification));
  59. }
  60. void Notification::animate()
  61. {
  62. setColor(cpp3ds::Color(255, 255, 255, 0));
  63. setTextColor(cpp3ds::Color(60, 60, 60, 0));
  64. m_destinationY = getPosition().y;
  65. move(0, -10.f);
  66. TweenEngine::Tween::to(*this, POSITION_Y, 0.5f).target(m_destinationY).start(m_tweenManager);
  67. TweenEngine::Tween::to(*this, COLOR_ALPHA, 0.5f).target(225.f).start(m_tweenManager);
  68. TweenEngine::Tween::to(*this, TEXTCOLOR_ALPHA, 0.5f).target(255.f).start(m_tweenManager);
  69. // Fade out and mark notification for deletion in update()
  70. TweenEngine::Tween::to(*this, COLOR_ALPHA, 0.5f).target(0.f).delay(NOTIFICATION_DURATION).start(m_tweenManager);
  71. TweenEngine::Tween::to(*this, TEXTCOLOR_ALPHA, 0.5f)
  72. .target(0.f)
  73. .setCallback(TweenEngine::TweenCallback::COMPLETE, [this](TweenEngine::BaseTween* source) {
  74. m_markForDelete = true;
  75. })
  76. .delay(NOTIFICATION_DURATION).start(m_tweenManager);
  77. }
  78. void Notification::sendNews(cpp3ds::String title, cpp3ds::String message)
  79. {
  80. #ifndef EMULATION
  81. // Check if the title is too long
  82. if (title.getSize() >= 32) {
  83. title = title.substring(0, 28);
  84. title.insert(title.getSize(), "...");
  85. }
  86. // Calculate word-wrapping
  87. int startPos = 0;
  88. int lastSpace = 0;
  89. auto s = message.toUtf16();
  90. cpp3ds::Text tmpText;
  91. tmpText.useSystemFont();
  92. tmpText.setCharacterSize(14);
  93. for (int i = 0; i < s.size(); ++i)
  94. {
  95. if (s[i] == ' ')
  96. lastSpace = i;
  97. tmpText.setString(cpp3ds::String::fromUtf16(s.begin() + startPos, s.begin() + i));
  98. if (tmpText.getLocalBounds().width > 254)
  99. {
  100. if (lastSpace != 0)
  101. {
  102. s[lastSpace] = '\n';
  103. i = startPos = lastSpace + 1;
  104. lastSpace = 0;
  105. }
  106. else
  107. {
  108. s.insert(s.begin() + i, '\n');
  109. startPos = ++i;
  110. }
  111. }
  112. }
  113. message = cpp3ds::String::fromUtf16(s.begin(), s.end());
  114. auto utfTitle = title.toUtf16();
  115. auto utfMessage = message.toUtf16();
  116. NEWS_AddNotification(utfTitle.c_str(), title.getSize(), utfMessage.c_str(), message.getSize(), NULL, 0, false);
  117. #endif
  118. }
  119. } // namespace FreeShop