[gtk+/wip/gtkmenutrackeritem: 20/20] GtkMenuTracker: add new_from_item_submenu()



commit 26e5e44dc6bb813220e8b08f226b3a57dfad9782
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri May 10 14:45:27 2013 -0400

    GtkMenuTracker: add new_from_item_submenu()
    
    Creates a menu tracker for the submenu of an existing item, filling in
    about half of the parameters for the new tracker from the correct values
    in the menuitem.
    
    Add also a "has-submenu" boolean property so implementations can just
    use this to check if they should do the submenu, without having to
    handle a GMenuModel at all.

 gtk/gtkmenushell.c       |   27 ++++++++++-----------------
 gtk/gtkmenutracker.c     |   13 +++++++++++++
 gtk/gtkmenutracker.h     |    5 +++++
 gtk/gtkmenutrackeritem.c |   22 ++++++++++++++++++++++
 gtk/gtkmenutrackeritem.h |    2 ++
 5 files changed, 52 insertions(+), 17 deletions(-)
---
diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
index 444b5d0..07ec537 100644
--- a/gtk/gtkmenushell.c
+++ b/gtk/gtkmenushell.c
@@ -2088,7 +2088,6 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
 {
   GtkMenuShell *menu_shell = user_data;
   GtkWidget *widget;
-  GMenuModel *submenu;
 
   if (gtk_menu_tracker_item_get_is_separator (item))
     {
@@ -2099,30 +2098,24 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
        */
       g_object_bind_property (item, "label", widget, "label", G_BINDING_SYNC_CREATE);
     }
-  else if ((submenu = gtk_menu_tracker_item_get_submenu (item)))
+  else if (gtk_menu_tracker_item_get_has_submenu (item))
     {
-      GtkActionObservable *observable;
-      GtkWidget *subwidget;
-      GtkMenuShell *subshell;
+      GtkMenuShell *submenu;
 
       widget = gtk_model_menu_item_new ();
       g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
 
-      /* reuse the observer to reduce the amount of GActionMuxer traffic */
-      observable = gtk_menu_tracker_item_get_observable (item);
-      subwidget = gtk_menu_new ();
-      subshell = GTK_MENU_SHELL (subwidget);
+      submenu = GTK_MENU_SHELL (gtk_menu_new ());
 
       /* We recurse directly here: we could use an idle instead to
        * prevent arbitrary recursion depth.  We could also do it
        * lazy...
        */
-      subshell->priv->tracker = gtk_menu_tracker_new (observable, submenu, TRUE,
-                                                      gtk_menu_tracker_item_get_submenu_namespace (item),
-                                                      gtk_menu_shell_tracker_insert_func,
-                                                      gtk_menu_shell_tracker_remove_func,
-                                                      subwidget);
-      gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), subwidget);
+      submenu->priv->tracker = gtk_menu_tracker_new_for_item_submenu (item,
+                                                                      gtk_menu_shell_tracker_insert_func,
+                                                                      gtk_menu_shell_tracker_remove_func,
+                                                                      submenu);
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), GTK_WIDGET (submenu));
 
       if (gtk_menu_tracker_item_get_should_request_show (item))
         {
@@ -2136,8 +2129,8 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
            *
            * Note: 'item' is already kept alive from above.
            */
-          g_signal_connect (subwidget, "show", G_CALLBACK (gtk_menu_shell_submenu_shown), item);
-          g_signal_connect (subwidget, "hide", G_CALLBACK (gtk_menu_shell_submenu_hidden), item);
+          g_signal_connect (submenu, "show", G_CALLBACK (gtk_menu_shell_submenu_shown), item);
+          g_signal_connect (submenu, "hide", G_CALLBACK (gtk_menu_shell_submenu_hidden), item);
         }
     }
   else
diff --git a/gtk/gtkmenutracker.c b/gtk/gtkmenutracker.c
index 5dedc3b..9a31835 100644
--- a/gtk/gtkmenutracker.c
+++ b/gtk/gtkmenutracker.c
@@ -433,6 +433,19 @@ gtk_menu_tracker_new (GtkActionObservable      *observable,
   return tracker;
 }
 
+GtkMenuTracker *
+gtk_menu_tracker_new_for_item_submenu (GtkMenuTrackerItem       *item,
+                                       GtkMenuTrackerInsertFunc  insert_func,
+                                       GtkMenuTrackerRemoveFunc  remove_func,
+                                       gpointer                  user_data)
+{
+  return gtk_menu_tracker_new (gtk_menu_tracker_item_get_observable (item),
+                               gtk_menu_tracker_item_get_submenu (item),
+                               TRUE,
+                               gtk_menu_tracker_item_get_submenu_namespace (item),
+                               insert_func, remove_func, user_data);
+}
+
 /*< private >
  * gtk_menu_tracker_free:
  * @tracker: a #GtkMenuTracker
diff --git a/gtk/gtkmenutracker.h b/gtk/gtkmenutracker.h
index 0464141..96370ad 100644
--- a/gtk/gtkmenutracker.h
+++ b/gtk/gtkmenutracker.h
@@ -42,6 +42,11 @@ GtkMenuTracker *        gtk_menu_tracker_new                            (GtkActi
                                                                          GtkMenuTrackerRemoveFunc  
remove_func,
                                                                          gpointer                  
user_data);
 
+GtkMenuTracker *        gtk_menu_tracker_new_for_item_submenu           (GtkMenuTrackerItem       *item,
+                                                                         GtkMenuTrackerInsertFunc  
insert_func,
+                                                                         GtkMenuTrackerRemoveFunc  
remove_func,
+                                                                         gpointer                  
user_data);
+
 void                    gtk_menu_tracker_free                           (GtkMenuTracker           *tracker);
 
 #endif /* __GTK_MENU_TRACKER_H__ */
diff --git a/gtk/gtkmenutrackeritem.c b/gtk/gtkmenutrackeritem.c
index df9ef85..ce80223 100644
--- a/gtk/gtkmenutrackeritem.c
+++ b/gtk/gtkmenutrackeritem.c
@@ -19,6 +19,7 @@ struct _GtkMenuTrackerItem
 enum {
   PROP_0,
   PROP_IS_SEPARATOR,
+  PROP_HAS_SUBMENU,
   PROP_LABEL,
   PROP_ICON,
   PROP_SENSITIVE,
@@ -73,6 +74,9 @@ gtk_menu_tracker_item_get_property (GObject    *object,
     case PROP_IS_SEPARATOR:
       g_value_set_boolean (value, gtk_menu_tracker_item_get_is_separator (self));
       break;
+    case PROP_HAS_SUBMENU:
+      g_value_set_boolean (value, gtk_menu_tracker_item_get_has_submenu (self));
+      break;
     case PROP_LABEL:
       g_value_set_string (value, gtk_menu_tracker_item_get_label (self));
       break;
@@ -134,6 +138,8 @@ gtk_menu_tracker_item_class_init (GtkMenuTrackerItemClass *class)
 
   gtk_menu_tracker_item_pspecs[PROP_IS_SEPARATOR] =
     g_param_spec_boolean ("is-separator", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
+  gtk_menu_tracker_item_pspecs[PROP_HAS_SUBMENU] =
+    g_param_spec_boolean ("has-submenu", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
   gtk_menu_tracker_item_pspecs[PROP_LABEL] =
     g_param_spec_string ("label", "", "", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
   gtk_menu_tracker_item_pspecs[PROP_ICON] =
@@ -382,6 +388,22 @@ gtk_menu_tracker_item_get_is_separator (GtkMenuTrackerItem *self)
   return self->is_separator;
 }
 
+gboolean
+gtk_menu_tracker_item_get_has_submenu (GtkMenuTrackerItem *self)
+{
+  GMenuModel *link;
+
+  link = g_menu_item_get_link (self->item, G_MENU_LINK_SUBMENU);
+
+  if (link)
+    {
+      g_object_unref (link);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
 const gchar *
 gtk_menu_tracker_item_get_label (GtkMenuTrackerItem *self)
 {
diff --git a/gtk/gtkmenutrackeritem.h b/gtk/gtkmenutrackeritem.h
index c82e444..46c93c3 100644
--- a/gtk/gtkmenutrackeritem.h
+++ b/gtk/gtkmenutrackeritem.h
@@ -52,6 +52,8 @@ GtkActionObservable *   gtk_menu_tracker_item_get_observable            (GtkMenu
 
 gboolean                gtk_menu_tracker_item_get_is_separator          (GtkMenuTrackerItem *self);
 
+gboolean                gtk_menu_tracker_item_get_has_submenu           (GtkMenuTrackerItem *self);
+
 const gchar *           gtk_menu_tracker_item_get_label                 (GtkMenuTrackerItem *self);
 
 GIcon *                 gtk_menu_tracker_item_get_icon                  (GtkMenuTrackerItem *self);


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