[libdazzle] panel: add support for GIcon in DzlDockItem and friends



commit 66a28b96e9758e2f74f82691463a0119f864c2cc
Author: Christian Hergert <chergert redhat com>
Date:   Tue Apr 30 12:22:05 2019 -0700

    panel: add support for GIcon in DzlDockItem and friends
    
    This allows having a DzlDockWidget with a GIcon so that it shows up in the
    tabstrip instead of the icon-name.

 src/panel/dzl-dock-item.c   | 27 +++++++++++++++++++++++
 src/panel/dzl-dock-item.h   |  4 ++++
 src/panel/dzl-dock-widget.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
 src/panel/dzl-dock-widget.h |  3 +++
 src/panel/dzl-tab-strip.c   | 46 +++++++++++++++++++++++++++++++++------
 src/panel/dzl-tab.c         | 12 +++++++++++
 src/panel/dzl-tab.h         |  3 +++
 7 files changed, 140 insertions(+), 7 deletions(-)
---
diff --git a/src/panel/dzl-dock-item.c b/src/panel/dzl-dock-item.c
index f05899d..53aca01 100644
--- a/src/panel/dzl-dock-item.c
+++ b/src/panel/dzl-dock-item.c
@@ -709,3 +709,30 @@ dzl_dock_item_emit_presented (DzlDockItem *self)
 
   g_signal_emit (self, signals [PRESENTED], 0);
 }
+
+/**
+ * dzl_dock_item_ref_gicon:
+ * @self: a #DzlDockItem
+ *
+ * Gets a #GIcon for the dock item, if any has been set.
+ *
+ * If an icon-name has been set, a new #GIcon for that icon-name
+ * may be returned.
+ *
+ * Returns: (transfer full) (nullable): a #GIcon or %NULL
+ *
+ * Since: 3.34
+ */
+GIcon *
+dzl_dock_item_ref_gicon (DzlDockItem *self)
+{
+  g_autofree gchar *icon_name = NULL;
+
+  if (DZL_DOCK_ITEM_GET_IFACE (self)->ref_gicon)
+    return DZL_DOCK_ITEM_GET_IFACE (self)->ref_gicon (self);
+
+  if ((icon_name = dzl_dock_item_get_icon_name (self)))
+    return g_themed_icon_new (icon_name);
+
+  return NULL;
+}
diff --git a/src/panel/dzl-dock-item.h b/src/panel/dzl-dock-item.h
index cb16675..9a95af8 100644
--- a/src/panel/dzl-dock-item.h
+++ b/src/panel/dzl-dock-item.h
@@ -58,6 +58,7 @@ struct _DzlDockItemInterface
   void            (*release)            (DzlDockItem     *self,
                                          DzlDockItem     *child);
   void            (*presented)          (DzlDockItem     *self);
+  GIcon          *(*ref_gicon)          (DzlDockItem     *self);
 };
 
 DZL_AVAILABLE_IN_ALL
@@ -105,6 +106,9 @@ void            dzl_dock_item_release           (DzlDockItem     *self,
                                                  DzlDockItem     *child);
 DZL_AVAILABLE_IN_3_30
 void            dzl_dock_item_emit_presented    (DzlDockItem     *self);
+DZL_AVAILABLE_IN_3_34
+GIcon          *dzl_dock_item_ref_gicon         (DzlDockItem     *self);
+G_GNUC_INTERNAL
 void            _dzl_dock_item_printf           (DzlDockItem     *self);
 
 G_END_DECLS
diff --git a/src/panel/dzl-dock-widget.c b/src/panel/dzl-dock-widget.c
index 3fd12b5..4983041 100644
--- a/src/panel/dzl-dock-widget.c
+++ b/src/panel/dzl-dock-widget.c
@@ -28,6 +28,7 @@ typedef struct
 {
   gchar *title;
   gchar *icon_name;
+  GIcon *gicon;
   guint can_close : 1;
 } DzlDockWidgetPrivate;
 
@@ -40,6 +41,7 @@ G_DEFINE_TYPE_EXTENDED (DzlDockWidget, dzl_dock_widget, DZL_TYPE_BIN, 0,
 enum {
   PROP_0,
   PROP_CAN_CLOSE,
+  PROP_GICON,
   PROP_ICON_NAME,
   PROP_MANAGER,
   PROP_TITLE,
@@ -140,6 +142,10 @@ dzl_dock_widget_get_property (GObject    *object,
       g_value_set_boolean (value, dzl_dock_widget_get_can_close (DZL_DOCK_ITEM (self)));
       break;
 
+    case PROP_GICON:
+      g_value_take_object (value, dzl_dock_item_ref_gicon (DZL_DOCK_ITEM (self)));
+      break;
+
     case PROP_ICON_NAME:
       g_value_take_string (value, dzl_dock_widget_item_get_icon_name (DZL_DOCK_ITEM (self)));
       break;
@@ -171,6 +177,10 @@ dzl_dock_widget_set_property (GObject      *object,
       dzl_dock_widget_set_can_close (self, g_value_get_boolean (value));
       break;
 
+    case PROP_GICON:
+      dzl_dock_widget_set_gicon (self, g_value_get_object (value));
+      break;
+
     case PROP_ICON_NAME:
       dzl_dock_widget_set_icon_name (self, g_value_get_string (value));
       break;
@@ -207,6 +217,13 @@ dzl_dock_widget_class_init (DzlDockWidgetClass *klass)
                           FALSE,
                           (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
 
+  properties [PROP_GICON] =
+    g_param_spec_object ("gicon",
+                         "GIcon",
+                         "The GIcon to be displayed",
+                         G_TYPE_ICON,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
   properties [PROP_ICON_NAME] =
     g_param_spec_string ("icon-name",
                          "Icon Name",
@@ -274,14 +291,49 @@ dzl_dock_widget_set_icon_name (DzlDockWidget *self,
     {
       g_free (priv->icon_name);
       priv->icon_name = g_strdup (icon_name);
+      g_clear_object (&priv->gicon);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ICON_NAME]);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_GICON]);
+    }
+}
+
+void
+dzl_dock_widget_set_gicon (DzlDockWidget *self,
+                           GIcon         *gicon)
+{
+  DzlDockWidgetPrivate *priv = dzl_dock_widget_get_instance_private (self);
+
+  g_return_if_fail (DZL_IS_DOCK_WIDGET (self));
+  g_return_if_fail (!gicon || G_IS_ICON (gicon));
+
+  if (g_set_object (&priv->gicon, gicon))
+    {
+      g_clear_pointer (&priv->icon_name, g_free);
       g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ICON_NAME]);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_GICON]);
     }
 }
 
+static GIcon *
+dzl_dock_widget_ref_gicon (DzlDockItem *item)
+{
+  DzlDockWidget *self = DZL_DOCK_WIDGET (item);
+  DzlDockWidgetPrivate *priv = dzl_dock_widget_get_instance_private (self);
+
+  if (priv->icon_name != NULL)
+    return g_themed_icon_new (priv->icon_name);
+
+  if (priv->gicon != NULL)
+    return g_object_ref (priv->gicon);
+
+  return NULL;
+}
+
 static void
 dock_item_iface_init (DzlDockItemInterface *iface)
 {
   iface->get_can_close = dzl_dock_widget_get_can_close;
   iface->get_title = dzl_dock_widget_item_get_title;
   iface->get_icon_name = dzl_dock_widget_item_get_icon_name;
+  iface->ref_gicon = dzl_dock_widget_ref_gicon;
 }
diff --git a/src/panel/dzl-dock-widget.h b/src/panel/dzl-dock-widget.h
index 069fce0..6976c81 100644
--- a/src/panel/dzl-dock-widget.h
+++ b/src/panel/dzl-dock-widget.h
@@ -51,6 +51,9 @@ void       dzl_dock_widget_set_title     (DzlDockWidget *self,
 DZL_AVAILABLE_IN_ALL
 void       dzl_dock_widget_set_icon_name (DzlDockWidget *self,
                                           const gchar   *icon_name);
+DZL_AVAILABLE_IN_3_34
+void       dzl_dock_widget_set_gicon     (DzlDockWidget *self,
+                                          GIcon         *gicon);
 
 G_END_DECLS
 
diff --git a/src/panel/dzl-tab-strip.c b/src/panel/dzl-tab-strip.c
index 8b5bb7c..9a7f476 100644
--- a/src/panel/dzl-tab-strip.c
+++ b/src/panel/dzl-tab-strip.c
@@ -363,7 +363,6 @@ dzl_tab_strip_child_icon_name_changed (DzlTabStrip *self,
                                        GParamSpec  *pspec,
                                        GtkWidget   *child)
 {
-  gchar *icon_name = NULL;
   GtkWidget *parent;
   DzlTab *tab;
 
@@ -379,13 +378,22 @@ dzl_tab_strip_child_icon_name_changed (DzlTabStrip *self,
 
   g_assert (GTK_IS_STACK (parent));
 
-  gtk_container_child_get (GTK_CONTAINER (parent), child,
-                           "icon-name", &icon_name,
-                           NULL);
+  if (DZL_IS_DOCK_ITEM (child))
+    {
+      g_autoptr(GIcon) gicon = NULL;
 
-  dzl_tab_set_icon_name (tab, icon_name);
+      gicon = dzl_dock_item_ref_gicon (DZL_DOCK_ITEM (child));
+      dzl_tab_set_gicon (tab, gicon);
+    }
+  else
+    {
+      g_autofree gchar *icon_name = NULL;
 
-  g_free (icon_name);
+      gtk_container_child_get (GTK_CONTAINER (parent), child,
+                               "icon-name", &icon_name,
+                               NULL);
+      dzl_tab_set_icon_name (tab, icon_name);
+    }
 }
 
 static void
@@ -425,6 +433,20 @@ dzl_tab_strip_tab_clicked (DzlTabStrip *self,
     }
 }
 
+static void
+dzl_tab_strip_gicon_changed (DzlDockItem *item,
+                             GParamSpec  *pspec,
+                             DzlTab      *tab)
+{
+  g_autoptr(GIcon) icon = NULL;
+
+  g_assert (DZL_IS_DOCK_ITEM (item));
+  g_assert (DZL_IS_TAB (tab));
+
+  if ((icon = dzl_dock_item_ref_gicon (item)))
+    dzl_tab_set_gicon (tab, icon);
+}
+
 static void
 dzl_tab_strip_stack_add (DzlTabStrip *self,
                          GtkWidget   *widget,
@@ -477,6 +499,13 @@ dzl_tab_strip_stack_add (DzlTabStrip *self,
                            self,
                            G_CONNECT_SWAPPED);
 
+  if (DZL_IS_DOCK_ITEM (widget))
+    g_signal_connect_object (widget,
+                             "notify::gicon",
+                             G_CALLBACK (dzl_tab_strip_gicon_changed),
+                             tab,
+                             0);
+
   gtk_container_add_with_properties (GTK_CONTAINER (self), GTK_WIDGET (tab),
                                      "pack-type", GTK_PACK_START,
                                      "expand", TRUE,
@@ -489,7 +518,10 @@ dzl_tab_strip_stack_add (DzlTabStrip *self,
     g_object_bind_property (widget, "can-close", tab, "can-close", 0);
 
   dzl_tab_strip_child_title_changed (self, NULL, widget);
-  dzl_tab_strip_child_icon_name_changed (self, NULL, widget);
+  if (DZL_IS_DOCK_ITEM (widget))
+    dzl_tab_strip_gicon_changed (DZL_DOCK_ITEM (widget), NULL, tab);
+  else
+    dzl_tab_strip_child_icon_name_changed (self, NULL, widget);
   dzl_tab_strip_stack_notify_visible_child (self, NULL, stack);
 }
 
diff --git a/src/panel/dzl-tab.c b/src/panel/dzl-tab.c
index c41d3a0..0e5ae17 100644
--- a/src/panel/dzl-tab.c
+++ b/src/panel/dzl-tab.c
@@ -914,6 +914,18 @@ dzl_tab_set_title (DzlTab      *self,
   gtk_label_set_label (priv->title, title);
 }
 
+void
+dzl_tab_set_gicon (DzlTab *self,
+                   GIcon  *gicon)
+{
+  DzlTabPrivate *priv = dzl_tab_get_instance_private (self);
+
+  g_return_if_fail (DZL_IS_TAB (self));
+  g_return_if_fail (!gicon || G_IS_ICON (gicon));
+
+  g_object_set (priv->image, "gicon", gicon, NULL);
+}
+
 const gchar *
 dzl_tab_get_icon_name (DzlTab *self)
 {
diff --git a/src/panel/dzl-tab.h b/src/panel/dzl-tab.h
index dcd4209..6729264 100644
--- a/src/panel/dzl-tab.h
+++ b/src/panel/dzl-tab.h
@@ -30,6 +30,9 @@
 
 G_BEGIN_DECLS
 
+DZL_AVAILABLE_IN_3_34
+void             dzl_tab_set_gicon      (DzlTab          *self,
+                                         GIcon           *gicon);
 DZL_AVAILABLE_IN_ALL
 const gchar     *dzl_tab_get_icon_name  (DzlTab          *self);
 DZL_AVAILABLE_IN_ALL


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