From 700286c6d8a88d4eb51e418e2675092a7bd232b5 Mon Sep 17 00:00:00 2001 From: Cosimo Cecchi Date: Fri, 1 Jan 2016 15:23:27 -0800 Subject: [PATCH] menubar: port to use a gadget --- gtk/gtkmenubar.c | 217 ++++++++++++++++++++++++++++------------------- 1 file changed, 130 insertions(+), 87 deletions(-) diff --git a/gtk/gtkmenubar.c b/gtk/gtkmenubar.c index fcfb67cafc..b26ffe437d 100644 --- a/gtk/gtkmenubar.c +++ b/gtk/gtkmenubar.c @@ -42,6 +42,7 @@ #include "gtkmenubar.h" #include "gtkbindings.h" +#include "gtkcsscustomgadgetprivate.h" #include "gtkmain.h" #include "gtkmarshalers.h" #include "gtkmenuitemprivate.h" @@ -70,6 +71,8 @@ struct _GtkMenuBarPrivate { GtkPackDirection pack_direction; GtkPackDirection child_pack_direction; + + GtkCssGadget *gadget; }; @@ -81,6 +84,7 @@ static void gtk_menu_bar_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gtk_menu_bar_finalize (GObject *object); static void gtk_menu_bar_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural); @@ -105,6 +109,27 @@ static gint gtk_menu_bar_get_popup_delay (GtkMenuShell *menu_shell); static void gtk_menu_bar_move_current (GtkMenuShell *menu_shell, GtkMenuDirectionType direction); +static void gtk_menu_bar_measure (GtkCssGadget *gadget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline, + gpointer data); +static void gtk_menu_bar_allocate (GtkCssGadget *gadget, + const GtkAllocation *allocation, + int baseline, + GtkAllocation *out_clip, + gpointer data); +static gboolean gtk_menu_bar_render (GtkCssGadget *gadget, + cairo_t *cr, + int x, + int y, + int width, + int height, + gpointer data); + G_DEFINE_TYPE_WITH_PRIVATE (GtkMenuBar, gtk_menu_bar, GTK_TYPE_MENU_SHELL) static void @@ -124,6 +149,7 @@ gtk_menu_bar_class_init (GtkMenuBarClass *class) gobject_class->get_property = gtk_menu_bar_get_property; gobject_class->set_property = gtk_menu_bar_set_property; + gobject_class->finalize = gtk_menu_bar_finalize; widget_class->get_preferred_width = gtk_menu_bar_get_preferred_width; widget_class->get_preferred_height = gtk_menu_bar_get_preferred_height; @@ -257,7 +283,20 @@ gtk_menu_bar_class_init (GtkMenuBarClass *class) static void gtk_menu_bar_init (GtkMenuBar *menu_bar) { - menu_bar->priv = gtk_menu_bar_get_instance_private (menu_bar); + GtkMenuBarPrivate *priv; + GtkWidget *widget; + GtkCssNode *widget_node; + + priv = menu_bar->priv = gtk_menu_bar_get_instance_private (menu_bar); + + widget = GTK_WIDGET (menu_bar); + widget_node = gtk_widget_get_css_node (widget); + priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node, + widget, + gtk_menu_bar_measure, + gtk_menu_bar_allocate, + gtk_menu_bar_render, + NULL, NULL); } /** @@ -273,6 +312,16 @@ gtk_menu_bar_new (void) return g_object_new (GTK_TYPE_MENU_BAR, NULL); } +static void +gtk_menu_bar_finalize (GObject *object) +{ + GtkMenuBar *menu_bar = GTK_MENU_BAR (object); + + g_clear_object (&menu_bar->priv->gadget); + + G_OBJECT_CLASS (gtk_menu_bar_parent_class)->finalize (object); +} + static void gtk_menu_bar_set_property (GObject *object, guint prop_id, @@ -318,12 +367,16 @@ gtk_menu_bar_get_property (GObject *object, } static void -gtk_menu_bar_size_request (GtkWidget *widget, - GtkOrientation orientation, - gint size, - gint *minimum, - gint *natural) +gtk_menu_bar_measure (GtkCssGadget *gadget, + GtkOrientation orientation, + int size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline, + gpointer data) { + GtkWidget *widget = gtk_css_gadget_get_owner (gadget); GtkMenuBar *menu_bar; GtkMenuBarPrivate *priv; GtkMenuShell *menu_shell; @@ -331,8 +384,6 @@ gtk_menu_bar_size_request (GtkWidget *widget, GList *children; gboolean use_toggle_size, use_maximize; gint child_minimum, child_natural; - GtkStyleContext *context; - GtkBorder border; *minimum = 0; *natural = 0; @@ -387,33 +438,6 @@ gtk_menu_bar_size_request (GtkWidget *widget, } } } - - context = gtk_widget_get_style_context (widget); - gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &border); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - *minimum += border.left + border.right; - *natural += border.left + border.right; - } - else - { - *minimum += border.top + border.bottom; - *natural += border.top + border.bottom; - } - - gtk_style_context_get_border (context, gtk_style_context_get_state (context), &border); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - *minimum += border.left + border.right; - *natural += border.left + border.right; - } - else - { - *minimum += border.top + border.bottom; - *natural += border.top + border.bottom; - } } static void @@ -421,7 +445,11 @@ gtk_menu_bar_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural) { - gtk_menu_bar_size_request (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum, natural); + gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget, + GTK_ORIENTATION_HORIZONTAL, + -1, + minimum, natural, + NULL, NULL); } static void @@ -429,7 +457,11 @@ gtk_menu_bar_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) { - gtk_menu_bar_size_request (widget, GTK_ORIENTATION_VERTICAL, -1, minimum, natural); + gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget, + GTK_ORIENTATION_VERTICAL, + -1, + minimum, natural, + NULL, NULL); } static void @@ -438,7 +470,11 @@ gtk_menu_bar_get_preferred_width_for_height (GtkWidget *widget, gint *minimum, gint *natural) { - gtk_menu_bar_size_request (widget, GTK_ORIENTATION_HORIZONTAL, height, minimum, natural); + gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget, + GTK_ORIENTATION_HORIZONTAL, + height, + minimum, natural, + NULL, NULL); } static void @@ -447,13 +483,21 @@ gtk_menu_bar_get_preferred_height_for_width (GtkWidget *widget, gint *minimum, gint *natural) { - gtk_menu_bar_size_request (widget, GTK_ORIENTATION_VERTICAL, width, minimum, natural); + gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget, + GTK_ORIENTATION_VERTICAL, + width, + minimum, natural, + NULL, NULL); } static void -gtk_menu_bar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +gtk_menu_bar_allocate (GtkCssGadget *gadget, + const GtkAllocation *allocation, + int baseline, + GtkAllocation *out_clip, + gpointer data) { + GtkWidget *widget = gtk_css_gadget_get_owner (gadget); GtkMenuBar *menu_bar; GtkMenuShell *menu_shell; GtkMenuBarPrivate *priv; @@ -464,42 +508,13 @@ gtk_menu_bar_size_allocate (GtkWidget *widget, gint toggle_size; guint i; - g_return_if_fail (GTK_IS_MENU_BAR (widget)); - g_return_if_fail (allocation != NULL); - menu_bar = GTK_MENU_BAR (widget); menu_shell = GTK_MENU_SHELL (widget); priv = menu_bar->priv; - gtk_widget_set_allocation (widget, allocation); - - if (gtk_widget_get_realized (widget)) - gdk_window_move_resize (gtk_widget_get_window (widget), - allocation->x, allocation->y, - allocation->width, allocation->height); - if (menu_shell->priv->children) { - GtkStyleContext *context; - GtkBorder border; - - context = gtk_widget_get_style_context (widget); - gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &border); - - remaining_space.x = border.left; - remaining_space.y = border.top; - remaining_space.width = allocation->width - - border.left - border.right; - remaining_space.height = allocation->height - - border.top - border.bottom; - - gtk_style_context_get_border (context, gtk_style_context_get_state (context), &border); - - remaining_space.x += border.left; - remaining_space.y += border.top; - remaining_space.width -= border.left + border.right; - remaining_space.height -= border.top + border.bottom; - + remaining_space = *allocation; requested_sizes = g_array_new (FALSE, FALSE, sizeof (GtkRequestedSize)); if (priv->pack_direction == GTK_PACK_DIRECTION_LTR || @@ -615,26 +630,54 @@ gtk_menu_bar_size_allocate (GtkWidget *widget, g_array_free (requested_sizes, TRUE); } } +static void +gtk_menu_bar_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkMenuBar *menu_bar; + GtkAllocation clip, content_allocation; -static gint + menu_bar = GTK_MENU_BAR (widget); + gtk_widget_set_allocation (widget, allocation); + + if (gtk_widget_get_realized (widget)) + gdk_window_move_resize (gtk_widget_get_window (widget), + allocation->x, allocation->y, + allocation->width, allocation->height); + + content_allocation = *allocation; + content_allocation.x = content_allocation.y = 0; + gtk_css_gadget_allocate (menu_bar->priv->gadget, + &content_allocation, + gtk_widget_get_allocated_baseline (widget), + &clip); + + clip.x += allocation->x; + clip.y += allocation->y; + gtk_widget_set_clip (widget, &clip); +} + +static gboolean +gtk_menu_bar_render (GtkCssGadget *gadget, + cairo_t *cr, + int x, + int y, + int width, + int height, + gpointer data) +{ + GtkWidget *widget = gtk_css_gadget_get_owner (gadget); + + GTK_WIDGET_CLASS (gtk_menu_bar_parent_class)->draw (widget, cr); + + return FALSE; +} + +static gboolean gtk_menu_bar_draw (GtkWidget *widget, cairo_t *cr) { - GtkStyleContext *context; - - context = gtk_widget_get_style_context (widget); - - gtk_render_background (context, cr, - 0, 0, - gtk_widget_get_allocated_width (widget), - gtk_widget_get_allocated_height (widget)); - - gtk_render_frame (context, cr, - 0, 0, - gtk_widget_get_allocated_width (widget), - gtk_widget_get_allocated_height (widget)); - - GTK_WIDGET_CLASS (gtk_menu_bar_parent_class)->draw (widget, cr); + gtk_css_gadget_draw (GTK_MENU_BAR (widget)->priv->gadget, cr); return FALSE; }