[gtk+/wip/matthiasc/fancy-overlay: 24/26] Add a blur child property to GtkOverlay
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/fancy-overlay: 24/26] Add a blur child property to GtkOverlay
- Date: Mon, 4 Sep 2017 00:52:28 +0000 (UTC)
commit c9eb292362d0b139461d1906086a72b663d9e11c
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Sep 2 20:42:47 2017 -0400
Add a blur child property to GtkOverlay
When set, it blurs the content behind the child.
gtk/gtkoverlay.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 103 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkoverlay.c b/gtk/gtkoverlay.c
index 9c46f34..97ee9eb 100644
--- a/gtk/gtkoverlay.c
+++ b/gtk/gtkoverlay.c
@@ -25,6 +25,7 @@
#include "gtkscrolledwindow.h"
#include "gtkwidgetprivate.h"
#include "gtkmarshalers.h"
+#include "gtksnapshot.h"
#include "gtkprivate.h"
#include "gtkintl.h"
@@ -65,6 +66,7 @@ struct _GtkOverlayChild
{
GtkWidget *widget;
gboolean pass_through;
+ double blur;
};
enum {
@@ -76,6 +78,7 @@ enum
{
CHILD_PROP_0,
CHILD_PROP_PASS_THROUGH,
+ CHILD_PROP_BLUR,
CHILD_PROP_INDEX
};
@@ -539,6 +542,17 @@ gtk_overlay_set_child_property (GtkContainer *container,
}
}
break;
+ case CHILD_PROP_BLUR:
+ if (child_info)
+ {
+ if (g_value_get_double (value) != child_info->blur)
+ {
+ child_info->blur = g_value_get_double (value);
+ gtk_container_child_notify (container, child, "blur");
+ gtk_widget_queue_draw (GTK_WIDGET (overlay));
+ }
+ }
+ break;
case CHILD_PROP_INDEX:
if (child_info != NULL)
gtk_overlay_reorder_overlay (GTK_OVERLAY (container),
@@ -585,6 +599,12 @@ gtk_overlay_get_child_property (GtkContainer *container,
else
g_value_set_boolean (value, FALSE);
break;
+ case CHILD_PROP_BLUR:
+ if (child_info)
+ g_value_set_double (value, child_info->blur);
+ else
+ g_value_set_double (value, 0);
+ break;
case CHILD_PROP_INDEX:
g_value_set_int (value, g_slist_index (priv->children, child_info));
break;
@@ -594,6 +614,77 @@ gtk_overlay_get_child_property (GtkContainer *container,
}
}
+static void
+gtk_overlay_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ GtkWidget *main_widget;
+ GtkWidget *child;
+ GtkAllocation main_alloc;
+ cairo_region_t *clip = NULL;
+ int i;
+
+ main_widget = gtk_bin_get_child (GTK_BIN (widget));
+ gtk_widget_get_allocation (widget, &main_alloc);
+
+ for (child = _gtk_widget_get_first_child (widget);
+ child != NULL;
+ child = _gtk_widget_get_next_sibling (child))
+ {
+ double blur;
+ gtk_container_child_get (GTK_CONTAINER (widget), child, "blur", &blur, NULL);
+ if (blur > 0)
+ {
+ GtkAllocation alloc;
+ graphene_rect_t bounds;
+
+ gtk_widget_get_allocation (child, &alloc);
+ graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
+ gtk_snapshot_push_clip (snapshot, &bounds, "Overlay Effect Clip");
+ gtk_snapshot_push_blur (snapshot, blur, "Overlay Effect");
+ gtk_widget_snapshot_child (widget, main_widget, snapshot);
+ gtk_snapshot_pop (snapshot);
+ gtk_snapshot_pop (snapshot);
+
+ if (clip == NULL)
+ {
+ clip = cairo_region_create ();
+ main_alloc.x = main_alloc.y = 0;
+ cairo_region_union_rectangle (clip, (cairo_rectangle_int_t *)&main_alloc);
+ }
+
+ cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
+ }
+ }
+
+ if (clip == NULL)
+ {
+ GTK_WIDGET_CLASS (gtk_overlay_parent_class)->snapshot (widget, snapshot);
+ return;
+ }
+
+ for (i = 0; i < cairo_region_num_rectangles (clip); i++)
+ {
+ cairo_rectangle_int_t rect;
+ graphene_rect_t bounds;
+
+ cairo_region_get_rectangle (clip, i, &rect);
+ graphene_rect_init (&bounds, rect.x, rect.y, rect.width, rect.height);
+ gtk_snapshot_push_clip (snapshot, &bounds, "Overlay Non-Effect Clip");
+ gtk_widget_snapshot_child (widget, main_widget, snapshot);
+ gtk_snapshot_pop (snapshot);
+ }
+
+ cairo_region_destroy (clip);
+
+ for (child = _gtk_widget_get_first_child (widget);
+ child != NULL;
+ child = _gtk_widget_get_next_sibling (child))
+ {
+ if (child != main_widget)
+ gtk_widget_snapshot_child (widget, child, snapshot);
+ }
+}
static void
gtk_overlay_class_init (GtkOverlayClass *klass)
@@ -603,6 +694,7 @@ gtk_overlay_class_init (GtkOverlayClass *klass)
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
widget_class->size_allocate = gtk_overlay_size_allocate;
+ widget_class->snapshot = gtk_overlay_snapshot;
container_class->add = gtk_overlay_add;
container_class->remove = gtk_overlay_remove;
@@ -625,6 +717,17 @@ gtk_overlay_class_init (GtkOverlayClass *klass)
GTK_PARAM_READWRITE));
/**
+ * GtkOverlay:blur:
+ *
+ * Blur the content behind this child with a Gaussian blur of this radius.
+ *
+ * Since: 3.92
+ */
+ gtk_container_class_install_child_property (container_class, CHILD_PROP_BLUR,
+ g_param_spec_double ("blur", P_("Blur Radius"), P_("Apply a blur to the content behind this child"),
+ 0, 100, 0,
+ GTK_PARAM_READWRITE));
+ /**
* GtkOverlay:index:
*
* The index of the overlay in the parent, -1 for the main child.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]