[gnome-photos] base-model, dropdown: Port to GMenuModel



commit c8d6651218c1419c776e2b9d00e1203d3f46787f
Author: Alessandro Bono <shadow openaliasbox org>
Date:   Tue Mar 31 20:03:55 2015 +0200

    base-model, dropdown: Port to GMenuModel
    
    Now that we have GActions for search options, tie it all together and
    use them to build the popover contents. We have to steal the child of a
    GtkPopover to get the UI, since GTK doesn't expose a public API for
    that yet.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=726462

 src/Makefile.am                 |    2 -
 src/photos-base-model.c         |  109 +++++++++++----
 src/photos-base-model.h         |   17 +--
 src/photos-base-view.c          |  275 ---------------------------------------
 src/photos-base-view.h          |   77 -----------
 src/photos-dropdown.c           |   53 ++++++--
 src/photos-overview-searchbar.c |    2 +-
 7 files changed, 127 insertions(+), 408 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 64115f5..7c0538c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -74,8 +74,6 @@ gnome_photos_SOURCES = \
        photos-base-model.h \
        photos-base-item.c \
        photos-base-item.h \
-       photos-base-view.c \
-       photos-base-view.h \
        photos-camera-cache.c \
        photos-camera-cache.h \
        photos-collection-icon-watcher.c \
diff --git a/src/photos-base-model.c b/src/photos-base-model.c
index a731f6e..016298a 100644
--- a/src/photos-base-model.c
+++ b/src/photos-base-model.c
@@ -1,5 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
+ * Copyright © 2015 Alessandro Bono
  * Copyright © 2014 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
@@ -28,10 +29,12 @@
 #include <glib.h>
 
 #include "photos-base-model.h"
+#include "photos-filterable.h"
 
 
 struct _PhotosBaseModelPrivate
 {
+  GMenu *model;
   PhotosBaseManager *mngr;
 };
 
@@ -42,7 +45,34 @@ enum
 };
 
 
-G_DEFINE_TYPE_WITH_PRIVATE (PhotosBaseModel, photos_base_model, GTK_TYPE_LIST_STORE);
+G_DEFINE_TYPE_WITH_PRIVATE (PhotosBaseModel, photos_base_model, G_TYPE_OBJECT);
+
+
+static void
+photos_base_model_action_state_changed (PhotosBaseModel *self, const gchar *action_name, GVariant *value)
+{
+  const gchar *id;
+
+  id = g_variant_get_string (value, NULL);
+  photos_base_manager_set_active_object_by_id (self->priv->mngr, id);
+}
+
+
+static void
+photos_base_model_active_changed (PhotosBaseModel *self, GObject *active_object)
+{
+  PhotosBaseModelPrivate *priv = self->priv;
+  GApplication *app;
+  GVariant *state;
+  const gchar *action_id;
+  const gchar *id;
+
+  app = g_application_get_default ();
+  action_id = photos_base_manager_get_action_id (priv->mngr);
+  id = photos_filterable_get_id (PHOTOS_FILTERABLE (active_object));
+  state = g_variant_new ("s", id);
+  g_action_group_change_action_state (G_ACTION_GROUP (app), action_id, state);
+}
 
 
 static void
@@ -51,43 +81,40 @@ photos_base_model_refresh (PhotosBaseModel *self)
   PhotosBaseModelPrivate *priv = self->priv;
   GHashTable *objects;
   GHashTableIter hash_iter;
+  GMenu *section;
   GObject *object;
-  GtkTreeIter model_iter;
+  const gchar *action_id;
   const gchar *id;
   const gchar *title;
 
-  gtk_list_store_clear (GTK_LIST_STORE (self));
+  g_menu_remove_all (priv->model);
 
   title = photos_base_manager_get_title (priv->mngr);
-  if (title != NULL)
-    {
-      gtk_list_store_append (GTK_LIST_STORE (self), &model_iter);
-      gtk_list_store_set (GTK_LIST_STORE (self),
-                          &model_iter,
-                          PHOTOS_BASE_MODEL_ID, "heading",
-                          PHOTOS_BASE_MODEL_NAME, "",
-                          PHOTOS_BASE_MODEL_HEADING_TEXT, title,
-                          -1);
-    }
+  action_id = photos_base_manager_get_action_id (priv->mngr);
+
+  section = g_menu_new ();
+  g_menu_append_section (priv->model, title, G_MENU_MODEL (section));
 
   objects = photos_base_manager_get_objects (priv->mngr);
 
   g_hash_table_iter_init (&hash_iter, objects);
   while (g_hash_table_iter_next (&hash_iter, (gpointer *) &id, (gpointer *) &object))
     {
+      GMenuItem *menu_item;
+      GVariant *target_value;
       gchar *name;
 
-      gtk_list_store_append (GTK_LIST_STORE (self), &model_iter);
-
       g_object_get (object, "name", &name, NULL);
-      gtk_list_store_set (GTK_LIST_STORE (self),
-                          &model_iter,
-                          PHOTOS_BASE_MODEL_ID, id,
-                          PHOTOS_BASE_MODEL_NAME, name,
-                          PHOTOS_BASE_MODEL_HEADING_TEXT, "",
-                          -1);
+
+      menu_item = g_menu_item_new (name, NULL);
+      target_value = g_variant_new ("s", id);
+      g_menu_item_set_action_and_target_value (menu_item, action_id, target_value);
+      g_menu_append_item (section, menu_item);
+
       g_free (name);
     }
+
+  g_object_unref (section);
 }
 
 
@@ -96,9 +123,14 @@ photos_base_model_constructed (GObject *object)
 {
   PhotosBaseModel *self = PHOTOS_BASE_MODEL (object);
   PhotosBaseModelPrivate *priv = self->priv;
+  GApplication *app;
+  const gchar *action_id;
+  gchar *detailed_signal;
 
   G_OBJECT_CLASS (photos_base_model_parent_class)->constructed (object);
 
+  priv->model = g_menu_new ();
+
   g_signal_connect_object (priv->mngr,
                            "object-added",
                            G_CALLBACK (photos_base_model_refresh),
@@ -110,6 +142,22 @@ photos_base_model_constructed (GObject *object)
                            self,
                            G_CONNECT_SWAPPED);
 
+  app = g_application_get_default ();
+  action_id = photos_base_manager_get_action_id (priv->mngr);
+  detailed_signal = g_strconcat ("action-state-changed::", action_id, NULL);
+  g_signal_connect_object (app,
+                           detailed_signal,
+                           G_CALLBACK (photos_base_model_action_state_changed),
+                           self,
+                           G_CONNECT_SWAPPED);
+  g_free (detailed_signal);
+
+  g_signal_connect_object (priv->mngr,
+                           "active-changed",
+                           G_CALLBACK (photos_base_model_active_changed),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   photos_base_model_refresh (self);
 }
 
@@ -118,8 +166,10 @@ static void
 photos_base_model_dispose (GObject *object)
 {
   PhotosBaseModel *self = PHOTOS_BASE_MODEL (object);
+  PhotosBaseModelPrivate *priv = self->priv;
 
-  g_clear_object (&self->priv->mngr);
+  g_clear_object (&priv->model);
+  g_clear_object (&priv->mngr);
 
   G_OBJECT_CLASS (photos_base_model_parent_class)->dispose (object);
 }
@@ -146,13 +196,7 @@ photos_base_model_set_property (GObject *object, guint prop_id, const GValue *va
 static void
 photos_base_model_init (PhotosBaseModel *self)
 {
-  GType columns[] = {G_TYPE_STRING,    /* ID */
-                     G_TYPE_STRING,    /* NAME */
-                     G_TYPE_STRING};   /* HEADING TEXT */
-
   self->priv = photos_base_model_get_instance_private (self);
-
-  gtk_list_store_set_column_types (GTK_LIST_STORE (self), sizeof (columns) / sizeof (columns[0]), columns);
 }
 
 
@@ -175,8 +219,15 @@ photos_base_model_class_init (PhotosBaseModelClass *class)
 }
 
 
-GtkListStore *
+PhotosBaseModel *
 photos_base_model_new (PhotosBaseManager *mngr)
 {
   return g_object_new (PHOTOS_TYPE_BASE_MODEL, "manager", mngr, NULL);
 }
+
+
+GMenu *
+photos_base_model_get_model (PhotosBaseModel *self)
+{
+  return self->priv->model;
+}
diff --git a/src/photos-base-model.h b/src/photos-base-model.h
index ed478f7..3a0003e 100644
--- a/src/photos-base-model.h
+++ b/src/photos-base-model.h
@@ -25,7 +25,7 @@
 #ifndef PHOTOS_BASE_MODEL_H
 #define PHOTOS_BASE_MODEL_H
 
-#include <gtk/gtk.h>
+#include <gio/gio.h>
 
 #include "photos-base-manager.h"
 
@@ -53,31 +53,26 @@ G_BEGIN_DECLS
   (G_TYPE_INSTANCE_GET_CLASS ((obj), \
    PHOTOS_TYPE_BASE_MODEL, PhotosBaseModelClass))
 
-typedef enum
-{
-  PHOTOS_BASE_MODEL_ID,
-  PHOTOS_BASE_MODEL_NAME,
-  PHOTOS_BASE_MODEL_HEADING_TEXT
-} PhotosBaseModelColumns;
-
 typedef struct _PhotosBaseModel        PhotosBaseModel;
 typedef struct _PhotosBaseModelClass   PhotosBaseModelClass;
 typedef struct _PhotosBaseModelPrivate PhotosBaseModelPrivate;
 
 struct _PhotosBaseModel
 {
-  GtkListStore parent_instance;
+  GObject parent_instance;
   PhotosBaseModelPrivate *priv;
 };
 
 struct _PhotosBaseModelClass
 {
-  GtkListStoreClass parent_class;
+  GObjectClass parent_class;
 };
 
 GType             photos_base_model_get_type               (void) G_GNUC_CONST;
 
-GtkListStore     *photos_base_model_new                    (PhotosBaseManager *mngr);
+PhotosBaseModel  *photos_base_model_new                    (PhotosBaseManager *mngr);
+
+GMenu            *photos_base_model_get_model              (PhotosBaseModel *self);
 
 G_END_DECLS
 
diff --git a/src/photos-dropdown.c b/src/photos-dropdown.c
index b45326c..b3df97c 100644
--- a/src/photos-dropdown.c
+++ b/src/photos-dropdown.c
@@ -1,5 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
+ * Copyright © 2015 Alessandro Bono
  * Copyright © 2014 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
@@ -26,14 +27,17 @@
 #include "config.h"
 
 #include <gio/gio.h>
+#include <glib.h>
 
-#include "photos-base-view.h"
+#include "photos-base-manager.h"
+#include "photos-base-model.h"
 #include "photos-dropdown.h"
 #include "photos-search-context.h"
 
 
 struct _PhotosDropdownPrivate
 {
+  GList *models;
   GtkWidget *grid;
   GtkWidget *match_view;
   GtkWidget *source_view;
@@ -48,6 +52,34 @@ G_DEFINE_TYPE_WITH_PRIVATE (PhotosDropdown, photos_dropdown, GTK_TYPE_POPOVER);
 
 
 static void
+photos_dropdown_add_manager (PhotosDropdown *self, PhotosBaseManager *mngr)
+{
+  PhotosDropdownPrivate *priv = self->priv;
+  GMenu *menu;
+  GtkWidget *popover;
+  GtkWidget *w;
+  PhotosBaseModel *model;
+
+  model = photos_base_model_new (mngr);
+  priv->models = g_list_prepend (priv->models, g_object_ref (model));
+
+  /* HACK: see https://bugzilla.gnome.org/show_bug.cgi?id=733977 */
+  popover = gtk_popover_new (NULL);
+  menu = photos_base_model_get_model (model);
+  gtk_popover_bind_model (GTK_POPOVER (popover), G_MENU_MODEL (menu), "app");
+  w = g_object_ref (gtk_bin_get_child (GTK_BIN (popover)));
+  gtk_container_remove (GTK_CONTAINER (popover), w);
+  gtk_container_add (GTK_CONTAINER (self->priv->grid), w);
+  g_object_unref (w);
+  gtk_widget_set_valign (w, GTK_ALIGN_START);
+  gtk_widget_set_vexpand (w, TRUE);
+  gtk_widget_destroy (popover);
+
+  g_object_unref (model);
+}
+
+
+static void
 photos_dropdown_dispose (GObject *object)
 {
   PhotosDropdown *self = PHOTOS_DROPDOWN (object);
@@ -57,6 +89,9 @@ photos_dropdown_dispose (GObject *object)
   g_clear_object (&priv->srch_typ_mngr);
   g_clear_object (&priv->src_mngr);
 
+  g_list_free_full (priv->models, g_object_unref);
+  priv->models = NULL;
+
   G_OBJECT_CLASS (photos_dropdown_parent_class)->dispose (object);
 }
 
@@ -79,22 +114,14 @@ photos_dropdown_init (PhotosDropdown *self)
   priv->srch_typ_mngr = g_object_ref (state->srch_typ_mngr);
   priv->src_mngr = g_object_ref (state->src_mngr);
 
-  priv->match_view = photos_base_view_new (priv->srch_mtch_mngr);
-  priv->source_view = photos_base_view_new (priv->src_mngr);
-  priv->type_view = photos_base_view_new (priv->srch_typ_mngr);
-
   priv->grid = gtk_grid_new ();
-  gtk_widget_set_margin_start (priv->grid, 10);
-  gtk_widget_set_margin_end (priv->grid, 10);
-  gtk_widget_set_margin_bottom (priv->grid, 10);
-  gtk_widget_set_margin_top (priv->grid, 10);
   gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->grid), GTK_ORIENTATION_HORIZONTAL);
   gtk_grid_set_row_homogeneous (GTK_GRID (priv->grid), TRUE);
   gtk_container_add (GTK_CONTAINER (self), priv->grid);
 
-  gtk_container_add (GTK_CONTAINER (priv->grid), priv->source_view);
-  gtk_container_add (GTK_CONTAINER (priv->grid), priv->type_view);
-  gtk_container_add (GTK_CONTAINER (priv->grid), priv->match_view);
+  photos_dropdown_add_manager (self, priv->src_mngr);
+  photos_dropdown_add_manager (self, priv->srch_typ_mngr);
+  photos_dropdown_add_manager (self, priv->srch_mtch_mngr);
 
   context = gtk_widget_get_style_context (GTK_WIDGET (self));
   gtk_style_context_add_class (context, "photos-dropdown");
@@ -115,5 +142,5 @@ photos_dropdown_class_init (PhotosDropdownClass *class)
 GtkWidget *
 photos_dropdown_new (GtkWidget *relative_to)
 {
-  return g_object_new (PHOTOS_TYPE_DROPDOWN, "relative-to", relative_to, "height_request", 240, NULL);
+  return g_object_new (PHOTOS_TYPE_DROPDOWN, "relative-to", relative_to, "position", GTK_POS_BOTTOM, NULL);
 }
diff --git a/src/photos-overview-searchbar.c b/src/photos-overview-searchbar.c
index 82db04f..201e995 100644
--- a/src/photos-overview-searchbar.c
+++ b/src/photos-overview-searchbar.c
@@ -211,7 +211,7 @@ photos_overview_searchbar_toggled (PhotosOverviewSearchbar *self)
   PhotosOverviewSearchbarPrivate *priv = self->priv;
 
   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->dropdown_button)))
-    gtk_widget_show (GTK_WIDGET(priv->dropdown));
+    gtk_widget_show_all (priv->dropdown);
 }
 
 


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