1 /* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
2 
3 #include <gtk/gtk.h>
4 #include <math.h>
5 
6 #include "frame-stats.h"
7 
8 
9 /* Stub definition of MyTextView which is used in the
10  * widget-factory.ui file. We just need this so the
11  * test keeps working
12  */
13 typedef struct
14 {
15   GtkTextView tv;
16 } MyTextView;
17 
18 typedef GtkTextViewClass MyTextViewClass;
19 
20 static GType my_text_view_get_type (void);
G_DEFINE_TYPE(MyTextView,my_text_view,GTK_TYPE_TEXT_VIEW)21 G_DEFINE_TYPE (MyTextView, my_text_view, GTK_TYPE_TEXT_VIEW)
22 
23 static void
24 my_text_view_init (MyTextView *tv) {}
25 
26 static void
my_text_view_class_init(MyTextViewClass * tv_class)27 my_text_view_class_init (MyTextViewClass *tv_class) {}
28 
29 
30 
31 static GtkWidget *
create_widget_factory_content(void)32 create_widget_factory_content (void)
33 {
34   GError *error = NULL;
35   GtkBuilder *builder;
36   GtkWidget *result;
37 
38   g_type_ensure (my_text_view_get_type ());
39   builder = gtk_builder_new ();
40   gtk_builder_add_from_file (builder, "./testsuite/gtk/focus-chain/widget-factory.ui", &error);
41   if (error != NULL)
42     g_error ("Failed to create widgets: %s", error->message);
43 
44   result = GTK_WIDGET (gtk_builder_get_object (builder, "box1"));
45   g_object_ref (result);
46   gtk_window_set_child (GTK_WINDOW (gtk_widget_get_parent (result)), NULL);
47   g_object_unref (builder);
48 
49   return result;
50 }
51 
52 static void
set_adjustment_to_fraction(GtkAdjustment * adjustment,double fraction)53 set_adjustment_to_fraction (GtkAdjustment *adjustment,
54                             double         fraction)
55 {
56   double upper = gtk_adjustment_get_upper (adjustment);
57   double lower = gtk_adjustment_get_lower (adjustment);
58   double page_size = gtk_adjustment_get_page_size (adjustment);
59 
60   gtk_adjustment_set_value (adjustment,
61                             (1 - fraction) * lower +
62                             fraction * (upper - page_size));
63 }
64 
65 static gboolean
scroll_viewport(GtkWidget * viewport,GdkFrameClock * frame_clock,gpointer user_data)66 scroll_viewport (GtkWidget     *viewport,
67                  GdkFrameClock *frame_clock,
68                  gpointer       user_data)
69 {
70   static gint64 start_time;
71   gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
72   double elapsed;
73   GtkAdjustment *hadjustment, *vadjustment;
74 
75   if (start_time == 0)
76     start_time = now;
77 
78   elapsed = (now - start_time) / 1000000.;
79 
80   hadjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (viewport));
81   vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (viewport));
82 
83   set_adjustment_to_fraction (hadjustment, 0.5 + 0.5 * sin (elapsed));
84   set_adjustment_to_fraction (vadjustment, 0.5 + 0.5 * cos (elapsed));
85 
86   return TRUE;
87 }
88 
89 static GOptionEntry options[] = {
90   { NULL }
91 };
92 
93 static void
quit_cb(GtkWidget * widget,gpointer data)94 quit_cb (GtkWidget *widget,
95          gpointer   data)
96 {
97   gboolean *done = data;
98 
99   *done = TRUE;
100 
101   g_main_context_wakeup (NULL);
102 }
103 
104 int
main(int argc,char ** argv)105 main (int argc, char **argv)
106 {
107   GtkWidget *window;
108   GtkWidget *scrolled_window;
109   GtkWidget *viewport;
110   GtkWidget *grid;
111   GError *error = NULL;
112   int i;
113   gboolean done = FALSE;
114 
115   GOptionContext *context = g_option_context_new (NULL);
116   g_option_context_add_main_entries (context, options, NULL);
117   frame_stats_add_options (g_option_context_get_main_group (context));
118 
119   if (!g_option_context_parse (context, &argc, &argv, &error))
120     {
121       g_printerr ("Option parsing failed: %s\n", error->message);
122       return 1;
123     }
124 
125   gtk_init ();
126 
127   window = gtk_window_new ();
128   frame_stats_ensure (GTK_WINDOW (window));
129   gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
130 
131   scrolled_window = gtk_scrolled_window_new ();
132   gtk_window_set_child (GTK_WINDOW (window), scrolled_window);
133 
134   viewport = gtk_viewport_new (NULL, NULL);
135   gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled_window), viewport);
136 
137   grid = gtk_grid_new ();
138   gtk_viewport_set_child (GTK_VIEWPORT (viewport), grid);
139 
140   for (i = 0; i < 4; i++)
141     {
142       GtkWidget *content = create_widget_factory_content ();
143       gtk_grid_attach (GTK_GRID (grid), content,
144                        i % 2, i / 2, 1, 1);
145       g_object_unref (content);
146     }
147 
148   gtk_widget_add_tick_callback (viewport,
149                                 scroll_viewport,
150                                 NULL,
151                                 NULL);
152 
153   gtk_widget_show (window);
154   g_signal_connect (window, "destroy",
155                     G_CALLBACK (quit_cb), &done);
156 
157   while (!done)
158     g_main_context_iteration (NULL, TRUE);
159 
160   return 0;
161 }
162