done matrix slowly, finished init_scene_theme
[livewp] / applet / src / livewp-actor.c
1 /*vim: set sw=4 ts=4 et: */
2 /*
3  * This file is part of Live Wallpaper (livewp)
4  * 
5  * Copyright (C) 2010 Vlad Vasiliev
6  * Copyright (C) 2010 Tanya Makova
7  *       for the code
8  * 
9  * This software is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  * 
14  * This software is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  * 
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this software; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23 */
24 /*******************************************************************************/
25 #include "livewp-actor.h"
26
27 Actor* 
28 init_object(AWallpaperPlugin *desktop_plugin, 
29             gchar * name, 
30             gchar * filename, 
31             gint x, 
32             gint y, 
33             gint z, 
34             gint width, 
35             gint height, 
36             gboolean visible, 
37             gboolean load_image,
38             gint scale, 
39             gint opacity, 
40             void (*pfunc_change)(Actor*),
41             void (*pfunc_probability)(Actor*),
42             GPtrArray *child
43            )
44 {
45     Actor *actor = NULL;
46     actor = g_new0(Actor, 1);
47     actor->x = x;
48     actor->y = y;
49     actor->z = z;
50     actor->width = width;
51     actor->height = height;
52     actor->visible = visible;
53     actor->scale = scale;
54     actor->opacity = opacity;
55     actor->filename = g_strdup(filename);
56     actor->name = g_strdup(name);
57     actor->func_change = (gpointer)pfunc_change; 
58     actor->func_probability = (gpointer)pfunc_probability;
59     actor->child = child;
60     if (load_image)
61         create_hildon_actor(actor, desktop_plugin);
62     else 
63          actor->widget = NULL;
64     actor->time_start_animation = 0;
65     actor->duration_animation = 0;
66     return actor;
67 }
68
69 void 
70 destroy_actor(Actor *actor)
71 {
72     if (actor){
73         if (actor->child){
74             g_ptr_array_free(actor->child, TRUE);
75         }
76         if (actor->filename)
77             g_free(actor->filename);
78         if (actor->name)
79             g_free(actor->name);
80         gtk_widget_destroy(actor->widget);
81         //actor->widget = NULL;
82         g_free(actor);
83     }
84 }
85 static gint 
86 path_line(gint x0, gint x1, double t)
87 {
88     // уравниение прямой
89     return ((x1 - x0) * t + x0);
90 }
91 void
92 set_actor_scale(Actor *actor, double scalex, double scaley)
93 {
94     hildon_animation_actor_set_scale(
95             HILDON_ANIMATION_ACTOR(actor->widget), 
96             scalex, 
97             scaley
98     );
99
100 }
101
102 void 
103 set_actor_visible(Actor *actor, gboolean visible)
104 {
105     hildon_animation_actor_set_show(HILDON_ANIMATION_ACTOR(actor->widget), visible);
106 }
107
108 void
109 set_actor_position(Actor *actor, gint x, gint y, gint z, AWallpaperPlugin *desktop_plugin)
110 {
111     hildon_animation_actor_set_position_full(HILDON_ANIMATION_ACTOR (actor->widget), 
112                                              x-desktop_plugin->priv->xapplet, 
113                                              y-desktop_plugin->priv->yapplet, 
114                                              z);
115 }
116
117 void 
118 change_moon(Actor * actor, AWallpaperPlugin *desktop_plugin)
119 {
120     gint phase;
121     char *newfile;
122     gint x0 = 150,
123          x1 = 650, 
124          x, y;
125     struct timeval tvb;     
126     suseconds_t ms;
127     long sec;
128     double t;
129 #if 0
130     gint y0, y1, x2, y2;
131     double a, b, c;
132     a = (double)(y2 - (double)(x2*(y1-y0) + x1*y0 - x0*y1)/(x1-x0))/(x2*(x2-x0-x1)+x0*x1);
133     b = (double)(y1-y0)/(x1-x0) - (double)a*(x0+x1);
134     c = (double)(x1*y0 - x0*y1)/(x1-x0) + (double)a*x0*x1;
135     fprintf(stderr, "a=%f, b=%f, c=%f\n", a, b, c);
136 #endif
137     gettimeofday(&tvb, NULL);
138     
139     ms = tvb.tv_usec;
140     sec = tvb.tv_sec;
141
142     if (actor){
143         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
144             if (!actor->visible){
145                 actor->visible = TRUE;
146                 phase = get_moon_phase();
147                 newfile = g_strdup_printf( "%s%d.png", actor->name, phase);
148                 if (actor->filename)
149                     g_free(actor->filename);
150                 actor->filename = newfile;
151                 actor->time_start_animation = sec - fast_rnd(60 * 60);
152                 actor->duration_animation = 1 * 60 * 60;
153                 create_hildon_actor(actor, desktop_plugin);
154
155             }
156             t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
157             if (t <= 1)
158                 x = path_line(x0, x1, t);
159             else 
160                 x = path_line(x1, x0, t-1);
161             y = 0.001920*x*x - 1.536*x + 337.2;
162             //y = a*x*x + b*x + c;
163
164             set_actor_position(actor, x, y, actor->z, desktop_plugin);
165
166             if (t>=2){
167                 actor->time_start_animation = sec;
168             }
169
170          }else if (actor->visible){
171             actor->visible = FALSE;
172             fprintf(stderr, "destroy moon \n");
173             destroy_hildon_actor(actor);
174             actor->time_start_animation = 0;
175         } 
176     }
177     
178 }
179
180 void 
181 change_sun(Actor * actor, AWallpaperPlugin *desktop_plugin)
182 {
183     double alt, azm;
184     gint x, y;
185
186     //fprintf(stderr, "change sun\n");
187     if (actor){
188         if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
189             if (!actor->visible){
190                 actor->visible = TRUE;
191                 create_hildon_actor(actor, desktop_plugin);
192             }
193             get_sun_pos(&alt, &azm);
194             get_sun_screen_pos(alt, azm, &x, &y);
195             actor->x = x;
196             actor->y = y;
197             set_actor_position(actor, x, y, actor->z, desktop_plugin);
198             actor->time_start_animation = time(NULL) + 60;
199          }else if (actor->visible){
200             actor->visible = FALSE;
201             destroy_hildon_actor(actor);
202             actor->time_start_animation = 0;
203         } 
204     }
205     
206 }
207
208 void 
209 change_tram(Actor * actor, AWallpaperPlugin *desktop_plugin)
210 {
211     gint x0 = -300, y0 = 225, scale0 = 100,
212          x1 = 800, y1 = 162, scale1 = 130, 
213          x, y, scale;
214     struct timeval tvb;     
215     suseconds_t ms;
216     long sec;
217     double t;
218
219     //fprintf(stderr, "change tram\n");
220     gettimeofday(&tvb, NULL);
221     
222     ms = tvb.tv_usec;
223     sec = tvb.tv_sec;
224     
225     if (!actor->visible){
226         actor->visible = TRUE;
227         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
228             if (actor->filename)
229                 g_free(actor->filename);
230             actor->filename = g_strdup("tram_dark.png");
231         } else{
232             if (actor->filename)
233                 g_free(actor->filename);
234             actor->filename = g_strdup("tram.png");
235         }
236         create_hildon_actor(actor, desktop_plugin);
237     }
238     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
239     x = path_line(x0, x1, t);
240     y = path_line(y0, y1, t);
241     scale = path_line(scale0, scale1, t);
242     set_actor_position(actor, x, y, actor->z, desktop_plugin);
243     set_actor_scale(actor, (double)scale/100, (double)scale/100);
244     if (t >= 1){
245         /* stop animation */
246         actor->visible = FALSE;
247         destroy_hildon_actor(actor);
248         actor->time_start_animation = sec + fast_rnd(60);
249     }
250 }
251
252 void
253 change_plane1(Actor *actor, AWallpaperPlugin *desktop_plugin)
254 {
255     gint x0 = 620, y0 = 233,
256          x1 = 79, y1 = -146, 
257          x, y;
258     struct timeval tvb;     
259     suseconds_t ms;
260     long sec;
261     double t;
262
263     gettimeofday(&tvb, NULL);
264     
265     ms = tvb.tv_usec;
266     sec = tvb.tv_sec;
267 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
268    
269     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
270         if (actor->time_start_animation == 0){
271             actor->time_start_animation = sec + fast_rnd(180);
272             return;
273         }
274     }
275     if (!actor->visible){
276         actor->visible = TRUE;
277         create_hildon_actor(actor, desktop_plugin);
278     }
279     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
280     x = path_line(x0, x1, t);
281     y = path_line(y0, y1, t);
282     //scale = path_line(scale0, scale1, t);
283     set_actor_position(actor, x, y, actor->z, desktop_plugin);
284     if (t >= 1){
285         /* stop animation */
286         actor->visible = FALSE;
287         destroy_hildon_actor(actor);
288         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
289             actor->time_start_animation = 0;
290         else 
291             actor->time_start_animation = sec + fast_rnd(180);
292     }
293
294 }
295
296 void
297 change_plane2(Actor *actor, AWallpaperPlugin *desktop_plugin)
298 {
299     gint x0 = -actor->width, y0 = 45,
300          x1 = 800, y1 = 20, 
301          x, y;
302     struct timeval tvb;     
303     suseconds_t ms;
304     long sec;
305     double t;
306
307     gettimeofday(&tvb, NULL);
308     
309     ms = tvb.tv_usec;
310     sec = tvb.tv_sec;
311 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
312     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
313         if (actor->time_start_animation == 0){
314             actor->time_start_animation = sec + fast_rnd(180);
315             return;
316         }
317     }
318     if (!actor->visible){
319         actor->visible = TRUE;
320         create_hildon_actor(actor, desktop_plugin);
321     }
322
323     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
324     x = path_line(x0, x1, t);
325     y = path_line(y0, y1, t);
326     //scale = path_line(scale0, scale1, t);
327     set_actor_position(actor, x, y, actor->z, desktop_plugin);
328     if (t >= 1){
329         /* stop animation */
330         actor->visible = FALSE;
331         destroy_hildon_actor(actor);
332         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
333             actor->time_start_animation = 0;
334         else 
335             actor->time_start_animation = sec + fast_rnd(180);
336     }
337
338 }
339
340 void
341 change_cloud(Actor *actor, AWallpaperPlugin *desktop_plugin)
342 {
343     gint x0, y0 = 300, scale0 = 100,
344          x1, y1 = -actor->height, scale1 = 150, 
345          x, y, scale;
346     struct timeval tvb;     
347     suseconds_t ms;
348     long sec;
349     double t;
350     gchar *newfile;
351
352     //fprintf(stderr, "change cloud\n");
353     gettimeofday(&tvb, NULL);
354     
355     ms = tvb.tv_usec;
356     sec = tvb.tv_sec;
357    
358     if (!actor->visible){
359         actor->visible = TRUE;
360         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
361             newfile = g_strdup_printf("%s_dark.png", actor->name);
362         }else{
363             newfile = g_strdup_printf("%s.png", actor->name);
364         } 
365         if (actor->filename)
366             g_free(actor->filename);
367         actor->filename = newfile;
368          
369         create_hildon_actor(actor, desktop_plugin);
370     }
371     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
372     
373     if (desktop_plugin->priv->scene->wind_orientation == 1){
374         x0 = -actor->width;
375         x1 = 800;
376     }
377     else {
378         x0 = 800;
379         x1 = -actor->width;
380     }
381
382     x = path_line(x0, x1, t);    
383     y = -desktop_plugin->priv->scene->wind_angle * (x - x0) + actor->y;
384     scale = path_line(scale0, scale1, (double)(y - y0)/(y1 - y0));
385
386     set_actor_position(actor, x, y, actor->z, desktop_plugin);
387     set_actor_scale(actor, (double)scale/100, (double)scale/100);
388     if ((y < y1 || y > y0) || t >= 1){
389         /* stop animation */
390         actor->visible = FALSE;
391         destroy_hildon_actor(actor);
392         actor->time_start_animation = sec + fast_rnd(300);
393         actor->y = fast_rnd(300);
394     }
395
396 }
397
398 void
399 change_wind(Actor *actor, AWallpaperPlugin *desktop_plugin)
400 {
401     desktop_plugin->priv->scene->wind_orientation = fast_rnd(2);
402     if (desktop_plugin->priv->scene->wind_orientation == 0) desktop_plugin->priv->scene->wind_orientation = -1;
403     desktop_plugin->priv->scene->wind_angle = (double)(fast_rnd(200) - 100) / 100;
404     actor->time_start_animation = time(NULL) + (fast_rnd(10) + 10) * 60;
405     //fprintf(stderr, "change wind orient = %d angle = %f after = %d\n", scene.wind_orientation, scene.wind_angle, actor->time_start_animation-time(NULL));
406 }
407
408 void 
409 change_window1(Actor * actor, AWallpaperPlugin *desktop_plugin)
410 {
411     gint now = time(NULL);
412     if (desktop_plugin->priv->scene->daytime == TIME_DAY){
413         if (actor->widget){
414             actor->visible = FALSE;
415             destroy_hildon_actor(actor);
416         }
417         actor->time_start_animation = 0;
418         return;
419     }else {
420         if (!actor->widget)
421             create_hildon_actor(actor, desktop_plugin);
422         if (actor->time_start_animation == 0){
423             actor->time_start_animation = now + fast_rnd(30);
424             return;
425         }
426     }
427
428     if (!actor->visible)
429         actor->visible = TRUE;
430     else 
431         actor->visible = FALSE;
432     set_actor_visible(actor, actor->visible);
433     actor->time_start_animation = now + fast_rnd(60) + 10;
434
435 }
436
437 void 
438 change_signal(Actor * actor, AWallpaperPlugin *desktop_plugin)
439 {
440     gint now = time(NULL);
441     Actor *a;
442     a = g_ptr_array_index(actor->child, 0);
443     if (a->visible)
444         a->visible = FALSE;
445     else 
446         a->visible = TRUE;
447     set_actor_visible(a, a->visible);
448     
449     a = g_ptr_array_index(actor->child, 1);
450     if (a->visible)
451         a->visible = FALSE;
452     else 
453         a->visible = TRUE;
454     set_actor_visible(a, a->visible);
455
456     actor->time_start_animation = now + fast_rnd(30) + 10;
457 }
458
459 void
460 change_layer(Actor * actor, AWallpaperPlugin *desktop_plugin)
461 {
462     gint y, speed1 = 8, speed2 = 16;
463     Actor *a;
464
465     if (!desktop_plugin->priv->rich_animation) return;
466
467     a = g_ptr_array_index(actor->child, 0);
468     y = a->y + speed1;
469     if (y > 480) y = -480;
470     set_actor_position(a, a->x, y, a->z, desktop_plugin);
471     a->y = y;
472     
473     a = g_ptr_array_index(actor->child, 1);
474     y = a->y + speed1;
475     if (y > 480) y = -480;
476     set_actor_position(a, a->x, y, a->z, desktop_plugin);
477     a->y = y;
478
479     a = g_ptr_array_index(actor->child, 2);
480     y = a->y + speed2;
481     if (y > 480) y = -480;
482     set_actor_position(a, a->x, y, a->z, desktop_plugin);
483     a->y = y;
484
485     a = g_ptr_array_index(actor->child, 3);
486     y = a->y + speed2;
487     if (y > 480) y = -480;
488     set_actor_position(a, a->x, y, a->z, desktop_plugin);
489     a->y = y;
490 }
491
492 void 
493 change_static_actor(Actor * actor, AWallpaperPlugin *desktop_plugin)
494 {
495     gchar *newfile;
496     newfile = g_strdup_printf("%s%d.png", actor->name, desktop_plugin->priv->scene->daytime); 
497     if (actor->filename)
498             g_free(actor->filename);
499     actor->filename = newfile;
500     change_hildon_actor(actor, desktop_plugin);
501 }
502
503 void 
504 change_static_actor_with_corner(Actor * actor, AWallpaperPlugin *desktop_plugin)
505 {
506     gchar buffer[2048];
507
508     if (desktop_plugin->priv->right_corner)
509         gtk_widget_destroy(desktop_plugin->priv->right_corner);
510     snprintf(buffer, sizeof(buffer) - 1, "%s/%s/town%i_right_corner.png", \
511                                   THEME_PATH, desktop_plugin->priv->theme, desktop_plugin->priv->scene->daytime);
512     desktop_plugin->priv->right_corner = gtk_image_new_from_file (buffer);
513     if (desktop_plugin->priv->right_corner){
514         gtk_fixed_put(GTK_FIXED(desktop_plugin->priv->main_widget), desktop_plugin->priv->right_corner, 0, 0);
515         gtk_widget_show (desktop_plugin->priv->right_corner);
516     }
517     change_static_actor(actor, desktop_plugin);
518
519 }