From 4ec66a4684407b61cc4f6a74b5de37601fc5fb66 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 27 Sep 2025 20:40:27 -0500 Subject: [PATCH] add flags as of now the new file picker is hidden in the debug menu. if you want to test it out, go there. coming soon is Windows testing --- src/gui/debugWindow.cpp | 29 ++++++++++ src/gui/gui.cpp | 6 --- src/gui/newFilePicker.cpp | 108 ++++++++++++++++++++++++++++++-------- src/gui/newFilePicker.h | 22 +++++++- 4 files changed, 136 insertions(+), 29 deletions(-) diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index 4153a5044..343a578c9 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -335,6 +335,35 @@ void FurnaceGUI::drawDebug() { ImGui::Unindent(); ImGui::TreePop(); } + if (ImGui::TreeNode("New File Picker Test")) { + static bool check0, check1, check2, check3, check4, check5; + + ImGui::Checkbox("Modal",&check0); + ImGui::Checkbox("No Close",&check1); + ImGui::Checkbox("Save",&check2); + ImGui::Checkbox("Multi Select",&check3); + ImGui::Checkbox("Dir Select",&check4); + ImGui::Checkbox("Embeddable",&check5); + + int fpFlags=( + (check0?FP_FLAGS_MODAL:0)| + (check1?FP_FLAGS_NO_CLOSE:0)| + (check2?FP_FLAGS_SAVE:0)| + (check3?FP_FLAGS_MULTI_SELECT:0)| + (check4?FP_FLAGS_DIR_SELECT:0)| + (check5?FP_FLAGS_EMBEDDABLE:0) + ); + + if (ImGui::Button("Open")) { + newFilePicker->open("New File Picker","/home",fpFlags, + {_("songs"), "*.fur *.dmf *.mod *.s3m *.xm *.it *.fc13 *.fc14 *.smod *.fc *.ftm *.0cc *.dnm *.eft *.fub *.tfe", + _("instruments"), "*.fui *.dmp *.tfi *.vgi *.s3i *.sbi *.opli *.opni *.y12 *.bnk *.ff *.gyb *.opm *.wopl *.wopn", + _("audio"), "*.wav", + _("all files"), "*"} + ); + } + ImGui::TreePop(); + } if (ImGui::TreeNode("File Selection Test")) { if (ImGui::Button("Test Open")) { openFileDialog(GUI_FILE_TEST_OPEN); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index ba41d5f91..5a6fe6c8d 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -7853,12 +7853,6 @@ bool FurnaceGUI::init() { newFilePicker=new FurnaceFilePicker; newFilePicker->setHomeDir(getHomeDir()); - newFilePicker->open("New File Picker","/home",false, - {_("songs"), "*.fur *.dmf *.mod *.s3m *.xm *.it *.fc13 *.fc14 *.smod *.fc *.ftm *.0cc *.dnm *.eft *.fub *.tfe", - _("instruments"), "*.fui *.dmp *.tfi *.vgi *.s3i *.sbi *.opli *.opni *.y12 *.bnk *.ff *.gyb *.opm *.wopl *.wopn", - _("audio"), "*.wav", - _("all files"), "*"} - ); updateWindowTitle(); updateROMExportAvail(); diff --git a/src/gui/newFilePicker.cpp b/src/gui/newFilePicker.cpp index 3d8ee9f08..e0952840c 100644 --- a/src/gui/newFilePicker.cpp +++ b/src/gui/newFilePicker.cpp @@ -555,8 +555,18 @@ bool FurnaceFilePicker::draw() { bool acknowledged=false; bool readDrives=false; - ImGui::SetNextWindowSizeConstraints(ImVec2(800.0,600.0),ImVec2(8000.0,6000.0)); - if (ImGui::Begin(windowName.c_str(),NULL,ImGuiWindowFlags_NoSavedSettings)) { + bool began=false; + + if (isEmbed) { + began=true; + } else if (isModal) { + ImGui::OpenPopup(windowName.c_str()); + began=ImGui::BeginPopupModal(windowName.c_str(),NULL,ImGuiWindowFlags_NoSavedSettings); + } else { + began=ImGui::Begin(windowName.c_str(),NULL,ImGuiWindowFlags_NoSavedSettings); + } + + if (began) { // header bars if (ImGui::Button(ICON_FA_PLUS "##MakeDir")) { mkdirError=""; @@ -891,17 +901,31 @@ bool FurnaceFilePicker::draw() { ImGui::PushStyleColor(ImGuiCol_Text,ImGui::GetColorU32(style->color)); ImGui::PushID(index++); if (ImGui::Selectable(style->icon.c_str(),i->isSelected,ImGuiSelectableFlags_AllowDoubleClick|ImGuiSelectableFlags_SpanAllColumns|ImGuiSelectableFlags_SpanAvailWidth)) { - for (FileEntry* j: chosenEntries) { - j->isSelected=false; + if ((ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) && multiSelect) { + // multiple selection + } else { + // clear selected entries + for (FileEntry* j: chosenEntries) { + j->isSelected=false; + } + chosenEntries.clear(); } - chosenEntries.clear(); - chosenEntries.push_back(i); - i->isSelected=true; - updateEntryName(); - if (isMobile) { - acknowledged=true; - } else if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - acknowledged=true; + + bool alreadySelected=false; + for (FileEntry* j: chosenEntries) { + if (j==i) alreadySelected=true; + } + + if (!alreadySelected) { + // select this entry + chosenEntries.push_back(i); + i->isSelected=true; + updateEntryName(); + if (isMobile) { + acknowledged=true; + } else if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { + acknowledged=true; + } } } ImGui::PopID(); @@ -980,10 +1004,12 @@ bool FurnaceFilePicker::draw() { acknowledged=true; } ImGui::EndDisabled(); - ImGui::SameLine(); - if (ImGui::Button("Cancel")) { - curStatus=FP_STATUS_CLOSED; - isOpen=false; + if (!noClose) { + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + curStatus=FP_STATUS_CLOSED; + isOpen=false; + } } ImGui::SameLine(); if (!haveFiles) { @@ -1019,7 +1045,15 @@ bool FurnaceFilePicker::draw() { } curStatus=FP_STATUS_ACCEPTED; - isOpen=false; + if (noClose) { + for (FileEntry* j: chosenEntries) { + j->isSelected=false; + } + chosenEntries.clear(); + updateEntryName(); + } else { + isOpen=false; + } } } else { // return the user-provided entry @@ -1059,28 +1093,50 @@ bool FurnaceFilePicker::draw() { // return now finalSelection.push_back(dirCheckPath); curStatus=FP_STATUS_ACCEPTED; - isOpen=false; + if (noClose) { + for (FileEntry* j: chosenEntries) { + j->isSelected=false; + } + chosenEntries.clear(); + updateEntryName(); + } else { + isOpen=false; + } } } } } } - ImGui::End(); + if (!isEmbed) { + if (isModal && began) { + if (!isOpen) ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } else { + ImGui::End(); + } + } if (!newDir.empty() || readDrives) { // change directory readDirectory(newDir); } - return false; + return isOpen; } -bool FurnaceFilePicker::open(String name, String pa, bool modal, const std::vector& filter) { +bool FurnaceFilePicker::open(String name, String pa, int flags, const std::vector& filter) { if (isOpen) return false; if (filter.size()&1) { logE("invalid filter data! it should be an even-sized vector with even elements containing names and odd ones being the filters."); return false; } + isModal=(flags&FP_FLAGS_MODAL); + noClose=(flags&FP_FLAGS_NO_CLOSE); + confirmOverwrite=(flags&FP_FLAGS_SAVE); + multiSelect=(flags&FP_FLAGS_MULTI_SELECT); + dirSelect=(flags&FP_FLAGS_DIR_SELECT); + isEmbed=(flags&FP_FLAGS_EMBEDDABLE); + filterOptions=filter; if (filterOptions.size()<2) { @@ -1113,6 +1169,10 @@ void FurnaceFilePicker::saveSettings(DivConfig& conf) { } +const String& FurnaceFilePicker::getPath() { + return path; +} + const String& FurnaceFilePicker::getEntryName() { return entryName; } @@ -1148,6 +1208,12 @@ FurnaceFilePicker::FurnaceFilePicker(): isOpen(false), isMobile(false), sortInvert(false), + multiSelect(false), + confirmOverwrite(false), + dirSelect(false), + noClose(false), + isModal(false), + isEmbed(false), scheduledSort(0), curFilterType(0), sortMode(FP_SORT_NAME), diff --git a/src/gui/newFilePicker.h b/src/gui/newFilePicker.h index 8aa44c1c7..5e19641e6 100644 --- a/src/gui/newFilePicker.h +++ b/src/gui/newFilePicker.h @@ -42,6 +42,22 @@ enum FileType { FP_TYPE_MAX }; +enum FilePickerFlags { + // display file picker as a modal pop-up + FP_FLAGS_MODAL=1, + // don't close the file picker on result + FP_FLAGS_NO_CLOSE=2, + // confirm overwrite and don't auto-acknowledge-on-tap on mobile + FP_FLAGS_SAVE=4, + // allow multiple selection + FP_FLAGS_MULTI_SELECT=8, + // directory selection mode + FP_FLAGS_DIR_SELECT=16, + // allows you to embed the file picker in an existing window (with draw()) + // DO NOT USE with FP_FLAGS_MODAL! + FP_FLAGS_EMBEDDABLE=32 +}; + class FurnaceFilePicker { enum SortModes { FP_SORT_NAME=0, @@ -83,7 +99,8 @@ class FurnaceFilePicker { String homeDir; String entryName; ImGuiListClipper listClipper; - bool haveFiles, haveStat, stopReading, isOpen, isMobile, sortInvert; + bool haveFiles, haveStat, stopReading, isOpen, isMobile, sortInvert, multiSelect; + bool confirmOverwrite, dirSelect, noClose, isModal, isEmbed; int scheduledSort; size_t curFilterType; SortModes sortMode; @@ -111,11 +128,12 @@ class FurnaceFilePicker { void readDirectorySub(); void setHomeDir(String where); FilePickerStatus getStatus(); + const String& getPath(); const String& getEntryName(); const std::vector& getSelected(); void setMobile(bool val); bool draw(); - bool open(String name, String path, bool modal, const std::vector& filter); + bool open(String name, String path, int flags, const std::vector& filter); void loadSettings(DivConfig& conf); void saveSettings(DivConfig& conf); void setTypeStyle(FileType type, ImVec4 color, String icon);