diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-05-01 16:53:14 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-05-04 17:01:18 -0400 |
commit | e098ffb88d604e898fcbf068bea9aba997847407 (patch) | |
tree | 1809e565b6db16d9e5d4bed6fde0e8d3b685e16d /gtk/gtkviewport.c | |
parent | e9ddf0fda552889ba17c2f34705ed87d38824cff (diff) | |
download | gtk+-e098ffb88d604e898fcbf068bea9aba997847407.tar.gz |
viewport: Derive from GtkWidget
We want to remove GtkBin and GtkContainer as they don't
provide much useful functionality anymore. This requires
us to move get_request_mode and compute_expand down.
We have to implement GtkBuildable in order to keep
the <child> element working for viewports in ui files.
See #2681
Diffstat (limited to 'gtk/gtkviewport.c')
-rw-r--r-- | gtk/gtkviewport.c | 135 |
1 files changed, 103 insertions, 32 deletions
diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c index dea061ec2f..1cbd46aa65 100644 --- a/gtk/gtkviewport.c +++ b/gtk/gtkviewport.c @@ -34,6 +34,7 @@ #include "gtkstylecontext.h" #include "gtktypebuiltins.h" #include "gtkwidgetprivate.h" +#include "gtkbuildable.h" #include "gtktext.h" @@ -69,7 +70,9 @@ typedef struct _GtkViewportClass GtkViewportClass; struct _GtkViewport { - GtkBin parent_instance; + GtkWidget parent_instance; + + GtkWidget *child; GtkAdjustment *hadjustment; GtkAdjustment *vadjustment; @@ -85,7 +88,7 @@ struct _GtkViewport struct _GtkViewportClass { - GtkBinClass parent_class; + GtkWidgetClass parent_class; }; enum { @@ -107,11 +110,12 @@ static void gtk_viewport_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void gtk_viewport_destroy (GtkWidget *widget); -static void gtk_viewport_size_allocate (GtkWidget *widget, - int width, - int height, - int baseline); +static void gtk_viewport_destroy (GtkWidget *widget); +static void gtk_viewport_size_allocate (GtkWidget *widget, + int width, + int height, + int baseline); + static void gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data); static void viewport_set_adjustment (GtkViewport *viewport, @@ -121,19 +125,44 @@ static void viewport_set_adjustment (GtkViewport *viewport, static void setup_focus_change_handler (GtkViewport *viewport); static void clear_focus_change_handler (GtkViewport *viewport); -G_DEFINE_TYPE_WITH_CODE (GtkViewport, gtk_viewport, GTK_TYPE_BIN, +static void gtk_viewport_buildable_init (GtkBuildableIface *iface); + + +G_DEFINE_TYPE_WITH_CODE (GtkViewport, gtk_viewport, GTK_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, + gtk_viewport_buildable_init) G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) +static GtkBuildableIface *parent_buildable_iface; + +static void +gtk_viewport_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *type) +{ + if (GTK_IS_WIDGET (child)) + gtk_viewport_set_child (GTK_VIEWPORT (buildable), GTK_WIDGET (child)); + else + parent_buildable_iface->add_child (buildable, builder, child, type); +} + +static void +gtk_viewport_buildable_init (GtkBuildableIface *iface) +{ + parent_buildable_iface = g_type_interface_peek_parent (iface); + + iface->add_child = gtk_viewport_buildable_add_child; +} + static void viewport_set_adjustment_values (GtkViewport *viewport, GtkOrientation orientation) { - GtkBin *bin = GTK_BIN (viewport); GtkAdjustment *adjustment; GtkScrollablePolicy scroll_policy; GtkScrollablePolicy other_scroll_policy; GtkOrientation other_orientation; - GtkWidget *child; gdouble upper, value; int viewport_size, other_viewport_size; int view_width, view_height; @@ -161,20 +190,19 @@ viewport_set_adjustment_values (GtkViewport *viewport, } - child = gtk_bin_get_child (bin); - if (child && gtk_widget_get_visible (child)) + if (viewport->child && gtk_widget_get_visible (viewport->child)) { int min_size, nat_size; int scroll_size; if (other_scroll_policy == GTK_SCROLL_MINIMUM) - gtk_widget_measure (child, other_orientation, -1, + gtk_widget_measure (viewport->child, other_orientation, -1, &scroll_size, NULL, NULL, NULL); else - gtk_widget_measure (child, other_orientation, -1, + gtk_widget_measure (viewport->child, other_orientation, -1, NULL, &scroll_size, NULL, NULL); - gtk_widget_measure (child, orientation, + gtk_widget_measure (viewport->child, orientation, MAX (other_viewport_size, scroll_size), &min_size, &nat_size, NULL, NULL); @@ -219,13 +247,12 @@ gtk_viewport_measure (GtkWidget *widget, int *minimum_baseline, int *natural_baseline) { - GtkWidget *child; + GtkViewport *viewport = GTK_VIEWPORT (widget); *minimum = *natural = 0; - child = gtk_bin_get_child (GTK_BIN (widget)); - if (child && gtk_widget_get_visible (child)) - gtk_widget_measure (child, + if (viewport->child && gtk_widget_get_visible (viewport->child)) + gtk_widget_measure (viewport->child, orientation, for_size, minimum, natural, @@ -233,9 +260,43 @@ gtk_viewport_measure (GtkWidget *widget, } static void +gtk_viewport_compute_expand (GtkWidget *widget, + gboolean *hexpand, + gboolean *vexpand) +{ + GtkViewport *viewport = GTK_VIEWPORT (widget); + + if (viewport->child) + { + *hexpand = gtk_widget_compute_expand (viewport->child, GTK_ORIENTATION_HORIZONTAL); + *vexpand = gtk_widget_compute_expand (viewport->child, GTK_ORIENTATION_VERTICAL); + } + else + { + *hexpand = FALSE; + *vexpand = FALSE; + } +} + +static GtkSizeRequestMode +gtk_viewport_get_request_mode (GtkWidget *widget) +{ + GtkViewport *viewport = GTK_VIEWPORT (widget); + + if (viewport->child) + return gtk_widget_get_request_mode (viewport->child); + else + return GTK_SIZE_REQUEST_CONSTANT_SIZE; +} + +static void gtk_viewport_dispose (GObject *object) { - clear_focus_change_handler (GTK_VIEWPORT (object)); + GtkViewport *viewport = GTK_VIEWPORT (object); + + clear_focus_change_handler (viewport); + + g_clear_pointer (&viewport->child, gtk_widget_unparent); G_OBJECT_CLASS (gtk_viewport_parent_class)->dispose (object); @@ -281,7 +342,12 @@ gtk_viewport_class_init (GtkViewportClass *class) widget_class->measure = gtk_viewport_measure; widget_class->root = gtk_viewport_root; widget_class->unroot = gtk_viewport_unroot; - + widget_class->compute_expand = gtk_viewport_compute_expand; + widget_class->get_request_mode = gtk_viewport_get_request_mode; + widget_class->grab_focus = gtk_widget_grab_focus_none; + widget_class->focus = gtk_widget_focus_child; + + gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_VIEWPORT); /* GtkScrollable implementation */ @@ -494,7 +560,6 @@ gtk_viewport_size_allocate (GtkWidget *widget, GtkViewport *viewport = GTK_VIEWPORT (widget); GtkAdjustment *hadjustment = viewport->hadjustment; GtkAdjustment *vadjustment = viewport->vadjustment; - GtkWidget *child; g_object_freeze_notify (G_OBJECT (hadjustment)); g_object_freeze_notify (G_OBJECT (vadjustment)); @@ -502,8 +567,7 @@ gtk_viewport_size_allocate (GtkWidget *widget, viewport_set_adjustment_values (viewport, GTK_ORIENTATION_HORIZONTAL); viewport_set_adjustment_values (viewport, GTK_ORIENTATION_VERTICAL); - child = gtk_bin_get_child (GTK_BIN (widget)); - if (child && gtk_widget_get_visible (child)) + if (viewport->child && gtk_widget_get_visible (viewport->child)) { GtkAllocation child_allocation; @@ -512,7 +576,7 @@ gtk_viewport_size_allocate (GtkWidget *widget, child_allocation.width = gtk_adjustment_get_upper (hadjustment); child_allocation.height = gtk_adjustment_get_upper (vadjustment); - gtk_widget_size_allocate (child, &child_allocation, -1); + gtk_widget_size_allocate (viewport->child, &child_allocation, -1); } g_object_thaw_notify (G_OBJECT (hadjustment)); @@ -595,7 +659,6 @@ focus_change_handler (GtkWidget *widget) GtkViewport *viewport = GTK_VIEWPORT (widget); GtkRoot *root; GtkWidget *focus_widget; - GtkWidget *child; graphene_rect_t rect; int x, y; @@ -611,12 +674,10 @@ focus_change_handler (GtkWidget *widget) if (GTK_IS_TEXT (focus_widget)) focus_widget = gtk_widget_get_parent (focus_widget); - child = gtk_bin_get_child (GTK_BIN (viewport)); - - if (!gtk_widget_compute_bounds (focus_widget, child, &rect)) + if (!gtk_widget_compute_bounds (focus_widget, viewport->child, &rect)) return; - gtk_widget_translate_coordinates (child, widget, + gtk_widget_translate_coordinates (viewport->child, widget, (int)rect.origin.x, (int)rect.origin.y, &x, &y); @@ -664,7 +725,17 @@ gtk_viewport_set_child (GtkViewport *viewport, g_return_if_fail (GTK_IS_VIEWPORT (viewport)); g_return_if_fail (child == NULL || GTK_IS_WIDGET (child)); - _gtk_bin_set_child (GTK_BIN (viewport), child); + if (viewport->child == child) + return; + + g_clear_pointer (&viewport->child, gtk_widget_unparent); + + if (child) + { + viewport->child = child; + gtk_widget_set_parent (child, GTK_WIDGET (viewport)); + } + g_object_notify (G_OBJECT (viewport), "child"); } @@ -681,6 +752,6 @@ gtk_viewport_get_child (GtkViewport *viewport) { g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL); - return gtk_bin_get_child (GTK_BIN (viewport)); + return viewport->child; } |