[gtk/wip/kill-menu: 2/2] toolbar: Use a popover for overflow
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/kill-menu: 2/2] toolbar: Use a popover for overflow
- Date: Mon, 16 Sep 2019 21:31:12 +0000 (UTC)
commit b14b0efefe840b8ca1ce3077e1170e757bc12340
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Sep 14 16:55:06 2019 -0400
toolbar: Use a popover for overflow
We are phasing out menus.
This is not quite complete, toolitems still
create menuitems, which we translate on the fly.
gtk/gtktoolbar.c | 160 +++++++++++++++++++++++++------------------------------
1 file changed, 72 insertions(+), 88 deletions(-)
---
diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c
index 667d80961c..6d6d88e1ed 100644
--- a/gtk/gtktoolbar.c
+++ b/gtk/gtktoolbar.c
@@ -45,10 +45,14 @@
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtkmenu.h"
#include "gtkorientable.h"
#include "gtkorientableprivate.h"
#include "gtkprivate.h"
+#include "gtkpopovermenu.h"
+#include "gtkmodelbutton.h"
+#include "gtkseparator.h"
+#include "gtkradiomenuitem.h"
+#include "gtkcheckmenuitem.h"
#include "gtkradiobutton.h"
#include "gtkradiotoolbutton.h"
#include "gtkseparatormenuitem.h"
@@ -132,7 +136,8 @@ struct _GtkToolbarClass
struct _GtkToolbarPrivate
{
- GtkMenu *menu;
+ GtkWidget *menu;
+ GtkWidget *menu_box;
GtkSettings *settings;
GtkToolbarStyle style;
@@ -429,6 +434,7 @@ gtk_toolbar_class_init (GtkToolbarClass *klass)
NULL,
G_TYPE_NONE, 1,
GTK_TYPE_TOOLBAR_STYLE);
+
/**
* GtkToolbar::popup-context-menu:
* @toolbar: the #GtkToolbar which emitted the signal
@@ -1108,76 +1114,96 @@ menu_deactivated (GtkWidget *menu,
}
static void
-menu_detached (GtkWidget *widget,
- GtkMenu *menu)
+button_clicked (GtkWidget *button,
+ GtkWidget *item)
{
- GtkToolbar *toolbar = GTK_TOOLBAR (widget);
- GtkToolbarPrivate *priv = toolbar->priv;
-
- priv->menu = NULL;
+ gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
+ if (GTK_IS_TOOL_BUTTON (item))
+ g_signal_emit_by_name (_gtk_tool_button_get_button (GTK_TOOL_BUTTON (item)), "clicked");
}
static void
rebuild_menu (GtkToolbar *toolbar)
{
GtkToolbarPrivate *priv = toolbar->priv;
- GList *list, *children;
+ GList *list;
if (!priv->menu)
{
- priv->menu = GTK_MENU (gtk_menu_new ());
- gtk_menu_attach_to_widget (priv->menu,
- GTK_WIDGET (toolbar),
- menu_detached);
+ priv->menu = gtk_popover_menu_new (priv->arrow_button);
+ priv->menu_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_popover_menu_add_submenu (GTK_POPOVER_MENU (priv->menu), priv->menu_box, "main");
- g_signal_connect (priv->menu, "deactivate",
+ g_signal_connect (priv->menu, "closed",
G_CALLBACK (menu_deactivated), toolbar);
}
- gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
-
+ gtk_container_foreach (GTK_CONTAINER (priv->menu_box), remove_item, NULL);
+
for (list = priv->content; list != NULL; list = list->next)
{
ToolbarContent *content = list->data;
-
+
if (toolbar_content_get_state (content) == OVERFLOWN &&
!toolbar_content_is_placeholder (content))
{
GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
-
+
if (menu_item)
{
- g_assert (GTK_IS_MENU_ITEM (menu_item));
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
- }
- }
- }
-
- /* Remove leading and trailing separator items */
- children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
-
- list = children;
- while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
- {
- GtkWidget *child = list->data;
-
- gtk_container_remove (GTK_CONTAINER (priv->menu), child);
- list = list->next;
- }
- g_list_free (children);
+ GtkWidget *button, *widget;
+ const char *text;
+ GtkButtonRole role;
+ gboolean active;
- /* Regenerate the list of children so we don't try to remove items twice */
- children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
+ g_assert (GTK_IS_MENU_ITEM (menu_item));
+ text = gtk_menu_item_get_label (GTK_MENU_ITEM (menu_item));
+ if (text == NULL)
+ {
+ GtkWidget *box, *child;
+ box = gtk_bin_get_child (GTK_BIN (menu_item));
+ for (child = gtk_widget_get_first_child (box);
+ child;
+ child = gtk_widget_get_next_sibling (child))
+ {
+ if (GTK_IS_LABEL (child))
+ {
+ text = gtk_label_get_label (GTK_LABEL (child));
+ break;
+ }
+ }
+ }
- list = g_list_last (children);
- while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
- {
- GtkWidget *child = list->data;
+ if (GTK_IS_SEPARATOR_MENU_ITEM (menu_item))
+ {
+ gtk_container_add (GTK_CONTAINER (priv->menu_box), gtk_separator_new
(GTK_ORIENTATION_HORIZONTAL));
+ continue;
+ }
+ else if (GTK_IS_RADIO_MENU_ITEM (menu_item))
+ role = GTK_BUTTON_ROLE_RADIO;
+ else if (GTK_IS_CHECK_MENU_ITEM (menu_item))
+ role = GTK_BUTTON_ROLE_CHECK;
+ else
+ role = GTK_BUTTON_ROLE_NORMAL;
- gtk_container_remove (GTK_CONTAINER (priv->menu), child);
- list = list->prev;
+ if (GTK_IS_CHECK_MENU_ITEM (menu_item))
+ active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item));
+ else
+ active = FALSE;
+
+ button = gtk_model_button_new ();
+ g_object_set (button,
+ "text", text,
+ "role", role,
+ "active", active,
+ NULL);
+ widget = toolbar_content_get_widget (content);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (button_clicked), widget);
+ gtk_container_add (GTK_CONTAINER (priv->menu_box), button);
+ }
+ }
}
- g_list_free (children);
priv->need_rebuild = FALSE;
}
@@ -2124,52 +2150,10 @@ show_menu (GtkToolbar *toolbar,
GdkEventButton *event)
{
GtkToolbarPrivate *priv = toolbar->priv;
- GtkRequisition minimum_size;
rebuild_menu (toolbar);
- gtk_widget_show (GTK_WIDGET (priv->menu));
-
- switch (priv->orientation)
- {
- case GTK_ORIENTATION_HORIZONTAL:
- gtk_widget_get_preferred_size (priv->arrow_button, &minimum_size, NULL);
-
- g_object_set (priv->menu,
- "anchor-hints", (GDK_ANCHOR_FLIP_Y |
- GDK_ANCHOR_SLIDE |
- GDK_ANCHOR_RESIZE),
- "menu-type-hint", GDK_SURFACE_TYPE_HINT_DROPDOWN_MENU,
- "rect-anchor-dx", -minimum_size.width,
- NULL);
-
- gtk_menu_popup_at_widget (priv->menu,
- priv->arrow_button,
- GDK_GRAVITY_SOUTH_EAST,
- GDK_GRAVITY_NORTH_WEST,
- (GdkEvent *) event);
-
- break;
-
- case GTK_ORIENTATION_VERTICAL:
- g_object_set (priv->menu,
- "anchor-hints", (GDK_ANCHOR_FLIP_X |
- GDK_ANCHOR_SLIDE |
- GDK_ANCHOR_RESIZE),
- NULL);
-
- gtk_menu_popup_at_widget (priv->menu,
- priv->arrow_button,
- GDK_GRAVITY_NORTH_EAST,
- GDK_GRAVITY_NORTH_WEST,
- (GdkEvent *) event);
-
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
+ gtk_popover_popup (GTK_POPOVER (priv->menu));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]