summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte.benjamin@googlemail.com>2018-06-11 11:55:09 +0000
committerBenjamin Otte <otte.benjamin@googlemail.com>2018-06-11 11:55:09 +0000
commitb22f45b2f678840db63b83d77cf72013903bfe9e (patch)
tree92891e9ec9cb90125e5b4fa88b8b2bfc13f11140
parent4f632296a57ee3df809c2a405ac5fb93550aa98e (diff)
parent0d46081645266d150d82539fb75e82f30e44081e (diff)
downloadgtk+-b22f45b2f678840db63b83d77cf72013903bfe9e.tar.gz
Merge branch 'wip/sadiq/fixes' into 'master'
overlay: Add support for clipping overlay widgets See merge request GNOME/gtk!189
-rw-r--r--docs/reference/gtk/gtk4-sections.txt2
-rw-r--r--gtk/gtkoverlay.c115
-rw-r--r--gtk/gtkoverlay.h7
3 files changed, 121 insertions, 3 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 440482b971..ef1eaa0f0e 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -6017,6 +6017,8 @@ gtk_overlay_get_overlay_pass_through
gtk_overlay_set_overlay_pass_through
gtk_overlay_get_measure_overlay
gtk_overlay_set_measure_overlay
+gtk_overlay_get_clip_overlay
+gtk_overlay_set_clip_overlay
<SUBSECTION Standard>
GTK_TYPE_OVERLAY
diff --git a/gtk/gtkoverlay.c b/gtk/gtkoverlay.c
index 0b2b44e3f0..5142624343 100644
--- a/gtk/gtkoverlay.c
+++ b/gtk/gtkoverlay.c
@@ -66,6 +66,7 @@ struct _GtkOverlayChild
{
guint pass_through : 1;
guint measure : 1;
+ guint clip_overlay : 1;
double blur;
};
@@ -80,7 +81,8 @@ enum
CHILD_PROP_PASS_THROUGH,
CHILD_PROP_MEASURE,
CHILD_PROP_BLUR,
- CHILD_PROP_INDEX
+ CHILD_PROP_INDEX,
+ CHILD_PROP_CLIP_OVERLAY
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -574,6 +576,17 @@ gtk_overlay_set_child_property (GtkContainer *container,
child,
g_value_get_int (value));
break;
+ case CHILD_PROP_CLIP_OVERLAY:
+ if (child_info)
+ {
+ if (g_value_get_boolean (value) != child_info->clip_overlay)
+ {
+ child_info->clip_overlay = g_value_get_boolean (value);
+ gtk_container_child_notify (container, child, "clip-overlay");
+ gtk_widget_queue_resize (GTK_WIDGET (overlay));
+ }
+ }
+ break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
@@ -637,6 +650,12 @@ gtk_overlay_get_child_property (GtkContainer *container,
g_value_set_int (value, pos);
break;
+ case CHILD_PROP_CLIP_OVERLAY:
+ if (child_info)
+ g_value_set_boolean (value, child_info->clip_overlay);
+ else
+ g_value_set_boolean (value, FALSE);
+ break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
@@ -644,6 +663,31 @@ gtk_overlay_get_child_property (GtkContainer *container,
}
static void
+gtk_overlay_snapshot_child (GtkWidget *overlay,
+ GtkWidget *child,
+ GtkSnapshot *snapshot)
+{
+ graphene_rect_t bounds;
+ gboolean clip_set;
+
+ clip_set = gtk_overlay_get_clip_overlay (GTK_OVERLAY (overlay), child);
+
+ if (!clip_set)
+ {
+ gtk_widget_snapshot_child (overlay, child, snapshot);
+ return;
+ }
+
+ graphene_rect_init (&bounds, 0, 0,
+ gtk_widget_get_width (overlay),
+ gtk_widget_get_height (overlay));
+
+ gtk_snapshot_push_clip (snapshot, &bounds);
+ gtk_widget_snapshot_child (overlay, child, snapshot);
+ gtk_snapshot_pop (snapshot);
+}
+
+static void
gtk_overlay_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
@@ -702,7 +746,12 @@ gtk_overlay_snapshot (GtkWidget *widget,
if (clip == NULL)
{
- GTK_WIDGET_CLASS (gtk_overlay_parent_class)->snapshot (widget, snapshot);
+ for (child = _gtk_widget_get_first_child (widget);
+ child != NULL;
+ child = _gtk_widget_get_next_sibling (child))
+ {
+ gtk_overlay_snapshot_child (widget, child, snapshot);
+ }
return;
}
@@ -725,7 +774,7 @@ gtk_overlay_snapshot (GtkWidget *widget,
child = _gtk_widget_get_next_sibling (child))
{
if (child != main_widget)
- gtk_widget_snapshot_child (widget, child, snapshot);
+ gtk_overlay_snapshot_child (widget, child, snapshot);
}
gsk_render_node_unref (main_widget_node);
@@ -792,6 +841,18 @@ gtk_overlay_class_init (GtkOverlayClass *klass)
P_("The index of the overlay in the parent, -1 for the main child"),
-1, G_MAXINT, 0,
GTK_PARAM_READWRITE));
+ /**
+ * GtkOverlay:clip-overlay:
+ *
+ * Clip the overlay child widget so as to fit the parent
+ */
+ gtk_container_class_install_child_property (container_class, CHILD_PROP_PASS_THROUGH,
+ g_param_spec_boolean ("clip-overlay",
+ P_("Clip Overlay"),
+ P_("Clip the overlay child widget so as to fit the parent"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
/**
* GtkOverlay::get-child-position:
@@ -1014,3 +1075,51 @@ gtk_overlay_get_measure_overlay (GtkOverlay *overlay,
return measure;
}
+
+/**
+ * gtk_overlay_set_clip_overlay:
+ * @overlay: a #GtkOverlay
+ * @widget: an overlay child of #GtkOverlay
+ * @clip_overlay: whether the child should be clipped
+ *
+ * Convenience function to set the value of the #GtkOverlay:clip-overlay
+ * child property for @widget.
+ */
+void
+gtk_overlay_set_clip_overlay (GtkOverlay *overlay,
+ GtkWidget *widget,
+ gboolean clip_overlay)
+{
+ g_return_if_fail (GTK_IS_OVERLAY (overlay));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ gtk_container_child_set (GTK_CONTAINER (overlay), widget,
+ "clip-overlay", clip_overlay,
+ NULL);
+}
+
+/**
+ * gtk_overlay_get_overlay_clip_overlay:
+ * @overlay: a #GtkOverlay
+ * @widget: an overlay child of #GtkOverlay
+ *
+ * Convenience function to get the value of the #GtkOverlay:clip-overlay
+ * child property for @widget.
+ *
+ * Returns: whether the widget is clipped within the parent.
+ */
+gboolean
+gtk_overlay_get_clip_overlay (GtkOverlay *overlay,
+ GtkWidget *widget)
+{
+ gboolean clip_overlay;
+
+ g_return_val_if_fail (GTK_IS_OVERLAY (overlay), FALSE);
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ gtk_container_child_get (GTK_CONTAINER (overlay), widget,
+ "clip-overlay", &clip_overlay,
+ NULL);
+
+ return clip_overlay;
+}
diff --git a/gtk/gtkoverlay.h b/gtk/gtkoverlay.h
index 0cd3aa891a..bf5bf7fead 100644
--- a/gtk/gtkoverlay.h
+++ b/gtk/gtkoverlay.h
@@ -99,6 +99,13 @@ GDK_AVAILABLE_IN_ALL
void gtk_overlay_set_measure_overlay (GtkOverlay *overlay,
GtkWidget *widget,
gboolean measure);
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_overlay_get_clip_overlay (GtkOverlay *overlay,
+ GtkWidget *widget);
+GDK_AVAILABLE_IN_ALL
+void gtk_overlay_set_clip_overlay (GtkOverlay *overlay,
+ GtkWidget *widget,
+ gboolean clip_overlay);
G_END_DECLS