I’m currently working with the C++ API of GTK, and I’m stuck on how to re-apply (or “redo”, or “update”) a Gtk::Filter
in my code.
Basic description of the application
I have a page in my application that displays a “catalog of images”. These images are presented in a “grid of thumbnails”. Each thumbnail in this grid is just a smaller version of image, together with some stars (which is the “rating of that image”). In other words, the user that is using the application might rate a particular image in the catalog with 5 stars (indicating that he/she likes that image very much), or, the user might rate it with just 1 star, or, zero stars, etc.
On the top corner of the window, there is a dropdown in which the user can one or multiple “number of stars” that he would like to use to filter the images in the catalog. So, if the user selects 1 in the dropdown, then, the application should display only the images with rating of “1 star” in the grid. But, if the user selects the options 1, 2 and 4 in the dropdown, then, only images with rating of “1, 2 or 4 stars” should be displayed in the grid. Etc.
Description of the code
This page of the application is represented by the LibraryPage
class, which contains a Gio::ListStore
of “thumbnail objects” called ThumbnailGridViewItem
(which is a class that inherits from Glib::GObject
). I use this Gio::ListStore
in a Gtk::GridView
to present these “thumbnail objects” in a grid format.
This Gio::ListStore
is connected to a Gtk::FilterListModel
which is used to “filter the thumbnails” that are in this Gio::ListStore
using a Gtk::BoolFilter
. So, this Gtk::BoolFilter
is the “core” of the filter. I know that the Gtk::BoolFilter
class have a signal_changed()
signal which is normally emitted when the filter changes, but I have no idea on how to emit this signal to force the filter to re-apply it’s match()
function over the ThumbnailGridViewItem
items of the Giio::ListStore
.
The Gtk::BoolFilter
is created with a Gtk::ClosureExpression
, which calls a method from the LibraryPage
named does_thumbnail_star_match_filter()
.
auto expression = Gtk::ClosureExpression<bool>::create(
sigc::mem_fun(*this, &LibraryPage::does_thumbnail_star_match_filter)
);
m_stars_filter = Gtk::BoolFilter::create(expression);
In my understanding, this method is the match()
function used by the Gtk::BoolFilter
to filter the thumbnails. This function is exposed below:
bool LibraryPage::does_thumbnail_star_match_filter(const Glib::RefPtr<Glib::ObjectBase>& item) {
m_logger.info("Checking if thumbnail star index match");
Glib::RefPtr<ThumbnailGridViewItem> thumb = std::dynamic_pointer_cast<ThumbnailGridViewItem>(item);
if (!thumb)
return false;
if (m_stars_currently_active.size() == 0) {
m_logger.info("No star option active, no need to filter.");
return true;
}
for (int index: m_stars_currently_active) {
if (thumb->m_stars == index) {
m_logger.info("Thumbnail star index match!");
return true;
}
}
return false;
}
All that this function does is to check if the “star rating” given to the thumbnail (which is a int
value stored in the m_stars
variable) matches any of the “star options that are currently active in the dropdown of the page”. In other words, the LibraryPage
class keeps track of all “star options” that the user selected in the dropdown through a std::vector<int>
object, which is stored in the m_stars_currently_active
variable.
So in order to know if a particular thumbnail matches the “star filter” that the user selected in the application, this function needs to iterate through the elements of m_stars_currently_active
and check if any of them matches the star rating of the current thumbnail.
My question
How can I force the Gtk::FilterListModel
to re-apply the filter over the thumbnails in the Gio::ListStore
everytime that the user selects a different option in the dropdown?
Some snippets of the mentioned classes
class LibraryPage: {
public:
/** Scrolled window where the thumbnails are displayed */
Gtk::ScrolledWindow m_scroll_window;
/** Grid view with the thumbnails presented at scroll window */
Gtk::GridView m_gridview;
/** Selection model for the view */
Glib::RefPtr<Gtk::MultiSelection> m_multi_selection_model;
/** Item factory for the grid view */
Glib::RefPtr<Gtk::SignalListItemFactory> m_thumbnail_factory;
/** Thumbnail store for the grid view. */
Glib::RefPtr<Gio::ListStore<ThumbnailGridViewItem>> m_thumbnail_store;
/** Expression used by the stars dropdown filter */
Glib::RefPtr<Gtk::BoolFilter> m_stars_filter;
/** Filter model for the view */
Glib::RefPtr<Gtk::FilterListModel> m_filter_model;
/** List of stars that are currently active */
std::vector<int> m_stars_currently_active;
/** The "match" function used by the Gtk::BoolFilter */
bool does_thumbnail_star_match_filter(const Glib::RefPtr<Glib::ObjectBase>& item);
};
class ThumbnailGridViewItem: public Glib::Object {
/** The number of stars associated with this thumbnail */
int m_stars;
};
Thank you for your attention!