gtkmodelmenu: simplify logic, expose bind API
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
This commit is contained in:
@ -2246,6 +2246,7 @@ gtk_menu_shell_set_take_focus
|
|||||||
gtk_menu_shell_get_take_focus
|
gtk_menu_shell_get_take_focus
|
||||||
gtk_menu_shell_get_selected_item
|
gtk_menu_shell_get_selected_item
|
||||||
gtk_menu_shell_get_parent_shell
|
gtk_menu_shell_get_parent_shell
|
||||||
|
gtk_menu_shell_bind_model
|
||||||
GtkMenuDirectionType
|
GtkMenuDirectionType
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GTK_MENU_SHELL
|
GTK_MENU_SHELL
|
||||||
|
|||||||
@ -1622,6 +1622,7 @@ gtk_menu_set_tearoff_state
|
|||||||
gtk_menu_set_title
|
gtk_menu_set_title
|
||||||
gtk_menu_shell_activate_item
|
gtk_menu_shell_activate_item
|
||||||
gtk_menu_shell_append
|
gtk_menu_shell_append
|
||||||
|
gtk_menu_shell_bind_model
|
||||||
gtk_menu_shell_cancel
|
gtk_menu_shell_cancel
|
||||||
gtk_menu_shell_deactivate
|
gtk_menu_shell_deactivate
|
||||||
gtk_menu_shell_deselect
|
gtk_menu_shell_deselect
|
||||||
|
|||||||
@ -24,9 +24,9 @@
|
|||||||
#include "gtkapplicationprivate.h"
|
#include "gtkapplicationprivate.h"
|
||||||
#include "gtkwidgetprivate.h"
|
#include "gtkwidgetprivate.h"
|
||||||
#include "gtkwindowprivate.h"
|
#include "gtkwindowprivate.h"
|
||||||
#include "gtkmodelmenu.h"
|
|
||||||
#include "gtkaccelgroup.h"
|
#include "gtkaccelgroup.h"
|
||||||
#include "gtkaccelmap.h"
|
#include "gtkaccelmap.h"
|
||||||
|
#include "gtkmenubar.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
#include "gtksettings.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->app_menu_section));
|
||||||
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_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_set_parent (window->priv->menubar, GTK_WIDGET (window));
|
||||||
gtk_widget_show_all (window->priv->menubar);
|
gtk_widget_show_all (window->priv->menubar);
|
||||||
g_object_unref (combined);
|
g_object_unref (combined);
|
||||||
|
|||||||
@ -5784,3 +5784,32 @@ gtk_menu_get_reserve_toggle_size (GtkMenu *menu)
|
|||||||
|
|
||||||
return !menu->priv->no_toggle_size;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -1041,3 +1041,32 @@ gtk_menu_bar_set_child_pack_direction (GtkMenuBar *menubar,
|
|||||||
g_object_notify (G_OBJECT (menubar), "child-pack-direction");
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -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_selected_item (GtkMenuShell *menu_shell);
|
||||||
GtkWidget *gtk_menu_shell_get_parent_shell (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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_MENU_SHELL_H__ */
|
#endif /* __GTK_MENU_SHELL_H__ */
|
||||||
|
|||||||
@ -21,10 +21,10 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "gtkmodelmenu.h"
|
#include "gtkmenushell.h"
|
||||||
|
|
||||||
#include "gtkmenu.h"
|
|
||||||
#include "gtkmenubar.h"
|
#include "gtkmenubar.h"
|
||||||
|
#include "gtkmenu.h"
|
||||||
|
|
||||||
#include "gtkseparatormenuitem.h"
|
#include "gtkseparatormenuitem.h"
|
||||||
#include "gtkmodelmenuitem.h"
|
#include "gtkmodelmenuitem.h"
|
||||||
#include "gtkapplicationprivate.h"
|
#include "gtkapplicationprivate.h"
|
||||||
@ -243,12 +243,52 @@ gtk_model_menu_binding_items_changed (GMenuModel *model,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/**
|
||||||
gtk_model_menu_bind (GtkMenuShell *shell,
|
* 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.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* 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".
|
||||||
|
*
|
||||||
|
* 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.6
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gtk_menu_shell_bind_model (GtkMenuShell *shell,
|
||||||
GMenuModel *model,
|
GMenuModel *model,
|
||||||
const gchar *action_namespace,
|
const gchar *action_namespace,
|
||||||
gboolean with_separators)
|
gboolean with_separators)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (GTK_IS_MENU_SHELL (shell));
|
||||||
|
g_return_if_fail (model == NULL || G_IS_MENU_MODEL (model));
|
||||||
|
|
||||||
|
if (model)
|
||||||
|
{
|
||||||
GtkModelMenuBinding *binding;
|
GtkModelMenuBinding *binding;
|
||||||
|
|
||||||
binding = g_slice_new (GtkModelMenuBinding);
|
binding = g_slice_new (GtkModelMenuBinding);
|
||||||
@ -260,99 +300,23 @@ gtk_model_menu_bind (GtkMenuShell *shell,
|
|||||||
binding->action_namespace = g_strdup (action_namespace);
|
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);
|
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);
|
gtk_model_menu_binding_populate (binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
else
|
||||||
gtk_model_menu_create_menu (GMenuModel *model,
|
{
|
||||||
const gchar *action_namespace)
|
GList *children;
|
||||||
{
|
|
||||||
GtkWidget *menu;
|
/* break existing binding */
|
||||||
|
g_object_set_data (G_OBJECT (shell), "gtk-model-menu-binding", NULL);
|
||||||
menu = gtk_menu_new ();
|
|
||||||
|
/* remove all children */
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, action_namespace, TRUE);
|
children = gtk_container_get_children (GTK_CONTAINER (shell));
|
||||||
gtk_model_menu_populate (GTK_MENU_SHELL (menu));
|
while (children)
|
||||||
|
{
|
||||||
return menu;
|
gtk_container_remove (GTK_CONTAINER (shell), children->data);
|
||||||
}
|
children = g_list_delete_link (children, children);
|
||||||
|
}
|
||||||
/**
|
}
|
||||||
* 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;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
GtkWidget *menubar;
|
|
||||||
|
|
||||||
menubar = gtk_menu_bar_new ();
|
|
||||||
|
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
|
|
||||||
gtk_model_menu_populate (GTK_MENU_SHELL (menubar));
|
|
||||||
|
|
||||||
return menubar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
menubar = gtk_menu_bar_new ();
|
|
||||||
|
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
|
|
||||||
gtk_model_menu_populate (GTK_MENU_SHELL (menubar));
|
|
||||||
|
|
||||||
return menubar;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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__ */
|
|
||||||
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include "gtkaccelmapprivate.h"
|
#include "gtkaccelmapprivate.h"
|
||||||
#include "gtkactionhelper.h"
|
#include "gtkactionhelper.h"
|
||||||
#include "gtkmodelmenu.h"
|
|
||||||
#include "gtkwidgetprivate.h"
|
#include "gtkwidgetprivate.h"
|
||||||
#include "gtkaccellabel.h"
|
#include "gtkaccellabel.h"
|
||||||
|
|
||||||
@ -121,17 +120,16 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
|||||||
GtkWidget *menu;
|
GtkWidget *menu;
|
||||||
|
|
||||||
g_menu_model_get_item_attribute (model, item_index, "action-namespace", "s", §ion_namespace);
|
g_menu_model_get_item_attribute (model, item_index, "action-namespace", "s", §ion_namespace);
|
||||||
|
menu = gtk_menu_new ();
|
||||||
|
|
||||||
if (action_namespace)
|
if (action_namespace)
|
||||||
{
|
{
|
||||||
gchar *namespace = g_strjoin (".", action_namespace, section_namespace, NULL);
|
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);
|
g_free (namespace);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
gtk_menu_shell_bind_model (GTK_MENU_SHELL (menu), submenu, section_namespace, TRUE);
|
||||||
menu = gtk_model_menu_create_menu (submenu, section_namespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
|
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user