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.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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, ".tr2") != 0)
  45. && (f.getName().compare(f.getName().length() - 4, 4, ".tr4") != 0)
  46. && (f.getName().compare(f.getName().length() - 4, 4, ".trc") != 0)) {
  47. return true; // delete file from list
  48. }
  49. // Check maps for validity
  50. Loader::LoaderVersion version = Loader::checkFile(f.getPath());
  51. if (version == Loader::TR_UNKNOWN) {
  52. Log::get(LOG_ERROR) << "Error: pak file '" << f.getName().c_str()
  53. << "' invalid" << Log::endl;
  54. return true; // delete file from list
  55. }
  56. return false; // keep file on list
  57. });
  58. }
  59. if ((mapFolder->fileCount() + mapFolder->folderCount()) > 0)
  60. mCursor = 1; // Don't select ".." by default
  61. return 0;
  62. }
  63. void MenuFolder::display() {
  64. if (!visible)
  65. return;
  66. Font::drawTextCentered(0, 10, 1.2f, BLUE, Window::getSize().x, VERSION);
  67. // Draw half-transparent overlay
  68. glm::vec4 color(0.0f, 0.0f, 0.0f, 0.75f);
  69. Render::drawTexture(0.0f, 0.0f, Window::getSize().x, Window::getSize().y,
  70. color, TEXTURE_WHITE, TextureStorage::SYSTEM);
  71. // Draw heading
  72. Font::drawTextCentered(0, 10, 1.2f, BLUE, Window::getSize().x, VERSION);
  73. // Estimate displayable number of items
  74. int items = (Window::getSize().y - 60) / 25;
  75. // Print list of "..", folders, files
  76. for (long i = mMin; (i < (mMin + items))
  77. && (i < (mapFolder->folderCount() + mapFolder->fileCount() + 1)); i++) {
  78. if (i == 0) {
  79. Font::drawText(25, 50, 0.75f, (mCursor == i) ? RED : BLUE, "..");
  80. } else {
  81. Font::drawText(25, (unsigned int)(50 + (25 * (i - mMin))), 0.75f,
  82. (mCursor == i) ? RED : BLUE,
  83. ((i - 1) < mapFolder->folderCount()) ?
  84. (mapFolder->getFolder(i - 1).getName() + "/")
  85. : mapFolder->getFile(i - 1 - mapFolder->folderCount()).getName());
  86. }
  87. }
  88. displayDialog();
  89. }
  90. void MenuFolder::loadOrOpen() {
  91. if (mCursor == 0) {
  92. if (init(mapFolder->getParent().getPath()) != 0) {
  93. showDialog("Error reading parent folder!", "OK", "");
  94. }
  95. } else if ((mCursor - 1) < mapFolder->folderCount()) {
  96. if (init(mapFolder->getFolder(mCursor - 1).getPath()) != 0) {
  97. showDialog("Error reading subfolder!", "OK", "");
  98. }
  99. } else {
  100. int error = Game::loadLevel(mapFolder->getFile((unsigned long)mCursor
  101. - 1 - mapFolder->folderCount()).getPath().c_str());
  102. if (error == 0) {
  103. visible = false;
  104. } else {
  105. std::ostringstream err;
  106. err << "Error loading map: " << error << "!";
  107. showDialog(err.str(), "OK", "");
  108. }
  109. }
  110. }
  111. void MenuFolder::handleKeyboard(KeyboardButton key, bool pressed) {
  112. if (handleKeyboardDialog(key, pressed))
  113. return;
  114. if (!pressed)
  115. return;
  116. assert(mapFolder != nullptr);
  117. int items = (Window::getSize().y - 60) / 25;
  118. if (key == upKey) {
  119. if (mCursor > 0)
  120. mCursor--;
  121. else
  122. mCursor = (long)(mapFolder->folderCount() + mapFolder->fileCount());
  123. } else if (key == downKey) {
  124. if (mCursor < (long)(mapFolder->folderCount() + mapFolder->fileCount()))
  125. mCursor++;
  126. else
  127. mCursor = 0;
  128. } else if (key == enterKey) {
  129. loadOrOpen();
  130. } else if (key == dotKey) {
  131. hiddenState = !hiddenState;
  132. init(mapFolder->getPath());
  133. }
  134. if (mCursor > (mMin + items - 1)) {
  135. mMin = mCursor - items + 1;
  136. } else if (mCursor < mMin) {
  137. mMin = mCursor;
  138. }
  139. }
  140. void MenuFolder::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button,
  141. bool released) {
  142. if (handleMouseClickDialog(x, y, button, released))
  143. return;
  144. int items = (Window::getSize().y - 60) / 25;
  145. if (released || (button != leftmouseKey))
  146. return;
  147. if ((y >= 50) && (y <= (unsigned int)(50 + (25 * items)))
  148. && ((mMin + (y / 25)) <= (mapFolder->folderCount() + mapFolder->fileCount() + 2))) {
  149. y -= 50;
  150. if (mCursor == (mMin + (y / 25)))
  151. loadOrOpen();
  152. else
  153. mCursor = mMin + (y / 25);
  154. }
  155. }
  156. void MenuFolder::handleMouseScroll(int xrel, int yrel) {
  157. if (handleMouseScrollDialog(xrel, yrel))
  158. return;
  159. assert((xrel != 0) || (yrel != 0));
  160. assert(mapFolder != nullptr);
  161. int items = (Window::getSize().y - 60) / 25;
  162. if ((mapFolder->folderCount() + mapFolder->fileCount() + 1) > items) {
  163. if (yrel < 0) {
  164. if (mMin < (mapFolder->folderCount() + mapFolder->fileCount() + 1 - items))
  165. mMin++;
  166. } else if (yrel > 0) {
  167. if (mMin > 0)
  168. mMin--;
  169. }
  170. if (mCursor < mMin) {
  171. mCursor = mMin;
  172. } else if (mCursor > (mMin + items - 1)) {
  173. mCursor = mMin + items - 1;
  174. }
  175. }
  176. }