43a9b29c3ae89518c90c71459960c292710ffa6c
[clutter-gtk] / examples / gtk-clutter-events.c
1 #include <gtk/gtk.h>
2 #include <clutter/clutter.h>
3
4 #include <clutter-gtk/gtk-clutter-embed.h>
5 #include <clutter-gtk/gtk-clutter-util.h>
6
7 typedef struct {
8
9   GtkWidget    *window;
10   GtkWidget    *popup;
11   GtkWidget    *gtk_entry;
12
13   ClutterActor *stage;
14   ClutterActor *hand;
15   ClutterActor *clutter_entry;
16
17 } EventApp;
18
19 static void
20 on_gtk_entry_changed (GtkEditable *editable, EventApp *app)
21 {
22   const gchar *text = gtk_entry_get_text (GTK_ENTRY (editable));
23
24   clutter_entry_set_text (CLUTTER_ENTRY (app->clutter_entry), text);
25 }
26
27 static void
28 on_x_changed (GtkSpinButton *button, EventApp *app)
29 {
30   clutter_actor_set_rotation (app->hand, CLUTTER_X_AXIS,
31                               gtk_spin_button_get_value (button),
32                               0,
33                               clutter_actor_get_height (app->hand) / 2,
34                               0);
35 }
36
37 static void
38 on_y_changed (GtkSpinButton *button, EventApp *app)
39 {
40   clutter_actor_set_rotation (app->hand, CLUTTER_Y_AXIS,
41                               gtk_spin_button_get_value (button),
42                               clutter_actor_get_width (app->hand) / 2,
43                               0,
44                               0);
45 }
46
47 static void
48 on_z_changed (GtkSpinButton *button, EventApp *app)
49 {
50   clutter_actor_set_rotation (app->hand, CLUTTER_Z_AXIS,
51                               gtk_spin_button_get_value (button),
52                               clutter_actor_get_width (app->hand) / 2,
53                               clutter_actor_get_height (app->hand) / 2,
54                               0);
55 }
56
57 static void
58 on_opacity_changed (GtkSpinButton *button, EventApp *app)
59 {
60   clutter_actor_set_opacity (app->hand, gtk_spin_button_get_value (button)); 
61 }
62
63 /* Set the clutter colors form the current gtk theme */
64 static void
65 create_colors (EventApp *app, ClutterColor *stage, ClutterColor *text)
66 {
67   gtk_clutter_get_bg_color (app->window, GTK_STATE_NORMAL, stage);
68   gtk_clutter_get_text_color (app->window, GTK_STATE_NORMAL, text);
69 }
70
71 static gboolean
72 on_stage_capture (ClutterActor *actor,
73                   ClutterEvent *event,
74                   gpointer      dummy)
75 {
76   if (event->type == CLUTTER_BUTTON_RELEASE)
77     {
78       gint x, y;
79
80       clutter_event_get_coords (event, &x, &y);
81
82       g_print ("Event captured at (%d, %d)\n", x, y);
83     }
84
85   return FALSE;
86 }
87
88 static gboolean
89 on_hand_button_press (ClutterActor       *actor,
90                       ClutterButtonEvent *event,
91                       gpointer            dummy)
92 {
93   g_print ("Button press on hand ('%s')\n",
94            g_type_name (G_OBJECT_TYPE (actor)));
95
96   return FALSE;
97 }
98
99 gint
100 main (gint argc, gchar **argv)
101 {
102   EventApp      *app = g_new0 (EventApp, 1);
103   GtkWidget     *widget, *vbox, *hbox, *button, *label, *box;
104   ClutterActor  *actor;
105   GdkPixbuf     *pixbuf = NULL;
106   guint          width, height;
107   ClutterColor   stage_color = {255, 255, 255, 255};
108   ClutterColor   text_color = {0, 0, 0, 255};
109
110   if (gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
111     g_error ("Unable to initialize GtkClutter");
112
113   /* Create the inital gtk window and widgets, just like normal */
114   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
115   app->window = widget;
116   gtk_window_set_title (GTK_WINDOW (widget), "Gtk-Clutter Interaction demo");
117   gtk_window_set_default_size (GTK_WINDOW (widget), 800, 600);
118   gtk_window_set_resizable (GTK_WINDOW (widget), FALSE);
119   gtk_container_set_border_width (GTK_CONTAINER (widget), 12);
120   g_signal_connect (widget, "destroy", G_CALLBACK (gtk_main_quit), NULL);
121  
122   /* Create our layout box */
123   vbox = gtk_vbox_new (FALSE, 12);
124   gtk_container_add (GTK_CONTAINER (app->window), vbox);
125
126   widget = gtk_entry_new ();
127   app->gtk_entry = widget;
128   gtk_entry_set_text (GTK_ENTRY (widget), "Enter some text");
129   gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
130   g_signal_connect (widget, "changed", G_CALLBACK (on_gtk_entry_changed), app);
131
132   hbox = gtk_hbox_new (FALSE, 12);
133   gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
134   
135   /* Set up clutter & create our stage */
136   create_colors (app, &stage_color, &text_color);
137   widget = gtk_clutter_embed_new ();
138   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
139   app->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (widget));
140   clutter_stage_set_color (CLUTTER_STAGE (app->stage), &stage_color);
141   gtk_widget_set_size_request (widget, 640, 480);
142   g_signal_connect (app->stage, "captured-event",
143                     G_CALLBACK (on_stage_capture),
144                     NULL);
145
146   /* Create the main texture that the spin buttons manipulate */
147   pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL);
148   if (pixbuf == NULL)
149     g_error ("Unable to load pixbuf\n");
150
151   actor = clutter_texture_new_from_pixbuf (pixbuf);
152   app->hand = actor;
153   clutter_group_add (CLUTTER_GROUP (app->stage), actor);
154   clutter_actor_get_size (actor, &width, &height);
155   clutter_actor_set_position (actor,
156                               (CLUTTER_STAGE_WIDTH ()/2) - (width/2),
157                               (CLUTTER_STAGE_HEIGHT ()/2) - (height/2));
158   clutter_actor_set_reactive (actor, TRUE);
159   g_signal_connect (actor, "button-press-event",
160                     G_CALLBACK (on_hand_button_press),
161                     NULL);
162
163   /* Setup the clutter entry */
164   actor = clutter_entry_new_full ("Sans 10", "", &text_color);
165   app->clutter_entry = actor;
166   clutter_group_add (CLUTTER_GROUP (app->stage), actor);
167   clutter_actor_set_position (actor, 0, 0);
168   clutter_actor_set_size (actor, 500, 20);
169
170   /* Create our adjustment widgets */
171   vbox = gtk_vbox_new (FALSE, 6);
172   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
173
174   box = gtk_hbox_new (TRUE, 6);
175   gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 0);
176   label = gtk_label_new ("Rotate x-axis");
177   gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
178   button = gtk_spin_button_new_with_range (0, 360, 1);
179   gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
180   g_signal_connect (button, "value-changed", G_CALLBACK (on_x_changed), app);
181   
182   box = gtk_hbox_new (TRUE, 6);
183   gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 0);
184   label = gtk_label_new ("Rotate y-axis");
185   gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
186   button = gtk_spin_button_new_with_range (0, 360, 1);
187   gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
188   g_signal_connect (button, "value-changed", G_CALLBACK (on_y_changed), app);
189
190   box = gtk_hbox_new (TRUE, 6);
191   gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 0);
192   label = gtk_label_new ("Rotate z-axis");
193   gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
194   button = gtk_spin_button_new_with_range (0, 360, 1);
195   gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
196   g_signal_connect (button, "value-changed", G_CALLBACK (on_z_changed), app);
197
198   box = gtk_hbox_new (TRUE, 6);
199   gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 0);
200   label = gtk_label_new ("Adjust opacity");
201   gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
202   button = gtk_spin_button_new_with_range (0, 255, 1);
203   gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), 255);
204   gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
205   g_signal_connect (button, "value-changed", G_CALLBACK (on_opacity_changed), app);
206
207   gtk_widget_show_all (app->window);
208
209   /* Only show/show_all the stage after parent show. widget_show will call
210    * show on the stage.
211   */
212   clutter_actor_show_all (app->stage);
213
214   gtk_main ();
215   
216   return 0;
217 }