snapshot: Add gtk_snapshot_to_paintable()
authorBenjamin Otte <otte@redhat.com>
Mon, 26 Mar 2018 02:37:01 +0000 (04:37 +0200)
committerBenjamin Otte <otte@redhat.com>
Mon, 26 Mar 2018 16:16:36 +0000 (18:16 +0200)
This is intended for DND icons

docs/reference/gtk/gtk4-sections.txt
gtk/gtkrendernodepaintable.c [new file with mode: 0644]
gtk/gtkrendernodepaintableprivate.h [new file with mode: 0644]
gtk/gtksnapshot.c
gtk/gtksnapshot.h
gtk/meson.build

index 374124bc9a6abadf05b0f53cd55b2c206d556801..64603bc9257d7971b57ef6456461297de728c020 100644 (file)
@@ -4171,7 +4171,9 @@ gtk_snapshot_new
 gtk_snapshot_ref
 gtk_snapshot_unref
 gtk_snapshot_to_node
+gtk_snapshot_to_paintable
 gtk_snapshot_free_to_node
+gtk_snapshot_free_to_paintable
 gtk_snapshot_get_renderer
 gtk_snapshot_get_record_names
 gtk_snapshot_push
diff --git a/gtk/gtkrendernodepaintable.c b/gtk/gtkrendernodepaintable.c
new file mode 100644 (file)
index 0000000..18c36a7
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "config.h"
+
+#include "gtkrendernodepaintableprivate.h"
+
+#include "gtksnapshot.h"
+
+struct _GtkRenderNodePaintable
+{
+  GObject parent_instance;
+
+  GskRenderNode *node;
+};
+
+struct _GtkRenderNodePaintableClass
+{
+  GObjectClass parent_class;
+};
+
+static void
+gtk_render_node_paintable_paintable_snapshot (GdkPaintable *paintable,
+                                              GdkSnapshot  *snapshot,
+                                              double        width,
+                                              double        height)
+{
+  GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
+  graphene_rect_t node_bounds;
+
+  gsk_render_node_get_bounds (self->node, &node_bounds);
+
+  if (node_bounds.origin.x + node_bounds.size.width != width ||
+      node_bounds.origin.y + node_bounds.size.height != height)
+    {
+      graphene_matrix_t transform;
+
+      graphene_matrix_init_scale (&transform,
+                                  width / (node_bounds.origin.x + node_bounds.size.width),
+                                  height / (node_bounds.origin.y + node_bounds.size.height),
+                                  1.0);
+      gtk_snapshot_push_transform (snapshot,
+                                   &transform,
+                                   "RenderNodeScaleToFit");
+      gtk_snapshot_append_node (snapshot, self->node);
+      gtk_snapshot_pop (snapshot);
+    }
+  else
+    {
+      gtk_snapshot_append_node (snapshot, self->node);
+    }
+}
+
+static GdkPaintableFlags
+gtk_render_node_paintable_paintable_get_flags (GdkPaintable *paintable)
+{
+  return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
+}
+
+static int
+gtk_render_node_paintable_paintable_get_intrinsic_width (GdkPaintable *paintable)
+{
+  GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
+  graphene_rect_t node_bounds;
+
+  gsk_render_node_get_bounds (self->node, &node_bounds);
+
+  return node_bounds.origin.x + node_bounds.size.width;
+}
+
+static int
+gtk_render_node_paintable_paintable_get_intrinsic_height (GdkPaintable *paintable)
+{
+  GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
+  graphene_rect_t node_bounds;
+
+  gsk_render_node_get_bounds (self->node, &node_bounds);
+
+  return node_bounds.origin.y + node_bounds.size.height;
+}
+
+static void
+gtk_render_node_paintable_paintable_init (GdkPaintableInterface *iface)
+{
+  iface->snapshot = gtk_render_node_paintable_paintable_snapshot;
+  iface->get_flags = gtk_render_node_paintable_paintable_get_flags;
+  iface->get_intrinsic_width = gtk_render_node_paintable_paintable_get_intrinsic_width;
+  iface->get_intrinsic_height = gtk_render_node_paintable_paintable_get_intrinsic_height;
+}
+
+G_DEFINE_TYPE_EXTENDED (GtkRenderNodePaintable, gtk_render_node_paintable, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
+                                               gtk_render_node_paintable_paintable_init))
+
+static void
+gtk_render_node_paintable_dispose (GObject *object)
+{
+  GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (object);
+
+  g_clear_pointer (&self->node, gsk_render_node_unref);
+
+  G_OBJECT_CLASS (gtk_render_node_paintable_parent_class)->dispose (object);
+}
+
+static void
+gtk_render_node_paintable_class_init (GtkRenderNodePaintableClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->dispose = gtk_render_node_paintable_dispose;
+}
+
+static void
+gtk_render_node_paintable_init (GtkRenderNodePaintable *self)
+{
+}
+
+GdkPaintable *
+gtk_render_node_paintable_new (GskRenderNode *node)
+{
+  GtkRenderNodePaintable *self;
+
+  g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
+
+  self = g_object_new (GTK_TYPE_RENDER_NODE_PAINTABLE, NULL);
+
+  self->node = gsk_render_node_ref (node);
+
+  return GDK_PAINTABLE (self);
+}
diff --git a/gtk/gtkrendernodepaintableprivate.h b/gtk/gtkrendernodepaintableprivate.h
new file mode 100644 (file)
index 0000000..1eba80e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_RENDER_NODE_PAINTABLE_H__
+#define __GTK_RENDER_NODE_PAINTABLE_H__
+
+#include <gsk/gsk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_RENDER_NODE_PAINTABLE (gtk_render_node_paintable_get_type ())
+
+G_DECLARE_FINAL_TYPE (GtkRenderNodePaintable, gtk_render_node_paintable, GTK, RENDER_NODE_PAINTABLE, GObject)
+
+GdkPaintable *  gtk_render_node_paintable_new   (GskRenderNode  *node);
+
+G_END_DECLS
+
+#endif /* __GTK_RENDER_NODE_PAINTABLE_H__ */
index 609a0c6473667edde94d8215100881cdcf0d7729..2fe1e783e2a1c73d8fc87e4801960719390ff93a 100644 (file)
@@ -25,6 +25,7 @@
 #include "gtkrenderbackgroundprivate.h"
 #include "gtkrenderborderprivate.h"
 #include "gtkrendericonprivate.h"
+#include "gtkrendernodepaintableprivate.h"
 #include "gtkstylecontextprivate.h"
 
 #include "gsk/gskrendernodeprivate.h"
@@ -222,6 +223,26 @@ gtk_snapshot_free_to_node (GtkSnapshot *snapshot)
   return result;
 }
 
+/**
+ * gtk_snapshot_free_to_paintable: (skip)
+ * @snapshot: (transfer full): a #GtkSnapshot
+ *
+ * Returns a paintable for the node that was
+ * constructed by @snapshot and frees @snapshot.
+ *
+ * Returns: a newly-created #GdkPaintable
+ */
+GdkPaintable *
+gtk_snapshot_free_to_paintable (GtkSnapshot *snapshot)
+{
+  GdkPaintable *result;
+
+  result = gtk_snapshot_to_paintable (snapshot);
+  g_object_unref (snapshot);
+
+  return result;
+}
+
 /**
  * gtk_snapshot_push:
  * @snapshot: a #GtkSnapshot
@@ -1268,6 +1289,31 @@ gtk_snapshot_to_node (GtkSnapshot *snapshot)
   return result;
 }
 
+/**
+ * gtk_snapshot_to_paintable:
+ * @snapshot: a #GtkSnapshot
+ *
+ * Returns a paintable encapsulating the render node
+ * that was constructed by @snapshot. After calling
+ * this function, it is no longer possible to add more
+ * nodes to @snapshot. The only function that should be
+ * called after this is gtk_snapshot_unref().
+ *
+ * Returns: a new #GdkPaintable
+ */
+GdkPaintable *
+gtk_snapshot_to_paintable (GtkSnapshot *snapshot)
+{
+  GskRenderNode *node;
+  GdkPaintable *paintable;
+
+  node = gtk_snapshot_to_node (snapshot);
+  paintable = gtk_render_node_paintable_new (node);
+  gsk_render_node_unref (node);
+
+  return paintable;
+}
+
 /**
  * gtk_snapshot_pop:
  * @snapshot: a #GtkSnapshot
index db9d4e6d7860b2c564c2930ab83848e3cfaa6dd1..add8cdd0b5bdfb198336adecb2f77af1464b2877 100644 (file)
@@ -58,9 +58,13 @@ GtkSnapshot *   gtk_snapshot_new                        (gboolean
                                                          ...) G_GNUC_PRINTF (3, 4);
 GDK_AVAILABLE_IN_ALL
 GskRenderNode * gtk_snapshot_free_to_node               (GtkSnapshot            *snapshot);
+GDK_AVAILABLE_IN_ALL
+GdkPaintable *  gtk_snapshot_free_to_paintable          (GtkSnapshot            *snapshot);
 
 GDK_AVAILABLE_IN_ALL
 GskRenderNode * gtk_snapshot_to_node                    (GtkSnapshot            *snapshot);
+GDK_AVAILABLE_IN_ALL
+GdkPaintable *  gtk_snapshot_to_paintable               (GtkSnapshot            *snapshot);
 
 GDK_AVAILABLE_IN_ALL
 gboolean        gtk_snapshot_get_record_names           (GtkSnapshot            *snapshot);
index c06b5aa07545f861747de49f71d1b358fe285d19..a0b3932d572a0c0a2becd2f22d477ed05eb6a563 100644 (file)
@@ -291,6 +291,7 @@ gtk_public_sources = files([
   'gtkrenderbackground.c',
   'gtkrenderborder.c',
   'gtkrendericon.c',
+  'gtkrendernodepaintable.c',
   'gtkrevealer.c',
   'gtkroundedbox.c',
   'gtkscale.c',