mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
Merge branch 'overlay-cleanup' into 'master'
Overlay cleanup See merge request GNOME/gtk!600
This commit is contained in:
commit
41c0ac1a68
482
demos/gtk-demo/bluroverlay.c
Normal file
482
demos/gtk-demo/bluroverlay.c
Normal file
@ -0,0 +1,482 @@
|
||||
/*
|
||||
* bluroverlay.c
|
||||
* This file is part of gtk
|
||||
*
|
||||
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
|
||||
#include "bluroverlay.h"
|
||||
|
||||
/*
|
||||
* This is a cut-down copy of gtkoverlay.c with a custom snapshot
|
||||
* function that support a limited form of blur-under.
|
||||
*/
|
||||
typedef struct _BlurOverlayChild BlurOverlayChild;
|
||||
|
||||
struct _BlurOverlayChild
|
||||
{
|
||||
double blur;
|
||||
};
|
||||
|
||||
enum {
|
||||
GET_CHILD_POSITION,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
static GQuark child_data_quark = 0;
|
||||
|
||||
G_DEFINE_TYPE (BlurOverlay, blur_overlay, GTK_TYPE_BIN)
|
||||
|
||||
static void
|
||||
blur_overlay_set_overlay_child (GtkWidget *widget,
|
||||
BlurOverlayChild *child_data)
|
||||
{
|
||||
g_object_set_qdata_full (G_OBJECT (widget), child_data_quark, child_data, g_free);
|
||||
}
|
||||
|
||||
static BlurOverlayChild *
|
||||
blur_overlay_get_overlay_child (GtkWidget *widget)
|
||||
{
|
||||
return (BlurOverlayChild *) g_object_get_qdata (G_OBJECT (widget), child_data_quark);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
int child_min, child_nat, child_min_baseline, child_nat_baseline;
|
||||
|
||||
gtk_widget_measure (child,
|
||||
orientation,
|
||||
for_size,
|
||||
&child_min, &child_nat,
|
||||
&child_min_baseline, &child_nat_baseline);
|
||||
|
||||
*minimum = MAX (*minimum, child_min);
|
||||
*natural = MAX (*natural, child_nat);
|
||||
if (child_min_baseline > -1)
|
||||
*minimum_baseline = MAX (*minimum_baseline, child_min_baseline);
|
||||
if (child_nat_baseline > -1)
|
||||
*natural_baseline = MAX (*natural_baseline, child_nat_baseline);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_compute_child_allocation (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
BlurOverlayChild *child,
|
||||
GtkAllocation *widget_allocation)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
gboolean result;
|
||||
|
||||
g_signal_emit (overlay, signals[GET_CHILD_POSITION],
|
||||
0, widget, &allocation, &result);
|
||||
|
||||
widget_allocation->x = allocation.x;
|
||||
widget_allocation->y = allocation.y;
|
||||
widget_allocation->width = allocation.width;
|
||||
widget_allocation->height = allocation.height;
|
||||
}
|
||||
|
||||
static GtkAlign
|
||||
effective_align (GtkAlign align,
|
||||
GtkTextDirection direction)
|
||||
{
|
||||
switch (align)
|
||||
{
|
||||
case GTK_ALIGN_START:
|
||||
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
|
||||
case GTK_ALIGN_END:
|
||||
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
|
||||
case GTK_ALIGN_FILL:
|
||||
case GTK_ALIGN_CENTER:
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
return align;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_child_update_style_classes (BlurOverlay *overlay,
|
||||
GtkWidget *child,
|
||||
GtkAllocation *child_allocation)
|
||||
{
|
||||
int width, height;
|
||||
GtkAlign valign, halign;
|
||||
gboolean is_left, is_right, is_top, is_bottom;
|
||||
gboolean has_left, has_right, has_top, has_bottom;
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (child);
|
||||
has_left = gtk_style_context_has_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
has_right = gtk_style_context_has_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
has_top = gtk_style_context_has_class (context, GTK_STYLE_CLASS_TOP);
|
||||
has_bottom = gtk_style_context_has_class (context, GTK_STYLE_CLASS_BOTTOM);
|
||||
|
||||
is_left = is_right = is_top = is_bottom = FALSE;
|
||||
|
||||
width = gtk_widget_get_width (GTK_WIDGET (overlay));
|
||||
height = gtk_widget_get_height (GTK_WIDGET (overlay));
|
||||
|
||||
halign = effective_align (gtk_widget_get_halign (child),
|
||||
gtk_widget_get_direction (child));
|
||||
|
||||
if (halign == GTK_ALIGN_START)
|
||||
is_left = (child_allocation->x == 0);
|
||||
else if (halign == GTK_ALIGN_END)
|
||||
is_right = (child_allocation->x + child_allocation->width == width);
|
||||
|
||||
valign = gtk_widget_get_valign (child);
|
||||
|
||||
if (valign == GTK_ALIGN_START)
|
||||
is_top = (child_allocation->y == 0);
|
||||
else if (valign == GTK_ALIGN_END)
|
||||
is_bottom = (child_allocation->y + child_allocation->height == height);
|
||||
|
||||
if (has_left && !is_left)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
else if (!has_left && is_left)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
|
||||
if (has_right && !is_right)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
else if (!has_right && is_right)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
|
||||
if (has_top && !is_top)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TOP);
|
||||
else if (!has_top && is_top)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
|
||||
|
||||
if (has_bottom && !is_bottom)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BOTTOM);
|
||||
else if (!has_bottom && is_bottom)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_child_allocate (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
BlurOverlayChild *child)
|
||||
{
|
||||
GtkAllocation child_allocation;
|
||||
|
||||
if (!gtk_widget_get_visible (widget))
|
||||
return;
|
||||
|
||||
blur_overlay_compute_child_allocation (overlay, widget, child, &child_allocation);
|
||||
|
||||
blur_overlay_child_update_style_classes (overlay, widget, &child_allocation);
|
||||
gtk_widget_size_allocate (widget, &child_allocation, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (widget);
|
||||
GtkWidget *child;
|
||||
GtkWidget *main_widget;
|
||||
|
||||
main_widget = gtk_bin_get_child (GTK_BIN (overlay));
|
||||
if (main_widget && gtk_widget_get_visible (main_widget))
|
||||
gtk_widget_size_allocate (main_widget,
|
||||
&(GtkAllocation) {
|
||||
0, 0,
|
||||
width, height
|
||||
}, -1);
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (child != main_widget)
|
||||
{
|
||||
BlurOverlayChild *child_data = blur_overlay_get_overlay_child (child);
|
||||
blur_overlay_child_allocate (overlay, child, child_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
blur_overlay_get_child_position (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
GtkAllocation *alloc)
|
||||
{
|
||||
GtkRequisition min, req;
|
||||
GtkAlign halign;
|
||||
GtkTextDirection direction;
|
||||
int width, height;
|
||||
|
||||
gtk_widget_get_preferred_size (widget, &min, &req);
|
||||
width = gtk_widget_get_width (GTK_WIDGET (overlay));
|
||||
height = gtk_widget_get_height (GTK_WIDGET (overlay));
|
||||
|
||||
alloc->x = 0;
|
||||
alloc->width = MAX (min.width, MIN (width, req.width));
|
||||
|
||||
direction = gtk_widget_get_direction (widget);
|
||||
|
||||
halign = gtk_widget_get_halign (widget);
|
||||
switch (effective_align (halign, direction))
|
||||
{
|
||||
case GTK_ALIGN_START:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case GTK_ALIGN_FILL:
|
||||
alloc->width = MAX (alloc->width, width);
|
||||
break;
|
||||
case GTK_ALIGN_CENTER:
|
||||
alloc->x += width / 2 - alloc->width / 2;
|
||||
break;
|
||||
case GTK_ALIGN_END:
|
||||
alloc->x += width - alloc->width;
|
||||
break;
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
alloc->y = 0;
|
||||
alloc->height = MAX (min.height, MIN (height, req.height));
|
||||
|
||||
switch (gtk_widget_get_valign (widget))
|
||||
{
|
||||
case GTK_ALIGN_START:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case GTK_ALIGN_FILL:
|
||||
alloc->height = MAX (alloc->height, height);
|
||||
break;
|
||||
case GTK_ALIGN_CENTER:
|
||||
alloc->y += height / 2 - alloc->height / 2;
|
||||
break;
|
||||
case GTK_ALIGN_END:
|
||||
alloc->y += height - alloc->height;
|
||||
break;
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_add (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (container);
|
||||
gtk_widget_insert_after (widget, GTK_WIDGET (container), NULL);
|
||||
overlay->main_widget = widget;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_remove (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (container);
|
||||
gtk_widget_unparent (widget);
|
||||
if (overlay->main_widget == widget)
|
||||
overlay->main_widget = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_forall (GtkContainer *overlay,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (overlay));
|
||||
while (child != NULL)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
|
||||
(* callback) (child, callback_data);
|
||||
|
||||
child = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *main_widget;
|
||||
GskRenderNode *main_widget_node = NULL;
|
||||
GtkWidget *child;
|
||||
GtkAllocation main_alloc;
|
||||
cairo_region_t *clip = NULL;
|
||||
int i;
|
||||
|
||||
main_widget = BLUR_OVERLAY (widget)->main_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))
|
||||
{
|
||||
BlurOverlayChild *child_info = blur_overlay_get_overlay_child (child);
|
||||
double blur = 0;
|
||||
if (child_info)
|
||||
blur = child_info->blur;
|
||||
|
||||
if (blur > 0)
|
||||
{
|
||||
GtkAllocation alloc;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
if (main_widget_node == NULL)
|
||||
{
|
||||
GtkSnapshot *child_snapshot;
|
||||
|
||||
child_snapshot = gtk_snapshot_new ();
|
||||
gtk_widget_snapshot_child (widget, main_widget, child_snapshot);
|
||||
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
|
||||
}
|
||||
|
||||
gtk_widget_get_allocation (child, &alloc);
|
||||
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
|
||||
gtk_snapshot_push_blur (snapshot, blur);
|
||||
gtk_snapshot_push_clip (snapshot, &bounds);
|
||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
if (clip == NULL)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = main_alloc.width;
|
||||
rect.height = main_alloc.height;
|
||||
clip = cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
|
||||
}
|
||||
}
|
||||
|
||||
if (clip == NULL)
|
||||
{
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
gtk_widget_snapshot_child (widget, child, 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);
|
||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
||||
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);
|
||||
}
|
||||
|
||||
gsk_render_node_unref (main_widget_node);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_class_init (BlurOverlayClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
widget_class->measure = blur_overlay_measure;
|
||||
widget_class->size_allocate = blur_overlay_size_allocate;
|
||||
widget_class->snapshot = blur_overlay_snapshot;
|
||||
|
||||
container_class->add = blur_overlay_add;
|
||||
container_class->remove = blur_overlay_remove;
|
||||
container_class->forall = blur_overlay_forall;
|
||||
|
||||
klass->get_child_position = blur_overlay_get_child_position;
|
||||
|
||||
signals[GET_CHILD_POSITION] =
|
||||
g_signal_new ("get-child-position",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (BlurOverlayClass, get_child_position),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
NULL,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
GTK_TYPE_WIDGET,
|
||||
GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
|
||||
child_data_quark = g_quark_from_static_string ("gtk-overlay-child-data");
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "overlay");
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_init (BlurOverlay *overlay)
|
||||
{
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (overlay), FALSE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
blur_overlay_new (void)
|
||||
{
|
||||
return g_object_new (BLUR_TYPE_OVERLAY, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
blur_overlay_add_overlay (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
double blur)
|
||||
{
|
||||
BlurOverlayChild *child = g_new0 (BlurOverlayChild, 1);
|
||||
|
||||
gtk_widget_insert_before (widget, GTK_WIDGET (overlay), NULL);
|
||||
|
||||
child->blur = blur;
|
||||
|
||||
blur_overlay_set_overlay_child (widget, child);
|
||||
}
|
65
demos/gtk-demo/bluroverlay.h
Normal file
65
demos/gtk-demo/bluroverlay.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* bluroverlay.h
|
||||
* This file is part of gtk
|
||||
*
|
||||
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
|
||||
*
|
||||
* 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 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __BLUR_OVERLAY_H__
|
||||
#define __BLUR_OVERLAY_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define BLUR_TYPE_OVERLAY (blur_overlay_get_type ())
|
||||
#define BLUR_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BLUR_TYPE_OVERLAY, BlurOverlay))
|
||||
#define BLUR_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BLUR_TYPE_OVERLAY, BlurOverlayClass))
|
||||
#define BLUR_IS_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BLUR_TYPE_OVERLAY))
|
||||
#define BLUR_IS_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BLUR_TYPE_OVERLAY))
|
||||
#define BLUR_OVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BLUR_TYPE_OVERLAY, BlurOverlayClass))
|
||||
|
||||
typedef struct _BlurOverlay BlurOverlay;
|
||||
typedef struct _BlurOverlayClass BlurOverlayClass;
|
||||
|
||||
struct _BlurOverlay
|
||||
{
|
||||
GtkBin parent_instance;
|
||||
|
||||
GtkWidget *main_widget;
|
||||
};
|
||||
|
||||
struct _BlurOverlayClass
|
||||
{
|
||||
GtkBinClass parent_class;
|
||||
|
||||
gboolean (*get_child_position) (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType blur_overlay_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget *blur_overlay_new (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void blur_overlay_add_overlay (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
double blur);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __BLUR_OVERLAY_H__ */
|
@ -247,6 +247,7 @@
|
||||
</gresource>
|
||||
<gresource prefix="/transparent">
|
||||
<file>portland-rose.jpg</file>
|
||||
<file>bluroverlay.c</file>
|
||||
</gresource>
|
||||
<gresource prefix="/markup">
|
||||
<file>markup.txt</file>
|
||||
|
@ -75,7 +75,7 @@ demos = files([
|
||||
|
||||
gtkdemo_deps = [ libgtk_dep, ]
|
||||
|
||||
extra_demo_sources = files(['main.c', 'gtkfishbowl.c', 'fontplane.c', 'gtkgears.c', 'puzzlepiece.c'])
|
||||
extra_demo_sources = files(['main.c', 'gtkfishbowl.c', 'fontplane.c', 'gtkgears.c', 'puzzlepiece.c', 'bluroverlay.c'])
|
||||
|
||||
if harfbuzz_dep.found() and pangoft_dep.found()
|
||||
demos += files('font_features.c')
|
||||
|
@ -57,7 +57,7 @@ do_overlay (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), vbox);
|
||||
gtk_overlay_set_overlay_pass_through (GTK_OVERLAY (overlay), vbox, TRUE);
|
||||
gtk_widget_set_can_pick (vbox, FALSE);
|
||||
gtk_widget_set_halign (vbox, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (vbox, GTK_ALIGN_CENTER);
|
||||
|
||||
|
@ -64,15 +64,15 @@ do_overlay2 (GtkWidget *do_widget)
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
image = gtk_image_new_from_resource ("/overlay2/decor1.png");
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor1.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_overlay_set_overlay_pass_through (GTK_OVERLAY (overlay), image, TRUE);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_START);
|
||||
|
||||
image = gtk_image_new_from_resource ("/overlay2/decor2.png");
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor2.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_overlay_set_overlay_pass_through (GTK_OVERLAY (overlay), image, TRUE);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_END);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "bluroverlay.h"
|
||||
|
||||
GtkWidget *
|
||||
do_transparent (GtkWidget *do_widget)
|
||||
@ -27,7 +28,7 @@ do_transparent (GtkWidget *do_widget)
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Transparency");
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
overlay = blur_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
|
||||
button = gtk_button_new_with_label ("Don't click this button!");
|
||||
@ -38,8 +39,7 @@ do_transparent (GtkWidget *do_widget)
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_START);
|
||||
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_container_child_set (GTK_CONTAINER (overlay), button, "blur", 5.0, NULL);
|
||||
blur_overlay_add_overlay (BLUR_OVERLAY (overlay), button, 5.0);
|
||||
|
||||
button = gtk_button_new_with_label ("Maybe this one?");
|
||||
label = gtk_bin_get_child (GTK_BIN (button));
|
||||
@ -49,8 +49,7 @@ do_transparent (GtkWidget *do_widget)
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_END);
|
||||
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_container_child_set (GTK_CONTAINER (overlay), button, "blur", 5.0, NULL);
|
||||
blur_overlay_add_overlay (BLUR_OVERLAY (overlay), button, 5.0);
|
||||
|
||||
picture = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
|
||||
gtk_container_add (GTK_CONTAINER (overlay), picture);
|
||||
|
@ -4568,6 +4568,8 @@ gtk_widget_set_can_focus
|
||||
gtk_widget_get_focus_on_click
|
||||
gtk_widget_set_focus_on_click
|
||||
gtk_widget_set_focus_child
|
||||
gtk_widget_get_can_pick
|
||||
gtk_widget_set_can_pick
|
||||
gtk_widget_get_has_surface
|
||||
gtk_widget_set_has_surface
|
||||
gtk_widget_get_sensitive
|
||||
@ -6247,9 +6249,6 @@ GtkOverlayClass
|
||||
|
||||
gtk_overlay_new
|
||||
gtk_overlay_add_overlay
|
||||
gtk_overlay_reorder_overlay
|
||||
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
|
||||
|
@ -623,6 +623,15 @@
|
||||
GtkPasswordEntry.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Adapt to changes in GtkOverlay API</title>
|
||||
<para>
|
||||
The GtkOverlay::pass-through child property has been replaced by the
|
||||
GtkWidget::can-pick property. Note that they have the oppositve sense:
|
||||
pass-through == !can-pick.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
288
gtk/gtkoverlay.c
288
gtk/gtkoverlay.c
@ -64,10 +64,8 @@ typedef struct _GtkOverlayChild GtkOverlayChild;
|
||||
|
||||
struct _GtkOverlayChild
|
||||
{
|
||||
guint pass_through : 1;
|
||||
guint measure : 1;
|
||||
guint clip_overlay : 1;
|
||||
double blur;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -80,8 +78,6 @@ enum
|
||||
CHILD_PROP_0,
|
||||
CHILD_PROP_PASS_THROUGH,
|
||||
CHILD_PROP_MEASURE,
|
||||
CHILD_PROP_BLUR,
|
||||
CHILD_PROP_INDEX,
|
||||
CHILD_PROP_CLIP_OVERLAY
|
||||
};
|
||||
|
||||
@ -375,83 +371,10 @@ gtk_overlay_remove (GtkContainer *container,
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWidget *w;
|
||||
|
||||
gtk_widget_unparent (widget);
|
||||
|
||||
for (w = gtk_widget_get_first_child (GTK_WIDGET (container));
|
||||
w != NULL;
|
||||
w = gtk_widget_get_next_sibling (w))
|
||||
{
|
||||
gtk_widget_child_notify (w, "index");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_overlay_reorder_overlay:
|
||||
* @overlay: a #GtkOverlay
|
||||
* @child: the overlaid #GtkWidget to move
|
||||
* @position: the new index for @child in the list of overlay children
|
||||
* of @overlay, starting from 0. If negative, indicates the end of
|
||||
* the list
|
||||
*
|
||||
* Moves @child to a new @index in the list of @overlay children.
|
||||
* The list contains overlays in the order that these were
|
||||
* added to @overlay.
|
||||
*
|
||||
* A widget’s index in the @overlay children list determines which order
|
||||
* the children are drawn if they overlap. The first child is drawn at
|
||||
* the bottom. It also affects the focus order.
|
||||
*/
|
||||
void
|
||||
gtk_overlay_reorder_overlay (GtkOverlay *overlay,
|
||||
GtkWidget *child,
|
||||
gint position)
|
||||
{
|
||||
GtkWidget *w;
|
||||
|
||||
g_return_if_fail (GTK_IS_OVERLAY (overlay));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (overlay));
|
||||
|
||||
if (child == gtk_bin_get_child (GTK_BIN (overlay)))
|
||||
return;
|
||||
|
||||
if (position < 0)
|
||||
{
|
||||
/* Just move it to the end */
|
||||
gtk_widget_insert_before (child, GTK_WIDGET (overlay), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = 0;
|
||||
for (w = gtk_widget_get_first_child (GTK_WIDGET (overlay));
|
||||
w != NULL;
|
||||
w = gtk_widget_get_next_sibling (w))
|
||||
{
|
||||
if (pos == position)
|
||||
break;
|
||||
|
||||
pos ++;
|
||||
}
|
||||
|
||||
if (w == child)
|
||||
return;
|
||||
|
||||
gtk_widget_insert_after (child, GTK_WIDGET (overlay), w);
|
||||
}
|
||||
|
||||
/* Not all indices changed, but notify for all of them, for simplicity. */
|
||||
for (w = gtk_widget_get_first_child (GTK_WIDGET (overlay));
|
||||
w != NULL;
|
||||
w = gtk_widget_get_next_sibling (w))
|
||||
{
|
||||
gtk_widget_child_notify (w, "index");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_overlay_forall (GtkContainer *overlay,
|
||||
GtkCallback callback,
|
||||
@ -497,18 +420,6 @@ gtk_overlay_set_child_property (GtkContainer *container,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case CHILD_PROP_PASS_THROUGH:
|
||||
/* Ignore value on main child */
|
||||
if (child_info)
|
||||
{
|
||||
if (g_value_get_boolean (value) != child_info->pass_through)
|
||||
{
|
||||
child_info->pass_through = g_value_get_boolean (value);
|
||||
gtk_widget_set_pass_through (child, child_info->pass_through);
|
||||
gtk_container_child_notify (container, child, "pass-through");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CHILD_PROP_MEASURE:
|
||||
if (child_info)
|
||||
{
|
||||
@ -520,23 +431,6 @@ 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),
|
||||
child,
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
case CHILD_PROP_CLIP_OVERLAY:
|
||||
if (child_info)
|
||||
{
|
||||
@ -565,8 +459,6 @@ gtk_overlay_get_child_property (GtkContainer *container,
|
||||
GtkOverlay *overlay = GTK_OVERLAY (container);
|
||||
GtkOverlayChild *child_info;
|
||||
GtkWidget *main_widget;
|
||||
GtkWidget *w;
|
||||
int pos = 0;
|
||||
|
||||
main_widget = gtk_bin_get_child (GTK_BIN (overlay));
|
||||
if (child == main_widget)
|
||||
@ -583,34 +475,12 @@ gtk_overlay_get_child_property (GtkContainer *container,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case CHILD_PROP_PASS_THROUGH:
|
||||
if (child_info)
|
||||
g_value_set_boolean (value, child_info->pass_through);
|
||||
else
|
||||
g_value_set_boolean (value, FALSE);
|
||||
break;
|
||||
case CHILD_PROP_MEASURE:
|
||||
if (child_info)
|
||||
g_value_set_boolean (value, child_info->measure);
|
||||
else
|
||||
g_value_set_boolean (value, TRUE);
|
||||
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:
|
||||
for (w = _gtk_widget_get_first_child (GTK_WIDGET (container));
|
||||
w != child;
|
||||
w = _gtk_widget_get_next_sibling (w))
|
||||
{
|
||||
pos ++;
|
||||
}
|
||||
|
||||
g_value_set_int (value, pos);
|
||||
break;
|
||||
case CHILD_PROP_CLIP_OVERLAY:
|
||||
if (child_info)
|
||||
g_value_set_boolean (value, child_info->clip_overlay);
|
||||
@ -652,90 +522,14 @@ static void
|
||||
gtk_overlay_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *main_widget;
|
||||
GskRenderNode *main_widget_node = NULL;
|
||||
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;
|
||||
|
||||
if (main_widget_node == NULL)
|
||||
{
|
||||
GtkSnapshot *child_snapshot;
|
||||
|
||||
child_snapshot = gtk_snapshot_new ();
|
||||
gtk_widget_snapshot (main_widget, child_snapshot);
|
||||
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
|
||||
}
|
||||
|
||||
gtk_widget_get_allocation (child, &alloc);
|
||||
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
|
||||
gtk_snapshot_push_blur (snapshot, blur);
|
||||
gtk_snapshot_push_clip (snapshot, &bounds);
|
||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
if (clip == NULL)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = main_alloc.width;
|
||||
rect.height = main_alloc.height;
|
||||
clip = cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
|
||||
}
|
||||
gtk_overlay_snapshot_child (widget, child, snapshot);
|
||||
}
|
||||
|
||||
if (clip == NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
||||
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_overlay_snapshot_child (widget, child, snapshot);
|
||||
}
|
||||
|
||||
gsk_render_node_unref (main_widget_node);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -757,16 +551,6 @@ gtk_overlay_class_init (GtkOverlayClass *klass)
|
||||
|
||||
klass->get_child_position = gtk_overlay_get_child_position;
|
||||
|
||||
/**
|
||||
* GtkOverlay:pass-through:
|
||||
*
|
||||
* Pass through input, does not affect main child.
|
||||
*/
|
||||
gtk_container_class_install_child_property (container_class, CHILD_PROP_PASS_THROUGH,
|
||||
g_param_spec_boolean ("pass-through", P_("Pass Through"), P_("Pass through input, does not affect main child"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkOverlay:measure:
|
||||
*
|
||||
@ -779,26 +563,6 @@ gtk_overlay_class_init (GtkOverlayClass *klass)
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkOverlay:blur:
|
||||
*
|
||||
* Blur the content behind this child with a Gaussian blur of this radius.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
gtk_container_class_install_child_property (container_class, CHILD_PROP_INDEX,
|
||||
g_param_spec_int ("index",
|
||||
P_("Index"),
|
||||
P_("The index of the overlay in the parent, -1 for the main child"),
|
||||
-1, G_MAXINT, 0,
|
||||
GTK_PARAM_READWRITE));
|
||||
/**
|
||||
* GtkOverlay:clip-overlay:
|
||||
*
|
||||
@ -931,56 +695,6 @@ gtk_overlay_add_overlay (GtkOverlay *overlay,
|
||||
|
||||
gtk_widget_insert_before (widget, GTK_WIDGET (overlay), NULL);
|
||||
gtk_overlay_set_overlay_child (widget, child);
|
||||
|
||||
gtk_widget_child_notify (widget, "index");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_overlay_set_overlay_pass_through:
|
||||
* @overlay: a #GtkOverlay
|
||||
* @widget: an overlay child of #GtkOverlay
|
||||
* @pass_through: whether the child should pass the input through
|
||||
*
|
||||
* Convenience function to set the value of the #GtkOverlay:pass-through
|
||||
* child property for @widget.
|
||||
*/
|
||||
void
|
||||
gtk_overlay_set_overlay_pass_through (GtkOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
gboolean pass_through)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_OVERLAY (overlay));
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
gtk_container_child_set (GTK_CONTAINER (overlay), widget,
|
||||
"pass-through", pass_through,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_overlay_get_overlay_pass_through:
|
||||
* @overlay: a #GtkOverlay
|
||||
* @widget: an overlay child of #GtkOverlay
|
||||
*
|
||||
* Convenience function to get the value of the #GtkOverlay:pass-through
|
||||
* child property for @widget.
|
||||
*
|
||||
* Returns: whether the widget is a pass through child.
|
||||
*/
|
||||
gboolean
|
||||
gtk_overlay_get_overlay_pass_through (GtkOverlay *overlay,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
gboolean pass_through;
|
||||
|
||||
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,
|
||||
"pass-through", &pass_through,
|
||||
NULL);
|
||||
|
||||
return pass_through;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,10 +82,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gtk_overlay_add_overlay (GtkOverlay *overlay,
|
||||
GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_overlay_reorder_overlay (GtkOverlay *overlay,
|
||||
GtkWidget *child,
|
||||
gint position);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_overlay_get_overlay_pass_through (GtkOverlay *overlay,
|
||||
GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
@ -518,6 +518,7 @@ enum {
|
||||
PROP_CAN_FOCUS,
|
||||
PROP_HAS_FOCUS,
|
||||
PROP_IS_FOCUS,
|
||||
PROP_CAN_PICK,
|
||||
PROP_FOCUS_ON_CLICK,
|
||||
PROP_CAN_DEFAULT,
|
||||
PROP_HAS_DEFAULT,
|
||||
@ -1036,6 +1037,13 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE);
|
||||
|
||||
widget_props[PROP_CAN_PICK] =
|
||||
g_param_spec_boolean ("can-pick",
|
||||
P_("Can pick"),
|
||||
P_("Whether the widget can receive pointer events"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkWidget:focus-on-click:
|
||||
*
|
||||
@ -2262,6 +2270,9 @@ gtk_widget_set_property (GObject *object,
|
||||
if (g_value_get_boolean (value))
|
||||
gtk_widget_grab_focus (widget);
|
||||
break;
|
||||
case PROP_CAN_PICK:
|
||||
gtk_widget_set_can_pick (widget, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_FOCUS_ON_CLICK:
|
||||
gtk_widget_set_focus_on_click (widget, g_value_get_boolean (value));
|
||||
break;
|
||||
@ -2437,6 +2448,9 @@ gtk_widget_get_property (GObject *object,
|
||||
case PROP_IS_FOCUS:
|
||||
g_value_set_boolean (value, gtk_widget_is_focus (widget));
|
||||
break;
|
||||
case PROP_CAN_PICK:
|
||||
g_value_set_boolean (value, gtk_widget_get_can_pick (widget));
|
||||
break;
|
||||
case PROP_FOCUS_ON_CLICK:
|
||||
g_value_set_boolean (value, gtk_widget_get_focus_on_click (widget));
|
||||
break;
|
||||
@ -2871,6 +2885,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
priv->highlight_resize = FALSE;
|
||||
#endif
|
||||
priv->can_pick = TRUE;
|
||||
|
||||
switch (_gtk_widget_get_direction (widget))
|
||||
{
|
||||
@ -11206,7 +11221,7 @@ gtk_widget_get_allocation (GtkWidget *widget,
|
||||
*
|
||||
* Pass-through widgets and insensitive widgets do never respond to
|
||||
* input and will therefor always return %FALSE here. See
|
||||
* gtk_widget_set_pass_through() and gtk_widget_set_sensitive() for
|
||||
* gtk_widget_set_can_pick() and gtk_widget_set_sensitive() for
|
||||
* details about those functions.
|
||||
*
|
||||
* Returns: %TRUE if @widget contains (@x, @y).
|
||||
@ -11218,7 +11233,7 @@ gtk_widget_contains (GtkWidget *widget,
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
|
||||
if (gtk_widget_get_pass_through (widget) ||
|
||||
if (!gtk_widget_get_can_pick (widget) ||
|
||||
!_gtk_widget_is_sensitive (widget) ||
|
||||
!_gtk_widget_is_drawable (widget))
|
||||
return FALSE;
|
||||
@ -11257,7 +11272,7 @@ gtk_widget_pick (GtkWidget *widget,
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
|
||||
if (gtk_widget_get_pass_through (widget) ||
|
||||
if (!gtk_widget_get_can_pick (widget) ||
|
||||
!_gtk_widget_is_sensitive (widget) ||
|
||||
!_gtk_widget_is_drawable (widget))
|
||||
return NULL;
|
||||
@ -13700,20 +13715,27 @@ gtk_widget_get_cursor (GtkWidget *widget)
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_pass_through (GtkWidget *widget,
|
||||
gboolean pass_through)
|
||||
gtk_widget_set_can_pick (GtkWidget *widget,
|
||||
gboolean can_pick)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
priv->pass_through = !!pass_through;
|
||||
can_pick = !!can_pick;
|
||||
|
||||
if (priv->can_pick == can_pick)
|
||||
return;
|
||||
|
||||
priv->can_pick = can_pick;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CAN_PICK]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_widget_get_pass_through (GtkWidget *widget)
|
||||
gtk_widget_get_can_pick (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
return priv->pass_through;
|
||||
return priv->can_pick;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -494,6 +494,13 @@ void gtk_widget_set_focus_on_click (GtkWidget *widget,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_get_focus_on_click (GtkWidget *widget);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_set_can_pick (GtkWidget *widget,
|
||||
gboolean can_pick);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_get_can_pick (GtkWidget *widget);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_set_can_default (GtkWidget *widget,
|
||||
gboolean can_default);
|
||||
|
@ -75,7 +75,7 @@ struct _GtkWidgetPrivate
|
||||
guint shadowed : 1;
|
||||
guint child_visible : 1;
|
||||
guint multidevice : 1;
|
||||
guint pass_through : 1;
|
||||
guint can_pick : 1;
|
||||
|
||||
/* Queue-resize related flags */
|
||||
guint resize_needed : 1; /* queue_resize() has been called but no get_preferred_size() yet */
|
||||
@ -332,10 +332,6 @@ void gtk_widget_get_surface_allocation (GtkWidget *widget,
|
||||
GtkWidget * gtk_widget_common_ancestor (GtkWidget *widget_a,
|
||||
GtkWidget *widget_b);
|
||||
|
||||
void gtk_widget_set_pass_through (GtkWidget *widget,
|
||||
gboolean pass_through);
|
||||
gboolean gtk_widget_get_pass_through (GtkWidget *widget);
|
||||
|
||||
void gtk_widget_cancel_event_sequence (GtkWidget *widget,
|
||||
GtkGesture *gesture,
|
||||
GdkEventSequence *sequence,
|
||||
|
@ -459,7 +459,7 @@ test_input_stacking (void)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), vbox);
|
||||
gtk_overlay_set_overlay_pass_through (GTK_OVERLAY (overlay), vbox, TRUE);
|
||||
gtk_widget_set_can_pick (vbox, FALSE);
|
||||
gtk_widget_set_halign (vbox, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (vbox, GTK_ALIGN_CENTER);
|
||||
|
||||
@ -481,126 +481,6 @@ test_input_stacking (void)
|
||||
return win;
|
||||
}
|
||||
|
||||
static void
|
||||
reorder_overlay (GtkButton *button, GtkOverlay *overlay)
|
||||
{
|
||||
gtk_overlay_reorder_overlay (overlay, gtk_widget_get_parent (GTK_WIDGET (button)), -1);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
test_child_order (void)
|
||||
{
|
||||
GtkWidget *win;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
GtkWidget *box;
|
||||
int i;
|
||||
|
||||
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (win), "Child Order");
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (win), overlay);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
char *style_classes[] = {
|
||||
"transparent-red", "transparent-green", "transparent-blue", "transparent-purple"
|
||||
};
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
button = gtk_button_new_with_label (g_strdup_printf ("Child %d", i));
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (reorder_overlay), overlay);
|
||||
gtk_widget_set_margin_start (button, 20);
|
||||
gtk_widget_set_margin_end (button, 20);
|
||||
gtk_widget_set_margin_top (button, 10);
|
||||
gtk_widget_set_margin_bottom (button, 10);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (box), style_classes[i]);
|
||||
|
||||
gtk_widget_set_halign (box, (i == 0 || i == 3) ? GTK_ALIGN_START : GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (box, i < 2 ? GTK_ALIGN_START : GTK_ALIGN_END);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), box);
|
||||
}
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (box), "overlay-white");
|
||||
|
||||
label = gtk_label_new ("Main\n"
|
||||
"Main\n"
|
||||
"Main\n"
|
||||
"Main\n");
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), box);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget *
|
||||
test_effect (void)
|
||||
{
|
||||
GtkWidget *win;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *button;
|
||||
GtkWidget *picture;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
|
||||
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
|
||||
gtk_window_set_title (GTK_WINDOW (win), "Fancy Effect");
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (win), overlay);
|
||||
|
||||
button = gtk_button_new_with_label ("Don't click this button!");
|
||||
label = gtk_bin_get_child (GTK_BIN (button));
|
||||
g_object_set (label, "margin", 50, NULL);
|
||||
|
||||
gtk_widget_set_opacity (button, 0.7);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_START);
|
||||
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_container_child_set (GTK_CONTAINER (overlay), button, "blur", 5.0, NULL);
|
||||
|
||||
button = gtk_button_new_with_label ("Maybe this one?");
|
||||
label = gtk_bin_get_child (GTK_BIN (button));
|
||||
g_object_set (label, "margin", 50, NULL);
|
||||
|
||||
gtk_widget_set_opacity (button, 0.7);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_END);
|
||||
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_container_child_set (GTK_CONTAINER (overlay), button, "blur", 5.0, NULL);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), sw);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (sw), box);
|
||||
picture = gtk_picture_new ();
|
||||
if (g_file_test ("portland-rose.jpg", G_FILE_TEST_EXISTS))
|
||||
gtk_picture_set_filename (GTK_PICTURE (picture), "portland-rose.jpg");
|
||||
else if (g_file_test ("tests/portland-rose.jpg", G_FILE_TEST_EXISTS))
|
||||
gtk_picture_set_filename (GTK_PICTURE (picture), "tests/portland-rose.jpg");
|
||||
else if (g_file_test ("../tests/portland-rose.jpg", G_FILE_TEST_EXISTS))
|
||||
gtk_picture_set_filename (GTK_PICTURE (picture), "../tests/portland-rose.jpg");
|
||||
else
|
||||
g_error ("portland-rose.jpg not found. No rose for you!\n");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), picture);
|
||||
|
||||
return win;
|
||||
}
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -612,8 +492,6 @@ main (int argc, char *argv[])
|
||||
GtkWidget *win6;
|
||||
GtkWidget *win7;
|
||||
GtkWidget *win8;
|
||||
GtkWidget *win9;
|
||||
GtkWidget *win10;
|
||||
GtkCssProvider *css_provider;
|
||||
|
||||
gtk_init ();
|
||||
@ -651,12 +529,6 @@ main (int argc, char *argv[])
|
||||
win8 = test_input_stacking ();
|
||||
gtk_widget_show (win8);
|
||||
|
||||
win9 = test_child_order ();
|
||||
gtk_widget_show (win9);
|
||||
|
||||
win10 = test_effect ();
|
||||
gtk_widget_show (win10);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user