mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 19:00:08 +00:00
snapshot: Convert GtkImage and GtkIconHelper
Adds a bunch of new APIs to render textures with theming. FIXME: Cannot draw shadows for textures.
This commit is contained in:
parent
92e6b3a000
commit
c0aa065ac1
@ -857,27 +857,24 @@ _gtk_icon_helper_draw (GtkIconHelper *self,
|
||||
}
|
||||
}
|
||||
|
||||
GskRenderNode *
|
||||
gtk_icon_helper_get_render_node (GtkIconHelper *self,
|
||||
GskRenderer *renderer)
|
||||
void
|
||||
gtk_icon_helper_snapshot (GtkIconHelper *self,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GskTexture *texture;
|
||||
GskRenderNode *node;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
gtk_icon_helper_ensure_texture (self, renderer);
|
||||
gtk_icon_helper_ensure_texture (self, gtk_snapshot_get_renderer (snapshot));
|
||||
texture = self->priv->texture;
|
||||
if (texture == NULL)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
graphene_rect_init (&bounds, 0, 0, gsk_texture_get_width (texture), gsk_texture_get_height (texture));
|
||||
|
||||
node = gsk_renderer_create_render_node (renderer);
|
||||
gsk_render_node_set_name (node, "Icon Helper");
|
||||
gsk_render_node_set_bounds (node, &bounds);
|
||||
node = gtk_snapshot_append (snapshot, &bounds, "Icon Helper");
|
||||
gsk_render_node_set_texture (node, texture);
|
||||
|
||||
return node;
|
||||
gsk_render_node_unref (node);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -125,8 +125,8 @@ void _gtk_icon_helper_draw (GtkIconHelper *self,
|
||||
cairo_t *cr,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
GskRenderNode * gtk_icon_helper_get_render_node (GtkIconHelper *self,
|
||||
GskRenderer *renderer);
|
||||
void gtk_icon_helper_snapshot (GtkIconHelper *self,
|
||||
GtkSnapshot *snapshot);
|
||||
|
||||
gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self);
|
||||
void _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
|
||||
|
101
gtk/gtkimage.c
101
gtk/gtkimage.c
@ -142,8 +142,8 @@ struct _GtkImagePrivate
|
||||
|
||||
|
||||
#define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
|
||||
static GskRenderNode *gtk_image_get_render_node (GtkWidget *widget,
|
||||
GskRenderer *renderer);
|
||||
static void gtk_image_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot);
|
||||
static void gtk_image_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation*allocation);
|
||||
static void gtk_image_unmap (GtkWidget *widget);
|
||||
@ -163,6 +163,13 @@ static void gtk_image_get_content_size (GtkCssGadget *gadget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer unused);
|
||||
static gboolean gtk_image_render_contents (GtkCssGadget *gadget,
|
||||
GtkSnapshot *snapshot,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data);
|
||||
|
||||
static void gtk_image_style_updated (GtkWidget *widget);
|
||||
static void gtk_image_finalize (GObject *object);
|
||||
@ -211,7 +218,7 @@ gtk_image_class_init (GtkImageClass *class)
|
||||
gobject_class->finalize = gtk_image_finalize;
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
widget_class->get_render_node = gtk_image_get_render_node;
|
||||
widget_class->snapshot = gtk_image_snapshot;
|
||||
widget_class->measure = gtk_image_measure;
|
||||
widget_class->size_allocate = gtk_image_size_allocate;
|
||||
widget_class->unmap = gtk_image_unmap;
|
||||
@ -367,8 +374,9 @@ gtk_image_init (GtkImage *image)
|
||||
gtk_image_get_content_size,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
gtk_image_render_contents,
|
||||
NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1403,69 +1411,60 @@ gtk_image_get_content_size (GtkCssGadget *gadget,
|
||||
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
gtk_image_get_render_node (GtkWidget *widget,
|
||||
GskRenderer *renderer)
|
||||
static void
|
||||
gtk_image_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkImage *image = GTK_IMAGE (widget);
|
||||
GtkImagePrivate *priv = image->priv;
|
||||
gtk_css_gadget_snapshot (GTK_IMAGE (widget)->priv->gadget,
|
||||
snapshot);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_image_render_contents (GtkCssGadget *gadget,
|
||||
GtkSnapshot *snapshot,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkImage *image;
|
||||
GtkImagePrivate *priv;
|
||||
gint w, h, baseline;
|
||||
gint x, y, width, height;
|
||||
GskRenderNode *res;
|
||||
GskRenderNode *node;
|
||||
GtkAllocation alloc, clip;
|
||||
cairo_t *cr;
|
||||
|
||||
res = gtk_css_gadget_get_render_node (priv->gadget, renderer, FALSE);
|
||||
widget = gtk_css_gadget_get_owner (gadget);
|
||||
image = GTK_IMAGE (widget);
|
||||
priv = image->priv;
|
||||
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
_gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
if (baseline == -1)
|
||||
y += floor(height - h) / 2;
|
||||
else
|
||||
y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
|
||||
|
||||
x += (width - w) / 2;
|
||||
|
||||
gtk_snapshot_translate_2d (snapshot, x, y);
|
||||
if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
|
||||
{
|
||||
node = gtk_widget_create_render_node (widget, renderer, "Image 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;
|
||||
|
||||
_gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
if (baseline == -1)
|
||||
y += floor(height - h) / 2;
|
||||
else
|
||||
y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
|
||||
|
||||
x += (width - w) / 2;
|
||||
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
||||
GdkPixbuf *pixbuf = get_animation_frame (image);
|
||||
|
||||
gtk_render_icon (context, cr, pixbuf, x, y);
|
||||
gtk_snapshot_render_icon (snapshot, context, pixbuf, x, y);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = gtk_icon_helper_get_render_node (priv->icon_helper, renderer);
|
||||
gtk_icon_helper_snapshot (priv->icon_helper, snapshot);
|
||||
}
|
||||
gtk_snapshot_translate_2d (snapshot, -x, -y);
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
gsk_render_node_append_child (res, node);
|
||||
gsk_render_node_unref (node);
|
||||
}
|
||||
|
||||
return res;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkcsstransformvalueprivate.h"
|
||||
#include "gtksnapshotprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@ -222,3 +223,51 @@ gtk_css_style_render_icon_get_extents (GtkCssStyle *style,
|
||||
extents->height += border.top + border.bottom;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_style_snapshot_icon (GtkCssStyle *style,
|
||||
GtkSnapshot *snapshot,
|
||||
GskTexture *texture)
|
||||
{
|
||||
const GtkCssValue *shadows, *transform;
|
||||
cairo_matrix_t transform_matrix;
|
||||
graphene_matrix_t matrix, other, saved_matrix;
|
||||
graphene_rect_t bounds;
|
||||
GskRenderNode *node;
|
||||
int width, height;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_STYLE (style));
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
g_return_if_fail (GSK_IS_TEXTURE (texture));
|
||||
|
||||
shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
|
||||
transform = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM);
|
||||
width = gsk_texture_get_width (texture);
|
||||
height = gsk_texture_get_height (texture);
|
||||
|
||||
if (!_gtk_css_transform_value_get_matrix (transform, &transform_matrix))
|
||||
return;
|
||||
|
||||
graphene_matrix_init_from_matrix (&saved_matrix, gtk_snapshot_get_transform (snapshot));
|
||||
|
||||
/* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
|
||||
graphene_matrix_init_translate (&matrix, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(width / 2.0, height / 2.0, 0));
|
||||
graphene_matrix_init_from_2d (&other, transform_matrix.xx, transform_matrix.yx,
|
||||
transform_matrix.xy, transform_matrix.yy,
|
||||
transform_matrix.x0, transform_matrix.y0);
|
||||
graphene_matrix_multiply (&other, &matrix, &matrix);
|
||||
graphene_matrix_init_translate (&other, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0));
|
||||
graphene_matrix_multiply (&matrix, &other, &matrix);
|
||||
gtk_snapshot_transform (snapshot, &matrix);
|
||||
|
||||
graphene_rect_init (&bounds, 0, 0, width, height);
|
||||
|
||||
node = gtk_snapshot_append (snapshot, &bounds, "Icon");
|
||||
if (!_gtk_css_shadows_value_is_none (shadows))
|
||||
{
|
||||
g_warning ("Painting shadows not implemented for textures yet.");
|
||||
}
|
||||
gsk_render_node_set_texture (node, texture);
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
gtk_snapshot_set_transform (snapshot, &saved_matrix);
|
||||
}
|
||||
|
@ -22,8 +22,10 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <cairo.h>
|
||||
#include <gsk/gsk.h>
|
||||
|
||||
#include "gtkcsstypesprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtktypes.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -41,6 +43,9 @@ void gtk_css_style_render_icon_surface (GtkCssStyle *style,
|
||||
cairo_surface_t *surface,
|
||||
double x,
|
||||
double y);
|
||||
void gtk_css_style_snapshot_icon (GtkCssStyle *style,
|
||||
GtkSnapshot *snapshot,
|
||||
GskTexture *texture);
|
||||
|
||||
void gtk_css_style_render_icon_get_extents (GtkCssStyle *style,
|
||||
GdkRectangle *extents,
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkrenderborderprivate.h"
|
||||
#include "gtkrendericonprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
@ -185,6 +186,39 @@ gtk_snapshot_append_node (GtkSnapshot *state,
|
||||
}
|
||||
}
|
||||
|
||||
GskRenderNode *
|
||||
gtk_snapshot_append (GtkSnapshot *state,
|
||||
const graphene_rect_t *bounds,
|
||||
const char *name,
|
||||
...)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
|
||||
g_return_val_if_fail (state != NULL, NULL);
|
||||
g_return_val_if_fail (bounds != NULL, NULL);
|
||||
|
||||
node = gsk_renderer_create_render_node (state->renderer);
|
||||
gsk_render_node_set_bounds (node, bounds);
|
||||
|
||||
if (name)
|
||||
{
|
||||
va_list args;
|
||||
char *str;
|
||||
|
||||
va_start (args, name);
|
||||
str = g_strdup_vprintf (name, args);
|
||||
va_end (args);
|
||||
|
||||
gsk_render_node_set_name (node, str);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
gtk_snapshot_append_node (state, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
cairo_t *
|
||||
gtk_snapshot_append_cairo_node (GtkSnapshot *state,
|
||||
const graphene_rect_t *bounds,
|
||||
@ -357,3 +391,21 @@ gtk_snapshot_render_layout (GtkSnapshot *state,
|
||||
gtk_snapshot_translate_2d (state, -x, -y);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_snapshot_render_icon (GtkSnapshot *snapshot,
|
||||
GtkStyleContext *context,
|
||||
GdkPixbuf *pixbuf,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GskTexture *texture;
|
||||
|
||||
texture = gsk_texture_new_for_pixbuf (snapshot->renderer, pixbuf);
|
||||
gtk_snapshot_translate_2d (snapshot, x, y);
|
||||
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
|
||||
snapshot,
|
||||
texture);
|
||||
gtk_snapshot_translate_2d (snapshot, -x, -y);
|
||||
gsk_texture_unref (texture);
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,11 @@ GDK_AVAILABLE_IN_3_90
|
||||
void gtk_snapshot_append_node (GtkSnapshot *state,
|
||||
GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GskRenderNode * gtk_snapshot_append (GtkSnapshot *state,
|
||||
const graphene_rect_t *bounds,
|
||||
const char *name,
|
||||
...) G_GNUC_PRINTF(3, 4);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
cairo_t * gtk_snapshot_append_cairo_node (GtkSnapshot *state,
|
||||
const graphene_rect_t *bounds,
|
||||
const char *name,
|
||||
@ -117,6 +122,12 @@ void gtk_snapshot_render_insertion_cursor (GtkSnapshot
|
||||
PangoLayout *layout,
|
||||
int index,
|
||||
PangoDirection direction);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gtk_snapshot_render_icon (GtkSnapshot *snapshot,
|
||||
GtkStyleContext *context,
|
||||
GdkPixbuf *pixbuf,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user