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
This commit is contained in:
@@ -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,23 +247,56 @@ 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,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkbin.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
Reference in New Issue
Block a user