~ubuntu-branches/ubuntu/oneiric/cairo-dock-plug-ins/oneiric-updates

« back to all changes in this revision

Viewing changes to Cairo-Penguin/src/applet-animation.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
ImportĀ upstreamĀ versionĀ 2.0.8.1

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
/******************************************************************************
 
21
 
 
22
This file is a part of the cairo-dock program, 
 
23
released under the terms of the GNU General Public License.
 
24
 
 
25
Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
 
26
 
 
27
******************************************************************************/
 
28
 
 
29
#include <stdlib.h>
 
30
#include <string.h>
 
31
#include <math.h>
 
32
 
 
33
#include "applet-struct.h"
 
34
#include "applet-notifications.h"
 
35
#include "applet-theme.h"
 
36
#include "applet-animation.h"
 
37
 
 
38
 
 
39
void penguin_move_in_dock (CairoDockModuleInstance *myApplet)
 
40
{
 
41
        static GdkRectangle area;
 
42
        if (! cairo_dock_animation_will_be_visible (myDock))
 
43
                return ;
 
44
        
 
45
        PenguinAnimation *pAnimation = penguin_get_current_animation ();
 
46
        g_return_if_fail (pAnimation != NULL);
 
47
        int iPreviousPositionX = myData.iCurrentPositionX, iPreviousPositionY = myData.iCurrentPositionY;
 
48
        
 
49
        Icon *pFirstDrawnIcon = NULL;
 
50
        if (myDock->pFirstDrawnElement != NULL)
 
51
                pFirstDrawnIcon = myDock->pFirstDrawnElement->data;
 
52
        if (pFirstDrawnIcon == NULL && myDock->icons != NULL)
 
53
                pFirstDrawnIcon = myDock->icons->data;
 
54
        int iXMin = (pFirstDrawnIcon != NULL ? pFirstDrawnIcon->fXAtRest : 0);
 
55
        int iXMax = iXMin + myDock->fFlatDockWidth;
 
56
        int iHeight = myDock->iCurrentHeight;
 
57
        
 
58
        penguin_calculate_new_position (myApplet, pAnimation, iXMin, iXMax, iHeight);
 
59
        
 
60
        area.x = (int) ((myDock->iCurrentWidth - myDock->fFlatDockWidth) / 2 + MIN (iPreviousPositionX, myData.iCurrentPositionX));
 
61
        area.y = myDock->iCurrentHeight - MAX (iPreviousPositionY, myData.iCurrentPositionY) - pAnimation->iFrameHeight;
 
62
        area.width = abs (iPreviousPositionX - myData.iCurrentPositionX) + pAnimation->iFrameWidth;
 
63
        area.height = abs (iPreviousPositionY - myData.iCurrentPositionY) + pAnimation->iFrameHeight;
 
64
        
 
65
        cairo_dock_redraw_container_area (myContainer, &area);
 
66
        
 
67
        penguin_advance_to_next_frame (myApplet, pAnimation);
 
68
}
 
69
 
 
70
static void _penguin_draw_texture (CairoDockModuleInstance *myApplet, PenguinAnimation *pAnimation, double fOffsetX, double fOffsetY, double fScale)
 
71
{
 
72
        g_return_if_fail (pAnimation->iTexture != 0);
 
73
        int iIconWidth, iIconHeight;
 
74
        cairo_dock_get_icon_extent (myIcon, myContainer, &iIconWidth, &iIconHeight);
 
75
        
 
76
        _cairo_dock_enable_texture ();
 
77
        _cairo_dock_set_blend_alpha ();
 
78
        _cairo_dock_set_alpha (1.);
 
79
        
 
80
        glBindTexture (GL_TEXTURE_2D, pAnimation->iTexture);
 
81
        _cairo_dock_apply_current_texture_portion_at_size_with_offset (1.*myData.iCurrentFrame/pAnimation->iNbFrames, 
 
82
                .5*myData.iCurrentDirection, 1./pAnimation->iNbFrames, 1./pAnimation->iNbDirections,
 
83
                pAnimation->iFrameWidth*fScale, pAnimation->iFrameHeight*fScale,
 
84
                fOffsetX + myData.iCurrentPositionX, fOffsetY + myData.iCurrentPositionY + pAnimation->iFrameHeight*fScale/2);
 
85
        _cairo_dock_disable_texture ();
 
86
        
 
87
        /*glEnable (GL_SCISSOR_TEST);
 
88
        glScissor ((fOffsetX + myData.iCurrentPositionX) * fScale,
 
89
                (fOffsetY * fScale + myData.iCurrentPositionY) * fScale,
 
90
                pAnimation->iFrameWidth * fScale,
 
91
                pAnimation->iFrameHeight * fScale);
 
92
        
 
93
        glTranslatef ((fOffsetX + myData.iCurrentPositionX + pAnimation->iFrameWidth * (.5 * pAnimation->iNbFrames - myData.iCurrentFrame)) * fScale,
 
94
                (fOffsetY * fScale + myData.iCurrentPositionY + pAnimation->iFrameHeight * (-.5 * pAnimation->iNbDirections + 1 + (myData.iCurrentDirection)) * fScale),
 
95
                0.);
 
96
        
 
97
        glColor4f (1., 1., 1., 1.);
 
98
        cairo_dock_draw_texture (pAnimation->iTexture,
 
99
                pAnimation->iFrameWidth * pAnimation->iNbFrames * fScale,
 
100
                pAnimation->iFrameHeight * pAnimation->iNbDirections * fScale);
 
101
        
 
102
        glDisable (GL_SCISSOR_TEST);*/
 
103
}
 
104
void penguin_draw_on_dock_opengl (CairoDockModuleInstance *myApplet, CairoContainer *pContainer)
 
105
{
 
106
        PenguinAnimation *pAnimation = penguin_get_current_animation ();
 
107
        if (pAnimation == NULL)
 
108
                return ;
 
109
        
 
110
        glPushMatrix ();
 
111
        glLoadIdentity ();
 
112
        
 
113
        _penguin_draw_texture (myApplet, pAnimation, (myDock->iCurrentWidth - myDock->fFlatDockWidth) * .5, 0., 1.);
 
114
        
 
115
        glPopMatrix ();
 
116
}
 
117
 
 
118
void penguin_draw_on_dock (CairoDockModuleInstance *myApplet, CairoContainer *pContainer, cairo_t *pCairoContext)
 
119
{
 
120
        PenguinAnimation *pAnimation = penguin_get_current_animation ();
 
121
        if (pAnimation == NULL)
 
122
                return ;
 
123
        
 
124
        g_return_if_fail (pAnimation->pSurfaces != NULL);
 
125
        cairo_surface_t *pSurface = pAnimation->pSurfaces[myData.iCurrentDirection][myData.iCurrentFrame];
 
126
        
 
127
        cairo_save (pCairoContext);
 
128
        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
 
129
        cairo_translate (pCairoContext, floor ((myDock->iCurrentWidth - myDock->fFlatDockWidth) / 2 + myData.iCurrentPositionX), myDock->iCurrentHeight - myData.iCurrentPositionY - pAnimation->iFrameHeight);
 
130
        cairo_set_source_surface (pCairoContext, pSurface, 0.0, 0.0);
 
131
        cairo_paint (pCairoContext);
 
132
        cairo_restore (pCairoContext);
 
133
}
 
134
gboolean penguin_render_on_container (CairoDockModuleInstance *myApplet, CairoContainer *pContainer, cairo_t *pCairoContext)
 
135
{
 
136
        if (pContainer != myContainer)
 
137
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
138
        if (! cairo_dock_animation_will_be_visible (myDock))
 
139
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
140
        
 
141
        if (pCairoContext != NULL)
 
142
                penguin_draw_on_dock (myApplet, pContainer, pCairoContext);
 
143
        else
 
144
                penguin_draw_on_dock_opengl (myApplet, pContainer);
 
145
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
146
}
 
147
 
 
148
 
 
149
 
 
150
void penguin_move_in_icon (CairoDockModuleInstance *myApplet)
 
151
{
 
152
        if (! cairo_dock_animation_will_be_visible (myDock))
 
153
                return ;
 
154
        
 
155
        PenguinAnimation *pAnimation = penguin_get_current_animation ();
 
156
        g_return_if_fail (pAnimation != NULL);
 
157
        
 
158
        double fScale = (pAnimation->iNbFrames > 1 || pAnimation->iSpeed != 0 || pAnimation->iAcceleration != 0 ? myIcon->fScale : 1.);  // s'il est a l'arret on le met a la taille de l'icone au repos.
 
159
        int iWidth = myIcon->fWidth / myDock->fRatio * fScale;
 
160
        int iHeight = myIcon->fHeight / myDock->fRatio * fScale;
 
161
        int iXMin = - iWidth / 2;
 
162
        int iXMax = - iXMin;
 
163
        
 
164
        penguin_calculate_new_position (myApplet, pAnimation, iXMin, iXMax, iHeight);
 
165
        
 
166
        if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
 
167
        {
 
168
                if (! cairo_dock_begin_draw_icon (myIcon, myContainer))
 
169
                        return ;
 
170
                
 
171
                int iIconWidth, iIconHeight;
 
172
                cairo_dock_get_icon_extent (myIcon, myContainer, &iIconWidth, &iIconHeight);
 
173
                
 
174
                g_return_if_fail (pAnimation->iTexture != 0);
 
175
                double f = (1 + g_fAmplitude) / fScale;
 
176
                double x, y;  // centre du pingouin, en coordonnĆ©es absolues.
 
177
                x = myData.iCurrentPositionX - iXMin - iIconWidth/2 + pAnimation->iFrameWidth/2*f;
 
178
                y = myData.iCurrentPositionY + pAnimation->iFrameHeight/2*f;
 
179
                
 
180
                _cairo_dock_enable_texture ();
 
181
                _cairo_dock_set_blend_alpha ();
 
182
                _cairo_dock_set_alpha (1.);
 
183
                
 
184
                glBindTexture (GL_TEXTURE_2D, pAnimation->iTexture);
 
185
                _cairo_dock_apply_current_texture_portion_at_size_with_offset (1.*myData.iCurrentFrame/pAnimation->iNbFrames, 
 
186
                        .5*myData.iCurrentDirection, 1./pAnimation->iNbFrames, 1./pAnimation->iNbDirections,
 
187
                        pAnimation->iFrameWidth*f, pAnimation->iFrameHeight*f,
 
188
                        x, - iIconHeight/2 + y);
 
189
                _cairo_dock_disable_texture ();
 
190
                
 
191
                cairo_dock_end_draw_icon (myIcon, myContainer);
 
192
        }
 
193
        else
 
194
        {
 
195
                g_return_if_fail (pAnimation->pSurfaces != NULL);
 
196
                cairo_surface_t *pSurface = pAnimation->pSurfaces[myData.iCurrentDirection][myData.iCurrentFrame];
 
197
                g_return_if_fail (pSurface != NULL);
 
198
                
 
199
                //\________________ On efface l'ancienne image.
 
200
                cairo_set_source_rgba (myDrawContext, 0.0, 0.0, 0.0, 0.0);
 
201
                cairo_set_operator (myDrawContext, CAIRO_OPERATOR_SOURCE);
 
202
                cairo_paint (myDrawContext);
 
203
                cairo_set_operator (myDrawContext, CAIRO_OPERATOR_OVER);
 
204
                
 
205
                //\________________ On applique la nouvelle image.
 
206
                if (pSurface != NULL)
 
207
                {
 
208
                        cairo_save (myDrawContext);
 
209
                        cairo_scale (myDrawContext, (1 + g_fAmplitude) / fScale, (1 + g_fAmplitude) / fScale);
 
210
                        cairo_set_source_surface (
 
211
                                myDrawContext,
 
212
                                pSurface,
 
213
                                iXMax + myData.iCurrentPositionX,
 
214
                                iHeight - myData.iCurrentPositionY - pAnimation->iFrameHeight);
 
215
                        cairo_paint (myDrawContext);
 
216
                        cairo_restore (myDrawContext);
 
217
                }
 
218
                
 
219
                //\________________ les reflets.
 
220
                CD_APPLET_UPDATE_REFLECT_ON_MY_ICON;
 
221
        }
 
222
        
 
223
        CD_APPLET_REDRAW_MY_ICON;
 
224
        
 
225
        penguin_advance_to_next_frame (myApplet, pAnimation);
 
226
}
 
227
 
 
228
 
 
229
 
 
230
void penguin_calculate_new_position (CairoDockModuleInstance *myApplet, PenguinAnimation *pAnimation, int iXMin, int iXMax, int iHeight)
 
231
{
 
232
        //\________________ On calule la nouvelle vitesse.
 
233
        if (pAnimation->iAcceleration != 0 && myData.iCurrentSpeed != pAnimation->iTerminalVelocity)
 
234
        {
 
235
                myData.iCurrentSpeed += pAnimation->iAcceleration;
 
236
                if ( (pAnimation->iAcceleration > 0 && myData.iCurrentSpeed > pAnimation->iTerminalVelocity) || (pAnimation->iAcceleration < 0 && myData.iCurrentSpeed < pAnimation->iTerminalVelocity))
 
237
                        myData.iCurrentSpeed = pAnimation->iTerminalVelocity;
 
238
        }
 
239
        
 
240
        //\________________ On calule la nouvelle position.
 
241
        int sens;
 
242
        if (pAnimation->iDirection == PENGUIN_HORIZONTAL)
 
243
        {
 
244
                sens = (myData.iCurrentDirection == 0 ? -1 : 1);
 
245
                myData.iCurrentPositionX += sens * myData.iCurrentSpeed;
 
246
        }
 
247
        else
 
248
        {
 
249
                sens = (pAnimation->iDirection == PENGUIN_UP ? 1 : -1);
 
250
                myData.iCurrentPositionY += sens * myData.iCurrentSpeed;
 
251
        }
 
252
        
 
253
        //\________________ On tient compte des contraintes.
 
254
        if (myData.iCurrentPositionX < iXMin || myData.iCurrentPositionX + pAnimation->iFrameWidth > iXMax)
 
255
        {
 
256
                if (myData.iCurrentPositionX < iXMin)
 
257
                        myData.iCurrentPositionX = iXMin;
 
258
                else
 
259
                        myData.iCurrentPositionX = iXMax - pAnimation->iFrameWidth;
 
260
                if (pAnimation->iDirection == PENGUIN_HORIZONTAL && myConfig.bFree)  // dans l'icone on continue l'animation.
 
261
                {
 
262
                        if (pAnimation->iNbDirections == 2) // on peut repartir dans l'autre sens ou remonter.
 
263
                        {
 
264
                                int iRandom = g_random_int_range (0, 3);
 
265
                                if (iRandom == 0)  // 1 chance sur 3.
 
266
                                {
 
267
                                        myData.iCurrentDirection = 1 - myData.iCurrentDirection;
 
268
                                        cd_debug ("myData.iCurrentDirection <- %d", myData.iCurrentDirection);
 
269
                                }
 
270
                                else
 
271
                                {
 
272
                                        int iNewAnimation = penguin_choose_go_up_animation (myApplet);
 
273
                                        penguin_set_new_animation (myApplet, iNewAnimation);
 
274
                                }
 
275
                        }
 
276
                        else  // on remonte.
 
277
                        {
 
278
                                int iNewAnimation = penguin_choose_go_up_animation (myApplet);
 
279
                                penguin_set_new_animation (myApplet, iNewAnimation);
 
280
                        }
 
281
                }
 
282
        }
 
283
        
 
284
        if (myData.iCurrentPositionY < (myConfig.bFree ? myBackground.iDockLineWidth + myConfig.iGroundOffset : 0))
 
285
        {
 
286
                myData.iCurrentPositionY = (myConfig.bFree ? myBackground.iDockLineWidth + myConfig.iGroundOffset : 0);
 
287
        }
 
288
        else if (myData.iCurrentPositionY + pAnimation->iFrameHeight > iHeight)
 
289
        {
 
290
                myData.iCurrentPositionY = iHeight - pAnimation->iFrameHeight;
 
291
        }
 
292
}
 
293
 
 
294
 
 
295
 
 
296
void penguin_advance_to_next_frame (CairoDockModuleInstance *myApplet, PenguinAnimation *pAnimation)
 
297
{
 
298
        myData.iCurrentFrame ++;
 
299
        if (myData.iCurrentFrame >= pAnimation->iNbFrames)
 
300
        {
 
301
                myData.iCurrentFrame = 0;
 
302
                myData.iCount ++;
 
303
                if (( myData.iCount * myData.fFrameDelay * pAnimation->iNbFrames > myConfig.iDelayBetweenChanges) || pAnimation->bEnding)  // il est temps de changer d'animation.
 
304
                {
 
305
                        if (pAnimation->bEnding)
 
306
                        {
 
307
                                myData.iSleepingTime = 0;
 
308
                                if (! myConfig.bFree)
 
309
                                {
 
310
                                        cairo_save (myDrawContext);  // on n'utilise pas CD_APPLET_SET_SURFACE_ON_MY_ICON (NULL) car il nous cree le pFullIconBuffer qui apres ecrase notre dessin.
 
311
                                        cairo_set_operator (myDrawContext, CAIRO_OPERATOR_SOURCE);
 
312
                                        cairo_set_source_rgba (
 
313
                                                myDrawContext,
 
314
                                                0, 0, 0, 0);
 
315
                                        cairo_paint (myDrawContext);
 
316
                                        cairo_restore (myDrawContext);
 
317
                                        
 
318
                                        if (myIcon->pReflectionBuffer != NULL)
 
319
                                        {
 
320
                                                cairo_surface_destroy (myIcon->pReflectionBuffer);
 
321
                                                myIcon->pReflectionBuffer = NULL;
 
322
                                        }
 
323
                                         if (CAIRO_DOCK_CONTAINER_IS_OPENGL (myContainer))
 
324
                                                cairo_dock_update_icon_texture (myIcon);
 
325
                                        else
 
326
                                                CD_APPLET_REDRAW_MY_ICON;
 
327
                                }
 
328
                                else  // on reste sur la derniere image de l'animation de fin.
 
329
                                {
 
330
                                        myData.iCurrentFrame = pAnimation->iNbFrames - 1;
 
331
                                }
 
332
                                
 
333
                                penguin_start_animating_with_delay (myApplet);
 
334
                        }
 
335
                        else
 
336
                        {
 
337
                                int iNewAnimation = penguin_choose_next_animation (myApplet, pAnimation);
 
338
                                penguin_set_new_animation (myApplet, iNewAnimation);
 
339
                        }
 
340
                }
 
341
        }
 
342
}
 
343
 
 
344
 
 
345
 
 
346
int penguin_choose_movement_animation (CairoDockModuleInstance *myApplet)
 
347
{
 
348
        cd_debug ("");
 
349
        if (myData.iNbMovmentAnimations == 0)
 
350
                return 0;
 
351
        else
 
352
        {
 
353
                int iRandom = g_random_int_range (0, myData.iNbMovmentAnimations);  // [a;b[
 
354
                //g_print (  "0<%d<%d => %d\n", iRandom, myData.iNbMovmentAnimations, myData.pMovmentAnimations[iRandom]);
 
355
                return myData.pMovmentAnimations[iRandom];
 
356
        }
 
357
}
 
358
 
 
359
int penguin_choose_go_up_animation (CairoDockModuleInstance *myApplet)
 
360
{
 
361
        cd_debug ("");
 
362
        if (myData.iNbGoUpAnimations == 0)
 
363
                return penguin_choose_movement_animation (myApplet);
 
364
        else
 
365
        {
 
366
                int iRandom = g_random_int_range (0, myData.iNbGoUpAnimations);  // [a;b[
 
367
                //g_print (  "0<%d<%d => %d\n", iRandom, myData.iNbGoUpAnimations, myData.pGoUpAnimations[iRandom]);
 
368
                return myData.pGoUpAnimations[iRandom];
 
369
        }
 
370
}
 
371
 
 
372
int penguin_choose_beginning_animation (CairoDockModuleInstance *myApplet)
 
373
{
 
374
        cd_debug ("");
 
375
        if (myData.iNbBeginningAnimations == 0)
 
376
                return penguin_choose_movement_animation (myApplet);
 
377
        else
 
378
        {
 
379
                int iRandom = g_random_int_range (0, myData.iNbBeginningAnimations);  // [a;b[
 
380
                //g_print (  "0<%d<%d => %d\n", iRandom, myData.iNbBeginningAnimations, myData.pBeginningAnimations[iRandom]);
 
381
                return myData.pBeginningAnimations[iRandom];
 
382
        }
 
383
}
 
384
 
 
385
int penguin_choose_ending_animation (CairoDockModuleInstance *myApplet)
 
386
{
 
387
        cd_debug ("");
 
388
        if (myData.iNbEndingAnimations == 0)
 
389
                return penguin_choose_go_up_animation (myApplet);
 
390
        else
 
391
        {
 
392
                int iRandom = g_random_int_range (0, myData.iNbEndingAnimations);  // [a;b[
 
393
                //g_print (  "0<%d<%d => %d\n", iRandom, myData.iNbEndingAnimations, myData.pEndingAnimations[iRandom]);
 
394
                return myData.pEndingAnimations[iRandom];
 
395
        }
 
396
}
 
397
 
 
398
int penguin_choose_resting_animation (CairoDockModuleInstance *myApplet)
 
399
{
 
400
        cd_debug ("");
 
401
        if (myData.iNbRestAnimations == 0)
 
402
                return penguin_choose_go_up_animation (myApplet);
 
403
        else
 
404
        {
 
405
                int iRandom = g_random_int_range (0, myData.iNbRestAnimations);  // [a;b[
 
406
                //g_print (  "0<%d<%d => %d\n", iRandom, myData.iNbRestAnimations, myData.pRestAnimations[iRandom]);
 
407
                return myData.pRestAnimations[iRandom];
 
408
        }
 
409
}
 
410
 
 
411
int penguin_choose_next_animation (CairoDockModuleInstance *myApplet, PenguinAnimation *pAnimation)
 
412
{
 
413
        cd_debug ("");
 
414
        int iNewAnimation;
 
415
        if (pAnimation == NULL || pAnimation->bEnding)  // le pingouin est en fin d'animation, on le relance.
 
416
        {
 
417
                iNewAnimation = penguin_choose_beginning_animation (myApplet);
 
418
        }
 
419
        else if (pAnimation->iDirection == PENGUIN_HORIZONTAL)  // le pingouin se deplace.
 
420
        {
 
421
                if (myConfig.bFree)
 
422
                        iNewAnimation = penguin_choose_movement_animation (myApplet);
 
423
                else  // dans l'icone on ne repart pas en haut sur les bords.
 
424
                {
 
425
                        int iRandom = g_random_int_range (0, 3);
 
426
                        if (iRandom == 0)
 
427
                                iNewAnimation = penguin_choose_go_up_animation (myApplet);
 
428
                        else
 
429
                                iNewAnimation = penguin_choose_movement_animation (myApplet);
 
430
                }
 
431
        }
 
432
        else  // le pingouin monte ou descend.
 
433
        {
 
434
                if (pAnimation->iDirection == PENGUIN_UP)  // il monte, on le refait descendre.
 
435
                        iNewAnimation = penguin_choose_beginning_animation (myApplet);
 
436
                else  // il descend, on le fait se deplacer.
 
437
                        iNewAnimation = penguin_choose_movement_animation (myApplet);
 
438
        }
 
439
        return iNewAnimation;
 
440
}
 
441
 
 
442
 
 
443
void penguin_set_new_animation (CairoDockModuleInstance *myApplet, int iNewAnimation)
 
444
{
 
445
        cd_message ("%s (%d)", __func__, iNewAnimation);
 
446
        PenguinAnimation *pPreviousAnimation = penguin_get_current_animation ();
 
447
        int iPreviousWidth = (pPreviousAnimation != NULL ? pPreviousAnimation->iFrameWidth : 0);
 
448
        int iPreviousHeight = (pPreviousAnimation != NULL ? pPreviousAnimation->iFrameHeight : 0);
 
449
        int iPreviousDirection = (pPreviousAnimation != NULL ? pPreviousAnimation->iDirection : 0);
 
450
        
 
451
        myData.iCurrentAnimation = iNewAnimation;
 
452
        myData.iCurrentFrame = 0;
 
453
        myData.iCount = 0;
 
454
        PenguinAnimation *pAnimation = penguin_get_current_animation ();
 
455
        if (pAnimation == NULL)
 
456
                return ;
 
457
        myData.iCurrentSpeed = pAnimation->iSpeed;
 
458
        
 
459
        if (pAnimation->pSurfaces == NULL && pAnimation->iTexture == 0)
 
460
        {
 
461
                penguin_load_animation_buffer (pAnimation, myDrawContext, myConfig.fAlpha, CAIRO_DOCK_CONTAINER_IS_OPENGL (myContainer));
 
462
        }
 
463
        
 
464
        if (pAnimation->iDirection == PENGUIN_HORIZONTAL)
 
465
        {
 
466
                if (pAnimation->iNbDirections == 2)
 
467
                        myData.iCurrentDirection = g_random_int_range (0, 2);  // [a;b[
 
468
                else
 
469
                        myData.iCurrentDirection = 0;
 
470
                myData.iCurrentPositionY = (myConfig.bFree ? myBackground.iDockLineWidth + myConfig.iGroundOffset : 0);
 
471
        }
 
472
        else  // la direction reste la meme.
 
473
        {
 
474
                myData.iCurrentDirection = MIN (myData.iCurrentDirection, pAnimation->iNbDirections - 1);
 
475
                if (myData.iCurrentDirection == 1)  // on plaque a droite.
 
476
                        myData.iCurrentPositionX += iPreviousWidth - pAnimation->iFrameWidth;
 
477
                if (pAnimation->iDirection == PENGUIN_DOWN)
 
478
                {
 
479
                        if (myConfig.bFree)
 
480
                                myData.iCurrentPositionY = myContainer->iHeight;
 
481
                        else
 
482
                                myData.iCurrentPositionY = myIcon->fHeight / myDock->fRatio * myIcon->fScale;
 
483
                }
 
484
        }
 
485
}
 
486
 
 
487
 
 
488
gboolean penguin_update_container (CairoDockModuleInstance *myApplet, CairoContainer *pContainer, gboolean *bContinueAnimation)
 
489
{
 
490
        if (pContainer != myContainer)
 
491
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
492
        
 
493
        penguin_move_in_dock (myApplet);
 
494
        *bContinueAnimation = TRUE;
 
495
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
496
}
 
497
 
 
498
gboolean penguin_update_icon (CairoDockModuleInstance *myApplet, Icon *pIcon, CairoContainer *pContainer, gboolean *bContinueAnimation)
 
499
{
 
500
        if (pIcon != myIcon)
 
501
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
502
        
 
503
        penguin_move_in_icon (myApplet);
 
504
        *bContinueAnimation = TRUE;
 
505
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
506
}
 
507
 
 
508
 
 
509
void penguin_start_animating (CairoDockModuleInstance *myApplet)
 
510
{
 
511
        int iNewAnimation = penguin_choose_beginning_animation (myApplet);
 
512
        penguin_set_new_animation (myApplet, iNewAnimation);
 
513
        
 
514
        cairo_dock_remove_notification_func (CAIRO_DOCK_UPDATE_ICON_SLOW, (CairoDockNotificationFunc) penguin_update_icon, myApplet);
 
515
        cairo_dock_remove_notification_func (CAIRO_DOCK_UPDATE_DOCK_SLOW, (CairoDockNotificationFunc) penguin_update_container, myApplet);
 
516
        cairo_dock_remove_notification_func (CAIRO_DOCK_RENDER_DOCK, (CairoDockNotificationFunc) penguin_render_on_container, myApplet);
 
517
        if (myConfig.bFree)
 
518
        {
 
519
                cairo_dock_register_notification (CAIRO_DOCK_UPDATE_DOCK_SLOW, (CairoDockNotificationFunc) penguin_update_container, CAIRO_DOCK_RUN_AFTER, myApplet);
 
520
                cairo_dock_register_notification (CAIRO_DOCK_RENDER_DOCK, (CairoDockNotificationFunc) penguin_render_on_container, CAIRO_DOCK_RUN_AFTER, myApplet);
 
521
        }
 
522
        else
 
523
        {
 
524
                cairo_dock_register_notification (CAIRO_DOCK_UPDATE_ICON_SLOW, (CairoDockNotificationFunc) penguin_update_icon, CAIRO_DOCK_RUN_AFTER, myApplet);
 
525
        }
 
526
}
 
527
 
 
528
static gboolean _penguin_restart_delayed (CairoDockModuleInstance *myApplet)
 
529
{
 
530
        myData.iSidRestartDelayed = 0;
 
531
        penguin_start_animating (myApplet);
 
532
        
 
533
        if (! myData.bHasBeenStarted)
 
534
        {
 
535
                myData.bHasBeenStarted = TRUE;
 
536
                cd_message ("le pingouin demarre pour la 1ere fois");
 
537
                
 
538
                if (myConfig.bFree)  // attention : c'est un hack moyen; il faudrait pouvoir indiquer a cairo-dock de ne pas inserer notre icone...
 
539
                {
 
540
                        cairo_dock_detach_icon_from_dock (myIcon, myDock, myIcons.bUseSeparator);
 
541
                        cairo_dock_update_dock_size (myDock);
 
542
                }
 
543
                else
 
544
                {
 
545
                        cairo_dock_insert_icon_in_dock (myIcon, myDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
 
546
                }
 
547
        }
 
548
        
 
549
        return FALSE;
 
550
}
 
551
void penguin_start_animating_with_delay (CairoDockModuleInstance *myApplet)
 
552
{
 
553
        if (myData.iSidRestartDelayed != 0)
 
554
                return ;
 
555
        if (cairo_dock_is_loading ())
 
556
        {
 
557
                myData.iSidRestartDelayed = g_timeout_add_seconds (2, (GSourceFunc) _penguin_restart_delayed, (gpointer) myApplet);  // priorite au chargement du dock, on demarrera plus tard.
 
558
        }
 
559
        else
 
560
        {
 
561
                myData.iSidRestartDelayed = g_timeout_add_seconds (1, (GSourceFunc) _penguin_restart_delayed, (gpointer) myApplet);  // on est oblige de faire ca, pour detacher l'icone apres que le dock l'ait inseree.
 
562
                //myData.iSidRestartDelayed = g_idle_add ((GSourceFunc) _penguin_restart_delayed, (gpointer) myApplet);  // on est oblige de faire ca, pour detacher l'icone apres que le dock l'ait inseree.
 
563
        }
 
564
}