[gtk+/wip/otte/snapshot: 10/15] snapshot: Add gtk_css_gadget_snapshot()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/snapshot: 10/15] snapshot: Add gtk_css_gadget_snapshot()
- Date: Mon, 14 Nov 2016 03:29:14 +0000 (UTC)
commit 94b201e32a46de57e2391cd62fe772c2b7f5e5c1
Author: Benjamin Otte <otte redhat com>
Date: Sun Nov 13 20:47:34 2016 +0100
snapshot: Add gtk_css_gadget_snapshot()
Including a snpahsot() vfunc, wee!
gtk/gtkcssgadget.c | 142 +++++++++++++++++++++++++++++++++++++++++++++
gtk/gtkcssgadgetprivate.h | 8 +++
gtk/gtksnapshot.c | 7 ++
gtk/gtksnapshot.h | 4 +
4 files changed, 161 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkcssgadget.c b/gtk/gtkcssgadget.c
index 1559fac..5bc0e0f 100644
--- a/gtk/gtkcssgadget.c
+++ b/gtk/gtkcssgadget.c
@@ -122,6 +122,51 @@ gtk_css_gadget_real_draw (GtkCssGadget *gadget,
}
static void
+gtk_css_gadget_get_clip (GtkCssGadget *gadget,
+ graphene_rect_t *bounds)
+{
+ GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
+
+ if (priv->owner && !gtk_widget_get_has_window (priv->owner))
+ {
+ GtkAllocation widget_alloc;
+ gtk_widget_get_allocation (priv->owner, &widget_alloc);
+
+ graphene_rect_init (bounds,
+ priv->clip.x - widget_alloc.x, priv->clip.y - widget_alloc.y,
+ priv->clip.width, priv->clip.height);
+ }
+ else
+ {
+ graphene_rect_init (bounds,
+ priv->clip.x, priv->clip.y,
+ priv->clip.width, priv->clip.height);
+ }
+}
+
+static gboolean
+gtk_css_gadget_real_snapshot (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ graphene_rect_t bounds;
+ gboolean result;
+ cairo_t *cr;
+
+ gtk_css_gadget_get_clip (gadget, &bounds);
+ cr = gtk_snapshot_append_cairo_node (snapshot, &bounds, "Fallback<%s>", G_OBJECT_TYPE_NAME (gadget));
+
+ result = GTK_CSS_GADGET_GET_CLASS (gadget)->draw (gadget, cr, x, y, width, height);
+
+ cairo_destroy (cr);
+
+ return result;
+}
+
+static void
gtk_css_gadget_real_style_changed (GtkCssGadget *gadget,
GtkCssStyleChange *change)
{
@@ -277,6 +322,7 @@ gtk_css_gadget_class_init (GtkCssGadgetClass *klass)
klass->get_preferred_size = gtk_css_gadget_real_get_preferred_size;
klass->allocate = gtk_css_gadget_real_allocate;
klass->draw = gtk_css_gadget_real_draw;
+ klass->snapshot = gtk_css_gadget_real_snapshot;
klass->get_render_node = gtk_css_gadget_real_get_render_node;
klass->style_changed = gtk_css_gadget_real_style_changed;
klass->has_content = gtk_css_gadget_has_content;
@@ -1117,6 +1163,102 @@ gtk_css_gadget_draw (GtkCssGadget *gadget,
#endif
}
+/**
+ * gtk_css_gadget_snapshot:
+ * @gadget: The gadget to snapshot
+ * @snapshot: The snapshot to use
+ *
+ * Will draw the gadget at the position allocated via
+ * gtk_css_gadget_allocate(). It is your responsibility to make
+ * sure that those 2 coordinate systems match.
+ *
+ * The drawing virtual function will be passed an untransformed @cr.
+ * This is important because functions like
+ * gtk_container_propagate_draw() depend on that.
+ */
+void
+gtk_css_gadget_snapshot (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot)
+{
+ GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
+ GtkBorder margin, border, padding;
+ gboolean draw_focus = FALSE;
+ GtkCssStyle *style;
+ int x, y, width, height;
+ int contents_x, contents_y, contents_width, contents_height;
+ GtkAllocation margin_box;
+ graphene_rect_t bounds;
+
+ if (!gtk_css_gadget_get_visible (gadget))
+ return;
+
+ gtk_css_gadget_get_clip (gadget, &bounds);
+ if (gtk_snapshot_clips_rect (snapshot, &bounds))
+ return;
+
+ gtk_css_gadget_get_margin_box (gadget, &margin_box);
+
+ x = margin_box.x;
+ y = margin_box.y;
+ width = margin_box.width;
+ height = margin_box.height;
+
+ if (width < 0 || height < 0)
+ {
+ g_warning ("Drawing a gadget with negative dimensions. "
+ "Did you forget to allocate a size? (node %s owner %s)",
+ gtk_css_node_get_name (gtk_css_gadget_get_node (gadget)),
+ G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget)));
+ x = 0;
+ y = 0;
+ width = gtk_widget_get_allocated_width (priv->owner);
+ height = gtk_widget_get_allocated_height (priv->owner);
+ }
+
+ style = gtk_css_gadget_get_style (gadget);
+ get_box_margin (style, &margin);
+ get_box_border (style, &border);
+ get_box_padding (style, &padding);
+
+ gtk_snapshot_push (snapshot, &bounds, "%s<%s>", gtk_css_node_get_name (priv->node), G_OBJECT_TYPE_NAME
(priv->owner));
+
+ gtk_snapshot_translate_2d (snapshot, x + margin.left, y + margin.top);
+ gtk_css_style_snapshot_background (style,
+ snapshot,
+ width - margin.left - margin.right,
+ height - margin.top - margin.bottom,
+ gtk_css_node_get_junction_sides (priv->node));
+ gtk_css_style_snapshot_border (style,
+ snapshot,
+ width - margin.left - margin.right,
+ height - margin.top - margin.bottom,
+ gtk_css_node_get_junction_sides (priv->node));
+ gtk_snapshot_translate_2d (snapshot, - x - margin.left, - y - margin.top);
+
+ contents_x = x + margin.left + border.left + padding.left;
+ contents_y = y + margin.top + border.top + padding.top;
+ contents_width = width - margin.left - margin.right - border.left - border.right - padding.left -
padding.right;
+ contents_height = height - margin.top - margin.bottom - border.top - border.bottom - padding.top -
padding.bottom;
+
+ if (contents_width > 0 && contents_height > 0)
+ draw_focus = GTK_CSS_GADGET_GET_CLASS (gadget)->snapshot (gadget,
+ snapshot,
+ contents_x, contents_y,
+ contents_width, contents_height);
+
+ if (draw_focus)
+ {
+ gtk_snapshot_translate_2d (snapshot, x + margin.left, y + margin.top);
+ gtk_css_style_snapshot_outline (style,
+ snapshot,
+ width - margin.left - margin.right,
+ height - margin.top - margin.bottom);
+ gtk_snapshot_translate_2d (snapshot, - x - margin.left, - y - margin.top);
+ }
+
+ gtk_snapshot_pop (snapshot);
+}
+
GskRenderNode *
gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
GskRenderer *renderer,
diff --git a/gtk/gtkcssgadgetprivate.h b/gtk/gtkcssgadgetprivate.h
index 347920d..3542746 100644
--- a/gtk/gtkcssgadgetprivate.h
+++ b/gtk/gtkcssgadgetprivate.h
@@ -67,6 +67,12 @@ struct _GtkCssGadgetClass
int y,
int width,
int height);
+ gboolean (* snapshot) (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height);
GskRenderNode * (* get_render_node) (GtkCssGadget *gadget,
GskRenderer *renderer,
@@ -130,6 +136,8 @@ void gtk_css_gadget_allocate (GtkCssGadget
GtkAllocation *out_clip);
void gtk_css_gadget_draw (GtkCssGadget *gadget,
cairo_t *cr);
+void gtk_css_gadget_snapshot (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot);
GskRenderNode * gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
GskRenderer *renderer,
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 2a0507a..26aef79 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -251,6 +251,13 @@ gtk_snapshot_push_cairo_node (GtkSnapshot *state,
return gsk_render_node_get_draw_context (node, state->renderer);
}
+gboolean
+gtk_snapshot_clips_rect (GtkSnapshot *snapshot,
+ const graphene_rect_t *bounds)
+{
+ return FALSE;
+}
+
void
gtk_snapshot_render_background (GtkSnapshot *state,
GtkStyleContext *context,
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index 90ecef0..159c253 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -79,6 +79,10 @@ cairo_t * gtk_snapshot_append_cairo_node (GtkSnapshot
...) G_GNUC_PRINTF(3, 4);
GDK_AVAILABLE_IN_3_90
+gboolean gtk_snapshot_clips_rect (GtkSnapshot *snapshot,
+ const graphene_rect_t *bounds);
+
+GDK_AVAILABLE_IN_3_90
void gtk_snapshot_render_background (GtkSnapshot *state,
GtkStyleContext *context,
gdouble x,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]