summaryrefslogtreecommitdiff
path: root/demos/gtk-demo/gltransition.c
blob: 4b994216c4d0c16e9a1825c5e6f2f2141b924123 (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
/* OpenGL/Transitions
 * #Keywords: OpenGL, shader
 *
 * Create transitions between pages using a custom fragment shader.
 *
 * The examples here are taken from gl-transitions.com.
 */
#include <math.h>
#include <gtk/gtk.h>
#include "gtkshaderstack.h"

static GtkWidget *demo_window = NULL;

static void
close_window (GtkWidget *widget)
{
  /* Reset the state */
  demo_window = NULL;
}

static GskGLShader *
gsk_shader_new_from_resource (const char *resource_path)
{
  GBytes *shader_b;
  GskGLShader *shader;

  shader_b = g_resources_lookup_data (resource_path, 0, NULL);
  shader = gsk_glshader_new ((const char *)g_bytes_get_data (shader_b, NULL));
  g_bytes_unref (shader_b);

  return shader;
}

static GtkWidget *
make_shader_stack (const char *resource_path)
{
  GtkWidget *stack, *child;
  GskGLShader *shader;

  stack = gtk_shader_stack_new ();
  shader = gsk_shader_new_from_resource (resource_path);
  gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
  g_object_unref (shader);

  child = gtk_picture_new_for_resource ("/css_pixbufs/background.jpg");
  gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
  gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);

  child = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
  gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
  gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);

  child = gtk_picture_new_for_resource ("/css_blendmodes/ducky.png");
  gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
  gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);

  return stack;
}

static GtkWidget *
create_gltransition_window (GtkWidget *do_widget)
{
  GtkWidget *window, *grid;

  window = gtk_window_new ();
  gtk_window_set_display (GTK_WINDOW (window),  gtk_widget_get_display (do_widget));
  gtk_window_set_title (GTK_WINDOW (window), "Transitions");
  gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
  g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);

  grid = gtk_grid_new ();
  gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
  gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
  gtk_widget_set_margin_start (grid, 12);
  gtk_widget_set_margin_end (grid, 12);
  gtk_widget_set_margin_top (grid, 12);
  gtk_widget_set_margin_bottom (grid, 12);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
  gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
  gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
  gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);

  gtk_window_set_child (GTK_WINDOW (window), grid);

  gtk_grid_attach (GTK_GRID (grid),
                   make_shader_stack ("/gltransition/transition1.glsl"),
                   0, 0, 1, 1);
  gtk_grid_attach (GTK_GRID (grid),
                   make_shader_stack ("/gltransition/transition2.glsl"),
                   1, 0, 1, 1);
  gtk_grid_attach (GTK_GRID (grid),
                   make_shader_stack ("/gltransition/transition3.glsl"),
                   0, 1, 1, 1);
  gtk_grid_attach (GTK_GRID (grid),
                   make_shader_stack ("/gltransition/transition4.glsl"),
                   1, 1, 1, 1);

  return window;
}

GtkWidget *
do_gltransition (GtkWidget *do_widget)
{
  if (!demo_window)
    demo_window = create_gltransition_window (do_widget);

  if (!gtk_widget_get_visible (demo_window))
    gtk_widget_show (demo_window);
  else
    gtk_window_destroy (GTK_WINDOW (demo_window));

  return demo_window;
}