feat: add ".." go-up entry to directory picker
The folder picker had no visible way to navigate to a parent directory. Add a ".." list item (shown when not at root) so users can go up by selecting it, matching standard file-picker conventions. Made-with: Cursor
This commit is contained in:
@@ -63,6 +63,14 @@ void DirectoryPickerActivity::loadDirectories() {
|
||||
StringUtils::sortFileList(directories);
|
||||
}
|
||||
|
||||
void DirectoryPickerActivity::navigateToParent() {
|
||||
auto slash = basepath.find_last_of('/');
|
||||
basepath = (slash == 0) ? "/" : basepath.substr(0, slash);
|
||||
selectorIndex = 0;
|
||||
loadDirectories();
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
void DirectoryPickerActivity::loop() {
|
||||
// Absorb the Confirm release from the parent activity that launched us
|
||||
if (waitForConfirmRelease) {
|
||||
@@ -72,14 +80,16 @@ void DirectoryPickerActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Index 0 = "Save Here", indices 1..N = directory entries
|
||||
const int totalItems = 1 + static_cast<int>(directories.size());
|
||||
const int offset = directoryOffset();
|
||||
const int totalItems = offset + static_cast<int>(directories.size());
|
||||
|
||||
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
|
||||
if (selectorIndex == 0) {
|
||||
onSelect(basepath);
|
||||
} else if (showGoUp() && selectorIndex == 1) {
|
||||
navigateToParent();
|
||||
} else {
|
||||
const auto& dirName = directories[selectorIndex - 1];
|
||||
const auto& dirName = directories[selectorIndex - offset];
|
||||
// Strip trailing '/'
|
||||
std::string folderName = dirName.substr(0, dirName.length() - 1);
|
||||
basepath = (basepath.back() == '/' ? basepath : basepath + "/") + folderName;
|
||||
@@ -94,11 +104,7 @@ void DirectoryPickerActivity::loop() {
|
||||
if (basepath == "/") {
|
||||
onCancel();
|
||||
} else {
|
||||
auto slash = basepath.find_last_of('/');
|
||||
basepath = (slash == 0) ? "/" : basepath.substr(0, slash);
|
||||
selectorIndex = 0;
|
||||
loadDirectories();
|
||||
requestUpdate();
|
||||
navigateToParent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -139,21 +145,24 @@ void DirectoryPickerActivity::render(Activity::RenderLock&&) {
|
||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing;
|
||||
|
||||
const int totalItems = 1 + static_cast<int>(directories.size());
|
||||
const int offset = directoryOffset();
|
||||
const int totalItems = offset + static_cast<int>(directories.size());
|
||||
const bool goUp = showGoUp();
|
||||
|
||||
GUI.drawList(
|
||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, totalItems, selectorIndex,
|
||||
[this](int index) -> std::string {
|
||||
[this, offset, goUp](int index) -> std::string {
|
||||
if (index == 0) {
|
||||
std::string label = std::string(tr(STR_SAVE_HERE)) + " (" + basepath + ")";
|
||||
return label;
|
||||
return std::string(tr(STR_SAVE_HERE)) + " (" + basepath + ")";
|
||||
}
|
||||
// Strip trailing '/' for display
|
||||
const auto& dir = directories[index - 1];
|
||||
if (goUp && index == 1) {
|
||||
return "..";
|
||||
}
|
||||
const auto& dir = directories[index - offset];
|
||||
return dir.substr(0, dir.length() - 1);
|
||||
},
|
||||
nullptr,
|
||||
[this](int index) -> UIIcon {
|
||||
[](int index) -> UIIcon {
|
||||
return (index == 0) ? UIIcon::File : UIIcon::Folder;
|
||||
});
|
||||
|
||||
|
||||
@@ -41,4 +41,7 @@ class DirectoryPickerActivity final : public Activity {
|
||||
std::function<void()> onCancel;
|
||||
|
||||
void loadDirectories();
|
||||
void navigateToParent();
|
||||
[[nodiscard]] bool showGoUp() const { return basepath != "/"; }
|
||||
[[nodiscard]] int directoryOffset() const { return showGoUp() ? 2 : 1; }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user