# 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`: ```cpp auto window = Gtk::make_managed(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.