text_array_object.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // SuperTux
  2. // Copyright (C) 2018 Nir <goproducti@gmail.com>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include "object/text_array_object.hpp"
  17. #include "control/input_manager.hpp"
  18. TextArrayObject::TextArrayObject(const std::string& name) :
  19. ExposedObject<TextArrayObject, scripting::TextArrayObject>(this),
  20. m_isDone(false),
  21. m_isAuto(false),
  22. m_keepVisible(false),
  23. m_fadeTransition(true),
  24. m_fadetime(1.0),
  25. m_texts(),
  26. m_curTextIndex(0),
  27. m_lastTextIndex(0),
  28. m_waiting()
  29. {
  30. m_name = name;
  31. }
  32. void
  33. TextArrayObject::clear()
  34. {
  35. m_texts.clear();
  36. reset_automation();
  37. }
  38. void
  39. TextArrayObject::add_text(const std::string& text, float duration)
  40. {
  41. auto pText = std::make_unique<TextArrayItem>();
  42. assert(pText);
  43. pText->duration = duration;
  44. pText->text_object.set_text(text);
  45. m_texts.push_back(std::move(pText));
  46. }
  47. void TextArrayObject::set_text_index(ta_index index)
  48. {
  49. if (index < m_texts.size())
  50. m_curTextIndex = index;
  51. }
  52. void
  53. TextArrayObject::set_fade_time(float fadetime)
  54. {
  55. m_fadetime = fadetime;
  56. }
  57. void
  58. TextArrayObject::next_text()
  59. {
  60. if (m_isDone)
  61. return;
  62. if (m_curTextIndex + 1 >= m_texts.size()) {
  63. m_isDone = true;
  64. return;
  65. }
  66. m_lastTextIndex = m_curTextIndex++;
  67. override_properties();
  68. reset_automation();
  69. }
  70. void
  71. TextArrayObject::prev_text()
  72. {
  73. if (m_isDone)
  74. return;
  75. if (m_curTextIndex == 0)
  76. return;
  77. m_lastTextIndex = m_curTextIndex--;
  78. override_properties();
  79. reset_automation();
  80. }
  81. void
  82. TextArrayObject::set_keep_visible(bool keep_visible)
  83. {
  84. m_keepVisible = keep_visible;
  85. }
  86. void
  87. TextArrayObject::set_fade_transition(bool fade_transition)
  88. {
  89. m_fadeTransition = fade_transition;
  90. }
  91. TextArrayItem*
  92. TextArrayObject::get_text_item(ta_index index) const
  93. {
  94. auto vecSize = m_texts.size();
  95. if (vecSize == 0 || index >= vecSize)
  96. return nullptr;
  97. return m_texts.at(index).get();
  98. }
  99. TextArrayItem*
  100. TextArrayObject::get_current_text_item() const
  101. {
  102. return get_text_item(m_curTextIndex);
  103. }
  104. TextArrayItem*
  105. TextArrayObject::get_last_text_item() const
  106. {
  107. return get_text_item(m_lastTextIndex);
  108. }
  109. void
  110. TextArrayObject::set_done(bool done)
  111. {
  112. m_isDone = done;
  113. }
  114. void
  115. TextArrayObject::set_auto(bool is_auto)
  116. {
  117. m_isAuto = is_auto;
  118. reset_automation();
  119. }
  120. void
  121. TextArrayObject::update(float dt_sec)
  122. {
  123. if (m_isDone)
  124. return;
  125. // make sure there's anything to update
  126. if (m_texts.size() == 0)
  127. return;
  128. // detect change request
  129. handle_input_requests();
  130. // check if if should update auto narration
  131. if (m_isAuto && m_waiting.check()) {
  132. next_text();
  133. }
  134. // update current
  135. auto* curTextItem = get_current_text_item();
  136. if (curTextItem)
  137. curTextItem->text_object.update(dt_sec);
  138. // update last (if transition is enabled)
  139. if (should_fade()) {
  140. auto* lastTextItem = get_last_text_item();
  141. if (lastTextItem)
  142. lastTextItem->text_object.update(dt_sec);
  143. }
  144. }
  145. void
  146. TextArrayObject::draw(DrawingContext& context)
  147. {
  148. if (m_isDone)
  149. return;
  150. auto* curTextItem = get_current_text_item();
  151. if (!curTextItem)
  152. return;
  153. // draw last if transition enabled
  154. if (should_fade()) {
  155. auto* lastTextItem = get_last_text_item();
  156. if (lastTextItem)
  157. lastTextItem->text_object.draw(context);
  158. }
  159. // draw current
  160. curTextItem->text_object.draw(context);
  161. }
  162. void
  163. TextArrayObject::override_properties()
  164. {
  165. if (!(should_fade() || m_keepVisible))
  166. return;
  167. auto* curTextItem = get_current_text_item();
  168. if (!curTextItem)
  169. return;
  170. // apply overrides
  171. if (should_fade()) { // make fade transition
  172. auto* lastTextItem = get_last_text_item();
  173. if (lastTextItem) {
  174. lastTextItem->text_object.fade_out(m_fadetime);
  175. curTextItem->text_object.fade_in(m_fadetime);
  176. }
  177. } else if (m_keepVisible) { // keep visible
  178. curTextItem->text_object.set_visible(true);
  179. }
  180. }
  181. void
  182. TextArrayObject::reset_automation()
  183. {
  184. m_waiting.stop();
  185. if (m_isAuto) {
  186. auto* text = get_current_text_item();
  187. if (text)
  188. m_waiting.start(text->duration);
  189. }
  190. }
  191. void
  192. TextArrayObject::handle_input_requests()
  193. {
  194. const Controller& controller = InputManager::current()->get_controller();
  195. if (controller.pressed(Control::MENU_SELECT)) {
  196. m_isAuto = false;
  197. next_text();
  198. } else if (controller.pressed(Control::REMOVE)) {
  199. m_isAuto = false;
  200. prev_text();
  201. }
  202. }
  203. bool
  204. TextArrayObject::should_fade() const
  205. {
  206. return m_fadeTransition && (m_curTextIndex != m_lastTextIndex);
  207. }
  208. /* EOF */