Stop scrolling when whole message was displayed
[conv-inbox] / src / el-home-applet.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 /*
3  *  Copyright (C) 2009 Artem Garmash. All rights reserved.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * Contact: Artem Garmash <artemgarmash@gmail.com>
20  *
21  */
22
23 #include "config.h"
24 #include "el-home-applet.h"
25
26 #include <hildon/hildon.h>
27 #include <rtcom-eventlogger/eventlogger.h>
28 #include <sqlite3.h>
29 #include <string.h>
30
31 #define EL_HOME_APPLET_GET_PRIVATE(obj) ( \
32         G_TYPE_INSTANCE_GET_PRIVATE (obj, \
33                 EL_TYPE_HOME_APPLET, ELHomeAppletPrivate))
34
35 #define BOX_WIDTH 352
36 #define BOX_HEIGHT 256
37
38 #define C_WIDTH (BOX_WIDTH - 2*HILDON_MARGIN_HALF)
39 #define C_HEIGHT (BOX_HEIGHT - 2*HILDON_MARGIN_HALF)
40 #define C_X HILDON_MARGIN_HALF
41 #define C_Y HILDON_MARGIN_HALF
42
43 #define HEADER_HEIGHT 48
44 #define MESSAGE_HEIGHT (C_HEIGHT - HEADER_HEIGHT)
45 #define MESSAGE_WIDTH (C_WIDTH - 2*HILDON_MARGIN_DEFAULT)
46
47 #define BOX_RADIOUS 10
48
49 #define DEBUG_LAYOUT
50
51 struct _ELHomeAppletPrivate
52 {
53         RTComEl *eventlogger;
54
55         GtkWidget *sender;
56         GtkWidget *icon;
57         GtkWidget *unread;
58         GtkWidget *received;
59         GtkWidget *empty;
60
61         gchar *message;
62         gint event_id;
63
64         gboolean active;
65
66         guint unread_count;
67
68         const gchar *current_font;
69
70         guint idle_id;
71
72         gboolean scroll_on_click;
73         gint scroll_offset;
74         guint scroll_anim_id;
75 };
76
77 HD_DEFINE_PLUGIN_MODULE (ELHomeApplet, el_home_applet, HD_TYPE_HOME_PLUGIN_ITEM);
78
79 const gchar* g_module_check_init(GModule *module);
80 const gchar*
81 g_module_check_init(GModule *module)
82 {
83         g_module_make_resident (module);
84         return NULL;
85 }
86
87 static void
88 el_home_applet_class_finalize (ELHomeAppletClass *klass)
89 {
90 }
91
92 static void
93 el_home_applet_realize (GtkWidget *widget)
94 {
95         GdkScreen *screen;
96
97         screen = gtk_widget_get_screen (widget);
98         gtk_widget_set_colormap (widget,
99                                  gdk_screen_get_rgba_colormap (screen));
100
101         gtk_widget_set_app_paintable (widget,
102                                       TRUE);
103
104         GTK_WIDGET_CLASS (el_home_applet_parent_class)->realize (widget);
105 }
106
107 /*
108  * Thanks http://cairographics.org/cookbook/roundedrectangles/
109  */
110 static void
111 rounded_rectangle (cairo_t *cr,
112                    double   x,
113                    double   y,
114                    double   w,
115                    double   h,
116                    double   r)
117 {
118         cairo_move_to (cr, x + r, y);
119         cairo_line_to (cr, x + w - r, y);
120         cairo_curve_to (cr, x + w, y,
121                         x + w, y,
122                         x + w, y + r);
123         cairo_line_to (cr, x + w, y + h - r);
124         cairo_curve_to (cr, x + w, y + h,
125                         x + w, y + h,
126                         x + w - r, y + h);
127         cairo_line_to (cr, x + r, y + h);
128         cairo_curve_to (cr, x, y + h,
129                         x, y + h,
130                         x, y + h - r);
131         cairo_line_to (cr, x, y + r);
132         cairo_curve_to (cr, x, y,
133                         x, y,
134                         x + r, y);
135 }
136
137 static gboolean
138 draw_text (cairo_t *cr,
139            const gchar *text,
140            double x,
141            double y,
142            int width,
143            int height,
144            int offset)
145 {
146         PangoLayout *layout;
147         PangoFontDescription *desc;
148         gboolean result;
149         PangoRectangle extent;
150
151         cairo_save (cr);
152         cairo_rectangle (cr,
153                          x, y, width, height);
154         cairo_clip (cr);
155
156         /* Create a PangoLayout, set the font and text */
157         layout = pango_cairo_create_layout (cr);
158         pango_layout_set_text (layout,
159                                text,
160                                -1);
161         desc = pango_font_description_from_string ("Sans 17");
162         pango_layout_set_font_description (layout, desc);
163         pango_font_description_free (desc);
164
165         pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
166         if (!offset)
167                 pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
168         pango_layout_set_width (layout, PANGO_SCALE*width);
169         pango_layout_set_height (layout, PANGO_SCALE*height);
170
171         /* draw shadow */
172         cairo_move_to (cr, x + 1, y + 1 - offset);
173         cairo_set_source_rgba (cr, 0.2, 0.2, 0.2, 0.8);
174         pango_cairo_show_layout (cr, layout);
175
176         /* draw fg */
177         cairo_move_to (cr, x, y - offset);
178         cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
179         pango_cairo_show_layout (cr, layout);
180
181         pango_layout_get_pixel_extents (layout, NULL, &extent);
182         if (offset)
183                 result = height < (extent.height - offset);
184         else
185                 result = pango_layout_is_ellipsized (layout);
186
187         g_object_unref (layout);
188         cairo_restore (cr);
189
190         return result;
191 }
192
193 static void
194 stop_scroll_anim (ELHomeAppletPrivate *priv)
195 {
196         priv->scroll_on_click = FALSE;
197         priv->scroll_offset = 0;
198         if (priv->scroll_anim_id > 0) {
199                 g_source_remove (priv->scroll_anim_id);
200                 priv->scroll_anim_id = 0;
201         }
202 }
203
204 static gboolean
205 expose_event (GtkWidget *self, GdkEventExpose *event)
206 {
207         ELHomeAppletPrivate *priv = EL_HOME_APPLET(self)->priv;
208
209         cairo_t *cr;
210         GdkColor color;
211         float red, green, blue;
212         int message_height;
213
214         message_height = C_HEIGHT - priv->received->allocation.height - HEADER_HEIGHT;
215
216         /* find theme active color */
217         gtk_style_lookup_color (self->style, "ActiveTextColor", &color);
218         red = color.red/(float)G_MAXUINT16;
219         green = color.green/(float)G_MAXUINT16;
220         blue = color.blue/(float)G_MAXUINT16;
221
222         cr = gdk_cairo_create (self->window);
223         gdk_cairo_region (cr, event->region);
224         cairo_clip (cr);
225
226         /* draw bound box */
227         cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
228
229         cairo_set_source_rgba (cr, 0.4f, 0.4f, 0.4f, 0.1f);
230         cairo_set_line_width (cr, 3.0f);
231
232         rounded_rectangle (cr,
233                            C_X,
234                            C_Y,
235                            BOX_WIDTH - 2*C_X,
236                            BOX_HEIGHT - 2*C_Y,
237                            BOX_RADIOUS);
238
239         cairo_close_path(cr);
240         cairo_stroke (cr);
241
242         /* draw header */
243         cairo_set_line_width (cr, 1.0f);
244
245         cairo_translate (cr, C_X, C_Y);
246         cairo_move_to (cr, 0, HEADER_HEIGHT);
247         cairo_line_to (cr, 0, BOX_RADIOUS);
248         cairo_curve_to (cr, 0, 0, 0, 0, BOX_RADIOUS, 0);
249         cairo_line_to (cr, C_WIDTH - BOX_RADIOUS, 0);
250         cairo_curve_to (cr, C_WIDTH, 0, C_WIDTH, 0, C_WIDTH, BOX_RADIOUS);
251         cairo_line_to (cr, C_WIDTH, HEADER_HEIGHT);
252         cairo_line_to (cr, 0, HEADER_HEIGHT);
253
254         cairo_close_path(cr);
255
256         cairo_set_source_rgba (cr, 0.2f, 0.2f, 0.2f, 0.8f);
257         cairo_fill_preserve (cr);
258         cairo_set_source_rgba (cr, red, green, blue, 1.0f);
259         cairo_stroke (cr);
260
261         /* draw body */
262         cairo_move_to (cr, 0, HEADER_HEIGHT);
263         cairo_line_to (cr, 0, C_HEIGHT - BOX_RADIOUS);
264         cairo_curve_to (cr, 0, C_HEIGHT, 0, C_HEIGHT, BOX_RADIOUS, C_HEIGHT);
265         cairo_line_to (cr, C_WIDTH - BOX_RADIOUS, C_HEIGHT);
266         cairo_curve_to (cr, C_WIDTH, C_HEIGHT, C_WIDTH, C_HEIGHT, C_WIDTH, C_HEIGHT - BOX_RADIOUS);
267         cairo_line_to (cr, C_WIDTH, HEADER_HEIGHT);
268         cairo_line_to (cr, 0, HEADER_HEIGHT);
269         cairo_close_path(cr);
270
271         /* draw body filling depending on (in)active state */
272         cairo_pattern_t *grad;
273         grad = cairo_pattern_create_linear(0, HEADER_HEIGHT,
274                                            0, C_HEIGHT);
275
276         if (priv->active){
277                 cairo_pattern_add_color_stop_rgba (grad, 0.5f,
278                                                    red, green, blue, 0.8f);
279                 cairo_pattern_add_color_stop_rgba (grad, 1.0f,
280                                                    red/2, green/2, blue/2, 0.8f);
281         }
282         else {
283                 cairo_pattern_add_color_stop_rgba (grad, 0.5f,
284                                                    0.4f, 0.4f, 0.4f, 0.8f);
285                 cairo_pattern_add_color_stop_rgba (grad, 1.0f,
286                                                    0.2f, 0.2f, 0.2f, 0.8f);
287         }
288         cairo_set_source (cr, grad);
289         cairo_fill (cr);
290
291         /* cairo_set_source_rgba (cr, red, green, blue, 1.0f); */
292         /* cairo_translate (cr, -C_X, -C_Y); */
293         /* rounded_rectangle (cr, */
294         /*                    C_X, */
295         /*                    C_Y, */
296         /*                    BOX_WIDTH - 2*C_X, */
297         /*                    BOX_HEIGHT - 2*C_Y, */
298         /*                    BOX_RADIOUS); */
299         /* cairo_close_path(cr); */
300         /* cairo_stroke (cr); */
301
302         /* draw message */
303         gboolean ellipsized;
304         ellipsized = draw_text (cr, priv->message,
305                                 2*C_X, HEADER_HEIGHT,
306                                 MESSAGE_WIDTH,
307                                 message_height,
308                                 priv->scroll_offset);
309         if (!priv->scroll_offset && !priv->active)
310                 priv->scroll_on_click = ellipsized;
311
312         cairo_pattern_destroy (grad);
313         cairo_destroy (cr);
314
315         if (!priv->scroll_on_click && !ellipsized && priv->scroll_offset)
316                 stop_scroll_anim (priv);
317
318         return GTK_WIDGET_CLASS (el_home_applet_parent_class)->expose_event (self, event);
319 }
320
321 static void
322 dispose (GObject *self)
323 {
324         ELHomeAppletPrivate *priv = EL_HOME_APPLET(self)->priv;
325
326         stop_scroll_anim (priv);
327         if (priv->idle_id){
328                 g_source_remove (priv->idle_id);
329                 priv->idle_id = 0;
330         }
331         if (priv->eventlogger){
332                 g_object_unref (priv->eventlogger);
333                 priv->eventlogger = NULL;
334         }
335
336         if (priv->message){
337                 g_free (priv->message);
338                 priv->message = NULL;
339         }
340
341         G_OBJECT_CLASS (el_home_applet_parent_class)->dispose (self);
342 }
343
344 static void
345 finalize (GObject *self)
346 {
347         G_OBJECT_CLASS (el_home_applet_parent_class)->finalize (self);
348 }
349
350 static gchar*
351 format_time (time_t t)
352 {
353         static const guint RESULT_SIZE = 32;
354
355         time_t now;
356         struct tm now_tm, t_tm;
357         const gchar *format = "%Y.%m.%d %T";
358         gchar *result = g_malloc0 (RESULT_SIZE);
359
360         now = time (NULL);
361         localtime_r (&now, &now_tm);
362         localtime_r (&t, &t_tm);
363
364         if ((now_tm.tm_year == t_tm.tm_year) &&
365             (now_tm.tm_mon  == t_tm.tm_mon) &&
366             (now_tm.tm_mday == t_tm.tm_mday))
367                 format = "%T";
368
369         strftime (result, RESULT_SIZE, format, &t_tm);
370
371         return result;
372 }
373
374 static void
375 show_event (ELHomeApplet *self, RTComElIter *it)
376 {
377         ELHomeAppletPrivate *priv = self->priv;
378
379         gchar *remote = NULL;
380         gchar *received = NULL;
381         const gchar *icon_name = NULL;
382
383         if (priv->message) {
384                 g_free (priv->message);
385                 priv->message = NULL;
386         }
387
388         if (it && rtcom_el_iter_first (it)){
389                 rtcom_el_iter_dup_string (it, "free-text", &priv->message);
390                 if (priv->message){
391                         const gchar *service;
392                         time_t received_t;
393
394                         rtcom_el_iter_get_int (it, "id", &priv->event_id);
395                         if (rtcom_el_iter_get_int (it, "start-time", (gint*)&received_t))
396                                 received = format_time (received_t);
397
398                         if(!rtcom_el_iter_dup_string (it, "remote-name", &remote))
399                                 rtcom_el_iter_dup_string (it, "remote-id", &remote);
400                         service = rtcom_el_iter_get_service (it);
401                         if (!g_strcmp0 (service, "RTCOM_EL_SERVICE_SMS"))
402                                 icon_name = "chat_unread_sms";
403                         else if (!g_strcmp0 (service, "RTCOM_EL_SERVICE_CHAT"))
404                                 icon_name = "chat_unread_chat";
405                 }
406         }
407         else{
408                 priv->event_id = -1;
409         }
410
411         if (priv->message)
412                 gtk_widget_hide (priv->empty);
413         else
414                 gtk_widget_show (priv->empty);
415
416         gtk_label_set_text (GTK_LABEL (priv->sender), remote);
417         gtk_label_set_text (GTK_LABEL (priv->received), received);
418
419         if (icon_name){
420                 const gchar *current_icon_name;
421                 gtk_image_get_icon_name (GTK_IMAGE (priv->icon),
422                                          &current_icon_name,
423                                          NULL);
424                 if (g_strcmp0 (current_icon_name, icon_name))
425                         gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon),
426                                                       icon_name,
427                                                       HILDON_ICON_SIZE_FINGER);
428                 gtk_widget_show (priv->icon);
429         }
430         else
431                 gtk_widget_hide (priv->icon);
432
433         g_free (remote);
434
435         gtk_widget_queue_draw (GTK_WIDGET (self));
436 }
437
438 static RTComElIter*
439 make_query (RTComEl *el, gint event_id)
440 {
441         RTComElQuery *query = NULL;
442         RTComElIter *it = NULL;
443
444         static const gchar *services[] = {"RTCOM_EL_SERVICE_SMS",
445                                           "RTCOM_EL_SERVICE_CHAT",
446                                           NULL};
447         static const gchar *event_types[] = {"RTCOM_EL_EVENTTYPE_SMS_INBOUND",
448                                              "RTCOM_EL_EVENTTYPE_CHAT_INBOUND",
449                                              NULL};
450
451         query = rtcom_el_query_new (el);
452         rtcom_el_query_set_limit (query, 1);
453         if (event_id >= 0){
454                 rtcom_el_query_prepare (query,
455                                         "is-read", FALSE, RTCOM_EL_OP_EQUAL,
456                                         "id", event_id, RTCOM_EL_OP_EQUAL,
457                                         "service", services, RTCOM_EL_OP_IN_STRV,
458                                         "event-type", event_types, RTCOM_EL_OP_IN_STRV,
459                                         NULL);
460         }
461         else{
462                 rtcom_el_query_prepare (query,
463                                         "is-read", FALSE, RTCOM_EL_OP_EQUAL,
464                                         "service", services, RTCOM_EL_OP_IN_STRV,
465                                         "event-type", event_types, RTCOM_EL_OP_IN_STRV,
466                                         NULL);
467         }
468         it = rtcom_el_get_events (el, query);
469         g_object_unref(query);
470
471         return it;
472 }
473
474 static void
475 update_unread_label (ELHomeApplet *self)
476 {
477         ELHomeAppletPrivate *priv = self->priv;
478         gchar *text;
479
480         if (priv->unread_count > 0){
481                 text = g_strdup_printf ("%d", priv->unread_count);
482                 gtk_label_set_text (GTK_LABEL (priv->unread), text);
483                 g_free (text);
484         }
485         else
486                 gtk_label_set_text (GTK_LABEL (priv->unread), NULL);
487 }
488
489 static gint
490 query_unread_events (RTComEl *el)
491 {
492         sqlite3 *db;
493         sqlite3_stmt *stmt;
494         int ret;
495         gint count = 0;
496
497         g_object_get (el, "db", &db, NULL);
498
499         if (sqlite3_prepare_v2 (db,
500                                 "SELECT SUM(total_events)-SUM(read_events) FROM GroupCache;",
501                                 -1,
502                                 &stmt,
503                                 NULL) != SQLITE_OK){
504                 g_error ("%s: can't compile SQL", G_STRFUNC);
505                 return -1;
506         }
507
508         while (SQLITE_BUSY == (ret = sqlite3_step (stmt)));
509
510         if (ret == SQLITE_ROW){
511                 count = sqlite3_column_int (stmt, 0);
512         }
513         else{
514                 g_error ("%s: error while executing SQL", G_STRFUNC);
515         }
516
517         sqlite3_finalize (stmt);
518
519         return count;
520 }
521
522 static void
523 read_event (ELHomeApplet *self)
524 {
525         ELHomeAppletPrivate *priv = self->priv;
526         RTComElIter *it = NULL;
527
528         it = make_query (priv->eventlogger, -1);
529         show_event (self, it);
530         if (it) g_object_unref (it);
531 }
532
533 static void
534 mark_as_read (ELHomeApplet *self)
535 {
536         ELHomeAppletPrivate *priv = self->priv;
537
538         if (priv->event_id >= 0){
539                 rtcom_el_set_read_event (priv->eventlogger,
540                                          priv->event_id,
541                                          TRUE,
542                                          NULL);
543                 read_event (self);
544                 priv->unread_count--;
545                 update_unread_label (self);
546         }
547 }
548
549 static gboolean
550 read_new_event (ELHomeApplet *self)
551 {
552         ELHomeAppletPrivate *priv = self->priv;
553
554         read_event (self);
555         priv->unread_count = query_unread_events (priv->eventlogger);
556         update_unread_label (self);
557
558         priv->idle_id = 0;
559
560         return FALSE;
561 }
562
563 static void
564 add_new_idle (ELHomeApplet *self)
565 {
566         ELHomeAppletPrivate *priv = self->priv;
567
568         if (priv->idle_id)
569                 g_source_remove (priv->idle_id);
570         priv->idle_id = g_idle_add ((GSourceFunc)read_new_event,
571                                     self);
572 }
573
574 static void
575 new_event_cb (RTComEl      *backend,
576               gint          event_id,
577               const gchar  *local_uid,
578               const gchar  *remote_uid,
579               const gchar  *remote_ebook_uid,
580               const gchar  *group_uid,
581               const gchar  *service,
582               ELHomeApplet *self)
583 {
584         add_new_idle (self);
585 }
586
587 static gboolean
588 scroll_anim_cb (ELHomeApplet *self)
589 {
590         ELHomeAppletPrivate *priv = self->priv;
591
592         priv->scroll_offset += 1;
593         gtk_widget_queue_draw (self);
594
595         return TRUE;
596 }
597
598 static gboolean
599 button_press_event_cb (GtkWidget      *widget,
600                        GdkEventButton *event,
601                        ELHomeApplet   *self)
602 {
603         ELHomeAppletPrivate *priv = self->priv;
604
605         if (priv->event_id > 0){
606                 priv->active = TRUE;
607                 gtk_widget_queue_draw (widget);
608         }
609         priv->active = TRUE;
610         if (priv->scroll_on_click) {
611                 stop_scroll_anim (priv);
612                 priv->scroll_anim_id = g_timeout_add (100,
613                                                       scroll_anim_cb,
614                                                       self);
615         }
616
617         gtk_widget_queue_draw (widget);
618         return TRUE;
619 }
620
621 static gboolean
622 button_release_event_cb (GtkWidget      *widget,
623                          GdkEventButton *event,
624                          ELHomeApplet   *self)
625 {
626         ELHomeAppletPrivate *priv = self->priv;
627
628         if (priv->active){
629                 priv->active = FALSE;
630                 /* stop_scroll_anim (priv); */
631 #ifndef DEBUG_LAYOUT
632                 mark_as_read (self);
633 #endif
634                 gtk_widget_queue_draw (widget);
635         }
636
637         return TRUE;
638 }
639
640 static gboolean
641 leave_notify_event_cb (GtkWidget        *widget,
642                        GdkEventCrossing *event,
643                        ELHomeApplet     *self)
644 {
645         ELHomeAppletPrivate *priv = self->priv;
646
647         if (priv->active){
648                 priv->active = FALSE;
649                 stop_scroll_anim (priv);
650                 gtk_widget_queue_draw (widget);
651         }
652
653         return FALSE;
654 }
655
656 static void
657 el_home_applet_init (ELHomeApplet *self)
658 {
659         ELHomeAppletPrivate *priv;
660         GtkWidget *event_box;
661         GtkWidget *hbox, *vbox, *align;
662
663         self->priv = EL_HOME_APPLET_GET_PRIVATE (self);
664         priv = self->priv;
665
666         gtk_widget_set_app_paintable (GTK_WIDGET (self), TRUE);
667
668         priv->unread = gtk_label_new ("12");
669         hildon_helper_set_logical_color (priv->unread,
670                                          GTK_RC_FG,
671                                          GTK_STATE_NORMAL,
672                                          "ActiveTextColor");
673         gtk_misc_set_alignment (GTK_MISC (priv->unread),
674                                 1.0f,
675                                 0.5f);
676         gtk_widget_set_size_request (priv->unread,
677                                      -1,
678                                      HEADER_HEIGHT);
679
680         priv->icon = gtk_image_new_from_icon_name ("chat_unread_sms",
681                                                    HILDON_ICON_SIZE_FINGER);
682         gtk_misc_set_alignment (GTK_MISC (priv->icon),
683                                 0.5f,
684                                 0.5f);
685
686         priv->sender = gtk_label_new ("asdf asdf asdf asdf asdf");
687         gtk_misc_set_alignment (GTK_MISC (priv->sender),
688                                 0.5f,
689                                 0.5f);
690         gtk_label_set_ellipsize (GTK_LABEL (priv->sender),
691                                  PANGO_ELLIPSIZE_END);
692         gtk_widget_set_name (priv->sender, "hildon-shadow-label");
693         hildon_helper_set_logical_font (priv->sender, "SystemFont");
694
695         priv->message = g_strdup ("One two three four five six seven eight nine ten"
696                                   "one two three four five six seven eight nine ten"
697                                   "one two three four five six seven eight nine ten"
698                                   "one two three four five six seven eight nine ten"
699                                   "one two three four five six seven eight nine ten"
700                                   "one two three four five six seven eight nine ten");
701
702         /* TODO: l10n */
703         priv->empty = gtk_label_new ("No new messages");
704         gtk_widget_set_name (priv->empty, "hildon-shadow-label");
705         GTK_WIDGET_SET_FLAGS (priv->empty, GTK_NO_SHOW_ALL);
706
707         priv->received = gtk_label_new ("aewf aewf aewf awef");
708         gtk_misc_set_alignment (GTK_MISC (priv->received),
709                                 1.0f,
710                                 0.5f);
711         gtk_widget_set_size_request (priv->received,
712                                      MESSAGE_WIDTH,
713                                      -1);
714         hildon_helper_set_logical_font (priv->received, "SmallSystemFont");
715         gtk_widget_set_name (priv->received, "hildon-shadow-label");
716
717         hbox = gtk_hbox_new (FALSE, 0);
718         gtk_box_pack_start (GTK_BOX (hbox), priv->unread, FALSE, FALSE, 0);
719         gtk_box_pack_start (GTK_BOX (hbox), priv->icon, FALSE, FALSE, 0);
720         gtk_box_pack_start (GTK_BOX (hbox), priv->sender, TRUE, TRUE, 0);
721
722         vbox = gtk_vbox_new (FALSE, 0);
723         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
724         gtk_box_pack_start (GTK_BOX (vbox), priv->empty, TRUE, TRUE, 0);
725         gtk_box_pack_end (GTK_BOX (vbox), priv->received, FALSE, FALSE, 0);
726
727         align = gtk_alignment_new (0.5f, 0.0f, 1.0f, 1.0f);
728         gtk_alignment_set_padding (GTK_ALIGNMENT (align),
729                                    0, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
730
731         gtk_container_set_border_width (GTK_CONTAINER (vbox), HILDON_MARGIN_HALF);
732
733         event_box = gtk_event_box_new ();
734         gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
735         gtk_widget_set_size_request (event_box, BOX_WIDTH, BOX_HEIGHT);
736
737         gtk_container_add (GTK_CONTAINER (align), vbox);
738         gtk_container_add (GTK_CONTAINER (event_box), align);
739         gtk_container_add (GTK_CONTAINER (self), event_box);
740
741         g_signal_connect (event_box, "button-press-event",
742                 G_CALLBACK (button_press_event_cb), self);
743         g_signal_connect (event_box, "button-release-event",
744                 G_CALLBACK (button_release_event_cb), self);
745         g_signal_connect (event_box, "leave-notify-event",
746                 G_CALLBACK (leave_notify_event_cb), self);
747
748         gtk_widget_show_all (GTK_WIDGET (event_box));
749
750 #ifndef DEBUG_LAYOUT
751         priv->eventlogger = rtcom_el_new ();
752         g_signal_connect (priv->eventlogger,
753                           "new-event",
754                           G_CALLBACK (new_event_cb),
755                           self);
756         g_signal_connect (priv->eventlogger,
757                           "event-updated",
758                           G_CALLBACK (new_event_cb),
759                           self);
760
761         read_new_event (self);
762 #endif
763 }
764
765 static void
766 el_home_applet_class_init (ELHomeAppletClass *klass)
767 {
768         GObjectClass *object_class = G_OBJECT_CLASS (klass);
769         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
770
771         object_class->dispose = dispose;
772         object_class->finalize = finalize;
773         widget_class->expose_event = expose_event;
774         widget_class->realize = el_home_applet_realize;
775
776         g_type_class_add_private (klass, sizeof (ELHomeAppletPrivate));
777 }
778