mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 14:31:10 +00:00
window: Implement snapshot()
This commit is contained in:
parent
b1154be1c4
commit
bb9626dc29
@ -42,6 +42,7 @@
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtksizerequestcacheprivate.h"
|
||||
#include "gtksnapshotprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtkassistant.h"
|
||||
@ -3158,47 +3159,16 @@ gtk_container_get_children_clip (GtkContainer *container,
|
||||
gtk_container_forall (container, union_with_clip, out_clip);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_propagate_draw:
|
||||
* @container: a #GtkContainer
|
||||
* @child: a child of @container
|
||||
* @cr: Cairo context as passed to the container. If you want to use @cr
|
||||
* in container’s draw function, consider using cairo_save() and
|
||||
* cairo_restore() before calling this function.
|
||||
*
|
||||
* When a container receives a call to the draw function, it must send
|
||||
* synthetic #GtkWidget::draw calls to all children that don’t have their
|
||||
* own #GdkWindows. This function provides a convenient way of doing this.
|
||||
* A container, when it receives a call to its #GtkWidget::draw function,
|
||||
* calls gtk_container_propagate_draw() once for each child, passing in
|
||||
* the @cr the container received.
|
||||
*
|
||||
* gtk_container_propagate_draw() takes care of translating the origin of @cr,
|
||||
* and deciding whether the draw needs to be sent to the child. It is a
|
||||
* convenient and optimized way of getting the same effect as calling
|
||||
* gtk_widget_draw() on the child directly.
|
||||
*
|
||||
* In most cases, a container can simply either inherit the
|
||||
* #GtkWidget::draw implementation from #GtkContainer, or do some drawing
|
||||
* and then chain to the ::draw implementation from #GtkContainer.
|
||||
**/
|
||||
void
|
||||
gtk_container_propagate_draw (GtkContainer *container,
|
||||
GtkWidget *child,
|
||||
cairo_t *cr)
|
||||
static void
|
||||
gtk_container_get_translation_to_child (GtkContainer *container,
|
||||
GtkWidget *child,
|
||||
int *x_out,
|
||||
int *y_out)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
GdkWindow *window, *w;
|
||||
int x, y;
|
||||
|
||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (_gtk_widget_get_parent (child) == GTK_WIDGET (container));
|
||||
|
||||
if (!gtk_container_should_propagate_draw (container, child, cr))
|
||||
return;
|
||||
|
||||
/* translate coordinates. Ugly business, that. */
|
||||
if (!_gtk_widget_get_has_window (GTK_WIDGET (container)))
|
||||
{
|
||||
@ -3235,6 +3205,51 @@ gtk_container_propagate_draw (GtkContainer *container,
|
||||
y += allocation.y;
|
||||
}
|
||||
|
||||
*x_out = x;
|
||||
*y_out = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_propagate_draw:
|
||||
* @container: a #GtkContainer
|
||||
* @child: a child of @container
|
||||
* @cr: Cairo context as passed to the container. If you want to use @cr
|
||||
* in container’s draw function, consider using cairo_save() and
|
||||
* cairo_restore() before calling this function.
|
||||
*
|
||||
* When a container receives a call to the draw function, it must send
|
||||
* synthetic #GtkWidget::draw calls to all children that don’t have their
|
||||
* own #GdkWindows. This function provides a convenient way of doing this.
|
||||
* A container, when it receives a call to its #GtkWidget::draw function,
|
||||
* calls gtk_container_propagate_draw() once for each child, passing in
|
||||
* the @cr the container received.
|
||||
*
|
||||
* gtk_container_propagate_draw() takes care of translating the origin of @cr,
|
||||
* and deciding whether the draw needs to be sent to the child. It is a
|
||||
* convenient and optimized way of getting the same effect as calling
|
||||
* gtk_widget_draw() on the child directly.
|
||||
*
|
||||
* In most cases, a container can simply either inherit the
|
||||
* #GtkWidget::draw implementation from #GtkContainer, or do some drawing
|
||||
* and then chain to the ::draw implementation from #GtkContainer.
|
||||
**/
|
||||
void
|
||||
gtk_container_propagate_draw (GtkContainer *container,
|
||||
GtkWidget *child,
|
||||
cairo_t *cr)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (_gtk_widget_get_parent (child) == GTK_WIDGET (container));
|
||||
|
||||
if (!gtk_container_should_propagate_draw (container, child, cr))
|
||||
return;
|
||||
|
||||
gtk_container_get_translation_to_child (container, child, &x, &y);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, x, y);
|
||||
|
||||
@ -3243,6 +3258,36 @@ gtk_container_propagate_draw (GtkContainer *container,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_container_snapshot_child (GtkContainer *container,
|
||||
GskRenderNode *container_node,
|
||||
GtkWidget *child,
|
||||
const GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkSnapshot child_snapshot;
|
||||
GskRenderNode *child_node;
|
||||
int x, y;
|
||||
|
||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (_gtk_widget_get_parent (child) == GTK_WIDGET (container));
|
||||
g_return_if_fail (GSK_IS_RENDER_NODE (container_node));
|
||||
g_return_if_fail (snapshot != NULL);
|
||||
|
||||
gtk_container_get_translation_to_child (container, child, &x, &y);
|
||||
|
||||
gtk_snapshot_init_translate (&child_snapshot, snapshot, x, y);
|
||||
child_node = gtk_widget_snapshot (child, &child_snapshot);
|
||||
|
||||
if (child_node)
|
||||
{
|
||||
gsk_render_node_append_child (container_node, child_node);
|
||||
gsk_render_node_unref (child_node);
|
||||
}
|
||||
|
||||
gtk_snapshot_finish (&child_snapshot);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_get_path_for_child:
|
||||
* @container: a #GtkContainer
|
||||
|
@ -50,6 +50,10 @@ void gtk_container_propagate_render_node_for_child (GtkContainer *contai
|
||||
GtkWidget *child,
|
||||
GskRenderer *renderer,
|
||||
GskRenderNode *parent_node);
|
||||
void gtk_container_snapshot_child (GtkContainer *container,
|
||||
GskRenderNode *container_node,
|
||||
GtkWidget *child,
|
||||
const GtkSnapshot *snapshot);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -265,8 +265,8 @@ gtk_debug_updates_queue_get_extents (GQueue *updates,
|
||||
}
|
||||
|
||||
GskRenderNode *
|
||||
gtk_debug_updates_get_render_node (GtkWidget *widget,
|
||||
GskRenderer *renderer)
|
||||
gtk_debug_updates_snapshot (GtkWidget *widget,
|
||||
const GtkSnapshot *snapshot)
|
||||
{
|
||||
GQueue *updates;
|
||||
GskRenderNode *node;
|
||||
@ -287,12 +287,11 @@ gtk_debug_updates_get_render_node (GtkWidget *widget,
|
||||
|
||||
gtk_debug_updates_print (updates, NULL, "Painting at %lli", (long long) timestamp);
|
||||
|
||||
node = gsk_renderer_create_render_node (renderer);
|
||||
gsk_render_node_set_name (node, "Debug Updates");
|
||||
node = gtk_snapshot_create_render_node (snapshot, "Debug Updates");
|
||||
gtk_debug_updates_queue_get_extents (updates, &rect);
|
||||
gsk_render_node_set_bounds (node, &(graphene_rect_t) GRAPHENE_RECT_INIT(rect.x, rect.y, rect.width, rect.height));
|
||||
|
||||
cr = gsk_render_node_get_draw_context (node, renderer);
|
||||
cr = gsk_render_node_get_draw_context (node, gtk_snapshot_get_renderer (snapshot));
|
||||
|
||||
for (l = g_queue_peek_head_link (updates); l != NULL; l = l->next)
|
||||
{
|
||||
|
@ -31,8 +31,8 @@ void gtk_debug_updates_set_enabled_for_display (GdkDisplay
|
||||
|
||||
void gtk_debug_updates_add (GtkWidget *widget,
|
||||
const cairo_region_t *region);
|
||||
GskRenderNode * gtk_debug_updates_get_render_node (GtkWidget *widget,
|
||||
GskRenderer *renderer);
|
||||
GskRenderNode * gtk_debug_updates_snapshot (GtkWidget *widget,
|
||||
const GtkSnapshot *snapshot);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -31,6 +31,19 @@ gtk_snapshot_init (GtkSnapshot *state,
|
||||
graphene_matrix_init_from_matrix (&state->transform, transform);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_snapshot_init_translate (GtkSnapshot *state,
|
||||
const GtkSnapshot *parent,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
|
||||
graphene_matrix_init_translate (&matrix, &(graphene_point3d_t) GRAPHENE_POINT3D_INIT (x, y, 0));
|
||||
|
||||
gtk_snapshot_init (state, parent, &matrix);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_snapshot_init_root (GtkSnapshot *state,
|
||||
GskRenderer *renderer)
|
||||
|
@ -33,9 +33,19 @@ struct _GtkSnapshot {
|
||||
void gtk_snapshot_init (GtkSnapshot *state,
|
||||
const GtkSnapshot *parent,
|
||||
const graphene_matrix_t *transform);
|
||||
void gtk_snapshot_init_translate (GtkSnapshot *state,
|
||||
const GtkSnapshot *parent,
|
||||
int x,
|
||||
int y);
|
||||
void gtk_snapshot_init_root (GtkSnapshot *state,
|
||||
GskRenderer *renderer);
|
||||
|
||||
static inline const graphene_matrix_t *
|
||||
gtk_snapshot_get_transform (const GtkSnapshot *snapshot)
|
||||
{
|
||||
return &snapshot->transform;
|
||||
}
|
||||
|
||||
void gtk_snapshot_finish (GtkSnapshot *state);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -15742,6 +15742,9 @@ gtk_widget_snapshot (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
if (node)
|
||||
gsk_render_node_set_transform (node, gtk_snapshot_get_transform (snapshot));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -447,8 +447,8 @@ static void gtk_window_real_activate_focus (GtkWindow *window);
|
||||
static void gtk_window_keys_changed (GtkWindow *window);
|
||||
static gboolean gtk_window_enable_debugging (GtkWindow *window,
|
||||
gboolean toggle);
|
||||
static GskRenderNode *gtk_window_get_render_node (GtkWidget *widget,
|
||||
GskRenderer *renderer);
|
||||
static GskRenderNode *gtk_window_snapshot (GtkWidget *widget,
|
||||
const GtkSnapshot *snapshot);
|
||||
static void gtk_window_unset_transient_for (GtkWindow *window);
|
||||
static void gtk_window_transient_parent_realized (GtkWidget *parent,
|
||||
GtkWidget *window);
|
||||
@ -776,7 +776,7 @@ gtk_window_class_init (GtkWindowClass *klass)
|
||||
widget_class->measure = gtk_window_measure;
|
||||
widget_class->state_flags_changed = gtk_window_state_flags_changed;
|
||||
widget_class->style_updated = gtk_window_style_updated;
|
||||
widget_class->get_render_node = gtk_window_get_render_node;
|
||||
widget_class->snapshot = gtk_window_snapshot;
|
||||
widget_class->queue_draw_region = gtk_window_queue_draw_region;
|
||||
|
||||
container_class->remove = gtk_window_remove;
|
||||
@ -9384,8 +9384,8 @@ gtk_window_compute_hints (GtkWindow *window,
|
||||
***********************/
|
||||
|
||||
static GskRenderNode *
|
||||
gtk_window_get_render_node (GtkWidget *widget,
|
||||
GskRenderer *renderer)
|
||||
gtk_window_snapshot (GtkWidget *widget,
|
||||
const GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
|
||||
GtkStyleContext *context;
|
||||
@ -9397,6 +9397,7 @@ gtk_window_get_render_node (GtkWidget *widget,
|
||||
graphene_matrix_t m;
|
||||
graphene_point3d_t p;
|
||||
cairo_t *cr;
|
||||
GList *l;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
@ -9406,12 +9407,11 @@ gtk_window_get_render_node (GtkWidget *widget,
|
||||
graphene_rect_init (&bounds, allocation.x, allocation.y, allocation.width, allocation.height);
|
||||
graphene_matrix_init_translate (&m, graphene_point3d_init (&p, allocation.x, allocation.y, 0.));
|
||||
|
||||
node = gsk_renderer_create_render_node (renderer);
|
||||
gsk_render_node_set_name (node, "Window Decoration");
|
||||
node = gtk_snapshot_create_render_node (snapshot, "Window Decoration");
|
||||
gsk_render_node_set_bounds (node, &bounds);
|
||||
gsk_render_node_set_transform (node, &m);
|
||||
|
||||
cr = gsk_render_node_get_draw_context (node, renderer);
|
||||
cr = gsk_render_node_get_draw_context (node, gtk_snapshot_get_renderer (snapshot));
|
||||
|
||||
if (priv->client_decorated &&
|
||||
priv->decorated &&
|
||||
@ -9478,9 +9478,19 @@ gtk_window_get_render_node (GtkWidget *widget,
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
gtk_container_propagate_render_node (GTK_CONTAINER (widget), renderer, node);
|
||||
if (priv->title_box != NULL)
|
||||
gtk_container_snapshot_child (GTK_CONTAINER (widget), node, priv->title_box, snapshot);
|
||||
|
||||
updates_node = gtk_debug_updates_get_render_node (widget, renderer);
|
||||
if (gtk_bin_get_child (GTK_BIN (widget)))
|
||||
gtk_container_snapshot_child (GTK_CONTAINER (widget), node, gtk_bin_get_child (GTK_BIN (widget)), snapshot);
|
||||
|
||||
for (l = priv->popovers; l; l = l->next)
|
||||
{
|
||||
GtkWindowPopover *data = l->data;
|
||||
gtk_container_snapshot_child (GTK_CONTAINER (widget), node, data->widget, snapshot);
|
||||
}
|
||||
|
||||
updates_node = gtk_debug_updates_snapshot (widget, snapshot);
|
||||
if (updates_node)
|
||||
{
|
||||
gsk_render_node_append_child (node, updates_node);
|
||||
|
Loading…
Reference in New Issue
Block a user