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 <stdio.h>
23 #include <stdlib.h>
24 
25 #include <gtk/gtk.h>
26 
27 #include <cairo.h>
28 
29 #include "rendering-caroussel.h"
30 
31 extern double my_fInclinationOnHorizon;
32 
33 extern double my_fForegroundRatio;
34 extern double my_iGapOnEllipse;
35 extern gboolean my_bRotateIconsOnEllipse;
36 extern double my_fScrollAcceleration;
37 extern double my_fScrollSpeed;
38 
39 /*void cd_rendering_set_subdock_position_caroussel (Icon *pPointedIcon, CairoDock *pDock)
40 {
41 	CairoDock *pSubDock = pPointedIcon->pSubDock;
42 	int iMouseX = pDock->container.iMouseX;
43 	int iX = iMouseX + (-iMouseX + pPointedIcon->fDrawX + pPointedIcon->fWidth * pPointedIcon->fScale / 2) / 2;
44 	//int iX = iMouseX + (iMouseX < pPointedIcon->fDrawX + pPointedIcon->fWidth * pPointedIcon->fScale / 2 ? (pDock->container.bDirectionUp ? 1 : 0) : (pDock->container.bDirectionUp ? 0 : -1)) * pPointedIcon->fWidth * pPointedIcon->fScale / 2;
45 	if (pSubDock->container.bIsHorizontal == pDock->container.bIsHorizontal)
46 	{
47 		pSubDock->fAlign = 0.5;
48 		pSubDock->iGapX = iX + pDock->container.iWindowPositionX - g_desktopGeometry.iXScreenWidth[pDock->container.bIsHorizontal] / 2;  // les sous-dock ont un alignement egal a 0.5.  // pPointedIcon->fDrawX + pPointedIcon->fWidth * pPointedIcon->fScale / 2
49 		pSubDock->iGapY = pDock->iGapY + pDock->iMaxDockHeight;
50 	}
51 	else
52 	{
53 		pSubDock->fAlign = (pDock->container.bDirectionUp ? 1 : 0);
54 		pSubDock->iGapX = (pDock->iGapY + pDock->iMaxDockHeight) * (pDock->container.bDirectionUp ? -1 : 1);
55 		if (pDock->container.bDirectionUp)
56 			pSubDock->iGapY = g_desktopGeometry.iXScreenWidth[pDock->container.bIsHorizontal] - (iX + pDock->container.iWindowPositionX) - pSubDock->iMaxDockHeight / 2;  // les sous-dock ont un alignement egal a 1.
57 		else
58 			pSubDock->iGapY = iX + pDock->container.iWindowPositionX - pSubDock->iMaxDockHeight / 2;  // les sous-dock ont un alignement egal a 0.
59 	}
60 }*/
61 
62 
cd_rendering_calculate_max_dock_size_caroussel(CairoDock * pDock)63 void cd_rendering_calculate_max_dock_size_caroussel (CairoDock *pDock)
64 {
65 	cairo_dock_calculate_icons_positions_at_rest_linear (pDock->icons, pDock->fFlatDockWidth, pDock->iScrollOffset);
66 
67 	int iEllipseHeight = (1 + myIconsParam.fAmplitude) * pDock->iMaxIconHeight / sqrt (1 + my_fInclinationOnHorizon * my_fInclinationOnHorizon) + my_iGapOnEllipse;
68 	pDock->iDecorationsHeight = iEllipseHeight + 2 * myDocksParam.iFrameMargin + myIconsParam.fReflectSize;
69 
70 	double fExtraWidth = cairo_dock_calculate_extra_width_for_trapeze (pDock->iDecorationsHeight, my_fInclinationOnHorizon, myDocksParam.iDockRadius, myDocksParam.iDockLineWidth);
71 	pDock->iMaxDockWidth = ceil (cairo_dock_calculate_max_dock_width (pDock, pDock->fFlatDockWidth, my_fForegroundRatio, fExtraWidth));  // fExtraWidth/2 de chaque cote.
72 	///pDock->iMaxDockWidth = MIN (pDock->iMaxDockWidth, g_iMaxAuthorizedWidth);
73 
74 	pDock->iMaxDockHeight = myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin + myIconsParam.fReflectSize + iEllipseHeight + pDock->iMaxIconHeight;  // de bas en haut;
75 	pDock->iMaxDockHeight = MAX (pDock->iMaxDockHeight, myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin + (1 + myIconsParam.fAmplitude) * pDock->iMaxIconHeight + myIconsParam.fReflectSize + myIconsParam.iLabelSize);
76 
77 	pDock->iDecorationsWidth = pDock->iMaxDockWidth;
78 
79 	pDock->iMinDockHeight = pDock->iMaxIconHeight + myIconsParam.fReflectSize + 2 * myDocksParam.iFrameMargin + 2 * myDocksParam.iDockLineWidth;
80 
81 	fExtraWidth = cairo_dock_calculate_extra_width_for_trapeze (pDock->iMinDockHeight, my_fInclinationOnHorizon, myDocksParam.iDockRadius, myDocksParam.iDockLineWidth);
82 	pDock->iMinDockWidth = MIN (pDock->iMaxDockWidth, pDock->fFlatDockWidth + fExtraWidth);
83 
84 	if (pDock->pRendererData == NULL)
85 	{
86 		pDock->pRendererData = GINT_TO_POINTER (1);
87 		gldi_object_register_notification (pDock, NOTIFICATION_UPDATE, (GldiNotificationFunc) cd_rendering_caroussel_update_dock, GLDI_RUN_AFTER, NULL);
88 	}
89 
90 	if (g_bEasterEggs)
91 	{
92 		pDock->iMinDockWidth = pDock->fFlatDockWidth/2;
93 	}
94 }
95 
96 
cd_rendering_calculate_construction_parameters_caroussel(Icon * icon,int iWidth,int iHeight,int iMaxIconHeight,int iMaxIconWidth,int iEllipseHeight,gboolean bDirectionUp,double fExtraWidth,double fLinearWidth,double fXFirstIcon)97 void cd_rendering_calculate_construction_parameters_caroussel (Icon *icon, int iWidth, int iHeight, int iMaxIconHeight, int iMaxIconWidth, int iEllipseHeight, gboolean bDirectionUp, double fExtraWidth, double fLinearWidth, double fXFirstIcon)
98 {
99 	double fXIconCenter = icon->fX + icon->fWidth * icon->fScale / 2 - fXFirstIcon;  // abscisse du centre de l'icone.
100 	double fTheta = (fXIconCenter - .5*fLinearWidth) / fLinearWidth * 2 * G_PI;  // changement de repere, dans ]-pi, pi[.
101 
102 	double a = .5 * iEllipseHeight;  // parametres de l'ellipse, theta=0 en bas (c'est-a-dire devant nous).
103 	double b = .5 * (iWidth - fExtraWidth - (my_bRotateIconsOnEllipse ? 0 : iMaxIconWidth));
104 
105 	double fXIconCenterDraw, fYIconBottomDraw;  // coordonnees du centre bas de l'icone une fois positionnee sur l'ellipse.
106 	fXIconCenterDraw = b * sin (fTheta) + .5 * iWidth;
107 	fYIconBottomDraw = (bDirectionUp ? a * cos (fTheta) + iMaxIconHeight + a : a + myDocksParam.iDockLineWidth - a * cos (fTheta));
108 
109 	icon->fHeightFactor = 1.;
110 	icon->fOrientation = 0.;
111 
112 	if (my_bRotateIconsOnEllipse)
113 		icon->fWidthFactor = (G_PI / 2 - fabs (fTheta)) * 2 / G_PI;
114 	else
115 		icon->fWidthFactor = 1.;
116 	icon->fDrawX = fXIconCenterDraw - icon->fWidth * icon->fScale / 2;  /// gerer le placement de profil...
117 
118 	if (fabs (fTheta) < G_PI / 2)  // icone a l'avant plan.
119 	{
120 		icon->fDrawX = fXIconCenterDraw - icon->fWidth * icon->fScale / 2;
121 		icon->fAlpha = 1.;
122 	}
123 	else
124 	{
125 		icon->fScale *= MAX (0.75, sin ((G_PI - fabs (fTheta)) / 3));
126 		icon->fAlpha = MAX (0.5, sin (fTheta) * sin (fTheta));
127 	}
128 	icon->fDrawY = fYIconBottomDraw  - (bDirectionUp ? icon->fHeight * icon->fScale : 0);
129 	//g_print ("%s : fTheta = %.2f ; fWidthFactor = %.2f ; fDrawX = %.2f\n", icon->cName, fTheta, icon->fWidthFactor, icon->fDrawX);
130 }
131 
cd_rendering_calculate_construction_parameters_caroussel2(Icon * icon,CairoDock * pDock,int iEllipseHeight,double fExtraWidth,double fLinearWidth)132 void cd_rendering_calculate_construction_parameters_caroussel2 (Icon *icon, CairoDock *pDock, int iEllipseHeight, double fExtraWidth, double fLinearWidth)
133 {
134 	int iWidth = pDock->container.iWidth;
135 	int iMaxIconWidth = pDock->iMaxIconHeight;
136 	int iMaxIconHeight = pDock->iMaxIconHeight;
137 	gboolean bDirectionUp = pDock->container.bDirectionUp;
138 	double fTheta = 2*G_PI * icon->fXAtRest / pDock->fFlatDockWidth;
139 	double a = .5 * iEllipseHeight;  // parametres de l'ellipse, theta=0 en bas (c'est-a-dire devant nous).
140 	double b = .5 * (iWidth - fExtraWidth - (my_bRotateIconsOnEllipse ? 0 : iMaxIconWidth));
141 
142 	icon->fScale = 1.;
143 
144 	double fXIconCenterDraw, fYIconBottomDraw;  // coordonnees du centre bas de l'icone une fois positionnee sur l'ellipse.
145 	fXIconCenterDraw = b * sin (fTheta) + .5 * iWidth;
146 	fYIconBottomDraw = (bDirectionUp ? a * cos (fTheta) + iMaxIconHeight + a : a + myDocksParam.iDockLineWidth - a * cos (fTheta));
147 
148 	icon->fHeightFactor = 1.;
149 	icon->fOrientation = 0.;
150 
151 	if (my_bRotateIconsOnEllipse)
152 		icon->fWidthFactor = (G_PI / 2 - fabs (fTheta)) * 2 / G_PI;
153 	else
154 		icon->fWidthFactor = 1.;
155 	icon->fDrawX = fXIconCenterDraw - icon->fWidth * icon->fScale / 2;  /// gerer le placement de profil...
156 
157 	if (fabs (fTheta) < G_PI / 2)  // icone a l'avant plan.
158 	{
159 		icon->fDrawX = fXIconCenterDraw - icon->fWidth * icon->fScale / 2;
160 		icon->fAlpha = 1.;
161 	}
162 	else
163 	{
164 		icon->fScale *= MAX (0.75, sin ((G_PI - fabs (fTheta)) / 3));
165 		icon->fAlpha = MAX (0.5, sin (fTheta) * sin (fTheta));
166 	}
167 	icon->fDrawY = fYIconBottomDraw  - (bDirectionUp ? icon->fHeight * icon->fScale : 0);
168 }
169 
170 
171 
cd_rendering_render_icons_caroussel(cairo_t * pCairoContext,CairoDock * pDock)172 void cd_rendering_render_icons_caroussel (cairo_t *pCairoContext, CairoDock *pDock)
173 {
174 	GList *pFirstDrawnElement = pDock->icons;
175 	if (pFirstDrawnElement == NULL)
176 		return;
177 	//double fChangeAxes = 0.5 * (pDock->container.iWidth - pDock->iMaxDockWidth);
178 
179 	//\____________________ Du debut jusqu'au milieu de la liste.
180 	double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
181 	Icon *icon;
182 	GList *pLeftElement = pFirstDrawnElement;
183 	GList *pRightElement = cairo_dock_get_previous_element (pFirstDrawnElement, pDock->icons);
184 	do
185 	{
186 		icon = pLeftElement->data;
187 		cairo_save (pCairoContext);
188 
189 		//g_print ("redessin a gauche de %s\n", icon->cName);
190 		cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
191 
192 		cairo_restore (pCairoContext);
193 
194 		if (pLeftElement == pRightElement)
195 			break;
196 
197 		icon = pRightElement->data;
198 		cairo_save (pCairoContext);
199 
200 		//g_print ("redessin a droite de %s\n", icon->cName);
201 		cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
202 
203 		cairo_restore (pCairoContext);
204 
205 		pLeftElement = cairo_dock_get_next_element (pLeftElement, pDock->icons);
206 		if (pLeftElement == pRightElement)
207 			break;
208 		pRightElement = cairo_dock_get_previous_element (pRightElement, pDock->icons);
209 	}
210 	while (TRUE);
211 	//while (icon->fX + icon->fWidth * icon->fScale < 0 && ic != pFirstDrawnElement);  // icon->fScale + fChangeAxes
212 }
213 
214 
cd_rendering_render_caroussel(cairo_t * pCairoContext,CairoDock * pDock)215 void cd_rendering_render_caroussel (cairo_t *pCairoContext, CairoDock *pDock)
216 {
217 	//\____________________ On trace le cadre.
218 	double fLineWidth = myDocksParam.iDockLineWidth;
219 	double fMargin = myDocksParam.iFrameMargin;
220 	///int iEllipseHeight = pDock->container.iHeight - myDocksParam.iDockLineWidth - fMargin - pDock->iMaxIconHeight;  // >0 par construction de iMinDockHeight.
221 	int iEllipseHeight = pDock->container.iHeight - (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin + pDock->iMaxIconHeight + myIconsParam.fReflectSize);
222 	int iFrameHeight = iEllipseHeight + 2 * fMargin + myIconsParam.fReflectSize;
223 
224 	double fExtraWidth = cairo_dock_calculate_extra_width_for_trapeze (iFrameHeight, my_fInclinationOnHorizon, myDocksParam.iDockRadius, myDocksParam.iDockLineWidth);
225 	double fDockWidth = pDock->container.iWidth - fExtraWidth;
226 	int sens;
227 	double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
228 	fDockOffsetX = fExtraWidth / 2;
229 	if (pDock->container.bDirectionUp)
230 	{
231 		sens = 1;
232 		fDockOffsetY = pDock->iMaxIconHeight - fMargin - .5 * fLineWidth;
233 	}
234 	else
235 	{
236 		sens = -1;
237 		fDockOffsetY = iFrameHeight + 1.5 * fLineWidth;
238 	}
239 
240 	cairo_save (pCairoContext);
241 	double fDeltaXTrapeze = cairo_dock_draw_frame (pCairoContext, myDocksParam.iDockRadius, fLineWidth, fDockWidth, iFrameHeight, fDockOffsetX, fDockOffsetY, sens, my_fInclinationOnHorizon, pDock->container.bIsHorizontal, myDocksParam.bRoundedBottomCorner);
242 
243 	//\____________________ On dessine les decorations dedans.
244 	fDockOffsetY = (pDock->container.bDirectionUp ? pDock->iMaxIconHeight - fMargin : fLineWidth);
245 
246 	cairo_dock_render_decorations_in_frame (pCairoContext, pDock, fDockOffsetY, fDockOffsetX-fDeltaXTrapeze, fDockWidth+2*fDeltaXTrapeze);
247 
248 	//\____________________ On dessine le cadre.
249 	if (fLineWidth > 0)
250 	{
251 		cairo_set_line_width (pCairoContext, fLineWidth);
252 		cairo_set_source_rgba (pCairoContext, myDocksParam.fLineColor[0], myDocksParam.fLineColor[1], myDocksParam.fLineColor[2], myDocksParam.fLineColor[3]);
253 		cairo_stroke (pCairoContext);
254 	}
255 	else
256 		cairo_new_path (pCairoContext);
257 	cairo_restore (pCairoContext);
258 
259 
260 	//\____________________ On dessine la ficelle qui les joint.
261 	if (myIconsParam.iStringLineWidth > 0)
262 		cairo_dock_draw_string (pCairoContext, pDock, myIconsParam.iStringLineWidth, TRUE, FALSE);
263 
264 	//\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan.
265 	cd_rendering_render_icons_caroussel (pCairoContext, pDock);
266 }
267 
268 
_cd_rendering_get_rotation_speed(CairoDock * pDock)269 static double _cd_rendering_get_rotation_speed (CairoDock *pDock)  // donne la vitesse de rotation entre -1 et 1.
270 {
271 	static double a=.2;  // entre -a/2 et a/2 la rotation est nulle.
272 	double x = 2.*(pDock->container.iMouseX - pDock->container.iWidth/2) / pDock->container.iWidth;  // [-1 ; 1]
273 	if (x > a)
274 		return (x - a) / (1 - a);
275 	else if (x < -a)
276 		return (x + a) / (1 - a);
277 	else
278 		return 0.;
279 }
cd_rendering_calculate_icons_caroussel(CairoDock * pDock)280 Icon *cd_rendering_calculate_icons_caroussel (CairoDock *pDock)
281 {
282 	// (x;y) => theta.
283 
284 	Icon *pPointedIcon = cairo_dock_apply_wave_effect (pDock);
285 
286 	//\____________________ On calcule les position/etirements/alpha des icones.
287 	int iEllipseHeight = pDock->container.iHeight - (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin + pDock->iMaxIconHeight + myIconsParam.fReflectSize);  // >0 par construction de iMinDockHeight.
288 	int iFrameHeight = iEllipseHeight + 2 * myDocksParam.iFrameMargin + myIconsParam.fReflectSize;
289 	double fExtraWidth = cairo_dock_calculate_extra_width_for_trapeze (iFrameHeight, my_fInclinationOnHorizon, myDocksParam.iDockRadius, myDocksParam.iDockLineWidth);
290 	double fLinearWidth = cairo_dock_get_current_dock_width_linear (pDock);
291 	Icon *pFirstIcon = cairo_dock_get_first_icon (pDock->icons);
292 	double fXFirstIcon = (pFirstIcon != NULL ? pFirstIcon->fX : 0);
293 	Icon* icon;
294 	GList* ic;
295 	for (ic = pDock->icons; ic != NULL; ic = ic->next)
296 	{
297 		icon = ic->data;
298 		///cd_rendering_calculate_construction_parameters_caroussel (icon, pDock->container.iWidth, pDock->container.iHeight, pDock->iMaxIconHeight, pDock->iMaxIconHeight, iEllipseHeight, pDock->container.bDirectionUp, fExtraWidth, fLinearWidth, fXFirstIcon);  // il manque un pDock->iMaxIconWidth en 2eme...
299 		cd_rendering_calculate_construction_parameters_caroussel2 (icon, pDock, iEllipseHeight, fExtraWidth, fLinearWidth);
300 	}
301 
302 	pDock->iMousePositionType = (pDock->container.bInside ? CAIRO_DOCK_MOUSE_INSIDE : CAIRO_DOCK_MOUSE_OUTSIDE);
303 
304 	cairo_dock_check_can_drop_linear (pDock);  /// marche ?...
305 
306 	if (pDock->container.bInside && ! cairo_dock_container_is_animating (CAIRO_CONTAINER (pDock)))
307 	{
308 		double fRotationSpeed = _cd_rendering_get_rotation_speed (pDock);
309 		if (fRotationSpeed != 0)
310 			cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
311 	}
312 
313 	return pPointedIcon;
314 }
315 
cd_rendering_free_caroussel_data(CairoDock * pDock)316 void cd_rendering_free_caroussel_data (CairoDock *pDock)
317 {
318 	if (pDock->pRendererData != NULL)
319 	{
320 		gldi_object_remove_notification (CAIRO_CONTAINER (pDock), NOTIFICATION_UPDATE, (GldiNotificationFunc) cd_rendering_caroussel_update_dock, NULL);
321 	}
322 }
323 
324 
cd_rendering_register_caroussel_renderer(const gchar * cRendererName)325 void cd_rendering_register_caroussel_renderer (const gchar *cRendererName)
326 {
327 	CairoDockRenderer *pRenderer = g_new0 (CairoDockRenderer, 1);
328 	pRenderer->cReadmeFilePath = g_strdup (MY_APPLET_SHARE_DATA_DIR"/readme-caroussel-view");
329 	pRenderer->cPreviewFilePath = g_strdup (MY_APPLET_SHARE_DATA_DIR"/preview-caroussel.jpg");
330 	pRenderer->compute_size = cd_rendering_calculate_max_dock_size_caroussel;
331 	pRenderer->calculate_icons = cd_rendering_calculate_icons_caroussel;  // cairo_dock_apply_wave_effect;
332 	pRenderer->render = cd_rendering_render_caroussel;
333 	pRenderer->render_optimized = NULL;
334 	pRenderer->set_subdock_position = cairo_dock_set_subdock_position_linear;  // cd_rendering_set_subdock_position_caroussel
335 	pRenderer->free_data = cd_rendering_free_caroussel_data;
336 	pRenderer->bUseReflect = TRUE;
337 	pRenderer->cDisplayedName = D_ (cRendererName);
338 
339 	cairo_dock_register_renderer (cRendererName, pRenderer);
340 }
341 
342 // TODO !!! @ Fabounet, je n'ai pas vérifié... J'ai juste copié ce que tu avais fait hier :)
_scroll_dock_icons(CairoDock * pDock,int iScrollAmount)343 static void _scroll_dock_icons (CairoDock *pDock, int iScrollAmount)
344 {
345 	if (iScrollAmount == 0)  // fin de scroll
346 	{
347 		cairo_dock_trigger_set_WM_icons_geometry (pDock);
348 		return ;
349 	}
350 
351 	//\_______________ On fait tourner les icones.
352 	pDock->iScrollOffset += iScrollAmount;
353 	if (pDock->iScrollOffset >= pDock->fFlatDockWidth)
354 		pDock->iScrollOffset -= pDock->fFlatDockWidth;
355 	if (pDock->iScrollOffset < 0)
356 		pDock->iScrollOffset += pDock->fFlatDockWidth;
357 
358 	pDock->pRenderer->compute_size (pDock);  // recalcule le pFirstDrawnElement.
359 
360 	//\_______________ On recalcule toutes les icones.
361 	Icon *pLastPointedIcon = cairo_dock_get_pointed_icon (pDock->icons);
362 	Icon *pPointedIcon = cairo_dock_calculate_dock_icons (pDock);
363 	gtk_widget_queue_draw (pDock->container.pWidget);
364 
365 	//\_______________ On gere le changement d'icone.
366 	if (pPointedIcon != pLastPointedIcon)
367 	{
368 		cairo_dock_on_change_icon (pLastPointedIcon, pPointedIcon, pDock);
369 	}
370 }
371 
cd_rendering_caroussel_update_dock(gpointer pUserData,GldiContainer * pContainer,gboolean * bContinueAnimation)372 gboolean cd_rendering_caroussel_update_dock (gpointer pUserData, GldiContainer *pContainer, gboolean *bContinueAnimation)
373 {
374 	if (! CAIRO_DOCK_IS_DOCK (pContainer))
375 		return GLDI_NOTIFICATION_LET_PASS;
376 	CairoDock *pDock = CAIRO_DOCK (pContainer);
377 	if (pDock->pRenderer->calculate_icons != cd_rendering_calculate_icons_caroussel)
378 		return GLDI_NOTIFICATION_LET_PASS;
379 
380 	if (pDock->container.bInside)
381 	{
382 		double fRotationSpeed = _cd_rendering_get_rotation_speed (pDock);
383 		int iScrollAmount = ceil (my_fScrollSpeed * fRotationSpeed);
384 		_scroll_dock_icons (pDock, iScrollAmount);  // avec un scroll de 0, cela termine le scroll.
385 		*bContinueAnimation |= (fRotationSpeed != 0);
386 	}
387 	else if (my_fScrollAcceleration != 0 && pDock->iScrollOffset != 0)  // on de-scrolle.
388 	{
389 		int iScrollAmount;
390 		if (pDock->iScrollOffset < pDock->fFlatDockWidth / 2)
391 		{
392 			iScrollAmount = - MAX (2, ceil (pDock->iScrollOffset * my_fScrollAcceleration));
393 		}
394 		else
395 		{
396 			iScrollAmount = MAX (2, ceil ((pDock->fFlatDockWidth - pDock->iScrollOffset) * my_fScrollAcceleration));
397 		}
398 		_scroll_dock_icons (pDock, iScrollAmount);  // avec un scroll de 0, cela termine le scroll.
399 		*bContinueAnimation |= (pDock->iScrollOffset != 0);
400 	}
401 	return GLDI_NOTIFICATION_LET_PASS;
402 }
403