Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UI.cpp 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*!
  2. * \file src/UI.cpp
  3. * \brief UI interface manager
  4. *
  5. * \author xythobuz
  6. */
  7. #include <algorithm>
  8. #include "global.h"
  9. #include "Console.h"
  10. #include "Debug.h"
  11. #include "Menu.h"
  12. #include "RunTime.h"
  13. #include "TextureManager.h"
  14. #include "Window.h"
  15. std::vector<UI*> UI::windows;
  16. UI::~UI() {
  17. }
  18. int UI::initialize() { return 0; }
  19. void UI::eventsFinished() { }
  20. void UI::display() { }
  21. void UI::calculate() { }
  22. void UI::shutdown() { }
  23. void UI::handleKeyboard(KeyboardButton key, bool pressed) { }
  24. void UI::handleText(char *text, bool notFinished) { }
  25. void UI::handleAction(ActionEvents action, bool isFinished) { }
  26. void UI::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) { }
  27. void UI::handleMouseMotion(int xrel, int yrel, int xabs, int yabs) { }
  28. void UI::handleMouseScroll(int xrel, int yrel) { }
  29. int UI::passInitialize() {
  30. for (auto &x : windows) {
  31. int error = x->initialize();
  32. if (error != 0)
  33. return error;
  34. }
  35. return 0;
  36. }
  37. void UI::passEvents() {
  38. for (auto &x : windows) {
  39. x->eventsFinished();
  40. }
  41. }
  42. void UI::passDisplay() {
  43. std::sort(windows.begin(), windows.end(), compareUIs);
  44. for (auto &x : windows) {
  45. if (x->zPos >= 0) {
  46. x->display();
  47. }
  48. }
  49. }
  50. void UI::passCalculate() {
  51. for (auto &x : windows) {
  52. x->calculate();
  53. }
  54. }
  55. void UI::passShutdown() {
  56. for (auto &x : windows) {
  57. x->shutdown();
  58. }
  59. }
  60. void UI::passKeyboard(KeyboardButton key, bool pressed) {
  61. if (pressed) {
  62. if (getRunTime().getKeyBinding(menuAction) == key) {
  63. if (getMenu().isOnTop()) {
  64. getMenu().makeInvisible();
  65. } else {
  66. getMenu().moveToTop();
  67. }
  68. } else if (getRunTime().getKeyBinding(consoleAction) == key) {
  69. if (getConsole().isOnTop()) {
  70. getConsole().makeInvisible();
  71. } else {
  72. getConsole().moveToTop();
  73. }
  74. } else if (getRunTime().getKeyBinding(debugAction) == key) {
  75. if (!getDebug().isOnTop()) {
  76. getDebug().moveToTop();
  77. }
  78. }
  79. }
  80. auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
  81. (*maxIterator)->handleKeyboard(key, pressed);
  82. for (int i = forwardAction; i < ActionEventCount; i++) {
  83. if (getRunTime().getKeyBinding((ActionEvents)i) == key) {
  84. (*maxIterator)->handleAction((ActionEvents)i, !pressed);
  85. }
  86. }
  87. bool mousegrab = (*maxIterator)->zPos == 0;
  88. if (mousegrab != getWindow().getMousegrab())
  89. getWindow().setMousegrab(mousegrab);
  90. }
  91. void UI::passText(char *text, bool notFinished) {
  92. auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
  93. (*maxIterator)->handleText(text, notFinished);
  94. }
  95. void UI::passMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
  96. auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
  97. (*maxIterator)->handleMouseClick(x, y, button, released);
  98. for (int i = forwardAction; i < ActionEventCount; i++) {
  99. if (getRunTime().getKeyBinding((ActionEvents)i) == button) {
  100. (*maxIterator)->handleAction((ActionEvents)i, released);
  101. }
  102. }
  103. }
  104. void UI::passMouseMotion(int xrel, int yrel, int xabs, int yabs) {
  105. auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
  106. (*maxIterator)->handleMouseMotion(xrel, yrel, xabs, yabs);
  107. }
  108. void UI::passMouseScroll(int xrel, int yrel) {
  109. auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
  110. (*maxIterator)->handleMouseScroll(xrel, yrel);
  111. }
  112. void UI::addWindow(UI* window) {
  113. windows.push_back(window);
  114. }
  115. void UI::removeWindow(UI *window) {
  116. if (windows.size() == 0) {
  117. // It seems as if our list was destroyed before the UIs
  118. return;
  119. }
  120. findInList(window, [](unsigned long i){
  121. windows.erase(windows.begin() + i);
  122. });
  123. }
  124. bool UI::compareUIs(UI* a, UI* b) {
  125. return a->zPos < b->zPos;
  126. }
  127. bool UI::isOnTop(unsigned long windowID) {
  128. assert(windowID < windows.size());
  129. auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
  130. unsigned long maxPos = (unsigned long)(maxIterator - windows.begin());
  131. return (maxPos == windowID);
  132. }
  133. void UI::moveToTop(unsigned long windowID) {
  134. assert(windowID < windows.size());
  135. auto maxIterator = std::max_element(windows.begin(), windows.end(), compareUIs);
  136. long max = (*maxIterator)->zPos;
  137. unsigned long maxPos = (unsigned long)(maxIterator - windows.begin());
  138. if (maxPos != windowID) {
  139. windows.at(windowID)->zPos = max + 1;
  140. }
  141. }
  142. void UI::makeInvisible(unsigned long windowID) {
  143. assert(windowID < windows.size());
  144. windows.at(windowID)->zPos = -1;
  145. }
  146. void UI::findInList(UI *w, std::function<void (unsigned long i)> func) {
  147. for (unsigned long i = 0; i < windows.size(); i++) {
  148. auto UIptr = &(*windows.at(i));
  149. if (w == UIptr) {
  150. func(i);
  151. return;
  152. }
  153. }
  154. assert(false); // called UI was not registered
  155. }
  156. bool UI::isOnTop() {
  157. bool top = false;
  158. findInList(this, [&](unsigned long i) {
  159. top = UI::isOnTop(i);
  160. });
  161. return top;
  162. }
  163. void UI::moveToTop() {
  164. findInList(this, [](unsigned long i) {
  165. UI::moveToTop(i);
  166. });
  167. }
  168. void UI::makeInvisible() {
  169. findInList(this, [](unsigned long i) {
  170. UI::makeInvisible(i);
  171. });
  172. }