bibliotheca_window.md 3.5 KB

BibliothecaWindow Module Overview

BibliothecaWindow is the top-level GTK window that stitches together the data model (BookList) and the UI widgets (BookShelf, search bar, placeholders). It owns the application chrome and orchestrates imports, filtering, and state transitions between empty / shelf / no-results views.

Responsibilities

  • Build the header bar (add button, search toggle) and main layout (Gtk::Box).
  • Manage the search UI (Gtk::SearchBar + Gtk::SearchEntry) and pipe queries to BookShelf::setFilter().
  • Host a Gtk::Stack that swaps between:
    • Empty library placeholder.
    • Library grid (BookShelf).
    • "No results" message when filtering yields nothing.
  • Handle "Add books" action: open a file dialog, import metadata/covers on a worker thread, and enqueue BookList::upsertMany().
  • Emit simple debug logging for activated books (placeholder behaviour for now).

Layout overview

Gtk::Window (BibliothecaWindow)
 └── Gtk::Box m_mainBox (vertical)
     ├── Gtk::SearchBar m_searchBar
     │    └── Gtk::SearchEntry m_searchEntry
     └── Gtk::Stack m_stack
          ├── Gtk::Box m_placeholder        // empty library
          ├── BookShelf (GridView)          // main shelf view
          └── Gtk::Box m_noResults          // "no match" placeholder

The header bar carries the add (+) button and a search toggle button that activates the search bar.

Event flow

  1. Startup: constructor calls buildHeaderBar(), buildPlaceholder(), creates the shelf, search widgets, and stack, then calls updateVisibleView() to pick the correct page based on the current library.
  2. Search:
    • Clicking the search toggle (or pressing Ctrl+F) toggles the Gtk::SearchBar.
    • Typing updates m_lastQuery, calls BookShelf::setFilter(), and refreshes the stack (showing “no results” if the filtered shelf is empty).
    • Leaving the search mode clears the entry.
  3. Importing books:
    • onAddBookClicked() opens Gtk::FileDialog::open_multiple().
    • Each selected file is processed on a background thread: compute SHA-256, call import_book_assets(), merge metadata, collect into a vector.
    • Once done, the vector is enqueued back onto the main loop via BookList::upsertMany(), and the UI refreshes.
  4. Activation: BookShelf::signalBookActivated() connects to BibliothecaWindow::onBookActivated(), which currently logs a placeholder message (can be extended to open a details pane or reader).

Signals & slots

BibliothecaWindow subscribes to the relevant BookList signals to call updateVisibleView() whenever the library changes. This keeps the stack in sync with imports, deletions, and resets without manual intervention.

Extension points

  • Actions on activation: replace the placeholder logging with navigation to a details page or opening the file.
  • Drag-and-drop import: wire a drop controller onto m_mainBox that reuses the existing import flow.
  • Search enhancements: add filters (e.g. tags, formats) or highlight matches inside the grid by extending BookShelf.

Expected usage

BibliothecaWindow is the root window instantiated in main.cpp. Other modules should construct it with an existing BookList:

auto window = Gtk::make_managed<BibliothecaWindow>(bookList);
app->add_window(*window);

The window takes ownership of the BookShelf widget and manages presentation according to the current state of the library and active search query.