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.
Gtk::SearchBar + Gtk::SearchEntry) and pipe queries
to BookShelf::setFilter().Gtk::Stack that swaps between:
BookShelf).BookDetails).BookList::upsertMany().BookDetails when a book is activated.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:
buildHeaderBar(), buildPlaceholder(),
buildToast(), creates the shelf and details widgets, search widgets, and
stack, then calls updateVisibleView() to pick the correct page.Gtk::SearchBar.m_lastQuery, calls BookShelf::setFilter(), and refreshes
the stack (showing "no results" if the filtered shelf is empty).onAddBookClicked() opens Gtk::FileDialog::open_multiple().import_book_assets(), merge metadata, collect into a vector.BookList::upsertMany(), and the UI refreshes.BookShelf::signalBookActivated() connects to
BibliothecaWindow::onBookActivated(), which navigates to the BookDetails
view for the selected book.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.
The toast system uses a Gtk::Revealer overlay to show temporary messages:
m_mainBox that reuses
the existing import flow.BibliothecaWindow is the root window instantiated in main.cpp. Other modules
should construct it with an existing DatabaseManager and BookList:
auto window = Gtk::make_managed<BibliothecaWindow>(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.