forked from AuroraMiddleware/gtk
snapshot: Convert GtkLabel and GtkAccelLabel
Also adds gtk_snapshot_render_insertion_cursor().
This commit is contained in:
parent
ab47479045
commit
349f55f2fe
@ -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;
|
||||
|
||||
res = GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->get_render_node (widget, renderer);
|
||||
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");
|
||||
|
||||
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
|
||||
|
104
gtk/gtklabel.c
104
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
|
||||
|
@ -298,6 +298,24 @@ gtk_snapshot_render_frame (GtkSnapshot *state,
|
||||
gtk_snapshot_translate_2d (state, -x, -y);
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
@ -2209,6 +2267,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
|
||||
|
Loading…
Reference in New Issue
Block a user