Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

MenuFolder.cpp 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*!
  2. * \file src/MenuFolder.cpp
  3. * \brief File-Explorer like menu
  4. *
  5. * \author xythobuz
  6. */
  7. #include "global.h"
  8. #include "Game.h"
  9. #include "loader/Loader.h"
  10. #include "Log.h"
  11. #include "Render.h"
  12. #include "RunTime.h"
  13. #include "MenuFolder.h"
  14. #include "system/Font.h"
  15. #include "system/Window.h"
  16. MenuFolder::MenuFolder() {
  17. mCursor = 0;
  18. mMin = 0;
  19. mapFolder = nullptr;
  20. hiddenState = false;
  21. dialogState = false;
  22. visible = false;
  23. }
  24. MenuFolder::~MenuFolder() {
  25. delete mapFolder;
  26. mapFolder = nullptr;
  27. }
  28. int MenuFolder::initialize() {
  29. return init(RunTime::getPakDir());
  30. }
  31. int MenuFolder::init(std::string s) {
  32. return init(new Folder(s));
  33. }
  34. int MenuFolder::init(Folder* folder, bool filter) {
  35. if (mapFolder != nullptr)
  36. delete mapFolder;
  37. mapFolder = folder;
  38. mMin = mCursor = 0;
  39. if (filter) {
  40. mapFolder->executeRemoveFiles([](File & f) {
  41. // Filter files based on file name
  42. if ((f.getName().length() > 4)
  43. && (f.getName().compare(f.getName().length() - 4, 4, ".phd") != 0)
  44. && (f.getName().compare(f.getName().length() - 4, 4, ".psx") != 0)
  45. && (f.getName().compare(f.getName().length() - 4, 4, ".tub") != 0)
  46. && (f.getName().compare(f.getName().length() - 4, 4, ".tr2") != 0)
  47. && (f.getName().compare(f.getName().length() - 4, 4, ".tr4") != 0)
  48. && (f.getName().compare(f.getName().length() - 4, 4, ".trc") != 0)) {
  49. return true; // delete file from list
  50. }
  51. // Check maps for validity
  52. Loader::LoaderVersion version = Loader::checkFile(f.getPath());
  53. if (version == Loader::TR_UNKNOWN) {
  54. Log::get(LOG_ERROR) << "Error: pak file '" << f.getName().c_str()
  55. << "' invalid" << Log::endl;
  56. return true; // delete file from list
  57. }
  58. return false; // keep file on list
  59. });
  60. }
  61. if ((mapFolder->fileCount() + mapFolder->folderCount()) > 0)
  62. mCursor = 1; // Don't select ".." by default
  63. return 0;
  64. }
  65. void MenuFolder::display() {
  66. if (!visible)
  67. return;
  68. Font::drawTextCentered(0, 10, 1.2f, textColor, Window::getSize().x, VERSION);
  69. // Draw half-transparent overlay
  70. glm::vec4 color(0.0f, 0.0f, 0.0f, 0.75f);
  71. Render::drawTexture(0.0f, 0.0f, Window::getSize().x, Window::getSize().y,
  72. color, TEXTURE_WHITE, TextureStorage::SYSTEM);
  73. // Draw heading
  74. Font::drawTextCentered(0, 10, 1.2f, textColor, Window::getSize().x, VERSION);
  75. // Estimate displayable number of items
  76. int items = (Window::getSize().y - 60) / 25;
  77. // Print list of "..", folders, files
  78. for (long i = mMin; (i < (mMin + items))
  79. && (i < (mapFolder->folderCount() + mapFolder->fileCount() + 1)); i++) {
  80. if (i == 0) {
  81. Font::drawText(25, 50, 0.75f, (mCursor == i) ? selectedColor : textColor, "..");
  82. } else {
  83. Font::drawText(25, (unsigned int)(50 + (25 * (i - mMin))), 0.75f,
  84. (mCursor == i) ? selectedColor : textColor,
  85. ((i - 1) < mapFolder->folderCount()) ?
  86. (mapFolder->getFolder(i - 1).getName() + "/")
  87. : mapFolder->getFile(i - 1 - mapFolder->folderCount()).getName());
  88. }
  89. }
  90. displayDialog();
  91. }
  92. void MenuFolder::loadOrOpen() {
  93. if (mCursor == 0) {
  94. if (init(mapFolder->getParent().getPath()) != 0) {
  95. showDialog("Error reading parent folder!", "OK", "");
  96. }
  97. } else if ((mCursor - 1) < mapFolder->folderCount()) {
  98. if (init(mapFolder->getFolder(mCursor - 1).getPath()) != 0) {
  99. showDialog("Error reading subfolder!", "OK", "");
  100. }
  101. } else {
  102. showDialog("Loading...", "OK");
  103. renderFrame();
  104. int error = Game::loadLevel(mapFolder->getFile((unsigned long)mCursor
  105. - 1 - mapFolder->folderCount()).getPath().c_str());
  106. ackDialog();
  107. if (error == 0) {
  108. visible = false;
  109. } else {
  110. std::ostringstream err;
  111. err << "Error loading map: " << error << "!";
  112. showDialog(err.str(), "OK", "");
  113. }
  114. }
  115. }
  116. void MenuFolder::handleKeyboard(KeyboardButton key, bool pressed) {
  117. if (handleKeyboardDialog(key, pressed))
  118. return;
  119. if (!pressed)
  120. return;
  121. assert(mapFolder != nullptr);
  122. int items = (Window::getSize().y - 60) / 25;
  123. if (key == upKey) {
  124. if (mCursor > 0)
  125. mCursor--;
  126. else
  127. mCursor = (long)(mapFolder->folderCount() + mapFolder->fileCount());
  128. } else if (key == downKey) {
  129. if (mCursor < (long)(mapFolder->folderCount() + mapFolder->fileCount()))
  130. mCursor++;
  131. else
  132. mCursor = 0;
  133. } else if (key == enterKey) {
  134. loadOrOpen();
  135. } else if (key == dotKey) {
  136. hiddenState = !hiddenState;
  137. init(mapFolder->getPath());
  138. }
  139. if (mCursor > (mMin + items - 1)) {
  140. mMin = mCursor - items + 1;
  141. } else if (mCursor < mMin) {
  142. mMin = mCursor;
  143. }
  144. }
  145. void MenuFolder::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button,
  146. bool released) {
  147. if (handleMouseClickDialog(x, y, button, released))
  148. return;
  149. int items = (Window::getSize().y - 60) / 25;
  150. if (released || (button != leftmouseKey))
  151. return;
  152. if ((y >= 50) && (y <= (unsigned int)(50 + (25 * items)))
  153. && ((mMin + (y / 25)) <= (mapFolder->folderCount() + mapFolder->fileCount() + 2))) {
  154. y -= 50;
  155. if (mCursor == (mMin + (y / 25)))
  156. loadOrOpen();
  157. else
  158. mCursor = mMin + (y / 25);
  159. }
  160. }
  161. void MenuFolder::handleMouseScroll(int xrel, int yrel) {
  162. if (handleMouseScrollDialog(xrel, yrel))
  163. return;
  164. assert((xrel != 0) || (yrel != 0));
  165. assert(mapFolder != nullptr);
  166. int items = (Window::getSize().y - 60) / 25;
  167. if ((mapFolder->folderCount() + mapFolder->fileCount() + 1) > items) {
  168. if (yrel < 0) {
  169. if (mMin < (mapFolder->folderCount() + mapFolder->fileCount() + 1 - items))
  170. mMin++;
  171. } else if (yrel > 0) {
  172. if (mMin > 0)
  173. mMin--;
  174. }
  175. if (mCursor < mMin) {
  176. mCursor = mMin;
  177. } else if (mCursor > (mMin + items - 1)) {
  178. mCursor = mMin + items - 1;
  179. }
  180. }
  181. }