[gtk] Add test for widget transforms



commit 8ce6cf569fe4f3b7e301b76e52467dae287dc012
Author: Timm Bäder <mail baedert org>
Date:   Sat Aug 11 22:19:13 2018 +0200

    Add test for widget transforms

 tests/meson.build            |   1 +
 tests/testwidgettransforms.c | 353 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 354 insertions(+)
---
diff --git a/tests/meson.build b/tests/meson.build
index 9e33e46912..fe9e09d86b 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -122,6 +122,7 @@ gtk_tests = [
   ['testpopupat'],
   ['testgaction'],
   ['testwidgetfocus'],
+  ['testwidgettransforms'],
   ['testcenterbox'],
   ['testgridbaseline'],
   ['showrendernode'],
diff --git a/tests/testwidgettransforms.c b/tests/testwidgettransforms.c
new file mode 100644
index 0000000000..65c78825cc
--- /dev/null
+++ b/tests/testwidgettransforms.c
@@ -0,0 +1,353 @@
+
+
+#include <gtk/gtk.h>
+
+static const char *css =
+"test>button {"
+"  all: unset; "
+"  background-color: white;"
+"  border: 30px solid teal;"
+"  margin: 40px;"
+"  padding: 40px;"
+"}"
+"test>button:hover {"
+"  background-color: blue;"
+"}"
+"test image {"
+"  background-color: purple;"
+"}"
+;
+
+/* Just so we can avoid a signal */
+GtkWidget *transform_tester;
+GtkWidget *test_widget;
+GtkWidget *test_child;
+float scale = 1;
+gboolean do_picking = TRUE;
+
+static const GdkRGBA RED   = {1, 0, 0, 0.4};
+static const GdkRGBA GREEN = {0, 1, 0, 0.7};
+static const GdkRGBA BLUE  = {0, 0, 1, 0.4};
+static const GdkRGBA BLACK = {0, 0, 0, 1  };
+
+
+
+/* ######################################################################### */
+/* ############################## MatrixChooser ############################ */
+/* ######################################################################### */
+
+
+#define GTK_TYPE_MATRIX_CHOOSER (gtk_matrix_chooser_get_type ())
+G_DECLARE_FINAL_TYPE (GtkMatrixChooser, gtk_matrix_chooser, GTK, MATRIX_CHOOSER, GtkWidget)
+
+struct _GtkMatrixChooser
+{
+  GtkWidget parent_instance;
+};
+
+G_DEFINE_TYPE (GtkMatrixChooser, gtk_matrix_chooser, GTK_TYPE_WIDGET)
+
+static void
+gtk_matrix_chooser_init (GtkMatrixChooser *self)
+{
+  gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
+}
+
+static void
+gtk_matrix_chooser_class_init (GtkMatrixChooserClass *klass)
+{
+
+}
+
+
+/* ######################################################################### */
+/* ############################# TransformTester ########################### */
+/* ######################################################################### */
+
+#define TEST_WIDGET_MIN_SIZE 100
+
+#define GTK_TYPE_TRANSFORM_TESTER (gtk_transform_tester_get_type ())
+G_DECLARE_FINAL_TYPE (GtkTransformTester, gtk_transform_tester, GTK, TRANSFORM_TESTER, GtkWidget);
+
+struct _GtkTransformTester
+{
+  GtkWidget parent_instance;
+
+  GtkWidget *test_widget;
+  int pick_increase;
+};
+
+G_DEFINE_TYPE (GtkTransformTester, gtk_transform_tester, GTK_TYPE_WIDGET);
+
+static void
+gtk_transform_tester_measure (GtkWidget      *widget,
+                              GtkOrientation  orientation,
+                              int             for_size,
+                              int            *minimum,
+                              int            *natural,
+                              int            *minimum_baseline,
+                              int            *natural_baseline)
+{
+  GtkTransformTester *self = (GtkTransformTester *)widget;
+
+  if (self->test_widget)
+    {
+      gtk_widget_measure (self->test_widget, orientation, for_size,
+                          minimum, natural, NULL, NULL);
+    }
+}
+
+static void
+gtk_transform_tester_size_allocate (GtkWidget  *widget,
+                                    int         width,
+                                    int         height,
+                                    int         baseline)
+{
+  GtkTransformTester *self = (GtkTransformTester *)widget;
+  graphene_matrix_t global_transform;
+  int w, h;
+
+  if (!self->test_widget)
+    return;
+
+  scale += 2.5f;
+
+  gtk_widget_measure (self->test_widget, GTK_ORIENTATION_HORIZONTAL, -1,
+                      &w, NULL, NULL, NULL);
+  gtk_widget_measure (self->test_widget, GTK_ORIENTATION_VERTICAL, w,
+                      &h, NULL, NULL, NULL);
+
+  g_message ("%s: %d, %d", __FUNCTION__, w, h);
+
+  graphene_matrix_init_identity (&global_transform);
+
+  graphene_matrix_translate (&global_transform, &(graphene_point3d_t){ -w/2.0f, -h/2.0f, 0});
+  graphene_matrix_rotate (&global_transform, scale,
+                          graphene_vec3_z_axis ());
+
+  graphene_matrix_translate (&global_transform, &(graphene_point3d_t){ width / 2.0f, height / 2.0f, 0});
+
+
+#if 0
+  gtk_widget_size_allocate (self->test_widget,
+                            &(GtkAllocation){ (width- w) / 2, (height - h) / 2, w,h }, -1);
+#else
+  gtk_widget_allocate (self->test_widget,
+                       w, h,
+                       -1,
+                       &global_transform);
+#endif
+}
+
+static void
+gtk_transform_tester_snapshot (GtkWidget   *widget,
+                               GtkSnapshot *snapshot)
+{
+  GtkTransformTester *self = (GtkTransformTester *)widget;
+  const int width = gtk_widget_get_width (widget);
+  const int height = gtk_widget_get_height (widget);
+  const int inc = self->pick_increase;
+  graphene_rect_t child_bounds;
+  graphene_rect_t self_bounds;
+  int x, y;
+
+  GTK_WIDGET_CLASS (gtk_transform_tester_parent_class)->snapshot (widget, snapshot);
+
+  if (!do_picking)
+    return;
+  gtk_widget_compute_bounds (self->test_widget, widget, &child_bounds);
+  gtk_widget_compute_bounds (self->test_widget, self->test_widget, &self_bounds);
+
+  {
+    const struct {
+      graphene_point_t coords;
+      GdkRGBA color;
+    } points[4] = {
+      { self_bounds.origin, {1, 0, 0, 1} },
+      { GRAPHENE_POINT_INIT (self_bounds.origin.x + self_bounds.size.width, self_bounds.origin.y), {0, 1, 0, 
1} },
+      { GRAPHENE_POINT_INIT (self_bounds.origin.x + self_bounds.size.width, self_bounds.origin.y + 
self_bounds.size.height), {0, 0, 1, 1} },
+      { GRAPHENE_POINT_INIT (self_bounds.origin.x, self_bounds.origin.y + self_bounds.size.height), {1, 0, 
1, 1} }
+    };
+
+    for (x = 0; x < G_N_ELEMENTS (points); x ++)
+      {
+        int px, py;
+
+        gtk_widget_translate_coordinates (self->test_widget, widget,
+                                          points[x].coords.x, points[x].coords.y,
+                                          &px, &py);
+
+        gtk_snapshot_append_color (snapshot, &points[x].color,
+                                   &GRAPHENE_RECT_INIT (px, py,
+                                                        4,
+                                                        4));
+      }
+  }
+
+  /* Now add custom drawing */
+  for (x = 0; x < width; x += inc)
+    {
+      for (y = 0; y < height; y += inc)
+        {
+          const float px = x;
+          const float py = y;
+          GtkWidget *picked;
+#if 1
+          picked = gtk_widget_pick (widget, px, py);
+#else
+          {
+            int dx, dy;
+            gtk_widget_translate_coordinates (widget, self->test_widget, px, py, &dx, &dy);
+            picked = gtk_widget_pick (self->test_widget, dx, dy);
+          }
+#endif
+
+          if (picked == self->test_widget)
+            gtk_snapshot_append_color (snapshot, &GREEN,
+                                       &GRAPHENE_RECT_INIT (px - (inc / 2), py - (inc / 2), inc, inc));
+          else if (picked == test_child)
+            gtk_snapshot_append_color (snapshot, &BLUE,
+                                       &GRAPHENE_RECT_INIT (px - (inc / 2), py - (inc / 2), inc, inc));
+
+          else
+            gtk_snapshot_append_color (snapshot, &RED,
+                                       &GRAPHENE_RECT_INIT (px - (inc / 2), py - (inc / 2), inc, inc));
+        }
+    }
+
+  gtk_snapshot_append_color (snapshot, &BLACK,
+                             &GRAPHENE_RECT_INIT (child_bounds.origin.x,
+                                                  child_bounds.origin.y,
+                                                  child_bounds.size.width,
+                                                  1));
+
+  gtk_snapshot_append_color (snapshot, &BLACK,
+                             &GRAPHENE_RECT_INIT (child_bounds.origin.x + child_bounds.size.width,
+                                                  child_bounds.origin.y,
+                                                  1,
+                                                  child_bounds.size.height));
+
+  gtk_snapshot_append_color (snapshot, &BLACK,
+                             &GRAPHENE_RECT_INIT (child_bounds.origin.x,
+                                                  child_bounds.origin.y + child_bounds.size.height,
+                                                  child_bounds.size.width,
+                                                  1));
+
+  gtk_snapshot_append_color (snapshot, &BLACK,
+                             &GRAPHENE_RECT_INIT (child_bounds.origin.x,
+                                                  child_bounds.origin.y,
+                                                  1,
+                                                  child_bounds.size.height));
+}
+
+static void
+gtk_transform_tester_init (GtkTransformTester *self)
+{
+  gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
+
+  self->pick_increase = 4;
+}
+
+static void
+gtk_transform_tester_class_init (GtkTransformTesterClass *klass)
+{
+  GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+  widget_class->measure = gtk_transform_tester_measure;
+  widget_class->size_allocate = gtk_transform_tester_size_allocate;
+  widget_class->snapshot = gtk_transform_tester_snapshot;
+
+  gtk_widget_class_set_css_name (widget_class, "test");
+}
+
+static gboolean
+tick_cb (GtkWidget     *widget,
+         GdkFrameClock *frame_clock,
+         gpointer       user_data)
+{
+  gtk_widget_queue_allocate (widget);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+gtk_transform_tester_set_test_widget (GtkTransformTester *self,
+                                      GtkWidget          *test_widget)
+{
+  g_assert (!self->test_widget);
+
+  self->test_widget = test_widget;
+  gtk_widget_set_parent (test_widget, (GtkWidget *)self);
+
+  gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, NULL, NULL);
+}
+
+static void
+toggled_cb (GtkToggleButton *source,
+            gpointer         user_data)
+{
+  do_picking = gtk_toggle_button_get_active (source);
+}
+
+int
+main (int argc, char **argv)
+{
+  GtkWidget *window;
+  GtkWidget *matrix_chooser;
+  GtkWidget *box;
+  GtkWidget *titlebar;
+  GtkWidget *toggle_button;
+  GtkCssProvider *provider;
+
+  gtk_init ();
+
+  provider = gtk_css_provider_new ();
+  gtk_css_provider_load_from_data (provider, css, -1);
+  gtk_style_context_add_provider_for_display (gdk_display_get_default (),
+                                              GTK_STYLE_PROVIDER (provider),
+                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  matrix_chooser = g_object_new (GTK_TYPE_MATRIX_CHOOSER, NULL);
+  transform_tester = g_object_new (GTK_TYPE_TRANSFORM_TESTER, NULL);
+  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+  titlebar = gtk_header_bar_new ();
+
+  gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
+  gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (titlebar), TRUE);
+
+  toggle_button = gtk_toggle_button_new ();
+  gtk_button_set_label (GTK_BUTTON (toggle_button), "Picking");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), do_picking);
+  g_signal_connect (toggle_button, "toggled", G_CALLBACK (toggled_cb), NULL);
+  gtk_container_add (GTK_CONTAINER (titlebar), toggle_button);
+
+  test_widget = gtk_button_new ();
+  gtk_widget_set_size_request (test_widget, TEST_WIDGET_MIN_SIZE, TEST_WIDGET_MIN_SIZE);
+  gtk_widget_set_halign (test_widget, GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (test_widget, GTK_ALIGN_CENTER);
+
+
+  test_child = gtk_image_new_from_icon_name ("weather-clear");
+  gtk_widget_set_halign (test_child, GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (test_child, GTK_ALIGN_CENTER);
+  gtk_widget_set_size_request (test_child, TEST_WIDGET_MIN_SIZE / 2, TEST_WIDGET_MIN_SIZE / 2);
+  gtk_container_add (GTK_CONTAINER (test_widget), test_child);
+
+
+  gtk_transform_tester_set_test_widget (GTK_TRANSFORM_TESTER (transform_tester), test_widget);
+
+  gtk_widget_set_vexpand (transform_tester, TRUE);
+  gtk_container_add (GTK_CONTAINER (box), transform_tester);
+  gtk_container_add (GTK_CONTAINER (box), matrix_chooser);
+  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]