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