diff --git a/include/JUI/Widgets/Anchor.hpp b/include/JUI/Widgets/Anchor.hpp index 8d9d1b9..9204d4c 100644 --- a/include/JUI/Widgets/Anchor.hpp +++ b/include/JUI/Widgets/Anchor.hpp @@ -61,27 +61,31 @@ namespace JUI { auto origin_point = origin->Point(); using namespace J3ML; - Color4 line_color = Colors::Blues::DarkBlue; - float line_size = 1; - J2D::DrawLine(line_color, origin->Point(), goal->Point(), line_size); - float tri_size = 10; + J2D::DrawLine(color, origin->Point(), goal->Point(), line_width); - Vector2 triangle_base_pt = goal->Point() + (origin->Point().Normalized()); - J2D::DrawPoint(Colors::Yellow, triangle_base_pt, 4); + Vector2 direction = ( origin->Point() - goal->Point()).Normalized(); - Vector2 tri_left = triangle_base_pt.Normalized().Rotated90CW()*tri_size; - Vector2 tri_right = triangle_base_pt.Normalized().Rotated90CW()*tri_size; + Vector2 triangle_base_pt = goal->Point() + (direction*arrowhead_size); + + //J2D::DrawPoint(Colors::Yellow, triangle_base_pt, 4); + + Vector2 tri_left = triangle_base_pt + (direction.Rotated90CW() *arrowhead_size); + Vector2 tri_right = triangle_base_pt + (direction.Rotated90CCW()*arrowhead_size); Vector2 tri_top = goal->Point(); - J2D::DrawLine(line_color, tri_top, tri_left, line_size); - J2D::DrawLine(line_color, tri_top, tri_right, line_size); + J2D::DrawLine(color, tri_top, tri_left, arrowhead_size); + J2D::DrawLine(color, tri_top, tri_right, arrowhead_size); - J2D::FillTriangle(line_color, {tri_left, tri_right, tri_top}); } protected: + + float arrowhead_size; + float line_width; + Color4 color; + Anchor* origin; Anchor* goal; private: diff --git a/include/JUI/Widgets/FileDialog.hpp b/include/JUI/Widgets/FileDialog.hpp index ee686dc..66572ed 100644 --- a/include/JUI/Widgets/FileDialog.hpp +++ b/include/JUI/Widgets/FileDialog.hpp @@ -20,6 +20,7 @@ namespace JUI { class FileListing : public JUI::Widget { }; + // TODO: Implement SortBy enumeration - Date, Size, Name, Type class FileDialogWindow : public JUI::Window { public: @@ -27,6 +28,9 @@ namespace JUI Event<> UserConfirmed; Event<> UserCancelled; FileDialogWindow() : Window() { + + Title("File Dialog"); + auto* toolbar = new JUI::UtilityBar(this->Content()); auto* file_listing = new JUI::Rect(this->Content()); @@ -37,24 +41,60 @@ namespace JUI /// 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 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(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 = stringify(entry.status().permissions()); - std::string type = stringify(entry.status().type()); + std::string perms = format_perms(entry.status().permissions()); - auto file_size = (entry.is_directory() ? entry.file_size() : 0 ); + 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(), entry.file_size(), perms, entry.last_write_time(), type); + std::string label = std::format("{} {} {} {} {}", entry.path().filename().string(), file_size_str, entry_type, perms, timestamp); - rect->Content(entry.path().filename()); - - - if (entry.is_directory()) { - - } + rect->Content(label); return rect; } @@ -63,6 +103,13 @@ namespace JUI 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); @@ -77,6 +124,7 @@ namespace JUI protected: + int directories_indexed = 0; VerticalListLayout* file_layout; std::vector file_entry_widgets; private: diff --git a/main.cpp b/main.cpp index 22bfaf0..6bb6114 100644 --- a/main.cpp +++ b/main.cpp @@ -66,7 +66,7 @@ int count_descendants(JUI::Widget* w) { } void CreateFileDialog() { - auto* dialog = new JUI::FileDialogWindow(scene, "assets"); + auto* dialog = new JUI::FileDialogWindow(scene, "."); } /// Creates the window that provides a "Welcome" dialog to the user. @@ -180,7 +180,7 @@ JUI::UtilityBar* CreateUtilityBar(JUI::Widget* root) { } } - auto* ptA = new JUI::Anchor(topbar, {30_px, 20_px}); + auto* ptA = new JUI::Anchor(topbar, {30_px, 40_px}); auto* ptB = new JUI::Anchor(demos, UDim2::BottomRight);