summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2015-11-02 20:45:46 -0500
committerMatthias Clasen <mclasen@redhat.com>2015-11-02 20:47:55 -0500
commit0b52b29dfc05cb042617f14dd2afb85fd4a038a7 (patch)
treea74792c1be6b173a7d4f2d5e0c92cde9c2be8d93
parentf6ca908e033269ee458539add9c05eda4a19d2a3 (diff)
downloadgtk+-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.c77
-rw-r--r--gtk/gtkmenuprivate.h4
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;