PolyUIFileDialog.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. #include "PolyUIFileDialog.h"
  2. #include "PolyConfig.h"
  3. #include "PolyRenderer.h"
  4. using namespace Polycode;
  5. UIFileDialogEntry::UIFileDialogEntry(OSFileEntry entry, bool canSelect, int width, bool isPlace) : UIElement() {
  6. this->canSelect = canSelect;
  7. ownsChildren = true;
  8. Config *conf = CoreServices::getInstance()->getConfig();
  9. String fileIconName = conf->getStringValue("Polycode", "uiFileBrowserFileIcon");
  10. String folderIconName = conf->getStringValue("Polycode", "uiFileBrowserFolderIcon");
  11. String placeIconName = conf->getStringValue("Polycode", "uiFileBrowserPlaceIcon");
  12. bg = new UIRect(width, 18);
  13. bg->setAnchorPoint(-1.0, -1.0, 0.0);
  14. addChild(bg);
  15. bg->setColor(0.5, 0.5, 0.5, 1.0);
  16. bg->processInputEvents = true;
  17. bg->visible = false;
  18. this->fileEntry = entry;
  19. if(isPlace) {
  20. icon = new UIImage(placeIconName);
  21. } else {
  22. if(entry.type == OSFileEntry::TYPE_FILE) {
  23. icon = new UIImage(fileIconName);
  24. } else {
  25. icon = new UIImage(folderIconName);
  26. }
  27. }
  28. icon->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
  29. addChild(icon);
  30. icon->setPosition(3,1);
  31. label = new UILabel(entry.name, 12, "sans");
  32. addChild(label);
  33. label->setPosition(25, 2);
  34. if(!canSelect) {
  35. label->color.a = 0.3;
  36. }
  37. }
  38. void UIFileDialogEntry::Select() {
  39. bg->visible = true;
  40. }
  41. void UIFileDialogEntry::Deselect() {
  42. bg->visible = false;
  43. }
  44. UIFileDialogEntry::~UIFileDialogEntry() {
  45. }
  46. UIFileDialog::UIFileDialog(String baseDir, bool foldersOnly, std::vector<String> extensions, bool allowMultiple) : UIWindow("", 500, 400) {
  47. this->foldersOnly = foldersOnly;
  48. this->allowMultiple = allowMultiple;
  49. this->extensions = extensions;
  50. closeOnEscape = true;
  51. if(foldersOnly) {
  52. setWindowCaption("Select a folder");
  53. } else {
  54. if(allowMultiple) {
  55. setWindowCaption("Select files");
  56. } else {
  57. setWindowCaption("Select a file");
  58. }
  59. }
  60. cancelButton = new UIButton("Cancel", 100);
  61. addChild(cancelButton);
  62. cancelButton->setPosition(500-210, 400 - 20);
  63. okButton = new UIButton("OK", 100);
  64. addChild(okButton);
  65. okButton->setPosition(500-100, 400 - 20);
  66. newFolderButton = new UIButton("New Folder", 100);
  67. addChild(newFolderButton);
  68. newFolderButton->setPosition(25, 400-20);
  69. newFolderButton->addEventListener(this, UIEvent::CLICK_EVENT);
  70. okButton->addEventListener(this, UIEvent::CLICK_EVENT);
  71. cancelButton->addEventListener(this, UIEvent::CLICK_EVENT);
  72. entryHolder = new UIElement();
  73. entryHolder->ownsChildren = true;
  74. entryHolder->setWidth(1);
  75. entryHolder->setHeight(1);
  76. scrollContainer = new UIScrollContainer(entryHolder, false, true, 500-140, 320);
  77. addChild(scrollContainer);
  78. scrollContainer->setPosition(160, 40);
  79. showFolder(baseDir);
  80. createFolderWindow = new CreateFolderWindow();
  81. createFolderWindow->visible = false;
  82. createFolderWindow->enabled = false;
  83. createFolderWindow->setPosition(100, 150);
  84. createFolderWindow->okButton->addEventListener(this, UIEvent::CLICK_EVENT);
  85. createFolderWindow->cancelButton->addEventListener(this, UIEvent::CLICK_EVENT);
  86. addChild(createFolderWindow);
  87. doChangeFolder = false;
  88. addToSidebar("/", "Filesystem");
  89. addToSidebar(CoreServices::getInstance()->getCore()->getUserHomeDirectory(), "Home");
  90. }
  91. bool UIFileDialog::canOpen(String extension) {
  92. if(extensions.empty()) {
  93. return true;
  94. }
  95. for(int i=0; i < extensions.size(); i++) {
  96. if(extensions[i] == extension) {
  97. return true;
  98. }
  99. }
  100. return false;
  101. }
  102. void UIFileDialog::addToSidebar(String path, String name) {
  103. OSFileEntry backEntry;
  104. backEntry.type = OSFileEntry::TYPE_FOLDER;
  105. backEntry.name = name;
  106. backEntry.fullPath = path;
  107. UIFileDialogEntry *newEntry = new UIFileDialogEntry(backEntry, true, 140, true);
  108. addChild(newEntry);
  109. newEntry->setPosition(10, 40 + (sideBarEntries.size() * 20));
  110. sideBarEntries.push_back(newEntry);
  111. newEntry->bg->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
  112. }
  113. void UIFileDialog::clearEntries() {
  114. for(int i=0; i < entries.size(); i++) {
  115. entryHolder->removeChild(entries[i]);
  116. delete entries[i];
  117. }
  118. entries.clear();
  119. }
  120. void UIFileDialog::onClose() {
  121. dispatchEvent(new UIEvent(), UIEvent::CANCEL_EVENT);
  122. }
  123. String UIFileDialog::getSelection() {
  124. return selection;
  125. }
  126. void UIFileDialog::showFolder(String folderPath) {
  127. doChangeFolder = false;
  128. currentFolderPath = folderPath;
  129. if(foldersOnly) {
  130. selection = folderPath;
  131. } else {
  132. selection = "";
  133. }
  134. for(int i=0; i < sideBarEntries.size(); i++) {
  135. sideBarEntries[i]->Deselect();
  136. }
  137. currentEntry = NULL;
  138. clearEntries();
  139. std::vector<OSFileEntry> _entries = OSBasics::parseFolder(folderPath, false);
  140. int offset = 0;
  141. if(folderPath != "/") {
  142. offset = 1;
  143. OSFileEntry backEntry;
  144. backEntry.type = OSFileEntry::TYPE_FOLDER;
  145. backEntry.name = "..";
  146. backEntry.basePath = folderPath;
  147. backEntry.fullPath = folderPath+"/..";
  148. UIFileDialogEntry *newEntry = new UIFileDialogEntry(backEntry, true);
  149. entryHolder->addChild(newEntry);
  150. entries.push_back(newEntry);
  151. newEntry->bg->addEventListener(this, InputEvent::EVENT_DOUBLECLICK);
  152. newEntry->bg->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
  153. }
  154. int i;
  155. for(i=0; i < _entries.size(); i++) {
  156. bool canSelect = false;
  157. if(_entries[i].type == OSFileEntry::TYPE_FOLDER) {
  158. canSelect = true;
  159. }
  160. if(foldersOnly) {
  161. } else {
  162. if(canOpen(_entries[i].extension)) {
  163. canSelect = true;
  164. }
  165. }
  166. UIFileDialogEntry *newEntry = new UIFileDialogEntry(_entries[i], canSelect);
  167. entryHolder->addChild(newEntry);
  168. newEntry->setPosition(0, (i+offset) * 20);
  169. entries.push_back(newEntry);
  170. newEntry->bg->addEventListener(this, InputEvent::EVENT_DOUBLECLICK);
  171. newEntry->bg->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
  172. }
  173. scrollContainer->setContentSize(500-160, (i+offset) * 20);
  174. }
  175. void UIFileDialog::Update() {
  176. if(doChangeFolder) {
  177. showFolder(newPath);
  178. doChangeFolder = false;
  179. }
  180. }
  181. void UIFileDialog::handleEvent(Event *event) {
  182. for(int i=0; i < sideBarEntries.size(); i++) {
  183. if(event->getDispatcher() == sideBarEntries[i]->bg) {
  184. showFolder(sideBarEntries[i]->fileEntry.fullPath);
  185. sideBarEntries[i]->Select();
  186. }
  187. }
  188. for(int i=0; i < entries.size(); i++) {
  189. if(event->getDispatcher() == entries[i]->bg) {
  190. switch(event->getEventCode()) {
  191. case InputEvent::EVENT_DOUBLECLICK:
  192. if(entries[i]->fileEntry.type == OSFileEntry::TYPE_FOLDER && entries[i]->canSelect) {
  193. doChangeFolder = true;
  194. if(entries[i]->fileEntry.name == "..") {
  195. std::vector<String> bits = currentFolderPath.split("/");
  196. newPath = "";
  197. if(bits.size() > 2) {
  198. for(int i=1; i < bits.size()-1; i++) {
  199. newPath += "/"+bits[i];
  200. }
  201. } else {
  202. newPath = "/";
  203. }
  204. } else{
  205. newPath = entries[i]->fileEntry.fullPath;
  206. }
  207. }
  208. break;
  209. case InputEvent::EVENT_MOUSEDOWN:
  210. if(entries[i]->canSelect) {
  211. if(currentEntry)
  212. currentEntry->Deselect();
  213. entries[i]->Select();
  214. currentEntry = entries[i];
  215. if((foldersOnly && entries[i]->fileEntry.type == OSFileEntry::TYPE_FOLDER)
  216. || (!foldersOnly && entries[i]->fileEntry.type == OSFileEntry::TYPE_FILE)) {
  217. selection = entries[i]->fileEntry.fullPath;
  218. }
  219. }
  220. break;
  221. }
  222. }
  223. }
  224. if(event->getDispatcher() == okButton) {
  225. dispatchEvent(new UIEvent(), UIEvent::OK_EVENT);
  226. }
  227. if(event->getDispatcher() == cancelButton) {
  228. dispatchEvent(new UIEvent(), UIEvent::CANCEL_EVENT);
  229. }
  230. if(event->getDispatcher() == createFolderWindow->okButton) {
  231. CoreServices::getInstance()->getCore()->createFolder(currentFolderPath+"/"+createFolderWindow->nameInput->getText());
  232. createFolderWindow->visible = false;
  233. createFolderWindow->enabled = false;
  234. showFolder(currentFolderPath);
  235. }
  236. if(event->getDispatcher() == createFolderWindow->cancelButton) {
  237. createFolderWindow->visible = false;
  238. createFolderWindow->enabled = false;
  239. }
  240. if(event->getDispatcher() == newFolderButton) {
  241. createFolderWindow->nameInput->setText("");
  242. createFolderWindow->visible = true;
  243. createFolderWindow->enabled = true;
  244. }
  245. UIWindow::handleEvent(event);
  246. }
  247. UIFileDialog::~UIFileDialog() {
  248. if(!ownsChildren) {
  249. delete okButton;
  250. delete cancelButton;
  251. delete newFolderButton;
  252. delete scrollContainer;
  253. delete createFolderWindow;
  254. delete entryHolder;
  255. for(int i=0; i < sideBarEntries.size(); i++) {
  256. delete sideBarEntries[i];
  257. }
  258. }
  259. }
  260. CreateFolderWindow::CreateFolderWindow() : UIWindow("New folder name", 290, 80) {
  261. closeBtn->visible = false;
  262. closeBtn->enabled = false;
  263. nameInput = new UITextInput(false, 270, 16);
  264. addChild(nameInput);
  265. nameInput->setPosition(20, 34);
  266. cancelButton = new UIButton("Cancel", 100);
  267. addChild(cancelButton);
  268. cancelButton->setPosition(300-210, 80 - 12);
  269. okButton = new UIButton("OK", 100);
  270. addChild(okButton);
  271. okButton->setPosition(300-100, 80 - 12);
  272. }
  273. CreateFolderWindow::~CreateFolderWindow() {
  274. if(!ownsChildren) {
  275. delete cancelButton;
  276. delete okButton;
  277. delete nameInput;
  278. }
  279. }