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
This commit is contained in:
tildearrow 2025-09-27 20:40:27 -05:00
parent 3f19be9b8d
commit 4ec66a4684
4 changed files with 136 additions and 29 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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<String>& filter) {
bool FurnaceFilePicker::open(String name, String pa, int flags, const std::vector<String>& 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),

View file

@ -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<String>& getSelected();
void setMobile(bool val);
bool draw();
bool open(String name, String path, bool modal, const std::vector<String>& filter);
bool open(String name, String path, int flags, const std::vector<String>& filter);
void loadSettings(DivConfig& conf);
void saveSettings(DivConfig& conf);
void setTypeStyle(FileType type, ImVec4 color, String icon);