[gtk/emoji-grid: 15/16] gtk-demo: Add a sectioned grid
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/emoji-grid: 15/16] gtk-demo: Add a sectioned grid
- Date: Mon, 28 Feb 2022 23:38:13 +0000 (UTC)
commit 8690ca4a6581a32c3b77f05f9729fad3f5d54010
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Feb 25 21:21:14 2022 -0500
gtk-demo: Add a sectioned grid
demos/gtk-demo/demo.gresource.xml | 1 +
demos/gtk-demo/listview_emoji.c | 216 ++++++++++++++++++++++++++++++++++++++
demos/gtk-demo/meson.build | 1 +
3 files changed, 218 insertions(+)
---
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index 5cb524328f..11fceb3aa4 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -303,6 +303,7 @@
<file>listview_applauncher.c</file>
<file>listview_colors.c</file>
<file>listview_clocks.c</file>
+ <file>listview_emoji.c</file>
<file>listview_filebrowser.c</file>
<file>listview_minesweeper.c</file>
<file>listview_objects.c</file>
diff --git a/demos/gtk-demo/listview_emoji.c b/demos/gtk-demo/listview_emoji.c
new file mode 100644
index 0000000000..c8f77b07f8
--- /dev/null
+++ b/demos/gtk-demo/listview_emoji.c
@@ -0,0 +1,216 @@
+/* Lists/Emoji
+ * #Keywords: GtkListItemFactory, GtkGridView
+ *
+ * This demo uses the GtkGridView widget to show Emoji.
+ *
+ * It shows how to use sections in GtkGridView
+ */
+
+#include <gtk/gtk.h>
+
+static char *
+get_section (GtkEmojiObject *object)
+{
+ switch (gtk_emoji_object_get_group (object))
+ {
+ case GTK_EMOJI_GROUP_RECENT: return g_strdup ("Recent");
+ case GTK_EMOJI_GROUP_SMILEYS: return g_strdup ("Smileys");
+ case GTK_EMOJI_GROUP_BODY: return g_strdup ("People");
+ case GTK_EMOJI_GROUP_COMPONENT: return g_strdup ("Components");
+ case GTK_EMOJI_GROUP_NATURE: return g_strdup ("Nature");
+ case GTK_EMOJI_GROUP_FOOD: return g_strdup ("Food");
+ case GTK_EMOJI_GROUP_PLACES: return g_strdup ("Places");
+ case GTK_EMOJI_GROUP_ACTIVITIES: return g_strdup ("Activities");
+ case GTK_EMOJI_GROUP_OBJECTS: return g_strdup ("Objects");
+ case GTK_EMOJI_GROUP_SYMBOLS: return g_strdup ("Symbols");
+ case GTK_EMOJI_GROUP_FLAGS: return g_strdup ("Flags");
+ default: return g_strdup ("Something else");
+ }
+}
+
+static void
+setup_section_listitem_cb (GtkListItemFactory *factory,
+ GtkListItem *list_item)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new ("");
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_widget_add_css_class (label, "heading");
+ gtk_widget_set_margin_top (label, 4);
+ gtk_widget_set_margin_bottom (label, 4);
+ gtk_list_item_set_child (list_item, label);
+}
+
+static void
+bind_section_listitem_cb (GtkListItemFactory *factory,
+ GtkListItem *list_item)
+{
+ GtkWidget *label;
+ GtkEmojiObject *item;
+ char *text;
+
+ label = gtk_list_item_get_child (list_item);
+ item = gtk_list_item_get_item (list_item);
+
+ text = get_section (item);
+ gtk_label_set_label (GTK_LABEL (label), text);
+ g_free (text);
+}
+
+static void
+setup_listitem_cb (GtkListItemFactory *factory,
+ GtkListItem *list_item)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new ("");
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_list_item_set_child (list_item, label);
+}
+
+static void
+bind_listitem_cb (GtkListItemFactory *factory,
+ GtkListItem *list_item)
+{
+ GtkWidget *label;
+ GtkEmojiObject *item;
+ char buffer[64];
+ PangoAttrList *attrs;
+
+ label = gtk_list_item_get_child (list_item);
+ item = gtk_list_item_get_item (list_item);
+
+ gtk_emoji_object_get_text (item, buffer, sizeof (buffer), 0);
+ gtk_label_set_label (GTK_LABEL (label), buffer);
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_X_LARGE));
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
+ pango_attr_list_unref (attrs);
+}
+
+static gboolean
+match_tokens (const char **term_tokens,
+ const char **hit_tokens)
+{
+ int i, j;
+ gboolean matched;
+
+ matched = TRUE;
+
+ for (i = 0; term_tokens[i]; i++)
+ {
+ for (j = 0; hit_tokens[j]; j++)
+ if (g_str_has_prefix (hit_tokens[j], term_tokens[i]))
+ goto one_matched;
+
+ matched = FALSE;
+ break;
+
+one_matched:
+ continue;
+ }
+
+ return matched;
+}
+
+static gboolean
+filter_func (gpointer item,
+ gpointer user_data)
+{
+ GtkEmojiObject *emoji = item;
+ GtkWidget *entry = user_data;
+ const char *text;
+ const char *name;
+ const char **keywords;
+ char **term_tokens;
+ char **name_tokens;
+ gboolean res;
+
+ text = gtk_editable_get_text (GTK_EDITABLE (entry));
+ if (text[0] == 0)
+ return TRUE;
+
+ name = gtk_emoji_object_get_name (emoji);
+ keywords = gtk_emoji_object_get_keywords (emoji);
+
+ term_tokens = g_str_tokenize_and_fold (text, "en", NULL);
+ name_tokens = g_str_tokenize_and_fold (name, "en", NULL);
+
+ res = match_tokens ((const char **)term_tokens, (const char **)name_tokens) ||
+ match_tokens ((const char **)term_tokens, keywords);
+
+ g_strfreev (term_tokens);
+ g_strfreev (name_tokens);
+
+ return res;
+}
+
+static void
+search_changed (GtkEntry *entry,
+ gpointer data)
+{
+ GtkFilter *filter = data;
+
+ gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
+}
+
+static GtkWidget *window = NULL;
+
+GtkWidget *
+do_listview_emoji (GtkWidget *do_widget)
+{
+ if (window == NULL)
+ {
+ GtkWidget *list, *sw;
+ GListModel *model;
+ GtkListItemFactory *factory;
+ GtkWidget *box, *entry;
+ GtkFilter *filter;
+
+ /* Create a window and set a few defaults */
+ window = gtk_window_new ();
+ gtk_window_set_default_size (GTK_WINDOW (window), 300, 400);
+ gtk_window_set_display (GTK_WINDOW (window),
+ gtk_widget_get_display (do_widget));
+ gtk_window_set_title (GTK_WINDOW (window), "Emoji");
+ g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
+
+ factory = gtk_signal_list_item_factory_new ();
+ g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
+ g_signal_connect (factory, "bind", G_CALLBACK (bind_listitem_cb), NULL);
+
+ entry = gtk_search_entry_new ();
+
+ model = G_LIST_MODEL (gtk_emoji_list_new ());
+ filter = GTK_FILTER (gtk_custom_filter_new (filter_func, entry, NULL));
+ model = G_LIST_MODEL (gtk_filter_list_model_new (model, filter));
+
+ g_signal_connect (entry, "search-changed", G_CALLBACK (search_changed), filter);
+
+ list = gtk_grid_view_new (GTK_SELECTION_MODEL (gtk_no_selection_new (model)), factory);
+ gtk_grid_view_set_max_columns (GTK_GRID_VIEW (list), 20);
+
+ factory = gtk_signal_list_item_factory_new ();
+ g_signal_connect (factory, "setup", G_CALLBACK (setup_section_listitem_cb), NULL);
+ g_signal_connect (factory, "bind", G_CALLBACK (bind_section_listitem_cb), NULL);
+ gtk_grid_view_set_section_factory (GTK_GRID_VIEW (list), factory);
+ g_object_unref (factory);
+
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_box_append (GTK_BOX (box), entry);
+ sw = gtk_scrolled_window_new ();
+ gtk_widget_set_hexpand (sw, TRUE);
+ gtk_widget_set_vexpand (sw, TRUE);
+ gtk_box_append (GTK_BOX (box), sw);
+ gtk_window_set_child (GTK_WINDOW (window), box);
+ gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), list);
+ }
+
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+ else
+ gtk_window_destroy (GTK_WINDOW (window));
+
+ return window;
+}
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index cc18609f77..b7db366998 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -52,6 +52,7 @@ demos = files([
'listview_applauncher.c',
'listview_clocks.c',
'listview_colors.c',
+ 'listview_emoji.c',
'listview_filebrowser.c',
'listview_minesweeper.c',
'listview_objects.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]