[gtk+/wip/otte/snapshot: 19/30] snapshot: Convert GtkLabel and GtkAccelLabel
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/snapshot: 19/30] snapshot: Convert GtkLabel and GtkAccelLabel
- Date: Tue, 15 Nov 2016 06:33:14 +0000 (UTC)
commit cc1c17481a42e3d4b1e00eed774f9b2652bbd6c5
Author: Benjamin Otte <otte redhat com>
Date: Mon Nov 14 22:58:58 2016 +0100
snapshot: Convert GtkLabel and GtkAccelLabel
Also adds gtk_snapshot_render_insertion_cursor().
gtk/gtkaccellabel.c | 46 ++++++---------
gtk/gtklabel.c | 104 ++++++++++++++++++----------------
gtk/gtksnapshot.c | 18 ++++++
gtk/gtksnapshot.h | 15 +++++
gtk/gtkstylecontext.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 252 insertions(+), 78 deletions(-)
---
diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c
index 93b660a..954b1d3 100644
--- a/gtk/gtkaccellabel.c
+++ b/gtk/gtkaccellabel.c
@@ -139,8 +139,8 @@ static void gtk_accel_label_get_property (GObject *object,
GParamSpec *pspec);
static void gtk_accel_label_destroy (GtkWidget *widget);
static void gtk_accel_label_finalize (GObject *object);
-static GskRenderNode *gtk_accel_label_get_render_node (GtkWidget *widget,
- GskRenderer *renderer);
+static void gtk_accel_label_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot);
static const gchar *gtk_accel_label_get_string (GtkAccelLabel *accel_label);
static void gtk_accel_label_measure (GtkWidget *widget,
GtkOrientation orientation,
@@ -163,7 +163,7 @@ gtk_accel_label_class_init (GtkAccelLabelClass *class)
gobject_class->set_property = gtk_accel_label_set_property;
gobject_class->get_property = gtk_accel_label_get_property;
- widget_class->get_render_node = gtk_accel_label_get_render_node;
+ widget_class->snapshot = gtk_accel_label_snapshot;
widget_class->measure = gtk_accel_label_measure;
widget_class->destroy = gtk_accel_label_destroy;
@@ -457,20 +457,26 @@ get_first_baseline (PangoLayout *layout)
return PANGO_PIXELS (result);
}
-static GskRenderNode *
-gtk_accel_label_get_render_node (GtkWidget *widget,
- GskRenderer *renderer)
+static void
+gtk_accel_label_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (widget);
guint ac_width;
- GtkAllocation allocation;
+ GtkAllocation allocation, clip;
GtkRequisition requisition;
- GskRenderNode *res;
+ graphene_rect_t bounds;
+
+ gtk_widget_get_clip (widget, &clip);
+ gtk_widget_get_allocation (widget, &allocation);
+ graphene_rect_init (&bounds,
+ clip.x - allocation.x, clip.y - allocation.y,
+ clip.width, clip.height);
+ gtk_snapshot_push (snapshot, &bounds, "AccelLabel");
- res = GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->get_render_node (widget, renderer);
+ GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->snapshot (widget, snapshot);
ac_width = gtk_accel_label_get_accel_width (accel_label);
- gtk_widget_get_allocation (widget, &allocation);
gtk_widget_get_preferred_size (widget, NULL, &requisition);
if (allocation.width >= requisition.width + ac_width)
@@ -480,17 +486,6 @@ gtk_accel_label_get_render_node (GtkWidget *widget,
PangoLayout *accel_layout;
gint x;
gint y;
- GtkAllocation alloc, clip;
- GskRenderNode *node;
- cairo_t *cr;
-
- node = gtk_widget_create_render_node (widget, renderer, "AccelLabel Content");
-
- gtk_widget_get_clip (widget, &clip);
- _gtk_widget_get_allocation (widget, &alloc);
-
- cr = gsk_render_node_get_draw_context (node, renderer);
- cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
context = gtk_widget_get_style_context (widget);
@@ -507,18 +502,13 @@ gtk_accel_label_get_render_node (GtkWidget *widget,
y += get_first_baseline (label_layout) - get_first_baseline (accel_layout) - allocation.y;
gtk_style_context_save_to_node (context, accel_label->priv->accel_node);
- gtk_render_layout (context, cr, x, y, accel_layout);
+ gtk_snapshot_render_layout (snapshot, context, x, y, accel_layout);
gtk_style_context_restore (context);
g_object_unref (accel_layout);
-
- cairo_destroy (cr);
-
- gsk_render_node_append_child (res, node);
- gsk_render_node_unref (node);
}
- return res;
+ gtk_snapshot_pop (snapshot);
}
static void
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 5461d3f..e9e6a69 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -414,12 +414,11 @@ static void gtk_label_size_allocate (GtkWidget *widget,
static void gtk_label_state_flags_changed (GtkWidget *widget,
GtkStateFlags prev_state);
static void gtk_label_style_updated (GtkWidget *widget);
+static void gtk_label_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot);
static gboolean gtk_label_focus (GtkWidget *widget,
GtkDirectionType direction);
-static GskRenderNode *gtk_label_get_render_node (GtkWidget *label,
- GskRenderer *renderer);
-
static void gtk_label_realize (GtkWidget *widget);
static void gtk_label_unrealize (GtkWidget *widget);
static void gtk_label_map (GtkWidget *widget);
@@ -565,6 +564,13 @@ static void gtk_label_measure (GtkCssGadget *gadget,
int *minimum_baseline,
int *natural_baseline,
gpointer unused);
+static gboolean gtk_label_render (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data);
static GtkBuildableIface *buildable_parent_iface = NULL;
@@ -612,7 +618,7 @@ gtk_label_class_init (GtkLabelClass *class)
widget_class->state_flags_changed = gtk_label_state_flags_changed;
widget_class->style_updated = gtk_label_style_updated;
widget_class->query_tooltip = gtk_label_query_tooltip;
- widget_class->get_render_node = gtk_label_get_render_node;
+ widget_class->snapshot = gtk_label_snapshot;
widget_class->realize = gtk_label_realize;
widget_class->unrealize = gtk_label_unrealize;
widget_class->map = gtk_label_map;
@@ -1371,7 +1377,7 @@ gtk_label_init (GtkLabel *label)
gtk_label_measure,
NULL,
NULL,
- NULL,
+ gtk_label_render,
NULL,
NULL);
}
@@ -4153,41 +4159,38 @@ gtk_label_get_focus_link (GtkLabel *label)
return NULL;
}
+static void
+gtk_label_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ gtk_css_gadget_snapshot (GTK_LABEL (widget)->priv->gadget, snapshot);
+}
+
static void layout_to_window_coords (GtkLabel *label,
gint *x,
gint *y);
+#define GRAPHENE_RECT_FROM_RECT(_r) ((graphene_rect_t) GRAPHENE_RECT_INIT ((_r)->x, (_r)->y, (_r)->width,
(_r)->height))
-static GskRenderNode *
-gtk_label_get_render_node (GtkWidget *widget,
- GskRenderer *renderer)
+static gboolean
+gtk_label_render (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data)
{
- GtkLabel *label = GTK_LABEL (widget);
- GtkLabelPrivate *priv = label->priv;
- GtkLabelSelectionInfo *info = priv->select_info;
+ GtkWidget *widget;
+ GtkLabel *label;
+ GtkLabelPrivate *priv;
+ GtkLabelSelectionInfo *info;
GtkStyleContext *context;
- gint x, y, width, height;
gint lx, ly;
- cairo_t *cr;
- GtkAllocation alloc, clip;
- GskRenderNode *node;
- GskRenderNode *res;
- res = gtk_css_gadget_get_render_node (priv->gadget, renderer, FALSE);
-
- if (res == NULL)
- return NULL;
-
- node = gtk_widget_create_render_node (widget, renderer, "Label Content");
-
- gtk_widget_get_clip (widget, &clip);
- _gtk_widget_get_allocation (widget, &alloc);
-
- cr = gsk_render_node_get_draw_context (node, renderer);
- cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
- x = 0;
- y = 0;
- width = alloc.width;
- height = alloc.height;
+ widget = gtk_css_gadget_get_owner (gadget);
+ label = GTK_LABEL (widget);
+ priv = label->priv;
+ info = priv->select_info;
gtk_label_ensure_layout (label);
@@ -4206,12 +4209,14 @@ gtk_label_get_render_node (GtkWidget *widget,
lx = ly = 0;
layout_to_window_coords (label, &lx, &ly);
- gtk_render_layout (context, cr, lx, ly, priv->layout);
+ gtk_snapshot_render_layout (snapshot, context, lx, ly, priv->layout);
if (info && (info->selection_anchor != info->selection_end))
{
gint range[2];
cairo_region_t *range_clip;
+ cairo_rectangle_int_t clip_extents;
+ cairo_t *cr;
range[0] = info->selection_anchor;
range[1] = info->selection_end;
@@ -4224,8 +4229,10 @@ gtk_label_get_render_node (GtkWidget *widget,
}
range_clip = gdk_pango_layout_get_clip_region (priv->layout, lx, ly, range, 1);
-
- cairo_save (cr);
+ cairo_region_get_extents (range_clip, &clip_extents);
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &GRAPHENE_RECT_FROM_RECT(&clip_extents),
+ "Selected Text");
gtk_style_context_save_to_node (context, info->selection_node);
gdk_cairo_region (cr, range_clip);
@@ -4235,7 +4242,7 @@ gtk_label_get_render_node (GtkWidget *widget,
gtk_render_layout (context, cr, lx, ly, priv->layout);
gtk_style_context_restore (context);
- cairo_restore (cr);
+ cairo_destroy (cr);
cairo_region_destroy (range_clip);
}
else if (info)
@@ -4244,7 +4251,9 @@ gtk_label_get_render_node (GtkWidget *widget,
GtkLabelLink *active_link;
gint range[2];
cairo_region_t *range_clip;
+ cairo_rectangle_int_t clip_extents;
GdkRectangle rect;
+ cairo_t *cr;
if (info->selectable &&
gtk_widget_has_focus (widget) &&
@@ -4253,10 +4262,10 @@ gtk_label_get_render_node (GtkWidget *widget,
PangoDirection cursor_direction;
cursor_direction = get_cursor_direction (label);
- gtk_render_insertion_cursor (context, cr,
- lx, ly,
- priv->layout, priv->select_info->selection_end,
- cursor_direction);
+ gtk_snapshot_render_insertion_cursor (snapshot, context,
+ lx, ly,
+ priv->layout, priv->select_info->selection_end,
+ cursor_direction);
}
focus_link = gtk_label_get_focus_link (label);
@@ -4267,11 +4276,13 @@ gtk_label_get_render_node (GtkWidget *widget,
range[0] = active_link->start;
range[1] = active_link->end;
- cairo_save (cr);
gtk_style_context_save_to_node (context, active_link->cssnode);
range_clip = gdk_pango_layout_get_clip_region (priv->layout, lx, ly, range, 1);
-
+ cairo_region_get_extents (range_clip, &clip_extents);
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &GRAPHENE_RECT_FROM_RECT(&clip_extents),
+ "Active Link");
gdk_cairo_region (cr, range_clip);
cairo_clip (cr);
cairo_region_destroy (range_clip);
@@ -4291,19 +4302,14 @@ gtk_label_get_render_node (GtkWidget *widget,
range_clip = gdk_pango_layout_get_clip_region (priv->layout, lx, ly, range, 1);
cairo_region_get_extents (range_clip, &rect);
- gtk_render_focus (context, cr, rect.x, rect.y, rect.width, rect.height);
+ gtk_snapshot_render_focus (snapshot, context, rect.x, rect.y, rect.width, rect.height);
cairo_region_destroy (range_clip);
}
}
}
- cairo_destroy (cr);
-
- gsk_render_node_append_child (res, node);
- gsk_render_node_unref (node);
-
- return res;
+ return FALSE;
}
static gboolean
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 110cdb5..62defef 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -299,6 +299,24 @@ gtk_snapshot_render_frame (GtkSnapshot *state,
}
void
+gtk_snapshot_render_focus (GtkSnapshot *state,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height)
+{
+ g_return_if_fail (state != NULL);
+ g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+
+ gtk_snapshot_translate_2d (state, x, y);
+ gtk_css_style_snapshot_outline (gtk_style_context_lookup_style (context),
+ state,
+ width, height);
+ gtk_snapshot_translate_2d (state, -x, -y);
+}
+
+void
gtk_snapshot_render_layout (GtkSnapshot *state,
GtkStyleContext *context,
gdouble x,
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index 948e22c..74be2c1 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -97,11 +97,26 @@ void gtk_snapshot_render_frame (GtkSnapshot
gdouble width,
gdouble height);
GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_render_focus (GtkSnapshot *state,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height);
+GDK_AVAILABLE_IN_3_90
void gtk_snapshot_render_layout (GtkSnapshot *state,
GtkStyleContext *context,
gdouble x,
gdouble y,
PangoLayout *layout);
+GDK_AVAILABLE_IN_3_90 /* in gtkstylecontext.c */
+void gtk_snapshot_render_insertion_cursor (GtkSnapshot *snapshot,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ PangoLayout *layout,
+ int index,
+ PangoDirection direction);
G_END_DECLS
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 64641f8..df934e0 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -2060,7 +2060,6 @@ draw_insertion_cursor (GtkStyleContext *context,
gboolean is_primary,
PangoDirection direction,
gboolean draw_arrow)
-
{
GdkRGBA primary_color;
GdkRGBA secondary_color;
@@ -2122,6 +2121,65 @@ draw_insertion_cursor (GtkStyleContext *context,
cairo_restore (cr);
}
+static void
+get_insertion_cursor_bounds (gdouble height,
+ PangoDirection direction,
+ gboolean draw_arrow,
+ graphene_rect_t *bounds)
+{
+ gint stem_width;
+ gint offset;
+
+ stem_width = height * CURSOR_ASPECT_RATIO + 1;
+ if (direction == PANGO_DIRECTION_LTR)
+ offset = stem_width / 2;
+ else
+ offset = stem_width - stem_width / 2;
+
+ if (draw_arrow)
+ {
+ if (direction == PANGO_DIRECTION_LTR)
+ {
+ graphene_rect_init (bounds,
+ - offset, 0,
+ 2 * stem_width + 1, height);
+ }
+ else
+ {
+ graphene_rect_init (bounds,
+ - offset - stem_width - 2, 0,
+ 2 * stem_width + 2, height);
+ }
+ }
+ else
+ {
+ graphene_rect_init (bounds,
+ - offset, 0,
+ stem_width, height);
+ }
+}
+
+static void
+snapshot_insertion_cursor (GtkSnapshot *snapshot,
+ GtkStyleContext *context,
+ gdouble height,
+ gboolean is_primary,
+ PangoDirection direction,
+ gboolean draw_arrow)
+{
+ graphene_rect_t bounds;
+ cairo_t *cr;
+
+ get_insertion_cursor_bounds (height, direction, draw_arrow, &bounds);
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &bounds,
+ "%s Cursor", is_primary ? "Primary" : "Secondary");
+
+ draw_insertion_cursor (context, cr, 0, 0, height, is_primary, direction, draw_arrow);
+
+ cairo_destroy (cr);
+}
+
/**
* gtk_render_insertion_cursor:
* @context: a #GtkStyleContext
@@ -2210,6 +2268,93 @@ gtk_render_insertion_cursor (GtkStyleContext *context,
}
/**
+ * gtk_snapshot_render_insertion_cursor:
+ * @snapshot: snapshot to render to
+ * @context: a #GtkStyleContext
+ * @x: X origin
+ * @y: Y origin
+ * @layout: the #PangoLayout of the text
+ * @index: the index in the #PangoLayout
+ * @direction: the #PangoDirection of the text
+ *
+ * Draws a text caret on @cr at the specified index of @layout.
+ *
+ * Since: 3.90
+ **/
+void
+gtk_snapshot_render_insertion_cursor (GtkSnapshot *snapshot,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ PangoLayout *layout,
+ int index,
+ PangoDirection direction)
+{
+ GtkStyleContextPrivate *priv;
+ gboolean split_cursor;
+ PangoRectangle strong_pos, weak_pos;
+ PangoRectangle *cursor1, *cursor2;
+ PangoDirection keymap_direction;
+ PangoDirection direction2;
+
+ g_return_if_fail (snapshot != NULL);
+ g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+ g_return_if_fail (PANGO_IS_LAYOUT (layout));
+ g_return_if_fail (index >= 0);
+
+ priv = context->priv;
+
+ g_object_get (gtk_settings_get_for_screen (priv->screen),
+ "gtk-split-cursor", &split_cursor,
+ NULL);
+
+ keymap_direction = gdk_keymap_get_direction (gdk_keymap_get_for_display (gdk_screen_get_display
(priv->screen)));
+
+ pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
+
+ direction2 = PANGO_DIRECTION_NEUTRAL;
+
+ if (split_cursor)
+ {
+ cursor1 = &strong_pos;
+
+ if (strong_pos.x != weak_pos.x || strong_pos.y != weak_pos.y)
+ {
+ direction2 = (direction == PANGO_DIRECTION_LTR) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
+ cursor2 = &weak_pos;
+ }
+ }
+ else
+ {
+ if (keymap_direction == direction)
+ cursor1 = &strong_pos;
+ else
+ cursor1 = &weak_pos;
+ }
+
+ gtk_snapshot_translate_2d (snapshot, x + PANGO_PIXELS (cursor1->x), y + PANGO_PIXELS (cursor1->y));
+ snapshot_insertion_cursor (snapshot,
+ context,
+ PANGO_PIXELS (cursor1->height),
+ TRUE,
+ direction,
+ direction2 != PANGO_DIRECTION_NEUTRAL);
+ gtk_snapshot_translate_2d (snapshot, - x - PANGO_PIXELS (cursor1->x), - y - PANGO_PIXELS (cursor1->y));
+
+ if (direction2 != PANGO_DIRECTION_NEUTRAL)
+ {
+ gtk_snapshot_translate_2d (snapshot, x + PANGO_PIXELS (cursor2->x), y + PANGO_PIXELS (cursor2->y));
+ snapshot_insertion_cursor (snapshot,
+ context,
+ PANGO_PIXELS (cursor2->height),
+ FALSE,
+ direction2,
+ TRUE);
+ gtk_snapshot_translate_2d (snapshot, - x - PANGO_PIXELS (cursor2->x), - y - PANGO_PIXELS (cursor2->y));
+ }
+}
+
+/**
* gtk_style_context_get_change:
* @context: the context to query
*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]