#pragma once #include "BookList.hpp" #include "BookTile.hpp" #include #include #include #include #include #include #include /** * @brief GridView-based widget that renders and filters the user's library. * * BookShelf mirrors the books held in @ref BookList into a Gio::ListStore, * drives a @ref Gtk::GridView factory to build @ref BookTile instances, * and exposes a fuzzy filtering API plus activation signal for the rest * of the UI. */ class BookShelf : public Gtk::ScrolledWindow { public: explicit BookShelf(BookList& bookList, int coverSize = 128); // force rebuild (e.g., on reset) /// Recompute the visible grid contents from the backing model. void reload(); // signal when a tile is activated (double-clicked) sigc::signal& signalBookActivated() { return m_signalBookActivated; } // signal when selection changes sigc::signal& signalSelectionChanged() { return m_signalSelectionChanged; } /// Apply a fuzzy search query (empty string restores the full collection). void setFilter(const std::string& query); const std::string& filter() const noexcept { return m_filter; } bool empty() const noexcept; /// Get the currently selected book (first if multiple), if any std::optional getSelectedBook() const; /// Get all selected books std::vector getSelectedBooks() const; /// Get count of selected books std::size_t getSelectionCount() const; /// Clear the current selection void clearSelection(); /// Select all visible books void selectAll(); private: // signal handlers void onBookAdded(const Book& b); void onBookUpdated(const Book& b); void onBookRemoved(const std::string& id); void onReset(); // helpers void addTile(const Book&); void updateTile(const Book&); void removeTile(const std::string&); void onFactorySetup(const Glib::RefPtr& item); void onFactoryBind(const Glib::RefPtr& item); void onFactoryUnbind(const Glib::RefPtr& item); void refreshVisible(); class BookObject; BookList& m_bookList; int m_coverSize = 128; Glib::RefPtr> m_store; Glib::RefPtr m_selection; Gtk::GridView m_grid; Glib::RefPtr m_backgroundClick; std::string m_filter; sigc::signal m_signalBookActivated; sigc::signal m_signalSelectionChanged; };