]> Pileus Git - ~andy/gtk/commitdiff
gtkmodelmenu: simplify logic, expose bind API
authorRyan Lortie <desrt@desrt.ca>
Tue, 11 Sep 2012 15:38:06 +0000 (11:38 -0400)
committerRyan Lortie <desrt@desrt.ca>
Mon, 17 Sep 2012 16:31:22 +0000 (12:31 -0400)
Make the main (and only) entry-point to gtkmodelmenu.c the now-public
gtk_menu_shell_bind_model().

Move the convenience constructors (gtk_menu_new_from_model() and
gtk_menu_bar_new_from_model()) to their proper files.

Remove the private header file.

Simplify the code a bit by making the initial populate part of the
bind() call.

https://bugzilla.gnome.org/show_bug.cgi?id=682831

docs/reference/gtk/gtk3-sections.txt
gtk/gtk.symbols
gtk/gtkapplicationwindow.c
gtk/gtkmenu.c
gtk/gtkmenubar.c
gtk/gtkmenushell.h
gtk/gtkmodelmenu.c
gtk/gtkmodelmenu.h [deleted file]
gtk/gtkmodelmenuitem.c

index dd1d53618d5c01f2fff00b3abb4d3385db844606..ce014ac4ef962618d54acfa26600f5f214ee65c5 100644 (file)
@@ -2246,6 +2246,7 @@ gtk_menu_shell_set_take_focus
 gtk_menu_shell_get_take_focus
 gtk_menu_shell_get_selected_item
 gtk_menu_shell_get_parent_shell
+gtk_menu_shell_bind_model
 GtkMenuDirectionType
 <SUBSECTION Standard>
 GTK_MENU_SHELL
index 40d3a31b5c79abe2596f8f83f7a565ed4c0b9e86..2bd830320f26a5030e27f7507d908f23e1355dab 100644 (file)
@@ -1622,6 +1622,7 @@ gtk_menu_set_tearoff_state
 gtk_menu_set_title
 gtk_menu_shell_activate_item
 gtk_menu_shell_append
+gtk_menu_shell_bind_model
 gtk_menu_shell_cancel
 gtk_menu_shell_deactivate
 gtk_menu_shell_deselect
index 0632bed5e49d3b2e1ac4227f2ad8b18dfabd55c3..2a9215a4a64f0bde995404595f470836f0622633 100644 (file)
@@ -24,9 +24,9 @@
 #include "gtkapplicationprivate.h"
 #include "gtkwidgetprivate.h"
 #include "gtkwindowprivate.h"
-#include "gtkmodelmenu.h"
 #include "gtkaccelgroup.h"
 #include "gtkaccelmap.h"
+#include "gtkmenubar.h"
 #include "gtkintl.h"
 #include "gtksettings.h"
 
@@ -256,7 +256,7 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
       g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
       g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
 
-      window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined));
+      window->priv->menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (combined));
       gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
       gtk_widget_show_all (window->priv->menubar);
       g_object_unref (combined);
index 6667ed5f6d3e30bb7f228596174586f071e40e24..9271c1d52e078a19acc94f34e089fff70e931a3f 100644 (file)
@@ -5784,3 +5784,32 @@ gtk_menu_get_reserve_toggle_size (GtkMenu *menu)
 
   return !menu->priv->no_toggle_size;
 }
+
+/**
+ * gtk_menu_new_from_model:
+ * @model: a #GMenuModel
+ *
+ * Creates a #GtkMenu and populates it with menu items and
+ * submenus according to @model.
+ *
+ * The created menu items are connected to actions found in the
+ * #GtkApplicationWindow to which the menu belongs - typically
+ * by means of being attached to a widget (see gtk_menu_attach_to_widget())
+ * that is contained within the #GtkApplicationWindows widget hierarchy.
+ *
+ * Returns: a new #GtkMenu
+ *
+ * Since: 3.4
+ */
+GtkWidget *
+gtk_menu_new_from_model (GMenuModel *model)
+{
+  GtkWidget *menu;
+
+  g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL);
+
+  menu = gtk_menu_new ();
+  gtk_menu_shell_bind_model (GTK_MENU_SHELL (menu), model, NULL, TRUE);
+
+  return menu;
+}
index c4f7e9f0d69fdb8ac3bc512ddc11688a75e1ab1b..b90e4b89213ea28024cd57a2b5b71ca4f54936fd 100644 (file)
@@ -1041,3 +1041,32 @@ gtk_menu_bar_set_child_pack_direction (GtkMenuBar       *menubar,
       g_object_notify (G_OBJECT (menubar), "child-pack-direction");
     }
 }
+
+/**
+ * gtk_menu_bar_new_from_model:
+ * @model: a #GMenuModel
+ *
+ * Creates a new #GtkMenuBar and populates it with menu items
+ * and submenus according to @model.
+ *
+ * The created menu items are connected to actions found in the
+ * #GtkApplicationWindow to which the menu bar belongs - typically
+ * by means of being contained within the #GtkApplicationWindows
+ * widget hierarchy.
+ *
+ * Returns: a new #GtkMenuBar
+ *
+ * Since: 3.4
+ */
+GtkWidget *
+gtk_menu_bar_new_from_model (GMenuModel *model)
+{
+  GtkWidget *menubar;
+
+  g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL);
+
+  menubar = gtk_menu_bar_new ();
+  gtk_menu_shell_bind_model (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
+
+  return menubar;
+}
index 6e15ffc671f0e77337bafdc56828baa9231f4ee4..c0479e8ab34ea3f2341b4fd05d74c5fc46326a53 100644 (file)
@@ -112,6 +112,12 @@ void     gtk_menu_shell_set_take_focus (GtkMenuShell *menu_shell,
 GtkWidget *gtk_menu_shell_get_selected_item (GtkMenuShell *menu_shell);
 GtkWidget *gtk_menu_shell_get_parent_shell  (GtkMenuShell *menu_shell);
 
+GDK_AVAILABLE_IN_3_6
+void       gtk_menu_shell_bind_model   (GtkMenuShell *menu_shell,
+                                        GMenuModel   *model,
+                                        const gchar  *action_namespace,
+                                        gboolean      with_separators);
+
 G_END_DECLS
 
 #endif /* __GTK_MENU_SHELL_H__ */
index f2174dd89d07ae4a7d813c8d2a4f7ed5bebced12..0c3cc5e96ccd94d8fc9baf2c55f261312d16cc83 100644 (file)
 
 #include "config.h"
 
-#include "gtkmodelmenu.h"
-
-#include "gtkmenu.h"
+#include "gtkmenushell.h"
 #include "gtkmenubar.h"
+#include "gtkmenu.h"
+
 #include "gtkseparatormenuitem.h"
 #include "gtkmodelmenuitem.h"
 #include "gtkapplicationprivate.h"
@@ -243,116 +243,80 @@ gtk_model_menu_binding_items_changed (GMenuModel *model,
     }
 }
 
-static void
-gtk_model_menu_bind (GtkMenuShell *shell,
-                     GMenuModel   *model,
-                     const gchar  *action_namespace,
-                     gboolean      with_separators)
-{
-  GtkModelMenuBinding *binding;
-
-  binding = g_slice_new (GtkModelMenuBinding);
-  binding->model = g_object_ref (model);
-  binding->shell = shell;
-  binding->update_idle = 0;
-  binding->connected = NULL;
-  binding->with_separators = with_separators;
-  binding->action_namespace = g_strdup (action_namespace);
-
-  g_object_set_data_full (G_OBJECT (shell), "gtk-model-menu-binding", binding, gtk_model_menu_binding_free);
-}
-
-
-static void
-gtk_model_menu_populate (GtkMenuShell *shell)
-{
-  GtkModelMenuBinding *binding;
-
-  binding = (GtkModelMenuBinding*) g_object_get_data (G_OBJECT (shell), "gtk-model-menu-binding");
-
-  gtk_model_menu_binding_populate (binding);
-}
-
-GtkWidget *
-gtk_model_menu_create_menu (GMenuModel    *model,
-                            const gchar   *action_namespace)
-{
-  GtkWidget *menu;
-
-  menu = gtk_menu_new ();
-
-  gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, action_namespace, TRUE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menu));
-
-  return menu;
-}
-
 /**
- * gtk_menu_new_from_model:
- * @model: a #GMenuModel
+ * gtk_menu_shell_bind_model:
+ * @menu_shell: a #GtkMenuShell
+ * @model: (allow-none): the #GMenuModel to bind to or %NULL to remove
+ *   binding
+ * @action_namespace: (allow-none): the namespace for actions in @model
+ * @with_separators: %TRUE if toplevel items in @shell should have
+ *   separators between them
+ *
+ * Establishes a binding between a #GtkMenuShell and a #GMenuModel.
+ *
+ * The contents of @shell are removed and then refilled with menu items
+ * according to @model.  When @model changes, @shell is updated.
+ * Calling this function twice on @shell with different @model will
+ * cause the first binding to be replaced with a binding to the new
+ * model. If @model is %NULL then any previous binding is undone and
+ * all children are removed.
  *
- * Creates a #GtkMenu and populates it with menu items and
- * submenus according to @model.
+ * @with_separators determines if toplevel items (eg: sections) have
+ * separators inserted between them.  This is typically desired for
+ * menus but doesn't make sense for menubars.
  *
- * The created menu items are connected to actions found in the
- * #GtkApplicationWindow to which the menu belongs - typically
- * by means of being attached to a widget (see gtk_menu_attach_to_widget())
- * that is contained within the #GtkApplicationWindows widget hierarchy.
+ * If @action_namespace is non-%NULL then the effect is as if all
+ * actions mentioned in the @model have their names prefixed with the
+ * namespace, plus a dot.  For example, if the action "quit" is
+ * mentioned and @action_namespace is "app" then the effective action
+ * name is "app.quit".
  *
- * Returns: a new #GtkMenu
+ * For most cases you are probably better off using
+ * gtk_menu_new_from_model() or gtk_menu_bar_new_from_model() or just
+ * directly passing the #GMenuModel to gtk_application_set_app_menu() or
+ * gtk_application_set_menu_bar().
  *
- * Since: 3.4
+ * Since: 3.6
  */
-GtkWidget *
-gtk_menu_new_from_model (GMenuModel *model)
-{
-  GtkWidget *menu;
-
-  menu = gtk_menu_new ();
-  gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, NULL, TRUE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menu));
-
-  return menu;
-}
-
-GtkWidget *
-gtk_model_menu_create_menu_bar (GMenuModel *model)
+void
+gtk_menu_shell_bind_model (GtkMenuShell *shell,
+                           GMenuModel   *model,
+                           const gchar  *action_namespace,
+                           gboolean      with_separators)
 {
-  GtkWidget *menubar;
+  g_return_if_fail (GTK_IS_MENU_SHELL (shell));
+  g_return_if_fail (model == NULL || G_IS_MENU_MODEL (model));
 
-  menubar = gtk_menu_bar_new ();
+  if (model)
+    {
+      GtkModelMenuBinding *binding;
 
-  gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menubar));
+      binding = g_slice_new (GtkModelMenuBinding);
+      binding->model = g_object_ref (model);
+      binding->shell = shell;
+      binding->update_idle = 0;
+      binding->connected = NULL;
+      binding->with_separators = with_separators;
+      binding->action_namespace = g_strdup (action_namespace);
 
-  return menubar;
-}
+      g_object_set_data_full (G_OBJECT (shell), "gtk-model-menu-binding", binding, gtk_model_menu_binding_free);
 
-/**
- * gtk_menu_bar_new_from_model:
- * @model: a #GMenuModel
- *
- * Creates a new #GtkMenuBar and populates it with menu items
- * and submenus according to @model.
- *
- * The created menu items are connected to actions found in the
- * #GtkApplicationWindow to which the menu bar belongs - typically
- * by means of being contained within the #GtkApplicationWindows
- * widget hierarchy.
- *
- * Returns: a new #GtkMenuBar
- *
- * Since: 3.4
- */
-GtkWidget *
-gtk_menu_bar_new_from_model (GMenuModel *model)
-{
-  GtkWidget *menubar;
+      gtk_model_menu_binding_populate (binding);
+    }
 
-  menubar = gtk_menu_bar_new ();
+  else
+    {
+      GList *children;
 
-  gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
-  gtk_model_menu_populate (GTK_MENU_SHELL (menubar));
+      /* break existing binding */
+      g_object_set_data (G_OBJECT (shell), "gtk-model-menu-binding", NULL);
 
-  return menubar;
+      /* remove all children */
+      children = gtk_container_get_children (GTK_CONTAINER (shell));
+      while (children)
+        {
+          gtk_container_remove (GTK_CONTAINER (shell), children->data);
+          children = g_list_delete_link (children, children);
+        }
+    }
 }
diff --git a/gtk/gtkmodelmenu.h b/gtk/gtkmodelmenu.h
deleted file mode 100644 (file)
index a27c7bd..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright © 2011 Canonical Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Author: Ryan Lortie <desrt@desrt.ca>
- */
-
-#ifndef __GTK_MODEL_MENU_H__
-#define __GTK_MODEL_MENU_H__
-
-#include <gtk/gtkmenushell.h>
-#include <gtk/gtkaccelgroup.h>
-#include <gio/gio.h>
-
-G_GNUC_INTERNAL
-GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel        *model);
-
-G_GNUC_INTERNAL
-GtkWidget * gtk_model_menu_create_menu     (GMenuModel        *model,
-                                            const gchar       *action_namespace);
-
-#endif /* __GTK_MODEL_MENU_H__ */
index 61e10e5a3c706ee5e2e73b9574583c2542317dd0..6d902c2352d3502f97678f872be62120c2aaf60d 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "gtkaccelmapprivate.h"
 #include "gtkactionhelper.h"
-#include "gtkmodelmenu.h"
 #include "gtkwidgetprivate.h"
 #include "gtkaccellabel.h"
 
@@ -121,17 +120,16 @@ gtk_model_menu_item_setup (GtkModelMenuItem  *item,
       GtkWidget *menu;
 
       g_menu_model_get_item_attribute (model, item_index, "action-namespace", "s", &section_namespace);
+      menu = gtk_menu_new ();
 
       if (action_namespace)
         {
           gchar *namespace = g_strjoin (".", action_namespace, section_namespace, NULL);
-          menu = gtk_model_menu_create_menu (submenu, namespace);
+          gtk_menu_shell_bind_model (GTK_MENU_SHELL (menu), submenu, namespace, TRUE);
           g_free (namespace);
         }
       else
-        {
-          menu = gtk_model_menu_create_menu (submenu, section_namespace);
-        }
+        gtk_menu_shell_bind_model (GTK_MENU_SHELL (menu), submenu, section_namespace, TRUE);
 
       gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);