summaryrefslogtreecommitdiff
path: root/gtk/gtkviewport.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-05-01 16:53:14 -0400
committerMatthias Clasen <mclasen@redhat.com>2020-05-04 17:01:18 -0400
commite098ffb88d604e898fcbf068bea9aba997847407 (patch)
tree1809e565b6db16d9e5d4bed6fde0e8d3b685e16d /gtk/gtkviewport.c
parente9ddf0fda552889ba17c2f34705ed87d38824cff (diff)
downloadgtk+-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.c135
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;
}