improve file name typing behavior
This commit is contained in:
parent
3eb4e02690
commit
3f19be9b8d
3 changed files with 113 additions and 26 deletions
|
|
@ -5115,6 +5115,23 @@ bool FurnaceGUI::loop() {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
switch (newFilePicker->getStatus()) {
|
||||
case FP_STATUS_ACCEPTED: {
|
||||
String combined="The file picker says: ";
|
||||
for (const String& i: newFilePicker->getSelected()) {
|
||||
combined+="\n- ";
|
||||
combined+=i;
|
||||
}
|
||||
showError(combined);
|
||||
break;
|
||||
}
|
||||
case FP_STATUS_CLOSED:
|
||||
showError("The file picker was closed.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (fileDialog->render(mobileUI?ImVec2(canvasW-(portrait?0:(60.0*dpiScale)),canvasH-60.0*dpiScale):ImVec2(600.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW-((mobileUI && !portrait)?(60.0*dpiScale):0),canvasH-(mobileUI?(60.0*dpiScale):0)))) {
|
||||
bool openOpen=false;
|
||||
//ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_NavEnableKeyboard;
|
||||
|
|
|
|||
|
|
@ -196,10 +196,8 @@ void FurnaceFilePicker::readDirectorySub() {
|
|||
readLinkPath=path+'/'+newEntry->name;
|
||||
}
|
||||
// silly, but works.
|
||||
logV("Read a symlink...");
|
||||
readLinkDir=opendir(readLinkPath.c_str());
|
||||
if (readLinkDir!=NULL) {
|
||||
logV("Is file");
|
||||
newEntry->isDir=true;
|
||||
closedir(readLinkDir);
|
||||
}
|
||||
|
|
@ -524,6 +522,32 @@ void FurnaceFilePicker::filterFiles() {
|
|||
}
|
||||
}
|
||||
|
||||
bool FurnaceFilePicker::isPathAbsolute(const String& p) {
|
||||
#ifdef _WIN32
|
||||
// TODO: test for UNC path?
|
||||
|
||||
// convert to absolute path if necessary
|
||||
bool willConvert=(p.size()<3);
|
||||
if (!willConvert) {
|
||||
// test for drive letter
|
||||
if (!(((p[0]>='A' && p[0]<='Z') || (p[0]>='a' && p[0]<='z')) && p[1]==':' && p[2]=='\\')) {
|
||||
if (p.size()<4) {
|
||||
willConvert=true;
|
||||
} else {
|
||||
if (!(((p[0]>='A' && p[0]<='Z') || (p[0]>='a' && p[0]<='z')) && ((p[1]>='A' && p[1]<='Z') || (p[1]>='a' && p[1]<='z')) && p[2]==':' && p[3]=='\\')) {
|
||||
willConvert=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !willConvert;
|
||||
#else
|
||||
if (p.size()<1) return false;
|
||||
return (p[0]=='/');
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FurnaceFilePicker::draw() {
|
||||
if (!isOpen) return false;
|
||||
|
||||
|
|
@ -550,22 +574,7 @@ bool FurnaceFilePicker::draw() {
|
|||
mkdirError="Maybe try that again under better circumstances...";
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
// convert to absolute path if necessary
|
||||
bool willConvert=(mkdirPath.size()<3);
|
||||
if (!willConvert) {
|
||||
// test for drive letter
|
||||
if (!(((mkdirPath[0]>='A' && mkdirPath[0]<='Z') || (mkdirPath[0]>='a' && mkdirPath[0]<='z')) && mkdirPath[1]==':' && mkdirPath[2]=='\\')) {
|
||||
if (mkdirPath.size()<4) {
|
||||
willConvert=true;
|
||||
} else {
|
||||
if (!(((mkdirPath[0]>='A' && mkdirPath[0]<='Z') || (mkdirPath[0]>='a' && mkdirPath[0]<='z')) && ((mkdirPath[1]>='A' && mkdirPath[1]<='Z') || (mkdirPath[1]>='a' && mkdirPath[1]<='z')) && mkdirPath[2]==':' && mkdirPath[3]=='\\')) {
|
||||
willConvert=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (willConvert) {
|
||||
if (!isPathAbsolute(mkdirPath)) {
|
||||
if (path.empty()) {
|
||||
// error out in the drives view
|
||||
mkdirError="Trying to create a directory in the drives list";
|
||||
|
|
@ -595,7 +604,7 @@ bool FurnaceFilePicker::draw() {
|
|||
}
|
||||
#else
|
||||
// convert to absolute path if necessary
|
||||
if (mkdirPath[0]!='/') {
|
||||
if (!isPathAbsolute(mkdirPath)) {
|
||||
if (!path.empty()) {
|
||||
if (*path.rbegin()=='/') {
|
||||
mkdirPath=path+mkdirPath;
|
||||
|
|
@ -947,7 +956,10 @@ bool FurnaceFilePicker::draw() {
|
|||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x*0.68f);
|
||||
if (ImGui::InputText("##EntryName",&entryName)) {
|
||||
// find an entry with this name
|
||||
for (FileEntry* j: chosenEntries) {
|
||||
j->isSelected=false;
|
||||
}
|
||||
chosenEntries.clear();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
|
@ -962,7 +974,7 @@ bool FurnaceFilePicker::draw() {
|
|||
}
|
||||
|
||||
// OK/Cancel buttons
|
||||
ImGui::BeginDisabled(chosenEntries.empty());
|
||||
ImGui::BeginDisabled(entryName.empty() && chosenEntries.empty());
|
||||
if (ImGui::Button("OK")) {
|
||||
// accept entry
|
||||
acknowledged=true;
|
||||
|
|
@ -995,9 +1007,61 @@ bool FurnaceFilePicker::draw() {
|
|||
}
|
||||
} else {
|
||||
// select this entry
|
||||
finalSelection.clear();
|
||||
for (FileEntry* i: chosenEntries) {
|
||||
if (path.empty()) {
|
||||
finalSelection.push_back(i->name);
|
||||
} else if (*path.rbegin()==DIR_SEPARATOR) {
|
||||
finalSelection.push_back(path+i->name);
|
||||
} else {
|
||||
finalSelection.push_back(path+DIR_SEPARATOR_STR+i->name);
|
||||
}
|
||||
}
|
||||
|
||||
curStatus=FP_STATUS_ACCEPTED;
|
||||
isOpen=false;
|
||||
}
|
||||
} else {
|
||||
// return the user-provided entry
|
||||
finalSelection.clear();
|
||||
if (!entryName.empty()) {
|
||||
String dirCheckPath;
|
||||
if (isPathAbsolute(entryName)) {
|
||||
dirCheckPath=entryName;
|
||||
} else {
|
||||
if (path.empty()) {
|
||||
dirCheckPath=entryName;
|
||||
} else if (*path.rbegin()==DIR_SEPARATOR) {
|
||||
dirCheckPath=path+entryName;
|
||||
} else {
|
||||
dirCheckPath=path+DIR_SEPARATOR_STR+entryName;
|
||||
}
|
||||
}
|
||||
|
||||
// check whether this is a directory
|
||||
bool isDir=false;
|
||||
#ifdef _WIN32
|
||||
WString dirCheckPathW=utf8To16(dirCheckPath);
|
||||
isDir=PathIsDirectoryW(dirCheckPathW.c_str());
|
||||
#else
|
||||
// again, silly but works.
|
||||
DIR* checkDir=opendir(dirCheckPath.c_str());
|
||||
if (checkDir!=NULL) {
|
||||
isDir=true;
|
||||
closedir(checkDir);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isDir) {
|
||||
// go to directory
|
||||
newDir=dirCheckPath;
|
||||
} else {
|
||||
// return now
|
||||
finalSelection.push_back(dirCheckPath);
|
||||
curStatus=FP_STATUS_ACCEPTED;
|
||||
isOpen=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1031,10 +1095,6 @@ bool FurnaceFilePicker::open(String name, String pa, bool modal, const std::vect
|
|||
return true;
|
||||
}
|
||||
|
||||
const String& FurnaceFilePicker::getEntryName() {
|
||||
return entryName;
|
||||
}
|
||||
|
||||
void FurnaceFilePicker::setMobile(bool val) {
|
||||
isMobile=val;
|
||||
}
|
||||
|
|
@ -1053,6 +1113,14 @@ void FurnaceFilePicker::saveSettings(DivConfig& conf) {
|
|||
|
||||
}
|
||||
|
||||
const String& FurnaceFilePicker::getEntryName() {
|
||||
return entryName;
|
||||
}
|
||||
|
||||
const std::vector<String>& FurnaceFilePicker::getSelected() {
|
||||
return finalSelection;
|
||||
}
|
||||
|
||||
void FurnaceFilePicker::setTypeStyle(FileType type, ImVec4 color, String icon) {
|
||||
// "##File" is appended here for performance.
|
||||
defaultTypeStyle[type].icon=icon+"##File";
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ class FurnaceFilePicker {
|
|||
std::vector<FileEntry*> sortedEntries;
|
||||
std::vector<FileEntry*> filteredEntries;
|
||||
std::vector<FileEntry*> chosenEntries;
|
||||
std::vector<String> finalSelection;
|
||||
std::vector<String> filterOptions;
|
||||
std::thread* fileThread;
|
||||
std::mutex entryLock;
|
||||
|
|
@ -104,13 +105,14 @@ class FurnaceFilePicker {
|
|||
void updateEntryName();
|
||||
void readDirectory(String path);
|
||||
String normalizePath(const String& which);
|
||||
bool isPathAbsolute(const String& p);
|
||||
|
||||
public:
|
||||
void readDirectorySub();
|
||||
void setHomeDir(String where);
|
||||
FilePickerStatus getStatus();
|
||||
const String& getEntryName();
|
||||
const std::vector<FileEntry*>& getSelected();
|
||||
const std::vector<String>& getSelected();
|
||||
void setMobile(bool val);
|
||||
bool draw();
|
||||
bool open(String name, String path, bool modal, const std::vector<String>& filter);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue