~ubuntu-branches/ubuntu/precise/evolution/precise

« back to all changes in this revision

Viewing changes to mail/e-mail-tab.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2011-09-08 09:38:57 UTC
  • mfrom: (1.1.84 upstream)
  • Revision ID: package-import@ubuntu.com-20110908093857-6lfl04ke2ns3kx2o
Tags: 3.1.91-0ubuntu1
* New upstream release. (LP: #843769)
* debian/control: bump e-d-s Build-Depends to 3.1.91. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
static void mx_draggable_iface_init (MxDraggableIface *iface);
31
31
 
32
 
G_DEFINE_TYPE_WITH_CODE (EMailTab,
33
 
                         e_mail_tab,
34
 
                         MX_TYPE_WIDGET,
35
 
                         G_IMPLEMENT_INTERFACE (MX_TYPE_DRAGGABLE,
36
 
                                                mx_draggable_iface_init))
37
 
 
38
 
enum
39
 
{
40
 
  PROP_0,
41
 
 
42
 
  PROP_ICON,
43
 
  PROP_TEXT,
44
 
  PROP_CAN_CLOSE,
45
 
  PROP_TAB_WIDTH,
46
 
  PROP_DOCKING,
47
 
  PROP_PREVIEW,
48
 
  PROP_PREVIEW_MODE,
49
 
  PROP_PREVIEW_DURATION,
50
 
  PROP_SPACING,
51
 
  PROP_PRIVATE,
52
 
  PROP_ACTIVE,
53
 
 
54
 
  PROP_DRAG_THRESHOLD,
55
 
  PROP_DRAG_AXIS,
56
 
 // PROP_DRAG_CONTAINMENT_TYPE,
57
 
  PROP_DRAG_CONTAINMENT_AREA,
58
 
  PROP_DRAG_ENABLED,
59
 
  PROP_DRAG_ACTOR,
 
32
G_DEFINE_TYPE_WITH_CODE (
 
33
        EMailTab,
 
34
        e_mail_tab,
 
35
        MX_TYPE_WIDGET,
 
36
        G_IMPLEMENT_INTERFACE (
 
37
                MX_TYPE_DRAGGABLE, mx_draggable_iface_init))
 
38
 
 
39
enum {
 
40
        PROP_0,
 
41
        PROP_ICON,
 
42
        PROP_TEXT,
 
43
        PROP_CAN_CLOSE,
 
44
        PROP_TAB_WIDTH,
 
45
        PROP_DOCKING,
 
46
        PROP_PREVIEW,
 
47
        PROP_PREVIEW_MODE,
 
48
        PROP_PREVIEW_DURATION,
 
49
        PROP_SPACING,
 
50
        PROP_PRIVATE,
 
51
        PROP_ACTIVE,
 
52
        PROP_DRAG_THRESHOLD,
 
53
        PROP_DRAG_AXIS,
 
54
        PROP_DRAG_CONTAINMENT_AREA,
 
55
        PROP_DRAG_ENABLED,
 
56
        PROP_DRAG_ACTOR,
60
57
};
61
58
 
62
 
enum
63
 
{
64
 
  CLICKED,
65
 
  CLOSED,
66
 
  TRANSITION_COMPLETE,
67
 
 
68
 
  LAST_SIGNAL
 
59
enum {
 
60
        CLICKED,
 
61
        CLOSED,
 
62
        TRANSITION_COMPLETE,
 
63
        LAST_SIGNAL
69
64
};
70
65
 
71
66
/* Animation stage lengths */
76
71
 
77
72
static void e_mail_tab_close_clicked_cb (MxButton *button, EMailTab *self);
78
73
 
79
 
struct _EMailTabPrivate
80
 
{
81
 
  ClutterActor *icon;
82
 
  ClutterActor *default_icon;
83
 
  ClutterActor *label;
84
 
  ClutterActor *close_button;
85
 
  gboolean      can_close;
86
 
  gint          width;
87
 
  gboolean      docking;
88
 
  gfloat        spacing;
89
 
  gboolean      private;
90
 
  guint         alert_count;
91
 
  guint         alert_source;
92
 
  gboolean      has_text;
93
 
 
94
 
  guint         active : 1;
95
 
  guint         pressed : 1;
96
 
  guint         hover : 1;
97
 
 
98
 
  ClutterActor    *preview;
99
 
  gboolean         preview_mode;
100
 
  ClutterTimeline *preview_timeline;
101
 
  gdouble          preview_height_progress;
102
 
  guint            anim_length;
103
 
 
104
 
  ClutterActor    *old_bg;
105
 
 
106
 
  ClutterActor        *drag_actor;
107
 
  ClutterActorBox      drag_area;
108
 
  gboolean             drag_enabled;
109
 
  MxDragAxis           drag_axis;
110
 
 // MxDragContainment    containment;
111
 
  gint                 drag_threshold;
112
 
  gulong               drag_threshold_handler;
113
 
  gfloat               press_x;
114
 
  gfloat               press_y;
115
 
  gboolean             in_drag;
 
74
struct _EMailTabPrivate {
 
75
        ClutterActor *icon;
 
76
        ClutterActor *default_icon;
 
77
        ClutterActor *label;
 
78
        ClutterActor *close_button;
 
79
        gboolean can_close;
 
80
        gint width;
 
81
        gboolean docking;
 
82
        gfloat spacing;
 
83
        gboolean private;
 
84
        guint alert_count;
 
85
        guint alert_source;
 
86
        gboolean has_text;
 
87
 
 
88
        guint active    : 1;
 
89
        guint pressed : 1;
 
90
        guint hover      : 1;
 
91
 
 
92
        ClutterActor *preview;
 
93
        gboolean preview_mode;
 
94
        ClutterTimeline *preview_timeline;
 
95
        gdouble preview_height_progress;
 
96
        guint anim_length;
 
97
 
 
98
        ClutterActor *old_bg;
 
99
 
 
100
        ClutterActor *drag_actor;
 
101
        ClutterActorBox drag_area;
 
102
        gboolean drag_enabled;
 
103
        MxDragAxis drag_axis;
 
104
        gint drag_threshold;
 
105
        gulong drag_threshold_handler;
 
106
        gfloat press_x;
 
107
        gfloat press_y;
 
108
        gboolean in_drag;
116
109
};
117
110
 
118
111
static void
119
 
e_mail_tab_drag_begin (MxDraggable         *draggable,
120
 
                    gfloat               event_x,
121
 
                    gfloat               event_y,
122
 
                    gint                 event_button,
123
 
                    ClutterModifierType  modifiers)
 
112
e_mail_tab_drag_begin (MxDraggable *draggable,
 
113
                       gfloat event_x,
 
114
                       gfloat event_y,
 
115
                       gint event_button,
 
116
                       ClutterModifierType modifiers)
124
117
{
125
 
  gfloat x, y;
126
 
 
127
 
  EMailTabPrivate *priv = E_MAIL_TAB (draggable)->priv;
128
 
  ClutterActor *self = CLUTTER_ACTOR (draggable);
129
 
  ClutterActor *actor = mx_draggable_get_drag_actor (draggable);
130
 
  ClutterActor *stage = clutter_actor_get_stage (self);
131
 
 
132
 
  priv->in_drag = TRUE;
133
 
 
134
 
  clutter_actor_get_transformed_position (self, &x, &y);
135
 
  clutter_actor_set_position (actor, x, y);
136
 
 
137
 
  /* Start up animation */
138
 
  if (CLUTTER_IS_TEXTURE (actor))
139
 
    {
140
 
      /* TODO: Some neat deformation effect? */
141
 
    }
142
 
  else
143
 
    {
144
 
      /* Fade in */
145
 
      clutter_actor_set_opacity (actor, 0x00);
146
 
      clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
147
 
                             "opacity", 0xff,
148
 
                             NULL);
149
 
    }
150
 
  clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
 
118
        gfloat x, y;
 
119
 
 
120
        EMailTabPrivate *priv = E_MAIL_TAB (draggable)->priv;
 
121
        ClutterActor *self = CLUTTER_ACTOR (draggable);
 
122
        ClutterActor *actor = mx_draggable_get_drag_actor (draggable);
 
123
        ClutterActor *stage = clutter_actor_get_stage (self);
 
124
 
 
125
        priv->in_drag = TRUE;
 
126
 
 
127
        clutter_actor_get_transformed_position (self, &x, &y);
 
128
        clutter_actor_set_position (actor, x, y);
 
129
 
 
130
        /* Start up animation */
 
131
        if (CLUTTER_IS_TEXTURE (actor)) {
 
132
                /* TODO: Some neat deformation effect? */
 
133
        } else {
 
134
                /* Fade in */
 
135
                clutter_actor_set_opacity (actor, 0x00);
 
136
                clutter_actor_animate (
 
137
                        actor, CLUTTER_LINEAR, 150,
 
138
                        "opacity", 0xff,
 
139
                        NULL);
 
140
        }
 
141
 
 
142
        clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
151
143
}
152
144
 
153
145
static void
154
146
e_mail_tab_drag_motion (MxDraggable *draggable,
155
 
                     gfloat         delta_x,
156
 
                     gfloat         delta_y)
 
147
                        gfloat delta_x,
 
148
                        gfloat delta_y)
157
149
{
158
 
  ClutterActor *actor = mx_draggable_get_drag_actor (draggable);
159
 
  clutter_actor_move_by (actor, delta_x, delta_y);
 
150
        ClutterActor *actor = mx_draggable_get_drag_actor (draggable);
 
151
        clutter_actor_move_by (actor, delta_x, delta_y);
160
152
}
161
153
 
162
154
static void
163
155
e_mail_tab_drag_end_anim_cb (ClutterAnimation *animation,
164
 
                          EMailTab           *tab)
 
156
                             EMailTab *tab)
165
157
{
166
 
  ClutterActor *actor =
167
 
    CLUTTER_ACTOR (clutter_animation_get_object (animation));
168
 
  ClutterActor *parent = clutter_actor_get_parent (actor);
 
158
        ClutterActor *actor =
 
159
                CLUTTER_ACTOR (clutter_animation_get_object (animation));
 
160
        ClutterActor *parent = clutter_actor_get_parent (actor);
169
161
 
170
 
  if (parent)
171
 
    clutter_container_remove_actor (CLUTTER_CONTAINER (parent), actor);
 
162
        if (parent)
 
163
                clutter_container_remove_actor (
 
164
                        CLUTTER_CONTAINER (parent), actor);
172
165
}
173
166
 
174
167
static void
175
168
e_mail_tab_drag_end (MxDraggable *draggable,
176
 
                  gfloat       event_x,
177
 
                  gfloat       event_y)
 
169
                     gfloat event_x,
 
170
                     gfloat event_y)
178
171
{
179
 
  EMailTab *self = E_MAIL_TAB (draggable);
180
 
  EMailTabPrivate *priv = self->priv;
181
 
 
182
 
  priv->in_drag = FALSE;
183
 
 
184
 
  if (priv->drag_actor)
185
 
    {
186
 
      ClutterActor *parent = clutter_actor_get_parent (priv->drag_actor);
187
 
      if (parent)
188
 
        {
189
 
          /* Animate drop */
190
 
          if (CLUTTER_IS_TEXTURE (priv->drag_actor))
191
 
            {
192
 
              /* TODO: Some neat deformation effect? */
193
 
              clutter_container_remove_actor (CLUTTER_CONTAINER (parent),
194
 
                                              priv->drag_actor);
195
 
            }
196
 
          else
197
 
            {
198
 
              clutter_actor_animate (priv->drag_actor, CLUTTER_LINEAR, 150,
199
 
                                     "opacity", 0x00,
200
 
                                     "signal::completed",
201
 
                                       G_CALLBACK (e_mail_tab_drag_end_anim_cb),
202
 
                                       self,
203
 
                                     NULL);
204
 
            }
 
172
        EMailTab *self = E_MAIL_TAB (draggable);
 
173
        EMailTabPrivate *priv = self->priv;
 
174
 
 
175
        priv->in_drag = FALSE;
 
176
 
 
177
        if (priv->drag_actor) {
 
178
                ClutterActor *parent = clutter_actor_get_parent (priv->drag_actor);
 
179
                if (parent) {
 
180
                        /* Animate drop */
 
181
                        if (CLUTTER_IS_TEXTURE (priv->drag_actor)) {
 
182
                                /* TODO: Some neat deformation effect? */
 
183
                                clutter_container_remove_actor (
 
184
                                        CLUTTER_CONTAINER (parent),
 
185
                                        priv->drag_actor);
 
186
                        } else {
 
187
                                clutter_actor_animate (
 
188
                                        priv->drag_actor,
 
189
                                        CLUTTER_LINEAR, 150,
 
190
                                        "opacity", 0x00,
 
191
                                        "signal::completed",
 
192
                                        G_CALLBACK (e_mail_tab_drag_end_anim_cb),
 
193
                                        self, NULL);
 
194
                        }
 
195
                }
 
196
 
 
197
                g_object_unref (priv->drag_actor);
 
198
                priv->drag_actor = NULL;
205
199
        }
206
 
      g_object_unref (priv->drag_actor);
207
 
      priv->drag_actor = NULL;
208
 
    }
209
200
}
210
201
 
211
202
static void
212
203
mx_draggable_iface_init (MxDraggableIface *iface)
213
204
{
214
 
  iface->drag_begin = e_mail_tab_drag_begin;
215
 
  iface->drag_motion = e_mail_tab_drag_motion;
216
 
  iface->drag_end = e_mail_tab_drag_end;
217
 
}
218
 
 
219
 
static void
220
 
e_mail_tab_get_property (GObject *object, guint property_id,
221
 
                      GValue *value, GParamSpec *pspec)
222
 
{
223
 
  EMailTab *tab = E_MAIL_TAB (object);
224
 
  EMailTabPrivate *priv = tab->priv;
225
 
 
226
 
  switch (property_id)
227
 
    {
228
 
    case PROP_ICON:
229
 
      g_value_set_object (value, e_mail_tab_get_icon (tab));
230
 
      break;
231
 
 
232
 
    case PROP_TEXT:
233
 
      g_value_set_string (value, e_mail_tab_get_text (tab));
234
 
      break;
235
 
 
236
 
    case PROP_CAN_CLOSE:
237
 
      g_value_set_boolean (value, e_mail_tab_get_can_close (tab));
238
 
      break;
239
 
 
240
 
    case PROP_TAB_WIDTH:
241
 
      g_value_set_int (value, e_mail_tab_get_width (tab));
242
 
      break;
243
 
 
244
 
    case PROP_DOCKING:
245
 
      g_value_set_boolean (value, e_mail_tab_get_docking (tab));
246
 
      break;
247
 
 
248
 
    case PROP_PREVIEW:
249
 
      g_value_set_object (value, e_mail_tab_get_preview_actor (tab));
250
 
      break;
251
 
 
252
 
    case PROP_PREVIEW_MODE:
253
 
      g_value_set_boolean (value, e_mail_tab_get_preview_mode (tab));
254
 
      break;
255
 
 
256
 
    case PROP_PREVIEW_DURATION:
257
 
      g_value_set_uint (value, e_mail_tab_get_preview_duration (tab));
258
 
      break;
259
 
 
260
 
    case PROP_SPACING:
261
 
      g_value_set_float (value, e_mail_tab_get_spacing (tab));
262
 
      break;
263
 
 
264
 
    case PROP_PRIVATE:
265
 
      g_value_set_boolean (value, e_mail_tab_get_private (tab));
266
 
      break;
267
 
 
268
 
    case PROP_ACTIVE:
269
 
      g_value_set_boolean (value, e_mail_tab_get_active (tab));
270
 
      break;
271
 
 
272
 
    case PROP_DRAG_THRESHOLD:
273
 
      g_value_set_uint (value, (guint) priv->drag_threshold);
274
 
      break;
275
 
 
276
 
    case PROP_DRAG_AXIS:
277
 
      g_value_set_enum (value, priv->drag_axis);
278
 
      break;
279
 
 
280
 
//    case PROP_DRAG_CONTAINMENT_TYPE:
281
 
  //    g_value_set_enum (value, priv->containment);
282
 
    //  break;
283
 
 
284
 
    case PROP_DRAG_CONTAINMENT_AREA:
285
 
      g_value_set_boxed (value, &priv->drag_area);
286
 
      break;
287
 
 
288
 
    case PROP_DRAG_ENABLED:
289
 
      g_value_set_boolean (value, priv->drag_enabled);
290
 
      break;
291
 
 
292
 
    case PROP_DRAG_ACTOR:
293
 
      if (!priv->drag_actor)
294
 
        {
295
 
          ClutterActor *fbo =
296
 
            /*clutter_texture_new_from_actor (CLUTTER_ACTOR (tab));*/
297
 
            NULL;
298
 
          if (fbo)
299
 
            {
300
 
              /* This is where we'd setup deformations, or something along
301
 
               * those lines.
302
 
               */
303
 
              priv->drag_actor = g_object_ref_sink (fbo);
304
 
            }
305
 
          else
306
 
            priv->drag_actor =
307
 
              g_object_ref_sink (clutter_clone_new (CLUTTER_ACTOR (tab)));
 
205
        iface->drag_begin = e_mail_tab_drag_begin;
 
206
        iface->drag_motion = e_mail_tab_drag_motion;
 
207
        iface->drag_end = e_mail_tab_drag_end;
 
208
}
 
209
 
 
210
static void
 
211
e_mail_tab_get_property (GObject *object,
 
212
                         guint property_id,
 
213
                         GValue *value,
 
214
                         GParamSpec *pspec)
 
215
{
 
216
        EMailTab *tab = E_MAIL_TAB (object);
 
217
        EMailTabPrivate *priv = tab->priv;
 
218
 
 
219
        switch (property_id) {
 
220
                case PROP_ICON:
 
221
                        g_value_set_object (value, e_mail_tab_get_icon (tab));
 
222
                        break;
 
223
 
 
224
                case PROP_TEXT:
 
225
                        g_value_set_string (value, e_mail_tab_get_text (tab));
 
226
                        break;
 
227
 
 
228
                case PROP_CAN_CLOSE:
 
229
                        g_value_set_boolean (value, e_mail_tab_get_can_close (tab));
 
230
                        break;
 
231
 
 
232
                case PROP_TAB_WIDTH:
 
233
                        g_value_set_int (value, e_mail_tab_get_width (tab));
 
234
                        break;
 
235
 
 
236
                case PROP_DOCKING:
 
237
                        g_value_set_boolean (value, e_mail_tab_get_docking (tab));
 
238
                        break;
 
239
 
 
240
                case PROP_PREVIEW:
 
241
                        g_value_set_object (value, e_mail_tab_get_preview_actor (tab));
 
242
                        break;
 
243
 
 
244
                case PROP_PREVIEW_MODE:
 
245
                        g_value_set_boolean (value, e_mail_tab_get_preview_mode (tab));
 
246
                        break;
 
247
 
 
248
                case PROP_PREVIEW_DURATION:
 
249
                        g_value_set_uint (value, e_mail_tab_get_preview_duration (tab));
 
250
                        break;
 
251
 
 
252
                case PROP_SPACING:
 
253
                        g_value_set_float (value, e_mail_tab_get_spacing (tab));
 
254
                        break;
 
255
 
 
256
                case PROP_PRIVATE:
 
257
                        g_value_set_boolean (value, e_mail_tab_get_private (tab));
 
258
                        break;
 
259
 
 
260
                case PROP_ACTIVE:
 
261
                        g_value_set_boolean (value, e_mail_tab_get_active (tab));
 
262
                        break;
 
263
 
 
264
                case PROP_DRAG_THRESHOLD:
 
265
                        g_value_set_uint (value, (guint) priv->drag_threshold);
 
266
                        break;
 
267
 
 
268
                case PROP_DRAG_AXIS:
 
269
                        g_value_set_enum (value, priv->drag_axis);
 
270
                        break;
 
271
 
 
272
                case PROP_DRAG_CONTAINMENT_AREA:
 
273
                        g_value_set_boxed (value, &priv->drag_area);
 
274
                        break;
 
275
 
 
276
                case PROP_DRAG_ENABLED:
 
277
                        g_value_set_boolean (value, priv->drag_enabled);
 
278
                        break;
 
279
 
 
280
                case PROP_DRAG_ACTOR:
 
281
                        if (!priv->drag_actor)
 
282
                                priv->drag_actor = g_object_ref_sink (
 
283
                                        clutter_clone_new (CLUTTER_ACTOR (tab)));
 
284
                        g_value_set_object (value, priv->drag_actor);
 
285
                        break;
 
286
 
 
287
                default:
 
288
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
289
                }
 
290
}
 
291
 
 
292
static void
 
293
e_mail_tab_set_property (GObject *object,
 
294
                         guint property_id,
 
295
                         const GValue *value,
 
296
                         GParamSpec *pspec)
 
297
{
 
298
        EMailTab *tab = E_MAIL_TAB (object);
 
299
        EMailTabPrivate *priv = tab->priv;
 
300
 
 
301
        switch (property_id) {
 
302
                case PROP_ICON:
 
303
                        e_mail_tab_set_icon (
 
304
                                tab, g_value_get_object (value));
 
305
                        break;
 
306
 
 
307
                case PROP_TEXT:
 
308
                        e_mail_tab_set_text (
 
309
                                tab, g_value_get_string (value));
 
310
                        break;
 
311
 
 
312
                case PROP_CAN_CLOSE:
 
313
                        e_mail_tab_set_can_close (
 
314
                                tab, g_value_get_boolean (value));
 
315
 
 
316
                case PROP_TAB_WIDTH:
 
317
                        e_mail_tab_set_width (
 
318
                                tab, g_value_get_int (value));
 
319
                        break;
 
320
 
 
321
                case PROP_DOCKING:
 
322
                        e_mail_tab_set_docking (
 
323
                                tab, g_value_get_boolean (value));
 
324
                        break;
 
325
 
 
326
                case PROP_PREVIEW:
 
327
                        e_mail_tab_set_preview_actor (
 
328
                                tab, g_value_get_object (value));
 
329
                        break;
 
330
 
 
331
                case PROP_PREVIEW_MODE:
 
332
                        e_mail_tab_set_preview_mode (
 
333
                                tab, g_value_get_boolean (value));
 
334
                        break;
 
335
 
 
336
                case PROP_PREVIEW_DURATION:
 
337
                        e_mail_tab_set_preview_duration (
 
338
                                tab, g_value_get_uint (value));
 
339
                        break;
 
340
 
 
341
                case PROP_SPACING:
 
342
                        e_mail_tab_set_spacing (
 
343
                                tab, g_value_get_float (value));
 
344
                        break;
 
345
 
 
346
                case PROP_PRIVATE:
 
347
                        e_mail_tab_set_private (
 
348
                                tab, g_value_get_boolean (value));
 
349
                        break;
 
350
 
 
351
                case PROP_ACTIVE:
 
352
                        e_mail_tab_set_active (
 
353
                                tab, g_value_get_boolean (value));
 
354
                        break;
 
355
 
 
356
                case PROP_DRAG_THRESHOLD:
 
357
                        break;
 
358
 
 
359
                case PROP_DRAG_AXIS:
 
360
                        priv->drag_axis = g_value_get_enum (value);
 
361
                        break;
 
362
 
 
363
                case PROP_DRAG_CONTAINMENT_AREA:
 
364
                {
 
365
                        ClutterActorBox *box = g_value_get_boxed (value);
 
366
 
 
367
                        if (box)
 
368
                                priv->drag_area = *box;
 
369
                        else
 
370
                                memset (
 
371
                                        &priv->drag_area, 0,
 
372
                                        sizeof (ClutterActorBox));
 
373
                        break;
 
374
                }
 
375
 
 
376
                case PROP_DRAG_ENABLED:
 
377
                        priv->drag_enabled = g_value_get_boolean (value);
 
378
                        break;
 
379
 
 
380
                case PROP_DRAG_ACTOR:
 
381
                {
 
382
                        ClutterActor *new_actor = g_value_get_object (value);
 
383
 
 
384
                        if (priv->drag_actor) {
 
385
                                ClutterActor *parent;
 
386
 
 
387
                                parent = clutter_actor_get_parent (priv->drag_actor);
 
388
 
 
389
                                /* We know it's a container because we added it ourselves */
 
390
                                if (parent)
 
391
                                        clutter_container_remove_actor (
 
392
                                                CLUTTER_CONTAINER (parent),
 
393
                                                priv->drag_actor);
 
394
 
 
395
                                g_object_unref (priv->drag_actor);
 
396
                                priv->drag_actor = NULL;
 
397
                        }
 
398
 
 
399
                        if (new_actor)
 
400
                                priv->drag_actor = g_object_ref_sink (new_actor);
 
401
 
 
402
                        break;
 
403
                }
 
404
 
 
405
                default:
 
406
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
308
407
        }
309
 
      g_value_set_object (value, priv->drag_actor);
310
 
      break;
311
 
 
312
 
    default:
313
 
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
314
 
    }
315
 
}
316
 
 
317
 
static void
318
 
e_mail_tab_set_property (GObject *object, guint property_id,
319
 
                      const GValue *value, GParamSpec *pspec)
320
 
{
321
 
  EMailTab *tab = E_MAIL_TAB (object);
322
 
  EMailTabPrivate *priv = tab->priv;
323
 
 
324
 
  switch (property_id)
325
 
    {
326
 
    case PROP_ICON:
327
 
      e_mail_tab_set_icon (tab, g_value_get_object (value));
328
 
      break;
329
 
 
330
 
    case PROP_TEXT:
331
 
      e_mail_tab_set_text (tab, g_value_get_string (value));
332
 
      break;
333
 
 
334
 
    case PROP_CAN_CLOSE:
335
 
      e_mail_tab_set_can_close (tab, g_value_get_boolean (value));
336
 
 
337
 
    case PROP_TAB_WIDTH:
338
 
      e_mail_tab_set_width (tab, g_value_get_int (value));
339
 
      break;
340
 
 
341
 
    case PROP_DOCKING:
342
 
      e_mail_tab_set_docking (tab, g_value_get_boolean (value));
343
 
      break;
344
 
 
345
 
    case PROP_PREVIEW:
346
 
      e_mail_tab_set_preview_actor (tab,
347
 
                                 CLUTTER_ACTOR (g_value_get_object (value)));
348
 
      break;
349
 
 
350
 
    case PROP_PREVIEW_MODE:
351
 
      e_mail_tab_set_preview_mode (tab, g_value_get_boolean (value));
352
 
      break;
353
 
 
354
 
    case PROP_PREVIEW_DURATION:
355
 
      e_mail_tab_set_preview_duration (tab, g_value_get_uint (value));
356
 
      break;
357
 
 
358
 
    case PROP_SPACING:
359
 
      e_mail_tab_set_spacing (tab, g_value_get_float (value));
360
 
      break;
361
 
 
362
 
    case PROP_PRIVATE:
363
 
      e_mail_tab_set_private (tab, g_value_get_boolean (value));
364
 
      break;
365
 
 
366
 
    case PROP_ACTIVE:
367
 
      e_mail_tab_set_active (tab, g_value_get_boolean (value));
368
 
      break;
369
 
 
370
 
    case PROP_DRAG_THRESHOLD:
371
 
      break;
372
 
 
373
 
    case PROP_DRAG_AXIS:
374
 
      priv->drag_axis = g_value_get_enum (value);
375
 
      break;
376
 
 
377
 
//    case PROP_DRAG_CONTAINMENT_TYPE:
378
 
 //     priv->containment = g_value_get_enum (value);
379
 
   //   break;
380
 
 
381
 
    case PROP_DRAG_CONTAINMENT_AREA:
382
 
      {
383
 
        ClutterActorBox *box = g_value_get_boxed (value);
384
 
 
385
 
        if (box)
386
 
          priv->drag_area = *box;
387
 
        else
388
 
          memset (&priv->drag_area, 0, sizeof (ClutterActorBox));
389
 
 
390
 
        break;
391
 
      }
392
 
 
393
 
    case PROP_DRAG_ENABLED:
394
 
      priv->drag_enabled = g_value_get_boolean (value);
395
 
      break;
396
 
 
397
 
    case PROP_DRAG_ACTOR:
398
 
      {
399
 
        ClutterActor *new_actor = g_value_get_object (value);
400
 
 
401
 
        if (priv->drag_actor)
402
 
          {
403
 
            ClutterActor *parent = clutter_actor_get_parent (priv->drag_actor);
404
 
 
405
 
            /* We know it's a container because we added it ourselves */
406
 
            if (parent)
407
 
              clutter_container_remove_actor (CLUTTER_CONTAINER (parent),
408
 
                                              priv->drag_actor);
409
 
 
410
 
            g_object_unref (priv->drag_actor);
411
 
            priv->drag_actor = NULL;
412
 
          }
413
 
 
414
 
        if (new_actor)
415
 
          priv->drag_actor = g_object_ref_sink (new_actor);
416
 
 
417
 
        break;
418
 
      }
419
 
 
420
 
    default:
421
 
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
422
 
    }
423
408
}
424
409
 
425
410
static void
426
411
e_mail_tab_dispose_old_bg (EMailTab *tab)
427
412
{
428
 
  EMailTabPrivate *priv = tab->priv;
429
 
 
430
 
  if (priv->old_bg)
431
 
    {
432
 
      if (clutter_actor_get_parent (priv->old_bg) == (ClutterActor *) tab)
433
 
        clutter_actor_unparent (priv->old_bg);
434
 
      g_object_unref (priv->old_bg);
435
 
      priv->old_bg = NULL;
436
 
    }
 
413
        EMailTabPrivate *priv = tab->priv;
 
414
 
 
415
        if (priv->old_bg) {
 
416
                ClutterActor *parent;
 
417
 
 
418
                parent = clutter_actor_get_parent (priv->old_bg);
 
419
                if (parent == (ClutterActor *) tab)
 
420
                        clutter_actor_unparent (priv->old_bg);
 
421
                g_object_unref (priv->old_bg);
 
422
                priv->old_bg = NULL;
 
423
        }
437
424
}
438
425
 
439
426
static void
440
427
e_mail_tab_dispose (GObject *object)
441
428
{
442
 
  EMailTab *tab = E_MAIL_TAB (object);
443
 
  EMailTabPrivate *priv = tab->priv;
444
 
 
445
 
  e_mail_tab_dispose_old_bg (tab);
446
 
 
447
 
  if (priv->icon)
448
 
    {
449
 
      clutter_actor_unparent (priv->icon);
450
 
      priv->icon = NULL;
451
 
    }
452
 
 
453
 
  if (priv->default_icon)
454
 
    {
455
 
      g_object_unref (priv->default_icon);
456
 
      priv->default_icon = NULL;
457
 
    }
458
 
 
459
 
  if (priv->label)
460
 
    {
461
 
      clutter_actor_unparent (CLUTTER_ACTOR (priv->label));
462
 
      priv->label = NULL;
463
 
    }
464
 
 
465
 
  if (priv->close_button)
466
 
    {
467
 
      clutter_actor_unparent (CLUTTER_ACTOR (priv->close_button));
468
 
      priv->close_button = NULL;
469
 
    }
470
 
 
471
 
  if (priv->preview)
472
 
    {
473
 
      clutter_actor_unparent (priv->preview);
474
 
      priv->preview = NULL;
475
 
    }
476
 
 
477
 
  if (priv->alert_source)
478
 
    {
479
 
      g_source_remove (priv->alert_source);
480
 
      priv->alert_source = 0;
481
 
    }
482
 
 
483
 
  if (priv->drag_actor)
484
 
    {
485
 
      ClutterActor *parent = clutter_actor_get_parent (priv->drag_actor);
486
 
      if (parent)
487
 
        clutter_container_remove_actor (CLUTTER_CONTAINER (parent),
488
 
                                        priv->drag_actor);
489
 
      g_object_unref (priv->drag_actor);
490
 
      priv->drag_actor = NULL;
491
 
    }
492
 
 
493
 
  if (priv->drag_threshold_handler)
494
 
    {
495
 
      g_signal_handler_disconnect (gtk_settings_get_default (),
496
 
                                   priv->drag_threshold_handler);
497
 
      priv->drag_threshold_handler = 0;
498
 
    }
499
 
 
500
 
  G_OBJECT_CLASS (e_mail_tab_parent_class)->dispose (object);
501
 
}
502
 
 
503
 
static void
504
 
e_mail_tab_finalize (GObject *object)
505
 
{
506
 
  G_OBJECT_CLASS (e_mail_tab_parent_class)->finalize (object);
 
429
        EMailTab *tab = E_MAIL_TAB (object);
 
430
        EMailTabPrivate *priv = tab->priv;
 
431
 
 
432
        e_mail_tab_dispose_old_bg (tab);
 
433
 
 
434
        if (priv->icon) {
 
435
                clutter_actor_unparent (priv->icon);
 
436
                priv->icon = NULL;
 
437
        }
 
438
 
 
439
        if (priv->default_icon) {
 
440
                g_object_unref (priv->default_icon);
 
441
                priv->default_icon = NULL;
 
442
        }
 
443
 
 
444
        if (priv->label) {
 
445
                clutter_actor_unparent (CLUTTER_ACTOR (priv->label));
 
446
                priv->label = NULL;
 
447
        }
 
448
 
 
449
        if (priv->close_button) {
 
450
                clutter_actor_unparent (CLUTTER_ACTOR (priv->close_button));
 
451
                priv->close_button = NULL;
 
452
        }
 
453
 
 
454
        if (priv->preview) {
 
455
                clutter_actor_unparent (priv->preview);
 
456
                priv->preview = NULL;
 
457
        }
 
458
 
 
459
        if (priv->alert_source) {
 
460
                g_source_remove (priv->alert_source);
 
461
                priv->alert_source = 0;
 
462
        }
 
463
 
 
464
        if (priv->drag_actor) {
 
465
                ClutterActor *parent;
 
466
 
 
467
                parent = clutter_actor_get_parent (priv->drag_actor);
 
468
                if (parent)
 
469
                        clutter_container_remove_actor (
 
470
                                CLUTTER_CONTAINER (parent),
 
471
                                priv->drag_actor);
 
472
 
 
473
                g_object_unref (priv->drag_actor);
 
474
                priv->drag_actor = NULL;
 
475
        }
 
476
 
 
477
        if (priv->drag_threshold_handler)
 
478
                g_signal_handler_disconnect (
 
479
                        gtk_settings_get_default (),
 
480
                        priv->drag_threshold_handler);
 
481
                        priv->drag_threshold_handler = 0;
 
482
 
 
483
        G_OBJECT_CLASS (e_mail_tab_parent_class)->dispose (object);
507
484
}
508
485
 
509
486
static void
510
487
e_mail_tab_get_preferred_width (ClutterActor *actor,
511
 
                             gfloat        for_height,
512
 
                             gfloat       *min_width_p,
513
 
                             gfloat       *natural_width_p)
 
488
                                gfloat for_height,
 
489
                                gfloat *min_width_p,
 
490
                                gfloat *natural_width_p)
514
491
{
515
 
  MxPadding padding;
516
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
517
 
 
518
 
  /* Get padding */
519
 
  mx_widget_get_padding (MX_WIDGET (actor), &padding);
520
 
  if (min_width_p)
521
 
    *min_width_p = padding.left + padding.right;
522
 
  if (natural_width_p)
523
 
    *natural_width_p = padding.left + padding.right;
524
 
 
525
 
  if (priv->width >= 0)
526
 
    {
527
 
      if (natural_width_p)
528
 
        *natural_width_p += priv->width;
529
 
    }
530
 
  else
531
 
    {
532
 
      gfloat min_width, nat_width, acc_min_width, acc_nat_width;
533
 
 
534
 
      acc_min_width = acc_nat_width = 0;
535
 
 
536
 
      if (priv->has_text)
537
 
        clutter_actor_get_preferred_size (CLUTTER_ACTOR (priv->label),
538
 
                                          &acc_min_width, NULL,
539
 
                                          &acc_nat_width, NULL);
540
 
 
541
 
      if (priv->icon)
542
 
        {
543
 
          clutter_actor_get_preferred_size (priv->icon,
544
 
                                            &min_width, NULL,
545
 
                                            &nat_width, NULL);
546
 
          acc_min_width += min_width;
547
 
          acc_nat_width += nat_width;
548
 
        }
549
 
 
550
 
      if (priv->can_close)
551
 
        {
552
 
          clutter_actor_get_preferred_size (CLUTTER_ACTOR (priv->close_button),
553
 
                                            &min_width, NULL,
554
 
                                            &nat_width, NULL);
555
 
          acc_min_width += min_width;
556
 
          acc_nat_width += nat_width;
557
 
        }
558
 
 
559
 
      if (priv->preview && priv->preview_mode)
560
 
        {
561
 
          clutter_actor_get_preferred_size (priv->preview,
562
 
                                            &min_width, NULL,
563
 
                                            &nat_width, NULL);
564
 
          if (min_width > acc_min_width)
565
 
            acc_min_width = min_width;
566
 
          if (nat_width > acc_nat_width)
567
 
            acc_nat_width = nat_width;
568
 
        }
569
 
 
570
 
      if (min_width_p)
571
 
        *min_width_p += acc_min_width;
572
 
      if (natural_width_p)
573
 
        *natural_width_p += acc_nat_width;
574
 
    }
 
492
        MxPadding padding;
 
493
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
494
 
 
495
        /* Get padding */
 
496
        mx_widget_get_padding (MX_WIDGET (actor), &padding);
 
497
        if (min_width_p)
 
498
                *min_width_p = padding.left + padding.right;
 
499
        if (natural_width_p)
 
500
                *natural_width_p = padding.left + padding.right;
 
501
 
 
502
        if (priv->width >= 0) {
 
503
                if (natural_width_p)
 
504
                        *natural_width_p += priv->width;
 
505
        } else {
 
506
                gfloat min_width, nat_width, acc_min_width, acc_nat_width;
 
507
 
 
508
                acc_min_width = acc_nat_width = 0;
 
509
 
 
510
                if (priv->has_text)
 
511
                        clutter_actor_get_preferred_size (
 
512
                                CLUTTER_ACTOR (priv->label),
 
513
                                &acc_min_width, NULL,
 
514
                                &acc_nat_width, NULL);
 
515
 
 
516
                if (priv->icon)
 
517
                        clutter_actor_get_preferred_size (
 
518
                                priv->icon,
 
519
                                &min_width, NULL,
 
520
                                &nat_width, NULL);
 
521
                                acc_min_width += min_width;
 
522
                                acc_nat_width += nat_width;
 
523
 
 
524
                if (priv->can_close)
 
525
                        clutter_actor_get_preferred_size (
 
526
                                CLUTTER_ACTOR (priv->close_button),
 
527
                                &min_width, NULL,
 
528
                                &nat_width, NULL);
 
529
                                acc_min_width += min_width;
 
530
                                acc_nat_width += nat_width;
 
531
 
 
532
                if (priv->preview && priv->preview_mode) {
 
533
                        clutter_actor_get_preferred_size (
 
534
                                priv->preview,
 
535
                                &min_width, NULL,
 
536
                                &nat_width, NULL);
 
537
 
 
538
                        if (min_width > acc_min_width)
 
539
                                acc_min_width = min_width;
 
540
                        if (nat_width > acc_nat_width)
 
541
                                acc_nat_width = nat_width;
 
542
                }
 
543
 
 
544
                if (min_width_p)
 
545
                        *min_width_p += acc_min_width;
 
546
                if (natural_width_p)
 
547
                        *natural_width_p += acc_nat_width;
 
548
        }
575
549
}
576
550
 
577
551
void
578
552
e_mail_tab_get_height_no_preview (EMailTab *tab,
579
 
                               gfloat  for_width,
580
 
                               gfloat *min_height_p,
581
 
                               gfloat *natural_height_p)
 
553
                                  gfloat for_width,
 
554
                                  gfloat *min_height_p,
 
555
                                  gfloat *natural_height_p)
582
556
{
583
 
  MxPadding padding;
584
 
  gfloat min_height, nat_height, tmp_min_height, tmp_nat_height;
585
 
 
586
 
  ClutterActor *actor = CLUTTER_ACTOR (tab);
587
 
  EMailTabPrivate *priv = tab->priv;
588
 
 
589
 
  /* Get padding */
590
 
  mx_widget_get_padding (MX_WIDGET (actor), &padding);
591
 
  if (min_height_p)
592
 
    *min_height_p = padding.top + padding.bottom;
593
 
  if (natural_height_p)
594
 
    *natural_height_p = padding.top + padding.bottom;
595
 
 
596
 
  min_height = nat_height = 0;
597
 
  if (priv->has_text)
598
 
    clutter_actor_get_preferred_height (CLUTTER_ACTOR (priv->label), -1,
599
 
                                        &min_height, &nat_height);
600
 
 
601
 
  if (priv->icon)
602
 
    {
603
 
      clutter_actor_get_preferred_height (priv->icon, -1,
604
 
                                          &tmp_min_height, &tmp_nat_height);
605
 
      if (tmp_min_height > min_height)
606
 
        min_height = tmp_min_height;
607
 
      if (tmp_nat_height > nat_height)
608
 
        nat_height = tmp_nat_height;
609
 
    }
610
 
 
611
 
  if (priv->can_close)
612
 
    {
613
 
      clutter_actor_get_preferred_height (CLUTTER_ACTOR (priv->close_button),
614
 
                                          -1, &tmp_min_height, &tmp_nat_height);
615
 
      if (tmp_min_height > min_height)
616
 
        min_height = tmp_min_height;
617
 
      if (tmp_nat_height > nat_height)
618
 
        nat_height = tmp_nat_height;
619
 
    }
620
 
 
621
 
  if (min_height_p)
622
 
    *min_height_p += min_height;
623
 
  if (natural_height_p)
624
 
    *natural_height_p += nat_height;
 
557
        MxPadding padding;
 
558
        gfloat min_height, nat_height, tmp_min_height, tmp_nat_height;
 
559
 
 
560
        ClutterActor *actor = CLUTTER_ACTOR (tab);
 
561
        EMailTabPrivate *priv = tab->priv;
 
562
 
 
563
        /* Get padding */
 
564
        mx_widget_get_padding (MX_WIDGET (actor), &padding);
 
565
        if (min_height_p)
 
566
                *min_height_p = padding.top + padding.bottom;
 
567
        if (natural_height_p)
 
568
                *natural_height_p = padding.top + padding.bottom;
 
569
 
 
570
        min_height = nat_height = 0;
 
571
        if (priv->has_text)
 
572
                clutter_actor_get_preferred_height (
 
573
                        CLUTTER_ACTOR (priv->label), -1,
 
574
                        &min_height, &nat_height);
 
575
 
 
576
        if (priv->icon) {
 
577
                clutter_actor_get_preferred_height (
 
578
                        priv->icon, -1, &tmp_min_height, &tmp_nat_height);
 
579
                if (tmp_min_height > min_height)
 
580
                        min_height = tmp_min_height;
 
581
                if (tmp_nat_height > nat_height)
 
582
                        nat_height = tmp_nat_height;
 
583
        }
 
584
 
 
585
        if (priv->can_close) {
 
586
                clutter_actor_get_preferred_height (
 
587
                        CLUTTER_ACTOR (priv->close_button),
 
588
                        -1, &tmp_min_height, &tmp_nat_height);
 
589
 
 
590
                if (tmp_min_height > min_height)
 
591
                        min_height = tmp_min_height;
 
592
                if (tmp_nat_height > nat_height)
 
593
                        nat_height = tmp_nat_height;
 
594
        }
 
595
 
 
596
        if (min_height_p)
 
597
                *min_height_p += min_height;
 
598
        if (natural_height_p)
 
599
                *natural_height_p += nat_height;
625
600
}
626
601
 
627
602
static void
628
603
e_mail_tab_get_preferred_height (ClutterActor *actor,
629
 
                              gfloat        for_width,
630
 
                              gfloat       *min_height_p,
631
 
                              gfloat       *natural_height_p)
 
604
                                 gfloat for_width,
 
605
                                 gfloat *min_height_p,
 
606
                                 gfloat *natural_height_p)
632
607
{
633
 
  EMailTab *tab = E_MAIL_TAB (actor);
634
 
  EMailTabPrivate *priv = tab->priv;
635
 
 
636
 
  e_mail_tab_get_height_no_preview (tab, for_width,
637
 
                                 min_height_p, natural_height_p);
638
 
 
639
 
  if (priv->preview)
640
 
    {
641
 
      MxPadding padding;
642
 
      gfloat min_height, nat_height, label_min_height, label_nat_height;
643
 
 
644
 
      /* Get preview + padding height */
645
 
      mx_widget_get_padding (MX_WIDGET (actor), &padding);
646
 
 
647
 
      clutter_actor_get_preferred_height (priv->preview,
648
 
                                          (gfloat) priv->width,
649
 
                                          &min_height,
650
 
                                          &nat_height);
651
 
 
652
 
      /* Add label height */
653
 
      clutter_actor_get_preferred_height (CLUTTER_ACTOR (priv->label), -1,
654
 
                                          &label_min_height, &label_nat_height);
655
 
 
656
 
      min_height = (min_height * priv->preview_height_progress) +
657
 
                   padding.top + padding.bottom + priv->spacing +
658
 
                   label_min_height;
659
 
      nat_height = (nat_height * priv->preview_height_progress) +
660
 
                   padding.top + padding.bottom + priv->spacing +
661
 
                   label_nat_height;
662
 
 
663
 
      /* Sometimes the preview's natural height will be nan due to
664
 
       * keeping of the aspect ratio. This guards against that and stops
665
 
       * Clutter from warning that the natural height is less than the
666
 
       * minimum height.
667
 
       */
668
 
      if (isnan (nat_height))
669
 
        nat_height = min_height;
670
 
 
671
 
      if (min_height_p && (min_height > *min_height_p))
672
 
        *min_height_p = min_height;
673
 
      if (natural_height_p && (nat_height > *natural_height_p))
674
 
        *natural_height_p = nat_height;
675
 
    }
 
608
        EMailTab *tab = E_MAIL_TAB (actor);
 
609
        EMailTabPrivate *priv = tab->priv;
 
610
 
 
611
        e_mail_tab_get_height_no_preview (
 
612
                tab, for_width, min_height_p, natural_height_p);
 
613
 
 
614
        if (priv->preview) {
 
615
                MxPadding padding;
 
616
                gfloat min_height, nat_height;
 
617
                gfloat label_min_height, label_nat_height;
 
618
 
 
619
                /* Get preview + padding height */
 
620
                mx_widget_get_padding (MX_WIDGET (actor), &padding);
 
621
 
 
622
                clutter_actor_get_preferred_height (
 
623
                        priv->preview,
 
624
                        (gfloat) priv->width,
 
625
                        &min_height, &nat_height);
 
626
 
 
627
                /* Add label height */
 
628
                clutter_actor_get_preferred_height (
 
629
                        CLUTTER_ACTOR (priv->label), -1,
 
630
                        &label_min_height, &label_nat_height);
 
631
 
 
632
                min_height =
 
633
                        (min_height * priv->preview_height_progress) +
 
634
                        padding.top + padding.bottom + priv->spacing +
 
635
                        label_min_height;
 
636
 
 
637
                nat_height =
 
638
                        (nat_height * priv->preview_height_progress) +
 
639
                        padding.top + padding.bottom + priv->spacing +
 
640
                        label_nat_height;
 
641
 
 
642
                /* Sometimes the preview's natural height will be nan due to
 
643
                 * keeping of the aspect ratio. This guards against that and
 
644
                 * stops Clutter from warning that the natural height is less
 
645
                 * than the minimum height. */
 
646
                if (isnan (nat_height))
 
647
                        nat_height = min_height;
 
648
 
 
649
                if (min_height_p && (min_height > *min_height_p))
 
650
                        *min_height_p = min_height;
 
651
                if (natural_height_p && (nat_height > *natural_height_p))
 
652
                        *natural_height_p = nat_height;
 
653
        }
676
654
}
677
655
 
678
656
static void
679
 
e_mail_tab_allocate (ClutterActor           *actor,
680
 
                  const ClutterActorBox  *box,
681
 
                  ClutterAllocationFlags  flags)
 
657
e_mail_tab_allocate (ClutterActor *actor,
 
658
                     const ClutterActorBox *box,
 
659
                     ClutterAllocationFlags flags)
682
660
{
683
 
  MxPadding padding;
684
 
  ClutterActorBox child_box;
685
 
  gfloat icon_width, icon_height, label_width, label_height,
686
 
         close_width, close_height, preview_width, preview_height;
687
 
 
688
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
689
 
 
690
 
  /* Chain up to store box */
691
 
  CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->allocate (actor, box, flags);
692
 
 
693
 
  /* Possibly synchronise an axis if we're dragging */
694
 
  if (priv->in_drag)
695
 
    {
696
 
      ClutterActor *drag_actor =
697
 
        mx_draggable_get_drag_actor (MX_DRAGGABLE (actor));
698
 
 
699
 
      if (drag_actor)
700
 
        {
701
 
          gfloat x, y;
702
 
          clutter_actor_get_transformed_position (actor, &x, &y);
703
 
          switch (mx_draggable_get_axis (MX_DRAGGABLE (actor)))
704
 
            {
705
 
            case MX_DRAG_AXIS_X :
706
 
              /* Synchronise y axis */
707
 
              clutter_actor_set_y (drag_actor, y);
708
 
              break;
709
 
            case MX_DRAG_AXIS_Y :
710
 
              /* Synchronise x axis */
711
 
              clutter_actor_set_x (drag_actor, x);
712
 
              break;
713
 
            default :
714
 
              break;
715
 
            }
716
 
        }
717
 
    }
718
 
 
719
 
  /* Allocate old background texture */
720
 
  if (priv->old_bg)
721
 
    {
722
 
      child_box.x1 = 0;
723
 
      child_box.y1 = 0;
724
 
      child_box.x2 = box->x2 - box->x1;
725
 
      child_box.y2 = box->y2 - box->y1;
726
 
      clutter_actor_allocate (priv->old_bg, &child_box, flags);
727
 
    }
728
 
 
729
 
  mx_widget_get_padding (MX_WIDGET (actor), &padding);
730
 
 
731
 
  /* Get the preferred width/height of the icon, label and close-button first */
732
 
  if (priv->icon)
733
 
    clutter_actor_get_preferred_size (priv->icon, NULL, NULL,
734
 
                                      &icon_width, &icon_height);
735
 
  clutter_actor_get_preferred_size (CLUTTER_ACTOR (priv->label), NULL, NULL,
736
 
                                    &label_width, &label_height);
737
 
  if (priv->can_close)
738
 
    clutter_actor_get_preferred_size (CLUTTER_ACTOR (priv->close_button),
739
 
                                      NULL, NULL, &close_width, &close_height);
740
 
 
741
 
  /* Allocate for icon */
742
 
  if (priv->icon)
743
 
    {
744
 
      child_box.x1 = padding.left;
745
 
      child_box.x2 = child_box.x1 + icon_width;
746
 
      child_box.y1 = E_MAIL_PIXBOUND ((box->y2 - box->y1)/2 - icon_height/2);
747
 
      child_box.y2 = child_box.y1 + icon_height;
748
 
      clutter_actor_allocate (priv->icon, &child_box, flags);
749
 
    }
750
 
 
751
 
  /* Allocate for close button */
752
 
  if (priv->can_close)
753
 
    {
754
 
      child_box.x2 = box->x2 - box->x1 - padding.right;
755
 
      child_box.x1 = child_box.x2 - close_width;
756
 
      child_box.y1 = E_MAIL_PIXBOUND ((box->y2 - box->y1)/2 - close_height/2);
757
 
      child_box.y2 = child_box.y1 + close_height;
758
 
      clutter_actor_allocate (CLUTTER_ACTOR (priv->close_button),
759
 
                              &child_box,
760
 
                              flags);
761
 
    }
762
 
 
763
 
  /* Allocate for preview widget */
764
 
  preview_height = 0;
765
 
  if (priv->preview)
766
 
    {
767
 
      preview_width = (box->x2 - box->x1 - padding.left - padding.right);
768
 
      preview_height = (box->y2 - box->y1 - padding.top - padding.bottom -
769
 
                        priv->spacing - label_height);
770
 
 
771
 
      child_box.x1 = E_MAIL_PIXBOUND (padding.left);
772
 
      child_box.y1 = E_MAIL_PIXBOUND (padding.top);
773
 
      child_box.x2 = child_box.x1 + preview_width;
774
 
      child_box.y2 = child_box.y1 + preview_height;
775
 
      clutter_actor_allocate (priv->preview, &child_box, flags);
776
 
    }
777
 
 
778
 
  /* Allocate for label */
779
 
  if ((priv->preview_height_progress <= TAB_S1_ANIM) || (!priv->preview))
780
 
    {
781
 
      if (priv->icon)
782
 
        child_box.x1 = E_MAIL_PIXBOUND (padding.left + icon_width + priv->spacing);
783
 
      else
784
 
        child_box.x1 = E_MAIL_PIXBOUND (padding.left);
785
 
      child_box.x2 = (box->x2 - box->x1 - padding.right);
786
 
      child_box.y1 = E_MAIL_PIXBOUND ((box->y2 - box->y1)/2 - label_height/2);
787
 
      child_box.y2 = child_box.y1 + label_height;
788
 
 
789
 
      /* If close button is visible, don't overlap it */
790
 
      if (priv->can_close)
791
 
        child_box.x2 -= close_width + priv->spacing;
792
 
    }
793
 
  else
794
 
    {
795
 
      /* Put label underneath preview */
796
 
      child_box.x1 = E_MAIL_PIXBOUND (padding.left);
797
 
      child_box.x2 = (box->x2 - box->x1 - padding.right);
798
 
      child_box.y1 = E_MAIL_PIXBOUND (padding.top + preview_height +
799
 
                                   priv->spacing);
800
 
      child_box.y2 = child_box.y1 + label_height;
801
 
    }
802
 
 
803
 
  clutter_actor_allocate (CLUTTER_ACTOR (priv->label), &child_box, flags);
804
 
 
805
 
  /* If we're in preview mode, re-allocate the background so it doesn't
806
 
   * encompass the label. (A bit hacky?)
807
 
   */
808
 
  if (priv->preview && CLUTTER_ACTOR_IS_VISIBLE (priv->preview))
809
 
    {
810
 
      gfloat max_height = padding.top + padding.bottom + preview_height;
811
 
      if (box->y2 - box->y1 > max_height)
812
 
        {
813
 
          MxWidget *widget = MX_WIDGET (actor);
814
 
          ClutterActor *background = mx_widget_get_border_image (widget);
815
 
 
816
 
          if (!background)
817
 
            background = mx_widget_get_background_image (widget);
818
 
 
819
 
          child_box.x1 = 0;
820
 
          child_box.x2 = box->x2 - box->x1;
821
 
          child_box.y1 = 0;
822
 
          child_box.y2 = max_height;
823
 
 
824
 
          if (background)
825
 
            clutter_actor_allocate (background, &child_box, flags);
826
 
          if (priv->old_bg && (priv->old_bg != background))
827
 
            clutter_actor_allocate (priv->old_bg, &child_box, flags);
828
 
        }
829
 
    }
 
661
        MxPadding padding;
 
662
        ClutterActorBox child_box;
 
663
        gfloat icon_width, icon_height;
 
664
        gfloat label_width, label_height;
 
665
        gfloat close_width, close_height;
 
666
        gfloat preview_width, preview_height;
 
667
 
 
668
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
669
 
 
670
        /* Chain up to store box */
 
671
        CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->allocate (actor, box, flags);
 
672
 
 
673
        /* Possibly synchronise an axis if we're dragging */
 
674
        if (priv->in_drag) {
 
675
                ClutterActor *drag_actor =
 
676
                        mx_draggable_get_drag_actor (MX_DRAGGABLE (actor));
 
677
 
 
678
                if (drag_actor) {
 
679
                        gfloat x, y;
 
680
                        clutter_actor_get_transformed_position (actor, &x, &y);
 
681
 
 
682
                        switch (mx_draggable_get_axis (MX_DRAGGABLE (actor))) {
 
683
                                case MX_DRAG_AXIS_X :
 
684
                                        /* Synchronise y axis */
 
685
                                        clutter_actor_set_y (drag_actor, y);
 
686
                                        break;
 
687
                                case MX_DRAG_AXIS_Y :
 
688
                                        /* Synchronise x axis */
 
689
                                        clutter_actor_set_x (drag_actor, x);
 
690
                                        break;
 
691
                                default:
 
692
                                        break;
 
693
                        }
 
694
                }
 
695
        }
 
696
 
 
697
        /* Allocate old background texture */
 
698
        if (priv->old_bg) {
 
699
                child_box.x1 = 0;
 
700
                child_box.y1 = 0;
 
701
                child_box.x2 = box->x2 - box->x1;
 
702
                child_box.y2 = box->y2 - box->y1;
 
703
                clutter_actor_allocate (priv->old_bg, &child_box, flags);
 
704
        }
 
705
 
 
706
        mx_widget_get_padding (MX_WIDGET (actor), &padding);
 
707
 
 
708
        /* Get the preferred width/height of the icon,
 
709
         * label and close-button first. */
 
710
        if (priv->icon)
 
711
                clutter_actor_get_preferred_size (
 
712
                        priv->icon, NULL, NULL,
 
713
                        &icon_width, &icon_height);
 
714
 
 
715
        clutter_actor_get_preferred_size (
 
716
                CLUTTER_ACTOR (priv->label), NULL, NULL,
 
717
                &label_width, &label_height);
 
718
 
 
719
        if (priv->can_close)
 
720
                clutter_actor_get_preferred_size (
 
721
                        CLUTTER_ACTOR (priv->close_button),
 
722
                        NULL, NULL, &close_width, &close_height);
 
723
 
 
724
        /* Allocate for icon */
 
725
        if (priv->icon) {
 
726
                child_box.x1 = padding.left;
 
727
                child_box.x2 = child_box.x1 + icon_width;
 
728
                child_box.y1 = E_MAIL_PIXBOUND ((box->y2 - box->y1) / 2 - icon_height / 2);
 
729
                child_box.y2 = child_box.y1 + icon_height;
 
730
                clutter_actor_allocate (priv->icon, &child_box, flags);
 
731
        }
 
732
 
 
733
        /* Allocate for close button */
 
734
        if (priv->can_close) {
 
735
                child_box.x2 = box->x2 - box->x1 - padding.right;
 
736
                child_box.x1 = child_box.x2 - close_width;
 
737
                child_box.y1 = E_MAIL_PIXBOUND ((box->y2 - box->y1) / 2 - close_height / 2);
 
738
                child_box.y2 = child_box.y1 + close_height;
 
739
                clutter_actor_allocate (
 
740
                        CLUTTER_ACTOR (priv->close_button),
 
741
                        &child_box, flags);
 
742
        }
 
743
 
 
744
        /* Allocate for preview widget */
 
745
        preview_height = 0;
 
746
        if (priv->preview) {
 
747
                preview_width =
 
748
                        (box->x2 - box->x1 -
 
749
                         padding.left - padding.right);
 
750
                preview_height =
 
751
                        (box->y2 - box->y1 -
 
752
                         padding.top - padding.bottom -
 
753
                         priv->spacing - label_height);
 
754
 
 
755
                child_box.x1 = E_MAIL_PIXBOUND (padding.left);
 
756
                child_box.y1 = E_MAIL_PIXBOUND (padding.top);
 
757
                child_box.x2 = child_box.x1 + preview_width;
 
758
                child_box.y2 = child_box.y1 + preview_height;
 
759
 
 
760
                clutter_actor_allocate (priv->preview, &child_box, flags);
 
761
        }
 
762
 
 
763
        /* Allocate for label */
 
764
        if ((priv->preview_height_progress <= TAB_S1_ANIM) || (!priv->preview)) {
 
765
                if (priv->icon)
 
766
                        child_box.x1 = E_MAIL_PIXBOUND (padding.left + icon_width + priv->spacing);
 
767
                else
 
768
                        child_box.x1 = E_MAIL_PIXBOUND (padding.left);
 
769
                child_box.x2 = (box->x2 - box->x1 - padding.right);
 
770
                child_box.y1 = E_MAIL_PIXBOUND ((box->y2 - box->y1) / 2 - label_height / 2);
 
771
                child_box.y2 = child_box.y1 + label_height;
 
772
 
 
773
                /* If close button is visible, don't overlap it */
 
774
                if (priv->can_close)
 
775
                        child_box.x2 -= close_width + priv->spacing;
 
776
        } else {
 
777
                /* Put label underneath preview */
 
778
                child_box.x1 = E_MAIL_PIXBOUND (padding.left);
 
779
                child_box.x2 = (box->x2 - box->x1 - padding.right);
 
780
                child_box.y1 = E_MAIL_PIXBOUND (
 
781
                        padding.top + preview_height + priv->spacing);
 
782
                child_box.y2 = child_box.y1 + label_height;
 
783
        }
 
784
 
 
785
        clutter_actor_allocate (CLUTTER_ACTOR (priv->label), &child_box, flags);
 
786
 
 
787
        /* If we're in preview mode, re-allocate the background so it doesn't
 
788
         * encompass the label. (A bit hacky?)
 
789
         */
 
790
        if (priv->preview && CLUTTER_ACTOR_IS_VISIBLE (priv->preview)) {
 
791
                gfloat max_height = padding.top + padding.bottom + preview_height;
 
792
                if (box->y2 - box->y1 > max_height) {
 
793
                        MxWidget *widget = MX_WIDGET (actor);
 
794
                        ClutterActor *background = mx_widget_get_border_image (widget);
 
795
 
 
796
                        if (!background)
 
797
                                background = mx_widget_get_background_image (widget);
 
798
 
 
799
                        child_box.x1 = 0;
 
800
                        child_box.x2 = box->x2 - box->x1;
 
801
                        child_box.y1 = 0;
 
802
                        child_box.y2 = max_height;
 
803
 
 
804
                        if (background)
 
805
                                clutter_actor_allocate (
 
806
                                        background, &child_box, flags);
 
807
 
 
808
                        if (priv->old_bg && (priv->old_bg != background))
 
809
                                clutter_actor_allocate (
 
810
                                        priv->old_bg, &child_box, flags);
 
811
                }
 
812
        }
830
813
}
831
814
 
832
815
static void
833
816
e_mail_tab_paint (ClutterActor *actor)
834
817
{
835
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
836
 
 
837
 
  /* Chain up to paint background */
838
 
  CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->paint (actor);
839
 
 
840
 
  if (priv->old_bg)
841
 
    clutter_actor_paint (priv->old_bg);
842
 
 
843
 
  if (priv->icon)
844
 
    clutter_actor_paint (priv->icon);
845
 
 
846
 
  clutter_actor_paint (CLUTTER_ACTOR (priv->label));
847
 
 
848
 
  if (priv->can_close)
849
 
    clutter_actor_paint (CLUTTER_ACTOR (priv->close_button));
850
 
 
851
 
  if (priv->preview)
852
 
    clutter_actor_paint (CLUTTER_ACTOR (priv->preview));
 
818
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
819
 
 
820
        /* Chain up to paint background */
 
821
        CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->paint (actor);
 
822
 
 
823
        if (priv->old_bg)
 
824
                clutter_actor_paint (priv->old_bg);
 
825
 
 
826
        if (priv->icon)
 
827
                clutter_actor_paint (priv->icon);
 
828
 
 
829
        clutter_actor_paint (CLUTTER_ACTOR (priv->label));
 
830
 
 
831
        if (priv->can_close)
 
832
                clutter_actor_paint (CLUTTER_ACTOR (priv->close_button));
 
833
 
 
834
        if (priv->preview)
 
835
                clutter_actor_paint (CLUTTER_ACTOR (priv->preview));
853
836
}
854
837
 
855
838
static void
856
 
e_mail_tab_pick (ClutterActor *actor, const ClutterColor *c)
 
839
e_mail_tab_pick (ClutterActor *actor,
 
840
                 const ClutterColor *c)
857
841
{
858
 
  CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->pick (actor, c);
 
842
        CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->pick (actor, c);
859
843
 
860
 
  if (clutter_actor_should_pick_paint (actor))
861
 
    e_mail_tab_paint (actor);
 
844
        if (clutter_actor_should_pick_paint (actor))
 
845
                e_mail_tab_paint (actor);
862
846
}
863
847
 
864
848
static void
865
849
e_mail_tab_map (ClutterActor *actor)
866
850
{
867
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
868
 
 
869
 
  CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->map (actor);
870
 
 
871
 
  clutter_actor_map (CLUTTER_ACTOR (priv->label));
872
 
  clutter_actor_map (CLUTTER_ACTOR (priv->close_button));
873
 
  if (priv->icon)
874
 
    clutter_actor_map (priv->icon);
875
 
  if (priv->preview)
876
 
    clutter_actor_map (priv->preview);
877
 
  if (priv->old_bg)
878
 
    clutter_actor_map (priv->old_bg);
 
851
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
852
 
 
853
        CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->map (actor);
 
854
 
 
855
        clutter_actor_map (CLUTTER_ACTOR (priv->label));
 
856
        clutter_actor_map (CLUTTER_ACTOR (priv->close_button));
 
857
 
 
858
        if (priv->icon)
 
859
                clutter_actor_map (priv->icon);
 
860
        if (priv->preview)
 
861
                clutter_actor_map (priv->preview);
 
862
        if (priv->old_bg)
 
863
                clutter_actor_map (priv->old_bg);
879
864
}
880
865
 
881
866
static void
882
867
e_mail_tab_unmap (ClutterActor *actor)
883
868
{
884
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
885
 
 
886
 
  CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->unmap (actor);
887
 
 
888
 
  clutter_actor_unmap (CLUTTER_ACTOR (priv->label));
889
 
  clutter_actor_unmap (CLUTTER_ACTOR (priv->close_button));
890
 
  if (priv->icon)
891
 
    clutter_actor_unmap (priv->icon);
892
 
  if (priv->preview)
893
 
    clutter_actor_unmap (priv->preview);
894
 
  if (priv->old_bg)
895
 
    clutter_actor_unmap (priv->old_bg);
896
 
}
897
 
 
898
 
static gboolean
899
 
e_mail_tab_button_press_event (ClutterActor       *actor,
900
 
                            ClutterButtonEvent *event)
901
 
{
902
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
903
 
 
904
 
  if (event->button == 1)
905
 
    {
906
 
      mx_stylable_set_style_pseudo_class (MX_STYLABLE (actor), "active");
907
 
      clutter_grab_pointer (actor);
908
 
      priv->pressed = TRUE;
909
 
 
910
 
      priv->press_x = event->x;
911
 
      priv->press_y = event->y;
912
 
    }
913
 
 
914
 
  /* We have to always return false, or dragging won't work */
915
 
  return FALSE;
916
 
}
917
 
 
918
 
static gboolean
919
 
e_mail_tab_button_release_event (ClutterActor       *actor,
920
 
                              ClutterButtonEvent *event)
921
 
{
922
 
  EMailTab *tab = E_MAIL_TAB (actor);
923
 
  EMailTabPrivate *priv = tab->priv;
924
 
 
925
 
  if (priv->pressed)
926
 
    {
927
 
      clutter_ungrab_pointer ();
928
 
      priv->pressed = FALSE;
929
 
 
930
 
      /* Note, no need to set the pseudo class here as clicking always results
931
 
       * in being set active.
932
 
       */
933
 
      if (priv->hover)
934
 
        {
935
 
          if (!priv->active)
936
 
            e_mail_tab_set_active (tab, TRUE);
937
 
 
938
 
          g_signal_emit (actor, signals[CLICKED], 0);
939
 
        }
940
 
    }
941
 
 
942
 
  return FALSE;
943
 
}
944
 
 
945
 
static gboolean
946
 
e_mail_tab_motion_event (ClutterActor       *actor,
947
 
                      ClutterMotionEvent *event)
948
 
{
949
 
  EMailTab *tab = E_MAIL_TAB (actor);
950
 
  EMailTabPrivate *priv = tab->priv;
951
 
 
952
 
  if (priv->pressed && priv->drag_enabled)
953
 
    {
954
 
      if ((ABS (event->x - priv->press_x) >= priv->drag_threshold) ||
955
 
          (ABS (event->y - priv->press_y) >= priv->drag_threshold))
956
 
        {
957
 
          /* Ungrab the pointer so that the MxDraggable code can take over */
958
 
          clutter_ungrab_pointer ();
959
 
          priv->pressed = FALSE;
960
 
          if (!priv->active)
961
 
            {
962
 
              if (priv->hover)
963
 
                mx_stylable_set_style_pseudo_class (MX_STYLABLE (actor),
964
 
                                                    "hover");
965
 
              else
 
869
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
870
 
 
871
        CLUTTER_ACTOR_CLASS (e_mail_tab_parent_class)->unmap (actor);
 
872
 
 
873
        clutter_actor_unmap (CLUTTER_ACTOR (priv->label));
 
874
        clutter_actor_unmap (CLUTTER_ACTOR (priv->close_button));
 
875
 
 
876
        if (priv->icon)
 
877
                clutter_actor_unmap (priv->icon);
 
878
        if (priv->preview)
 
879
                clutter_actor_unmap (priv->preview);
 
880
        if (priv->old_bg)
 
881
                clutter_actor_unmap (priv->old_bg);
 
882
}
 
883
 
 
884
static gboolean
 
885
e_mail_tab_button_press_event (ClutterActor *actor,
 
886
                               ClutterButtonEvent *event)
 
887
{
 
888
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
889
 
 
890
        if (event->button == 1) {
 
891
                mx_stylable_set_style_pseudo_class (
 
892
                        MX_STYLABLE (actor), "active");
 
893
                clutter_grab_pointer (actor);
 
894
                priv->pressed = TRUE;
 
895
 
 
896
                priv->press_x = event->x;
 
897
                priv->press_y = event->y;
 
898
        }
 
899
 
 
900
        /* We have to always return false, or dragging won't work */
 
901
        return FALSE;
 
902
}
 
903
 
 
904
static gboolean
 
905
e_mail_tab_button_release_event (ClutterActor *actor,
 
906
                                 ClutterButtonEvent *event)
 
907
{
 
908
        EMailTab *tab = E_MAIL_TAB (actor);
 
909
        EMailTabPrivate *priv = tab->priv;
 
910
 
 
911
        if (priv->pressed) {
 
912
                clutter_ungrab_pointer ();
 
913
                priv->pressed = FALSE;
 
914
 
 
915
                /* Note, no need to set the pseudo class here as clicking
 
916
                 * always results in being set active. */
 
917
                if (priv->hover) {
 
918
                        if (!priv->active)
 
919
                                e_mail_tab_set_active (tab, TRUE);
 
920
 
 
921
                        g_signal_emit (actor, signals[CLICKED], 0);
 
922
                }
 
923
        }
 
924
 
 
925
        return FALSE;
 
926
}
 
927
 
 
928
static gboolean
 
929
e_mail_tab_motion_event (ClutterActor *actor,
 
930
                         ClutterMotionEvent *event)
 
931
{
 
932
        EMailTab *tab = E_MAIL_TAB (actor);
 
933
        EMailTabPrivate *priv = tab->priv;
 
934
 
 
935
        if (priv->pressed && priv->drag_enabled) {
 
936
                if ((ABS (event->x - priv->press_x) >= priv->drag_threshold) ||
 
937
                    (ABS (event->y - priv->press_y) >= priv->drag_threshold)) {
 
938
                        /* Ungrab the pointer so that the MxDraggable code can take over */
 
939
                        clutter_ungrab_pointer ();
 
940
                        priv->pressed = FALSE;
 
941
                        if (!priv->active) {
 
942
                                if (priv->hover)
 
943
                                        mx_stylable_set_style_pseudo_class (
 
944
                                                MX_STYLABLE (actor), "hover");
 
945
                                else
 
946
                                        mx_stylable_set_style_pseudo_class (
 
947
                                                MX_STYLABLE (actor), NULL);
 
948
                        }
 
949
                }
 
950
        }
 
951
 
 
952
        return FALSE;
 
953
}
 
954
 
 
955
static gboolean
 
956
e_mail_tab_enter_event (ClutterActor *actor,
 
957
                        ClutterCrossingEvent *event)
 
958
{
 
959
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
960
 
 
961
        if (event->source != actor)
 
962
                return FALSE;
 
963
 
 
964
        priv->hover = TRUE;
 
965
 
 
966
        if (priv->pressed)
 
967
                mx_stylable_set_style_pseudo_class (
 
968
                        MX_STYLABLE (actor), "active");
 
969
        else if (!priv->active)
 
970
                mx_stylable_set_style_pseudo_class (
 
971
                        MX_STYLABLE (actor), "hover");
 
972
 
 
973
        return FALSE;
 
974
}
 
975
 
 
976
static gboolean
 
977
e_mail_tab_leave_event (ClutterActor *actor,
 
978
                        ClutterCrossingEvent *event)
 
979
{
 
980
        EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
 
981
 
 
982
        if ((event->source != actor) ||
 
983
                (event->related == (ClutterActor *) priv->close_button))
 
984
                return FALSE;
 
985
 
 
986
        priv->hover = FALSE;
 
987
 
 
988
        if (!priv->active)
966
989
                mx_stylable_set_style_pseudo_class (MX_STYLABLE (actor), NULL);
967
 
            }
968
 
        }
969
 
    }
970
 
 
971
 
  return FALSE;
972
 
}
973
 
 
974
 
static gboolean
975
 
e_mail_tab_enter_event (ClutterActor         *actor,
976
 
                     ClutterCrossingEvent *event)
977
 
{
978
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
979
 
 
980
 
  if (event->source != actor)
981
 
    return FALSE;
982
 
 
983
 
  priv->hover = TRUE;
984
 
 
985
 
  if (priv->pressed)
986
 
    mx_stylable_set_style_pseudo_class (MX_STYLABLE (actor), "active");
987
 
  else if (!priv->active)
988
 
    mx_stylable_set_style_pseudo_class (MX_STYLABLE (actor), "hover");
989
 
 
990
 
  return FALSE;
991
 
}
992
 
 
993
 
static gboolean
994
 
e_mail_tab_leave_event (ClutterActor         *actor,
995
 
                     ClutterCrossingEvent *event)
996
 
{
997
 
  EMailTabPrivate *priv = E_MAIL_TAB (actor)->priv;
998
 
 
999
 
  if ((event->source != actor) ||
1000
 
      (event->related == (ClutterActor *) priv->close_button))
1001
 
    return FALSE;
1002
 
 
1003
 
  priv->hover = FALSE;
1004
 
 
1005
 
  if (!priv->active)
1006
 
    mx_stylable_set_style_pseudo_class (MX_STYLABLE (actor), NULL);
1007
 
 
1008
 
  return FALSE;
1009
 
}
1010
 
 
1011
 
static void
1012
 
e_mail_tab_class_init (EMailTabClass *klass)
1013
 
{
1014
 
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
1015
 
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
1016
 
 
1017
 
  g_type_class_add_private (klass, sizeof (EMailTabPrivate));
1018
 
 
1019
 
  object_class->get_property = e_mail_tab_get_property;
1020
 
  object_class->set_property = e_mail_tab_set_property;
1021
 
  object_class->dispose = e_mail_tab_dispose;
1022
 
  object_class->finalize = e_mail_tab_finalize;
1023
 
 
1024
 
  actor_class->get_preferred_width = e_mail_tab_get_preferred_width;
1025
 
  actor_class->get_preferred_height = e_mail_tab_get_preferred_height;
1026
 
  actor_class->button_press_event = e_mail_tab_button_press_event;
1027
 
  actor_class->button_release_event = e_mail_tab_button_release_event;
1028
 
  actor_class->motion_event = e_mail_tab_motion_event;
1029
 
  actor_class->enter_event = e_mail_tab_enter_event;
1030
 
  actor_class->leave_event = e_mail_tab_leave_event;
1031
 
  actor_class->allocate = e_mail_tab_allocate;
1032
 
  actor_class->paint = e_mail_tab_paint;
1033
 
  actor_class->pick = e_mail_tab_pick;
1034
 
  actor_class->map = e_mail_tab_map;
1035
 
  actor_class->unmap = e_mail_tab_unmap;
1036
 
 
1037
 
  g_object_class_install_property (object_class,
1038
 
                                   PROP_ICON,
1039
 
                                   g_param_spec_object ("icon",
1040
 
                                                        "Icon",
1041
 
                                                        "Icon actor.",
1042
 
                                                        CLUTTER_TYPE_ACTOR,
1043
 
                                                        G_PARAM_READWRITE |
1044
 
                                                        G_PARAM_STATIC_NAME |
1045
 
                                                        G_PARAM_STATIC_NICK |
1046
 
                                                        G_PARAM_STATIC_BLURB));
1047
 
 
1048
 
  g_object_class_install_property (object_class,
1049
 
                                   PROP_TEXT,
1050
 
                                   g_param_spec_string ("text",
1051
 
                                                        "Text",
1052
 
                                                        "Tab text.",
1053
 
                                                        "",
1054
 
                                                        G_PARAM_READWRITE |
1055
 
                                                        G_PARAM_STATIC_NAME |
1056
 
                                                        G_PARAM_STATIC_NICK |
1057
 
                                                        G_PARAM_STATIC_BLURB));
1058
 
 
1059
 
  g_object_class_install_property (object_class,
1060
 
                                   PROP_CAN_CLOSE,
1061
 
                                   g_param_spec_boolean ("can-close",
1062
 
                                                         "Can close",
1063
 
                                                         "Whether the tab can "
1064
 
                                                         "close.",
1065
 
                                                         TRUE,
1066
 
                                                         G_PARAM_READWRITE |
1067
 
                                                         G_PARAM_STATIC_NAME |
1068
 
                                                         G_PARAM_STATIC_NICK |
1069
 
                                                         G_PARAM_STATIC_BLURB));
1070
 
 
1071
 
  g_object_class_install_property (object_class,
1072
 
                                   PROP_TAB_WIDTH,
1073
 
                                   g_param_spec_int ("tab-width",
1074
 
                                                     "Tab width",
1075
 
                                                     "Tab width.",
1076
 
                                                     -1, G_MAXINT, -1,
1077
 
                                                     G_PARAM_READWRITE |
1078
 
                                                     G_PARAM_STATIC_NAME |
1079
 
                                                     G_PARAM_STATIC_NICK |
1080
 
                                                     G_PARAM_STATIC_BLURB));
1081
 
 
1082
 
  g_object_class_install_property (object_class,
1083
 
                                   PROP_DOCKING,
1084
 
                                   g_param_spec_boolean ("docking",
1085
 
                                                         "Docking",
1086
 
                                                         "Whether the tab "
1087
 
                                                         "should dock to edges "
1088
 
                                                         "when scrolled.",
1089
 
                                                         FALSE,
1090
 
                                                         G_PARAM_READWRITE |
1091
 
                                                         G_PARAM_STATIC_NAME |
1092
 
                                                         G_PARAM_STATIC_NICK |
1093
 
                                                         G_PARAM_STATIC_BLURB));
1094
 
 
1095
 
  g_object_class_install_property (object_class,
1096
 
                                   PROP_PREVIEW,
1097
 
                                   g_param_spec_object ("preview",
1098
 
                                                        "Preview actor",
1099
 
                                                        "ClutterActor used "
1100
 
                                                        "when in preview mode.",
1101
 
                                                        CLUTTER_TYPE_ACTOR,
1102
 
                                                        G_PARAM_READWRITE |
1103
 
                                                        G_PARAM_STATIC_NAME |
1104
 
                                                        G_PARAM_STATIC_NICK |
1105
 
                                                        G_PARAM_STATIC_BLURB));
1106
 
 
1107
 
  g_object_class_install_property (object_class,
1108
 
                                   PROP_PREVIEW_MODE,
1109
 
                                   g_param_spec_boolean ("preview-mode",
1110
 
                                                         "Preview mode",
1111
 
                                                         "Whether to display "
1112
 
                                                         "in preview mode.",
1113
 
                                                         FALSE,
1114
 
                                                         G_PARAM_READWRITE |
1115
 
                                                         G_PARAM_STATIC_NAME |
1116
 
                                                         G_PARAM_STATIC_NICK |
1117
 
                                                         G_PARAM_STATIC_BLURB));
1118
 
 
1119
 
  g_object_class_install_property (object_class,
1120
 
                                   PROP_PREVIEW_DURATION,
1121
 
                                   g_param_spec_uint ("preview-duration",
1122
 
                                                      "Preview duration",
1123
 
                                                      "How long the transition "
1124
 
                                                      "between preview mode "
1125
 
                                                      "states lasts, in ms.",
1126
 
                                                      0, G_MAXUINT, 200,
1127
 
                                                      G_PARAM_READWRITE |
1128
 
                                                      G_PARAM_STATIC_NAME |
1129
 
                                                      G_PARAM_STATIC_NICK |
1130
 
                                                      G_PARAM_STATIC_BLURB));
1131
 
 
1132
 
  g_object_class_install_property (object_class,
1133
 
                                   PROP_SPACING,
1134
 
                                   g_param_spec_float ("spacing",
1135
 
                                                       "Spacing",
1136
 
                                                       "Spacing between "
1137
 
                                                       "tab elements.",
1138
 
                                                       0, G_MAXFLOAT,
1139
 
                                                       6.0,
1140
 
                                                       G_PARAM_READWRITE |
1141
 
                                                       G_PARAM_STATIC_NAME |
1142
 
                                                       G_PARAM_STATIC_NICK |
1143
 
                                                       G_PARAM_STATIC_BLURB));
1144
 
 
1145
 
  g_object_class_install_property (object_class,
1146
 
                                   PROP_PRIVATE,
1147
 
                                   g_param_spec_boolean ("private",
1148
 
                                                         "Private",
1149
 
                                                         "Set if the tab is "
1150
 
                                                         "'private'.",
1151
 
                                                         FALSE,
1152
 
                                                         G_PARAM_READWRITE |
1153
 
                                                         G_PARAM_STATIC_NAME |
1154
 
                                                         G_PARAM_STATIC_NICK |
1155
 
                                                         G_PARAM_STATIC_BLURB));
1156
 
 
1157
 
  g_object_class_install_property (object_class,
1158
 
                                   PROP_ACTIVE,
1159
 
                                   g_param_spec_boolean ("active",
1160
 
                                                         "Active",
1161
 
                                                         "Set if the tab is "
1162
 
                                                         "active.",
1163
 
                                                         FALSE,
1164
 
                                                         G_PARAM_READWRITE |
1165
 
                                                         G_PARAM_STATIC_NAME |
1166
 
                                                         G_PARAM_STATIC_NICK |
1167
 
                                                         G_PARAM_STATIC_BLURB));
1168
 
 
1169
 
  g_object_class_override_property (object_class,
1170
 
                                    PROP_DRAG_THRESHOLD,
1171
 
                                    "drag-threshold");
1172
 
  g_object_class_override_property (object_class,
1173
 
                                    PROP_DRAG_AXIS,
1174
 
                                    "axis");
1175
 
 // g_object_class_override_property (object_class,
1176
 
   //                                 PROP_DRAG_CONTAINMENT_TYPE,
1177
 
     //                               "containment-type");
1178
 
  g_object_class_override_property (object_class,
1179
 
                                    PROP_DRAG_CONTAINMENT_AREA,
1180
 
                                    "containment-area");
1181
 
  g_object_class_override_property (object_class,
1182
 
                                    PROP_DRAG_ENABLED,
1183
 
                                    "drag-enabled");
1184
 
  g_object_class_override_property (object_class,
1185
 
                                    PROP_DRAG_ACTOR,
1186
 
                                    "drag-actor");
1187
 
 
1188
 
  signals[CLICKED] =
1189
 
    g_signal_new ("clicked",
1190
 
                  G_TYPE_FROM_CLASS (klass),
1191
 
                  G_SIGNAL_RUN_LAST,
1192
 
                  G_STRUCT_OFFSET (EMailTabClass, clicked),
1193
 
                  NULL, NULL,
1194
 
                  g_cclosure_marshal_VOID__VOID,
1195
 
                  G_TYPE_NONE, 0);
1196
 
 
1197
 
  signals[CLOSED] =
1198
 
    g_signal_new ("closed",
1199
 
                  G_TYPE_FROM_CLASS (klass),
1200
 
                  G_SIGNAL_RUN_LAST,
1201
 
                  G_STRUCT_OFFSET (EMailTabClass, closed),
1202
 
                  NULL, NULL,
1203
 
                  g_cclosure_marshal_VOID__VOID,
1204
 
                  G_TYPE_NONE, 0);
1205
 
 
1206
 
  signals[TRANSITION_COMPLETE] =
1207
 
    g_signal_new ("transition-complete",
1208
 
                  G_TYPE_FROM_CLASS (klass),
1209
 
                  G_SIGNAL_RUN_LAST,
1210
 
                  G_STRUCT_OFFSET (EMailTabClass, transition_complete),
1211
 
                  NULL, NULL,
1212
 
                  g_cclosure_marshal_VOID__VOID,
1213
 
                  G_TYPE_NONE, 0);
1214
 
}
1215
 
 
1216
 
static void
1217
 
e_mail_tab_close_clicked_cb (MxButton *button, EMailTab *self)
1218
 
{
1219
 
  g_signal_emit (self, signals[CLOSED], 0);
 
990
 
 
991
        return FALSE;
 
992
}
 
993
 
 
994
static void
 
995
e_mail_tab_class_init (EMailTabClass *class)
 
996
{
 
997
        GObjectClass *object_class = G_OBJECT_CLASS (class);
 
998
        ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (class);
 
999
 
 
1000
        g_type_class_add_private (class, sizeof (EMailTabPrivate));
 
1001
 
 
1002
        object_class->get_property = e_mail_tab_get_property;
 
1003
        object_class->set_property = e_mail_tab_set_property;
 
1004
        object_class->dispose = e_mail_tab_dispose;
 
1005
 
 
1006
        actor_class->get_preferred_width = e_mail_tab_get_preferred_width;
 
1007
        actor_class->get_preferred_height = e_mail_tab_get_preferred_height;
 
1008
        actor_class->button_press_event = e_mail_tab_button_press_event;
 
1009
        actor_class->button_release_event = e_mail_tab_button_release_event;
 
1010
        actor_class->motion_event = e_mail_tab_motion_event;
 
1011
        actor_class->enter_event = e_mail_tab_enter_event;
 
1012
        actor_class->leave_event = e_mail_tab_leave_event;
 
1013
        actor_class->allocate = e_mail_tab_allocate;
 
1014
        actor_class->paint = e_mail_tab_paint;
 
1015
        actor_class->pick = e_mail_tab_pick;
 
1016
        actor_class->map = e_mail_tab_map;
 
1017
        actor_class->unmap = e_mail_tab_unmap;
 
1018
 
 
1019
        g_object_class_install_property (
 
1020
                object_class,
 
1021
                PROP_ICON,
 
1022
                g_param_spec_object (
 
1023
                        "icon",
 
1024
                        "Icon",
 
1025
                        "Icon actor.",
 
1026
                        CLUTTER_TYPE_ACTOR,
 
1027
                        G_PARAM_READWRITE |
 
1028
                        G_PARAM_STATIC_STRINGS));
 
1029
 
 
1030
        g_object_class_install_property (
 
1031
                object_class,
 
1032
                PROP_TEXT,
 
1033
                g_param_spec_string (
 
1034
                        "text",
 
1035
                        "Text",
 
1036
                        "Tab text.",
 
1037
                        "",
 
1038
                        G_PARAM_READWRITE |
 
1039
                        G_PARAM_STATIC_STRINGS));
 
1040
 
 
1041
        g_object_class_install_property (
 
1042
                object_class,
 
1043
                PROP_CAN_CLOSE,
 
1044
                g_param_spec_boolean (
 
1045
                        "can-close",
 
1046
                        "Can close",
 
1047
                        "Whether the tab can "
 
1048
                        "close.",
 
1049
                        TRUE,
 
1050
                        G_PARAM_READWRITE |
 
1051
                        G_PARAM_STATIC_STRINGS));
 
1052
 
 
1053
        g_object_class_install_property (
 
1054
                object_class,
 
1055
                PROP_TAB_WIDTH,
 
1056
                g_param_spec_int (
 
1057
                        "tab-width",
 
1058
                        "Tab width",
 
1059
                        "Tab width.",
 
1060
                        -1, G_MAXINT, -1,
 
1061
                        G_PARAM_READWRITE |
 
1062
                        G_PARAM_STATIC_STRINGS));
 
1063
 
 
1064
        g_object_class_install_property (
 
1065
                object_class,
 
1066
                PROP_DOCKING,
 
1067
                g_param_spec_boolean (
 
1068
                        "docking",
 
1069
                        "Docking",
 
1070
                        "Whether the tab should dock to edges when scrolled.",
 
1071
                        FALSE,
 
1072
                        G_PARAM_READWRITE |
 
1073
                        G_PARAM_STATIC_STRINGS));
 
1074
 
 
1075
        g_object_class_install_property (
 
1076
                object_class,
 
1077
                PROP_PREVIEW,
 
1078
                g_param_spec_object (
 
1079
                        "preview",
 
1080
                        "Preview actor",
 
1081
                        "ClutterActor used "
 
1082
                        "when in preview mode.",
 
1083
                        CLUTTER_TYPE_ACTOR,
 
1084
                        G_PARAM_READWRITE |
 
1085
                        G_PARAM_STATIC_STRINGS));
 
1086
 
 
1087
        g_object_class_install_property (
 
1088
                object_class,
 
1089
                PROP_PREVIEW_MODE,
 
1090
                g_param_spec_boolean (
 
1091
                        "preview-mode",
 
1092
                        "Preview mode",
 
1093
                        "Whether to display "
 
1094
                        "in preview mode.",
 
1095
                        FALSE,
 
1096
                        G_PARAM_READWRITE |
 
1097
                        G_PARAM_STATIC_STRINGS));
 
1098
 
 
1099
        g_object_class_install_property (
 
1100
                object_class,
 
1101
                PROP_PREVIEW_DURATION,
 
1102
                g_param_spec_uint (
 
1103
                        "preview-duration",
 
1104
                        "Preview duration",
 
1105
                        "How long the transition "
 
1106
                        "between preview mode "
 
1107
                        "states lasts, in ms.",
 
1108
                        0, G_MAXUINT, 200,
 
1109
                        G_PARAM_READWRITE |
 
1110
                        G_PARAM_STATIC_STRINGS));
 
1111
 
 
1112
        g_object_class_install_property (
 
1113
                object_class,
 
1114
                PROP_SPACING,
 
1115
                g_param_spec_float (
 
1116
                        "spacing",
 
1117
                        "Spacing",
 
1118
                        "Spacing between "
 
1119
                        "tab elements.",
 
1120
                        0, G_MAXFLOAT,
 
1121
                        6.0,
 
1122
                        G_PARAM_READWRITE |
 
1123
                        G_PARAM_STATIC_STRINGS));
 
1124
 
 
1125
        g_object_class_install_property (
 
1126
                object_class,
 
1127
                PROP_PRIVATE,
 
1128
                g_param_spec_boolean (
 
1129
                        "private",
 
1130
                        "Private",
 
1131
                        "Set if the tab is "
 
1132
                        "'private'.",
 
1133
                        FALSE,
 
1134
                        G_PARAM_READWRITE |
 
1135
                        G_PARAM_STATIC_STRINGS));
 
1136
 
 
1137
        g_object_class_install_property (
 
1138
                object_class,
 
1139
                PROP_ACTIVE,
 
1140
                g_param_spec_boolean (
 
1141
                        "active",
 
1142
                        "Active",
 
1143
                        "Set if the tab is "
 
1144
                        "active.",
 
1145
                        FALSE,
 
1146
                        G_PARAM_READWRITE |
 
1147
                        G_PARAM_STATIC_STRINGS));
 
1148
 
 
1149
        g_object_class_override_property (
 
1150
                object_class,
 
1151
                PROP_DRAG_THRESHOLD,
 
1152
                "drag-threshold");
 
1153
 
 
1154
        g_object_class_override_property (
 
1155
                object_class,
 
1156
                PROP_DRAG_AXIS,
 
1157
                "axis");
 
1158
 
 
1159
        g_object_class_override_property (
 
1160
                object_class,
 
1161
                PROP_DRAG_CONTAINMENT_AREA,
 
1162
                "containment-area");
 
1163
 
 
1164
        g_object_class_override_property (
 
1165
                object_class,
 
1166
                PROP_DRAG_ENABLED,
 
1167
                "drag-enabled");
 
1168
 
 
1169
        g_object_class_override_property (
 
1170
                object_class,
 
1171
                PROP_DRAG_ACTOR,
 
1172
                "drag-actor");
 
1173
 
 
1174
        signals[CLICKED] = g_signal_new (
 
1175
                "clicked",
 
1176
                G_TYPE_FROM_CLASS (class),
 
1177
                G_SIGNAL_RUN_LAST,
 
1178
                G_STRUCT_OFFSET (EMailTabClass, clicked),
 
1179
                NULL, NULL,
 
1180
                g_cclosure_marshal_VOID__VOID,
 
1181
                G_TYPE_NONE, 0);
 
1182
 
 
1183
        signals[CLOSED] = g_signal_new (
 
1184
                "closed",
 
1185
                G_TYPE_FROM_CLASS (class),
 
1186
                G_SIGNAL_RUN_LAST,
 
1187
                G_STRUCT_OFFSET (EMailTabClass, closed),
 
1188
                NULL, NULL,
 
1189
                g_cclosure_marshal_VOID__VOID,
 
1190
                G_TYPE_NONE, 0);
 
1191
 
 
1192
        signals[TRANSITION_COMPLETE] = g_signal_new (
 
1193
                "transition-complete",
 
1194
                G_TYPE_FROM_CLASS (class),
 
1195
                G_SIGNAL_RUN_LAST,
 
1196
                G_STRUCT_OFFSET (EMailTabClass, transition_complete),
 
1197
                NULL, NULL,
 
1198
                g_cclosure_marshal_VOID__VOID,
 
1199
                G_TYPE_NONE, 0);
 
1200
}
 
1201
 
 
1202
static void
 
1203
e_mail_tab_close_clicked_cb (MxButton *button,
 
1204
                             EMailTab *self)
 
1205
{
 
1206
        g_signal_emit (self, signals[CLOSED], 0);
1220
1207
}
1221
1208
 
1222
1209
static void
1223
1210
e_mail_tab_anim_completed_cb (ClutterAnimation *animation,
1224
 
                           EMailTab           *tab)
 
1211
                              EMailTab *tab)
1225
1212
{
1226
 
  e_mail_tab_dispose_old_bg (tab);
 
1213
        e_mail_tab_dispose_old_bg (tab);
1227
1214
}
1228
1215
 
1229
1216
static void
1230
1217
e_mail_tab_style_changed_cb (MxWidget *widget)
1231
1218
{
1232
 
  EMailTabPrivate *priv = E_MAIL_TAB (widget)->priv;
1233
 
 
1234
 
  /* Don't transition on hover */
1235
 
  if (g_strcmp0 (mx_stylable_get_style_pseudo_class (MX_STYLABLE (widget)),
1236
 
                                                     "hover") == 0)
1237
 
    return;
1238
 
 
1239
 
  if (priv->old_bg)
1240
 
    {
1241
 
      if (!clutter_actor_get_parent (priv->old_bg))
1242
 
        {
1243
 
          ClutterActorBox box;
1244
 
          ClutterActor *background;
1245
 
          ClutterActor *actor = CLUTTER_ACTOR (widget);
1246
 
 
1247
 
          clutter_actor_set_parent (priv->old_bg, actor);
1248
 
 
1249
 
          /* Try to allocate the same size as the background widget,
1250
 
           * otherwise allocate the same size as the widget itself.
1251
 
           */
1252
 
          background = mx_widget_get_border_image (widget);
1253
 
          if (!background)
1254
 
            background = mx_widget_get_background_image (widget);
1255
 
 
1256
 
          if (background)
1257
 
            clutter_actor_get_allocation_box (background, &box);
1258
 
          else
1259
 
            {
1260
 
              clutter_actor_get_allocation_box (actor, &box);
1261
 
              box.x2 -= box.x1;
1262
 
              box.y2 -= box.y1;
1263
 
              box.x1 = 0;
1264
 
              box.y1 = 0;
1265
 
            }
1266
 
 
1267
 
          clutter_actor_allocate (priv->old_bg, &box, 0);
 
1219
        EMailTabPrivate *priv = E_MAIL_TAB (widget)->priv;
 
1220
 
 
1221
        /* Don't transition on hover */
 
1222
        if (g_strcmp0 (mx_stylable_get_style_pseudo_class (
 
1223
                MX_STYLABLE (widget)), "hover") == 0)
 
1224
                return;
 
1225
 
 
1226
        if (priv->old_bg) {
 
1227
                if (!clutter_actor_get_parent (priv->old_bg)) {
 
1228
                        ClutterActorBox box;
 
1229
                        ClutterActor *background;
 
1230
                        ClutterActor *actor = CLUTTER_ACTOR (widget);
 
1231
 
 
1232
                        clutter_actor_set_parent (priv->old_bg, actor);
 
1233
 
 
1234
                        /* Try to allocate the same size as the background
 
1235
                         * widget, otherwise allocate the same size as the
 
1236
                         * widget itself. */
 
1237
                        background = mx_widget_get_border_image (widget);
 
1238
                        if (!background)
 
1239
                                background = mx_widget_get_background_image (widget);
 
1240
 
 
1241
                        if (background)
 
1242
                                clutter_actor_get_allocation_box (background, &box);
 
1243
                        else {
 
1244
                                clutter_actor_get_allocation_box (actor, &box);
 
1245
                                box.x2 -= box.x1;
 
1246
                                box.y2 -= box.y1;
 
1247
                                box.x1 = 0;
 
1248
                                box.y1 = 0;
 
1249
                        }
 
1250
 
 
1251
                        clutter_actor_allocate (priv->old_bg, &box, 0);
 
1252
                }
 
1253
 
 
1254
                clutter_actor_animate (
 
1255
                        priv->old_bg, CLUTTER_LINEAR, 150,
 
1256
                        "opacity", 0, "signal::completed",
 
1257
                        G_CALLBACK (e_mail_tab_anim_completed_cb),
 
1258
                        widget, NULL);
1268
1259
        }
1269
 
 
1270
 
      clutter_actor_animate (priv->old_bg,
1271
 
                             CLUTTER_LINEAR,
1272
 
                             150,
1273
 
                             "opacity", 0,
1274
 
                             "signal::completed",
1275
 
                               G_CALLBACK (e_mail_tab_anim_completed_cb),
1276
 
                               widget,
1277
 
                             NULL);
1278
 
    }
1279
1260
}
1280
1261
 
1281
1262
static void
1282
1263
e_mail_tab_stylable_changed_cb (MxStylable *stylable)
1283
1264
{
1284
 
  EMailTab *tab = E_MAIL_TAB (stylable);
1285
 
  EMailTabPrivate *priv = tab->priv;
1286
 
 
1287
 
  e_mail_tab_dispose_old_bg (tab);
1288
 
 
1289
 
  priv->old_bg = mx_widget_get_border_image (MX_WIDGET (tab));
1290
 
  if (priv->old_bg)
1291
 
    g_object_ref (priv->old_bg);
 
1265
        EMailTab *tab = E_MAIL_TAB (stylable);
 
1266
        EMailTabPrivate *priv = tab->priv;
 
1267
 
 
1268
        e_mail_tab_dispose_old_bg (tab);
 
1269
 
 
1270
        priv->old_bg = mx_widget_get_border_image (MX_WIDGET (tab));
 
1271
        if (priv->old_bg)
 
1272
                g_object_ref (priv->old_bg);
1292
1273
}
1293
1274
 
1294
1275
static void
1295
 
e_mail_tab_dnd_notify_cb (GObject    *settings,
1296
 
                       GParamSpec *pspec,
1297
 
                       EMailTab     *tab)
 
1276
e_mail_tab_dnd_notify_cb (GObject *settings,
 
1277
                          GParamSpec *pspec,
 
1278
                          EMailTab *tab)
1298
1279
{
1299
 
  g_object_get (settings,
1300
 
                "gtk-dnd-drag-threshold", &tab->priv->drag_threshold,
 
1280
        g_object_get (
 
1281
                settings,
 
1282
                "gtk-dnd-drag-threshold", &tab->priv->drag_threshold,
1301
1283
                NULL);
1302
1284
}
1303
1285
 
1304
1286
static void
1305
1287
e_mail_tab_init (EMailTab *self)
1306
1288
{
1307
 
  ClutterActor *text;
1308
 
  GtkSettings *settings;
1309
 
  EMailTabPrivate *priv;
 
1289
        ClutterActor *text;
 
1290
        GtkSettings *settings;
 
1291
        EMailTabPrivate *priv;
1310
1292
 
1311
 
  priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (
 
1293
        priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (
1312
1294
        self, E_MAIL_TYPE_TAB, EMailTabPrivate);
1313
1295
 
1314
 
  priv->width = -1;
1315
 
  priv->anim_length = 200;
1316
 
  priv->spacing = 6.0;
1317
 
  priv->can_close = TRUE;
1318
 
 
1319
 
  priv->label = mx_label_new ();
1320
 
  g_object_set (G_OBJECT (priv->label), "clip-to-allocation", TRUE, NULL);
1321
 
  text = mx_label_get_clutter_text (MX_LABEL (priv->label));
1322
 
  clutter_text_set_ellipsize (CLUTTER_TEXT (text), PANGO_ELLIPSIZE_END);
1323
 
  clutter_actor_set_parent (CLUTTER_ACTOR (priv->label),
1324
 
                            CLUTTER_ACTOR (self));
1325
 
 
1326
 
  priv->close_button = mx_button_new ();
1327
 
  clutter_actor_set_name (CLUTTER_ACTOR (priv->close_button),
1328
 
                          "tab-close-button");
1329
 
  clutter_actor_set_parent (CLUTTER_ACTOR (priv->close_button),
1330
 
                            CLUTTER_ACTOR (self));
1331
 
 
1332
 
  g_signal_connect (priv->close_button, "clicked",
1333
 
                    G_CALLBACK (e_mail_tab_close_clicked_cb), self);
1334
 
 
1335
 
  /* Connect up styling signals */
1336
 
  g_signal_connect (self, "style-changed",
1337
 
                    G_CALLBACK (e_mail_tab_style_changed_cb), NULL);
1338
 
  g_signal_connect (self, "stylable-changed",
1339
 
                    G_CALLBACK (e_mail_tab_stylable_changed_cb), NULL);
1340
 
 
1341
 
  clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
1342
 
 
1343
 
  settings = gtk_settings_get_default ();
1344
 
  priv->drag_threshold_handler =
1345
 
    g_signal_connect (settings, "notify::gtk-dnd-drag-threshold",
1346
 
                      G_CALLBACK (e_mail_tab_dnd_notify_cb), self);
1347
 
  g_object_get (G_OBJECT (settings),
1348
 
                "gtk-dnd-drag-threshold", &priv->drag_threshold,
 
1296
        priv->width = -1;
 
1297
        priv->anim_length = 200;
 
1298
        priv->spacing = 6.0;
 
1299
        priv->can_close = TRUE;
 
1300
 
 
1301
        priv->label = mx_label_new ();
 
1302
        g_object_set (priv->label, "clip-to-allocation", TRUE, NULL);
 
1303
        text = mx_label_get_clutter_text (MX_LABEL (priv->label));
 
1304
        clutter_text_set_ellipsize (CLUTTER_TEXT (text), PANGO_ELLIPSIZE_END);
 
1305
        clutter_actor_set_parent (
 
1306
                CLUTTER_ACTOR (priv->label), CLUTTER_ACTOR (self));
 
1307
 
 
1308
        priv->close_button = mx_button_new ();
 
1309
        clutter_actor_set_name (
 
1310
                CLUTTER_ACTOR (priv->close_button), "tab-close-button");
 
1311
        clutter_actor_set_parent (
 
1312
                CLUTTER_ACTOR (priv->close_button), CLUTTER_ACTOR (self));
 
1313
 
 
1314
        g_signal_connect (
 
1315
                priv->close_button, "clicked",
 
1316
                G_CALLBACK (e_mail_tab_close_clicked_cb), self);
 
1317
 
 
1318
        /* Connect up styling signals */
 
1319
        g_signal_connect (
 
1320
                self, "style-changed",
 
1321
                G_CALLBACK (e_mail_tab_style_changed_cb), NULL);
 
1322
        g_signal_connect (
 
1323
                self, "stylable-changed",
 
1324
                G_CALLBACK (e_mail_tab_stylable_changed_cb), NULL);
 
1325
 
 
1326
        clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
 
1327
 
 
1328
        settings = gtk_settings_get_default ();
 
1329
        priv->drag_threshold_handler = g_signal_connect (
 
1330
                settings, "notify::gtk-dnd-drag-threshold",
 
1331
                G_CALLBACK (e_mail_tab_dnd_notify_cb), self);
 
1332
        g_object_get (
 
1333
                G_OBJECT (settings),
 
1334
                "gtk-dnd-drag-threshold", &priv->drag_threshold,
1349
1335
                NULL);
1350
1336
}
1351
1337
 
1352
1338
ClutterActor *
1353
1339
e_mail_tab_new (void)
1354
1340
{
1355
 
  return g_object_new (E_MAIL_TYPE_TAB, NULL);
 
1341
        return g_object_new (E_MAIL_TYPE_TAB, NULL);
1356
1342
}
1357
1343
 
1358
1344
ClutterActor *
1359
 
e_mail_tab_new_full (const gchar *text, ClutterActor *icon, gint width)
1360
 
{
1361
 
  return g_object_new (E_MAIL_TYPE_TAB,
1362
 
                       "text", text,
1363
 
                       "icon", icon,
1364
 
                       "tab-width", width, NULL);
1365
 
}
1366
 
 
1367
 
void
1368
 
e_mail_tab_set_text (EMailTab *tab, const gchar *text)
1369
 
{
1370
 
  EMailTabPrivate *priv = tab->priv;
1371
 
 
1372
 
  if (!text)
1373
 
    text = "";
1374
 
 
1375
 
  priv->has_text = (text[0] != '\0');
1376
 
 
1377
 
  if (priv->label)
1378
 
    mx_label_set_text (MX_LABEL (priv->label), text);
1379
 
 
1380
 
  g_object_notify (G_OBJECT (tab), "text");
1381
 
}
1382
 
 
1383
 
void
1384
 
e_mail_tab_set_default_icon (EMailTab       *tab,
1385
 
                          ClutterActor *icon)
1386
 
{
1387
 
  EMailTabPrivate *priv = tab->priv;
1388
 
  gboolean changed = !priv->icon || (priv->icon == priv->default_icon);
1389
 
 
1390
 
  if (icon)
1391
 
    g_object_ref_sink (icon);
1392
 
 
1393
 
  if (priv->default_icon)
1394
 
    g_object_unref (priv->default_icon);
1395
 
 
1396
 
  priv->default_icon = icon;
1397
 
 
1398
 
  if (changed)
1399
 
    e_mail_tab_set_icon (tab, NULL);
1400
 
}
1401
 
 
1402
 
void
1403
 
e_mail_tab_set_icon (EMailTab *tab, ClutterActor *icon)
1404
 
{
1405
 
  EMailTabPrivate *priv = tab->priv;
1406
 
 
1407
 
  /* passing NULL for icon will use default icon if available */
1408
 
 
1409
 
  if (priv->icon)
1410
 
    clutter_actor_unparent (priv->icon);
1411
 
 
1412
 
  if (icon)
1413
 
    priv->icon = icon;
1414
 
  else
1415
 
    priv->icon = priv->default_icon;
1416
 
 
1417
 
  if (priv->icon)
1418
 
    {
1419
 
      clutter_actor_set_parent (priv->icon, CLUTTER_ACTOR (tab));
1420
 
    }
1421
 
 
1422
 
  clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1423
 
 
1424
 
  g_object_notify (G_OBJECT (tab), "icon");
 
1345
e_mail_tab_new_full (const gchar *text,
 
1346
                     ClutterActor *icon,
 
1347
                     gint width)
 
1348
{
 
1349
        return g_object_new (
 
1350
                E_MAIL_TYPE_TAB,
 
1351
                "text", text,
 
1352
                "icon", icon,
 
1353
                "tab-width", width,
 
1354
                NULL);
 
1355
}
 
1356
 
 
1357
void
 
1358
e_mail_tab_set_text (EMailTab *tab,
 
1359
                     const gchar *text)
 
1360
{
 
1361
        EMailTabPrivate *priv = tab->priv;
 
1362
 
 
1363
        if (!text)
 
1364
                text = "";
 
1365
 
 
1366
        priv->has_text = (text[0] != '\0');
 
1367
 
 
1368
        if (priv->label)
 
1369
                mx_label_set_text (MX_LABEL (priv->label), text);
 
1370
 
 
1371
        g_object_notify (G_OBJECT (tab), "text");
 
1372
}
 
1373
 
 
1374
void
 
1375
e_mail_tab_set_default_icon (EMailTab *tab,
 
1376
                             ClutterActor *icon)
 
1377
{
 
1378
        EMailTabPrivate *priv = tab->priv;
 
1379
        gboolean changed = !priv->icon || (priv->icon == priv->default_icon);
 
1380
 
 
1381
        if (icon)
 
1382
                g_object_ref_sink (icon);
 
1383
 
 
1384
        if (priv->default_icon)
 
1385
                g_object_unref (priv->default_icon);
 
1386
 
 
1387
        priv->default_icon = icon;
 
1388
 
 
1389
        if (changed)
 
1390
                e_mail_tab_set_icon (tab, NULL);
 
1391
}
 
1392
 
 
1393
void
 
1394
e_mail_tab_set_icon (EMailTab *tab,
 
1395
                     ClutterActor *icon)
 
1396
{
 
1397
        EMailTabPrivate *priv = tab->priv;
 
1398
 
 
1399
        /* passing NULL for icon will use default icon if available */
 
1400
 
 
1401
        if (priv->icon)
 
1402
                clutter_actor_unparent (priv->icon);
 
1403
 
 
1404
        if (icon)
 
1405
                priv->icon = icon;
 
1406
        else
 
1407
                priv->icon = priv->default_icon;
 
1408
 
 
1409
        if (priv->icon)
 
1410
                clutter_actor_set_parent (priv->icon, CLUTTER_ACTOR (tab));
 
1411
 
 
1412
        clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1413
 
 
1414
        g_object_notify (G_OBJECT (tab), "icon");
1425
1415
}
1426
1416
 
1427
1417
const gchar *
1428
1418
e_mail_tab_get_text (EMailTab *tab)
1429
1419
{
1430
 
  EMailTabPrivate *priv = tab->priv;
 
1420
        EMailTabPrivate *priv = tab->priv;
1431
1421
 
1432
 
  if (priv->label)
1433
 
    return mx_label_get_text (MX_LABEL (priv->label));
1434
 
  else
1435
 
    return NULL;
 
1422
        if (priv->label)
 
1423
                return mx_label_get_text (MX_LABEL (priv->label));
 
1424
        else
 
1425
                return NULL;
1436
1426
}
1437
1427
 
1438
1428
ClutterActor *
1439
1429
e_mail_tab_get_icon (EMailTab *tab)
1440
1430
{
1441
 
  EMailTabPrivate *priv = tab->priv;
1442
 
  return priv->icon == priv->default_icon ? NULL : priv->icon;
 
1431
        EMailTabPrivate *priv = tab->priv;
 
1432
        return priv->icon == priv->default_icon ? NULL : priv->icon;
1443
1433
}
1444
1434
 
1445
1435
void
1446
 
e_mail_tab_set_can_close (EMailTab *tab, gboolean can_close)
 
1436
e_mail_tab_set_can_close (EMailTab *tab,
 
1437
                          gboolean can_close)
1447
1438
{
1448
 
  EMailTabPrivate *priv = tab->priv;
1449
 
 
1450
 
  if (priv->can_close == can_close)
1451
 
    return;
1452
 
 
1453
 
  priv->can_close = can_close;
1454
 
 
1455
 
  clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1456
 
 
1457
 
  g_object_notify (G_OBJECT (tab), "can-close");
 
1439
        EMailTabPrivate *priv = tab->priv;
 
1440
 
 
1441
        if (priv->can_close == can_close)
 
1442
                return;
 
1443
 
 
1444
        priv->can_close = can_close;
 
1445
 
 
1446
        clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1447
 
 
1448
        g_object_notify (G_OBJECT (tab), "can-close");
1458
1449
}
1459
1450
 
1460
1451
gboolean
1461
1452
e_mail_tab_get_can_close (EMailTab *tab)
1462
1453
{
1463
 
  return tab->priv->can_close;
 
1454
        return tab->priv->can_close;
1464
1455
}
1465
1456
 
1466
1457
void
1467
1458
e_mail_tab_set_width (EMailTab *tab,
1468
 
                   gint    width)
 
1459
                      gint width)
1469
1460
{
1470
 
  EMailTabPrivate *priv = tab->priv;
1471
 
 
1472
 
  if (priv->width == width)
1473
 
    return;
1474
 
 
1475
 
  priv->width = width;
1476
 
 
1477
 
  clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1478
 
 
1479
 
  g_object_notify (G_OBJECT (tab), "tab-width");
 
1461
        EMailTabPrivate *priv = tab->priv;
 
1462
 
 
1463
        if (priv->width == width)
 
1464
                return;
 
1465
 
 
1466
        priv->width = width;
 
1467
 
 
1468
        clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1469
 
 
1470
        g_object_notify (G_OBJECT (tab), "tab-width");
1480
1471
}
1481
1472
 
1482
1473
gint
1483
1474
e_mail_tab_get_width (EMailTab *tab)
1484
1475
{
1485
 
  EMailTabPrivate *priv = tab->priv;
1486
 
  return priv->width;
 
1476
        EMailTabPrivate *priv = tab->priv;
 
1477
        return priv->width;
1487
1478
}
1488
1479
 
1489
1480
void
1490
 
e_mail_tab_set_docking (EMailTab   *tab,
1491
 
                     gboolean  docking)
 
1481
e_mail_tab_set_docking (EMailTab *tab,
 
1482
                        gboolean docking)
1492
1483
{
1493
 
  EMailTabPrivate *priv = tab->priv;
1494
 
 
1495
 
  if (priv->docking == docking)
1496
 
    return;
1497
 
 
1498
 
  priv->docking = docking;
1499
 
 
1500
 
  clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1501
 
 
1502
 
  g_object_notify (G_OBJECT (tab), "docking");
 
1484
        EMailTabPrivate *priv = tab->priv;
 
1485
 
 
1486
        if (priv->docking == docking)
 
1487
                return;
 
1488
 
 
1489
        priv->docking = docking;
 
1490
 
 
1491
        clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1492
 
 
1493
        g_object_notify (G_OBJECT (tab), "docking");
1503
1494
}
1504
1495
 
1505
1496
gboolean
1506
1497
e_mail_tab_get_docking (EMailTab *tab)
1507
1498
{
1508
 
  EMailTabPrivate *priv = tab->priv;
1509
 
  return priv->docking;
 
1499
        EMailTabPrivate *priv = tab->priv;
 
1500
        return priv->docking;
1510
1501
}
1511
1502
 
1512
1503
void
1513
 
e_mail_tab_set_preview_actor (EMailTab *tab, ClutterActor *actor)
 
1504
e_mail_tab_set_preview_actor (EMailTab *tab,
 
1505
                              ClutterActor *actor)
1514
1506
{
1515
 
  EMailTabPrivate *priv = tab->priv;
1516
 
 
1517
 
  if (priv->preview)
1518
 
    clutter_actor_unparent (priv->preview);
1519
 
 
1520
 
  priv->preview = actor;
1521
 
 
1522
 
  if (actor)
1523
 
    {
1524
 
      clutter_actor_set_parent (actor, CLUTTER_ACTOR (tab));
1525
 
 
1526
 
      clutter_actor_set_opacity (actor, priv->preview_mode ? 0xff : 0x00);
1527
 
      if (!priv->preview_mode)
1528
 
        clutter_actor_hide (actor);
1529
 
    }
1530
 
 
1531
 
  clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1532
 
 
1533
 
  g_object_notify (G_OBJECT (tab), "preview");
 
1507
        EMailTabPrivate *priv = tab->priv;
 
1508
 
 
1509
        if (priv->preview)
 
1510
                clutter_actor_unparent (priv->preview);
 
1511
 
 
1512
        priv->preview = actor;
 
1513
 
 
1514
        if (actor) {
 
1515
                clutter_actor_set_parent (actor, CLUTTER_ACTOR (tab));
 
1516
 
 
1517
                clutter_actor_set_opacity (
 
1518
                        actor, priv->preview_mode ? 0xff : 0x00);
 
1519
                if (!priv->preview_mode)
 
1520
                        clutter_actor_hide (actor);
 
1521
        }
 
1522
 
 
1523
        clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1524
 
 
1525
        g_object_notify (G_OBJECT (tab), "preview");
1534
1526
}
1535
1527
 
1536
1528
ClutterActor *
1537
1529
e_mail_tab_get_preview_actor (EMailTab *tab)
1538
1530
{
1539
 
  EMailTabPrivate *priv = tab->priv;
1540
 
  return priv->preview;
 
1531
        EMailTabPrivate *priv = tab->priv;
 
1532
        return priv->preview;
1541
1533
}
1542
1534
 
1543
1535
static void
1544
1536
preview_new_frame_cb (ClutterTimeline *timeline,
1545
 
                      guint            msecs,
1546
 
                      EMailTab          *tab)
 
1537
                      guint msecs,
 
1538
                      EMailTab *tab)
1547
1539
{
1548
 
  gboolean forwards;
1549
 
  EMailTabPrivate *priv = tab->priv;
1550
 
 
1551
 
  forwards = (clutter_timeline_get_direction (timeline) ==
1552
 
               CLUTTER_TIMELINE_FORWARD) ? TRUE : FALSE;
1553
 
  if (priv->preview_mode)
1554
 
    forwards = !forwards;
1555
 
 
1556
 
  priv->preview_height_progress = clutter_timeline_get_progress (timeline);
1557
 
  if (forwards)
1558
 
    priv->preview_height_progress = 1.0 - priv->preview_height_progress;
1559
 
 
1560
 
  if (priv->preview)
1561
 
    clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1540
        gboolean forwards;
 
1541
        EMailTabPrivate *priv = tab->priv;
 
1542
 
 
1543
        forwards =
 
1544
                (clutter_timeline_get_direction (timeline) ==
 
1545
                 CLUTTER_TIMELINE_FORWARD);
 
1546
        if (priv->preview_mode)
 
1547
                forwards = !forwards;
 
1548
 
 
1549
        priv->preview_height_progress =
 
1550
                clutter_timeline_get_progress (timeline);
 
1551
        if (forwards)
 
1552
                priv->preview_height_progress =
 
1553
                        1.0 - priv->preview_height_progress;
 
1554
 
 
1555
        if (priv->preview)
 
1556
                clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1562
1557
}
1563
1558
 
1564
1559
static void
1565
1560
preview_completed_cb (ClutterTimeline *timeline,
1566
 
                      EMailTab          *tab)
 
1561
                      EMailTab *tab)
1567
1562
{
1568
 
  EMailTabPrivate *priv = tab->priv;
1569
 
 
1570
 
  if (priv->preview_timeline)
1571
 
    {
1572
 
      clutter_timeline_stop (priv->preview_timeline);
1573
 
      g_object_unref (priv->preview_timeline);
1574
 
      priv->preview_timeline = NULL;
1575
 
 
1576
 
      if (priv->preview_mode)
1577
 
        priv->preview_height_progress = 1.0;
1578
 
      else
1579
 
        {
1580
 
          priv->preview_height_progress = 0.0;
1581
 
          if (priv->preview)
1582
 
            clutter_actor_hide (priv->preview);
1583
 
          if (priv->can_close)
1584
 
            clutter_actor_set_reactive (CLUTTER_ACTOR (priv->close_button),
 
1563
        EMailTabPrivate *priv = tab->priv;
 
1564
 
 
1565
        if (priv->preview_timeline) {
 
1566
                clutter_timeline_stop (priv->preview_timeline);
 
1567
                g_object_unref (priv->preview_timeline);
 
1568
                priv->preview_timeline = NULL;
 
1569
 
 
1570
                if (priv->preview_mode)
 
1571
                        priv->preview_height_progress = 1.0;
 
1572
                else {
 
1573
                        priv->preview_height_progress = 0.0;
 
1574
                        if (priv->preview)
 
1575
                                clutter_actor_hide (priv->preview);
 
1576
                        if (priv->can_close)
 
1577
                                clutter_actor_set_reactive (
 
1578
                                        CLUTTER_ACTOR (priv->close_button),
1585
1579
                                        TRUE);
1586
 
        }
1587
 
 
1588
 
      /* Remove style hint if we're not in preview mode */
1589
 
      if (priv->preview)
1590
 
        {
1591
 
          if (!priv->preview_mode)
1592
 
            clutter_actor_set_name (CLUTTER_ACTOR (tab),
1593
 
                                    priv->private ? "private-tab" : NULL);
1594
 
        }
1595
 
      else
1596
 
        {
1597
 
          /* If there's no preview actor, disable the tab */
1598
 
          clutter_actor_set_reactive (CLUTTER_ACTOR (tab), !priv->preview_mode);
1599
 
        }
1600
 
 
1601
 
      if (priv->preview)
1602
 
        clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1603
 
 
1604
 
      g_signal_emit (tab, signals[TRANSITION_COMPLETE], 0);
1605
 
    }
 
1580
                }
 
1581
 
 
1582
                /* Remove style hint if we're not in preview mode */
 
1583
                if (priv->preview) {
 
1584
                        if (!priv->preview_mode)
 
1585
                                clutter_actor_set_name (
 
1586
                                        CLUTTER_ACTOR (tab),
 
1587
                                        priv->private ? "private-tab" : NULL);
 
1588
                } else {
 
1589
                        /* If there's no preview actor, disable the tab */
 
1590
                        clutter_actor_set_reactive (
 
1591
                                CLUTTER_ACTOR (tab), !priv->preview_mode);
 
1592
                }
 
1593
 
 
1594
                if (priv->preview)
 
1595
                        clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1596
 
 
1597
                g_signal_emit (tab, signals[TRANSITION_COMPLETE], 0);
 
1598
        }
1606
1599
}
1607
1600
 
1608
1601
static void
1609
1602
preview_s1_started_cb (ClutterTimeline *timeline,
1610
 
                       EMailTab          *tab)
 
1603
                       EMailTab *tab)
1611
1604
{
1612
 
  EMailTabPrivate *priv = tab->priv;
 
1605
        EMailTabPrivate *priv = tab->priv;
1613
1606
 
1614
 
  if (!priv->preview)
1615
 
    clutter_actor_animate_with_timeline (CLUTTER_ACTOR (priv->label),
1616
 
                                         CLUTTER_EASE_IN_OUT_QUAD,
1617
 
                                         timeline,
1618
 
                                         "opacity", 0xff,
1619
 
                                         NULL);
 
1607
        if (!priv->preview)
 
1608
                clutter_actor_animate_with_timeline (
 
1609
                        CLUTTER_ACTOR (priv->label),
 
1610
                        CLUTTER_EASE_IN_OUT_QUAD,
 
1611
                        timeline,
 
1612
                        "opacity", 0xff,
 
1613
                        NULL);
1620
1614
}
1621
1615
 
1622
1616
static void
1623
1617
preview_s2_started_cb (ClutterTimeline *timeline,
1624
 
                       EMailTab          *tab)
 
1618
                       EMailTab *tab)
1625
1619
{
1626
 
  EMailTabPrivate *priv = tab->priv;
 
1620
        EMailTabPrivate *priv = tab->priv;
1627
1621
 
1628
 
  if (priv->preview)
1629
 
    clutter_actor_animate_with_timeline (CLUTTER_ACTOR (priv->label),
1630
 
                                         CLUTTER_EASE_IN_OUT_QUAD,
1631
 
                                         timeline,
1632
 
                                         "opacity", 0xff,
1633
 
                                         NULL);
 
1622
        if (priv->preview)
 
1623
                clutter_actor_animate_with_timeline (
 
1624
                        CLUTTER_ACTOR (priv->label),
 
1625
                        CLUTTER_EASE_IN_OUT_QUAD,
 
1626
                        timeline,
 
1627
                        "opacity", 0xff,
 
1628
                        NULL);
1634
1629
}
1635
1630
 
1636
1631
void
1637
 
e_mail_tab_set_preview_mode (EMailTab *tab, gboolean preview)
 
1632
e_mail_tab_set_preview_mode (EMailTab *tab,
 
1633
                             gboolean preview)
1638
1634
{
1639
 
  EMailTabPrivate *priv = tab->priv;
1640
 
 
1641
 
  if (priv->preview_mode != preview)
1642
 
    {
1643
 
      ClutterTimeline *timeline, *timeline2;
1644
 
      gdouble progress, total_duration, duration1, duration2;
1645
 
 
1646
 
      priv->preview_mode = preview;
1647
 
 
1648
 
      /* Disable the close button in preview mode */
1649
 
      if (preview && priv->can_close)
1650
 
        clutter_actor_set_reactive (CLUTTER_ACTOR (priv->close_button), FALSE);
 
1635
        EMailTabPrivate *priv = tab->priv;
 
1636
 
 
1637
        if (priv->preview_mode != preview) {
 
1638
                ClutterTimeline *timeline, *timeline2;
 
1639
                gdouble progress, total_duration, duration1, duration2;
 
1640
 
 
1641
                priv->preview_mode = preview;
 
1642
 
 
1643
                /* Disable the close button in preview mode */
 
1644
                if (preview && priv->can_close)
 
1645
                        clutter_actor_set_reactive (CLUTTER_ACTOR (priv->close_button), FALSE);
1651
1646
 
1652
1647
#define DEBUG_MULT 1
1653
 
      if (priv->preview_timeline)
1654
 
        {
1655
 
          progress = 1.0 -
1656
 
                     clutter_timeline_get_progress (priv->preview_timeline);
1657
 
          clutter_timeline_stop (priv->preview_timeline);
1658
 
          g_object_unref (priv->preview_timeline);
1659
 
        }
1660
 
      else
1661
 
        progress = 0.0;
1662
 
 
1663
 
      total_duration = priv->anim_length * (1.0 - progress) * DEBUG_MULT;
1664
 
      duration1 = total_duration * TAB_S1_ANIM;
1665
 
      duration2 = total_duration * TAB_S2_ANIM;
1666
 
 
1667
 
      priv->preview_timeline =
1668
 
        clutter_timeline_new (priv->anim_length * DEBUG_MULT);
1669
 
      clutter_timeline_skip (priv->preview_timeline,
1670
 
        clutter_timeline_get_duration (priv->preview_timeline) * progress);
1671
 
 
1672
 
      g_signal_connect (priv->preview_timeline, "completed",
 
1648
                if (priv->preview_timeline) {
 
1649
                        progress = 1.0 - clutter_timeline_get_progress (
 
1650
                                priv->preview_timeline);
 
1651
                        clutter_timeline_stop (priv->preview_timeline);
 
1652
                        g_object_unref (priv->preview_timeline);
 
1653
                } else
 
1654
                        progress = 0.0;
 
1655
 
 
1656
                total_duration = priv->anim_length * (1.0 - progress) * DEBUG_MULT;
 
1657
                duration1 = total_duration * TAB_S1_ANIM;
 
1658
                duration2 = total_duration * TAB_S2_ANIM;
 
1659
 
 
1660
                priv->preview_timeline =
 
1661
                        clutter_timeline_new (priv->anim_length * DEBUG_MULT);
 
1662
                clutter_timeline_skip (
 
1663
                        priv->preview_timeline, clutter_timeline_get_duration (
 
1664
                        priv->preview_timeline) * progress);
 
1665
 
 
1666
                g_signal_connect (
 
1667
                        priv->preview_timeline, "completed",
1673
1668
                        G_CALLBACK (preview_completed_cb), tab);
1674
1669
 
1675
 
      clutter_timeline_start (priv->preview_timeline);
1676
 
 
1677
 
      if (!priv->preview)
1678
 
        {
1679
 
          clutter_actor_animate_with_timeline (CLUTTER_ACTOR (tab),
1680
 
                                               CLUTTER_EASE_IN_OUT_QUAD,
1681
 
                                               priv->preview_timeline,
1682
 
                                               "opacity", preview ? 0x00 : 0xff,
1683
 
                                               NULL);
1684
 
          return;
1685
 
        }
1686
 
 
1687
 
      g_signal_connect (priv->preview_timeline, "new-frame",
 
1670
                clutter_timeline_start (priv->preview_timeline);
 
1671
 
 
1672
                if (!priv->preview) {
 
1673
                        clutter_actor_animate_with_timeline (
 
1674
                                CLUTTER_ACTOR (tab),
 
1675
                                CLUTTER_EASE_IN_OUT_QUAD,
 
1676
                                priv->preview_timeline,
 
1677
                                "opacity", preview ? 0x00 : 0xff,
 
1678
                                NULL);
 
1679
                        return;
 
1680
                }
 
1681
 
 
1682
                g_signal_connect (
 
1683
                        priv->preview_timeline, "new-frame",
1688
1684
                        G_CALLBACK (preview_new_frame_cb), tab);
1689
1685
 
1690
 
      timeline = clutter_timeline_new ((guint) duration1);
1691
 
      timeline2 = clutter_timeline_new ((guint) duration2);
 
1686
                timeline = clutter_timeline_new ((guint) duration1);
 
1687
                timeline2 = clutter_timeline_new ((guint) duration2);
1692
1688
 
1693
 
      g_signal_connect (timeline, "started",
 
1689
                g_signal_connect (
 
1690
                        timeline, "started",
1694
1691
                        G_CALLBACK (preview_s1_started_cb), tab);
1695
 
      g_signal_connect (timeline2, "started",
 
1692
                g_signal_connect (
 
1693
                        timeline2, "started",
1696
1694
                        G_CALLBACK (preview_s2_started_cb), tab);
1697
1695
 
1698
 
      if (preview)
1699
 
        clutter_timeline_set_delay (timeline2, duration1);
1700
 
      else
1701
 
        clutter_timeline_set_delay (timeline, duration2);
1702
 
 
1703
 
      /* clutter_actor_animate_with_timeline will start the timelines */
1704
 
      clutter_actor_animate_with_timeline (CLUTTER_ACTOR (priv->label),
1705
 
                                           CLUTTER_EASE_IN_OUT_QUAD,
1706
 
                                           preview ? timeline : timeline2,
1707
 
                                           "opacity", 0x00,
1708
 
                                           NULL);
1709
 
      if (priv->icon)
1710
 
        clutter_actor_animate_with_timeline (priv->icon,
1711
 
                                             CLUTTER_EASE_IN_OUT_QUAD,
1712
 
                                             timeline,
1713
 
                                             "opacity", preview ? 0x00 : 0xff,
1714
 
                                             NULL);
1715
 
      if (priv->can_close)
1716
 
        clutter_actor_animate_with_timeline (CLUTTER_ACTOR (priv->close_button),
1717
 
                                             CLUTTER_EASE_IN_OUT_QUAD,
1718
 
                                             timeline,
1719
 
                                             "opacity", preview ? 0x00 : 0xff,
1720
 
                                             NULL);
1721
 
 
1722
 
      if (priv->preview)
1723
 
        {
1724
 
          clutter_actor_show (priv->preview);
1725
 
          clutter_actor_animate_with_timeline (priv->preview,
1726
 
                                               CLUTTER_EASE_IN_OUT_QUAD,
1727
 
                                               timeline2,
1728
 
                                               "opacity", preview ? 0xff : 0x00,
1729
 
                                               NULL);
 
1696
                if (preview)
 
1697
                        clutter_timeline_set_delay (timeline2, duration1);
 
1698
                else
 
1699
                        clutter_timeline_set_delay (timeline, duration2);
 
1700
 
 
1701
                /* clutter_actor_animate_with_timeline will start the timelines */
 
1702
                clutter_actor_animate_with_timeline (
 
1703
                        CLUTTER_ACTOR (priv->label),
 
1704
                        CLUTTER_EASE_IN_OUT_QUAD,
 
1705
                        preview ? timeline : timeline2,
 
1706
                        "opacity", 0x00, NULL);
 
1707
 
 
1708
                if (priv->icon)
 
1709
                        clutter_actor_animate_with_timeline (
 
1710
                                priv->icon,
 
1711
                                CLUTTER_EASE_IN_OUT_QUAD,
 
1712
                                timeline,
 
1713
                                "opacity", preview ? 0x00 : 0xff,
 
1714
                                NULL);
 
1715
 
 
1716
                if (priv->can_close)
 
1717
                        clutter_actor_animate_with_timeline (
 
1718
                                CLUTTER_ACTOR (priv->close_button),
 
1719
                                CLUTTER_EASE_IN_OUT_QUAD,
 
1720
                                timeline,
 
1721
                                "opacity", preview ? 0x00 : 0xff,
 
1722
                                NULL);
 
1723
 
 
1724
                if (priv->preview)
 
1725
                        clutter_actor_show (priv->preview);
 
1726
                        clutter_actor_animate_with_timeline (
 
1727
                                priv->preview,
 
1728
                                CLUTTER_EASE_IN_OUT_QUAD,
 
1729
                                timeline2,
 
1730
                                "opacity", preview ? 0xff : 0x00,
 
1731
                                NULL);
 
1732
 
 
1733
                /* The animations have references on these, drop ours */
 
1734
                g_object_unref (timeline);
 
1735
                g_object_unref (timeline2);
 
1736
 
 
1737
                /* Add an actor name, for style */
 
1738
                clutter_actor_set_name (
 
1739
                        CLUTTER_ACTOR (tab),
 
1740
                        priv->private ? "private-preview-tab" :
 
1741
                        "preview-tab");
1730
1742
        }
1731
 
 
1732
 
      /* The animations have references on these, drop ours */
1733
 
      g_object_unref (timeline);
1734
 
      g_object_unref (timeline2);
1735
 
 
1736
 
      /* Add an actor name, for style */
1737
 
      clutter_actor_set_name (CLUTTER_ACTOR (tab),
1738
 
                              priv->private ? "private-preview-tab" :
1739
 
                                              "preview-tab");
1740
 
    }
1741
1743
}
1742
1744
 
1743
1745
gboolean
1744
1746
e_mail_tab_get_preview_mode (EMailTab *tab)
1745
1747
{
1746
 
  EMailTabPrivate *priv = tab->priv;
1747
 
  return priv->preview_mode;
 
1748
        EMailTabPrivate *priv = tab->priv;
 
1749
        return priv->preview_mode;
1748
1750
}
1749
1751
 
1750
1752
void
1751
 
e_mail_tab_set_preview_duration (EMailTab *tab, guint duration)
 
1753
e_mail_tab_set_preview_duration (EMailTab *tab,
 
1754
                                 guint duration)
1752
1755
{
1753
 
  EMailTabPrivate *priv = tab->priv;
 
1756
        EMailTabPrivate *priv = tab->priv;
1754
1757
 
1755
 
  if (priv->anim_length != duration)
1756
 
    {
1757
 
      priv->anim_length = duration;
1758
 
      g_object_notify (G_OBJECT (tab), "preview-duration");
1759
 
    }
 
1758
        if (priv->anim_length != duration) {
 
1759
                priv->anim_length = duration;
 
1760
                g_object_notify (G_OBJECT (tab), "preview-duration");
 
1761
        }
1760
1762
}
1761
1763
 
1762
1764
guint
1763
1765
e_mail_tab_get_preview_duration (EMailTab *tab)
1764
1766
{
1765
 
  EMailTabPrivate *priv = tab->priv;
1766
 
  return priv->anim_length;
 
1767
        EMailTabPrivate *priv = tab->priv;
 
1768
        return priv->anim_length;
1767
1769
}
1768
1770
 
1769
1771
void
1770
 
e_mail_tab_set_spacing (EMailTab *tab, gfloat spacing)
 
1772
e_mail_tab_set_spacing (EMailTab *tab,
 
1773
                        gfloat spacing)
1771
1774
{
1772
 
  EMailTabPrivate *priv = tab->priv;
 
1775
        EMailTabPrivate *priv = tab->priv;
1773
1776
 
1774
 
  if (priv->spacing != spacing)
1775
 
    {
1776
 
      priv->spacing = spacing;
1777
 
      g_object_notify (G_OBJECT (tab), "spacing");
1778
 
      clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
1779
 
    }
 
1777
        if (priv->spacing != spacing) {
 
1778
                priv->spacing = spacing;
 
1779
                g_object_notify (G_OBJECT (tab), "spacing");
 
1780
                clutter_actor_queue_relayout (CLUTTER_ACTOR (tab));
 
1781
        }
1780
1782
}
1781
1783
 
1782
1784
gfloat
1783
1785
e_mail_tab_get_spacing (EMailTab *tab)
1784
1786
{
1785
 
  EMailTabPrivate *priv = tab->priv;
1786
 
  return priv->spacing;
 
1787
        EMailTabPrivate *priv = tab->priv;
 
1788
        return priv->spacing;
1787
1789
}
1788
1790
 
1789
1791
void
1790
 
e_mail_tab_set_private (EMailTab *tab, gboolean private)
 
1792
e_mail_tab_set_private (EMailTab *tab,
 
1793
                        gboolean private)
1791
1794
{
1792
 
  EMailTabPrivate *priv = tab->priv;
1793
 
 
1794
 
  if (priv->private == private)
1795
 
    return;
1796
 
 
1797
 
  priv->private = private;
1798
 
 
1799
 
  if (!priv->preview_mode)
1800
 
    clutter_actor_set_name (CLUTTER_ACTOR (tab),
1801
 
                            private ? "private-tab" : NULL);
1802
 
 
1803
 
  g_object_notify (G_OBJECT (tab), "private");
 
1795
        EMailTabPrivate *priv = tab->priv;
 
1796
 
 
1797
        if (priv->private == private)
 
1798
                return;
 
1799
 
 
1800
        priv->private = private;
 
1801
 
 
1802
        if (!priv->preview_mode)
 
1803
                clutter_actor_set_name (
 
1804
                        CLUTTER_ACTOR (tab), private ? "private-tab" : NULL);
 
1805
 
 
1806
        g_object_notify (G_OBJECT (tab), "private");
1804
1807
}
1805
1808
 
1806
1809
gboolean
1807
1810
e_mail_tab_get_private (EMailTab *tab)
1808
1811
{
1809
 
  EMailTabPrivate *priv = tab->priv;
1810
 
  return priv->private;
 
1812
        EMailTabPrivate *priv = tab->priv;
 
1813
        return priv->private;
1811
1814
}
1812
1815
 
1813
1816
void
1814
 
e_mail_tab_set_active (EMailTab *tab, gboolean active)
 
1817
e_mail_tab_set_active (EMailTab *tab,
 
1818
                       gboolean active)
1815
1819
{
1816
 
  EMailTabPrivate *priv = tab->priv;
1817
 
 
1818
 
  if (priv->active == active)
1819
 
    return;
1820
 
 
1821
 
  priv->active = active;
1822
 
 
1823
 
  g_object_notify (G_OBJECT (tab), "active");
1824
 
 
1825
 
  if (active)
1826
 
    mx_stylable_set_style_pseudo_class (MX_STYLABLE (tab), "active");
1827
 
  else if (!priv->pressed)
1828
 
    {
1829
 
      if (priv->hover)
1830
 
        mx_stylable_set_style_pseudo_class (MX_STYLABLE (tab), "hover");
1831
 
      else
1832
 
        mx_stylable_set_style_pseudo_class (MX_STYLABLE (tab), NULL);
1833
 
    }
 
1820
        EMailTabPrivate *priv = tab->priv;
 
1821
 
 
1822
        if (priv->active == active)
 
1823
                return;
 
1824
 
 
1825
        priv->active = active;
 
1826
 
 
1827
        g_object_notify (G_OBJECT (tab), "active");
 
1828
 
 
1829
        if (active)
 
1830
                mx_stylable_set_style_pseudo_class (MX_STYLABLE (tab), "active");
 
1831
        else if (!priv->pressed) {
 
1832
                if (priv->hover)
 
1833
                        mx_stylable_set_style_pseudo_class (MX_STYLABLE (tab), "hover");
 
1834
                else
 
1835
                        mx_stylable_set_style_pseudo_class (MX_STYLABLE (tab), NULL);
 
1836
        }
1834
1837
}
1835
1838
 
1836
1839
gboolean
1837
1840
e_mail_tab_get_active (EMailTab *tab)
1838
1841
{
1839
 
  EMailTabPrivate *priv = tab->priv;
1840
 
  return priv->active;
 
1842
        EMailTabPrivate *priv = tab->priv;
 
1843
        return priv->active;
1841
1844
}
1842
1845
 
1843
1846
static gboolean
1844
1847
e_mail_tab_alert_cb (EMailTab *tab)
1845
1848
{
1846
 
  const gchar *name;
1847
 
  EMailTabPrivate *priv = tab->priv;
1848
 
 
1849
 
  /* FIXME: Work in preview mode */
1850
 
 
1851
 
  /* Alternate between private mode and non-private to alert */
1852
 
  name = (priv->private ^ (priv->alert_count % 2)) ? NULL : "private-tab";
1853
 
  if (!priv->preview_mode)
1854
 
    clutter_actor_set_name (CLUTTER_ACTOR (tab), name);
1855
 
  priv->alert_count++;
1856
 
 
1857
 
  if (priv->alert_count < 4)
1858
 
    return TRUE;
1859
 
 
1860
 
  /* This call isn't needed, it should be in the correct state as long as
1861
 
   * the above check always checks for < (an even number)
1862
 
   */
1863
 
  /*if (!priv->preview_mode)
1864
 
    clutter_actor_set_name (CLUTTER_ACTOR (tab),
1865
 
                            priv->private ? "private-tab" : NULL);*/
1866
 
  priv->alert_source = 0;
1867
 
 
1868
 
  return FALSE;
 
1849
        const gchar *name;
 
1850
        EMailTabPrivate *priv = tab->priv;
 
1851
 
 
1852
        /* FIXME: Work in preview mode */
 
1853
 
 
1854
        /* Alternate between private mode and non-private to alert */
 
1855
        name = (priv->private ^ (priv->alert_count % 2)) ? NULL : "private-tab";
 
1856
        if (!priv->preview_mode)
 
1857
                clutter_actor_set_name (CLUTTER_ACTOR (tab), name);
 
1858
        priv->alert_count++;
 
1859
 
 
1860
        if (priv->alert_count < 4)
 
1861
                return TRUE;
 
1862
 
 
1863
        /* This call isn't needed, it should be in the correct state as long as
 
1864
         * the above check always checks for < (an even number)
 
1865
         */
 
1866
        /*if (!priv->preview_mode)
 
1867
                clutter_actor_set_name (CLUTTER_ACTOR (tab),
 
1868
                                                                                                                priv->private ? "private-tab" : NULL);*/
 
1869
        priv->alert_source = 0;
 
1870
 
 
1871
        return FALSE;
1869
1872
}
1870
1873
 
1871
1874
void
1872
1875
e_mail_tab_alert (EMailTab *tab)
1873
1876
{
1874
 
  EMailTabPrivate *priv = tab->priv;
 
1877
        EMailTabPrivate *priv = tab->priv;
1875
1878
 
1876
 
  priv->alert_count = 0;
1877
 
  if (!priv->alert_source)
1878
 
    priv->alert_source =
1879
 
      g_timeout_add_full (G_PRIORITY_HIGH,
1880
 
                          500,
1881
 
                          (GSourceFunc) e_mail_tab_alert_cb,
1882
 
                          tab,
1883
 
                          NULL);
 
1879
        priv->alert_count = 0;
 
1880
        if (!priv->alert_source)
 
1881
                priv->alert_source =
 
1882
                        g_timeout_add_full (G_PRIORITY_HIGH,
 
1883
                                500,
 
1884
                                (GSourceFunc) e_mail_tab_alert_cb,
 
1885
                                tab,
 
1886
                                NULL);
1884
1887
}
1885
1888
 
1886
1889
void
1887
 
e_mail_tab_enable_drag (EMailTab *tab, gboolean enable)
 
1890
e_mail_tab_enable_drag (EMailTab *tab,
 
1891
                        gboolean enable)
1888
1892
{
1889
 
  EMailTabPrivate *priv = tab->priv;
1890
 
 
1891
 
  if (priv->drag_enabled == enable)
1892
 
    return;
1893
 
 
1894
 
  priv->drag_enabled = enable;
1895
 
  if (enable)
1896
 
    mx_draggable_enable (MX_DRAGGABLE (tab));
1897
 
  else
1898
 
    mx_draggable_disable (MX_DRAGGABLE (tab));
 
1893
        EMailTabPrivate *priv = tab->priv;
 
1894
 
 
1895
        if (priv->drag_enabled == enable)
 
1896
                return;
 
1897
 
 
1898
        priv->drag_enabled = enable;
 
1899
        if (enable)
 
1900
                mx_draggable_enable (MX_DRAGGABLE (tab));
 
1901
        else
 
1902
                mx_draggable_disable (MX_DRAGGABLE (tab));
1899
1903
}
1900
1904