diff options
author | Matthias Clasen <mclasen@redhat.com> | 2015-11-02 20:45:46 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2015-11-02 20:47:55 -0500 |
commit | 0b52b29dfc05cb042617f14dd2afb85fd4a038a7 (patch) | |
tree | a74792c1be6b173a7d4f2d5e0c92cde9c2be8d93 | |
parent | f6ca908e033269ee458539add9c05eda4a19d2a3 (diff) | |
download | gtk+-0b52b29dfc05cb042617f14dd2afb85fd4a038a7.tar.gz |
menu: Port to use css nodes
Use the element name menu for the main node, and use two subnodes
with name arrow and style classes .top and .bottom for the arrows
of scrolling menus.
-rw-r--r-- | gtk/gtkmenu.c | 77 | ||||
-rw-r--r-- | gtk/gtkmenuprivate.h | 4 |
2 files changed, 66 insertions, 15 deletions
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 61f8541950..0409b54097 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -112,6 +112,9 @@ #include "gtktypebuiltins.h" #include "gtkwidgetprivate.h" #include "gtkwindowprivate.h" +#include "gtkcssnodeprivate.h" +#include "gtkstylecontextprivate.h" +#include "gtkcssstylepropertyprivate.h" #include "deprecated/gtktearoffmenuitem.h" @@ -878,6 +881,7 @@ gtk_menu_class_init (GtkMenuClass *class) GTK_SCROLL_PAGE_DOWN); gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_MENU_ACCESSIBLE); + gtk_widget_class_set_css_name (widget_class, "menu"); } @@ -1078,10 +1082,33 @@ gtk_menu_window_event (GtkWidget *window, } static void +node_style_changed_cb (GtkCssNode *node, + GtkCssStyle *old_style, + GtkCssStyle *new_style, + GtkWidget *widget) +{ + GtkBitmask *changes; + static GtkBitmask *affects_size = NULL; + + if (G_UNLIKELY (affects_size == NULL)) + affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP); + + changes = _gtk_bitmask_new (); + changes = gtk_css_style_add_difference (changes, old_style, new_style); + + if (_gtk_bitmask_intersects (changes, affects_size)) + gtk_widget_queue_resize (widget); + else + gtk_widget_queue_draw (widget); + + _gtk_bitmask_free (changes); +} + +static void gtk_menu_init (GtkMenu *menu) { GtkMenuPrivate *priv; - GtkStyleContext *context; + GtkCssNode *widget_node; priv = gtk_menu_get_instance_private (menu); @@ -1110,10 +1137,26 @@ gtk_menu_init (GtkMenu *menu) priv->monitor_num = -1; priv->drag_start_y = -1; - context = gtk_widget_get_style_context (GTK_WIDGET (menu)); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_MENU); - _gtk_widget_set_captured_event_handler (GTK_WIDGET (menu), gtk_menu_captured_event); + + widget_node = gtk_widget_get_css_node (GTK_WIDGET (menu)); + priv->top_arrow = gtk_css_node_new (); + gtk_css_node_set_name (priv->top_arrow, I_("arrow")); + gtk_css_node_add_class (priv->top_arrow, g_quark_from_static_string (GTK_STYLE_CLASS_TOP)); + gtk_css_node_set_parent (priv->top_arrow, widget_node); + gtk_css_node_set_visible (priv->top_arrow, FALSE); + gtk_css_node_set_state (priv->top_arrow, gtk_css_node_get_state (widget_node)); + g_signal_connect_object (priv->top_arrow, "style-changed", G_CALLBACK (node_style_changed_cb), menu, 0); + g_object_unref (priv->top_arrow); + + priv->bottom_arrow = gtk_css_node_new (); + gtk_css_node_set_name (priv->bottom_arrow, I_("arrow")); + gtk_css_node_add_class (priv->bottom_arrow, g_quark_from_static_string (GTK_STYLE_CLASS_BOTTOM)); + gtk_css_node_set_parent (priv->bottom_arrow, widget_node); + gtk_css_node_set_visible (priv->bottom_arrow, FALSE); + gtk_css_node_set_state (priv->bottom_arrow, gtk_css_node_get_state (widget_node)); + g_signal_connect_object (priv->bottom_arrow, "style-changed", G_CALLBACK (node_style_changed_cb), menu, 0); + g_object_unref (priv->bottom_arrow); } static void @@ -3071,14 +3114,9 @@ gtk_menu_draw (GtkWidget *widget, gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget)); - gtk_style_context_save (context); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON); - if (priv->upper_arrow_visible && !priv->tearoff_active) { - gtk_style_context_save (context); - gtk_style_context_set_state (context, priv->upper_arrow_state); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP); + gtk_style_context_save_to_node (context, priv->top_arrow); gtk_render_background (context, cr, upper.x, upper.y, @@ -3097,9 +3135,7 @@ gtk_menu_draw (GtkWidget *widget, if (priv->lower_arrow_visible && !priv->tearoff_active) { - gtk_style_context_save (context); - gtk_style_context_set_state (context, priv->lower_arrow_state); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM); + gtk_style_context_save_to_node (context, priv->bottom_arrow); gtk_render_background (context, cr, lower.x, lower.y, @@ -3115,8 +3151,6 @@ gtk_menu_draw (GtkWidget *widget, gtk_style_context_restore (context); } - - gtk_style_context_restore (context); } if (gtk_cairo_should_draw_window (cr, priv->bin_window)) @@ -3904,6 +3938,7 @@ gtk_menu_handle_scrolling (GtkMenu *menu, if (arrow_state != priv->upper_arrow_state) { priv->upper_arrow_state = arrow_state; + gtk_css_node_set_state (priv->top_arrow, arrow_state); gdk_window_invalidate_rect (gtk_widget_get_window (GTK_WIDGET (menu)), &rect, FALSE); @@ -3977,6 +4012,7 @@ gtk_menu_handle_scrolling (GtkMenu *menu, if (arrow_state != priv->lower_arrow_state) { priv->lower_arrow_state = arrow_state; + gtk_css_node_set_state (priv->bottom_arrow, arrow_state); gdk_window_invalidate_rect (gtk_widget_get_window (GTK_WIDGET (menu)), &rect, FALSE); @@ -4704,10 +4740,16 @@ static void gtk_menu_stop_scrolling (GtkMenu *menu) { GtkMenuPrivate *priv = menu->priv; + GtkStateFlags state; gtk_menu_remove_scroll_timeout (menu); priv->upper_arrow_prelight = FALSE; priv->lower_arrow_prelight = FALSE; + + state = gtk_css_node_get_state (priv->top_arrow); + gtk_css_node_set_state (priv->top_arrow, state & ~GTK_STATE_FLAG_PRELIGHT); + state = gtk_css_node_get_state (priv->bottom_arrow); + gtk_css_node_set_state (priv->bottom_arrow, state & ~GTK_STATE_FLAG_PRELIGHT); } static void @@ -4871,6 +4913,11 @@ gtk_menu_scroll_to (GtkMenu *menu, y += arrow_border.top; } + gtk_css_node_set_visible (priv->top_arrow, priv->upper_arrow_visible); + gtk_css_node_set_visible (priv->bottom_arrow, priv->lower_arrow_visible); + gtk_css_node_set_state (priv->top_arrow, priv->upper_arrow_state); + gtk_css_node_set_state (priv->bottom_arrow, priv->lower_arrow_state); + /* Scroll the menu: */ if (gtk_widget_get_realized (widget)) { diff --git a/gtk/gtkmenuprivate.h b/gtk/gtkmenuprivate.h index f1a40d8a8e..927747b38e 100644 --- a/gtk/gtkmenuprivate.h +++ b/gtk/gtkmenuprivate.h @@ -26,6 +26,7 @@ #define __GTK_MENU_PRIVATE_H__ #include <gtk/gtkmenu.h> +#include <gtk/gtkcssnodeprivate.h> G_BEGIN_DECLS @@ -68,6 +69,9 @@ struct _GtkMenuPrivate GdkWindow *view_window; GdkWindow *bin_window; + GtkCssNode *top_arrow; + GtkCssNode *bottom_arrow; + gint scroll_offset; gint saved_scroll_offset; gint scroll_step; |