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