started restructuring
[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 #include <sys/time.h>
27 #include "livewp-rules.h"
28
29 Actor* 
30 init_object(AWallpaperPlugin *desktop_plugin, 
31             gchar * name, 
32             gchar * filename, 
33             gint x, 
34             gint y, 
35             gint z, 
36             gint width, 
37             gint height, 
38             gboolean visible, 
39             gboolean load_image,
40             gint scale, 
41             gint opacity, 
42             void (*pfunc_change)(Actor*),
43             void (*pfunc_probability)(Actor*),
44             GPtrArray *child
45            )
46 {
47     Actor *actor = NULL;
48     actor = g_new0(Actor, 1);
49     actor->x = x;
50     actor->y = y;
51     actor->z = z;
52     actor->width = width;
53     actor->height = height;
54     actor->visible = visible;
55     actor->scale = scale;
56     actor->opacity = opacity;
57     actor->filename = g_strdup(filename);
58     actor->name = g_strdup(name);
59     actor->func_change = (gpointer)pfunc_change; 
60     actor->func_probability = (gpointer)pfunc_probability;
61     actor->child = child;
62     if (load_image)
63         create_hildon_actor(actor, desktop_plugin);
64     else 
65          actor->widget = NULL;
66     actor->time_start_animation = 0;
67     actor->duration_animation = 0;
68     return actor;
69 }
70
71 static gint 
72 path_line(gint x0, gint x1, double t)
73 {
74     // уравниение прямой
75     return ((x1 - x0) * t + x0);
76 }
77
78 void 
79 change_moon(Actor * actor, AWallpaperPlugin *desktop_plugin)
80 {
81     gint phase;
82     char *newfile;
83     gint x0 = 150,
84          x1 = 650, 
85          x, y;
86     struct timeval tvb;     
87     suseconds_t ms;
88     long sec;
89     double t;
90 #if 0
91     gint y0, y1, x2, y2;
92     double a, b, c;
93     a = (double)(y2 - (double)(x2*(y1-y0) + x1*y0 - x0*y1)/(x1-x0))/(x2*(x2-x0-x1)+x0*x1);
94     b = (double)(y1-y0)/(x1-x0) - (double)a*(x0+x1);
95     c = (double)(x1*y0 - x0*y1)/(x1-x0) + (double)a*x0*x1;
96     fprintf(stderr, "a=%f, b=%f, c=%f\n", a, b, c);
97 #endif
98     gettimeofday(&tvb, NULL);
99     
100     ms = tvb.tv_usec;
101     sec = tvb.tv_sec;
102
103     if (actor){
104         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
105             if (!actor->visible){
106                 actor->visible = TRUE;
107                 phase = get_moon_phase();
108                 newfile = g_strdup_printf( "%s%d.png", actor->name, phase);
109                 if (actor->filename)
110                     g_free(actor->filename);
111                 actor->filename = newfile;
112                 actor->time_start_animation = sec - fast_rnd(60 * 60);
113                 actor->duration_animation = 1 * 60 * 60;
114                 create_hildon_actor(actor, desktop_plugin);
115
116             }
117             t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
118             if (t <= 1)
119                 x = path_line(x0, x1, t);
120             else 
121                 x = path_line(x1, x0, t-1);
122             y = 0.001920*x*x - 1.536*x + 337.2;
123             //y = a*x*x + b*x + c;
124
125             actor_set_position_full(actor->widget, x, y, actor->z);
126
127             if (t>=2){
128                 actor->time_start_animation = sec;
129             }
130
131          }else if (actor->visible){
132             actor->visible = FALSE;
133             fprintf(stderr, "destroy moon \n");
134             destroy_hildon_actor(actor);
135             actor->time_start_animation = 0;
136         } 
137     }
138     
139 }
140
141 void 
142 change_sun(Actor * actor, AWallpaperPlugin *desktop_plugin)
143 {
144     double alt, azm;
145     gint x, y;
146
147     //fprintf(stderr, "change sun\n");
148     if (actor){
149         if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
150             if (!actor->visible){
151                 actor->visible = TRUE;
152                 create_hildon_actor(actor, desktop_plugin);
153             }
154             get_sun_pos(&alt, &azm);
155             get_sun_screen_pos(alt, azm, &x, &y);
156             actor->x = x;
157             actor->y = y;
158             actor_set_position_full(actor->widget, x, y, actor->z);
159             actor->time_start_animation = time(NULL) + 60;
160          }else if (actor->visible){
161             actor->visible = FALSE;
162             destroy_hildon_actor(actor);
163             actor->time_start_animation = 0;
164         } 
165     }
166     
167 }
168
169 void 
170 change_tram(Actor * actor, AWallpaperPlugin *desktop_plugin)
171 {
172     gint x0 = -300, y0 = 225, scale0 = 100,
173          x1 = 800, y1 = 162, scale1 = 130, 
174          x, y, scale;
175     struct timeval tvb;     
176     suseconds_t ms;
177     long sec;
178     double t;
179
180     //fprintf(stderr, "change tram\n");
181     gettimeofday(&tvb, NULL);
182     
183     ms = tvb.tv_usec;
184     sec = tvb.tv_sec;
185     
186     if (!actor->visible){
187         actor->visible = TRUE;
188         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
189             if (actor->filename)
190                 g_free(actor->filename);
191             actor->filename = g_strdup("tram_dark.png");
192         } else{
193             if (actor->filename)
194                 g_free(actor->filename);
195             actor->filename = g_strdup("tram.png");
196         }
197         create_hildon_actor(actor, desktop_plugin);
198     }
199     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
200     x = path_line(x0, x1, t);
201     y = path_line(y0, y1, t);
202     scale = path_line(scale0, scale1, t);
203     actor_set_position_full(actor->widget, x, y, actor->z);
204     set_actor_scale(actor, (double)scale/100, (double)scale/100);
205     if (t >= 1){
206         /* stop animation */
207         actor->visible = FALSE;
208         destroy_hildon_actor(actor);
209         actor->time_start_animation = sec + fast_rnd(60);
210     }
211 }
212
213 void
214 change_plane1(Actor *actor, AWallpaperPlugin *desktop_plugin)
215 {
216     gint x0 = 620, y0 = 233,
217          x1 = 79, y1 = -146, 
218          x, y;
219     struct timeval tvb;     
220     suseconds_t ms;
221     long sec;
222     double t;
223
224     gettimeofday(&tvb, NULL);
225     
226     ms = tvb.tv_usec;
227     sec = tvb.tv_sec;
228 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
229    
230     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
231         if (actor->time_start_animation == 0){
232             actor->time_start_animation = sec + fast_rnd(180);
233             return;
234         }
235     }
236     if (!actor->visible){
237         actor->visible = TRUE;
238         create_hildon_actor(actor, desktop_plugin);
239     }
240     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
241     x = path_line(x0, x1, t);
242     y = path_line(y0, y1, t);
243     //scale = path_line(scale0, scale1, t);
244     actor_set_position_full(actor->widget, x, y, actor->z);
245     if (t >= 1){
246         /* stop animation */
247         actor->visible = FALSE;
248         destroy_hildon_actor(actor);
249         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
250             actor->time_start_animation = 0;
251         else 
252             actor->time_start_animation = sec + fast_rnd(180);
253     }
254
255 }
256
257 void
258 change_plane2(Actor *actor, AWallpaperPlugin *desktop_plugin)
259 {
260     gint x0 = -actor->width, y0 = 45,
261          x1 = 800, y1 = 20, 
262          x, y;
263     struct timeval tvb;     
264     suseconds_t ms;
265     long sec;
266     double t;
267
268     gettimeofday(&tvb, NULL);
269     
270     ms = tvb.tv_usec;
271     sec = tvb.tv_sec;
272 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
273     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
274         if (actor->time_start_animation == 0){
275             actor->time_start_animation = sec + fast_rnd(180);
276             return;
277         }
278     }
279     if (!actor->visible){
280         actor->visible = TRUE;
281         create_hildon_actor(actor, desktop_plugin);
282     }
283
284     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
285     x = path_line(x0, x1, t);
286     y = path_line(y0, y1, t);
287     //scale = path_line(scale0, scale1, t);
288     actor_set_position_full(actor->widget, x, y, actor->z);
289     if (t >= 1){
290         /* stop animation */
291         actor->visible = FALSE;
292         destroy_hildon_actor(actor);
293         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
294             actor->time_start_animation = 0;
295         else 
296             actor->time_start_animation = sec + fast_rnd(180);
297     }
298
299 }
300
301 void
302 change_cloud(Actor *actor, AWallpaperPlugin *desktop_plugin)
303 {
304     gint x0, y0 = 300, scale0 = 100,
305          x1, y1 = -actor->height, scale1 = 150, 
306          x, y, scale;
307     struct timeval tvb;     
308     suseconds_t ms;
309     long sec;
310     double t;
311     gchar *newfile;
312
313     //fprintf(stderr, "change cloud\n");
314     gettimeofday(&tvb, NULL);
315     
316     ms = tvb.tv_usec;
317     sec = tvb.tv_sec;
318    
319     if (!actor->visible){
320         actor->visible = TRUE;
321         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
322             newfile = g_strdup_printf("%s_dark.png", actor->name);
323         }else{
324             newfile = g_strdup_printf("%s.png", actor->name);
325         } 
326         if (actor->filename)
327             g_free(actor->filename);
328         actor->filename = newfile;
329          
330         create_hildon_actor(actor, desktop_plugin);
331     }
332     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
333     
334     if (desktop_plugin->priv->scene->wind_orientation == 1){
335         x0 = -actor->width;
336         x1 = 800;
337     }
338     else {
339         x0 = 800;
340         x1 = -actor->width;
341     }
342
343     x = path_line(x0, x1, t);    
344     y = -desktop_plugin->priv->scene->wind_angle * (x - x0) + actor->y;
345     scale = path_line(scale0, scale1, (double)(y - y0)/(y1 - y0));
346
347     actor_set_position_full(actor->widget, x, y, actor->z);
348     set_actor_scale(actor, (double)scale/100, (double)scale/100);
349     if ((y < y1 || y > y0) || t >= 1){
350         /* stop animation */
351         actor->visible = FALSE;
352         destroy_hildon_actor(actor);
353         actor->time_start_animation = sec + fast_rnd(300);
354         actor->y = fast_rnd(300);
355     }
356
357 }
358
359 void
360 change_wind(Actor *actor, AWallpaperPlugin *desktop_plugin)
361 {
362     desktop_plugin->priv->scene->wind_orientation = fast_rnd(2);
363     if (desktop_plugin->priv->scene->wind_orientation == 0) desktop_plugin->priv->scene->wind_orientation = -1;
364     desktop_plugin->priv->scene->wind_angle = (double)(fast_rnd(200) - 100) / 100;
365     actor->time_start_animation = time(NULL) + (fast_rnd(10) + 10) * 60;
366     //fprintf(stderr, "change wind orient = %d angle = %f after = %d\n", scene.wind_orientation, scene.wind_angle, actor->time_start_animation-time(NULL));
367 }
368
369 void 
370 change_window1(Actor * actor, AWallpaperPlugin *desktop_plugin)
371 {
372     gint now = time(NULL);
373     if (desktop_plugin->priv->scene->daytime == TIME_DAY){
374         if (actor->widget){
375             actor->visible = FALSE;
376             destroy_hildon_actor(actor);
377         }
378         actor->time_start_animation = 0;
379         return;
380     }else {
381         if (!actor->widget)
382             create_hildon_actor(actor, desktop_plugin);
383         if (actor->time_start_animation == 0){
384             actor->time_start_animation = now + fast_rnd(30);
385             return;
386         }
387     }
388
389     if (!actor->visible)
390         actor->visible = TRUE;
391     else 
392         actor->visible = FALSE;
393     set_actor_visible(actor, actor->visible);
394     actor->time_start_animation = now + fast_rnd(60) + 10;
395
396 }
397
398 void 
399 change_signal(Actor * actor, AWallpaperPlugin *desktop_plugin)
400 {
401     gint now = time(NULL);
402     Actor *a;
403     a = g_ptr_array_index(actor->child, 0);
404     if (a->visible)
405         a->visible = FALSE;
406     else 
407         a->visible = TRUE;
408     set_actor_visible(a, a->visible);
409     
410     a = g_ptr_array_index(actor->child, 1);
411     if (a->visible)
412         a->visible = FALSE;
413     else 
414         a->visible = TRUE;
415     set_actor_visible(a, a->visible);
416
417     actor->time_start_animation = now + fast_rnd(30) + 10;
418 }
419
420 void
421 set_actor_scale(Actor *actor, double scalex, double scaley)
422 {
423     hildon_animation_actor_set_scale(
424             HILDON_ANIMATION_ACTOR(actor->widget), 
425             scalex, 
426             scaley
427     );
428
429 }
430
431 void 
432 set_actor_visible(Actor *actor, gboolean visible)
433 {
434     hildon_animation_actor_set_show(HILDON_ANIMATION_ACTOR(actor->widget), visible);
435 }