~cairo-dock-team/ubuntu/oneiric/cairo-dock/2.3.0-3

« back to all changes in this revision

Viewing changes to src/gldit/cairo-dock-animations.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include <math.h>
 
21
#include <string.h>
 
22
#include <stdlib.h>
 
23
#include <cairo.h>
 
24
#include <gtk/gtk.h>
 
25
 
 
26
#ifdef HAVE_GLITZ
 
27
#include <gdk/gdkx.h>
 
28
#include <glitz-glx.h>
 
29
#include <cairo-glitz.h>
 
30
#endif
 
31
 
 
32
#include "cairo-dock-icons.h"
 
33
#include "cairo-dock-dock-factory.h"
 
34
#include "cairo-dock-dock-facility.h"
 
35
#include "cairo-dock-callbacks.h"
 
36
#include "cairo-dock-draw.h"
 
37
#include "cairo-dock-draw-opengl.h"
 
38
#include "cairo-dock-dialog-manager.h"
 
39
#include "cairo-dock-applications-manager.h"
 
40
#include "cairo-dock-dock-manager.h"
 
41
#include "cairo-dock-log.h"
 
42
#include "cairo-dock-gui-manager.h"
 
43
#include "cairo-dock-notifications.h"
 
44
#include "cairo-dock-internal-accessibility.h"
 
45
#include "cairo-dock-internal-system.h"
 
46
#include "cairo-dock-internal-icons.h"
 
47
#include "cairo-dock-internal-taskbar.h"
 
48
#include "cairo-dock-backends-manager.h"
 
49
#include "cairo-dock-class-manager.h"
 
50
#include "cairo-dock-desklet-factory.h"
 
51
#include "cairo-dock-container.h"
 
52
#include "cairo-dock-flying-container.h"
 
53
#include "cairo-dock-load.h"
 
54
#include "cairo-dock-application-facility.h"
 
55
#include "cairo-dock-animations.h"
 
56
 
 
57
CairoDockHidingEffect *g_pHidingBackend = NULL;
 
58
CairoDockHidingEffect *g_pKeepingBelowBackend = NULL;
 
59
 
 
60
extern gboolean g_bUseOpenGL;
 
61
extern CairoDockGLConfig g_openglConfig;
 
62
 
 
63
static gboolean _update_fade_out_dock (gpointer pUserData, CairoDock *pDock, gboolean *bContinueAnimation)
 
64
{
 
65
        pDock->iFadeCounter += (pDock->bFadeInOut ? 1 : -1);  // fade out, puis fade in.
 
66
        
 
67
        if (pDock->iFadeCounter >= mySystem.iHideNbSteps)
 
68
        {
 
69
                pDock->bFadeInOut = FALSE;
 
70
                //g_print ("set below\n");
 
71
                gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), TRUE);
 
72
                // si fenetre maximisee, on met direct iFadeCounter a 0.  // malheureusement X met du temps a faire passer le dock derriere, et ca donne un "sursaut" :-/
 
73
                ///if (cairo_dock_search_window_covering_dock (pDock, FALSE, FALSE) != NULL)
 
74
                ///     pDock->iFadeCounter = 0;
 
75
        }
 
76
        
 
77
        //g_print ("pDock->iFadeCounter : %d\n", pDock->iFadeCounter);
 
78
        if (pDock->iFadeCounter > 0)
 
79
        {
 
80
                *bContinueAnimation = TRUE;
 
81
        }
 
82
        else
 
83
        {
 
84
                cairo_dock_remove_notification_func_on_container (CAIRO_CONTAINER (pDock),
 
85
                        CAIRO_DOCK_UPDATE_DOCK,
 
86
                        (CairoDockNotificationFunc) _update_fade_out_dock,
 
87
                        NULL);
 
88
        }
 
89
        
 
90
        cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
91
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
92
}
 
93
 
 
94
void cairo_dock_pop_up (CairoDock *pDock)
 
95
{
 
96
        //g_print ("%s (%d)\n", __func__, pDock->bIsBelow);
 
97
        if (pDock->bIsBelow)
 
98
        {
 
99
                cairo_dock_remove_notification_func_on_container (CAIRO_CONTAINER (pDock),
 
100
                        CAIRO_DOCK_UPDATE_DOCK,
 
101
                        (CairoDockNotificationFunc) _update_fade_out_dock,
 
102
                        NULL);
 
103
                pDock->iFadeCounter = 0;
 
104
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
105
                //g_print ("set above\n");
 
106
                gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), FALSE);  // keep above
 
107
                pDock->bIsBelow = FALSE;
 
108
        }
 
109
}
 
110
 
 
111
void cairo_dock_pop_down (CairoDock *pDock)
 
112
{
 
113
        //g_print ("%s (%d, %d)\n", __func__, pDock->bIsBelow, pDock->container.bInside);
 
114
        /**if (pDock->bIsMainDock && cairo_dock_get_nb_dialog_windows () != 0)
 
115
                return FALSE;*/
 
116
        if (! pDock->bIsBelow && pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->container.bInside)
 
117
        {
 
118
                if (cairo_dock_search_window_overlapping_dock (pDock) != NULL)
 
119
                {
 
120
                        pDock->iFadeCounter = 0;
 
121
                        pDock->bFadeInOut = TRUE;
 
122
                        cairo_dock_register_notification_on_container (CAIRO_CONTAINER (pDock),
 
123
                                CAIRO_DOCK_UPDATE_DOCK,
 
124
                                (CairoDockNotificationFunc) _update_fade_out_dock,
 
125
                                CAIRO_DOCK_RUN_FIRST, NULL);
 
126
                        if (g_pKeepingBelowBackend != NULL && g_pKeepingBelowBackend->init)
 
127
                                g_pKeepingBelowBackend->init (pDock);
 
128
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
 
129
                }
 
130
                else
 
131
                {
 
132
                        //g_print ("set below\n");
 
133
                        gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), TRUE);
 
134
                }
 
135
                pDock->bIsBelow = TRUE;
 
136
        }
 
137
        ///pDock->iSidPopDown = 0;
 
138
        ///return FALSE;
 
139
}
 
140
 
 
141
 
 
142
gfloat cairo_dock_calculate_magnitude (gint iMagnitudeIndex)  // merci a Robrob pour le patch !
 
143
{
 
144
        gfloat tmp= ((gfloat)iMagnitudeIndex)/CAIRO_DOCK_NB_MAX_ITERATIONS;
 
145
 
 
146
        if (tmp>0.5f)
 
147
                tmp=1.0f-(1.0f-tmp)*(1.0f-tmp)*(1.0f-tmp)*4.0f;
 
148
        else
 
149
                tmp=tmp*tmp*tmp*4.0f;
 
150
 
 
151
        if (tmp<0.0f)
 
152
                tmp=0.0f;
 
153
 
 
154
        if (tmp>1.0f)
 
155
                tmp=1.0f;
 
156
        
 
157
        return tmp;
 
158
}
 
159
 
 
160
static gboolean _cairo_dock_grow_up (CairoDock *pDock)
 
161
{
 
162
        //g_print ("%s (%d ; %2f ; bInside:%d)\n", __func__, pDock->iMagnitudeIndex, pDock->fFoldingFactor, pDock->container.bInside);
 
163
        if (pDock->bIsShrinkingDown)
 
164
                return TRUE;  // on se met en attente de fin d'animation.
 
165
        
 
166
        pDock->iMagnitudeIndex += mySystem.iGrowUpInterval;
 
167
        if (pDock->iMagnitudeIndex > CAIRO_DOCK_NB_MAX_ITERATIONS)
 
168
                pDock->iMagnitudeIndex = CAIRO_DOCK_NB_MAX_ITERATIONS;
 
169
 
 
170
        if (pDock->fFoldingFactor != 0)
 
171
        {
 
172
                int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
 
173
                if (iAnimationDeltaT == 0)  // precaution.
 
174
                {
 
175
                        cairo_dock_set_default_animation_delta_t (pDock);
 
176
                        iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
 
177
                }
 
178
                pDock->fFoldingFactor -= (double) iAnimationDeltaT / mySystem.iUnfoldingDuration;
 
179
                if (pDock->fFoldingFactor < 0)
 
180
                        pDock->fFoldingFactor = 0;
 
181
        }
 
182
        
 
183
        if (pDock->container.bIsHorizontal)
 
184
                gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
 
185
        else
 
186
                gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
 
187
        
 
188
        Icon *pLastPointedIcon = cairo_dock_get_pointed_icon (pDock->icons);
 
189
        Icon *pPointedIcon = cairo_dock_calculate_dock_icons (pDock);
 
190
        if (! pDock->bIsGrowingUp)
 
191
                return FALSE;
 
192
        
 
193
        if (pLastPointedIcon != pPointedIcon && pDock->container.bInside)
 
194
                cairo_dock_on_change_icon (pLastPointedIcon, pPointedIcon, pDock);
 
195
 
 
196
        if (pDock->iMagnitudeIndex == CAIRO_DOCK_NB_MAX_ITERATIONS && pDock->fFoldingFactor == 0)  // fin de grossissement et de depliage.
 
197
        {
 
198
                if (pDock->bWMIconsNeedUpdate)
 
199
                {
 
200
                        cairo_dock_trigger_set_WM_icons_geometry (pDock);
 
201
                        pDock->bWMIconsNeedUpdate = FALSE;
 
202
                }
 
203
                
 
204
                cairo_dock_replace_all_dialogs ();
 
205
                return FALSE;
 
206
        }
 
207
        else
 
208
                return TRUE;
 
209
}
 
210
 
 
211
static gboolean _cairo_dock_shrink_down (CairoDock *pDock)
 
212
{
 
213
        //g_print ("%s (%d, %f, %f)\n", __func__, pDock->iMagnitudeIndex, pDock->fFoldingFactor, pDock->fDecorationsOffsetX);
 
214
        //\_________________ On fait decroitre la magnitude du dock.
 
215
        int iPrevMagnitudeIndex = pDock->iMagnitudeIndex;
 
216
        pDock->iMagnitudeIndex -= mySystem.iShrinkDownInterval;
 
217
        if (pDock->iMagnitudeIndex < 0)
 
218
                pDock->iMagnitudeIndex = 0;
 
219
        
 
220
        //\_________________ On replie le dock.
 
221
        if (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)
 
222
        {
 
223
                int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
 
224
                if (iAnimationDeltaT == 0)  // precaution.
 
225
                {
 
226
                        cairo_dock_set_default_animation_delta_t (pDock);
 
227
                        iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
 
228
                }
 
229
                pDock->fFoldingFactor += (double) iAnimationDeltaT / mySystem.iUnfoldingDuration;
 
230
                if (pDock->fFoldingFactor > 1)
 
231
                        pDock->fFoldingFactor = 1;
 
232
        }
 
233
        
 
234
        //\_________________ On remet les decorations a l'equilibre.
 
235
        pDock->fDecorationsOffsetX *= .8;
 
236
        if (fabs (pDock->fDecorationsOffsetX) < 3)
 
237
                pDock->fDecorationsOffsetX = 0.;
 
238
        
 
239
        //\_________________ On recupere la position de la souris manuellement (car a priori on est hors du dock).
 
240
        if (pDock->container.bIsHorizontal)  // ce n'est pas le motion_notify qui va nous donner des coordonnees en dehors du dock, et donc le fait d'etre dedans va nous faire interrompre le shrink_down et re-grossir, du coup il faut le faire ici. L'inconvenient, c'est que quand on sort par les cotes, il n'y a soudain plus d'icone pointee, et donc le dock devient tout plat subitement au lieu de le faire doucement. Heureusement j'ai trouve une astuce. ^_^
 
241
                gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
 
242
        else
 
243
                gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
 
244
        
 
245
        //\_________________ On recalcule les icones.
 
246
        ///if (iPrevMagnitudeIndex != 0)
 
247
        {
 
248
                cairo_dock_calculate_dock_icons (pDock);
 
249
                if (! pDock->bIsShrinkingDown)
 
250
                        return FALSE;
 
251
                
 
252
                ///cairo_dock_replace_all_dialogs ();
 
253
        }
 
254
 
 
255
        if (pDock->iMagnitudeIndex == 0 && (pDock->fFoldingFactor == 0 || pDock->fFoldingFactor == 1))  // on est arrive en bas.
 
256
        {
 
257
                //g_print ("equilibre atteint (%d)\n", pDock->container.bInside);
 
258
                ///if (iPrevMagnitudeIndex != 0 || (pDock->fDecorationsOffsetX == 0 && (pDock->fFoldingFactor == 0 || pDock->fFoldingFactor == 1)))  // on vient d'arriver en bas OU l'animation de depliage est finie.
 
259
                ///{
 
260
                        if (! pDock->container.bInside)  // on peut etre hors des icones sans etre hors de la fenetre.
 
261
                        {
 
262
                                //g_print ("rideau !\n");
 
263
                                
 
264
                                //\__________________ On repasse derriere si on etait devant.
 
265
                                if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->bIsBelow)
 
266
                                        cairo_dock_pop_down (pDock);
 
267
                                
 
268
                                //\__________________ On se redimensionne en taille normale.
 
269
                                if (! pDock->bAutoHide && pDock->iRefCount == 0 && ! pDock->bMenuVisible)  // fin de shrink sans auto-hide => taille normale.
 
270
                                {
 
271
                                        //g_print ("taille normale (%x; %d)\n", pDock->pShapeBitmap , pDock->iInputState);
 
272
                                        if (pDock->pShapeBitmap && pDock->iInputState != CAIRO_DOCK_INPUT_AT_REST)
 
273
                                        {
 
274
                                                //g_print ("+++ input shape at rest on end shrinking\n");
 
275
                                                cairo_dock_set_input_shape_at_rest (pDock);
 
276
                                                pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST;
 
277
                                                ///cairo_dock_replace_all_dialogs ();
 
278
                                        }
 
279
                                }
 
280
                                /**else if (pDock->bAutoHide && pDock->iRefCount == 0 && pDock->fFoldingFactor != 0)  // si le dock se replie, inutile de rester en taille grande avec une fenetre transparente, ca perturbe.
 
281
                                {
 
282
                                        if (pDock->pHiddenShapeBitmap && pDock->iInputState != CAIRO_DOCK_INPUT_HIDDEN)
 
283
                                        {
 
284
                                                //g_print ("+++ input shape hidden on end shrinking\n");
 
285
                                                gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
 
286
                                                        NULL,
 
287
                                                        0,
 
288
                                                        0);
 
289
                                                gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
 
290
                                                        pDock->pHiddenShapeBitmap,
 
291
                                                        0,
 
292
                                                        0);
 
293
                                                pDock->iInputState = CAIRO_DOCK_INPUT_HIDDEN;
 
294
                                        }
 
295
                                }*/
 
296
                                
 
297
                                //\__________________ On se cache si sous-dock.
 
298
                                if (pDock->iRefCount > 0)
 
299
                                {
 
300
                                        //g_print ("on cache ce sous-dock en sortant par lui\n");
 
301
                                        gtk_widget_hide (pDock->container.pWidget);
 
302
                                        cairo_dock_hide_parent_dock (pDock);
 
303
                                }
 
304
                                cairo_dock_hide_after_shortcut ();
 
305
                        }
 
306
                        else
 
307
                        {
 
308
                                cairo_dock_calculate_dock_icons (pDock);  // relance le grossissement si on est dedans.
 
309
                        }
 
310
                /**}
 
311
                else if (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)
 
312
                {
 
313
                        cairo_dock_calculate_dock_icons (pDock);
 
314
                }*/
 
315
                if (!pDock->bIsGrowingUp)
 
316
                        cairo_dock_replace_all_dialogs ();
 
317
                return (!pDock->bIsGrowingUp && (pDock->fDecorationsOffsetX != 0 || (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)));
 
318
        }
 
319
        else
 
320
        {
 
321
                return (!pDock->bIsGrowingUp);
 
322
        }
 
323
}
 
324
 
 
325
static gboolean _cairo_dock_hide (CairoDock *pDock)
 
326
{
 
327
        if (pDock->iMagnitudeIndex > 0)  // on retarde le cachage du dock pour apercevoir les effets.
 
328
                return TRUE;
 
329
        
 
330
        if (pDock->fHideOffset < 1)
 
331
        {
 
332
                pDock->fHideOffset += 1./mySystem.iHideNbSteps;
 
333
                if (pDock->fHideOffset > .99)  // fin d'anim.
 
334
                {
 
335
                        pDock->fHideOffset = 1;
 
336
                        
 
337
                        //g_print ("on arrete le cachage\n");
 
338
                        gboolean bVisibleIconsPresent = FALSE;
 
339
                        Icon *pIcon;
 
340
                        GList *ic;
 
341
                        for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
342
                        {
 
343
                                pIcon = ic->data;
 
344
                                if (pIcon->fInsertRemoveFactor != 0)  // on accelere l'animation d'apparition/disparition.
 
345
                                {
 
346
                                        if (pIcon->fInsertRemoveFactor > 0)
 
347
                                                pIcon->fInsertRemoveFactor = 0.05;
 
348
                                        else
 
349
                                                pIcon->fInsertRemoveFactor = - 0.05;
 
350
                                }
 
351
                                
 
352
                                if (! pIcon->bIsDemandingAttention && ! pIcon->bAlwaysVisible)
 
353
                                        cairo_dock_stop_icon_animation (pIcon);  // s'il y'a une autre animation en cours, on l'arrete.
 
354
                                else
 
355
                                        bVisibleIconsPresent = TRUE;
 
356
                        }
 
357
                        
 
358
                        pDock->pRenderer->calculate_icons (pDock);
 
359
                        ///pDock->fFoldingFactor = (mySystem.bAnimateOnAutoHide ? .99 : 0.);  // on arme le depliage.
 
360
                        cairo_dock_allow_entrance (pDock);
 
361
                        
 
362
                        cairo_dock_replace_all_dialogs ();
 
363
                        
 
364
                        if (bVisibleIconsPresent)  // il y'a des icones a montrer progressivement, on reste dans la boucle.
 
365
                        {
 
366
                                pDock->fPostHideOffset = 0.05;
 
367
                                return TRUE;
 
368
                        }
 
369
                        else
 
370
                        {
 
371
                                pDock->fPostHideOffset = 1;  // pour que les icones demandant l'attention plus tard soient visibles.
 
372
                                return FALSE;
 
373
                        }
 
374
                }
 
375
        }
 
376
        else if (pDock->fPostHideOffset > 0 && pDock->fPostHideOffset < 1)
 
377
        {
 
378
                pDock->fPostHideOffset += 1./mySystem.iHideNbSteps;
 
379
                if (pDock->fPostHideOffset > .99)
 
380
                {
 
381
                        pDock->fPostHideOffset = 1.;
 
382
                        return FALSE;
 
383
                }
 
384
        }
 
385
        return TRUE;
 
386
}
 
387
 
 
388
static gboolean _cairo_dock_show (CairoDock *pDock)
 
389
{
 
390
        pDock->fHideOffset -= 1./mySystem.iUnhideNbSteps;
 
391
        if (pDock->fHideOffset < 0.01)
 
392
        {
 
393
                pDock->fHideOffset = 0;
 
394
                cairo_dock_allow_entrance (pDock);
 
395
                
 
396
                return FALSE;
 
397
        }
 
398
        return TRUE;
 
399
}
 
400
 
 
401
static gboolean _cairo_dock_handle_inserting_removing_icons (CairoDock *pDock)
 
402
{
 
403
        gboolean bRecalculateIcons = FALSE;
 
404
        GList* ic = pDock->icons, *next_ic;
 
405
        Icon *pIcon;
 
406
        while (ic != NULL)
 
407
        {
 
408
                pIcon = ic->data;
 
409
                next_ic = ic->next;
 
410
                if (pIcon->fInsertRemoveFactor == (gdouble)0.05)
 
411
                {
 
412
                        gboolean bIsAppli = CAIRO_DOCK_IS_NORMAL_APPLI (pIcon);
 
413
                        if (bIsAppli && pIcon->iLastCheckTime != -1)  // c'est une icone d'appli non vieille qui disparait, elle s'est probablement cachee => on la detache juste.
 
414
                        {
 
415
                                cd_message ("cette (%s) appli est toujours valide, on la detache juste", pIcon->cName);
 
416
                                pIcon->fInsertRemoveFactor = 0.;  // on le fait avant le reload, sinon l'icone n'est pas rechargee.
 
417
                                if (!pIcon->bIsHidden && myTaskBar.bHideVisibleApplis)  // on lui remet l'image normale qui servira d'embleme lorsque l'icone sera inseree a nouveau dans le dock.
 
418
                                        cairo_dock_reload_icon_image (pIcon, CAIRO_CONTAINER (pDock));
 
419
                                cairo_dock_detach_appli (pIcon);
 
420
                        }
 
421
                        else
 
422
                        {
 
423
                                cd_message (" - %s va etre supprimee", pIcon->cName);
 
424
                                cairo_dock_remove_icon_from_dock (pDock, pIcon);  // enleve le separateur automatique avec; supprime le .desktop et le sous-dock des lanceurs; stoppe les applets; marque le theme.
 
425
                                
 
426
                                if (pIcon->cClass != NULL && pDock == cairo_dock_search_dock_from_name (pIcon->cClass))
 
427
                                {
 
428
                                        gboolean bEmptyClassSubDock = cairo_dock_check_class_subdock_is_empty (pDock, pIcon->cClass);
 
429
                                        if (bEmptyClassSubDock)
 
430
                                        {
 
431
                                                cairo_dock_free_icon (pIcon);
 
432
                                                return FALSE;
 
433
                                        }
 
434
                                }
 
435
                                
 
436
                                cairo_dock_free_icon (pIcon);
 
437
                                cairo_dock_update_dock_size (pDock);  // si on le fait avant le free, le dock se fige (mais continue a tourner)...
 
438
                        }
 
439
                }
 
440
                else if (pIcon->fInsertRemoveFactor == (gdouble)-0.05)
 
441
                {
 
442
                        pIcon->fInsertRemoveFactor = 0;  // cela n'arrete pas l'animation, qui peut se poursuivre meme apres que l'icone ait atteint sa taille maximale.
 
443
                        bRecalculateIcons = TRUE;
 
444
                }
 
445
                else if (pIcon->fInsertRemoveFactor != 0)
 
446
                {
 
447
                        bRecalculateIcons = TRUE;
 
448
                }
 
449
                ic = next_ic;
 
450
        }
 
451
        
 
452
        if (bRecalculateIcons)
 
453
                cairo_dock_calculate_dock_icons (pDock);
 
454
        return TRUE;
 
455
}
 
456
 
 
457
static gboolean _cairo_dock_dock_animation_loop (CairoDock *pDock)
 
458
{
 
459
        //g_print ("%s (%d, %d, %d)\n", __func__, pDock->iRefCount, pDock->bIsShrinkingDown, pDock->bIsGrowingUp);
 
460
        gboolean bContinue = FALSE;
 
461
        if (pDock->bIsShrinkingDown)
 
462
        {
 
463
                pDock->bIsShrinkingDown = _cairo_dock_shrink_down (pDock);
 
464
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
465
                bContinue |= pDock->bIsShrinkingDown;
 
466
        }
 
467
        if (pDock->bIsGrowingUp)
 
468
        {
 
469
                pDock->bIsGrowingUp = _cairo_dock_grow_up (pDock);
 
470
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
471
                bContinue |= pDock->bIsGrowingUp;
 
472
        }
 
473
        if (pDock->bIsHiding)
 
474
        {
 
475
                //g_print ("le dock se cache\n");
 
476
                pDock->bIsHiding = _cairo_dock_hide (pDock);
 
477
                gtk_widget_queue_draw (pDock->container.pWidget);  // on n'utilise pas cairo_dock_redraw_container, sinon a la derniere iteration, le dock etant cache, la fonction ne le redessine pas.
 
478
                bContinue |= pDock->bIsHiding;
 
479
        }
 
480
        if (pDock->bIsShowing)
 
481
        {
 
482
                pDock->bIsShowing = _cairo_dock_show (pDock);
 
483
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
484
                bContinue |= pDock->bIsShowing;
 
485
        }
 
486
        //g_print (" => %d, %d\n", pDock->bIsShrinkingDown, pDock->bIsGrowingUp);
 
487
        
 
488
        gboolean bUpdateSlowAnimation = FALSE;
 
489
        pDock->container.iAnimationStep ++;
 
490
        if (pDock->container.iAnimationStep * pDock->container.iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
 
491
        {
 
492
                bUpdateSlowAnimation = TRUE;
 
493
                pDock->container.iAnimationStep = 0;
 
494
                pDock->container.bKeepSlowAnimation = FALSE;
 
495
        }
 
496
        double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
 
497
        gboolean bIconIsAnimating;
 
498
        gboolean bNoMoreDemandingAttention = FALSE;
 
499
        Icon *icon;
 
500
        GList *ic;
 
501
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
502
        {
 
503
                icon = ic->data;
 
504
                
 
505
                icon->fDeltaYReflection = 0;
 
506
                if (myIcons.fAlphaAtRest != 1)
 
507
                        icon->fAlpha = fDockMagnitude + myIcons.fAlphaAtRest * (1 - fDockMagnitude);
 
508
                
 
509
                bIconIsAnimating = FALSE;
 
510
                if (bUpdateSlowAnimation)
 
511
                {
 
512
                        cairo_dock_notify_on_icon (icon, CAIRO_DOCK_UPDATE_ICON_SLOW, icon, pDock, &bIconIsAnimating);
 
513
                        pDock->container.bKeepSlowAnimation |= bIconIsAnimating;
 
514
                }
 
515
                cairo_dock_notify_on_icon (icon, CAIRO_DOCK_UPDATE_ICON, icon, pDock, &bIconIsAnimating);
 
516
                
 
517
                if ((icon->bIsDemandingAttention || icon->bAlwaysVisible) && cairo_dock_is_hidden (pDock))  // animation d'une icone demandant l'attention dans un dock cache => on force le dessin qui normalement ne se fait pas.
 
518
                {
 
519
                        gtk_widget_queue_draw (pDock->container.pWidget);
 
520
                }
 
521
                
 
522
                bContinue |= bIconIsAnimating;
 
523
                if (! bIconIsAnimating)
 
524
                {
 
525
                        icon->iAnimationState = CAIRO_DOCK_STATE_REST;
 
526
                        if (icon->bIsDemandingAttention)
 
527
                        {
 
528
                                icon->bIsDemandingAttention = FALSE;
 
529
                                bNoMoreDemandingAttention = TRUE;
 
530
                        }
 
531
                }
 
532
        }
 
533
        bContinue |= pDock->container.bKeepSlowAnimation;
 
534
        
 
535
        if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && bNoMoreDemandingAttention && ! pDock->bIsBelow && ! pDock->container.bInside)
 
536
        {
 
537
                //g_print ("plus de raison d'etre devant\n");
 
538
                cairo_dock_pop_down (pDock);
 
539
        }
 
540
        
 
541
        if (! _cairo_dock_handle_inserting_removing_icons (pDock))
 
542
        {
 
543
                cd_debug ("ce dock n'a plus de raison d'etre");
 
544
                return FALSE;
 
545
        }
 
546
        
 
547
        if (bUpdateSlowAnimation)
 
548
        {
 
549
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_UPDATE_DOCK_SLOW, pDock, &pDock->container.bKeepSlowAnimation);
 
550
        }
 
551
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_UPDATE_DOCK, pDock, &bContinue);
 
552
        
 
553
        if (! bContinue && ! pDock->container.bKeepSlowAnimation)
 
554
        {
 
555
                pDock->container.iSidGLAnimation = 0;
 
556
                return FALSE;
 
557
        }
 
558
        else
 
559
                return TRUE;
 
560
}
 
561
static gboolean _cairo_desklet_animation_loop (CairoDesklet *pDesklet)
 
562
{
 
563
        gboolean bContinue = FALSE;
 
564
        
 
565
        gboolean bUpdateSlowAnimation = FALSE;
 
566
        pDesklet->container.iAnimationStep ++;
 
567
        if (pDesklet->container.iAnimationStep * pDesklet->container.iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
 
568
        {
 
569
                bUpdateSlowAnimation = TRUE;
 
570
                pDesklet->container.iAnimationStep = 0;
 
571
                pDesklet->container.bKeepSlowAnimation = FALSE;
 
572
        }
 
573
        
 
574
        if (pDesklet->pIcon != NULL)
 
575
        {
 
576
                gboolean bIconIsAnimating = FALSE;
 
577
                
 
578
                if (bUpdateSlowAnimation)
 
579
                {
 
580
                        cairo_dock_notify_on_icon (pDesklet->pIcon, CAIRO_DOCK_UPDATE_ICON_SLOW, pDesklet->pIcon, pDesklet, &bIconIsAnimating);
 
581
                        pDesklet->container.bKeepSlowAnimation |= bIconIsAnimating;
 
582
                }
 
583
                
 
584
                cairo_dock_notify_on_icon (pDesklet->pIcon, CAIRO_DOCK_UPDATE_ICON, pDesklet->pIcon, pDesklet, &bIconIsAnimating);
 
585
                if (! bIconIsAnimating)
 
586
                        pDesklet->pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
 
587
                else
 
588
                        bContinue = TRUE;
 
589
        }
 
590
        
 
591
        if (bUpdateSlowAnimation)
 
592
        {
 
593
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_UPDATE_DESKLET_SLOW, pDesklet, &pDesklet->container.bKeepSlowAnimation);
 
594
        }
 
595
        
 
596
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_UPDATE_DESKLET, pDesklet, &bContinue);
 
597
        
 
598
        if (! bContinue && ! pDesklet->container.bKeepSlowAnimation)
 
599
        {
 
600
                pDesklet->container.iSidGLAnimation = 0;
 
601
                return FALSE;
 
602
        }
 
603
        else
 
604
                return TRUE;
 
605
}
 
606
 
 
607
static gboolean _cairo_flying_container_animation_loop (CairoFlyingContainer *pFlyingContainer)
 
608
{
 
609
        gboolean bContinue = FALSE;
 
610
        
 
611
        if (pFlyingContainer->pIcon != NULL)
 
612
        {
 
613
                gboolean bIconIsAnimating = FALSE;
 
614
                
 
615
                cairo_dock_notify_on_icon (pFlyingContainer->pIcon, CAIRO_DOCK_UPDATE_ICON, pFlyingContainer->pIcon, pFlyingContainer, &bIconIsAnimating);
 
616
                if (! bIconIsAnimating)
 
617
                        pFlyingContainer->pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
 
618
                else
 
619
                        bContinue = TRUE;
 
620
        }
 
621
        
 
622
        cairo_dock_notify (CAIRO_DOCK_UPDATE_FLYING_CONTAINER, pFlyingContainer, &bContinue);
 
623
        
 
624
        if (! bContinue)
 
625
        {
 
626
                cairo_dock_free_flying_container (pFlyingContainer);
 
627
                return FALSE;
 
628
        }
 
629
        else
 
630
                return TRUE;
 
631
}
 
632
 
 
633
static gboolean _cairo_dialog_animation_loop (CairoDialog *pDialog)
 
634
{
 
635
        gboolean bContinue = FALSE;
 
636
        
 
637
        gboolean bUpdateSlowAnimation = FALSE;
 
638
        pDialog->container.iAnimationStep ++;
 
639
        if (pDialog->container.iAnimationStep * pDialog->container.iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
 
640
        {
 
641
                bUpdateSlowAnimation = TRUE;
 
642
                pDialog->container.iAnimationStep = 0;
 
643
                pDialog->container.bKeepSlowAnimation = FALSE;
 
644
        }
 
645
        
 
646
        if (pDialog->fAppearanceCounter < 1)
 
647
        {
 
648
                pDialog->fAppearanceCounter += .08;
 
649
                if (pDialog->fAppearanceCounter > .99)
 
650
                {
 
651
                        pDialog->fAppearanceCounter = 1.;
 
652
                }
 
653
                else
 
654
                {
 
655
                        bContinue = TRUE;
 
656
                }
 
657
        }
 
658
        
 
659
        if (bUpdateSlowAnimation)
 
660
        {
 
661
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDialog), CAIRO_DOCK_UPDATE_DIALOG_SLOW, pDialog, &pDialog->container.bKeepSlowAnimation);
 
662
        }
 
663
        
 
664
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDialog), CAIRO_DOCK_UPDATE_DIALOG, pDialog, &bContinue);
 
665
        
 
666
        cairo_dock_redraw_container (CAIRO_CONTAINER (pDialog));
 
667
        if (! bContinue && ! pDialog->container.bKeepSlowAnimation)
 
668
        {
 
669
                pDialog->container.iSidGLAnimation = 0;
 
670
                return FALSE;
 
671
        }
 
672
        else
 
673
                return TRUE;
 
674
}
 
675
 
 
676
static gboolean _cairo_default_container_animation_loop (CairoContainer *pContainer)
 
677
{
 
678
        gboolean bContinue = FALSE;
 
679
        
 
680
        gboolean bUpdateSlowAnimation = FALSE;
 
681
        pContainer->iAnimationStep ++;
 
682
        if (pContainer->iAnimationStep * pContainer->iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
 
683
        {
 
684
                bUpdateSlowAnimation = TRUE;
 
685
                pContainer->iAnimationStep = 0;
 
686
                pContainer->bKeepSlowAnimation = FALSE;
 
687
        }
 
688
        
 
689
        if (bUpdateSlowAnimation)
 
690
        {
 
691
                cairo_dock_notify_on_container (pContainer, CAIRO_DOCK_UPDATE_DEFAULT_CONTAINER_SLOW, pContainer, &pContainer->bKeepSlowAnimation);
 
692
        }
 
693
        
 
694
        cairo_dock_notify_on_container (pContainer, CAIRO_DOCK_UPDATE_DEFAULT_CONTAINER, pContainer, &bContinue);
 
695
        
 
696
        if (! bContinue && ! pContainer->bKeepSlowAnimation)
 
697
        {
 
698
                pContainer->iSidGLAnimation = 0;
 
699
                return FALSE;
 
700
        }
 
701
        else
 
702
                return TRUE;
 
703
}
 
704
 
 
705
void cairo_dock_launch_animation (CairoContainer *pContainer)
 
706
{
 
707
        if (pContainer->iSidGLAnimation == 0)
 
708
        {
 
709
                int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pContainer);
 
710
                if (iAnimationDeltaT == 0)  // precaution.
 
711
                {
 
712
                        cairo_dock_set_default_animation_delta_t (pContainer);
 
713
                        iAnimationDeltaT = cairo_dock_get_animation_delta_t (pContainer);
 
714
                }
 
715
                pContainer->bKeepSlowAnimation = TRUE;
 
716
                switch (pContainer->iType)
 
717
                {
 
718
                        case CAIRO_DOCK_TYPE_DOCK :
 
719
                                pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_dock_dock_animation_loop, pContainer);
 
720
                        break ;
 
721
                        case CAIRO_DOCK_TYPE_DESKLET :
 
722
                                pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc) _cairo_desklet_animation_loop, pContainer);
 
723
                        break;
 
724
                        case CAIRO_DOCK_TYPE_FLYING_CONTAINER :
 
725
                                pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_flying_container_animation_loop, pContainer);
 
726
                        break ;
 
727
                        case CAIRO_DOCK_TYPE_DIALOG:
 
728
                                pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_dialog_animation_loop, pContainer);
 
729
                        break;
 
730
                        default :
 
731
                                pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_default_container_animation_loop, pContainer);
 
732
                        break ;
 
733
                }
 
734
        }
 
735
}
 
736
 
 
737
void cairo_dock_start_shrinking (CairoDock *pDock)
 
738
{
 
739
        if (! pDock->bIsShrinkingDown)  // on lance l'animation.
 
740
        {
 
741
                pDock->bIsGrowingUp = FALSE;
 
742
                pDock->bIsShrinkingDown = TRUE;
 
743
                
 
744
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
 
745
        }
 
746
}
 
747
 
 
748
void cairo_dock_start_growing (CairoDock *pDock)
 
749
{
 
750
        //g_print ("%s (%d)\n", __func__, pDock->bIsGrowingUp);
 
751
        if (! pDock->bIsGrowingUp)  // on lance l'animation.
 
752
        {
 
753
                pDock->bIsShrinkingDown = FALSE;
 
754
                pDock->bIsGrowingUp = TRUE;
 
755
                
 
756
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
 
757
        }
 
758
}
 
759
 
 
760
void cairo_dock_start_hiding (CairoDock *pDock)
 
761
{
 
762
        //g_print ("%s (%d)\n", __func__, pDock->bIsHiding);
 
763
        if (! pDock->bIsHiding && ! pDock->container.bInside)  // rien de plus desagreable que le dock qui se cache quand on est dedans.
 
764
        {
 
765
                pDock->bIsShowing = FALSE;
 
766
                pDock->bIsHiding = TRUE;
 
767
                
 
768
                if (pDock->pHiddenShapeBitmap && pDock->iInputState != CAIRO_DOCK_INPUT_HIDDEN)
 
769
                {
 
770
                        //g_print ("+++ input shape hidden on start hiding\n");
 
771
                        cairo_dock_set_input_shape_hidden (pDock);
 
772
                        pDock->iInputState = CAIRO_DOCK_INPUT_HIDDEN;
 
773
                }
 
774
                
 
775
                if (g_pHidingBackend != NULL && g_pHidingBackend->init)
 
776
                        g_pHidingBackend->init (pDock);
 
777
                
 
778
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
 
779
        }
 
780
}
 
781
 
 
782
void cairo_dock_start_showing (CairoDock *pDock)
 
783
{
 
784
        //g_print ("%s (%d)\n", __func__, pDock->bIsShowing);
 
785
        if (! pDock->bIsShowing)  // on lance l'animation.
 
786
        {
 
787
                pDock->bIsShowing = TRUE;
 
788
                pDock->bIsHiding = FALSE;
 
789
                
 
790
                if (pDock->pShapeBitmap && pDock->iInputState == CAIRO_DOCK_INPUT_HIDDEN)
 
791
                {
 
792
                        //g_print ("+++ input shape at rest on start showing\n");
 
793
                        cairo_dock_set_input_shape_at_rest (pDock);
 
794
                        pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST;
 
795
                }
 
796
                
 
797
                if (g_pHidingBackend != NULL && g_pHidingBackend->init)
 
798
                        g_pHidingBackend->init (pDock);
 
799
                
 
800
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
 
801
        }
 
802
}
 
803
 
 
804
 
 
805
void cairo_dock_start_icon_animation (Icon *pIcon, CairoDock *pDock)
 
806
{
 
807
        g_return_if_fail (pIcon != NULL && pDock != NULL);
 
808
        cd_message ("%s (%s, %d)", __func__, pIcon->cName, pIcon->iAnimationState);
 
809
        
 
810
        if (pIcon->iAnimationState != CAIRO_DOCK_STATE_REST &&
 
811
                (cairo_dock_icon_is_being_inserted_or_removed (pIcon) || pIcon->bIsDemandingAttention  || cairo_dock_animation_will_be_visible (pDock)))
 
812
        {
 
813
                //g_print ("  c'est parti\n");
 
814
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
 
815
        }
 
816
}
 
817
 
 
818
void cairo_dock_request_icon_animation (Icon *pIcon, CairoDock *pDock, const gchar *cAnimation, int iNbRounds)
 
819
{
 
820
        //cd_debug ("%s (%s, state:%d)", __func__, pIcon->cName, pIcon->iAnimationState);
 
821
        if (pIcon->iAnimationState != CAIRO_DOCK_STATE_REST)  // on le fait avant de changer d'animation, pour le cas ou l'icone ne serait plus placee au meme endroit (rebond).
 
822
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
823
        cairo_dock_stop_icon_animation (pIcon);
 
824
        
 
825
        if (cAnimation == NULL || iNbRounds == 0 || pIcon->iAnimationState != CAIRO_DOCK_STATE_REST)
 
826
                return ;
 
827
        cairo_dock_notify (CAIRO_DOCK_REQUEST_ICON_ANIMATION, pIcon, pDock, cAnimation, iNbRounds);
 
828
        cairo_dock_start_icon_animation (pIcon, pDock);
 
829
}
 
830
 
 
831
void cairo_dock_request_icon_attention (Icon *pIcon, CairoDock *pDock, const gchar *cAnimation, int iNbRounds)
 
832
{
 
833
        cairo_dock_stop_icon_animation (pIcon);
 
834
        pIcon->bIsDemandingAttention = TRUE;
 
835
        
 
836
        if (iNbRounds <= 0)
 
837
                iNbRounds = 1e6;
 
838
        if (cAnimation == NULL || *cAnimation == '\0' || strcmp (cAnimation, "default") == 0)
 
839
        {
 
840
                if (myTaskBar.cAnimationOnDemandsAttention != NULL)
 
841
                        cAnimation = myTaskBar.cAnimationOnDemandsAttention;
 
842
                else
 
843
                        cAnimation = "rotate";
 
844
        }
 
845
        
 
846
        cairo_dock_request_icon_animation (pIcon, pDock, cAnimation, iNbRounds);
 
847
        cairo_dock_mark_icon_as_clicked (pIcon);  // pour eviter qu'un simple survol ne stoppe l'animation.
 
848
        
 
849
        // on reporte la demande d'attention recursivement vers le bas.
 
850
        if (pDock->iRefCount > 0)
 
851
        {
 
852
                CairoDock *pParentDock = NULL;
 
853
                Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
 
854
                if (pPointingIcon != NULL)
 
855
                {
 
856
                        cairo_dock_request_icon_attention (pPointingIcon, pParentDock, cAnimation, iNbRounds);
 
857
                }
 
858
        }
 
859
        else if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && pDock->bIsBelow)
 
860
                cairo_dock_pop_up (pDock);
 
861
}
 
862
 
 
863
void cairo_dock_stop_icon_attention (Icon *pIcon, CairoDock *pDock)
 
864
{
 
865
        cairo_dock_stop_icon_animation (pIcon);
 
866
        cairo_dock_redraw_icon (pIcon, CAIRO_CONTAINER (pDock));  // a faire avant, lorsque l'icone est encore en mode demande d'attention.
 
867
        pIcon->bIsDemandingAttention = FALSE;
 
868
        
 
869
        // on stoppe la demande d'attention recursivement vers le bas.
 
870
        if (pDock->iRefCount > 0)
 
871
        {
 
872
                GList *ic;
 
873
                for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
874
                {
 
875
                        pIcon = ic->data;
 
876
                        if (pIcon->bIsDemandingAttention)
 
877
                                break;
 
878
                }
 
879
                if (ic == NULL)  // plus aucune animation dans ce dock.
 
880
                {
 
881
                        CairoDock *pParentDock = NULL;
 
882
                        Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
 
883
                        if (pPointingIcon != NULL)
 
884
                        {
 
885
                                cairo_dock_stop_icon_attention (pPointingIcon, pParentDock);
 
886
                        }
 
887
                }
 
888
        }
 
889
        else if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->bIsBelow && ! pDock->container.bInside)
 
890
        {
 
891
                cairo_dock_pop_down (pDock);
 
892
        }
 
893
}
 
894
 
 
895
 
 
896
void cairo_dock_trigger_icon_removal_from_dock (Icon *pIcon)
 
897
{
 
898
        CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
 
899
        if (pDock != NULL)
 
900
        {
 
901
                cairo_dock_stop_icon_animation (pIcon);
 
902
                if (cairo_dock_animation_will_be_visible (pDock))  // sinon inutile de se taper toute l'animation.
 
903
                        pIcon->fInsertRemoveFactor = 1.0;
 
904
                else
 
905
                        pIcon->fInsertRemoveFactor = 0.05;
 
906
                cairo_dock_notify (CAIRO_DOCK_REMOVE_ICON, pIcon, pDock);
 
907
                cairo_dock_start_icon_animation (pIcon, pDock);
 
908
        }
 
909
}
 
910
 
 
911
 
 
912
void cairo_dock_mark_icon_animation_as (Icon *pIcon, CairoDockAnimationState iAnimationState)
 
913
{
 
914
        if (pIcon->iAnimationState < iAnimationState)
 
915
        {
 
916
                pIcon->iAnimationState = iAnimationState;
 
917
        }
 
918
}
 
919
void cairo_dock_stop_marking_icon_animation_as (Icon *pIcon, CairoDockAnimationState iAnimationState)
 
920
{
 
921
        if (pIcon->iAnimationState == iAnimationState)
 
922
        {
 
923
                pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
 
924
        }
 
925
}
 
926
 
 
927
 
 
928
void cairo_dock_update_removing_inserting_icon_size_default (Icon *icon)
 
929
{
 
930
        icon->fInsertRemoveFactor *= .85;
 
931
        if (icon->fInsertRemoveFactor > 0)
 
932
        {
 
933
                if (icon->fInsertRemoveFactor < 0.05)
 
934
                        icon->fInsertRemoveFactor = 0.05;
 
935
        }
 
936
        else if (icon->fInsertRemoveFactor < 0)
 
937
        {
 
938
                if (icon->fInsertRemoveFactor > -0.05)
 
939
                        icon->fInsertRemoveFactor = -0.05;
 
940
        }
 
941
}
 
942
 
 
943
 
 
944
gboolean cairo_dock_update_inserting_removing_icon_notification (gpointer pUserData, Icon *pIcon, CairoDock *pDock, gboolean *bContinueAnimation)
 
945
{
 
946
        if (pIcon->iGlideDirection != 0)
 
947
        {
 
948
                pIcon->fGlideOffset += pIcon->iGlideDirection * .1;
 
949
                if (fabs (pIcon->fGlideOffset) > .99)
 
950
                {
 
951
                        pIcon->fGlideOffset = pIcon->iGlideDirection;
 
952
                        pIcon->iGlideDirection = 0;
 
953
                }
 
954
                else if (fabs (pIcon->fGlideOffset) < .01)
 
955
                {
 
956
                        pIcon->fGlideOffset = 0;
 
957
                        pIcon->iGlideDirection = 0;
 
958
                }
 
959
                *bContinueAnimation = TRUE;
 
960
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
961
        }
 
962
        
 
963
        if (pIcon->fInsertRemoveFactor == 0 || ! pIcon->bBeingRemovedByCairo)
 
964
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
965
        
 
966
        cairo_dock_update_removing_inserting_icon_size_default (pIcon);
 
967
        
 
968
        if (fabs (pIcon->fInsertRemoveFactor) > 0.05)
 
969
        {
 
970
                cairo_dock_mark_icon_as_inserting_removing (pIcon);
 
971
                *bContinueAnimation = TRUE;
 
972
        }
 
973
        cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
974
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
975
}
 
976
 
 
977
gboolean cairo_dock_on_insert_remove_icon_notification (gpointer pUserData, Icon *pIcon, CairoDock *pDock)
 
978
{
 
979
        if (pIcon->iAnimationState == CAIRO_DOCK_STATE_REMOVE_INSERT)
 
980
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
981
        
 
982
        pIcon->bBeingRemovedByCairo = TRUE;
 
983
        cairo_dock_mark_icon_as_inserting_removing (pIcon);  // On prend en charge le dessin de l'icone pendant sa phase d'insertion/suppression.
 
984
        
 
985
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
986
}
 
987
 
 
988
gboolean cairo_dock_stop_inserting_removing_icon_notification (gpointer pUserData, Icon *pIcon)
 
989
{
 
990
        pIcon->fGlideOffset = 0;
 
991
        pIcon->iGlideDirection = 0;
 
992
        pIcon->bBeingRemovedByCairo = FALSE;
 
993
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
994
}
 
995
 
 
996
 
 
997
 
 
998
#define cairo_dock_get_transition(pIcon) (pIcon)->pTransition
 
999
 
 
1000
#define cairo_dock_set_transition(pIcon, transition) (pIcon)->pTransition = transition
 
1001
 
 
1002
static gboolean _cairo_dock_transition_step (gpointer pUserData, Icon *pIcon, CairoContainer *pContainer, gboolean *bContinueAnimation)
 
1003
{
 
1004
        CairoDockTransition *pTransition = cairo_dock_get_transition (pIcon);
 
1005
        if (pTransition == NULL)
 
1006
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
1007
        
 
1008
        pTransition->iCount ++;
 
1009
        int iDetlaT = (pTransition->bFastPace ? cairo_dock_get_animation_delta_t (pContainer) : cairo_dock_get_slow_animation_delta_t (pContainer));
 
1010
        //int iNbSteps = 1.*pTransition->iDuration / iDetlaT;
 
1011
        pTransition->iElapsedTime += iDetlaT;
 
1012
        
 
1013
        if (! pTransition->bRemoveWhenFinished && pTransition->iDuration != 0 && pTransition->iElapsedTime > pTransition->iDuration)  // skip
 
1014
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
1015
        
 
1016
        gboolean bContinue = FALSE;
 
1017
        if (CAIRO_CONTAINER_IS_OPENGL (pTransition->pContainer))
 
1018
        {
 
1019
                if (pTransition->render_opengl)
 
1020
                {
 
1021
                        if (! cairo_dock_begin_draw_icon (pIcon, pContainer, 0))
 
1022
                                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
1023
                        bContinue = pTransition->render_opengl (pIcon, pTransition->pUserData);
 
1024
                        cairo_dock_end_draw_icon (pIcon, pContainer);
 
1025
                }
 
1026
                else if (pTransition->pIconContext != NULL)
 
1027
                {
 
1028
                        cairo_dock_erase_cairo_context (pTransition->pIconContext);
 
1029
                        bContinue = pTransition->render (pIcon, pTransition->pUserData, pTransition->pIconContext);
 
1030
                        cairo_dock_update_icon_texture (pIcon);
 
1031
                }
 
1032
        }
 
1033
        else if (pTransition->render && pTransition->pIconContext != NULL)
 
1034
        {
 
1035
                cairo_dock_erase_cairo_context (pTransition->pIconContext);
 
1036
                bContinue = pTransition->render (pIcon, pTransition->pUserData, pTransition->pIconContext);
 
1037
                if (pContainer->bUseReflect)
 
1038
                        cairo_dock_add_reflection_to_icon (pIcon, pContainer);
 
1039
        }
 
1040
        
 
1041
        cairo_dock_redraw_icon (pIcon, pContainer);
 
1042
        
 
1043
        if (pTransition->iDuration != 0 && pTransition->iElapsedTime >= pTransition->iDuration)
 
1044
                bContinue = FALSE;
 
1045
        
 
1046
        if (! bContinue)
 
1047
        {
 
1048
                if (pTransition->bRemoveWhenFinished)
 
1049
                        cairo_dock_remove_transition_on_icon (pIcon);
 
1050
        }
 
1051
        else
 
1052
        {
 
1053
                *bContinueAnimation = TRUE;
 
1054
        }
 
1055
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
1056
}
 
1057
void cairo_dock_set_transition_on_icon (Icon *pIcon, CairoContainer *pContainer, cairo_t *pIconContext, CairoDockTransitionRenderFunc render_step_cairo, CairoDockTransitionGLRenderFunc render_step_opengl, gboolean bFastPace, gint iDuration, gboolean bRemoveWhenFinished, gpointer pUserData, GFreeFunc pFreeUserDataFunc)
 
1058
{
 
1059
        cairo_dock_remove_transition_on_icon (pIcon);
 
1060
        
 
1061
        CairoDockTransition *pTransition = g_new0 (CairoDockTransition, 1);
 
1062
        pTransition->render = render_step_cairo;
 
1063
        pTransition->render_opengl = render_step_opengl;
 
1064
        pTransition->bFastPace = bFastPace;
 
1065
        pTransition->iDuration = iDuration;
 
1066
        pTransition->bRemoveWhenFinished = bRemoveWhenFinished;
 
1067
        pTransition->pContainer = pContainer;
 
1068
        pTransition->pIconContext = pIconContext;
 
1069
        pTransition->pUserData = pUserData;
 
1070
        pTransition->pFreeUserDataFunc = pFreeUserDataFunc;
 
1071
        cairo_dock_set_transition (pIcon, pTransition);
 
1072
        
 
1073
        cairo_dock_register_notification_on_icon (pIcon, bFastPace ? CAIRO_DOCK_UPDATE_ICON : CAIRO_DOCK_UPDATE_ICON_SLOW,
 
1074
                (CairoDockNotificationFunc) _cairo_dock_transition_step, CAIRO_DOCK_RUN_AFTER, pUserData);
 
1075
        
 
1076
        cairo_dock_launch_animation (pContainer);
 
1077
}
 
1078
 
 
1079
void cairo_dock_remove_transition_on_icon (Icon *pIcon)
 
1080
{
 
1081
        CairoDockTransition *pTransition = cairo_dock_get_transition (pIcon);
 
1082
        if (pTransition == NULL)
 
1083
                return ;
 
1084
        
 
1085
        cairo_dock_remove_notification_func_on_icon (pIcon, pTransition->bFastPace ? CAIRO_DOCK_UPDATE_ICON : CAIRO_DOCK_UPDATE_ICON_SLOW,
 
1086
                (CairoDockNotificationFunc) _cairo_dock_transition_step,
 
1087
                pTransition->pUserData);
 
1088
        
 
1089
        if (pTransition->pFreeUserDataFunc != NULL)
 
1090
                pTransition->pFreeUserDataFunc (pTransition->pUserData);
 
1091
        g_free (pTransition);
 
1092
        cairo_dock_set_transition (pIcon, NULL);
 
1093
}