diff --git a/meson.build b/meson.build index ea7c632..923eb96 100644 --- a/meson.build +++ b/meson.build @@ -9,6 +9,9 @@ librsvg_dep = dependency('librsvg-2.0') executable( 'filemanager', + './src/SvgWidget.cpp', + './src/FileButton.cpp', + './src/DirectoryView.cpp', './src/main.cpp', dependencies : [raven_dep, librsvg_dep] ) diff --git a/src/DirectoryView.cpp b/src/DirectoryView.cpp new file mode 100644 index 0000000..a092287 --- /dev/null +++ b/src/DirectoryView.cpp @@ -0,0 +1,30 @@ +#include "DirectoryView.hpp" +#include "src/Forward.hpp" + +DirectoryView::~DirectoryView() {} + +void DirectoryView::update() { + window()->start_batch(); + target()->clear_children(); + for (const auto &entry : std::filesystem::directory_iterator(m_current_path)) { + auto button = m_target->add(entry.path().filename(), this); + } + window()->end_batch(); +} + +void DirectoryView::navigate(std::string path) { + m_current_path = path; + update(); +} + +void DirectoryView::navigate_relative(std::string path) { + m_current_path /= path; + update(); +} + +void DirectoryView::on_init() { + m_target = make_target(); + m_target->set_layout(12.0); + update(); + set_did_init(true); +} diff --git a/src/DirectoryView.hpp b/src/DirectoryView.hpp new file mode 100644 index 0000000..f2daea5 --- /dev/null +++ b/src/DirectoryView.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include "raven/Widget.hpp" +#include "raven/ScrollContainer.hpp" +#include "raven/DocumentLayout.hpp" +#include "FileButton.hpp" + +class DirectoryView : public Raven::ScrollContainer { +public: + DirectoryView() + : Raven::ScrollContainer() {} + + ~DirectoryView(); + + void update(); + void navigate(std::string path); + void navigate_relative(std::string path); +protected: + void on_init(); +private: + std::filesystem::path m_current_path { "/" }; + std::shared_ptr m_target; +}; diff --git a/src/FileButton.cpp b/src/FileButton.cpp new file mode 100644 index 0000000..5990f45 --- /dev/null +++ b/src/FileButton.cpp @@ -0,0 +1,36 @@ +#include "FileButton.hpp" +#include "DirectoryView.hpp" + +Raven::GenericStyle FileButton::style = Raven::GenericStyle { + pango_font_description_from_string("sans-serif"), + Raven::black6, + Raven::white3, + Raven::white2, + Raven::white1, + 0.0, + true, + true +}; + +void FileButton::on_init() { + rect().set_width(96); + rect().set_height(118); + + set_style(&style); + + auto layout = set_layout(Raven::Direction::Vertical); + layout->slot_percent(100); // icon + layout->slot_pixel(24); // name (text) + + add("folder-adwaita.svg"); + auto label = add(m_name, Raven::PaintTextAlign::Center); + label->rect().set_max_width(rect().width()); + label->rect().set_max_height(24); + set_did_init(true); +} + +void FileButton::on_activation_update(Raven::ActivationUpdateEvent &event) { + if (event.activation_status() == false && m_directory_view) { + m_directory_view->navigate_relative(m_name); + } +} diff --git a/src/FileButton.hpp b/src/FileButton.hpp new file mode 100644 index 0000000..5fb42dd --- /dev/null +++ b/src/FileButton.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include "raven/Widget.hpp" +#include "raven/BoxLayout.hpp" +#include "raven/Label.hpp" +#include "Forward.hpp" +#include "SvgWidget.hpp" + + +class FileButton : public Raven::Widget { +public: + static Raven::GenericStyle style; +public: + FileButton(std::string name, DirectoryView* directory_view) + : Raven::Widget() + , m_directory_view(directory_view) + , m_name(name) {} + + std::string &name() { return m_name; } +protected: + void on_init(); + void on_activation_update(Raven::ActivationUpdateEvent &event); +private: + DirectoryView* m_directory_view; + std::string m_name; +}; diff --git a/src/Forward.hpp b/src/Forward.hpp new file mode 100644 index 0000000..25a3ae3 --- /dev/null +++ b/src/Forward.hpp @@ -0,0 +1,5 @@ +#pragma once + +class SvgWidget; +class FileButton; +class DirectoryView; diff --git a/src/SvgWidget.cpp b/src/SvgWidget.cpp new file mode 100644 index 0000000..0c3fe6f --- /dev/null +++ b/src/SvgWidget.cpp @@ -0,0 +1,32 @@ +#include "SvgWidget.hpp" + +void SvgWidget::on_init() { + m_file = g_file_new_for_path(m_path.c_str()); + m_handle = rsvg_handle_new_from_gfile_sync(m_file, RSVG_HANDLE_FLAGS_NONE, NULL, NULL); + + set_style(&Raven::clear_widget_style); + + if (!m_handle) + { + std::cerr << "could not load svg file: " << m_path << std::endl; + exit(EXIT_FAILURE); + } + + set_did_init(true); +} + +void SvgWidget::on_paint() { + RsvgRectangle viewport = { + .x = 0.0, + .y = 0.0, + .width = rect().width(), + .height = rect().height(), + }; + + rsvg_handle_render_document(m_handle, painter()->cairo()->cobj(), &viewport, NULL); +} + +SvgWidget::~SvgWidget() { + g_object_unref(m_file); + g_object_unref(m_handle); +} diff --git a/src/SvgWidget.hpp b/src/SvgWidget.hpp new file mode 100644 index 0000000..7eafbae --- /dev/null +++ b/src/SvgWidget.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include "raven/Widget.hpp" +#include "librsvg/rsvg.h" + + +class SvgWidget : public Raven::Widget { +public: + SvgWidget(std::string path) + : Raven::Widget() + , m_path(path) {} + + ~SvgWidget(); + + std::string &path() { return m_path; } + void set_path(std::string path) { m_path = path; repaint(); } +protected: + void on_init(); + void on_paint(); +private: + std::string m_path; + RsvgHandle *m_handle; + GFile *m_file; +}; diff --git a/src/main.cpp b/src/main.cpp index af30318..b813ec5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,165 +1,10 @@ -#include "GenericStyle.hpp" -#include "Painter.hpp" -#include "librsvg/rsvg.h" -#include "raven/Label.hpp" -#include "cairomm/refptr.h" -#include "cairomm/surface.h" -#include "raven/Window.hpp" -#include "raven/Widget.hpp" -#include "raven/Button.hpp" -#include "raven/Box.hpp" -#include "raven/Label.hpp" -#include "raven/Layout.hpp" -#include "raven/RGB.hpp" -#include "raven/DocumentLayout.hpp" -#include "raven/Events.hpp" -#include "raven/BoxLayout.hpp" -#include "raven/Box.hpp" -#include "raven/ScrollContainer.hpp" -#include "raven/Styles.hpp" -#include -#include -#include -#include -#include - -class SvgWidget : public Raven::Widget { -public: - SvgWidget(std::string path) - : Raven::Widget() - , m_path(path) {} - - ~SvgWidget() { - g_object_unref(m_file); - g_object_unref(m_handle); - } - - std::string &path() { return m_path; } - void set_path(std::string path) { m_path = path; repaint(); } -protected: - void on_init() { - m_file = g_file_new_for_path(m_path.c_str()); - m_handle = rsvg_handle_new_from_gfile_sync(m_file, RSVG_HANDLE_FLAGS_NONE, NULL, NULL); - - set_style(&Raven::clear_widget_style); - - if (!m_handle) - { - std::cerr << "could not load svg file: " << m_path << std::endl; - exit(EXIT_FAILURE); - } - - set_did_init(true); - } - - void on_paint() { - RsvgRectangle viewport = { - .x = 0.0, - .y = 0.0, - .width = rect().width(), - .height = rect().height(), - }; - - rsvg_handle_render_document(m_handle, painter()->cairo()->cobj(), &viewport, NULL); - } -private: - std::string m_path; - RsvgHandle *m_handle; - GFile *m_file; -}; - -class FileButton : public Raven::Widget { -public: - static Raven::GenericStyle style; -public: - FileButton(std::string name) - : Raven::Widget() - , m_name(name) {} - - std::function on_open { [](){} }; - - std::string &name() { return m_name; } -protected: - void on_init() { - rect().set_width(96); - rect().set_height(118); - - set_style(&style); - - auto layout = set_layout(Raven::Direction::Vertical); - layout->slot_percent(100); // icon - layout->slot_pixel(24); // name (text) - - add("folder-adwaita.svg"); - auto label = add(m_name, Raven::PaintTextAlign::Center); - label->rect().set_max_width(rect().width()); - label->rect().set_max_height(24); - set_did_init(true); - } - - void on_activation_update(Raven::ActivationUpdateEvent &event) { - if (event.activation_status() == false) { - on_open(); - } - } -private: - std::string m_name; -}; - -Raven::GenericStyle FileButton::style = Raven::GenericStyle { - pango_font_description_from_string("sans-serif"), - Raven::black6, - Raven::white3, - Raven::white2, - Raven::white1, - 0.0, - true, - true -}; - -class DirectoryView : public Raven::ScrollContainer { -public: - DirectoryView() - : Raven::ScrollContainer() {} - - void update() { - window()->start_batch(); - m_target->clear_children(); - for (const auto &entry : std::filesystem::directory_iterator(m_current_path)) { - auto button = m_target->add(entry.path().filename()); - button->on_open = [this, button]() { - navigate_relative(button->name()); - }; - } - window()->end_batch(); - } - - void navigate(std::string path) { - m_current_path = path; - update(); - } - - void navigate_relative(std::string path) { - m_current_path /= path; - update(); - } -protected: - void on_init() { - m_target = make_target(); - m_target->set_layout(12.0); - update(); - set_did_init(true); - } -private: - std::filesystem::path m_current_path { "/" }; - std::shared_ptr m_target; -}; +#include "DirectoryView.hpp" int main() { Raven::Window window {}; window.spawn_window(); - auto main_widget = window.set_main_widget(); + window.set_main_widget(); window.run(true); return 0;