# BibliothecaWindow Module Overview `BibliothecaWindow` is the top-level GTK window that stitches together the data model (`BookList`) and the UI widgets (`BookShelf`, `BookDetails`, search bar, placeholders). It owns the application chrome and orchestrates imports, filtering, and state transitions between empty / shelf / no-results / details views. ## Responsibilities - Build the header bar (add button, back button, search toggle) and main layout. - 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. - Book details view (`BookDetails`). - Handle "Add books" action: open a file dialog, import metadata/covers on a worker thread, detect duplicates, and enqueue `BookList::upsertMany()`. - Show toast notifications for import results and errors. - Navigate to `BookDetails` when a book is activated. - Handle keyboard navigation (Enter, Escape, Backspace). ## Layout overview ``` Gtk::Window (BibliothecaWindow) └── Gtk::Box m_mainBox (vertical) ├── Gtk::SearchBar m_searchBar │ └── Gtk::SearchEntry m_searchEntry └── Gtk::Overlay m_overlay ├── Gtk::Stack m_stack │ ├── Gtk::Box m_placeholder // empty library │ ├── BookShelf (GridView) // main shelf view │ ├── Gtk::Box m_noResults // "no match" placeholder │ └── BookDetails // book details view └── Gtk::Revealer m_toastRevealer // toast notification overlay └── Gtk::Box m_toastBox ├── Gtk::Label m_toastLabel └── Gtk::Button m_toastCloseButton ``` The header bar carries: - Add (+) button to import books - Back button (visible on details view) - Search toggle button that activates the search bar ## Event flow 1. **Startup**: constructor calls `buildHeaderBar()`, `buildPlaceholder()`, `buildToast()`, creates the shelf and details widgets, search widgets, and stack, then calls `updateVisibleView()` to pick the correct page. 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). - Search query is preserved when navigating to details and restored on return. - Leaving the search mode clears the entry (only on shelf/noresults views). 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. - Duplicates are detected by matching SHA-256 hash against existing books. - Once done, the vector is enqueued back onto the main loop via `BookList::upsertMany()`, and the UI refreshes. - Toast notifications show import results ("Added N books", "N duplicates"). 4. **Activation**: `BookShelf::signalBookActivated()` connects to `BibliothecaWindow::onBookActivated()`, which navigates to the `BookDetails` view for the selected book. 5. **Keyboard navigation**: - Enter/Return: Open selected book from shelf view. - Escape: Go back from details, close search bar, or clear selection. - Backspace: Go back from details view. ## 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. It also subscribes to `BookDetails::signalBookRemoved()` to navigate back to the shelf when the currently displayed book is deleted. ## Toast notifications The toast system uses a `Gtk::Revealer` overlay to show temporary messages: - Success messages (green styling) for successful imports. - Error messages (red styling) for failed imports. - Mixed messages when some imports succeed and others fail. - Auto-hide after 4 seconds with manual close button. ## Extension points - **Drag-and-drop import**: wire a drop controller onto `m_mainBox` that reuses the existing import flow. - **Search enhancements**: add tag chips as quick filters in the search UI. - **Loading indicator**: add spinner during import operations. ## Expected usage `BibliothecaWindow` is the root window instantiated in `main.cpp`. Other modules should construct it with an existing `DatabaseManager` and `BookList`: ```cpp auto window = Gtk::make_managed(db, bookList); app->add_window(*window); ``` The window takes ownership of the `BookShelf` and `BookDetails` widgets and manages presentation according to the current state of the library and active search query.