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