[gimp] app/tests: Add keyboard zoom focus regression test



commit 7e3898da0934bcab753747ace4ae2477e801b34b
Author: Martin Nordholts <martinn src gnome org>
Date:   Fri Jun 18 20:57:59 2010 +0200

    app/tests: Add keyboard zoom focus regression test
    
    Add keyboard zoom focus regression test. We also need a new display
    shell utility function
    gimp_display_shell_push_zoom_focus_pointer_pos() for that.

 app/display/gimpdisplayshell-scale.c |   40 ++++++++++++-
 app/display/gimpdisplayshell-scale.h |    3 +
 app/display/gimpdisplayshell.c       |    2 +
 app/display/gimpdisplayshell.h       |    2 +
 app/tests/test-ui.c                  |  106 ++++++++++++++++++++++++++++++++++
 5 files changed, 150 insertions(+), 3 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c
index c167947..859f913 100644
--- a/app/display/gimpdisplayshell-scale.c
+++ b/app/display/gimpdisplayshell-scale.c
@@ -841,6 +841,28 @@ gimp_display_shell_set_initial_scale (GimpDisplayShell *shell,
 }
 
 /**
+ * gimp_display_shell_push_zoom_focus_pointer_pos:
+ * @shell:
+ * @x:
+ * @y:
+ *
+ * When the zoom focus mechanism asks for the pointer the next time,
+ * use @x and @y.
+ **/
+void
+gimp_display_shell_push_zoom_focus_pointer_pos (GimpDisplayShell *shell,
+                                                gint              x,
+                                                gint              y)
+{
+  GdkPoint *point = g_slice_new (GdkPoint);
+  point->x = x;
+  point->y = y;
+
+  g_queue_push_head (shell->zoom_focus_pointer_queue,
+                     point);
+}
+
+/**
  * gimp_display_shell_scale_to:
  * @shell:
  * @scale:
@@ -1051,9 +1073,21 @@ gimp_display_shell_scale_get_zoom_focus (GimpDisplayShell *shell,
                         gtk_get_event_widget (event) == window);
 
 
-    gtk_widget_get_pointer (shell->canvas,
-                            &canvas_pointer_x,
-                            &canvas_pointer_y);
+    if (g_queue_peek_head (shell->zoom_focus_pointer_queue) == NULL)
+      {
+        gtk_widget_get_pointer (shell->canvas,
+                                &canvas_pointer_x,
+                                &canvas_pointer_y);
+      }
+    else
+      {
+        GdkPoint *point = g_queue_pop_head (shell->zoom_focus_pointer_queue);
+
+        canvas_pointer_x = point->x;
+        canvas_pointer_y = point->y;
+
+        g_slice_free (GdkPoint, point);
+      }
 
     cursor_within_canvas = canvas_pointer_x >= 0 &&
                            canvas_pointer_y >= 0 &&
diff --git a/app/display/gimpdisplayshell-scale.h b/app/display/gimpdisplayshell-scale.h
index 3dfc4bb..50185dc 100644
--- a/app/display/gimpdisplayshell-scale.h
+++ b/app/display/gimpdisplayshell-scale.h
@@ -62,6 +62,9 @@ void     gimp_display_shell_set_initial_scale              (GimpDisplayShell *sh
                                                             gdouble           scale,
                                                             gint             *display_width,
                                                             gint             *display_height);
+void     gimp_display_shell_push_zoom_focus_pointer_pos    (GimpDisplayShell *shell,
+                                                            gint              x,
+                                                            gint              y);
 
 
 #endif  /*  __GIMP_DISPLAY_SHELL_SCALE_H__  */
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index 227e5b3..2650995 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -304,6 +304,8 @@ gimp_display_shell_init (GimpDisplayShell *shell)
   shell->event_history = g_array_new (FALSE, FALSE, sizeof (GimpCoords));
   shell->event_queue   = g_array_new (FALSE, FALSE, sizeof (GimpCoords));
 
+  shell->zoom_focus_pointer_queue = g_queue_new ();
+
   gtk_widget_set_events (GTK_WIDGET (shell), (GDK_POINTER_MOTION_MASK      |
                                               GDK_POINTER_MOTION_HINT_MASK |
                                               GDK_BUTTON_PRESS_MASK        |
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index 46f4251..562eb4e 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -198,6 +198,8 @@ struct _GimpDisplayShell
   gboolean           event_delay;      /* TRUE if theres an unsent event in
                                           the history buffer                  */
 
+  GQueue            *zoom_focus_pointer_queue;
+
   gint               event_delay_timeout;
   GdkModifierType    last_active_state;
 };
diff --git a/app/tests/test-ui.c b/app/tests/test-ui.c
index 85902ef..2233298 100644
--- a/app/tests/test-ui.c
+++ b/app/tests/test-ui.c
@@ -23,11 +23,13 @@
 
 #include "libgimpbase/gimpbase.h"
 #include "libgimpmath/gimpmath.h"
+#include "libgimpwidgets/gimpwidgets.h"
 
 #include "dialogs/dialogs-types.h"
 
 #include "display/gimpdisplay.h"
 #include "display/gimpdisplayshell.h"
+#include "display/gimpdisplayshell-scale.h"
 #include "display/gimpdisplayshell-transform.h"
 #include "display/gimpimagewindow.h"
 
@@ -44,6 +46,7 @@
 
 #include "core/gimp.h"
 #include "core/gimpcontext.h"
+#include "core/gimpimage.h"
 #include "core/gimptoolinfo.h"
 #include "core/gimptooloptions.h"
 
@@ -54,6 +57,7 @@
 
 #define GIMP_UI_WINDOW_POSITION_EPSILON 10
 #define GIMP_UI_POSITION_EPSILON        1
+#define GIMP_UI_ZOOM_EPSILON            0.01
 
 #define ADD_TEST(function) \
   g_test_add ("/gimp-ui/" #function, \
@@ -75,6 +79,7 @@ typedef struct
 
 static GimpUIManager * gimp_ui_get_ui_manager                   (Gimp              *gimp);
 static void            gimp_ui_synthesize_delete_event          (GtkWidget         *widget);
+static void            gimp_ui_synthesize_plus_key_event        (GtkWidget         *widget);
 static GtkWidget     * gimp_ui_find_dock_window                 (GimpDialogFactory *dialog_factory,
                                                                  GimpUiTestFunc     predicate);
 static gboolean        gimp_ui_not_toolbox_window               (GObject           *object);
@@ -254,6 +259,68 @@ create_new_image_via_dialog (GimpTestFixture *fixture,
 }
 
 static void
+keyboard_zoom_focus (GimpTestFixture *fixture,
+                     gconstpointer    data)
+{
+  Gimp              *gimp    = GIMP (data);
+  GimpDisplay       *display = GIMP_DISPLAY (gimp_get_display_iter (gimp)->data);
+  GimpDisplayShell  *shell   = gimp_display_get_shell (display);
+  GimpImageWindow   *window  = gimp_display_shell_get_window (shell);
+  gint               image_x;
+  gint               image_y;
+  gint               shell_x_before_zoom;
+  gint               shell_y_before_zoom;
+  gdouble            factor_before_zoom;
+  gint               shell_x_after_zoom;
+  gint               shell_y_after_zoom;
+  gdouble            factor_after_zoom;
+
+  /* We need to use a point that is within the visible (exposed) part
+   * of the canvas
+   */
+  image_x = 400;
+  image_y = 50;
+
+  /* Setup zoom focus on the bottom right part of the image. We avoid
+   * 0,0 because that's essentially a particularly easy special case.
+   */
+  gimp_display_shell_transform_xy (shell,
+                                   image_x,
+                                   image_y,
+                                   &shell_x_before_zoom,
+                                   &shell_y_before_zoom,
+                                   FALSE /*use_offsets*/);
+  gimp_display_shell_push_zoom_focus_pointer_pos (shell,
+                                                  shell_x_before_zoom,
+                                                  shell_y_before_zoom);
+  factor_before_zoom = gimp_zoom_model_get_factor (shell->zoom);
+
+  /* Do the zoom */
+  gimp_ui_synthesize_plus_key_event (GTK_WIDGET (window));
+  gimp_test_run_mainloop_until_idle ();
+
+  /* Make sure the zoom focus point remained fixed */
+  gimp_display_shell_transform_xy (shell,
+                                   image_x,
+                                   image_y,
+                                   &shell_x_after_zoom,
+                                   &shell_y_after_zoom,
+                                   FALSE /*use_offsets*/);
+  factor_after_zoom = gimp_zoom_model_get_factor (shell->zoom);
+
+  /* First of all make sure a zoom happend at all */
+  g_assert_cmpfloat (fabs (factor_before_zoom - factor_after_zoom),
+                     >=,
+                     GIMP_UI_ZOOM_EPSILON);
+  g_assert_cmpint (ABS (shell_x_after_zoom - shell_x_before_zoom),
+                   <=,
+                   GIMP_UI_POSITION_EPSILON);
+  g_assert_cmpint (ABS (shell_y_after_zoom - shell_y_before_zoom),
+                   <=,
+                   GIMP_UI_POSITION_EPSILON);
+}
+
+static void
 restore_recently_closed_multi_column_dock (GimpTestFixture *fixture,
                                            gconstpointer    data)
 {
@@ -507,6 +574,44 @@ gimp_ui_synthesize_delete_event (GtkWidget *widget)
   gdk_event_free (event);
 }
 
+static void
+gimp_ui_synthesize_plus_key_event (GtkWidget *widget)
+{
+  GdkWindow *window           = NULL;
+  GdkEvent  *event            = NULL;
+  guint      keyval           = GDK_plus;
+  guint      hardware_keycode = 20;
+
+  /* FIXME: How do we figure out hardware_keycode, especially in a
+   * platform independent way? 20 is the hardware keycode on my
+   * machine for GDK_plus when using a X11 backend... I hope it will
+   * be the same on others running at least the X11 build of GTK+
+   */
+
+  window = gtk_widget_get_window (widget);
+  g_assert (window);
+
+  event = gdk_event_new (GDK_KEY_PRESS);
+  event->any.window           = g_object_ref (window);
+  event->any.send_event       = TRUE;
+  event->key.keyval           = keyval;
+  event->key.time             = GDK_CURRENT_TIME;
+  event->key.state            = 0;
+  event->key.hardware_keycode = hardware_keycode;
+  gdk_event_put (event);
+  gdk_event_free (event);
+
+  event = gdk_event_new (GDK_KEY_RELEASE);
+  event->any.window           = g_object_ref (window);
+  event->any.send_event       = TRUE;
+  event->key.keyval           = keyval;
+  event->key.time             = GDK_CURRENT_TIME;
+  event->key.state            = 0;
+  event->key.hardware_keycode = hardware_keycode;
+  gdk_event_put (event);
+  gdk_event_free (event);
+}
+
 static GtkWidget *
 gimp_ui_find_dock_window (GimpDialogFactory *dialog_factory,
                           GimpUiTestFunc     predicate)
@@ -569,6 +674,7 @@ int main(int argc, char **argv)
   ADD_TEST (tool_options_editor_updates);
   ADD_TEST (automatic_tab_style);
   ADD_TEST (create_new_image_via_dialog);
+  ADD_TEST (keyboard_zoom_focus);
   ADD_TEST (restore_recently_closed_multi_column_dock);
   ADD_TEST (tab_toggle_dont_change_dock_window_position);
   ADD_TEST (switch_to_single_window_mode);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]