struct FileDialog : Window { VerticalLayout layout; HorizontalLayout pathLayout; LineEdit pathEdit; Button homeButton; Button upButton; ListView fileList; HorizontalLayout controlLayout; Label filterLabel; Button openButton; string open() { setModal(); setVisible(); fileList.setFocused(); filename = ""; bool backspace = false; dialogActive = true; while(dialogActive) { OS::processEvents(); if(Keyboard::pressed(Keyboard::Scancode::Escape)) onClose(); if(Keyboard::pressed(Keyboard::Scancode::Backspace)) { if(backspace == false) { backspace = true; if(fileList.focused()) upButton.onActivate(); } } else { backspace = false; } usleep(20 * 1000); } return filename; } void setPath(const string &path) { pathname = string{path}.transform("\\", "/"); if(pathname.empty()) pathname = userpath(); if(pathname.endswith("/") == false) pathname.append("/"); pathEdit.setText(pathname); fileList.reset(); filenameList.reset(); lstring folders = directory::ifolders(pathname); for(auto &folder : folders) { fileList.append(string{folder}.rtrim<1>("/")); fileList.setImage(filenameList.size(), 0, {resource::folder, sizeof resource::folder}); filenameList.append({pathname, folder}); } lstring files = directory::ifiles(pathname); for(auto &file : files) { if(Ananke::supported(file) == false) continue; //ignore unsupported extensions fileList.append(file); if(extension(file) == "zip") { fileList.setImage(filenameList.size(), 0, {resource::archive, sizeof resource::archive}); } else { fileList.setImage(filenameList.size(), 0, {resource::file, sizeof resource::file}); } filenameList.append({pathname, file}); } fileList.setSelection(0); fileList.setSelected(); fileList.setFocused(); } FileDialog() { setFrameGeometry({64, 64, 480, 600}); setTitle("Load Image"); layout.setMargin(5); homeButton.setImage({resource::home, sizeof resource::home}); upButton.setImage({resource::up, sizeof resource::up}); filterLabel.setText("Filter: *.fc, *.sfc, *.st, *.bs, *.gb, *.gbc, *.gba, *.nes, *.smc, *.zip"); openButton.setText("Open"); append(layout); layout.append(pathLayout, {~0, 0}, 5); pathLayout.append(pathEdit, {~0, 0}, 5); pathLayout.append(homeButton, {28, 28}, 5); pathLayout.append(upButton, {28, 28}); layout.append(fileList, {~0, ~0}, 5); layout.append(controlLayout, {~0, 0}); controlLayout.append(filterLabel, {~0, 0}, 5); controlLayout.append(openButton, {80, 0}); pathEdit.onActivate = [&] { string path = pathEdit.text(); setPath(path); }; homeButton.onActivate = [&] { setPath(userpath()); }; upButton.onActivate = [&] { setPath(parentdir(pathname)); }; fileList.onActivate = openButton.onActivate = [&] { if(fileList.selected() == false) return; string name = filenameList(fileList.selection()); if(name.empty()) return; if(name.endswith("/")) return setPath(name); filename = name; onClose(); }; onClose = [&] { dialogActive = false; setModal(false); setVisible(false); }; } private: bool dialogActive; string pathname; string filename; lstring filenameList; };