menuitem: Replace arrow gadget with GtkIcon

This commit is contained in:
Timm Bäder 2017-05-10 20:55:38 +02:00 committed by Matthias Clasen
parent 753e915f87
commit 273aa2be61
2 changed files with 66 additions and 81 deletions

View File

@ -27,7 +27,6 @@
#include <string.h> #include <string.h>
#include "gtkaccellabel.h" #include "gtkaccellabel.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkcontainerprivate.h" #include "gtkcontainerprivate.h"
#include "gtkmain.h" #include "gtkmain.h"
#include "gtkmarshalers.h" #include "gtkmarshalers.h"
@ -46,6 +45,7 @@
#include "a11y/gtkmenuitemaccessible.h" #include "a11y/gtkmenuitemaccessible.h"
#include "gtkstylecontextprivate.h" #include "gtkstylecontextprivate.h"
#include "gtkcssstylepropertyprivate.h" #include "gtkcssstylepropertyprivate.h"
#include "gtkiconprivate.h"
#define MENU_POPUP_DELAY 225 #define MENU_POPUP_DELAY 225
@ -245,22 +245,6 @@ gtk_menu_item_actionable_interface_init (GtkActionableInterface *iface)
iface->get_action_target_value = gtk_menu_item_get_action_target_value; iface->get_action_target_value = gtk_menu_item_get_action_target_value;
} }
static void
gtk_menu_item_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkMenuItem *menu_item = GTK_MENU_ITEM (widget);
GtkMenuItemPrivate *priv = menu_item->priv;
GtkWidget *parent;
parent = gtk_widget_get_parent (widget);
if (priv->submenu && !GTK_IS_MENU_BAR (parent))
gtk_css_gadget_snapshot (priv->arrow_gadget, snapshot);
GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->snapshot (widget, snapshot);
}
static void static void
gtk_menu_item_size_allocate (GtkWidget *widget, gtk_menu_item_size_allocate (GtkWidget *widget,
GtkAllocation *allocation) GtkAllocation *allocation)
@ -314,16 +298,16 @@ gtk_menu_item_size_allocate (GtkWidget *widget,
{ {
GtkAllocation arrow_alloc; GtkAllocation arrow_alloc;
gtk_css_gadget_get_preferred_size (priv->arrow_gadget, gtk_widget_measure (priv->arrow_widget,
GTK_ORIENTATION_HORIZONTAL, GTK_ORIENTATION_HORIZONTAL,
-1, -1,
&arrow_alloc.width, NULL, &arrow_alloc.width, NULL,
NULL, NULL); NULL, NULL);
gtk_css_gadget_get_preferred_size (priv->arrow_gadget, gtk_widget_measure (priv->arrow_widget,
GTK_ORIENTATION_VERTICAL, GTK_ORIENTATION_VERTICAL,
-1, -1,
&arrow_alloc.height, NULL, &arrow_alloc.height, NULL,
NULL, NULL); NULL, NULL);
if (direction == GTK_TEXT_DIR_LTR) if (direction == GTK_TEXT_DIR_LTR)
{ {
@ -340,10 +324,9 @@ gtk_menu_item_size_allocate (GtkWidget *widget,
arrow_alloc.y = child_allocation.y + arrow_alloc.y = child_allocation.y +
(child_allocation.height - arrow_alloc.height) / 2; (child_allocation.height - arrow_alloc.height) / 2;
gtk_css_gadget_allocate (priv->arrow_gadget, gtk_widget_size_allocate (priv->arrow_widget, &arrow_alloc);
&arrow_alloc, gtk_widget_get_clip (priv->arrow_widget, &arrow_clip);
-1, gdk_rectangle_union (&arrow_clip, &clip, &clip);
&arrow_clip);
} }
child_allocation.width = MAX (1, child_allocation.width); child_allocation.width = MAX (1, child_allocation.width);
@ -406,11 +389,11 @@ gtk_menu_item_real_get_width (GtkWidget *widget,
{ {
gint arrow_size; gint arrow_size;
gtk_css_gadget_get_preferred_size (priv->arrow_gadget, gtk_widget_measure (priv->arrow_widget,
GTK_ORIENTATION_HORIZONTAL, GTK_ORIENTATION_HORIZONTAL,
-1, -1,
&arrow_size, NULL, &arrow_size, NULL,
NULL, NULL); NULL, NULL);
min_width += arrow_size; min_width += arrow_size;
nat_width = min_width; nat_width = min_width;
@ -458,11 +441,11 @@ gtk_menu_item_real_get_height (GtkWidget *widget,
gint arrow_size = 0; gint arrow_size = 0;
if ((priv->submenu && !GTK_IS_MENU_BAR (parent)) || priv->reserve_indicator) if ((priv->submenu && !GTK_IS_MENU_BAR (parent)) || priv->reserve_indicator)
gtk_css_gadget_get_preferred_size (priv->arrow_gadget, gtk_widget_measure (priv->arrow_widget,
GTK_ORIENTATION_VERTICAL, GTK_ORIENTATION_VERTICAL,
-1, -1,
&arrow_size, NULL, &arrow_size, NULL,
NULL, NULL); NULL, NULL);
if (for_size != -1) if (for_size != -1)
{ {
@ -527,7 +510,6 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass)
widget_class->destroy = gtk_menu_item_destroy; widget_class->destroy = gtk_menu_item_destroy;
widget_class->size_allocate = gtk_menu_item_size_allocate; widget_class->size_allocate = gtk_menu_item_size_allocate;
widget_class->snapshot = gtk_menu_item_snapshot;
widget_class->enter_notify_event = gtk_menu_item_enter; widget_class->enter_notify_event = gtk_menu_item_enter;
widget_class->leave_notify_event = gtk_menu_item_leave; widget_class->leave_notify_event = gtk_menu_item_leave;
widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate; widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate;
@ -769,7 +751,11 @@ gtk_menu_item_dispose (GObject *object)
g_clear_object (&priv->action_helper); g_clear_object (&priv->action_helper);
g_clear_object (&priv->arrow_gadget); if (priv->arrow_widget)
{
gtk_widget_unparent (priv->arrow_widget);
priv->arrow_widget = NULL;
}
G_OBJECT_CLASS (gtk_menu_item_parent_class)->dispose (object); G_OBJECT_CLASS (gtk_menu_item_parent_class)->dispose (object);
} }
@ -865,7 +851,11 @@ gtk_menu_item_detacher (GtkWidget *widget,
g_return_if_fail (priv->submenu == (GtkWidget*) menu); g_return_if_fail (priv->submenu == (GtkWidget*) menu);
priv->submenu = NULL; priv->submenu = NULL;
g_clear_object (&priv->arrow_gadget); if (priv->arrow_widget)
{
gtk_widget_unparent (priv->arrow_widget);
priv->arrow_widget = NULL;
}
} }
static void static void
@ -930,65 +920,61 @@ gtk_menu_item_buildable_custom_finished (GtkBuildable *buildable,
} }
static void static void
update_node_classes (GtkMenuItem *menu_item) update_arrow_classes (GtkMenuItem *menu_item)
{ {
GtkMenuItemPrivate *priv = menu_item->priv; GtkMenuItemPrivate *priv = menu_item->priv;
GtkCssNode *arrow_node, *widget_node, *node; GtkStyleContext *context;
GtkWidget *child;
if (!priv->arrow_gadget) if (!priv->arrow_widget)
return; return;
arrow_node = gtk_css_gadget_get_node (priv->arrow_gadget); context = gtk_widget_get_style_context (priv->arrow_widget);
widget_node = gtk_widget_get_css_node (GTK_WIDGET (menu_item));
gtk_css_node_set_state (arrow_node, gtk_css_node_get_state (widget_node));
if (gtk_widget_get_direction (GTK_WIDGET (menu_item)) == GTK_TEXT_DIR_RTL) if (gtk_widget_get_direction (GTK_WIDGET (menu_item)) == GTK_TEXT_DIR_RTL)
{ {
gtk_css_node_add_class (arrow_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT)); gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
gtk_css_node_remove_class (arrow_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT)); gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT);
node = gtk_css_node_get_first_child (widget_node); child = gtk_widget_get_first_child (GTK_WIDGET (menu_item));
if (node != arrow_node)
gtk_css_node_insert_before (widget_node, arrow_node, node); if (child != priv->arrow_widget)
gtk_widget_insert_after (GTK_WIDGET (menu_item), priv->arrow_widget, NULL);
} }
else else
{ {
gtk_css_node_remove_class (arrow_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT)); gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
gtk_css_node_add_class (arrow_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT)); gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT);
node = gtk_css_node_get_last_child (widget_node); child = gtk_widget_get_last_child (GTK_WIDGET (menu_item));
if (node != arrow_node)
gtk_css_node_insert_after (widget_node, arrow_node, node); if (child != priv->arrow_widget)
gtk_widget_insert_before (GTK_WIDGET (menu_item), priv->arrow_widget, NULL);
} }
} }
static void static void
update_arrow_gadget (GtkMenuItem *menu_item) update_arrow_widget (GtkMenuItem *menu_item)
{ {
GtkMenuItemPrivate *priv = menu_item->priv; GtkMenuItemPrivate *priv = menu_item->priv;
GtkWidget *widget = GTK_WIDGET (menu_item); GtkWidget *widget = GTK_WIDGET (menu_item);
gboolean should_have_gadget; gboolean should_have_arrow;
should_have_gadget = priv->reserve_indicator || should_have_arrow = priv->reserve_indicator ||
(priv->submenu && !GTK_IS_MENU_BAR (gtk_widget_get_parent (widget))); (priv->submenu && !GTK_IS_MENU_BAR (gtk_widget_get_parent (widget)));
if (should_have_gadget) if (should_have_arrow)
{ {
if (!priv->arrow_gadget) if (!priv->arrow_widget)
{ {
priv->arrow_gadget = gtk_builtin_icon_new ("arrow", priv->arrow_widget = gtk_icon_new ("arrow");
widget, gtk_widget_set_parent (priv->arrow_widget, widget);
NULL,
NULL);
gtk_css_node_set_parent (gtk_css_gadget_get_node (priv->arrow_gadget),
gtk_widget_get_css_node (widget));
update_node_classes (menu_item);
} }
} }
else else if (priv->arrow_widget)
{ {
g_clear_object (&priv->arrow_gadget); gtk_widget_unparent (priv->arrow_widget);
priv->arrow_widget = NULL;
} }
} }
@ -1029,7 +1015,7 @@ gtk_menu_item_set_submenu (GtkMenuItem *menu_item,
gtk_menu_item_detacher); gtk_menu_item_detacher);
} }
update_arrow_gadget (menu_item); update_arrow_widget (menu_item);
if (gtk_widget_get_parent (widget)) if (gtk_widget_get_parent (widget))
gtk_widget_queue_resize (widget); gtk_widget_queue_resize (widget);
@ -1651,7 +1637,7 @@ gtk_menu_item_parent_set (GtkWidget *widget,
menu->priv->accel_group, menu->priv->accel_group,
TRUE); TRUE);
update_arrow_gadget (menu_item); update_arrow_widget (menu_item);
if (GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->parent_set) if (GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->parent_set)
GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->parent_set (widget, previous_parent); GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->parent_set (widget, previous_parent);
@ -1663,7 +1649,7 @@ gtk_menu_item_direction_changed (GtkWidget *widget,
{ {
GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); GtkMenuItem *menu_item = GTK_MENU_ITEM (widget);
update_node_classes (menu_item); update_arrow_classes (menu_item);
GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->direction_changed (widget, previous_dir); GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->direction_changed (widget, previous_dir);
} }
@ -1963,7 +1949,7 @@ gtk_menu_item_set_reserve_indicator (GtkMenuItem *menu_item,
if (priv->reserve_indicator != reserve) if (priv->reserve_indicator != reserve)
{ {
priv->reserve_indicator = reserve; priv->reserve_indicator = reserve;
update_arrow_gadget (menu_item); update_arrow_widget (menu_item);
gtk_widget_queue_resize (GTK_WIDGET (menu_item)); gtk_widget_queue_resize (GTK_WIDGET (menu_item));
} }
} }

View File

@ -37,8 +37,7 @@ struct _GtkMenuItemPrivate
GtkActionHelper *action_helper; GtkActionHelper *action_helper;
GtkCssGadget *gadget; GtkWidget *arrow_widget;
GtkCssGadget *arrow_gadget;
guint submenu_placement : 1; guint submenu_placement : 1;
guint submenu_direction : 1; guint submenu_direction : 1;