#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"
struct _GtkToolbarPrivate
{
- GtkMenu *menu;
+ GtkWidget *menu;
+ GtkWidget *menu_box;
GtkSettings *settings;
GtkToolbarStyle style;
NULL,
G_TYPE_NONE, 1,
GTK_TYPE_TOOLBAR_STYLE);
+
/**
* GtkToolbar::popup-context-menu:
* @toolbar: the #GtkToolbar which emitted the signal
}
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;
}
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