started to do info in billboard
[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 int
118 func_callback(void *user_data, int argc, char **argv, char **azColName)
119 {
120     fprintf(stderr, "callback\n");
121     int i;
122     GtkTreeIter iter;
123     GtkListStore *list = GTK_LIST_STORE(user_data);
124     gtk_list_store_append(list, &iter);
125     for(i = 0; i < argc; i++){
126         fprintf(stderr, "argc=%d, argv=%s, colname=%s\n", argc, argv, azColName[i]);
127         //if(!strcmp(azColName[i], "count"))
128             gtk_list_store_set(list, &iter, 0, atoi(argv[i]), -1);
129     }
130     return 0;
131 }
132 void 
133 change_billboard(Actor * actor, AWallpaperPlugin *desktop_plugin)
134 {
135     GtkWidget *label;
136     sqlite3 *db = NULL;
137     sqlite3_stmt *res = NULL;
138     gchar *errMsg = NULL;
139     gchar sql[1024], str[2048];
140     gint call_count=0, sms_count=0, rc=0;
141     GtkListStore *list = NULL;
142     
143     rc = sqlite3_open("/home/user/.rtcom-eventlogger/el.db", &db);
144     if (rc){
145         fprintf(stderr, "error open db %d %s\n", rc, sqlite3_errmsg(db));
146     }else {
147         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d", 3);
148 #if 0
149         gtk_list_store_new(1, G_TYPE_INT);
150         rc = sqlite3_exec(db, sql, func_callback, (void*)list, &errMsg);
151         if (rc != SQLITE_OK){
152             fprintf(stderr, "error %s\n", errMsg);
153
154         }
155         fprintf(stderr, "after exec sql=%s rc= %d err=%d \n", sql, rc, errMsg);
156 #endif
157 //#if 0
158         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
159         if (rc != SQLITE_OK){
160             fprintf(stderr, "error prepare %d %s\n", rc, sql);
161         }
162         if (sqlite3_step(res) != SQLITE_ROW){
163             fprintf(stderr, "not sqlite_row\n");
164         }
165         call_count = sqlite3_column_int(res, 0);
166         fprintf(stderr, "count missing calls = %d\n", call_count);
167         sqlite3_finalize(res);
168
169         snprintf(sql, sizeof(sql)-1, "select count(id) from Events where event_type_id=%d and is_read=%d", 7, 0);
170         rc = sqlite3_prepare(db, sql, sizeof(sql)-1, &res, NULL);
171         if (rc != SQLITE_OK){
172             fprintf(stderr, "error prepare %d %s\n", rc, sql);
173         }
174         if (sqlite3_step(res) != SQLITE_ROW){
175             fprintf(stderr, "not sqlite_row\n");
176         }
177         sms_count = sqlite3_column_int(res, 0);
178         fprintf(stderr, "count sms = %d\n", sms_count);
179         sqlite3_finalize(res);
180
181 //#endif
182         sqlite3_close(db);
183     }
184     label = actor->image;
185     snprintf(str, sizeof(str)-1, "Missed calls: %d\nUnread sms: %d", call_count, sms_count);
186     gtk_label_set_text(label, str);
187     actor->time_start_animation = time(NULL) + 20;    
188 }
189
190
191 void 
192 change_moon(Actor * actor, AWallpaperPlugin *desktop_plugin)
193 {
194     gint phase;
195     char *newfile;
196     gint x0 = 150,
197          x1 = 650, 
198          x, y;
199     struct timeval tvb;     
200     suseconds_t ms;
201     long sec;
202     double t;
203 #if 0
204     gint y0, y1, x2, y2;
205     double a, b, c;
206     a = (double)(y2 - (double)(x2*(y1-y0) + x1*y0 - x0*y1)/(x1-x0))/(x2*(x2-x0-x1)+x0*x1);
207     b = (double)(y1-y0)/(x1-x0) - (double)a*(x0+x1);
208     c = (double)(x1*y0 - x0*y1)/(x1-x0) + (double)a*x0*x1;
209     fprintf(stderr, "a=%f, b=%f, c=%f\n", a, b, c);
210 #endif
211     gettimeofday(&tvb, NULL);
212     
213     ms = tvb.tv_usec;
214     sec = tvb.tv_sec;
215
216     if (actor){
217         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
218             if (!actor->visible){
219                 actor->visible = TRUE;
220                 phase = get_moon_phase();
221                 newfile = g_strdup_printf( "%s%d.png", actor->name, phase);
222                 if (actor->filename)
223                     g_free(actor->filename);
224                 actor->filename = newfile;
225                 actor->time_start_animation = sec - fast_rnd(60 * 60);
226                 actor->duration_animation = 1 * 60 * 60;
227                 create_hildon_actor(actor, desktop_plugin);
228
229             }
230             t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
231             if (t <= 1)
232                 x = path_line(x0, x1, t);
233             else 
234                 x = path_line(x1, x0, t-1);
235             y = 0.001920*x*x - 1.536*x + 337.2;
236             //y = a*x*x + b*x + c;
237
238             set_actor_position(actor, x, y, actor->z, desktop_plugin);
239
240             if (t>=2){
241                 actor->time_start_animation = sec;
242             }
243
244          }else if (actor->visible){
245             actor->visible = FALSE;
246             fprintf(stderr, "destroy moon \n");
247             destroy_hildon_actor(actor);
248             actor->time_start_animation = 0;
249         } 
250     }
251     
252 }
253
254 void 
255 change_sun(Actor * actor, AWallpaperPlugin *desktop_plugin)
256 {
257     double alt, azm;
258     gint x, y;
259
260     //fprintf(stderr, "change sun\n");
261     if (actor){
262         if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
263             if (!actor->visible){
264                 actor->visible = TRUE;
265                 create_hildon_actor(actor, desktop_plugin);
266             }
267             get_sun_pos(&alt, &azm);
268             get_sun_screen_pos(alt, azm, &x, &y);
269             actor->x = x;
270             actor->y = y;
271             set_actor_position(actor, x, y, actor->z, desktop_plugin);
272             actor->time_start_animation = time(NULL) + 60;
273          }else if (actor->visible){
274             actor->visible = FALSE;
275             destroy_hildon_actor(actor);
276             actor->time_start_animation = 0;
277         } 
278     }
279     
280 }
281
282 void 
283 change_tram(Actor * actor, AWallpaperPlugin *desktop_plugin)
284 {
285     gint x0 = -300, y0 = 225, scale0 = 100,
286          x1 = 800, y1 = 162, scale1 = 130, 
287          x, y, scale;
288     struct timeval tvb;     
289     suseconds_t ms;
290     long sec;
291     double t;
292
293     //fprintf(stderr, "change tram\n");
294     gettimeofday(&tvb, NULL);
295     
296     ms = tvb.tv_usec;
297     sec = tvb.tv_sec;
298     
299     if (!actor->visible){
300         actor->visible = TRUE;
301         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
302             if (actor->filename)
303                 g_free(actor->filename);
304             actor->filename = g_strdup("tram_dark.png");
305         } else{
306             if (actor->filename)
307                 g_free(actor->filename);
308             actor->filename = g_strdup("tram.png");
309         }
310         create_hildon_actor(actor, desktop_plugin);
311     }
312     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
313     x = path_line(x0, x1, t);
314     y = path_line(y0, y1, t);
315     scale = path_line(scale0, scale1, t);
316     set_actor_position(actor, x, y, actor->z, desktop_plugin);
317     set_actor_scale(actor, (double)scale/100, (double)scale/100);
318     if (t >= 1){
319         /* stop animation */
320         actor->visible = FALSE;
321         destroy_hildon_actor(actor);
322         actor->time_start_animation = sec + fast_rnd(60);
323     }
324 }
325
326 void
327 change_plane1(Actor *actor, AWallpaperPlugin *desktop_plugin)
328 {
329     gint x0 = 620, y0 = 233,
330          x1 = 79, y1 = -146, 
331          x, y;
332     struct timeval tvb;     
333     suseconds_t ms;
334     long sec;
335     double t;
336
337     gettimeofday(&tvb, NULL);
338     
339     ms = tvb.tv_usec;
340     sec = tvb.tv_sec;
341 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
342    
343     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
344         if (actor->time_start_animation == 0){
345             actor->time_start_animation = sec + fast_rnd(180);
346             return;
347         }
348     }
349     if (!actor->visible){
350         actor->visible = TRUE;
351         create_hildon_actor(actor, desktop_plugin);
352     }
353     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
354     x = path_line(x0, x1, t);
355     y = path_line(y0, y1, t);
356     //scale = path_line(scale0, scale1, t);
357     set_actor_position(actor, x, y, actor->z, desktop_plugin);
358     if (t >= 1){
359         /* stop animation */
360         actor->visible = FALSE;
361         destroy_hildon_actor(actor);
362         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
363             actor->time_start_animation = 0;
364         else 
365             actor->time_start_animation = sec + fast_rnd(180);
366     }
367
368 }
369
370 void
371 change_plane2(Actor *actor, AWallpaperPlugin *desktop_plugin)
372 {
373     gint x0 = -actor->width, y0 = 45,
374          x1 = 800, y1 = 20, 
375          x, y;
376     struct timeval tvb;     
377     suseconds_t ms;
378     long sec;
379     double t;
380
381     gettimeofday(&tvb, NULL);
382     
383     ms = tvb.tv_usec;
384     sec = tvb.tv_sec;
385 //    fprintf(stderr, "1 %f - %d\n", sec+(double)ms/100000, now);
386     if (desktop_plugin->priv->scene->daytime != TIME_NIGHT){
387         if (actor->time_start_animation == 0){
388             actor->time_start_animation = sec + fast_rnd(180);
389             return;
390         }
391     }
392     if (!actor->visible){
393         actor->visible = TRUE;
394         create_hildon_actor(actor, desktop_plugin);
395     }
396
397     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
398     x = path_line(x0, x1, t);
399     y = path_line(y0, y1, t);
400     //scale = path_line(scale0, scale1, t);
401     set_actor_position(actor, x, y, actor->z, desktop_plugin);
402     if (t >= 1){
403         /* stop animation */
404         actor->visible = FALSE;
405         destroy_hildon_actor(actor);
406         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT) 
407             actor->time_start_animation = 0;
408         else 
409             actor->time_start_animation = sec + fast_rnd(180);
410     }
411
412 }
413
414 void
415 change_cloud(Actor *actor, AWallpaperPlugin *desktop_plugin)
416 {
417     gint x0, y0 = 300, scale0 = 100,
418          x1, y1 = -actor->height, scale1 = 150, 
419          x, y, scale;
420     struct timeval tvb;     
421     suseconds_t ms;
422     long sec;
423     double t;
424     gchar *newfile;
425
426     //fprintf(stderr, "change cloud\n");
427     gettimeofday(&tvb, NULL);
428     
429     ms = tvb.tv_usec;
430     sec = tvb.tv_sec;
431    
432     if (!actor->visible){
433         actor->visible = TRUE;
434         if (desktop_plugin->priv->scene->daytime == TIME_NIGHT){
435             newfile = g_strdup_printf("%s_dark.png", actor->name);
436         }else{
437             newfile = g_strdup_printf("%s.png", actor->name);
438         } 
439         if (actor->filename)
440             g_free(actor->filename);
441         actor->filename = newfile;
442          
443         create_hildon_actor(actor, desktop_plugin);
444     }
445     t = (double)((double)sec+(double)ms/1000000 - actor->time_start_animation) / actor->duration_animation;
446     
447     if (desktop_plugin->priv->scene->wind_orientation == 1){
448         x0 = -actor->width;
449         x1 = 800;
450     }
451     else {
452         x0 = 800;
453         x1 = -actor->width;
454     }
455
456     x = path_line(x0, x1, t);    
457     y = -desktop_plugin->priv->scene->wind_angle * (x - x0) + actor->y;
458     scale = path_line(scale0, scale1, (double)(y - y0)/(y1 - y0));
459
460     set_actor_position(actor, x, y, actor->z, desktop_plugin);
461     set_actor_scale(actor, (double)scale/100, (double)scale/100);
462     if ((y < y1 || y > y0) || t >= 1){
463         /* stop animation */
464         actor->visible = FALSE;
465         destroy_hildon_actor(actor);
466         actor->time_start_animation = sec + fast_rnd(300);
467         actor->y = fast_rnd(300);
468     }
469
470 }
471
472 void
473 change_wind(Actor *actor, AWallpaperPlugin *desktop_plugin)
474 {
475     desktop_plugin->priv->scene->wind_orientation = fast_rnd(2);
476     if (desktop_plugin->priv->scene->wind_orientation == 0) desktop_plugin->priv->scene->wind_orientation = -1;
477     desktop_plugin->priv->scene->wind_angle = (double)(fast_rnd(200) - 100) / 100;
478     actor->time_start_animation = time(NULL) + (fast_rnd(10) + 10) * 60;
479     //fprintf(stderr, "change wind orient = %d angle = %f after = %d\n", scene.wind_orientation, scene.wind_angle, actor->time_start_animation-time(NULL));
480 }
481
482 void 
483 change_window1(Actor * actor, AWallpaperPlugin *desktop_plugin)
484 {
485     gint now = time(NULL);
486     if (desktop_plugin->priv->scene->daytime == TIME_DAY){
487         if (actor->widget){
488             actor->visible = FALSE;
489             destroy_hildon_actor(actor);
490         }
491         actor->time_start_animation = 0;
492         return;
493     }else {
494         if (!actor->widget)
495             create_hildon_actor(actor, desktop_plugin);
496         if (actor->time_start_animation == 0){
497             actor->time_start_animation = now + fast_rnd(30);
498             return;
499         }
500     }
501
502     if (!actor->visible)
503         actor->visible = TRUE;
504     else 
505         actor->visible = FALSE;
506     set_actor_visible(actor, actor->visible);
507     actor->time_start_animation = now + fast_rnd(60) + 10;
508
509 }
510
511 void 
512 change_signal(Actor * actor, AWallpaperPlugin *desktop_plugin)
513 {
514     gint now = time(NULL);
515     Actor *a;
516     a = g_ptr_array_index(actor->child, 0);
517     if (a->visible)
518         a->visible = FALSE;
519     else 
520         a->visible = TRUE;
521     set_actor_visible(a, a->visible);
522     
523     a = g_ptr_array_index(actor->child, 1);
524     if (a->visible)
525         a->visible = FALSE;
526     else 
527         a->visible = TRUE;
528     set_actor_visible(a, a->visible);
529
530     actor->time_start_animation = now + fast_rnd(30) + 10;
531 }
532
533 void
534 change_layer(Actor * actor, AWallpaperPlugin *desktop_plugin)
535 {
536     gint y, speed1 = 8, speed2 = 16;
537     Actor *a;
538
539     if (!desktop_plugin->priv->rich_animation) return;
540
541     a = g_ptr_array_index(actor->child, 0);
542     y = a->y + speed1;
543     if (y > 480) y = -480;
544     set_actor_position(a, a->x, y, a->z, desktop_plugin);
545     a->y = y;
546     
547     a = g_ptr_array_index(actor->child, 1);
548     y = a->y + speed1;
549     if (y > 480) y = -480;
550     set_actor_position(a, a->x, y, a->z, desktop_plugin);
551     a->y = y;
552
553     a = g_ptr_array_index(actor->child, 2);
554     y = a->y + speed2;
555     if (y > 480) y = -480;
556     set_actor_position(a, a->x, y, a->z, desktop_plugin);
557     a->y = y;
558
559     a = g_ptr_array_index(actor->child, 3);
560     y = a->y + speed2;
561     if (y > 480) y = -480;
562     set_actor_position(a, a->x, y, a->z, desktop_plugin);
563     a->y = y;
564 }
565
566 void 
567 change_static_actor(Actor * actor, AWallpaperPlugin *desktop_plugin)
568 {
569     gchar *newfile;
570     newfile = g_strdup_printf("%s%d.png", actor->name, desktop_plugin->priv->scene->daytime); 
571     if (actor->filename)
572             g_free(actor->filename);
573     actor->filename = newfile;
574     change_hildon_actor(actor, desktop_plugin);
575 }
576
577 void 
578 change_static_actor_with_corner(Actor * actor, AWallpaperPlugin *desktop_plugin)
579 {
580     gchar buffer[2048];
581
582     if (desktop_plugin->priv->right_corner)
583         gtk_widget_destroy(desktop_plugin->priv->right_corner);
584     snprintf(buffer, sizeof(buffer) - 1, "%s/%s/town%i_right_corner.png", \
585                                   THEME_PATH, desktop_plugin->priv->theme, desktop_plugin->priv->scene->daytime);
586     desktop_plugin->priv->right_corner = gtk_image_new_from_file (buffer);
587     if (desktop_plugin->priv->right_corner){
588         gtk_fixed_put(GTK_FIXED(desktop_plugin->priv->main_widget), desktop_plugin->priv->right_corner, 0, 0);
589         gtk_widget_show (desktop_plugin->priv->right_corner);
590     }
591     change_static_actor(actor, desktop_plugin);
592
593 }