summaryrefslogtreecommitdiff
path: root/tests/scrolling-performance.c
blob: 5b6aac2482ba0822548167ce66b0cb3e6cda49e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */

#include <gtk/gtk.h>
#include <math.h>

#include "frame-stats.h"

GtkWidget *
create_widget_factory_content (void)
{
  GError *error = NULL;
  GtkBuilder *builder;
  GtkWidget *result;

  builder = gtk_builder_new ();
  gtk_builder_add_from_file (builder,
                             "../demos/widget-factory/widget-factory.ui",
                             &error);
  if (error != NULL)
    g_error ("Failed to create widgets: %s\n", error->message);

  result = GTK_WIDGET (gtk_builder_get_object (builder, "box1"));
  g_object_ref (result);
  gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (result)),
                        result);
  g_object_unref (builder);

  return result;
}

static void
set_adjustment_to_fraction (GtkAdjustment *adjustment,
                            gdouble        fraction)
{
  gdouble upper = gtk_adjustment_get_upper (adjustment);
  gdouble lower = gtk_adjustment_get_lower (adjustment);
  gdouble page_size = gtk_adjustment_get_page_size (adjustment);

  gtk_adjustment_set_value (adjustment,
                            (1 - fraction) * lower +
                            fraction * (upper - page_size));
}

gboolean
scroll_viewport (GtkWidget     *viewport,
                 GdkFrameClock *frame_clock,
                 gpointer       user_data)
{
  static gint64 start_time;
  gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
  gdouble elapsed;
  GtkAdjustment *hadjustment, *vadjustment;

  if (start_time == 0)
    start_time = now;

  elapsed = (now - start_time) / 1000000.;

  hadjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (viewport));
  vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (viewport));

  set_adjustment_to_fraction (hadjustment, 0.5 + 0.5 * sin (elapsed));
  set_adjustment_to_fraction (vadjustment, 0.5 + 0.5 * cos (elapsed));

  return TRUE;
}

static GOptionEntry options[] = {
  { NULL }
};

int
main (int argc, char **argv)
{
  GtkWidget *window;
  GtkWidget *scrolled_window;
  GtkWidget *viewport;
  GtkWidget *grid;
  GError *error = NULL;
  int i;

  GOptionContext *context = g_option_context_new (NULL);
  g_option_context_add_main_entries (context, options, NULL);
  frame_stats_add_options (g_option_context_get_main_group (context));
  g_option_context_add_group (context,
                              gtk_get_option_group (TRUE));

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      g_printerr ("Option parsing failed: %s\n", error->message);
      return 1;
    }

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  frame_stats_ensure (GTK_WINDOW (window));
  gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);

  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (window), scrolled_window);

  viewport = gtk_viewport_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (scrolled_window), viewport);

  grid = gtk_grid_new ();
  gtk_container_add (GTK_CONTAINER (viewport), grid);

  for (i = 0; i < 4; i++)
    {
      GtkWidget *content = create_widget_factory_content ();
      gtk_grid_attach (GTK_GRID (grid), content,
                       i % 2, i / 2, 1, 1);
      g_object_unref (content);
    }

  gtk_widget_add_tick_callback (viewport,
                                scroll_viewport,
                                NULL,
                                NULL);

  gtk_widget_show_all (window);
  g_signal_connect (window, "destroy",
                    G_CALLBACK (gtk_main_quit), NULL);
  gtk_main ();

  return 0;
}