[gtk/suggestion-entry] gtk-demo: Add suggestion entry demos



commit 20f2dcbe82e4b1a4ba37872a22b50d30cdc8e863
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jun 26 10:13:44 2020 -0400

    gtk-demo: Add suggestion entry demos
    
    Move the Dropdowns demo to Lists/Selections,
    and make it show both GtkDropDown and
    GtkSuggestionEntry, with some variations.

 demos/gtk-demo/dropdown.c  | 204 ++++++++++++++++++++++++++++++++++++++++-----
 demos/gtk-demo/meson.build |   2 +-
 2 files changed, 183 insertions(+), 23 deletions(-)
---
diff --git a/demos/gtk-demo/dropdown.c b/demos/gtk-demo/dropdown.c
index d90643e433..7a9ae281ff 100644
--- a/demos/gtk-demo/dropdown.c
+++ b/demos/gtk-demo/dropdown.c
@@ -1,13 +1,15 @@
-/* Drop Downs
+/* Lists/Selections
  *
- * The GtkDropDown widget is a modern alternative to GtkComboBox.
- * It uses list models instead of tree models, and the content is
- * displayed using widgets instead of cell renderers.
+ * The GtkDropDown and GtkSuggestionEntry widgets are modern
+ * alternatives to GtkComboBox and GtkEntryCompletion.
+ *
+ * They use list models instead of tree models, and the content
+ * is displayed using widgets instead of cell renderers.
  *
  * The examples here demonstrate how to use different kinds of
- * list models with GtkDropDown, how to use search and how to
- * display the selected item differently from the presentation
- * in the popup.
+ * list models with GtkDropDown and GtkSuggestionEntry, how to
+ * use search and how to display the selected item differently
+ * from the presentation in the popup.
  */
 
 #include <gtk/gtk.h>
@@ -218,13 +220,59 @@ get_title (gpointer item)
   return g_strdup (STRING_HOLDER (item)->title);
 }
 
+static char *
+get_file_name (gpointer item)
+{
+  return g_strdup (g_file_info_get_display_name (G_FILE_INFO (item)));
+}
+
+static void
+setup_item (GtkSignalListItemFactory *factory,
+            GtkListItem              *item)
+{
+  GtkWidget *box;
+  GtkWidget *icon;
+  GtkWidget *label;
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
+  icon = gtk_image_new ();
+  label = gtk_label_new ("");
+  gtk_label_set_xalign (GTK_LABEL (label), 0);
+  gtk_box_append (GTK_BOX (box), icon);
+  gtk_box_append (GTK_BOX (box), label);
+  gtk_list_item_set_child (item, box);
+}
+
+static void
+bind_item (GtkSignalListItemFactory *factory,
+           GtkListItem              *item)
+{
+  GFileInfo *info = G_FILE_INFO (gtk_list_item_get_item (item));
+  GtkWidget *box = gtk_list_item_get_child (item);
+  GtkWidget *icon = gtk_widget_get_first_child (box);
+  GtkWidget *label = gtk_widget_get_last_child (box);
+
+  gtk_image_set_from_gicon (GTK_IMAGE (icon), g_file_info_get_icon (info));
+  gtk_label_set_label (GTK_LABEL (label), g_file_info_get_display_name (info));
+}
+
+static void
+button_clicked (GtkButton *button,
+                GtkWidget *entry)
+{
+  gtk_widget_grab_focus (entry);
+  gtk_editable_set_position (GTK_EDITABLE (entry), -1);
+  gtk_widget_activate_action (entry, "popup.show", NULL);
+}
+
 GtkWidget *
 do_dropdown (GtkWidget *do_widget)
 {
   static GtkWidget *window = NULL;
-  GtkWidget *button, *box, *spin, *check;
+  GtkWidget *button, *box, *spin, *check, *hbox, *label, *entry;
   GListModel *model;
   GtkExpression *expression;
+  GtkListItemFactory *factory;
   const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
   const char * const many_times[] = {
     "1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
@@ -237,23 +285,78 @@ do_dropdown (GtkWidget *do_widget)
   const char * const device_descriptions[] = {
     "Built-in Audio", "Built-in audio", "Thinkpad Tunderbolt 3 Dock USB Audio", "Thinkpad Tunderbolt 3 Dock 
USB Audio", NULL
   };
+  const char *words[] = {
+    "GNOME",
+    "gnominious",
+    "Gnomonic projection",
+    "total",
+    "totally",
+    "toto",
+    "tottery",
+    "totterer",
+    "Totten trust",
+    "totipotent",
+    "totipotency",
+    "totemism",
+    "totem pole",
+    "Totara",
+    "totalizer",
+    "totalizator",
+    "totalitarianism",
+    "total parenteral nutrition",
+    "total hysterectomy",
+    "total eclipse",
+    "Totipresence",
+    "Totipalmi",
+    "Tomboy",
+    "zombie",
+    NULL
+  };
+
+  char *cwd;
+  GFile *file;
+  GListModel *dir;
 
   if (!window)
     {
       window = gtk_window_new ();
       gtk_window_set_display (GTK_WINDOW (window),
                               gtk_widget_get_display (do_widget));
-      gtk_window_set_title (GTK_WINDOW (window), "Drop Downs");
+      gtk_window_set_title (GTK_WINDOW (window), "Selections");
       gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
       g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
 
+      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 20);
+
+      gtk_widget_set_margin_start (hbox, 20);
+      gtk_widget_set_margin_end (hbox, 20);
+      gtk_widget_set_margin_top (hbox, 20);
+      gtk_widget_set_margin_bottom (hbox, 20);
+      gtk_window_set_child (GTK_WINDOW (window), hbox);
+
       box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
-      gtk_widget_set_margin_start (box, 10);
-      gtk_widget_set_margin_end (box, 10);
-      gtk_widget_set_margin_top (box, 10);
-      gtk_widget_set_margin_bottom (box, 10);
-      gtk_window_set_child (GTK_WINDOW (window), box);
+      gtk_box_append (GTK_BOX (hbox), box);
 
+      label = gtk_label_new ("Dropdowns");
+      gtk_widget_add_css_class (label, "title-4");
+      gtk_box_append (GTK_BOX (box), label);
+
+      /* A basic dropdown */
+      button = drop_down_new_from_strings (times, NULL, NULL);
+      gtk_box_append (GTK_BOX (box), button);
+
+      /* A dropdown using an expression to obtain strings */
+      button = drop_down_new_from_strings (many_times, NULL, NULL);
+      gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
+      expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
+                                                0, NULL,
+                                                (GCallback)get_title,
+                                                NULL, NULL);
+      gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
+      gtk_expression_unref (expression);
+      gtk_box_append (GTK_BOX (box), button);
+
+      /* A dropdown using a non-trivial model, and search */
       button = gtk_drop_down_new ();
 
       model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
@@ -270,30 +373,87 @@ do_dropdown (GtkWidget *do_widget)
 
       spin = gtk_spin_button_new_with_range (-1, g_list_model_get_n_items (G_LIST_MODEL (model)), 1);
       gtk_widget_set_halign (spin, GTK_ALIGN_START);
+      gtk_widget_set_margin_start (spin, 20);
       g_object_bind_property  (button, "selected", spin, "value", G_BINDING_SYNC_CREATE | 
G_BINDING_BIDIRECTIONAL);
       gtk_box_append (GTK_BOX (box), spin);
 
       check = gtk_check_button_new_with_label ("Enable search");
+      gtk_widget_set_margin_start (check, 20);
       g_object_bind_property  (button, "enable-search", check, "active", G_BINDING_SYNC_CREATE | 
G_BINDING_BIDIRECTIONAL);
       gtk_box_append (GTK_BOX (box), check);
 
       g_object_unref (model);
 
-      button = drop_down_new_from_strings (times, NULL, NULL);
+      /* A dropdown with a separate list factory */
+      button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
       gtk_box_append (GTK_BOX (box), button);
 
-      button = drop_down_new_from_strings (many_times, NULL, NULL);
-      gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
+      gtk_box_append (GTK_BOX (hbox), gtk_separator_new (GTK_ORIENTATION_VERTICAL));
+
+      box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
+      gtk_box_append (GTK_BOX (hbox), box);
+
+      label = gtk_label_new ("Suggestions");
+      gtk_widget_add_css_class (label, "title-4");
+      gtk_box_append (GTK_BOX (box), label);
+
+      /* A basic suggestion entry */
+      entry = gtk_suggestion_entry_new ();
+      g_object_set (entry, "placeholder-text", "Words with T or G…", NULL);
+      gtk_suggestion_entry_set_from_strings (GTK_SUGGESTION_ENTRY (entry), words);
+
+      gtk_box_append (GTK_BOX (box), entry);
+
+      check = gtk_check_button_new_with_label ("Auto-Insert");
+      gtk_widget_set_margin_start (check, 20);
+      g_object_bind_property  (entry, "insert-prefix", check, "active", G_BINDING_SYNC_CREATE | 
G_BINDING_BIDIRECTIONAL);
+      gtk_box_append (GTK_BOX (box), check);
+
+      check = gtk_check_button_new_with_label ("Auto-Select");
+      gtk_widget_set_margin_start (check, 20);
+      g_object_bind_property  (entry, "insert-selection", check, "active", G_BINDING_SYNC_CREATE | 
G_BINDING_BIDIRECTIONAL);
+      gtk_box_append (GTK_BOX (box), check);
+
+      /* A suggestion entry using a custom model, and no filtering */
+      entry = gtk_suggestion_entry_new ();
+
+      cwd = g_get_current_dir ();
+      file = g_file_new_for_path (cwd);
+      dir = G_LIST_MODEL (gtk_directory_list_new 
("standard::display-name,standard::content-type,standard::icon,standard::size", file));
+      gtk_suggestion_entry_set_model (GTK_SUGGESTION_ENTRY (entry), dir);
+      g_object_unref (dir);
+      g_object_unref (file);
+      g_free (cwd);
+
       expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
                                                 0, NULL,
-                                                (GCallback)get_title,
+                                                (GCallback)get_file_name,
                                                 NULL, NULL);
-      gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
+      gtk_suggestion_entry_set_expression (GTK_SUGGESTION_ENTRY (entry), expression);
       gtk_expression_unref (expression);
-      gtk_box_append (GTK_BOX (box), button);
 
-      button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
-      gtk_box_append (GTK_BOX (box), button);
+      factory = gtk_signal_list_item_factory_new ();
+      g_signal_connect (factory, "setup", G_CALLBACK (setup_item), NULL);
+      g_signal_connect (factory, "bind", G_CALLBACK (bind_item), NULL);
+
+      gtk_suggestion_entry_set_factory (GTK_SUGGESTION_ENTRY (entry), factory);
+      g_object_unref (factory);
+
+      gtk_suggestion_entry_set_use_filter (GTK_SUGGESTION_ENTRY (entry), FALSE);
+      gtk_suggestion_entry_set_insert_selection (GTK_SUGGESTION_ENTRY (entry), TRUE);
+
+      gtk_widget_set_hexpand (entry, TRUE);
+
+      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+      gtk_widget_add_css_class (hbox, "linked");
+      gtk_box_append (GTK_BOX (hbox), entry);
+
+      button = gtk_button_new_from_icon_name ("pan-down-symbolic");
+      gtk_widget_set_focus_on_click (button, FALSE);
+      g_signal_connect (button, "clicked", G_CALLBACK (button_clicked), entry);
+      gtk_box_append (GTK_BOX (hbox), button);
+
+      gtk_box_append (GTK_BOX (box), hbox);
     }
 
   if (!gtk_widget_get_visible (window))
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index eb6513591b..47a4b5bf0c 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -18,7 +18,6 @@ demos = files([
   'cursors.c',
   'dialog.c',
   'drawingarea.c',
-  'dropdown.c',
   'dnd.c',
   'editable_cells.c',
   'entry_completion.c',
@@ -47,6 +46,7 @@ demos = files([
   'listview_colors.c',
   'listview_filebrowser.c',
   'listview_minesweeper.c',
+  'dropdown.c',
   'listview_settings.c',
   'listview_weather.c',
   'markup.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]