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-slide.h"
30 
31 extern gdouble  my_diapo_simple_max_size;
32 extern gint     my_diapo_simple_iconGapX;
33 extern gint     my_diapo_simple_iconGapY;
34 extern gdouble  my_diapo_simple_fScaleMax;
35 extern gint     my_diapo_simple_sinW;
36 extern gboolean my_diapo_simple_lineaire;
37 extern gboolean  my_diapo_simple_wide_grid;
38 
39 extern gboolean  my_diapo_simple_use_default_colors;
40 extern gdouble  my_diapo_simple_color_frame_start[4];
41 extern gdouble  my_diapo_simple_color_frame_stop[4];
42 extern gboolean my_diapo_simple_fade2bottom;
43 extern gboolean my_diapo_simple_fade2right;
44 extern gint    my_diapo_simple_arrowWidth;
45 extern gint    my_diapo_simple_arrowHeight;
46 extern gint    my_diapo_simple_lineWidth;
47 extern gint    my_diapo_simple_radius;
48 extern gdouble  my_diapo_simple_color_border_line[4];
49 extern gboolean my_diapo_simple_display_all_labels;
50 
51 extern gdouble my_diapo_simple_color_scrollbar_line[4];
52 extern gdouble my_diapo_simple_color_scrollbar_inside[4];
53 extern gdouble my_diapo_simple_color_grip[4];
54 
55 const gint iSeparatorHeight = 30;  // height added by a separator.
56 const gint X_BORDER_SPACE = 40;  // espace laisse de chaque cote pour eviter de sortir trop facilement (et pour laisser de la place pour les etiquettes).
57 const gint ARROW_TIP = 3;  // pour gerer la pointe de la fleche.
58 const double fArrowHeight = 14, fScrollbarWidth = 10, fScrollbarArrowGap = 4, fScrollbarRadius = 5;
59 const double fScrollbarIconGap = 10;
60 /// On considere qu'on a my_diapo_simple_iconGapX entre chaque icone horizontalement, et my_diapo_simple_iconGapX/2 entre les icones et les bords (pour aerer un peu plus le dessin). Idem verticalement. X_BORDER_SPACE est la pour empecher que les icones debordent de la fenetre au zoom.
61 
62 typedef struct {
63 	gint nRowsX;
64 	gint nRowsY;
65 	gint iNbSeparators;  // number of drawn separators.
66 	gint iDeltaHeight;  // hauteur scrollable, en pixels
67 	gint iScrollOffset;  // hauteur scrollee, en pixels, positive.
68 	gboolean bDraggingScrollbar;  // si le clic est couramment enfonce sur la scrollbar.
69 	guint iSidPressEvent;  // sid du clic
70 	guint iSidReleaseEvent;  // sid du relachement du clic
71 	gint iClickY;  // hauteur ou on a clique, en coordonnees container.
72 	gint iClickOffset;  // hauteur scrollee au moment du clic
73 	gint iDeltaIconX;
74 	gint iArrowShift;
75 	gint lmargin, rmargin, bmargin, tmargin;  // margins around the frame
76 	gint iFrameWidth, iFrameHeight;  // frame dimensions
77 	gint iArrowPosition;  // b, t, r, l
78 	} CDSlideData;
79 
80 static void cd_rendering_render_diapo_simple (cairo_t *pCairoContext, CairoDock *pDock);
81 
82 
83   ////////////////////////
84  /// SCROLL CALLBACKS ///
85 ////////////////////////
86 
_set_scroll(CairoDock * pDock,int iOffsetY)87 static void _set_scroll (CairoDock *pDock, int iOffsetY)
88 {
89 	//g_print ("%s (%d)\n", __func__, iOffsetY);
90 	CDSlideData *pData = pDock->pRendererData;
91 	g_return_if_fail (pData != NULL);
92 
93 	pData->iScrollOffset = MAX (0, MIN (iOffsetY, pData->iDeltaHeight));
94 	cairo_dock_calculate_dock_icons (pDock);
95 	gtk_widget_queue_draw (pDock->container.pWidget);
96 }
_add_scroll(CairoDock * pDock,int iDeltaOffsetY)97 static gboolean _add_scroll (CairoDock *pDock, int iDeltaOffsetY)
98 {
99 	//g_print ("%s (%d)\n", __func__, iDeltaOffsetY);
100 	CDSlideData *pData = pDock->pRendererData;
101 	g_return_val_if_fail (pData != NULL, FALSE);
102 
103 	if (iDeltaOffsetY < 0)
104 	{
105 		if (pData->iScrollOffset <= 0)
106 			return FALSE;
107 	}
108 	else
109 	{
110 		if (pData->iScrollOffset >= pData->iDeltaHeight)
111 			return FALSE;
112 	}
113 	_set_scroll (pDock, pData->iScrollOffset + iDeltaOffsetY);
114 	return TRUE;
115 }
116 
_cd_slide_on_scroll(gpointer data,Icon * pClickedIcon,CairoDock * pDock,int iDirection)117 static gboolean _cd_slide_on_scroll (gpointer data, Icon *pClickedIcon, CairoDock *pDock, int iDirection)
118 {
119 	CDSlideData *pData = pDock->pRendererData;
120 	g_return_val_if_fail (pData != NULL, GLDI_NOTIFICATION_LET_PASS);
121 	if (pData->iDeltaHeight == 0)
122 		return GLDI_NOTIFICATION_LET_PASS;
123 
124 	gboolean bScrolled = _add_scroll (pDock, iDirection == 1 ? pDock->iMaxIconHeight : - pDock->iMaxIconHeight);
125 	return (bScrolled ? GLDI_NOTIFICATION_INTERCEPT : GLDI_NOTIFICATION_LET_PASS);
126 }
_cd_slide_on_click(gpointer data,Icon * pClickedIcon,CairoDock * pDock,guint iButtonState)127 static gboolean _cd_slide_on_click (gpointer data, Icon *pClickedIcon, CairoDock *pDock, guint iButtonState)
128 {
129 	CDSlideData *pData = pDock->pRendererData;
130 	g_return_val_if_fail (pData != NULL, GLDI_NOTIFICATION_LET_PASS);
131 	if (pData->iDeltaHeight == 0)
132 		return GLDI_NOTIFICATION_LET_PASS;
133 	if (pData->bDraggingScrollbar)
134 		return GLDI_NOTIFICATION_INTERCEPT;
135 	else
136 		return GLDI_NOTIFICATION_LET_PASS;
137 }
_cd_slide_on_press_button(GtkWidget * pWidget,GdkEventButton * pButton,CairoDock * pDock)138 gboolean _cd_slide_on_press_button (GtkWidget* pWidget, GdkEventButton* pButton, CairoDock *pDock)
139 {
140 	CDSlideData *pData = pDock->pRendererData;
141 	g_return_val_if_fail (pData != NULL, FALSE);
142 	if (pData->iDeltaHeight == 0)
143 		return FALSE;
144 
145 	if (pButton->type == GDK_BUTTON_PRESS && pButton->button == 1)
146 	{
147 		double x_arrow = pData->lmargin + pData->iFrameWidth - fScrollbarIconGap - fScrollbarWidth;
148 		int x, y;
149 		x = pButton->x;
150 		y = pButton->y;
151 
152 		if (x > x_arrow)  // on a clique dans la zone de scroll.
153 		{
154 			// on regarde sur quoi on clic.
155 			double y_arrow_top, y_arrow_bottom;
156 			y_arrow_top = pData->tmargin + my_diapo_simple_lineWidth + my_diapo_simple_radius;
157 			y_arrow_bottom = pData->tmargin + pData->iFrameHeight - my_diapo_simple_radius;
158 
159 			if (y > y_arrow_top - fScrollbarArrowGap/2 && y < y_arrow_top + fArrowHeight + fScrollbarArrowGap/2)  // bouton haut
160 			{
161 				_set_scroll (pDock, 0);
162 			}
163 			else if (y < y_arrow_bottom + fScrollbarArrowGap/2 && y > y_arrow_bottom - fArrowHeight - fScrollbarArrowGap/2)  // bouton bas
164 			{
165 				_set_scroll (pDock, pData->iDeltaHeight);
166 			}
167 			else  // scrollbar
168 			{
169 				pData->bDraggingScrollbar = TRUE;
170 				pData->iClickY = y;
171 				pData->iClickOffset = pData->iScrollOffset;
172 			}
173 		}
174 	}
175 	else if (GDK_BUTTON_RELEASE)
176 	{
177 		//g_print ("release\n");
178 		pData->bDraggingScrollbar = FALSE;
179 	}
180 	return FALSE;
181 }
_cd_slide_on_mouse_moved(gpointer data,CairoDock * pDock,gboolean * bStartAnimation)182 static gboolean _cd_slide_on_mouse_moved (gpointer data, CairoDock *pDock, gboolean *bStartAnimation)
183 {
184 	CDSlideData *pData = pDock->pRendererData;
185 	g_return_val_if_fail (pData != NULL, GLDI_NOTIFICATION_LET_PASS);
186 	if (pData->iDeltaHeight == 0)
187 		return GLDI_NOTIFICATION_LET_PASS;
188 
189 	if (pData->bDraggingScrollbar)
190 	{
191 		//g_print ("scroll on motion (y=%d)\n", pDock->container.iMouseY);
192 
193 		double y_arrow_top, y_arrow_bottom;
194 		y_arrow_top = pData->tmargin + my_diapo_simple_lineWidth + my_diapo_simple_radius;
195 		y_arrow_bottom = pData->tmargin + pData->iFrameHeight - my_diapo_simple_radius;
196 
197 		double fFrameHeight = pData->iFrameHeight;
198 		double fGripHeight = fFrameHeight / (fFrameHeight + pData->iDeltaHeight) * (y_arrow_bottom - y_arrow_top - 2*(fArrowHeight+fScrollbarArrowGap));
199 		//double ygrip = (double) pData->iScrollOffset / pData->iDeltaHeight * (y_arrow_top - y_arrow_bottom - 2*(fArrowHeight+fScrollbarArrowGap) - fGripHeight);
200 
201 		int delta = (pDock->container.bIsHorizontal ? pDock->container.iMouseY : pDock->container.iMouseX) - pData->iClickY;
202 		_set_scroll (pDock, (pData->iClickOffset + (double)delta / (y_arrow_bottom - y_arrow_top - 2*(fArrowHeight+fScrollbarArrowGap) - fGripHeight) * pData->iDeltaHeight));
203 		return GLDI_NOTIFICATION_INTERCEPT;
204 	}
205 	return GLDI_NOTIFICATION_LET_PASS;
206 }
cd_slide_on_leave(gpointer data,CairoDock * pDock,gboolean * bStartAnimation)207 gboolean cd_slide_on_leave (gpointer data, CairoDock *pDock, gboolean *bStartAnimation)
208 {
209 	CDSlideData *pData = pDock->pRendererData;
210 	//g_return_val_if_fail (pData != NULL, GLDI_NOTIFICATION_LET_PASS);
211 	if (pData == NULL || ! pDock->pRenderer || pDock->pRenderer->render != cd_rendering_render_diapo_simple)  // pas nous
212 		return GLDI_NOTIFICATION_LET_PASS;
213 
214 	//g_print (" LEAVE (%d)\n", pData->bDraggingScrollbar);
215 
216 	return (pData->bDraggingScrollbar ? GLDI_NOTIFICATION_INTERCEPT : GLDI_NOTIFICATION_LET_PASS);
217 }
218 
219 
220   ////////////////////////
221  /// GRID COMPUTATION ///
222 ////////////////////////
223 
_cd_rendering_diapo_simple_guess_grid(GList * pIconList,guint * nRowX,guint * nRowY,guint * nSep)224 static guint _cd_rendering_diapo_simple_guess_grid (GList *pIconList, guint *nRowX, guint *nRowY, guint *nSep)
225 {
226 	// first count the number of icons and separators
227 	int nc=0, nl=0;  // nb columns and lines
228 	int ncmax=0, ncmin=999999;  // min/max number of columns = smallest/largest line
229 
230 	guint count = 0;  // number of drawn icons (= not a separator)
231 	guint nb_sep = 0;  // number of separators.
232 	Icon *icon;
233 	GList *ic;
234 	for (ic = pIconList; ic != NULL; ic = ic->next)
235 	{
236 		icon = ic->data;
237 		if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
238 		{
239 			nb_sep ++;
240 			ncmax = MAX (ncmax, nc);
241 			ncmin = MIN (ncmin, nc);
242 			nc = 0;  // new line
243 		}
244 		else
245 		{
246 			count ++;
247 			nc ++;
248 		}
249 	}
250 	ncmax = MAX (ncmax, nc);
251 	ncmin = MIN (ncmin, nc);
252 	if (nc == 0 && nl > 0)  // if we ended on an empty line, ignore it.
253 	{
254 		nb_sep --;
255 	}
256 	//g_print (" %d icons, %d separator(s), min/max line=%d/%d\n", count, nb_sep, ncmin, ncmax);
257 
258 	// then compute the best layout
259 	if (count == 0)  // if no icons, stop here.
260 	{
261 		*nRowX = 0;
262 		*nRowY = 0;
263 		*nSep = 0;
264 		return 0;
265 	}
266 	else if (nb_sep == 0)  // if no separator, the grid is obvious.
267 	{
268 		if (my_diapo_simple_wide_grid)
269 		{
270 			*nRowX = ceil(sqrt(count));
271 			*nRowY = ceil(((double) count) / *nRowX);
272 		}
273 		else
274 		{
275 			*nRowY = ceil(sqrt(count));
276 			*nRowX = ceil(((double) count) / *nRowY);
277 		}
278 	}
279 	else  // iterate on the possible layouts.
280 	{
281 		int iSurface, iSurfaceMin = count * count;
282 		int delta_lc, delta_lc_min = count;  // delta line/column
283 		int nx=0, ny=0;  // result
284 		int nclim, ncols=0;
285 		for (nclim = MIN (ncmin, floor(sqrt(count))); nclim <= ncmax; nclim ++)  // if no separator, we'll have sqrt(count) columns; since each separator adds a line, and we want as many columns as lines, we can iterate from this value.
286 		{
287 			nl = 1;
288 			nc = 0;
289 			ncols = 0;
290 			for (ic = pIconList; ic != NULL; ic = ic->next)
291 			{
292 				icon = ic->data;
293 				if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))  // new line
294 				{
295 					if (nc > 0)
296 					{
297 						ncols = MAX (ncols, nc);
298 						nc = 0;
299 						nl ++;
300 					}
301 				}
302 				else
303 				{
304 					nc ++;
305 					if (nc == nclim)  // end of line reached, start a new line.
306 					{
307 						ncols = MAX (ncols, nc);
308 						nc = 0;
309 						nl ++;
310 					}
311 				}
312 			}
313 			if (nc == 0 && nl > 0)  // if we ended on an empty line, ignore it.
314 			{
315 				nl --;
316 			}
317 
318 			if ((my_diapo_simple_wide_grid && ncols >= nl)
319 				|| (!my_diapo_simple_wide_grid && ncols <= nl))  // this layout is ok, let's take it if it's better than the current one.
320 			{
321 				delta_lc = abs (ncols - nl);
322 				iSurface = ncols * nl;
323 				if (delta_lc < delta_lc_min
324 				|| (delta_lc == delta_lc_min && iSurface < iSurfaceMin))  // we want to have something roughly square, and which minimizes the lost space.
325 				{
326 					delta_lc_min = delta_lc;
327 					iSurfaceMin = iSurface;
328 					nx = ncols;
329 					ny = nl;
330 				}
331 			}
332 			else if (nx == 0)  // no result yet, take this one as a default result, but keep its weight low
333 			{
334 				nx = ncols;
335 				ny = nl;
336 			}
337 		}
338 		*nRowX = nx;
339 		*nRowY = ny;
340 	}
341 
342 	/**
343 	// Calcul du nombre de lignes (nY) / colonnes (nX) :
344 	guint count = 0;
345 	Icon *icon;
346 	GList *ic;
347 	for (ic = pIconList; ic != NULL; ic = ic->next)
348 	{
349 		icon = ic->data;
350 		if (! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
351 			count ++;
352 	}
353 
354 	if (count == 0)
355 	{
356 		*nRowX = 0;
357 		*nRowY = 0;
358 	}
359 	else if (my_diapo_simple_wide_grid)
360 	{
361 		*nRowX = ceil(sqrt(count));
362 		*nRowY = ceil(((double) count) / *nRowX);
363 	}
364 	else
365 	{
366 		*nRowY = ceil(sqrt(count));
367 		*nRowX = ceil(((double) count) / *nRowY);
368 	}*/
369 	*nSep = nb_sep;
370 	return count;
371 }
372 
cd_rendering_calculate_max_dock_size_diapo_simple(CairoDock * pDock)373 static void cd_rendering_calculate_max_dock_size_diapo_simple (CairoDock *pDock)
374 {
375 	// add our private data if not already done
376 	CDSlideData *pData = pDock->pRendererData;
377 	if (pData == NULL)
378 	{
379 		pData = g_new0 (CDSlideData, 1);
380 		pDock->pRendererData = pData;
381 		gldi_object_register_notification (CAIRO_CONTAINER (pDock), NOTIFICATION_SCROLL_ICON, (GldiNotificationFunc) _cd_slide_on_scroll, GLDI_RUN_AFTER, NULL);
382 		gldi_object_register_notification (CAIRO_CONTAINER (pDock), NOTIFICATION_CLICK_ICON, (GldiNotificationFunc) _cd_slide_on_click, GLDI_RUN_FIRST, NULL);
383 		gldi_object_register_notification (CAIRO_CONTAINER (pDock), NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) _cd_slide_on_mouse_moved, GLDI_RUN_AFTER, NULL);
384 		pData->iSidPressEvent = g_signal_connect (G_OBJECT (pDock->container.pWidget),
385 			"button-press-event",
386 			G_CALLBACK (_cd_slide_on_press_button),
387 			pDock);  // car les notification de clic en provenance du dock sont emises lors du relachement du bouton.
388 		pData->iSidReleaseEvent = g_signal_connect (G_OBJECT (pDock->container.pWidget),
389 			"button-release-event",
390 			G_CALLBACK (_cd_slide_on_press_button),
391 			pDock);
392 	}
393 
394 	if (pDock->container.bIsHorizontal)
395 	{
396 		pData->rmargin = X_BORDER_SPACE;
397 		pData->lmargin = X_BORDER_SPACE;
398 		if (pDock->container.bDirectionUp)
399 		{
400 			pData->bmargin = my_diapo_simple_arrowHeight + ARROW_TIP;
401 			pData->tmargin = 0;
402 			pData->iArrowPosition = 0;
403 		}
404 		else
405 		{
406 			pData->bmargin = 0;
407 			pData->tmargin = my_diapo_simple_arrowHeight + ARROW_TIP;
408 			pData->iArrowPosition = 1;
409 		}
410 	}
411 	else
412 	{
413 		pData->bmargin = pData->tmargin = 0;
414 		if (pDock->container.bDirectionUp)
415 		{
416 			pData->rmargin = my_diapo_simple_arrowHeight + ARROW_TIP;
417 			pData->lmargin = X_BORDER_SPACE;
418 			pData->iArrowPosition = 2;
419 		}
420 		else
421 		{
422 			pData->rmargin = X_BORDER_SPACE;
423 			pData->lmargin = my_diapo_simple_arrowHeight + ARROW_TIP;
424 			pData->iArrowPosition = 3;
425 		}
426 	}
427 
428 	// On calcule la configuration de la grille sans contrainte.
429 	double srx = my_diapo_simple_max_size;  // screen ratio hori
430 	double sry = MIN (1., my_diapo_simple_max_size * 1.2);  // screen ratio verti
431 	guint nRowsX = 0;  // nb colonnes.
432 	guint nRowsY = 0;  // nb lignes.
433 	guint nIcones = 0;  // nb icones.
434 	guint iNbSeparators = 0;  // nb separators
435 	int iDeltaHeight = 0;  // hauteur ne pouvant rentrer dans le dock.
436 	int iMaxIconWidth = 0;
437 	int iDockWidth, iDockHeight;  // dimension dock.
438 	int iFrameWidth, iFrameHeight;
439 	int Ws = gldi_dock_get_screen_width (pDock) - 2;  // let 1px on each edge, so that we can leave the dock even if it gets huge.
440 	int Hs = gldi_dock_get_screen_height (pDock) - 2;
441 	nIcones = _cd_rendering_diapo_simple_guess_grid (pDock->icons, &nRowsX, &nRowsY, &iNbSeparators);
442 	//g_print ("*** nIcones : %d (%dx%d)\n", nIcones, Ws, Hs);
443 
444 	/**if (! pDock->container.bIsHorizontal)
445 	{
446 		int tmp = nRowsX;
447 		nRowsX = nRowsY;
448 		nRowsY = tmp;
449 	}*/
450 	// On calcule la taille de l'affichage avec contrainte taille ecran.
451 	if (nIcones != 0)
452 	{
453 		// on calcule la largeur avec contrainte, ce qui donne aussi le nombre de lignes.
454 		iMaxIconWidth = ((Icon*)pDock->icons->data)->fWidth;  // approximation un peu bof.
455 		iFrameWidth = nRowsX * (iMaxIconWidth + my_diapo_simple_iconGapX);
456 		iDockWidth = iFrameWidth + pData->lmargin + pData->rmargin;
457 
458 		int iMaxWidth = Ws * (Ws > Hs ? srx : sry);
459 		if (iDockWidth > iMaxWidth)
460 		{
461 			nRowsX = (iMaxWidth - (pData->lmargin + pData->rmargin)) / (iMaxIconWidth + my_diapo_simple_iconGapX);
462 			nRowsY = ceil((double) nIcones / nRowsX);
463 			iFrameWidth = nRowsX * (iMaxIconWidth + my_diapo_simple_iconGapX);
464 			iDockWidth = iFrameWidth + pData->lmargin + pData->rmargin;
465 			//g_print ("%d -> %d\n", iMaxWidth, iDockWidth);
466 		}
467 
468 		// on calcule la hauteur avec contrainte, ce qui donne aussi la marge de defilement.
469 		int iSingleLineHeight = pDock->iMaxIconHeight * pDock->container.fRatio * my_diapo_simple_fScaleMax +  // les icones des bords zooment
470 			myIconsParam.iLabelSize +  // le texte des icones de la 1ere ligne
471 			iNbSeparators * iSeparatorHeight;  // les separateurs
472 		int iOneLineHeight = pDock->iMaxIconHeight * pDock->container.fRatio + my_diapo_simple_iconGapY;
473 		iFrameHeight = (nRowsY - 1) * iOneLineHeight + iSingleLineHeight;
474 		iDockHeight = iFrameHeight + pData->bmargin + pData->tmargin;
475 
476 		int iMaxHeight = Hs * (Ws > Hs ? sry : srx);
477 		if (iDockHeight > iMaxHeight)
478 		{
479 			nRowsY = (iMaxHeight - (pData->bmargin + pData->tmargin) - iSingleLineHeight) / iOneLineHeight + 1;
480 			if (Ws > Hs && nRowsY > nRowsX)  // on evite d'avoir un sous-dock plus haut que large si l'ecran est ausi comme ca, ca rend mieux.
481 				nRowsY = MIN (nRowsY, MAX (5, nRowsX));  // tout de meme, au moins 5 lignes.
482 			int iMaxDockHeight0 = iDockHeight;
483 			iFrameHeight = (nRowsY - 1) * iOneLineHeight + iSingleLineHeight;
484 			iDockHeight = iFrameHeight + pData->bmargin + pData->tmargin;
485 			iDeltaHeight = iMaxDockHeight0 - iDockHeight;
486 			//g_print ("%d -> %d\n", iMaxHeight, iDockHeight);
487 		}
488 	}
489 	else
490 	{
491 		iFrameWidth = iFrameHeight = 10;
492 		iDockWidth = iFrameWidth + pData->lmargin + pData->rmargin;
493 		iDockHeight = iFrameHeight + pData->bmargin + pData->tmargin;
494 	}
495 	/**if (! pDock->container.bIsHorizontal)
496 	{
497 		int tmp = nRowsX;
498 		nRowsX = nRowsY;
499 		nRowsY = tmp;
500 	}*/
501 
502 	pData->nRowsX = nRowsX;
503 	pData->nRowsY = nRowsY;
504 	pData->iNbSeparators = iNbSeparators;
505 	pData->iDeltaHeight = iDeltaHeight;
506 	if (iDeltaHeight != 0)
507 	{
508 		int iScrollMargin = 2*fScrollbarIconGap
509 			+ fScrollbarWidth;
510 		iFrameWidth += iScrollMargin;
511 		iDockWidth += iScrollMargin;
512 	}
513 	pData->iScrollOffset = MIN (pData->iScrollOffset, iDeltaHeight);  // ensure we don't suddenly become out of range.
514 	pData->iFrameWidth = iFrameWidth;
515 	pData->iFrameHeight = iFrameHeight;
516 
517 	// taille du dock
518 	if (pDock->container.bIsHorizontal)
519 	{
520 		pDock->iMaxDockWidth = iDockWidth;
521 		pDock->iMaxDockHeight = iDockHeight;
522 	}
523 	else  // pareil, sauf la fleche qui sera sur les cotes.
524 	{
525 		pDock->iMaxDockWidth = iDockHeight;
526 		pDock->iMaxDockHeight = iDockWidth;
527 	}
528 	pDock->iMinDockWidth = pDock->iMaxDockWidth - (pData->lmargin + pData->rmargin);
529 	pDock->iMinDockHeight = pDock->iMaxDockHeight;
530 	// pas de decorations.
531 	pDock->iDecorationsHeight = 0;
532 	pDock->iDecorationsWidth  = 0;
533 	// On affecte ca aussi au cas ou.
534 	pDock->fFlatDockWidth = pDock->iMaxDockWidth;
535 	pDock->fMagnitudeMax = my_diapo_simple_fScaleMax / (1+myIconsParam.fAmplitude);
536 
537 	pDock->iActiveWidth = pDock->iMaxDockWidth;
538 	pDock->iActiveHeight = pDock->iMaxDockHeight;
539 }
540 
541 
542   /////////////////////////
543  /// ICONS COMPUTATION ///
544 /////////////////////////
545 
_cd_rendering_calculate_icons_for_diapo_simple(CairoDock * pDock,gint nRowsX,gint nRowsY,gint Mx,gint My)546 static Icon* _cd_rendering_calculate_icons_for_diapo_simple (CairoDock *pDock, gint nRowsX, gint nRowsY, gint Mx, gint My)
547 {
548 	CDSlideData *pData = pDock->pRendererData;  // non nul
549 	double fScrollOffset = (pDock->container.bDirectionUp ? - pData->iScrollOffset : pData->iScrollOffset);
550 
551 	// On calcule la position de base pour toutes les icones
552 	// int iOneLineHeight = pDock->iMaxIconHeight + my_diapo_simple_iconGapY;
553 	int iOffsetY = .5 * pDock->iMaxIconHeight * pDock->container.fRatio * (my_diapo_simple_fScaleMax - 1)  // les icones de la 1ere ligne zooment
554 		+ myIconsParam.iLabelSize  // le texte des icones de la 1ere ligne
555 		+ my_diapo_simple_lineWidth  // ligne du haut;
556 		+ pData->tmargin
557 		+ (pDock->container.bDirectionUp ? fScrollOffset : - fScrollOffset);
558 
559 	double fFoldingX = (pDock->fFoldingFactor > .2 ? (pDock->fFoldingFactor - .2) / .8 : 0.);  // placement de 1 a 0.2
560 	double fFoldingY = (pDock->fFoldingFactor > .5 ? (pDock->fFoldingFactor - .5) / .5 : 0.);  // placement de 1 a 0.5
561 	double fFoldingScale = (pDock->fFoldingFactor > .7 ? (1 - pDock->fFoldingFactor) / .3 : 1.);
562 	Icon* icon;
563 	GList* ic, *pointed_ic=NULL;
564 	int x=0, y=0;  // index of the current icon on the grid.
565 	double fx, fy, sep_offset = 0.;
566 	for (ic = pDock->icons; ic != NULL; ic = ic->next)
567 	{
568 		icon = ic->data;
569 		if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
570 		{
571 			if (x > 0)
572 			{
573 				x = 0;  // go to next line.
574 				y ++;
575 			}
576 
577 			sep_offset += iSeparatorHeight;
578 
579 			icon->fWidthFactor = pData->iFrameWidth;  // we'll use it as the width of the line.
580 			if (pData->iScrollOffset != 0)  // the scroll bar is present, don't overlap it
581 				icon->fWidthFactor -= (2*fScrollbarIconGap + fScrollbarWidth);
582 
583 			icon->fX = pData->lmargin;
584 
585 			icon->fY = iOffsetY
586 				+ (pDock->iMaxIconHeight + my_diapo_simple_iconGapY) * y
587 				+ sep_offset
588 				- (my_diapo_simple_iconGapY + iSeparatorHeight + myIconsParam.iLabelSize)/2;
589 
590 			// on tient compte du depliage.
591 			icon->fDrawX = icon->fX + icon->fWidthFactor * fFoldingX / 2;
592 			icon->fDrawY = icon->fY;
593 			/*icon->fDrawY = icon->fY + (pDock->container.bDirectionUp ?
594 				pDock->container.iHeight - (my_diapo_simple_arrowHeight + ARROW_TIP + icon->fDrawY) :
595 				- icon->fDrawY) * fFoldingY;*/
596 			icon->fWidthFactor *= (1 - fFoldingX);
597 
598 			icon->fScale = 1.;
599 		}
600 		else
601 		{
602 			fx = pData->lmargin
603 				+ my_diapo_simple_iconGapX/2
604 				+ (icon->fWidth + my_diapo_simple_iconGapX) * x;
605 
606 			fy = iOffsetY
607 				+ (pDock->iMaxIconHeight + my_diapo_simple_iconGapY) * y
608 				+ sep_offset;
609 
610 			if (pDock->container.bIsHorizontal)
611 			{
612 				icon->fX = fx;
613 				icon->fY = fy;
614 			}
615 			else
616 			{
617 				icon->fX = fy;
618 				icon->fY = fx;
619 			}
620 
621 			// on en deduit le zoom par rapport a la position de la souris.
622 			gdouble distanceE = sqrt ((icon->fX + icon->fWidth/2 - Mx) * (icon->fX + icon->fWidth/2 - Mx) + (icon->fY + icon->fHeight/2 - My) * (icon->fY + icon->fHeight/2 - My));
623 			if (my_diapo_simple_lineaire)
624 			{
625 				gdouble eloignementMax = my_diapo_simple_sinW;  // 3. * (icon->fWidth + icon->fHeight)  / 2
626 				icon->fScale = MAX (1., my_diapo_simple_fScaleMax + (1. - my_diapo_simple_fScaleMax) * distanceE / eloignementMax);
627 				icon->fPhase = 0.;
628 			}
629 			else
630 			{
631 				icon->fPhase = distanceE * G_PI / my_diapo_simple_sinW + G_PI / 2.;
632 				if (icon->fPhase < 0)
633 					icon->fPhase = 0;
634 				else if (icon->fPhase > G_PI)
635 					icon->fPhase = G_PI;
636 				icon->fScale = 1. + (my_diapo_simple_fScaleMax - 1.) * sin (icon->fPhase);
637 			}
638 
639 			// on tient compte du zoom (zoom centre).
640 			icon->fXMin = icon->fXMax = icon->fXAtRest =  // Ca on s'en sert pas encore
641 			icon->fDrawX = icon->fX + icon->fWidth  * (1. - icon->fScale) / 2;
642 			icon->fDrawY = icon->fY + icon->fHeight * (1. - icon->fScale) / 2;
643 
644 			// on tient compte du depliage.
645 			icon->fDrawX -= (icon->fDrawX - pDock->container.iWidth/2) * fFoldingX;
646 			icon->fDrawY = icon->fDrawY + (pDock->container.bDirectionUp ?
647 				pDock->container.iHeight - (my_diapo_simple_arrowHeight + ARROW_TIP + icon->fDrawY) :
648 				- icon->fDrawY) * fFoldingY;
649 
650 			// On affecte tous les parametres qui n'ont pas été défini précédement
651 			icon->fPhase = 0.;
652 			icon->fOrientation = 0.;  // 2. * G_PI * pDock->fFoldingFactor;
653 			icon->fWidthFactor = icon->fHeightFactor = fFoldingScale;
654 
655 			x ++;
656 			if (x >= nRowsX)
657 			{
658 				x = 0;
659 				y ++;
660 			}
661 		}
662 		icon->fAlpha = (pDock->fFoldingFactor > .7 ? (1 - pDock->fFoldingFactor) / (1 - .7) : 1.);  // apparition de 1 a 0.7
663 
664 		///g_print (" +%s %d;%d\n", icon->cName, x, y);
665 		// On regarde si l'icone est pointee.
666 		if((Mx > icon->fX - .5*my_diapo_simple_iconGapX) &&
667 			(My > icon->fY - .5*my_diapo_simple_iconGapY) &&
668 			(Mx < icon->fX + icon->fWidth  + .5*my_diapo_simple_iconGapX) &&
669 			(My < icon->fY + icon->fHeight + .5*my_diapo_simple_iconGapY))
670 		{
671 			icon->bPointed = TRUE;
672 			pointed_ic = ic;
673 		}
674 		else
675 		{
676 			icon->bPointed = FALSE;
677 		}
678 	}
679 	return (pointed_ic == NULL ? NULL : pointed_ic->data);
680 }
_cd_rendering_check_if_mouse_inside_diapo_simple(CairoDock * pDock)681 static void _cd_rendering_check_if_mouse_inside_diapo_simple (CairoDock *pDock)
682 {
683 	if ((pDock->container.iMouseX < 0) || (pDock->container.iMouseX > pDock->iMaxDockWidth - 1) || (pDock->container.iMouseY < 0) || (pDock->container.iMouseY > pDock->iMaxDockHeight - 0))
684 	{
685 		pDock->iMousePositionType = CAIRO_DOCK_MOUSE_OUTSIDE;
686 	}
687 	else  // on fait simple.
688 	{
689 		pDock->iMousePositionType = CAIRO_DOCK_MOUSE_INSIDE;
690 	}
691 }
692 #define make_icon_avoid_mouse(icon, sens) do { \
693 	cairo_dock_mark_icon_as_avoiding_mouse (icon);\
694 	icon->fAlpha = 0.75;\
695 	if (myIconsParam.fAmplitude != 0)\
696 		icon->fDrawX += icon->fWidth / 2 * (icon->fScale - 1) / myIconsParam.fAmplitude * sens; } while (0)
697 ///TODO: make it work...
_check_can_drop(CairoDock * pDock,CairoDockIconGroup iGroup,double fMargin)698 static inline gboolean _check_can_drop (CairoDock *pDock, CairoDockIconGroup iGroup, double fMargin)
699 {
700 	gboolean bUndefined = TRUE;
701 	gboolean bCanDrop = FALSE;
702 	Icon *icon;
703 	GList *ic;
704 	for (ic = pDock->icons; ic != NULL; ic = ic->next)
705 	{
706 		icon = ic->data;
707 		if (icon->bPointed)
708 		{
709 			if (pDock->container.iMouseX < icon->fDrawX + icon->fWidth * icon->fScale * fMargin)  // on est a gauche.  // fDrawXAtRest
710 			{
711 				GList *prev_ic = ic->prev;
712 				Icon *prev_icon = (prev_ic ? prev_ic->data : NULL);
713 				if (icon->iGroup == iGroup
714 				|| (prev_icon && prev_icon->iGroup == iGroup) )
715 				{
716 					make_icon_avoid_mouse (icon, 1);
717 					if (prev_icon)
718 						make_icon_avoid_mouse (prev_icon, -1);
719 					//g_print ("%s> <%s\n", prev_icon->cName, icon->cName);
720 					bCanDrop = TRUE;
721 					bUndefined = FALSE;
722 				}
723 			}
724 			else if (pDock->container.iMouseX > icon->fDrawX + icon->fWidth * icon->fScale * (1 - fMargin))  // on est a droite.  // fDrawXAtRest
725 			{
726 				GList *next_ic = ic->next;
727 				Icon *next_icon = (next_ic ? next_ic->data : NULL);
728 				if (icon->iGroup == iGroup
729 				|| (next_icon && next_icon->iGroup == iGroup) )
730 				{
731 					make_icon_avoid_mouse (icon, -1);
732 					if (next_icon)
733 						make_icon_avoid_mouse (next_icon, 1);
734 					bCanDrop = TRUE;
735 					bUndefined = FALSE;
736 				}
737 				ic = ic->next;  // on la saute pour ne pas la de-marquer.
738 				if (ic == NULL)
739 					break;
740 			}
741 			else  // on the icon
742 			{
743 				bCanDrop = FALSE;
744 				bUndefined = FALSE;
745 			}
746 		}
747 		else
748 			cairo_dock_stop_marking_icon_as_avoiding_mouse (icon);
749 	}
750 
751 	if (bUndefined)  // no pointed icon, so we are either on the side, on between icons.
752 	{
753 		bCanDrop = (pDock->container.iMouseX > X_BORDER_SPACE && pDock->container.iMouseX < pDock->container.iWidth - X_BORDER_SPACE);  // no drop on the side.
754 	}
755 	return bCanDrop;
756 }
_cd_rendering_check_can_drop(CairoDock * pDock)757 static void _cd_rendering_check_can_drop (CairoDock *pDock)
758 {
759 	if (! pDock->bIsDragging)  // not dragging, so no drop possible.
760 	{
761 		pDock->bCanDrop = FALSE;
762 	}
763 	else if (pDock->icons == NULL)  // dragging but no icons, so drop always possible.
764 	{
765 		pDock->bCanDrop = TRUE;
766 	}
767 	else  // dragging and some icons.
768 	{
769 		pDock->bCanDrop = _check_can_drop (pDock, pDock->iAvoidingMouseIconType, pDock->fAvoidingMouseMargin);
770 	}
771 }
cd_rendering_calculate_icons_diapo_simple(CairoDock * pDock)772 Icon *cd_rendering_calculate_icons_diapo_simple (CairoDock *pDock)
773 {
774 	if (pDock->icons == NULL)
775 		return NULL;
776 	CDSlideData *pData = pDock->pRendererData;
777 	g_return_val_if_fail (pData != NULL, NULL);
778 
779 	// On recupere la configuration de la grille
780 	gint nRowsX = pData->nRowsX;
781 	gint nRowsY = pData->nRowsY;
782 	if (nRowsX == 0 || nRowsY == 0)  // maybe a dock with no displayed icons (like 1 separator); anyway the grid is not valid, so discard.
783 		return NULL;
784 
785 	// On calcule les parametres des icones
786 	Icon *pPointedIcon = _cd_rendering_calculate_icons_for_diapo_simple (pDock, nRowsX, nRowsY, pDock->container.iMouseX, pDock->container.iMouseY);
787 
788 	_cd_rendering_check_if_mouse_inside_diapo_simple (pDock);
789 
790 	_cd_rendering_check_can_drop (pDock);
791 
792 	return pPointedIcon;
793 }
794 
795 
796   /////////////////////
797  /// CAIRO DRAWING ///
798 /////////////////////
799 
_cairo_dock_draw_frame_for_diapo_simple(cairo_t * pCairoContext,CairoDock * pDock)800 static void _cairo_dock_draw_frame_for_diapo_simple (cairo_t *pCairoContext, CairoDock *pDock)
801 {
802 	CDSlideData *pData = pDock->pRendererData;  // non nul
803 	int iArrowShift = pData->iArrowShift;
804 	int iDeltaIconX = pData->iDeltaIconX;
805 	double fRadius = my_diapo_simple_radius, fLineWidth = my_diapo_simple_lineWidth;
806 
807 	gdouble fFrameWidth  = pData->iFrameWidth - 2*my_diapo_simple_radius - fLineWidth;
808 	gdouble fFrameHeight = pData->iFrameHeight - 2*my_diapo_simple_radius - fLineWidth;
809 	gdouble fDockOffsetX = pData->lmargin + fRadius + fLineWidth/2;
810 	gdouble fDockOffsetY = pData->tmargin + fLineWidth/2;
811 
812 	int iArrowPosition = pData->iArrowPosition;
813 
814 	cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);  // top bottom corner
815 
816 	//HautGauche -> HautDroit
817 	if (iArrowPosition == 1)  // top arrow
818 	{
819 		cairo_rel_line_to (pCairoContext,  fFrameWidth/2 - my_diapo_simple_arrowWidth/2 + iArrowShift, 0);                //     _
820 		cairo_rel_line_to (pCairoContext, + my_diapo_simple_arrowWidth/2 - iArrowShift + iDeltaIconX, -my_diapo_simple_arrowHeight);       //  \.
821 		cairo_rel_line_to (pCairoContext, + my_diapo_simple_arrowWidth/2 + iArrowShift - iDeltaIconX, +my_diapo_simple_arrowHeight);        //    /----
822 		cairo_rel_line_to (pCairoContext, (fFrameWidth/2 - my_diapo_simple_arrowWidth/2 - iArrowShift) , 0);               // _
823 	}
824 	else
825 		cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
826 
827 	//\_________________ Coin haut droit.
828 	cairo_rel_curve_to (pCairoContext,
829 		0, 0,
830 		my_diapo_simple_radius, 0,
831 		my_diapo_simple_radius, my_diapo_simple_radius );
832 
833 	//HautDroit -> BasDroit
834 	if (iArrowPosition == 2)  // right arrow
835 	{
836 		cairo_rel_line_to (pCairoContext, 0, fFrameHeight/2 - my_diapo_simple_arrowWidth/2 + iArrowShift);                //     _
837 		cairo_rel_line_to (pCairoContext, +my_diapo_simple_arrowHeight, + my_diapo_simple_arrowWidth/2 - iArrowShift + iDeltaIconX);       //  \.
838 		cairo_rel_line_to (pCairoContext, -my_diapo_simple_arrowHeight, + my_diapo_simple_arrowWidth/2 + iArrowShift - iDeltaIconX);        //    /
839 		cairo_rel_line_to (pCairoContext, 0, fFrameHeight/2 - my_diapo_simple_arrowWidth/2 - iArrowShift);               // _
840 	}
841 	else
842 		cairo_rel_line_to (pCairoContext, 0, fFrameHeight);
843 
844 	//\_________________ Coin bas droit.
845 	cairo_rel_curve_to (pCairoContext,
846 		0, 0,
847 		0 , my_diapo_simple_radius,
848 		-my_diapo_simple_radius , my_diapo_simple_radius);
849 
850 	//BasDroit -> BasGauche
851 	if (iArrowPosition == 0)  // bottom arrow
852 	{
853 		cairo_rel_line_to (pCairoContext, - fFrameWidth/2 + my_diapo_simple_arrowWidth/2 + iArrowShift, 0);                //     _
854 		cairo_rel_line_to (pCairoContext, - my_diapo_simple_arrowWidth/2 - iArrowShift + iDeltaIconX, +my_diapo_simple_arrowHeight);       //  \.
855 		cairo_rel_line_to (pCairoContext, - my_diapo_simple_arrowWidth/2 + iArrowShift - iDeltaIconX, -my_diapo_simple_arrowHeight);        //    /
856 		cairo_rel_line_to (pCairoContext, - fFrameWidth/2 + my_diapo_simple_arrowWidth/2 - iArrowShift , 0);               // _
857 	}
858 	else
859 		cairo_rel_line_to (pCairoContext, - fFrameWidth , 0);
860 
861 	//\_________________ Coin bas gauche.
862 	cairo_rel_curve_to (pCairoContext,
863 		0, 0,
864 		-my_diapo_simple_radius, 0,
865 		-my_diapo_simple_radius, -my_diapo_simple_radius);
866 
867 	//BasGauche -> HautGauche
868 	if (iArrowPosition == 3)  // left arrow
869 	{
870 		cairo_rel_line_to (pCairoContext, 0, - fFrameHeight/2 + my_diapo_simple_arrowWidth/2 + iArrowShift);                //     _
871 		cairo_rel_line_to (pCairoContext, -my_diapo_simple_arrowHeight, - my_diapo_simple_arrowWidth/2 - iArrowShift + iDeltaIconX);       //  \.
872 		cairo_rel_line_to (pCairoContext, +my_diapo_simple_arrowHeight, - my_diapo_simple_arrowWidth/2 + iArrowShift - iDeltaIconX);        //    /
873 		cairo_rel_line_to (pCairoContext, 0, - fFrameHeight/2 + my_diapo_simple_arrowWidth/2 - iArrowShift);               // _
874 	}
875 	else
876 		cairo_rel_line_to (pCairoContext, 0, - fFrameHeight);
877 
878 	//\_________________ Coin haut gauche.
879 	cairo_rel_curve_to (pCairoContext,
880 		0, 0,
881 		0 , -my_diapo_simple_radius ,
882 		my_diapo_simple_radius, -my_diapo_simple_radius);
883 }
884 
cairo_dock_render_decorations_in_frame_for_diapo_simple(cairo_t * pCairoContext,CairoDock * pDock,double fAlpha)885 static void cairo_dock_render_decorations_in_frame_for_diapo_simple (cairo_t *pCairoContext, CairoDock *pDock, double fAlpha)
886 {
887 	// On se fait un beau pattern degrade :
888 	cairo_pattern_t *mon_super_pattern;
889 	mon_super_pattern = cairo_pattern_create_linear (0.0,
890 		0.0,
891 		my_diapo_simple_fade2right  ? pDock->iMaxDockWidth  : 0.0, // Y'aurait surement des calculs complexes a faire mais
892 		my_diapo_simple_fade2bottom ? pDock->iMaxDockHeight : 0.0);     //  a quelques pixels pres pour un degrade : OSEF !
893 
894 	if (my_diapo_simple_use_default_colors)
895 	{
896 		GldiColor bg_color, bg_color2;
897 		gldi_style_color_get (GLDI_COLOR_BG, &bg_color);
898 		gldi_style_color_shade (&bg_color, GLDI_COLOR_SHADE_LIGHT, &bg_color2);  // same as other views
899 
900 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 0,
901 			bg_color.rgba.red,
902 			bg_color.rgba.green,
903 			bg_color.rgba.blue,
904 			1. * fAlpha);  // transparent -> opaque au depliage.
905 
906 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 1,
907 			bg_color2.rgba.red,
908 			bg_color2.rgba.green,
909 			bg_color2.rgba.blue,
910 			bg_color2.rgba.alpha * fAlpha);
911 	}
912 	else
913 	{
914 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 0,
915 			my_diapo_simple_color_frame_start[0],
916 			my_diapo_simple_color_frame_start[1],
917 			my_diapo_simple_color_frame_start[2],
918 			my_diapo_simple_color_frame_start[3] * fAlpha);  // transparent -> opaque au depliage.
919 
920 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 1,
921 			my_diapo_simple_color_frame_stop[0],
922 			my_diapo_simple_color_frame_stop[1],
923 			my_diapo_simple_color_frame_stop[2],
924 			my_diapo_simple_color_frame_stop[3] * fAlpha);
925 	}
926 	cairo_set_source (pCairoContext, mon_super_pattern);
927 
928 	//On remplit le contexte en le preservant -> pourquoi ?  ----> parce qu'on va tracer le contour plus tard ;-)
929 	cairo_fill_preserve (pCairoContext);
930 	cairo_pattern_destroy (mon_super_pattern);
931 }
932 
_render_separator(Icon * icon,CairoDock * pDock,cairo_t * pCairoContext)933 static void _render_separator (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext)
934 {
935 	cairo_pattern_t *mon_super_pattern = NULL;
936 	mon_super_pattern = cairo_pattern_create_linear (icon->fDrawX,
937 		0.0,
938 		icon->fDrawX + icon->fWidthFactor,
939 		0.0);
940 	if (my_diapo_simple_use_default_colors)
941 	{
942 		GldiColor color;
943 		gldi_style_color_get (GLDI_COLOR_SEPARATOR, &color);
944 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 0.0,
945 			color.rgba.red,
946 			color.rgba.green,
947 			color.rgba.blue,
948 			0.);
949 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, .2,
950 			color.rgba.red,
951 			color.rgba.green,
952 			color.rgba.blue,
953 			color.rgba.alpha * icon->fAlpha);
954 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, .8,
955 			color.rgba.red,
956 			color.rgba.green,
957 			color.rgba.blue,
958 			color.rgba.alpha * icon->fAlpha);
959 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 1.0,
960 			color.rgba.red,
961 			color.rgba.green,
962 			color.rgba.blue,
963 			0.);
964 	}
965 	else
966 	{
967 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 0.0,
968 			my_diapo_simple_color_border_line[0],
969 			my_diapo_simple_color_border_line[1],
970 			my_diapo_simple_color_border_line[2],
971 			0.);
972 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, .2,
973 			my_diapo_simple_color_border_line[0],
974 			my_diapo_simple_color_border_line[1],
975 			my_diapo_simple_color_border_line[2],
976 			my_diapo_simple_color_border_line[3] * icon->fAlpha);
977 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, .8,
978 			my_diapo_simple_color_border_line[0],
979 			my_diapo_simple_color_border_line[1],
980 			my_diapo_simple_color_border_line[2],
981 			my_diapo_simple_color_border_line[3] * icon->fAlpha);
982 		cairo_pattern_add_color_stop_rgba (mon_super_pattern, 1.0,
983 			my_diapo_simple_color_border_line[0],
984 			my_diapo_simple_color_border_line[1],
985 			my_diapo_simple_color_border_line[2],
986 			0.);
987 	}
988 	cairo_set_source (pCairoContext, mon_super_pattern);
989 	cairo_set_line_width (pCairoContext, my_diapo_simple_lineWidth);
990 
991 	cairo_move_to (pCairoContext, icon->fDrawX, icon->fDrawY);
992 	cairo_rel_line_to (pCairoContext, icon->fWidthFactor, 0.);
993 
994 	cairo_stroke (pCairoContext);
995 	if  (mon_super_pattern)
996 		cairo_pattern_destroy (mon_super_pattern);
997 }
998 
cd_rendering_render_diapo_simple(cairo_t * pCairoContext,CairoDock * pDock)999 static void cd_rendering_render_diapo_simple (cairo_t *pCairoContext, CairoDock *pDock)
1000 {
1001 	CDSlideData *pData = pDock->pRendererData;
1002 	g_return_if_fail (pData != NULL);
1003 
1004 	double fAlpha = (pDock->fFoldingFactor < .3 ? (.3 - pDock->fFoldingFactor) / .3 : 0.);  // apparition du cadre de 0.3 a 0
1005 
1006 	//\____________________ On trace le cadre.
1007 	cairo_save (pCairoContext);
1008 	_cairo_dock_draw_frame_for_diapo_simple (pCairoContext, pDock);
1009 
1010 	//\____________________ On dessine les decorations dedans.
1011 	cairo_dock_render_decorations_in_frame_for_diapo_simple (pCairoContext, pDock, fAlpha);
1012 
1013 	//\____________________ On dessine le cadre.
1014 	if (my_diapo_simple_lineWidth != 0 && fAlpha != 0)
1015 	{
1016 		cairo_set_line_width (pCairoContext,  my_diapo_simple_lineWidth);
1017 
1018 		if (my_diapo_simple_use_default_colors)
1019 		{
1020 			GldiColor color;
1021 			gldi_style_color_get (GLDI_COLOR_LINE, &color);
1022 			color.rgba.alpha *= fAlpha;
1023 			gldi_color_set_cairo (pCairoContext, &color);
1024 		}
1025 		else
1026 		{
1027 			cairo_set_source_rgba (pCairoContext,
1028 				my_diapo_simple_color_border_line[0],
1029 				my_diapo_simple_color_border_line[1],
1030 				my_diapo_simple_color_border_line[2],
1031 				my_diapo_simple_color_border_line[3] * fAlpha);
1032 		}
1033 		cairo_stroke (pCairoContext);
1034 	}
1035 	else
1036 		cairo_new_path (pCairoContext);
1037 	cairo_restore (pCairoContext);
1038 
1039 	if (pDock->icons == NULL)
1040 		return;
1041 
1042 	//\____________________ On dessine la ficelle qui les joint.
1043 	//TODO Rendre joli !
1044 	if (myIconsParam.iStringLineWidth > 0)
1045 		cairo_dock_draw_string (pCairoContext, pDock, myIconsParam.iStringLineWidth, TRUE, TRUE);
1046 
1047 	//\____________________ On dessine les barres de defilement.
1048 	if (pData->iDeltaHeight != 0)
1049 	{
1050 		cairo_save (pCairoContext);
1051 		cairo_set_line_width (pCairoContext, 2.);
1052 
1053 		double x_arrow = pData->lmargin + pData->iFrameWidth - fScrollbarIconGap - fScrollbarWidth/2;
1054 		double y_arrow_top, y_arrow_bottom;
1055 		y_arrow_top = pData->tmargin + my_diapo_simple_lineWidth + my_diapo_simple_radius;
1056 		y_arrow_bottom = pData->tmargin + pData->iFrameHeight - my_diapo_simple_radius;
1057 
1058 		if (pData->iScrollOffset != 0)  // fleche vers le haut.
1059 		{
1060 			cairo_move_to (pCairoContext, x_arrow, y_arrow_top);
1061 			cairo_rel_line_to (pCairoContext, fScrollbarWidth/2, fArrowHeight);
1062 			cairo_rel_line_to (pCairoContext, -fScrollbarWidth, 0.);
1063 			cairo_close_path (pCairoContext);
1064 
1065 			cairo_set_source_rgba (pCairoContext, my_diapo_simple_color_scrollbar_inside[0], my_diapo_simple_color_scrollbar_inside[1], my_diapo_simple_color_scrollbar_inside[2], my_diapo_simple_color_scrollbar_inside[3] * fAlpha);
1066 			cairo_fill_preserve (pCairoContext);
1067 
1068 			cairo_set_source_rgba (pCairoContext, my_diapo_simple_color_scrollbar_line[0], my_diapo_simple_color_scrollbar_line[1], my_diapo_simple_color_scrollbar_line[2], my_diapo_simple_color_scrollbar_line[3] * fAlpha);
1069 			cairo_stroke (pCairoContext);
1070 		}
1071 		if (pData->iScrollOffset != pData->iDeltaHeight)  // fleche vers le bas.
1072 		{
1073 			cairo_move_to (pCairoContext, x_arrow, y_arrow_bottom);
1074 			cairo_rel_line_to (pCairoContext, fScrollbarWidth/2, - fArrowHeight);
1075 			cairo_rel_line_to (pCairoContext, -fScrollbarWidth, 0.);
1076 			cairo_close_path (pCairoContext);
1077 
1078 			cairo_set_source_rgba (pCairoContext, my_diapo_simple_color_scrollbar_inside[0], my_diapo_simple_color_scrollbar_inside[1], my_diapo_simple_color_scrollbar_inside[2], my_diapo_simple_color_scrollbar_inside[3] * fAlpha);
1079 			cairo_fill_preserve (pCairoContext);
1080 
1081 			cairo_set_source_rgba (pCairoContext, my_diapo_simple_color_scrollbar_line[0], my_diapo_simple_color_scrollbar_line[1], my_diapo_simple_color_scrollbar_line[2], my_diapo_simple_color_scrollbar_line[3] * fAlpha);
1082 			cairo_stroke (pCairoContext);
1083 		}
1084 		// scrollbar outline
1085 		cairo_move_to (pCairoContext, x_arrow - fScrollbarWidth/2, y_arrow_top + fArrowHeight + fScrollbarArrowGap);
1086 		cairo_rel_line_to (pCairoContext, fScrollbarWidth, 0.);
1087 		cairo_rel_line_to (pCairoContext, 0., y_arrow_bottom - y_arrow_top - 2*(fArrowHeight+fScrollbarArrowGap));
1088 		cairo_rel_line_to (pCairoContext, -fScrollbarWidth, 0.);
1089 		cairo_close_path (pCairoContext);
1090 
1091 		cairo_set_source_rgba (pCairoContext, my_diapo_simple_color_scrollbar_inside[0], my_diapo_simple_color_scrollbar_inside[1], my_diapo_simple_color_scrollbar_inside[2], my_diapo_simple_color_scrollbar_inside[3] * fAlpha);
1092 		cairo_fill_preserve (pCairoContext);
1093 
1094 		cairo_set_source_rgba (pCairoContext, my_diapo_simple_color_scrollbar_line[0], my_diapo_simple_color_scrollbar_line[1], my_diapo_simple_color_scrollbar_line[2], my_diapo_simple_color_scrollbar_line[3] * fAlpha);
1095 		cairo_stroke (pCairoContext);
1096 		// grip
1097 		double fFrameHeight = pData->iFrameHeight;
1098 		double fGripHeight = fFrameHeight / (fFrameHeight + pData->iDeltaHeight) * (y_arrow_bottom - y_arrow_top - 2*(fArrowHeight+fScrollbarArrowGap));
1099 		double ygrip = (double) pData->iScrollOffset / pData->iDeltaHeight * (y_arrow_bottom - y_arrow_top - 2*(fArrowHeight+fScrollbarArrowGap) - fGripHeight);
1100 		cairo_set_source_rgba (pCairoContext, my_diapo_simple_color_grip[0], my_diapo_simple_color_grip[1], my_diapo_simple_color_grip[2], my_diapo_simple_color_grip[3] * fAlpha);
1101 		cairo_move_to (pCairoContext, x_arrow - fScrollbarWidth/2 + 1, y_arrow_top + fArrowHeight + fScrollbarArrowGap + ygrip);
1102 		cairo_rel_line_to (pCairoContext, fScrollbarWidth - 2, 0.);
1103 		cairo_rel_line_to (pCairoContext, 0., fGripHeight);
1104 		cairo_rel_line_to (pCairoContext, - (fScrollbarWidth - 2), 0.);
1105 		cairo_fill (pCairoContext);
1106 
1107 		cairo_restore (pCairoContext);
1108 	}
1109 
1110 	//\____________________ On dessine les icones avec leurs etiquettes.
1111 	// on determine la 1ere icone a tracer : l'icone suivant l'icone pointee.
1112 	GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
1113 	if (pFirstDrawnElement == NULL)
1114 		return;
1115 
1116 	//clip pour le scroll
1117 	if (pData->iDeltaHeight != 0) // on fait un clip pour les icones qui debordent.
1118 	{
1119 		int h = my_diapo_simple_arrowHeight + ARROW_TIP + my_diapo_simple_lineWidth;
1120 		if (pDock->container.bIsHorizontal)
1121 		{
1122 			cairo_rectangle (pCairoContext,
1123 				0.,
1124 				(pDock->container.bDirectionUp ? my_diapo_simple_lineWidth : h),  // top left corner.
1125 				pDock->container.iWidth,
1126 				pDock->container.iHeight - h - my_diapo_simple_lineWidth);
1127 		}
1128 		else
1129 		{
1130 			cairo_rectangle (pCairoContext,
1131 				(pDock->container.bDirectionUp ? my_diapo_simple_lineWidth : h),  // top left corner.
1132 				0.,
1133 				pDock->container.iHeight - h - my_diapo_simple_lineWidth,
1134 				pDock->container.iWidth);
1135 		}
1136 		cairo_clip (pCairoContext);
1137 	}
1138 
1139 	// on dessine les icones, l'icone pointee en dernier.
1140 	Icon *icon;
1141 	GList *ic = pFirstDrawnElement;
1142 	do
1143 	{
1144 		icon = ic->data;
1145 		if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
1146 		{
1147 			_render_separator (icon, pDock, pCairoContext);
1148 
1149 			ic = cairo_dock_get_next_element (ic, pDock->icons);
1150 			continue;
1151 		}
1152 
1153 		cairo_save (pCairoContext);
1154 		cairo_dock_render_one_icon (icon, pDock, pCairoContext, 1., FALSE);
1155 		cairo_restore (pCairoContext);
1156 
1157 //////////////////////////////////////////////////////////////////////////////////////// On affiche le texte !
1158 		if (icon->label.pSurface != NULL && (my_diapo_simple_display_all_labels || icon->bPointed))
1159 		{
1160 			double fAlpha = (pDock->fFoldingFactor > .5 ? (1 - pDock->fFoldingFactor) / .5 : 1.);
1161 			cairo_save (pCairoContext);
1162 
1163 			double fOffsetX = -icon->label.iWidth/2 + icon->fWidthFactor * icon->fWidth * icon->fScale / 2;
1164 			if (fOffsetX < 0)
1165 				fOffsetX = 0;
1166 			else if (0 + fOffsetX + icon->label.iWidth > pDock->container.iWidth)
1167 				fOffsetX = pDock->container.iWidth - icon->label.iWidth - 0;
1168 
1169 			if (icon->label.iWidth > icon->fWidth + my_diapo_simple_iconGapX && ! icon->bPointed)
1170 			{
1171 				if (pDock->container.bIsHorizontal)
1172 				{
1173 					cairo_translate (pCairoContext,
1174 						floor (icon->fDrawX - my_diapo_simple_iconGapX/2),
1175 						floor (icon->fDrawY - icon->label.iHeight));
1176 				}
1177 				else
1178 				{
1179 					cairo_translate (pCairoContext,
1180 						floor (icon->fDrawY - my_diapo_simple_iconGapX/2),
1181 						floor (icon->fDrawX - icon->label.iHeight));
1182 				}
1183 				cairo_set_source_surface (pCairoContext,
1184 					icon->label.pSurface,
1185 					fOffsetX,
1186 					0.);
1187 
1188 				cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (0.,
1189 					0.,
1190 					icon->fWidth * 1 + my_diapo_simple_iconGapX,
1191 					0.);
1192 				cairo_pattern_set_extend (pGradationPattern, icon->bPointed ? CAIRO_EXTEND_PAD : CAIRO_EXTEND_NONE);
1193 				cairo_pattern_add_color_stop_rgba (pGradationPattern,
1194 					0.,
1195 					0.,
1196 					0.,
1197 					0.,
1198 					fAlpha);
1199 				cairo_pattern_add_color_stop_rgba (pGradationPattern,
1200 					0.75,
1201 					0.,
1202 					0.,
1203 					0.,
1204 					fAlpha);
1205 				cairo_pattern_add_color_stop_rgba (pGradationPattern,
1206 					1.,
1207 					0.,
1208 					0.,
1209 					0.,
1210 					0*MIN (0.2, fAlpha/2));
1211 				cairo_mask (pCairoContext, pGradationPattern);
1212 				cairo_pattern_destroy (pGradationPattern);
1213 			}
1214 			else  // le texte tient dans l'icone.
1215 			{
1216 				if (pDock->container.bIsHorizontal)
1217 				{
1218 					fOffsetX = icon->fDrawX + (icon->fWidth * icon->fScale - icon->label.iWidth) / 2;
1219 					if (fOffsetX < 0)
1220 						fOffsetX = 0;
1221 					else if (fOffsetX + icon->label.iWidth > pDock->container.iWidth)
1222 						fOffsetX = pDock->container.iWidth - icon->label.iWidth;
1223 					cairo_translate (pCairoContext,
1224 						floor (fOffsetX),
1225 						floor (icon->fDrawY - icon->label.iHeight));
1226 				}
1227 				else
1228 				{
1229 					fOffsetX = icon->fDrawY + (icon->fWidth * icon->fScale - icon->label.iWidth) / 2;
1230 					if (fOffsetX < 0)
1231 						fOffsetX = 0;
1232 					else if (fOffsetX + icon->label.iWidth > pDock->container.iHeight)
1233 						fOffsetX = pDock->container.iHeight - icon->label.iWidth;
1234 					cairo_translate (pCairoContext,
1235 						floor (fOffsetX),
1236 						floor (icon->fDrawX - icon->label.iHeight));
1237 				}
1238 				/**cairo_set_source_surface (pCairoContext,
1239 					icon->pTextBuffer,
1240 					0.,
1241 					0.);
1242 				cairo_paint_with_alpha (pCairoContext, fAlpha);*/
1243 				cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
1244 					0, 0, fAlpha);
1245 			}
1246 			cairo_restore (pCairoContext);
1247 		}
1248 
1249 		ic = cairo_dock_get_next_element (ic, pDock->icons);
1250 	}
1251 	while (ic != pFirstDrawnElement);
1252 }
1253 
1254 
1255   //////////////////////
1256  /// OPENGL DRAWING ///
1257 //////////////////////
1258 
1259 #define DELTA_ROUND_DEGREE 5
1260 #define _copy_color(pColorTab, i, fAlpha, c) do { \
1261 	pColorTab[4*i]   = c[0];\
1262 	pColorTab[4*i+1] = c[1];\
1263 	pColorTab[4*i+2] = c[2];\
1264 	pColorTab[4*i+3] = c[3] * fAlpha; } while (0)
1265 /*#define _copy_mean_color(pColorTab, i, fAlpha, c1, c2, f) do { \
1266 	pColorTab[4*i]   = c1[0]*f + c2[0]*(1-f);\
1267 	pColorTab[4*i+1] = c1[1]*f + c2[1]*(1-f);\
1268 	pColorTab[4*i+2] = c1[2]*f + c2[2]*(1-f);\
1269 	pColorTab[4*i+3] = (c1[3]*f + c2[3]*(1-f)) * fAlpha; } while (0)*/
cd_add_arrow_to_path(CairoDockGLPath * pPath,double fFrameWidth,CDSlideData * pData)1270 static void cd_add_arrow_to_path (CairoDockGLPath *pPath, double fFrameWidth, CDSlideData *pData)
1271 {
1272 	int iArrowShift = pData->iArrowShift;
1273 	int iDeltaIconX = pData->iDeltaIconX;
1274 	double w = fFrameWidth / 2;
1275 	double aw = my_diapo_simple_arrowWidth/2;
1276 	double ah = my_diapo_simple_arrowHeight;
1277 	cairo_dock_gl_path_rel_line_to (pPath, w - aw + iArrowShift, 0.);  // pointe.
1278 	cairo_dock_gl_path_rel_line_to (pPath, aw - iArrowShift + iDeltaIconX, -ah);
1279 	cairo_dock_gl_path_rel_line_to (pPath, aw + iArrowShift - iDeltaIconX, ah);
1280 }
cd_generate_frame_path_without_arrow(double fFrameWidth,double fTotalHeight,double fRadius)1281 static CairoDockGLPath *cd_generate_frame_path_without_arrow (double fFrameWidth, double fTotalHeight, double fRadius)
1282 {
1283 	static CairoDockGLPath *pPath = NULL;
1284 	double fTotalWidth = fFrameWidth + 2 * fRadius;
1285 	double fFrameHeight = MAX (0, fTotalHeight - 2 * fRadius);
1286 	double w = fFrameWidth / 2;
1287 	double h = fFrameHeight / 2;
1288 	double r = fRadius;
1289 
1290 	int iNbPoins1Round = 90/DELTA_ROUND_DEGREE;
1291 	if (pPath == NULL)
1292 		pPath = cairo_dock_new_gl_path ((iNbPoins1Round+1)*4+1+3, w, -h-r, fTotalWidth, fTotalHeight);  // on commence au coin haut droit pour avoir une bonne triangulation du polygone, et en raisonnant par rapport au centre du rectangle.
1293 	else
1294 		cairo_dock_gl_path_move_to (pPath, w, -h-r);
1295 
1296 	cairo_dock_gl_path_arc (pPath, iNbPoins1Round,  w, -h, r, -G_PI/2, +G_PI/2);  // coin bas droit.
1297 
1298 	cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, h, r, 0.,     +G_PI/2);  // coin haut droit.
1299 
1300 	cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w,  h, r, G_PI/2,  +G_PI/2);  // coin haut gauche.
1301 
1302 	cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w, -h, r, G_PI,    +G_PI/2);  // coin bas gauche.
1303 
1304 	return pPath;
1305 }
1306 
cd_generate_arrow_path(double fFrameWidth,double fTotalHeight,CDSlideData * pData)1307 static CairoDockGLPath *cd_generate_arrow_path (double fFrameWidth, double fTotalHeight, CDSlideData *pData)
1308 {
1309 	static CairoDockGLPath *pPath = NULL;
1310 	int iArrowShift = pData->iArrowShift;
1311 	int iDeltaIconX = pData->iDeltaIconX;
1312 	double aw = my_diapo_simple_arrowWidth/2;
1313 	double ah = my_diapo_simple_arrowHeight;
1314 
1315 	if (pPath == NULL)
1316 		pPath = cairo_dock_new_gl_path (3, iArrowShift - aw, -fTotalHeight/2, 0., 0.);
1317 	else
1318 		cairo_dock_gl_path_move_to (pPath, iArrowShift - aw, -fTotalHeight/2);
1319 
1320 	cairo_dock_gl_path_rel_line_to (pPath, aw - iArrowShift + iDeltaIconX, -ah);
1321 	cairo_dock_gl_path_rel_line_to (pPath, aw + iArrowShift - iDeltaIconX, ah);
1322 
1323 	return pPath;
1324 }
1325 
cd_generate_color_tab(double fAlpha,GLfloat * pBottomLeftColorTab,GLfloat * pBottomRightColorTab)1326 static const GLfloat *cd_generate_color_tab (double fAlpha, GLfloat *pBottomLeftColorTab, GLfloat *pBottomRightColorTab)
1327 {
1328 	static GLfloat *pColorTab = NULL;
1329 	int iNbPoins1Round = 90/DELTA_ROUND_DEGREE;
1330 	if (pColorTab == NULL)
1331 		pColorTab = g_new (GLfloat, ((iNbPoins1Round+1)*4+1) * 4);
1332 
1333 	double *pColor1, *pColor2;
1334 	double *pTopRightColor, *pTopLeftColor, *pBottomLeftColor, *pBottomRightColor;
1335 	double pMeanColor[4];
1336 
1337 	GldiColor bg_color, bg_color2;
1338 	if (my_diapo_simple_use_default_colors)
1339 	{
1340 		gldi_style_color_get (GLDI_COLOR_BG, &bg_color);
1341 		gldi_style_color_shade (&bg_color, GLDI_COLOR_SHADE_LIGHT, &bg_color2);  // same as other views
1342 		bg_color.rgba.alpha = 1.;
1343 		pColor1 = (double*)&bg_color.rgba;
1344 		pColor2 = (double*)&bg_color2.rgba;
1345 	}
1346 	else
1347 	{
1348 		pColor1 = my_diapo_simple_color_frame_start;
1349 		pColor2 = my_diapo_simple_color_frame_stop;
1350 	}
1351 	pMeanColor[0] = (pColor1[0] + pColor2[0])/2;
1352 	pMeanColor[1] = (pColor1[1] + pColor2[1])/2;
1353 	pMeanColor[2] = (pColor1[2] + pColor2[2])/2;
1354 	pMeanColor[3] = (pColor1[3] + pColor2[3])/2;
1355 
1356 	pTopLeftColor = pColor1;
1357 	if (my_diapo_simple_fade2bottom || my_diapo_simple_fade2right)
1358 	{
1359 		pBottomRightColor = pColor2;
1360 		if (my_diapo_simple_fade2bottom && my_diapo_simple_fade2right)
1361 		{
1362 			pBottomLeftColor = pMeanColor;
1363 			pTopRightColor = pMeanColor;
1364 		}
1365 		else if (my_diapo_simple_fade2bottom)
1366 		{
1367 			pBottomLeftColor = pColor2;
1368 			pTopRightColor = pColor1;
1369 		}
1370 		else
1371 		{
1372 			pBottomLeftColor = pColor1;
1373 			pTopRightColor = pColor2;
1374 		}
1375 	}
1376 	else
1377 	{
1378 		pBottomRightColor = pColor1;
1379 		pBottomLeftColor = pColor1;
1380 		pTopRightColor = pColor1;
1381 	}
1382 
1383 	pBottomLeftColorTab[0] = pBottomLeftColor[0];
1384 	pBottomLeftColorTab[1] = pBottomLeftColor[1];
1385 	pBottomLeftColorTab[2] = pBottomLeftColor[2];
1386 	pBottomLeftColorTab[3] = pBottomLeftColor[3];
1387 
1388 	pBottomRightColorTab[0] = pBottomRightColor[0];
1389 	pBottomRightColorTab[1] = pBottomRightColor[1];
1390 	pBottomRightColorTab[2] = pBottomRightColor[2];
1391 	pBottomRightColorTab[3] = pBottomRightColor[3];
1392 
1393 	int i=0, j;
1394 	_copy_color (pColorTab, i, fAlpha, pBottomRightColor);
1395 	i ++;
1396 
1397 	for (j = 0; j < iNbPoins1Round; j ++, i ++)  // coin bas droit.
1398 	{
1399 		_copy_color (pColorTab, i, fAlpha, pBottomRightColor);
1400 	}
1401 
1402 	for (j = 0; j < iNbPoins1Round; j ++, i ++)  // coin haut droit.
1403 	{
1404 		_copy_color (pColorTab, i, fAlpha, pTopRightColor);
1405 	}
1406 
1407 	for (j = 0; j < iNbPoins1Round; j ++, i ++)  // coin haut gauche.
1408 	{
1409 		_copy_color (pColorTab, i, fAlpha, pTopLeftColor);
1410 	}
1411 
1412 	for (j = 0; j < iNbPoins1Round; j ++, i ++)  // coin bas gauche.
1413 	{
1414 		_copy_color (pColorTab, i, fAlpha, pBottomLeftColor);
1415 	}
1416 
1417 	return pColorTab;
1418 }
1419 
_render_separator_opengl(Icon * icon,CairoDock * pDock)1420 static void _render_separator_opengl (Icon *icon, CairoDock *pDock)
1421 {
1422 	glPushMatrix ();
1423 
1424 	glTranslatef (icon->fDrawX, floor ((pDock->container.bIsHorizontal?pDock->container.iHeight:pDock->container.iWidth) - icon->fDrawY) + .5 * (my_diapo_simple_lineWidth&1), 0.);
1425 
1426 	glEnable (GL_BLEND);
1427 	_cairo_dock_set_blend_alpha ();
1428 
1429 	glPolygonMode (GL_FRONT, GL_LINE);
1430 	glLineWidth (my_diapo_simple_lineWidth);
1431 
1432 	glBegin(GL_LINE_STRIP);
1433 
1434 	if (my_diapo_simple_use_default_colors)
1435 	{
1436 		GldiColor color;
1437 		gldi_style_color_get (GLDI_COLOR_SEPARATOR, &color);
1438 		color.rgba.alpha *= icon->fAlpha;
1439 
1440 		glColor4f (color.rgba.red, color.rgba.green, color.rgba.blue, 0.);
1441 		glVertex3f (0., 0., 0.);
1442 
1443 		glColor4f (color.rgba.red, color.rgba.green, color.rgba.blue, color.rgba.alpha * icon->fAlpha);
1444 		glVertex3f (.2 * icon->fWidthFactor, 0, 0.);
1445 		glVertex3f (.8 * icon->fWidthFactor, 0, 0.);
1446 
1447 		glColor4f (color.rgba.red, color.rgba.green, color.rgba.blue, 0.);
1448 		glVertex3f (icon->fWidthFactor, 0., 0.);
1449 	}
1450 	else
1451 	{
1452 		glColor4f (my_diapo_simple_color_border_line[0], my_diapo_simple_color_border_line[1], my_diapo_simple_color_border_line[2], 0.);
1453 		glVertex3f (0., 0., 0.);
1454 
1455 		glColor4f (my_diapo_simple_color_border_line[0], my_diapo_simple_color_border_line[1], my_diapo_simple_color_border_line[2], my_diapo_simple_color_border_line[3] * icon->fAlpha);
1456 		glVertex3f (.2 * icon->fWidthFactor, 0., 0.);
1457 		glVertex3f (.8 * icon->fWidthFactor, 0., 0.);
1458 
1459 		glColor4f (my_diapo_simple_color_border_line[0], my_diapo_simple_color_border_line[1], my_diapo_simple_color_border_line[2], 0.);
1460 		glVertex3f (icon->fWidthFactor, 0., 0.);
1461 	}
1462 	glEnd();
1463 
1464 	glPopMatrix ();
1465 }
1466 
1467 #define N_ROUND 7
cd_rendering_render_diapo_simple_opengl(CairoDock * pDock)1468 static void cd_rendering_render_diapo_simple_opengl (CairoDock *pDock)
1469 {
1470 	CDSlideData *pData = pDock->pRendererData;
1471 	g_return_if_fail (pData != NULL);
1472 	static CairoDockGLPath *pScrollPath = NULL;
1473 
1474 	//\____________________ On initialise le cadre.
1475 	double fRadius = my_diapo_simple_radius;
1476 	double fFrameWidth, fFrameHeight;
1477 	double fDockOffsetX, fDockOffsetY;
1478 	if (pDock->container.bIsHorizontal)
1479 	{
1480 		fFrameWidth  = pData->iFrameWidth - 2*fRadius;
1481 		fFrameHeight = pData->iFrameHeight - my_diapo_simple_lineWidth;
1482 		fDockOffsetX = (pDock->container.bDirectionUp ? pData->lmargin : pData->rmargin);
1483 		fDockOffsetY = (pDock->container.bDirectionUp ? pData->bmargin : pData->tmargin);
1484 	}
1485 	else
1486 	{
1487 		fFrameWidth  = pData->iFrameHeight - 2*fRadius - my_diapo_simple_lineWidth;
1488 		fFrameHeight = pData->iFrameWidth - my_diapo_simple_lineWidth;
1489 		fDockOffsetX = (pDock->container.bDirectionUp ? pData->bmargin : pData->tmargin);
1490 		fDockOffsetY = (pDock->container.bDirectionUp ? pData->rmargin : pData->lmargin);
1491 	}
1492 
1493 	//\_____________ On genere les coordonnees du contour.
1494 	CairoDockGLPath *pFramePath = cd_generate_frame_path_without_arrow (fFrameWidth, fFrameHeight, fRadius);
1495 
1496 	//\_____________ On remplit avec le fond.
1497 	glPushMatrix ();
1498 	double fAlpha = (pDock->fFoldingFactor < .3 ? (.3 - pDock->fFoldingFactor) / .3 : 0.);  // apparition du cadre de 0.3 a 0
1499 	cairo_dock_set_container_orientation_opengl (CAIRO_CONTAINER (pDock));
1500 	glTranslatef (fDockOffsetX + (fFrameWidth)/2 + fRadius,
1501 		fDockOffsetY + fFrameHeight/2,
1502 		0.);
1503 	_cairo_dock_set_blend_alpha ();
1504 
1505 	// le cadre sans la pointe.
1506 	GLfloat pBottomLeftColor[4], pBottomRightColor[4];
1507 	const GLfloat *pColorTab = cd_generate_color_tab (fAlpha, pBottomLeftColor, pBottomRightColor);
1508 	glEnableClientState (GL_COLOR_ARRAY);
1509 	glColorPointer (4, GL_FLOAT, 0, pColorTab);
1510 	cairo_dock_fill_gl_path (pFramePath, 0);
1511 	glDisableClientState (GL_COLOR_ARRAY);
1512 
1513 	// la pointe.
1514 	CairoDockGLPath *pArrowPath = cd_generate_arrow_path (fFrameWidth, fFrameHeight, pData);
1515 	double f = .5 + (double)pData->iArrowShift / fFrameWidth;
1516 	GLfloat pArrowColor[4];
1517 	pArrowColor[0] = pBottomRightColor[0] * f + pBottomLeftColor[0] * (1-f);
1518 	pArrowColor[1] = pBottomRightColor[1] * f + pBottomLeftColor[1] * (1-f);
1519 	pArrowColor[2] = pBottomRightColor[2] * f + pBottomLeftColor[2] * (1-f);
1520 	pArrowColor[3] = pBottomRightColor[3] * f + pBottomLeftColor[3] * (1-f);
1521 
1522 	glColor4f (pArrowColor[0], pArrowColor[1], pArrowColor[2], pArrowColor[3] * fAlpha);
1523 	cairo_dock_fill_gl_path (pArrowPath, 0);
1524 
1525 	//\_____________ On trace le contour.
1526 	if (my_diapo_simple_lineWidth != 0 && fAlpha != 0)
1527 	{
1528 		cd_add_arrow_to_path (pFramePath, fFrameWidth, pData);
1529 		glLineWidth (my_diapo_simple_lineWidth);
1530 
1531 		if (my_diapo_simple_use_default_colors)
1532 		{
1533 			GldiColor color;
1534 			gldi_style_color_get (GLDI_COLOR_LINE, &color);
1535 			glColor4f (color.rgba.red, color.rgba.green, color.rgba.blue, color.rgba.alpha * fAlpha);
1536 		}
1537 		else
1538 		{
1539 			glColor4f (my_diapo_simple_color_border_line[0], my_diapo_simple_color_border_line[1], my_diapo_simple_color_border_line[2], my_diapo_simple_color_border_line[3] * fAlpha);
1540 		}
1541 		cairo_dock_stroke_gl_path (pFramePath, TRUE);
1542 	}
1543 	glPopMatrix ();
1544 	_cairo_dock_set_blend_alpha ();
1545 
1546 	//\____________________ On dessine les barres de defilement.
1547 	if (pData->iDeltaHeight != 0)
1548 	{
1549 		if (pScrollPath == NULL)
1550 			pScrollPath = cairo_dock_new_gl_path (N_ROUND + 5, 0., 0., 0, 0);  // un arc + le sommet + la base
1551 		glLineWidth (2.);
1552 		glPushMatrix ();
1553 		double x_arrow = pData->lmargin + pData->iFrameWidth - fScrollbarIconGap - fScrollbarWidth/2;
1554 		double y_arrow_top, y_arrow_bottom;
1555 		y_arrow_top = pData->bmargin + pData->iFrameHeight - my_diapo_simple_radius;
1556 		y_arrow_bottom = pData->bmargin + my_diapo_simple_lineWidth + my_diapo_simple_radius;
1557 
1558 		if (pData->iScrollOffset != 0)  // fleche vers le haut.
1559 		{
1560 			cairo_dock_gl_path_move_to (pScrollPath, x_arrow, y_arrow_top);
1561 			cairo_dock_gl_path_rel_line_to (pScrollPath, fScrollbarWidth/2, -fArrowHeight);
1562 			cairo_dock_gl_path_rel_line_to (pScrollPath, 0., -fScrollbarArrowGap);
1563 			cairo_dock_gl_path_rel_simple_curve_to (pScrollPath, N_ROUND,
1564 				-fScrollbarWidth/2, 4*fScrollbarRadius/3,  // hauteur de controle pour atteindre la meme hauteur que l'arc de la barre.
1565 				-fScrollbarWidth, 0.);
1566 			cairo_dock_gl_path_rel_line_to (pScrollPath, 0., fScrollbarArrowGap);
1567 
1568 			glColor4f (my_diapo_simple_color_scrollbar_inside[0], my_diapo_simple_color_scrollbar_inside[1], my_diapo_simple_color_scrollbar_inside[2], my_diapo_simple_color_scrollbar_inside[3] * fAlpha);
1569 			cairo_dock_fill_gl_path (pScrollPath, 0);
1570 
1571 			glColor4f (my_diapo_simple_color_scrollbar_line[0], my_diapo_simple_color_scrollbar_line[1], my_diapo_simple_color_scrollbar_line[2], my_diapo_simple_color_scrollbar_line[3] * fAlpha);
1572 			cairo_dock_stroke_gl_path (pScrollPath, TRUE);  // TRUE <=> close
1573 		}
1574 		if (pData->iScrollOffset != pData->iDeltaHeight)  // fleche vers le bas.
1575 		{
1576 			cairo_dock_gl_path_move_to (pScrollPath, x_arrow, y_arrow_bottom);
1577 			cairo_dock_gl_path_rel_line_to (pScrollPath, fScrollbarWidth/2, fArrowHeight);
1578 			cairo_dock_gl_path_rel_line_to (pScrollPath, 0., fScrollbarArrowGap);
1579 			cairo_dock_gl_path_rel_simple_curve_to (pScrollPath, N_ROUND,
1580 				-fScrollbarWidth/2, -(fScrollbarArrowGap + 4*fScrollbarRadius/3),
1581 				-fScrollbarWidth, 0.);
1582 			cairo_dock_gl_path_rel_line_to (pScrollPath, 0., -fScrollbarArrowGap);
1583 
1584 			glColor4f (my_diapo_simple_color_scrollbar_inside[0], my_diapo_simple_color_scrollbar_inside[1], my_diapo_simple_color_scrollbar_inside[2], my_diapo_simple_color_scrollbar_inside[3] * fAlpha);
1585 			cairo_dock_fill_gl_path (pScrollPath, 0);
1586 
1587 			glColor4f (my_diapo_simple_color_scrollbar_line[0], my_diapo_simple_color_scrollbar_line[1], my_diapo_simple_color_scrollbar_line[2], my_diapo_simple_color_scrollbar_line[3] * fAlpha);
1588 			cairo_dock_stroke_gl_path (pScrollPath, TRUE);  // TRUE <=> close
1589 		}
1590 
1591 		// scrollbar outline
1592 		int iBarHeight = y_arrow_top - y_arrow_bottom - 2*(fArrowHeight+fScrollbarArrowGap);
1593 		const CairoDockGLPath *pPath = cairo_dock_generate_rectangle_path (fScrollbarWidth - 2*fScrollbarRadius,
1594 			iBarHeight,
1595 			fScrollbarRadius, TRUE);
1596 		glPushMatrix ();
1597 		glTranslatef (x_arrow, (y_arrow_bottom + y_arrow_top)/2, 0.);
1598 
1599 		glColor4f (my_diapo_simple_color_scrollbar_inside[0], my_diapo_simple_color_scrollbar_inside[1], my_diapo_simple_color_scrollbar_inside[2], my_diapo_simple_color_scrollbar_inside[3] * fAlpha);
1600 		cairo_dock_fill_gl_path (pPath, 0);
1601 
1602 		glColor4f (my_diapo_simple_color_scrollbar_line[0], my_diapo_simple_color_scrollbar_line[1], my_diapo_simple_color_scrollbar_line[2], my_diapo_simple_color_scrollbar_line[3] * fAlpha);
1603 		cairo_dock_stroke_gl_path (pPath, TRUE);
1604 		glPopMatrix ();
1605 
1606 		// grip
1607 		double fGripHeight = (double)pData->iFrameHeight / (pData->iFrameHeight + pData->iDeltaHeight) * (y_arrow_top - y_arrow_bottom - 2*(fArrowHeight+fScrollbarArrowGap));
1608 		if (fGripHeight < 2*fScrollbarRadius)
1609 			fGripHeight = 2*fScrollbarRadius;
1610 		double ygrip = (double) pData->iScrollOffset / pData->iDeltaHeight * (y_arrow_top - y_arrow_bottom - 2*(fArrowHeight+fScrollbarArrowGap) - fGripHeight);
1611 		pPath = cairo_dock_generate_rectangle_path (fScrollbarWidth - 2*fScrollbarRadius - 2,
1612 			fGripHeight,
1613 			fScrollbarRadius, TRUE);
1614 		glPushMatrix ();
1615 		glTranslatef (x_arrow, y_arrow_top - (fArrowHeight+fScrollbarArrowGap) - ygrip - fGripHeight/2, 0.);
1616 
1617 		glColor4f (my_diapo_simple_color_grip[0], my_diapo_simple_color_grip[1], my_diapo_simple_color_grip[2], my_diapo_simple_color_grip[3] * fAlpha);
1618 		cairo_dock_fill_gl_path (pPath, 0);
1619 		glPopMatrix ();
1620 
1621 		glPopMatrix ();
1622 	}
1623 
1624 	if (pDock->icons == NULL)
1625 		return ;
1626 
1627 	//\____________________ On dessine la ficelle.
1628 	if (myIconsParam.iStringLineWidth > 0)
1629 		cairo_dock_draw_string_opengl (pDock, myIconsParam.iStringLineWidth, FALSE, FALSE);
1630 
1631 	//\____________________ On dessine les icones.
1632 	// on determine la 1ere icone a tracer : l'icone suivant l'icone pointee.
1633 	GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
1634 	if (pFirstDrawnElement == NULL)
1635 		return;
1636 
1637 	// on dessine les icones, l'icone pointee en dernier.
1638 	if (pData->iDeltaHeight != 0) // on fait un clip pour les icones qui debordent.
1639 	{
1640 		int h = my_diapo_simple_arrowHeight + ARROW_TIP + my_diapo_simple_lineWidth;
1641 		glEnable (GL_SCISSOR_TEST);
1642 		if (pDock->container.bIsHorizontal)
1643 		{
1644 			glScissor (0,
1645 				(pDock->container.bDirectionUp ? h : my_diapo_simple_lineWidth),  // lower left corner of the scissor box.
1646 				pDock->container.iWidth,
1647 				pDock->container.iHeight - h - my_diapo_simple_lineWidth);
1648 		}
1649 		else
1650 		{
1651 			glScissor ((!pDock->container.bDirectionUp ? h : my_diapo_simple_lineWidth),  // lower left corner of the scissor box.
1652 				my_diapo_simple_lineWidth,
1653 				pDock->container.iHeight - h - my_diapo_simple_lineWidth,
1654 				pDock->container.iWidth);
1655 		}
1656 	}
1657 
1658 	Icon *icon;
1659 	GList *ic = pFirstDrawnElement;
1660 	do
1661 	{
1662 		icon = ic->data;
1663 		if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
1664 		{
1665 			_render_separator_opengl (icon, pDock);
1666 			ic = cairo_dock_get_next_element (ic, pDock->icons);
1667 			continue;
1668 		}
1669 
1670 		cairo_dock_render_one_icon_opengl (icon, pDock, 1., FALSE);
1671 
1672 		if (icon->label.iTexture != 0 && (my_diapo_simple_display_all_labels || icon->bPointed))
1673 		{
1674 			glPushMatrix ();
1675 			glLoadIdentity ();
1676 
1677 			double fAlpha = (pDock->fFoldingFactor > .5 ? (1 - pDock->fFoldingFactor) / .5 : 1.);  // apparition du texte de 1 a 0.5
1678 
1679 			double dx, dy = .5 * (icon->label.iHeight & 1);  // on decale la texture pour la coller sur la grille des coordonnees entieres.
1680 			double u0 = 0., u1 = 1.;
1681 			double fOffsetX = 0.;
1682 			if (pDock->container.bIsHorizontal)
1683 			{
1684 				if (icon->bPointed)
1685 				{
1686 					_cairo_dock_set_alpha (fAlpha);
1687 					if (icon->fDrawX + icon->fWidth/2 + icon->label.iWidth/2 > pDock->container.iWidth)
1688 						fOffsetX = pDock->container.iWidth - (icon->fDrawX + icon->fWidth/2 + icon->label.iWidth/2);
1689 					if (icon->fDrawX + icon->fWidth/2 - icon->label.iWidth/2 < 0)
1690 						fOffsetX = icon->label.iWidth/2 - (icon->fDrawX + icon->fWidth/2);
1691 				}
1692 				else
1693 				{
1694 					_cairo_dock_set_alpha (fAlpha);
1695 					///_cairo_dock_set_alpha (fAlpha * icon->fScale / my_diapo_simple_fScaleMax);
1696 					double text_width = floor ((icon->fWidth + my_diapo_simple_iconGapX) / 2) * 2;  // make it even, so that we don't get blur when we draw with the gradation.
1697 					if (icon->label.iWidth > text_width)
1698 					{
1699 						fOffsetX = 0.;
1700 						u1 = text_width / icon->label.iWidth;
1701 					}
1702 				}
1703 				dx = .5 * (((int)round (icon->label.iWidth * (u1 - u0))) & 1);
1704 
1705 				glTranslatef (ceil (icon->fDrawX + icon->fScale * icon->fWidth/2 + fOffsetX) + dx,
1706 					ceil (pDock->container.iHeight - icon->fDrawY + icon->label.iHeight / 2) + dy,
1707 					0.);
1708 			}
1709 			else
1710 			{
1711 				if (icon->bPointed)
1712 				{
1713 					_cairo_dock_set_alpha (fAlpha);
1714 					if (icon->fDrawY + icon->fHeight/2 + icon->label.iWidth/2 > pDock->container.iHeight)
1715 						fOffsetX = pDock->container.iHeight - (icon->fDrawY + icon->fHeight/2 + icon->label.iWidth/2);
1716 					if (icon->fDrawY + icon->fHeight/2 - icon->label.iWidth/2 < 0)
1717 						fOffsetX = icon->label.iWidth/2 - (icon->fDrawY + icon->fHeight/2);
1718 				}
1719 				else
1720 				{
1721 					_cairo_dock_set_alpha (fAlpha);
1722 					double text_width = (int)floor (icon->fWidth + 2 * myIconsParam.iLabelSize) / 2 * 2;  // see above.
1723 					if (icon->label.iWidth > text_width)
1724 					{
1725 						fOffsetX = 0.;
1726 						u1 = text_width / icon->label.iWidth;
1727 					}
1728 				}
1729 				dx = .5 * (((int)round (icon->label.iWidth * (u1 - u0))) & 1);
1730 
1731 				glTranslatef (ceil (icon->fDrawY + icon->fScale * icon->fHeight/2 + fOffsetX / 2) + dx,
1732 					ceil (pDock->container.iWidth - icon->fDrawX + icon->label.iHeight / 2) + dy,
1733 					0.);
1734 			}
1735 			_cairo_dock_enable_texture ();
1736 			_cairo_dock_set_blend_alpha ();
1737 			glBindTexture (GL_TEXTURE_2D, icon->label.iTexture);
1738 
1739 			double w = round (icon->label.iWidth * (u1 - u0)), h = icon->label.iHeight;
1740 			if (u1 < .99)  // draw with an alpha gradation on the last part.
1741 			{
1742 				glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1743 				glBegin(GL_QUAD_STRIP);
1744 
1745 				double a = .75; // 3/4 plain, 1/4 gradation
1746 				a = (double) (floor ((-.5+a)*w)) / w + .5;
1747 				glColor4f (1., 1., 1., 1.);
1748 				glTexCoord2f(u0, 0); glVertex3f(-.5*w,  .5*h, 0.);  // top left
1749 				glTexCoord2f(u0, 1); glVertex3f(-.5*w, -.5*h, 0.);  // bottom left
1750 
1751 				glTexCoord2f(u1*a, 0); glVertex3f(  ((-.5+a)*w),  .5*h, 0.);  // top middle
1752 				glTexCoord2f(u1*a, 1); glVertex3f(  ((-.5+a)*w),  -.5*h, 0.);  // bottom middle
1753 
1754 				glColor4f (1., 1., 1., 0.);
1755 
1756 				glTexCoord2f(u1, 0); glVertex3f( .5*w,  .5*h, 0.);  // top right
1757 				glTexCoord2f(u1, 1); glVertex3f( .5*w, -.5*h, 0.);  // bottom right
1758 
1759 				glEnd();
1760 			}
1761 			else
1762 			{
1763 				_cairo_dock_apply_current_texture_at_size (w, h);
1764 			}
1765 			_cairo_dock_disable_texture ();
1766 			_cairo_dock_set_alpha (1.);
1767 
1768 			glPopMatrix ();
1769 		}
1770 
1771 		ic = cairo_dock_get_next_element (ic, pDock->icons);
1772 	}
1773 	while (ic != pFirstDrawnElement);
1774 	glDisable (GL_SCISSOR_TEST);
1775 }
1776 
1777 
cd_rendering_free_slide_data(CairoDock * pDock)1778 void cd_rendering_free_slide_data (CairoDock *pDock)
1779 {
1780 	CDSlideData *pData = pDock->pRendererData;
1781 	if (pData != NULL)
1782 	{
1783 		gldi_object_remove_notification (CAIRO_CONTAINER (pDock), NOTIFICATION_SCROLL_ICON, (GldiNotificationFunc) _cd_slide_on_scroll, NULL);
1784 		gldi_object_remove_notification (CAIRO_CONTAINER (pDock), NOTIFICATION_CLICK_ICON, (GldiNotificationFunc) _cd_slide_on_click, NULL);
1785 		gldi_object_remove_notification (CAIRO_CONTAINER (pDock), NOTIFICATION_MOUSE_MOVED, (GldiNotificationFunc) _cd_slide_on_mouse_moved, NULL);
1786 		g_signal_handler_disconnect (pDock->container.pWidget, pData->iSidPressEvent);
1787 		g_signal_handler_disconnect (pDock->container.pWidget, pData->iSidReleaseEvent);
1788 
1789 		g_free (pData);
1790 		pDock->pRendererData = NULL;
1791 	}
1792 }
1793 
1794 
cd_rendering_set_subdock_position_slide(Icon * pPointedIcon,CairoDock * pDock)1795 void cd_rendering_set_subdock_position_slide (Icon *pPointedIcon, CairoDock *pDock)
1796 {
1797 	CairoDock *pSubDock = pPointedIcon->pSubDock;
1798 
1799 	CDSlideData *pData = pSubDock->pRendererData;
1800 	g_return_if_fail (pData != NULL);
1801 
1802 	///int iX = pPointedIcon->fXAtRest - (pDock->fFlatDockWidth - pDock->iMaxDockWidth) / 2 + pPointedIcon->fWidth / 2 + (pDock->iOffsetForExtend * (pDock->fAlign - .5) * 2);
1803 	//int iX = pPointedIcon->fDrawX + pPointedIcon->fWidth * pPointedIcon->fScale / 2 + (pDock->iOffsetForExtend * (pDock->fAlign - .5) * 2);
1804 	int W = gldi_dock_get_screen_width (pDock);
1805 	int iScreenOffsetX = gldi_dock_get_screen_offset_x (pDock);
1806 	int iX = pPointedIcon->fDrawX + pPointedIcon->fWidth * pPointedIcon->fScale / 2;
1807 	if (pSubDock->container.bIsHorizontal == pDock->container.bIsHorizontal)
1808 	{
1809 		pSubDock->fAlign = 0.5;
1810 		pSubDock->iGapX = iX + pDock->container.iWindowPositionX - iScreenOffsetX - W / 2;  // ici les sous-dock ont un alignement egal a 0.5
1811 		pSubDock->iGapY = pDock->iGapY + pDock->iActiveHeight;
1812 	}
1813 	else
1814 	{
1815 		pSubDock->fAlign = (pDock->container.bDirectionUp ? 1 : 0);
1816 		pSubDock->iGapX = (pDock->iGapY + pDock->iActiveHeight) * (pDock->container.bDirectionUp ? -1 : 1);
1817 		if (pDock->container.bDirectionUp)
1818 			pSubDock->iGapY = W - (iX + pDock->container.iWindowPositionX - iScreenOffsetX) - pSubDock->iMaxDockHeight / 2;  // les sous-dock ont un alignement egal a 1.
1819 		else
1820 			pSubDock->iGapY = iX + pDock->container.iWindowPositionX - pSubDock->iMaxDockHeight / 2;  // les sous-dock ont un alignement egal a 0.
1821 	}
1822 
1823 	int delta_max = (pDock->container.bIsHorizontal ? pData->iFrameWidth : pData->iFrameHeight) / 2 - my_diapo_simple_radius;
1824 	pData->iDeltaIconX = MAX (-delta_max, MIN (0, iX + pDock->container.iWindowPositionX - iScreenOffsetX - pSubDock->iMaxDockWidth/2));
1825 	if (pData->iDeltaIconX == 0)
1826 		pData->iDeltaIconX = MIN ( delta_max, MAX (0, iX + pDock->container.iWindowPositionX - iScreenOffsetX + pSubDock->iMaxDockWidth/2 - W));
1827 	//g_print ("iDeltaIconX: %d\n", pData->iDeltaIconX);
1828 
1829 	if (pData->iDeltaIconX != 0)  // il y'a un decalage, on va limiter la pente du cote le plus court de la pointe a 30 degres.
1830 	{
1831 		pData->iArrowShift = MAX (0, fabs (pData->iDeltaIconX) - my_diapo_simple_arrowHeight * .577 - my_diapo_simple_arrowWidth/2);  // tan(30)
1832 		if (pData->iDeltaIconX < 0)
1833 			pData->iArrowShift = - pData->iArrowShift;
1834 		//g_print ("iArrowShift: %d\n", pData->iArrowShift);
1835 	}
1836 	else
1837 		pData->iArrowShift = 0;
1838 }
1839 
1840 
cd_rendering_register_diapo_simple_renderer(const gchar * cRendererName)1841 void cd_rendering_register_diapo_simple_renderer (const gchar *cRendererName)
1842 {
1843 	CairoDockRenderer *pRenderer = g_new0 (CairoDockRenderer, 1);
1844 	// interface
1845 	pRenderer->compute_size 		= cd_rendering_calculate_max_dock_size_diapo_simple;
1846 	pRenderer->calculate_icons 		= cd_rendering_calculate_icons_diapo_simple;
1847 	pRenderer->render 				= cd_rendering_render_diapo_simple;
1848 	pRenderer->render_optimized 	= NULL;
1849 	pRenderer->render_opengl 		= cd_rendering_render_diapo_simple_opengl;
1850 	pRenderer->free_data 			= cd_rendering_free_slide_data;
1851 	pRenderer->set_subdock_position = cd_rendering_set_subdock_position_slide;
1852 	// parametres
1853 	pRenderer->cReadmeFilePath 		= g_strdup (MY_APPLET_SHARE_DATA_DIR"/readme-slide-view");
1854 	pRenderer->cPreviewFilePath 	= g_strdup (MY_APPLET_SHARE_DATA_DIR"/preview-slide.jpg");
1855 	pRenderer->bUseReflect 			= FALSE;  // pas de reflections
1856 	pRenderer->cDisplayedName 		= D_(cRendererName);
1857 
1858 	cairo_dock_register_renderer (cRendererName, pRenderer);
1859 }
1860