138 lines
4.5 KiB
C++
138 lines
4.5 KiB
C++
/// Josh's User Interface Library
|
|
/// A C++20 Library for creating, styling, and rendering of a UI/UX widgets.
|
|
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
|
|
/// Special Thanks to William Tomasine II and Maxine Hayes.
|
|
/// (c) 2024 Redacted Software
|
|
/// This work is dedicated to the public domain.
|
|
|
|
/// @file FileDialog.hpp
|
|
/// @desc A dialog window that shows a selection of files on disk, and a form for naming, used for file loading and saving.
|
|
|
|
/// @edit 2024-5-29
|
|
|
|
#pragma once
|
|
|
|
#include <JUI/Widgets/Window.hpp>
|
|
#include <JUI/Widgets/UtilityBar.hpp>
|
|
#include <JUI/Widgets/ScrollingRect.hpp>
|
|
|
|
namespace JUI
|
|
{
|
|
class FileListing : public JUI::Widget { };
|
|
|
|
// TODO: Implement SortBy enumeration - Date, Size, Name, Type
|
|
class FileDialogWindow : public JUI::Window
|
|
{
|
|
public:
|
|
Event<> UserCompleted;
|
|
Event<> UserConfirmed;
|
|
Event<> UserCancelled;
|
|
FileDialogWindow() : Window() {
|
|
|
|
Title("File Dialog");
|
|
|
|
auto* toolbar = new JUI::UtilityBar(this->Content());
|
|
|
|
auto* file_listing = new JUI::Rect(this->Content());
|
|
file_listing->Size({100_percent, 100_percent-20_px});
|
|
|
|
file_layout = new JUI::VerticalListLayout(file_listing);
|
|
}
|
|
|
|
/// Tree system
|
|
|
|
std::string format_perms(const std::filesystem::perms& p) const {
|
|
using std::filesystem::perms;
|
|
auto parse = [=](char op, perms perm) {
|
|
return (perms::none == (perm & p) ? '-' : op);
|
|
};
|
|
|
|
std::string perm_string = "";
|
|
|
|
perm_string += parse('r', perms::owner_read);
|
|
perm_string += parse('w', perms::owner_write);
|
|
perm_string += parse('x', perms::owner_exec);
|
|
|
|
perm_string += parse('r', perms::group_read);
|
|
perm_string += parse('w', perms::group_write);
|
|
perm_string += parse('x', perms::group_exec);
|
|
|
|
perm_string += parse('r', perms::others_read);
|
|
perm_string += parse('w', perms::others_write);
|
|
perm_string += parse('x', perms::others_exec);
|
|
|
|
return perm_string;
|
|
}
|
|
|
|
std::string format_size(uintmax_t size) const {
|
|
bool addSpace = false;
|
|
int precision = 2;
|
|
std::vector<std::string> units = {"B", "KB", "GB", "TB", "PB", "EB", "ZB", "YB"};
|
|
|
|
if (Math::Abs(size) < 1) return std::to_string(size) + (addSpace ? " " : "") + units[0];
|
|
|
|
auto exponent = Math::Min<uintmax_t>(Math::Floor(Math::Log10(size < 0 ? -size : size) / 3), units.size()-1);
|
|
|
|
auto n = (size < 0 ? -size : size) / std::pow(1000, exponent);
|
|
|
|
|
|
return (size < 0 ? "-" : "") + std::format("{}", n) + (addSpace ? " ": "") + units[exponent];
|
|
}
|
|
|
|
JUI::Rect* CreateFileEntry(const std::filesystem::directory_entry& entry) {
|
|
|
|
|
|
auto* rect = new JUI::TextRect(file_layout);
|
|
rect->Size({100_percent, 20_px});
|
|
|
|
std::string entry_type = entry.is_directory() ? "directory" : "file";
|
|
std::string perms = format_perms(entry.status().permissions());
|
|
|
|
auto file_size = (entry.is_directory() ? 0 : entry.file_size());
|
|
auto file_size_str = format_size(file_size);
|
|
std::filesystem::file_time_type timestamp = (entry.is_directory() ? std::filesystem::file_time_type{} : entry.last_write_time());
|
|
|
|
std::string label = std::format("{} {} {} {} {}", entry.path().filename().string(), file_size_str, entry_type, perms, timestamp);
|
|
|
|
rect->Content(label);
|
|
|
|
return rect;
|
|
}
|
|
|
|
|
|
FileDialogWindow(const std::filesystem::path& root) : FileDialogWindow() {
|
|
std::cout << root.relative_path() << std::endl;
|
|
std::cout << root.root_directory() << std::endl;
|
|
std::cout << root.filename() << std::endl;
|
|
std::cout << root.parent_path() << std::endl;
|
|
std::cout << root.string() << std::endl;
|
|
std::cout << std::filesystem::current_path() << std::endl;
|
|
|
|
Title(std::format("'{}' in '{}' - File Dialog", root.relative_path().string(), std::filesystem::current_path().string()));
|
|
|
|
for (const auto& entry: std::filesystem::directory_iterator(root)) {
|
|
|
|
CreateFileEntry(entry);
|
|
}
|
|
}
|
|
explicit FileDialogWindow(Widget* parent, const std::filesystem::path& root) : FileDialogWindow(root)
|
|
{
|
|
Parent(parent);
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
int directories_indexed = 0;
|
|
VerticalListLayout* file_layout;
|
|
std::vector<Rect*> file_entry_widgets;
|
|
private:
|
|
};
|
|
|
|
|
|
class OpenFileDialogWindow : public JUI::Window { };
|
|
class SaveFileDialogWindow : public JUI::Window { };
|
|
class SelectFolderDialog : public JUI::Window { };
|
|
|
|
} |