type numbers to go through directories

This commit is contained in:
Jason Ly 2025-12-20 18:33:59 -05:00
parent 3b0b7359af
commit 8bc030fe94

View File

@ -3,18 +3,16 @@
#include <ftxui/component/screen_interactive.hpp> #include <ftxui/component/screen_interactive.hpp>
#include <ftxui/screen/screen.hpp> #include <ftxui/screen/screen.hpp>
#include <iostream> #include <iostream>
#include <filesystem> // Required for std::filesystem #include <filesystem>
//using namespace std; std::string directory_path = ".";
//namespace fs = std::filesystem; // Create a shorter alias for std::filesystem
std::string directory_path = "."; // Replace with your directory path
std::string test;
// Note: You must pass the ScreenInteractive object to trigger a redraw. // Note: You must pass the ScreenInteractive object to trigger a redraw.
void ReloadDirectory(ftxui::ScreenInteractive& screen, const std::filesystem::path& new_path, std::vector<std::string>& entries) { void ReloadDirectory(ftxui::ScreenInteractive& screen, const std::filesystem::path& new_path, std::vector<std::string>& entries, std::vector<std::string>& clean_names) {
test = "ReloadDirectory"; if (!std::filesystem::exists(new_path) || !std::filesystem::is_directory(new_path)) return;
//namespace fs = std::filesystem;
entries.clear();
clean_names.clear();
//std::string directory_path = new_path.string; // Replace with your directory path // linux //std::string directory_path = new_path.string; // Replace with your directory path // linux
std::string directory_path = new_path.string(); // Replace with your directory path //windows std::string directory_path = new_path.string(); // Replace with your directory path //windows
@ -22,38 +20,43 @@ void ReloadDirectory(ftxui::ScreenInteractive& screen, const std::filesystem::pa
if (!std::filesystem::exists(new_path) || !std::filesystem::is_directory(new_path)) { if (!std::filesystem::exists(new_path) || !std::filesystem::is_directory(new_path)) {
// Handle error case (optional: display a warning in the TUI) // Handle error case (optional: display a warning in the TUI)
std::cerr << "Error: Not a directory or path does not exist." << std::endl; std::cerr << "Error: Not a directory or path does not exist." << std::endl;
test = "path not a directory: " + new_path.string(); std::cerr << "Path not a directory: " + new_path.string();
return; return;
} }
// 2. Read the new directory entries // 2. Read the new directory entries
int i = 1; int i = 1;
test = "list dir";
clean_names.clear();
entries.clear(); entries.clear();
entries.push_back("0. .. (go up one level)"); // Option to go up one level
clean_names.push_back("..");
for (const auto& entry : std::filesystem::directory_iterator(new_path)) { for (const auto& entry : std::filesystem::directory_iterator(new_path)) {
test = "got in for loop, new path is " + new_path.string();
if (std::filesystem::is_directory(entry.path()) || std::filesystem::is_regular_file(entry.path())) { if (std::filesystem::is_directory(entry.path()) || std::filesystem::is_regular_file(entry.path())) {
i++;
std::string name = entry.path().filename().string(); std::string name = entry.path().filename().string();
//if (fs::is_directory(entry.path())) { if (name.starts_with("."))
// name += "/"; continue; // Skip hidden files and directories
//} entries.push_back(std::to_string(i) + ". " + name);
entries.push_back(name); clean_names.push_back(name);
//entries.push_back(std::to_string(i) + ". " + name); i++;
//actual_paths.push_back(entry.path());
} }
} }
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
//using namespace ftxui;
//using namespace std;
// Define a variable to hold the final selection index // Define a variable to hold the final selection index
int final_selected_index = -1; // Use -1 to indicate no selection was made int final_selected_index = -1; // Use -1 to indicate no selection was made
std::vector<std::string> entries; std::vector<std::string> entries;
std::vector<std::string> clean_names; // New vector for logic
std::string current_path = std::filesystem::current_path().string();
if (argc > 1) if (argc > 1)
{
directory_path = argv[1]; directory_path = argv[1];
current_path = directory_path;
}
// Check if the directory exists // Check if the directory exists
if (!std::filesystem::exists(directory_path) || !std::filesystem::is_directory(directory_path)) { if (!std::filesystem::exists(directory_path) || !std::filesystem::is_directory(directory_path)) {
@ -62,39 +65,61 @@ int main(int argc, char* argv[]) {
} }
auto screen = ftxui::ScreenInteractive::TerminalOutput(); auto screen = ftxui::ScreenInteractive::TerminalOutput();
ReloadDirectory(screen, directory_path, entries, clean_names);
std::filesystem::directory_iterator entryIt(directory_path);
int i = 0;
// Iterate through the directory entries
for (const auto& entry : std::filesystem::directory_iterator(directory_path))
//for (entryIt = entries.begin(), i = 0; entryIt != entries.end(); ++ entryIt, i++)
{
i++;
std::string str_num = std::to_string(i);
entries.push_back( entry.path().filename().string());
}
/* = {
"entry 1",
"entry 2",
"entry 3",
};*/
int selected = 0; int selected = 0;
auto menu = ftxui::Menu({ auto menu = ftxui::Menu({
.entries = &entries, .entries = &entries,
.selected = &selected, .selected = &selected,
}); });
std::string input_buffer = ""; // Stores digits as the user types them
// --- The key part: Applying CatchEvent() --- // --- The key part: Applying CatchEvent() ---
auto menu_with_event_handler = menu | ftxui::CatchEvent([&](ftxui::Event event) { auto menu_with_event_handler = menu | ftxui::CatchEvent([&](ftxui::Event event) {
// 1. Handle Digit Input (0-9)
if (event.is_character()) {
char c = event.character()[0];
if (std::isdigit(c)) {
input_buffer += c; // Add the digit to our "typing" buffer
//std::cout << "Typed so far: " << input_buffer << std::endl; // For debugging
return true;
}
}
// 2. Handle Backspace (to correct typing errors)
if (event == ftxui::Event::Backspace && !input_buffer.empty()) {
input_buffer.pop_back();
return true;
}
// Handle the 'Enter' key press // Handle the 'Enter' key press
if (event == ftxui::Event::Return) { if (event == ftxui::Event::Return) {
// 1. Store the selected index if (!input_buffer.empty()) {
final_selected_index = selected; // Convert buffer to integer and check bounds
std::cout << "Selected Entry: " << entries[selected] << std::endl; int requested_index = std::stoi(input_buffer);// -1;
directory_path = directory_path + "/" + entries[selected]; if (requested_index >= 0 && requested_index < (int)clean_names.size()) {
selected = requested_index; // Move the highlight to the typed index
}
input_buffer.clear(); // Clear buffer after use
}
std::string selected_name;
std::filesystem::path new_path;
if (clean_names.size() > 0)
selected_name = clean_names[selected];
// Construct the new path
if (selected_name == "..") {
new_path = std::filesystem::path(current_path).parent_path();
}
else {
new_path = std::filesystem::path(current_path) / selected_name;
}
new_path.make_preferred();
current_path = new_path.string();
// Call the function to switch and reload // Call the function to switch and reload
ReloadDirectory(screen, directory_path, entries); ReloadDirectory(screen, new_path, entries,clean_names);
selected = 0; // Reset selection to the first item
//screen.Exit(); // Exit the application //screen.Exit(); // Exit the application
return true; // Event handled return true; // Event handled
} }
@ -110,13 +135,43 @@ int main(int argc, char* argv[]) {
return false; return false;
}); });
screen.Loop(menu_with_event_handler); // Create a renderer that defines the layout of your application
auto main_renderer = ftxui::Renderer(menu_with_event_handler, [&] {
return ftxui::vbox({
// Header showing the current directory
ftxui::hbox({
ftxui::text(" Current Directory: ") | ftxui::bold,
ftxui::text(current_path) | ftxui::color(ftxui::Color::Cyan),
}),
ftxui::separator(),
// The menu itself, wrapped in a frame to allow scrolling if the list is long
menu_with_event_handler->Render() | ftxui::vscroll_indicator | ftxui::frame,
ftxui::filler(), // Pushes the footer to the bottom
ftxui::separator(),
ftxui::hbox({
ftxui::text("Enter folder #: "),
ftxui::text(input_buffer),
}),
// Footer with instructions
ftxui::hbox({
ftxui::text(" [Enter] Open [q] Quit "),
ftxui::filler(),
ftxui::text(" Items: " + std::to_string(clean_names.size())) | ftxui::dim,
}),
}) | ftxui::border; // Adds a border around the whole app
});
screen.Loop(main_renderer);
// ---------------------------------------------------- // ----------------------------------------------------
// --- OUTPUT AFTER THE LOOP HAS CLEANLY EXITED --- // --- OUTPUT AFTER THE LOOP HAS CLEANLY EXITED ---
// ---------------------------------------------------- // ----------------------------------------------------
std::cout<< "directory path: " << directory_path << std::endl; std::cout<< "directory path: " << directory_path << std::endl;
//cout << "test: " << test << endl;
if (final_selected_index >= 0 && final_selected_index < entries.size()) { if (final_selected_index >= 0 && final_selected_index < entries.size()) {
std::cout << "Selected Entry: " << entries[final_selected_index] << std::endl; std::cout << "Selected Entry: " << entries[final_selected_index] << std::endl;
} else { } else {