[gtk/wip/baedert/transforms6: 28/52] Add form entry test
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/baedert/transforms6: 28/52] Add form entry test
- Date: Thu, 14 Feb 2019 07:10:07 +0000 (UTC)
commit 13d9848da740e35fa3e66dcfe0b014c44d73f85e
Author: Timm Bäder <mail baedert org>
Date: Thu Aug 16 11:51:41 2018 +0200
Add form entry test
tests/meson.build | 1 +
tests/testformentry.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 230 insertions(+)
---
diff --git a/tests/meson.build b/tests/meson.build
index fe9e09d86b..1f4c8ee8fc 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -41,6 +41,7 @@ gtk_tests = [
['testflowbox'],
['testfontchooser'],
['testfontoptions'],
+ ['testformentry'],
['testframe'],
['testfullscreen'],
['testgiconpixbuf'],
diff --git a/tests/testformentry.c b/tests/testformentry.c
new file mode 100644
index 0000000000..0105fd4030
--- /dev/null
+++ b/tests/testformentry.c
@@ -0,0 +1,229 @@
+#include <gtk/gtk.h>
+
+
+#define GTK_TYPE_FORM_ENTRY (gtk_form_entry_get_type ())
+G_DECLARE_FINAL_TYPE (GtkFormEntry, gtk_form_entry, GTK, FORM_ENTRY, GtkWidget)
+
+#define FINAL_SCALE 0.7
+#define TRANSITION_DURATION (200 * 1000)
+
+struct _GtkFormEntry
+{
+ GtkWidget parent_instance;
+
+ GtkWidget *entry;
+ GtkWidget *placeholder;
+
+ double placeholder_scale;
+};
+
+G_DEFINE_TYPE (GtkFormEntry, gtk_form_entry, GTK_TYPE_WIDGET)
+
+
+static void
+gtk_form_entry_size_allocate (GtkWidget *widget,
+ int width,
+ int height,
+ int baseline)
+{
+ GtkFormEntry *self = (GtkFormEntry *)widget;
+ int placeholder_height;
+ int top;
+
+ gtk_widget_measure (self->placeholder, GTK_ORIENTATION_VERTICAL, -1,
+ &placeholder_height, NULL, NULL, NULL);
+ top = placeholder_height * FINAL_SCALE;
+
+ gtk_widget_size_allocate (self->entry,
+ &(GtkAllocation) {
+ 0, top,
+ width, height - top
+ }, -1);
+
+ /* Placeholder allocation depends on self->placeholder_scale.
+ * If that's 1.0, we don't scale it and center it on the
+ * GtkEntry. Otherwise, we move it up until y = 0. */
+ {
+ const int max_y = top + ((height - top) / 2) - (placeholder_height / 2);
+ const double t = self->placeholder_scale; /* TODO: Interpolate */
+ const int y = 0 + (t * max_y);
+ int x;
+ graphene_matrix_t m;
+
+ /* Get 0 in entry coords so we can position the placeholder there. */
+ gtk_widget_translate_coordinates (self->entry, widget, 0, 0, &x, NULL);
+
+ x *= t;
+
+ gtk_widget_size_allocate (self->placeholder,
+ &(GtkAllocation) {
+ x, y,
+ width,
+ placeholder_height
+ }, -1);
+
+ graphene_matrix_init_scale (&m,
+ CLAMP (t, FINAL_SCALE, 1.0),
+ CLAMP (t, FINAL_SCALE, 1.0),
+ 1);
+ gtk_widget_set_transform (self->placeholder, &m);
+ }
+}
+
+static void
+gtk_form_entry_measure (GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural,
+ int *minimum_baseline,
+ int *natural_baseline)
+{
+ GtkFormEntry *self = (GtkFormEntry *)widget;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ int min1, nat1;
+ int min2, nat2;
+
+ gtk_widget_measure (self->entry, orientation, for_size,
+ &min1, &nat1, NULL, NULL);
+
+ gtk_widget_measure (self->entry, orientation, for_size,
+ &min2, &nat2, NULL, NULL);
+
+ *minimum = MAX (min1, min2);
+ *natural = MAX (nat1, nat2);
+ }
+ else /* VERTICAL */
+ {
+ int min, nat;
+ int pmin, pnat;
+
+ gtk_widget_measure (self->entry, orientation, -1,
+ &min, &nat, NULL, NULL);
+
+ gtk_widget_measure (self->entry, orientation, -1,
+ &pmin, &pnat, NULL, NULL);
+
+ *minimum = min + (pmin * FINAL_SCALE);
+ *natural = nat + (pnat * FINAL_SCALE);
+ }
+}
+
+static gboolean
+tick_cb (GtkWidget *widget,
+ GdkFrameClock *frame_clock,
+ gpointer user_data)
+{
+ GtkFormEntry *self = user_data;
+
+ self->placeholder_scale -= 0.02;
+
+ gtk_widget_queue_allocate (GTK_WIDGET (self));
+ gtk_widget_queue_draw (self->placeholder);
+
+ if (self->placeholder_scale <= 0)
+ {
+ self->placeholder_scale = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+gtk_form_entry_focused (GtkEventControllerKey *controller,
+ gpointer user_data)
+{
+ GtkFormEntry *self = user_data;
+
+ gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, self, NULL);
+}
+
+static void
+gtk_form_entry_unfocused (GtkEventControllerKey *controller,
+ gpointer user_data)
+{
+ GtkFormEntry *self = user_data;
+
+ self->placeholder_scale = 1.0;
+ gtk_widget_queue_allocate (GTK_WIDGET (self));
+ gtk_widget_queue_draw (self->placeholder);
+}
+
+
+static void
+gtk_form_entry_class_init (GtkFormEntryClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->measure = gtk_form_entry_measure;
+ widget_class->size_allocate = gtk_form_entry_size_allocate;
+}
+
+static void
+gtk_form_entry_init (GtkFormEntry *self)
+{
+ GtkEventController *key_controller;
+ gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
+
+ self->entry = gtk_entry_new ();
+ self->placeholder = gtk_label_new ("");
+ gtk_label_set_xalign (GTK_LABEL (self->placeholder), 0);
+ self->placeholder_scale = 1.0;
+
+ gtk_widget_set_parent (self->entry, GTK_WIDGET (self));
+ gtk_widget_set_parent (self->placeholder, GTK_WIDGET (self));
+
+ key_controller = gtk_event_controller_key_new ();
+ g_signal_connect (key_controller, "focus-in", G_CALLBACK (gtk_form_entry_focused), self);
+ g_signal_connect (key_controller, "focus-out", G_CALLBACK (gtk_form_entry_unfocused), self);
+ gtk_widget_add_controller (self->entry, key_controller);
+}
+
+GtkWidget *
+gtk_form_entry_new (const char *text)
+{
+ GtkWidget *w = g_object_new (GTK_TYPE_FORM_ENTRY, NULL);
+
+ gtk_label_set_text (GTK_LABEL (((GtkFormEntry*)w)->placeholder), text);
+
+ return w;
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window;
+ GtkWidget *box;
+ GtkWidget *form_entry1;
+ GtkWidget *form_entry2;
+
+ gtk_init ();
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ form_entry1 = gtk_form_entry_new ("First Name");
+ form_entry2 = gtk_form_entry_new ("Last Name");
+
+ gtk_container_add (GTK_CONTAINER (box), form_entry1);
+ gtk_container_add (GTK_CONTAINER (box), form_entry2);
+
+
+ gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
+ gtk_container_add (GTK_CONTAINER (window), box);
+
+
+
+ gtk_window_set_default_size ((GtkWindow *)window, 200, 200);
+ g_signal_connect (window, "close-request", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_widget_show (window);
+
+
+ gtk_main ();
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]