diff options
author | Timm Bäder <mail@baedert.org> | 2017-02-09 17:59:24 +0100 |
---|---|---|
committer | Timm Bäder <mail@baedert.org> | 2017-03-31 09:50:40 +0200 |
commit | 9b70d9897d52fc5612c0059e088e8ad6e1cfe8e4 (patch) | |
tree | deadabd6e0f2ff3bea8609fe47cc5be85b03ee28 | |
parent | 1a7cbddbd4e98e4641e690035013abbfaec130b0 (diff) | |
download | gtk+-9b70d9897d52fc5612c0059e088e8ad6e1cfe8e4.tar.gz |
tests: Add widget focus test case
Shows an example of a widget that directly inherits from GtkWidget and
has multiple focusable children.
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/testwidgetfocus.c | 171 |
2 files changed, 175 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 82d155493f..1c5fc315c8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -156,6 +156,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \ testpopup \ testpopupat \ testgaction \ + testwidgetfocus \ $(NULL) if USE_X11 @@ -268,6 +269,7 @@ testrevealer2_DEPENDENCIES = $(TEST_DEPS) testtitlebar_DEPENDENCIES = $(TEST_DEPS) testwindowsize_DEPENDENCIES = $(TEST_DEPS) listmodel_DEPENDENCIES = $(TEST_DEPS) +testwidgetfocus_DEPENDENCIES = $(TEST_DEPS) animated_resizing_SOURCES = \ animated-resizing.c \ @@ -457,6 +459,8 @@ testglblending_SOURCES = \ listmodel_SOURCES = listmodel.c +testwidgetfocus_SOURCES = testwidgetfocus.c + EXTRA_DIST += \ gradient1.png \ testgtk.1 \ diff --git a/tests/testwidgetfocus.c b/tests/testwidgetfocus.c new file mode 100644 index 0000000000..e63deb3946 --- /dev/null +++ b/tests/testwidgetfocus.c @@ -0,0 +1,171 @@ +#include <gtk/gtk.h> + + + +typedef struct _GtkFocusWidget GtkFocusWidget; +typedef struct _GtkFocusWidgetClass GtkFocusWidgetClass; + +#define GTK_TYPE_FOCUS_WIDGET (gtk_focus_widget_get_type ()) +#define GTK_FOCUS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GTK_TYPE_FOCUS_WIDGET, GtkFocusWidget)) +#define GTK_FOCUS_WIDGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST(cls, GTK_TYPE_FOCUS_WIDGET, GtkFocusWidgetClass)) +#define GTK_IS_FOCUS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GTK_TYPE_FOCUS_WIDGET)) +#define GTK_IS_FOCUS_WIDGET_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE(cls, GTK_TYPE_FOCUS_WIDGET)) +#define GTK_FOCUS_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, GTK_TYPE_FOCUS_WIDGET, GtkFocusWidgetClass)) + +#define SPACING 30 + +struct _GtkFocusWidget +{ + GtkWidget parent_instance; + + union { + struct { + GtkWidget *child1; + GtkWidget *child2; + GtkWidget *child3; + GtkWidget *child4; + }; + GtkWidget* children[4]; + }; +}; + +struct _GtkFocusWidgetClass +{ + GtkWidgetClass parent_class; +}; + +GType gtk_focus_widget_get_type (void) G_GNUC_CONST; + + +G_DEFINE_TYPE(GtkFocusWidget, gtk_focus_widget, GTK_TYPE_WIDGET) + +static void +gtk_focus_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget); + int child_width = (allocation->width - (3 * SPACING)) / 2; + int child_height = (allocation->height - (3 * SPACING)) / 2; + GtkAllocation child_alloc; + + child_alloc.x = SPACING + allocation->x; + child_alloc.y = SPACING + allocation->y; + child_alloc.width = child_width; + child_alloc.height = child_height; + + gtk_widget_size_allocate (self->child1, &child_alloc); + + child_alloc.x += SPACING + child_width; + + gtk_widget_size_allocate (self->child2, &child_alloc); + + child_alloc.y += SPACING + child_height; + + gtk_widget_size_allocate (self->child4, &child_alloc); + + child_alloc.x -= SPACING + child_width; + + gtk_widget_size_allocate (self->child3, &child_alloc); +} + +static void +gtk_focus_widget_measure (GtkWidget *widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline) +{ + GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget); + int min, nat; + int i; + + *minimum = 0; + *natural = 0; + + for (i = 0; i < 4; i ++) + { + gtk_widget_measure (self->children[i], orientation, for_size, + &min, &nat, NULL, NULL); + + *minimum = MAX (*minimum, min); + *natural = MAX (*natural, nat); + } + + *minimum *= 2; + *natural *= 2; + + *minimum += SPACING * 3; + *natural += SPACING * 3; +} + +static void +gtk_focus_widget_snapshot (GtkWidget *widget, GtkSnapshot *snapshot) +{ + GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget); + + gtk_widget_snapshot_child (widget, self->child1, snapshot); + gtk_widget_snapshot_child (widget, self->child2, snapshot); + gtk_widget_snapshot_child (widget, self->child3, snapshot); + gtk_widget_snapshot_child (widget, self->child4, snapshot); +} + +static void +gtk_focus_widget_finalize (GObject *object) +{ + GtkFocusWidget *self = GTK_FOCUS_WIDGET (object); + + gtk_widget_unparent (self->child1); + gtk_widget_unparent (self->child2); + gtk_widget_unparent (self->child3); + gtk_widget_unparent (self->child4); + + G_OBJECT_CLASS (gtk_focus_widget_parent_class)->finalize (object); +} + +static void +gtk_focus_widget_init (GtkFocusWidget *self) +{ + gtk_widget_set_has_window (GTK_WIDGET (self), FALSE); + + self->child1 = gtk_button_new_with_label ("1"); + gtk_widget_set_parent (self->child1, GTK_WIDGET (self)); + self->child2 = gtk_button_new_with_label ("2"); + gtk_widget_set_parent (self->child2, GTK_WIDGET (self)); + self->child3 = gtk_button_new_with_label ("3"); + gtk_widget_set_parent (self->child3, GTK_WIDGET (self)); + self->child4 = gtk_button_new_with_label ("4"); + gtk_widget_set_parent (self->child4, GTK_WIDGET (self)); +} + +static void +gtk_focus_widget_class_init (GtkFocusWidgetClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = gtk_focus_widget_finalize; + + widget_class->snapshot = gtk_focus_widget_snapshot; + widget_class->measure = gtk_focus_widget_measure; + widget_class->size_allocate = gtk_focus_widget_size_allocate; +} + +int +main() +{ + GtkWidget *window; + GtkWidget *widget; + gtk_init (); + + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + widget = g_object_new (GTK_TYPE_FOCUS_WIDGET, NULL); + + gtk_container_add (GTK_CONTAINER (window), widget); + g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL); + + gtk_widget_show (window); + + gtk_main (); +} |