joomer-ftxui-file-browser/joomer-ftxui-file-browser.cpp
2025-11-22 07:55:38 +00:00

133 lines
4.8 KiB
C++

#include <ftxui/component/component.hpp>
#include <ftxui/dom/elements.hpp>
#include <ftxui/component/screen_interactive.hpp>
#include <ftxui/screen/screen.hpp>
#include <iostream>
#include <filesystem> // Required for std::filesystem
using namespace std;
namespace fs = std::filesystem; // Create a shorter alias for std::filesystem
std::string directory_path = "."; // Replace with your directory path
string test;
// Note: You must pass the ScreenInteractive object to trigger a redraw.
void ReloadDirectory(ftxui::ScreenInteractive& screen, const fs::path& new_path, std::vector<std::string>& entries) {
test = "ReloadDirectory";
namespace fs = std::filesystem;
std::string directory_path = new_path; // Replace with your directory path
// Check if the path is a valid directory
if (!fs::exists(new_path) || !fs::is_directory(new_path)) {
// Handle error case (optional: display a warning in the TUI)
cerr << "Error: Not a directory or path does not exist." << endl;
test = "path not a directory: " + string(new_path.c_str());
return;
}
// 2. Read the new directory entries
int i = 1;
test = "list dir";
entries.clear();
for (const auto& entry : fs::directory_iterator(new_path)) {
test = "got in for loop, new path is " + string(new_path.c_str());
if (fs::is_directory(entry.path()) || fs::is_regular_file(entry.path())) {
i++;
std::string name = entry.path().filename().string();
//if (fs::is_directory(entry.path())) {
// name += "/";
//}
entries.push_back(name);
//entries.push_back(std::to_string(i) + ". " + name);
//actual_paths.push_back(entry.path());
}
}
}
int main(int argc, char* argv[]) {
using namespace ftxui;
using namespace std;
// Define a variable to hold the final selection index
int final_selected_index = -1; // Use -1 to indicate no selection was made
std::vector<std::string> entries;
if (argc > 1)
directory_path = argv[1];
// Check if the directory exists
if (!fs::exists(directory_path) || !fs::is_directory(directory_path)) {
std::cerr << "Error: Directory '" << directory_path << "' not found or is not a directory." << std::endl;
return 1;
}
auto screen = ScreenInteractive::TerminalOutput();
fs::directory_iterator entryIt(directory_path);
int i = 0;
// Iterate through the directory entries
for (const auto& entry : fs::directory_iterator(directory_path))
//for (entryIt = entries.begin(), i = 0; entryIt != entries.end(); ++ entryIt, i++)
{
i++;
string str_num = to_string(i);
entries.push_back( entry.path().filename().string());
}
/* = {
"entry 1",
"entry 2",
"entry 3",
};*/
int selected = 0;
auto menu = Menu({
.entries = &entries,
.selected = &selected,
});
// --- The key part: Applying CatchEvent() ---
auto menu_with_event_handler = menu | CatchEvent([&](Event event) {
// Handle the 'Enter' key press
if (event == Event::Return) {
// 1. Store the selected index
final_selected_index = selected;
std::cout << "Selected Entry: " << entries[selected] << std::endl;
directory_path = directory_path + "/" + entries[selected];
// Call the function to switch and reload
ReloadDirectory(screen, directory_path, entries);
//screen.Exit(); // Exit the application
return true; // Event handled
}
// Handle the 'q' key press to quit anytime
if (event == Event::Character('q')) {
screen.Exit();
return true; // Event handled
}
// If the event is not one we want to catch, return false
// so the Menu can handle it (like arrow keys)
return false;
});
screen.Loop(menu_with_event_handler);
// ----------------------------------------------------
// --- OUTPUT AFTER THE LOOP HAS CLEANLY EXITED ---
// ----------------------------------------------------
cout<< "directory path: " << directory_path << endl;
cout << "test: " << test << endl;
if (final_selected_index >= 0 && final_selected_index < entries.size()) {
std::cout << "Selected Entry: " << entries[final_selected_index] << std::endl;
} else {
std::cout << "Selection cancelled or no valid entry selected." << std::endl;
}
/*Element document = vbox({
text("left") | border,
text("middle") | border | flex,
text("right") | border,
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();*/
}