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
22 #include "cairo-dock-icon-facility.h" // cairo_dock_get_next_element
23 #include "cairo-dock-dock-factory.h"
24 #include "cairo-dock-dock-facility.h" // cairo_dock_get_first_drawn_element_linear
25 #include "cairo-dock-animations.h" // cairo_dock_calculate_magnitude
26 #include "cairo-dock-log.h"
27 #include "cairo-dock-dock-manager.h" // myDocksParam
28 #include "cairo-dock-applications-manager.h"
29 #include "cairo-dock-separator-manager.h"
30 #include "cairo-dock-applet-manager.h"
31 #include "cairo-dock-backends-manager.h"
32 #include "cairo-dock-container.h"
33 #include "cairo-dock-image-buffer.h"
34 #include "cairo-dock-desktop-manager.h" // g_pFakeTransparencyDesktopBg
35 #include "cairo-dock-windows-manager.h"
36 #include "cairo-dock-style-manager.h"
37 #include "cairo-dock-draw-opengl.h" // pour cairo_dock_render_one_icon
38 #include "cairo-dock-overlay.h" // cairo_dock_draw_icon_overlays_cairo
39 #include "cairo-dock-draw.h"
40
41 extern CairoDockImageBuffer g_pVisibleZoneBuffer;
42
43 extern GldiDesktopBackground *g_pFakeTransparencyDesktopBg;
44 extern gboolean g_bUseOpenGL;
45
46
cairo_dock_create_drawing_context_generic(GldiContainer * pContainer)47 cairo_t * cairo_dock_create_drawing_context_generic (GldiContainer *pContainer)
48 {
49 return gdk_cairo_create (gldi_container_get_gdk_window (pContainer));
50 }
51
cairo_dock_create_drawing_context_on_container(GldiContainer * pContainer)52 cairo_t *cairo_dock_create_drawing_context_on_container (GldiContainer *pContainer)
53 {
54 cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (pContainer);
55 g_return_val_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS, NULL);
56
57 cairo_dock_init_drawing_context_on_container (pContainer, pCairoContext);
58
59 return pCairoContext;
60 }
61
cairo_dock_init_drawing_context_on_container(GldiContainer * pContainer,cairo_t * pCairoContext)62 void cairo_dock_init_drawing_context_on_container (GldiContainer *pContainer, cairo_t *pCairoContext)
63 {
64 if (g_pFakeTransparencyDesktopBg && g_pFakeTransparencyDesktopBg->pSurface)
65 {
66 if (pContainer->bIsHorizontal)
67 cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionX, - pContainer->iWindowPositionY);
68 else
69 cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionY, - pContainer->iWindowPositionX);
70 }
71 else
72 cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
73 cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
74 cairo_paint (pCairoContext);
75
76 cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
77 }
78
cairo_dock_create_drawing_context_on_area(GldiContainer * pContainer,GdkRectangle * pArea,double * fBgColor)79 cairo_t *cairo_dock_create_drawing_context_on_area (GldiContainer *pContainer, GdkRectangle *pArea, double *fBgColor)
80 {
81 cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (pContainer);
82 g_return_val_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS, pCairoContext);
83
84 if (pArea != NULL && (pArea->x > 0 || pArea->y > 0))
85 {
86 cairo_rectangle (pCairoContext,
87 pArea->x,
88 pArea->y,
89 pArea->width,
90 pArea->height);
91 cairo_clip (pCairoContext);
92 }
93
94 ///if (myContainersParam.bUseFakeTransparency)
95 ///{
96 if (g_pFakeTransparencyDesktopBg && g_pFakeTransparencyDesktopBg->pSurface)
97 {
98 if (pContainer->bIsHorizontal)
99 cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionX, - pContainer->iWindowPositionY);
100 else
101 cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionY, - pContainer->iWindowPositionX);
102 }
103 /**else
104 cairo_set_source_rgba (pCairoContext, 0.8, 0.8, 0.8, 0.0);
105 }*/
106 else if (fBgColor != NULL)
107 cairo_set_source_rgba (pCairoContext, fBgColor[0], fBgColor[1], fBgColor[2], fBgColor[3]);
108 else
109 cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
110 cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
111 cairo_paint (pCairoContext);
112
113 cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
114 return pCairoContext;
115 }
116
117
118
119
cairo_dock_calculate_extra_width_for_trapeze(double fFrameHeight,double fInclination,double fRadius,double fLineWidth)120 double cairo_dock_calculate_extra_width_for_trapeze (double fFrameHeight, double fInclination, double fRadius, double fLineWidth)
121 {
122 if (2 * fRadius > fFrameHeight + fLineWidth)
123 fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
124 double cosa = 1. / sqrt (1 + fInclination * fInclination);
125 double sina = fInclination * cosa;
126
127 double fExtraWidth = fInclination * (fFrameHeight - (FALSE ? 2 : 1-cosa) * fRadius) + fRadius * (FALSE ? 1 : sina);
128 return (2 * fExtraWidth + fLineWidth);
129 /**double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (myDocksParam.bRoundedBottomCorner ? 2 : 1) * fRadius);
130 double fDeltaCornerForLoop = fRadius * cosa + (myDocksParam.bRoundedBottomCorner ? fRadius * (1 + sina) * fInclination : 0);
131
132 return (2 * (fLineWidth/2 + fDeltaXForLoop + fDeltaCornerForLoop + myDocksParam.iFrameMargin));*/
133 }
134
135 /**void cairo_dock_draw_rounded_rectangle (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight)
136 {
137 if (2*fRadius > fFrameHeight + fLineWidth)
138 fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
139 double fDockOffsetX = fRadius + fLineWidth/2;
140 double fDockOffsetY = 0.;
141 cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
142 cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
143 //\_________________ Coin haut droit.
144 cairo_rel_curve_to (pCairoContext,
145 0, 0,
146 fRadius, 0,
147 fRadius, fRadius);
148 cairo_rel_line_to (pCairoContext, 0, (fFrameHeight + fLineWidth - fRadius * 2));
149 //\_________________ Coin bas droit.
150 cairo_rel_curve_to (pCairoContext,
151 0, 0,
152 0, fRadius,
153 -fRadius, fRadius);
154
155 cairo_rel_line_to (pCairoContext, - fFrameWidth, 0);
156 //\_________________ Coin bas gauche.
157 cairo_rel_curve_to (pCairoContext,
158 0, 0,
159 -fRadius, 0,
160 -fRadius, - fRadius);
161 cairo_rel_line_to (pCairoContext, 0, (- fFrameHeight - fLineWidth + fRadius * 2));
162 //\_________________ Coin haut gauche.
163 cairo_rel_curve_to (pCairoContext,
164 0, 0,
165 0, -fRadius,
166 fRadius, -fRadius);
167 if (fRadius < 1)
168 cairo_close_path (pCairoContext);
169 }*/
cairo_dock_draw_rounded_rectangle(cairo_t * pCairoContext,double fRadius,double fLineWidth,double fFrameWidth,double fFrameHeight)170 void cairo_dock_draw_rounded_rectangle (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight)
171 {
172 if (2*fRadius > fFrameHeight + fLineWidth)
173 fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
174 double fDockOffsetX = fRadius + fLineWidth/2;
175 double fDockOffsetY = fLineWidth/2;
176 cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
177 cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
178 //\_________________ Coin haut droit.
179 cairo_arc (pCairoContext,
180 fDockOffsetX + fFrameWidth, fDockOffsetY + fRadius,
181 fRadius,
182 -G_PI/2, 0.);
183 cairo_rel_line_to (pCairoContext, 0, (fFrameHeight + fLineWidth - fRadius * 2));
184 //\_________________ Coin bas droit.
185 cairo_arc (pCairoContext,
186 fDockOffsetX + fFrameWidth, fDockOffsetY + fFrameHeight - fLineWidth/2 - fRadius,
187 fRadius,
188 0., G_PI/2);
189
190 cairo_rel_line_to (pCairoContext, - fFrameWidth, 0);
191 //\_________________ Coin bas gauche.
192 cairo_arc (pCairoContext,
193 fDockOffsetX, fDockOffsetY + fFrameHeight - fLineWidth/2 - fRadius,
194 fRadius,
195 G_PI/2, G_PI);
196
197 cairo_rel_line_to (pCairoContext, 0, (- fFrameHeight - fLineWidth + fRadius * 2));
198 //\_________________ Coin haut gauche.
199 cairo_arc (pCairoContext,
200 fDockOffsetX, fDockOffsetY + fRadius,
201 fRadius,
202 G_PI, -G_PI/2);
203
204 if (fRadius < 1)
205 cairo_close_path (pCairoContext);
206 }
207
cairo_dock_draw_frame_horizontal(cairo_t * pCairoContext,double fRadius,double fLineWidth,double fFrameWidth,double fFrameHeight,double fDockOffsetX,double fDockOffsetY,int sens,double fInclination,gboolean bRoundedBottomCorner)208 static double cairo_dock_draw_frame_horizontal (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bRoundedBottomCorner) // la largeur est donnee par rapport "au fond".
209 {
210 if (2*fRadius > fFrameHeight + fLineWidth)
211 fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
212 double cosa = 1. / sqrt (1 + fInclination * fInclination);
213 double sina = cosa * fInclination;
214 double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (bRoundedBottomCorner ? 2 : 1-sina) * fRadius);
215
216 cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
217
218 cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
219 //\_________________ Coin haut droit.
220 cairo_rel_curve_to (pCairoContext,
221 0, 0,
222 fRadius * (1. / cosa - fInclination), 0,
223 fRadius * cosa, sens * fRadius * (1 - sina));
224 cairo_rel_line_to (pCairoContext, fDeltaXForLoop, sens * (fFrameHeight + fLineWidth - fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)));
225 //\_________________ Coin bas droit.
226 if (bRoundedBottomCorner)
227 cairo_rel_curve_to (pCairoContext,
228 0, 0,
229 fRadius * (1 + sina) * fInclination, sens * fRadius * (1 + sina),
230 -fRadius * cosa, sens * fRadius * (1 + sina));
231
232 cairo_rel_line_to (pCairoContext, - fFrameWidth - 2 * fDeltaXForLoop - (bRoundedBottomCorner ? 0 : 2 * fRadius * cosa), 0);
233 //\_________________ Coin bas gauche.
234 if (bRoundedBottomCorner)
235 cairo_rel_curve_to (pCairoContext,
236 0, 0,
237 -fRadius * (fInclination + 1. / cosa), 0,
238 -fRadius * cosa, -sens * fRadius * (1 + sina));
239 cairo_rel_line_to (pCairoContext, fDeltaXForLoop, sens * (- fFrameHeight - fLineWidth + fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)));
240 //\_________________ Coin haut gauche.
241 cairo_rel_curve_to (pCairoContext,
242 0, 0,
243 fRadius * (1 - sina) * fInclination, -sens * fRadius * (1 - sina),
244 fRadius * cosa, -sens * fRadius * (1 - sina));
245 if (fRadius < 1)
246 cairo_close_path (pCairoContext);
247 //return fDeltaXForLoop + fRadius * cosa;
248 return fInclination * (fFrameHeight - (FALSE ? 2 : 1-sina) * fRadius) + fRadius * (FALSE ? 1 : cosa);
249 }
cairo_dock_draw_frame_vertical(cairo_t * pCairoContext,double fRadius,double fLineWidth,double fFrameWidth,double fFrameHeight,double fDockOffsetX,double fDockOffsetY,int sens,double fInclination,gboolean bRoundedBottomCorner)250 static double cairo_dock_draw_frame_vertical (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bRoundedBottomCorner)
251 {
252 if (2*fRadius > fFrameHeight + fLineWidth)
253 fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
254 double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (bRoundedBottomCorner ? 2 : 1) * fRadius);
255 double cosa = 1. / sqrt (1 + fInclination * fInclination);
256 double sina = cosa * fInclination;
257
258 cairo_move_to (pCairoContext, fDockOffsetY, fDockOffsetX);
259
260 cairo_rel_line_to (pCairoContext, 0, fFrameWidth);
261 //\_________________ Coin haut droit.
262 cairo_rel_curve_to (pCairoContext,
263 0, 0,
264 0, fRadius * (1. / cosa - fInclination),
265 sens * fRadius * (1 - sina), fRadius * cosa);
266 cairo_rel_line_to (pCairoContext, sens * (fFrameHeight + fLineWidth - fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)), fDeltaXForLoop);
267 //\_________________ Coin bas droit.
268 if (bRoundedBottomCorner)
269 cairo_rel_curve_to (pCairoContext,
270 0, 0,
271 sens * fRadius * (1 + sina), fRadius * (1 + sina) * fInclination,
272 sens * fRadius * (1 + sina), -fRadius * cosa);
273
274 cairo_rel_line_to (pCairoContext, 0, - fFrameWidth - 2 * fDeltaXForLoop - (bRoundedBottomCorner ? 0 : 2 * fRadius * cosa));
275 //\_________________ Coin bas gauche.
276 if (bRoundedBottomCorner)
277 cairo_rel_curve_to (pCairoContext,
278 0, 0,
279 0, -fRadius * (fInclination + 1. / cosa),
280 -sens * fRadius * (1 + sina), -fRadius * cosa);
281 cairo_rel_line_to (pCairoContext, sens * (- fFrameHeight - fLineWidth + fRadius * (bRoundedBottomCorner ? 2 : 1)), fDeltaXForLoop);
282 //\_________________ Coin haut gauche.
283 cairo_rel_curve_to (pCairoContext,
284 0, 0,
285 -sens * fRadius * (1 - sina), fRadius * (1 - sina) * fInclination,
286 -sens * fRadius * (1 - sina), fRadius * cosa);
287 if (fRadius < 1)
288 cairo_close_path (pCairoContext);
289 //return fDeltaXForLoop + fRadius * cosa;
290 return fInclination * (fFrameHeight - (FALSE ? 2 : 1-sina) * fRadius) + fRadius * (FALSE ? 1 : cosa);
291 }
cairo_dock_draw_frame(cairo_t * pCairoContext,double fRadius,double fLineWidth,double fFrameWidth,double fFrameHeight,double fDockOffsetX,double fDockOffsetY,int sens,double fInclination,gboolean bHorizontal,gboolean bRoundedBottomCorner)292 double cairo_dock_draw_frame (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bHorizontal, gboolean bRoundedBottomCorner)
293 {
294 if (bHorizontal)
295 return cairo_dock_draw_frame_horizontal (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclination, bRoundedBottomCorner);
296 else
297 return cairo_dock_draw_frame_vertical (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclination, bRoundedBottomCorner);
298 }
299
cairo_dock_render_decorations_in_frame(cairo_t * pCairoContext,CairoDock * pDock,double fOffsetY,double fOffsetX,double fWidth)300 void cairo_dock_render_decorations_in_frame (cairo_t *pCairoContext, CairoDock *pDock, double fOffsetY, double fOffsetX, double fWidth)
301 {
302 //g_print ("%.2f\n", pDock->fDecorationsOffsetX);
303 if (pDock->backgroundBuffer.pSurface == NULL)
304 return ;
305 cairo_save (pCairoContext);
306
307 if (pDock->container.bIsHorizontal)
308 {
309 cairo_translate (pCairoContext, fOffsetX, fOffsetY);
310 cairo_scale (pCairoContext, (double)fWidth / pDock->backgroundBuffer.iWidth, (double)pDock->iDecorationsHeight / pDock->backgroundBuffer.iHeight); // pDock->container.iWidth
311 }
312 else
313 {
314 cairo_translate (pCairoContext, fOffsetY, fOffsetX);
315 cairo_scale (pCairoContext, (double)pDock->iDecorationsHeight / pDock->backgroundBuffer.iHeight, (double)fWidth / pDock->backgroundBuffer.iWidth);
316 }
317
318 cairo_dock_draw_surface (pCairoContext, pDock->backgroundBuffer.pSurface, pDock->backgroundBuffer.iWidth, pDock->backgroundBuffer.iHeight, pDock->container.bDirectionUp, pDock->container.bIsHorizontal, -1.); // -1 <=> fill_preserve
319
320 cairo_restore (pCairoContext);
321 }
322
323
cairo_dock_set_icon_scale_on_context(cairo_t * pCairoContext,Icon * icon,gboolean bIsHorizontal,G_GNUC_UNUSED double fRatio,gboolean bDirectionUp)324 void cairo_dock_set_icon_scale_on_context (cairo_t *pCairoContext, Icon *icon, gboolean bIsHorizontal, G_GNUC_UNUSED double fRatio, gboolean bDirectionUp)
325 {
326 if (bIsHorizontal)
327 {
328 if (myIconsParam.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
329 {
330 cairo_translate (pCairoContext,
331 icon->fWidthFactor * icon->fWidth * (icon->fScale - 1) / 2,
332 (bDirectionUp ? 1 * icon->fHeightFactor * icon->fHeight * (icon->fScale - 1) : 0));
333 cairo_scale (pCairoContext,
334 icon->fWidth / icon->image.iWidth * icon->fWidthFactor/**fRatio * icon->fWidthFactor / (1 + myIconsParam.fAmplitude)*/,
335 icon->fHeight / icon->image.iHeight * icon->fHeightFactor/**fRatio * icon->fHeightFactor / (1 + myIconsParam.fAmplitude)*/);
336 }
337 else
338 cairo_scale (pCairoContext,
339 icon->fWidth / icon->image.iWidth * icon->fWidthFactor * icon->fScale/**fRatio * icon->fWidthFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale,
340 icon->fHeight / icon->image.iHeight * icon->fHeightFactor * icon->fScale/**fRatio * icon->fHeightFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale);
341 }
342 else
343 {
344 if (myIconsParam.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
345 {
346 cairo_translate (pCairoContext,
347 icon->fHeightFactor * icon->fHeight * (icon->fScale - 1) / 2,
348 (bDirectionUp ? 1 * icon->fWidthFactor * icon->fWidth * (icon->fScale - 1) : 0));
349 cairo_scale (pCairoContext,
350 icon->fHeight / icon->image.iWidth * icon->fHeightFactor/**fRatio * icon->fHeightFactor / (1 + myIconsParam.fAmplitude)*/,
351 icon->fWidth / icon->image.iHeight * icon->fWidthFactor/**fRatio * icon->fWidthFactor / (1 + myIconsParam.fAmplitude)*/);
352 }
353 else
354 cairo_scale (pCairoContext,
355 icon->fHeight / icon->image.iWidth * icon->fHeightFactor * icon->fScale/**fRatio * icon->fHeightFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale,
356 icon->fWidth / icon->image.iHeight * icon->fWidthFactor * icon->fScale/**fRatio * icon->fWidthFactor * icon->fScale / (1 + myIconsParam.fAmplitude)*/ * icon->fGlideScale);
357
358 }
359 }
360
361
cairo_dock_draw_icon_reflect_cairo(Icon * icon,GldiContainer * pContainer,cairo_t * pCairoContext)362 void cairo_dock_draw_icon_reflect_cairo (Icon *icon, GldiContainer *pContainer, cairo_t *pCairoContext)
363 {
364 if (pContainer->bUseReflect && icon->image.pSurface != NULL)
365 {
366 cairo_save (pCairoContext);
367 double fScale = (myIconsParam.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? 1. : icon->fScale);
368
369 if (pContainer->bIsHorizontal)
370 {
371 cairo_translate (pCairoContext,
372 0,
373 (pContainer->bDirectionUp ?
374 icon->fDeltaYReflection + icon->fHeight * fScale : // go to bottom of icon
375 -icon->fDeltaYReflection - icon->fHeight * myIconsParam.fReflectHeightRatio)); // go to top of reflect
376 cairo_rectangle (pCairoContext, 0, 0, icon->fWidth * icon->fScale, icon->fHeight * myIconsParam.fReflectHeightRatio);
377 if (pContainer->bDirectionUp)
378 cairo_translate (pCairoContext, 0, icon->fHeight * icon->fHeightFactor * fScale);
379 else
380 cairo_translate (pCairoContext, 0, icon->fHeight * icon->fHeightFactor * myIconsParam.fReflectHeightRatio); // go back to top of icon, since we will flip y axis
381 }
382 else
383 {
384 cairo_translate (pCairoContext,
385 (pContainer->bDirectionUp ?
386 icon->fDeltaYReflection + icon->fHeight * fScale : // go to bottom of icon
387 -icon->fDeltaYReflection - icon->fHeight * myIconsParam.fReflectHeightRatio), // go to top of reflect
388 0);
389 cairo_rectangle (pCairoContext, 0, 0, icon->fHeight * myIconsParam.fReflectHeightRatio, icon->fWidth * icon->fScale);
390 if (pContainer->bDirectionUp)
391 cairo_translate (pCairoContext, icon->fHeight * icon->fHeightFactor * fScale, 0);
392 else
393 cairo_translate (pCairoContext, icon->fHeight * icon->fHeightFactor * myIconsParam.fReflectHeightRatio, 0); // go back to top of icon, since we will flip y axis
394 }
395 cairo_clip (pCairoContext);
396
397 cairo_dock_set_icon_scale_on_context (pCairoContext, icon, pContainer->bIsHorizontal, 1., pContainer->bDirectionUp);
398
399 if (pContainer->bIsHorizontal)
400 cairo_scale (pCairoContext, 1, -1);
401 else
402 cairo_scale (pCairoContext, -1, 1);
403
404 cairo_set_source_surface (pCairoContext, icon->image.pSurface, 0.0, 0.0);
405
406 if (myBackendsParam.bDynamicReflection) // on applique la surface avec un degrade en transparence, ou avec une transparence simple.
407 {
408 cairo_pattern_t *pGradationPattern;
409 if (pContainer->bIsHorizontal)
410 {
411 if (pContainer->bDirectionUp)
412 pGradationPattern = cairo_pattern_create_linear (
413 0,
414 icon->image.iHeight,
415 0,
416 icon->image.iHeight * (1 - myIconsParam.fReflectHeightRatio));
417 else
418 pGradationPattern = cairo_pattern_create_linear (
419 0,
420 0.,
421 0,
422 icon->image.iHeight * myIconsParam.fReflectHeightRatio);
423 g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
424
425 cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
426 cairo_pattern_add_color_stop_rgba (pGradationPattern,
427 0.,
428 0.,
429 0.,
430 0.,
431 icon->fAlpha * myIconsParam.fAlbedo);
432 cairo_pattern_add_color_stop_rgba (pGradationPattern,
433 1.,
434 0.,
435 0.,
436 0.,
437 0.);
438 }
439 else
440 {
441 if (pContainer->bDirectionUp)
442 pGradationPattern = cairo_pattern_create_linear (
443 icon->image.iWidth,
444 0.,
445 icon->image.iWidth * (1-myIconsParam.fReflectHeightRatio),
446 0);
447 else
448 pGradationPattern = cairo_pattern_create_linear (
449 0,
450 0.,
451 icon->image.iWidth * myIconsParam.fReflectHeightRatio,
452 0);
453 g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
454
455 cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
456 cairo_pattern_add_color_stop_rgba (pGradationPattern,
457 0.,
458 0.,
459 0.,
460 0.,
461 icon->fAlpha * myIconsParam.fAlbedo);
462 cairo_pattern_add_color_stop_rgba (pGradationPattern,
463 1.,
464 0.,
465 0.,
466 0.,
467 0.);
468 }
469 cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
470 cairo_mask (pCairoContext, pGradationPattern);
471
472 cairo_pattern_destroy (pGradationPattern);
473 }
474 else
475 {
476 cairo_paint_with_alpha (pCairoContext, icon->fAlpha * myIconsParam.fAlbedo);
477 }
478 cairo_restore (pCairoContext);
479 }
480 }
481
cairo_dock_draw_icon_cairo(Icon * icon,CairoDock * pDock,cairo_t * pCairoContext)482 void cairo_dock_draw_icon_cairo (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext)
483 {
484 //\_____________________ On dessine l'icone.
485 if (icon->image.pSurface != NULL)
486 {
487 cairo_save (pCairoContext);
488
489 cairo_dock_set_icon_scale_on_context (pCairoContext, icon, pDock->container.bIsHorizontal, 1., pDock->container.bDirectionUp);
490 cairo_set_source_surface (pCairoContext, icon->image.pSurface, 0.0, 0.0);
491 if (icon->fAlpha == 1)
492 cairo_paint (pCairoContext);
493 else
494 cairo_paint_with_alpha (pCairoContext, icon->fAlpha);
495
496 cairo_restore (pCairoContext);
497 }
498 //\_____________________ On dessine son reflet.
499 cairo_dock_draw_icon_reflect_cairo (icon, CAIRO_CONTAINER (pDock), pCairoContext);
500 }
501
cairo_dock_render_icon_notification(G_GNUC_UNUSED gpointer pUserData,Icon * icon,CairoDock * pDock,gboolean * bHasBeenRendered,cairo_t * pCairoContext)502 gboolean cairo_dock_render_icon_notification (G_GNUC_UNUSED gpointer pUserData, Icon *icon, CairoDock *pDock, gboolean *bHasBeenRendered, cairo_t *pCairoContext)
503 {
504 if (*bHasBeenRendered)
505 return GLDI_NOTIFICATION_LET_PASS;
506 if (pCairoContext != NULL)
507 {
508 if (icon->image.pSurface != NULL)
509 {
510 cairo_dock_draw_icon_cairo (icon, pDock, pCairoContext);
511 }
512 }
513 else
514 {
515 if (icon->image.iTexture != 0)
516 {
517 cairo_dock_draw_icon_opengl (icon, pDock);
518 }
519 }
520
521 *bHasBeenRendered = TRUE;
522 return GLDI_NOTIFICATION_LET_PASS;
523 }
524
cairo_dock_render_one_icon(Icon * icon,CairoDock * pDock,cairo_t * pCairoContext,double fDockMagnitude,gboolean bUseText)525 void cairo_dock_render_one_icon (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext, double fDockMagnitude, gboolean bUseText)
526 {
527 int iWidth = pDock->container.iWidth;
528 double fRatio = pDock->container.fRatio;
529 gboolean bDirectionUp = pDock->container.bDirectionUp;
530 gboolean bIsHorizontal = pDock->container.bIsHorizontal;
531
532 if (CAIRO_DOCK_IS_APPLI (icon) && myTaskbarParam.fVisibleAppliAlpha != 0 && ! CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon) && !(myTaskbarParam.iMinimizedWindowRenderType == 1 && icon->pAppli->bIsHidden))
533 {
534 double fAlpha = (icon->pAppli->bIsHidden ? MIN (1 - myTaskbarParam.fVisibleAppliAlpha, 1) : MIN (myTaskbarParam.fVisibleAppliAlpha + 1, 1));
535 if (fAlpha != 1)
536 icon->fAlpha = fAlpha; // astuce bidon pour pas multiplier 2 fois.
537 /**if (icon->bIsHidden)
538 icon->fAlpha *= MIN (1 - myTaskbarParam.fVisibleAppliAlpha, 1);
539 else
540 icon->fAlpha *= MIN (myTaskbarParam.fVisibleAppliAlpha + 1, 1);*/
541 //g_print ("fVisibleAppliAlpha : %.2f & %d => %.2f\n", myTaskbarParam.fVisibleAppliAlpha, icon->bIsHidden, icon->fAlpha);
542 }
543
544 //\_____________________ On se place sur l'icone.
545 double fGlideScale;
546 if (icon->fGlideOffset != 0 && (! myIconsParam.bConstantSeparatorSize || ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon)))
547 {
548 double fPhase = icon->fPhase + icon->fGlideOffset * icon->fWidth / fRatio / myIconsParam.iSinusoidWidth * G_PI;
549 if (fPhase < 0)
550 {
551 fPhase = 0;
552 }
553 else if (fPhase > G_PI)
554 {
555 fPhase = G_PI;
556 }
557 fGlideScale = (1 + fDockMagnitude * pDock->fMagnitudeMax * myIconsParam.fAmplitude * sin (fPhase)) / icon->fScale; // c'est un peu hacky ... il faudrait passer l'icone precedente en parametre ...
558 if (bDirectionUp)
559 {
560 if (bIsHorizontal)
561 cairo_translate (pCairoContext, 0., (1-fGlideScale)*icon->fHeight*icon->fScale);
562 else
563 cairo_translate (pCairoContext, (1-fGlideScale)*icon->fHeight*icon->fScale, 0.);
564 }
565 }
566 else
567 fGlideScale = 1;
568 icon->fGlideScale = fGlideScale;
569
570 if (bIsHorizontal)
571 cairo_translate (pCairoContext, icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1), icon->fDrawY);
572 else
573 cairo_translate (pCairoContext, icon->fDrawY, icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1));
574
575 cairo_save (pCairoContext);
576
577 //\_____________________ On positionne l'icone.
578 if (icon->fOrientation != 0)
579 cairo_rotate (pCairoContext, icon->fOrientation);
580
581 //\_____________________ On dessine l'icone.
582 gboolean bIconHasBeenDrawn = FALSE;
583 gldi_object_notify (&myIconObjectMgr, NOTIFICATION_PRE_RENDER_ICON, icon, pDock, pCairoContext);
584 gldi_object_notify (&myIconObjectMgr, NOTIFICATION_RENDER_ICON, icon, pDock, &bIconHasBeenDrawn, pCairoContext);
585
586 cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
587
588 //\_____________________ On dessine les etiquettes, avec un alpha proportionnel au facteur d'echelle de leur icone.
589 if (bUseText && icon->label.pSurface != NULL && icon->iHideLabel == 0
590 && (icon->bPointed || (icon->fScale > 1.01 && ! myIconsParam.bLabelForPointedIconOnly))) // 1.01 car sin(pi) = 1+epsilon :-/ // && icon->iAnimationState < CAIRO_DOCK_STATE_CLICKED
591 {
592 cairo_save (pCairoContext);
593
594 double fMagnitude;
595 if (myIconsParam.bLabelForPointedIconOnly || pDock->fMagnitudeMax == 0. || myIconsParam.fAmplitude == 0.)
596 {
597 fMagnitude = fDockMagnitude; // (icon->fScale - 1) / myIconsParam.fAmplitude / sin (icon->fPhase); // sin (phi ) != 0 puisque fScale > 1.
598 }
599 else
600 {
601 fMagnitude = (icon->fScale - 1) / myIconsParam.fAmplitude; /// il faudrait diviser par pDock->fMagnitudeMax ...
602 fMagnitude = pow (fMagnitude, myIconsParam.fLabelAlphaThreshold);
603 ///fMagnitude *= (fMagnitude * myIconsParam.fLabelAlphaThreshold + 1) / (myIconsParam.fLabelAlphaThreshold + 1);
604 }
605
606 int iLabelSize = icon->label.iHeight;
607 ///int iLabelSize = myIconsParam.iLabelSize;
608 int gap = (myDocksParam.iDockLineWidth + myDocksParam.iFrameMargin) * (1 - pDock->fMagnitudeMax) + 1; // gap between icon and label: let 1px between the icon or the dock's outline
609 //g_print ("%d / %d\n", icon->label.iHeight, myIconsParam.iLabelSize),
610 cairo_identity_matrix (pCairoContext); // on positionne les etiquettes sur un pixels entier, sinon ca floute.
611 if (bIsHorizontal)
612 cairo_translate (pCairoContext, floor (icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1)), floor (icon->fDrawY));
613 else
614 cairo_translate (pCairoContext, floor (icon->fDrawY), floor (icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1)));
615
616 double fOffsetX = (icon->fWidth * icon->fScale - icon->label.iWidth) / 2;
617 if (fOffsetX < - icon->fDrawX) // l'etiquette deborde a gauche.
618 fOffsetX = - icon->fDrawX;
619 else if (icon->fDrawX + fOffsetX + icon->label.iWidth > iWidth) // l'etiquette deborde a droite.
620 fOffsetX = iWidth - icon->label.iWidth - icon->fDrawX;
621
622 if (bIsHorizontal)
623 {
624 cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
625 floor (fOffsetX), floor (bDirectionUp ? - iLabelSize - gap : icon->fHeight * icon->fScale + gap), fMagnitude);
626 }
627 else // horizontal label on a vertical dock -> draw them next to the icon, vertically centered (like the Parabolic view)
628 {
629 if (icon->pSubDock && gldi_container_is_visible (CAIRO_CONTAINER (icon->pSubDock))) // in vertical mode
630 {
631 fMagnitude /= 3;
632 }
633 const int pad = 0;
634 double fY = icon->fDrawY;
635 int iMaxWidth = (pDock->container.bDirectionUp ?
636 fY - gap - pad :
637 pDock->container.iHeight - (fY + icon->fHeight * icon->fScale + gap + pad));
638 int iOffsetX = floor (bDirectionUp ?
639 MAX (- iMaxWidth, - gap - pad - icon->label.iWidth):
640 icon->fHeight * icon->fScale + gap + pad);
641 int iOffsetY = floor (icon->fWidth * icon->fScale/2 - icon->label.iHeight/2);
642 if (icon->label.iWidth < iMaxWidth)
643 {
644 cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
645 iOffsetX,
646 iOffsetY,
647 fMagnitude);
648 }
649 else
650 {
651 cairo_dock_apply_image_buffer_surface_with_offset_and_limit (&icon->label, pCairoContext, iOffsetX, iOffsetY, fMagnitude, iMaxWidth);
652 }
653 }
654
655 cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
656 }
657
658 //\_____________________ Draw the overlays on top of that.
659 cairo_dock_draw_icon_overlays_cairo (icon, fRatio, pCairoContext);
660 }
661
662
cairo_dock_render_one_icon_in_desklet(Icon * icon,GldiContainer * pContainer,cairo_t * pCairoContext,gboolean bUseText)663 void cairo_dock_render_one_icon_in_desklet (Icon *icon, GldiContainer *pContainer, cairo_t *pCairoContext, gboolean bUseText)
664 {
665 //\_____________________ On dessine l'icone en fonction de son placement, son angle, et sa transparence.
666 //g_print ("%s (%.2f;%.2f x %.2f)\n", __func__, icon->fDrawX, icon->fDrawY, icon->fScale);
667 if (icon->image.pSurface != NULL)
668 {
669 cairo_save (pCairoContext);
670
671 cairo_translate (pCairoContext, icon->fDrawX, icon->fDrawY);
672 cairo_scale (pCairoContext, icon->fWidthFactor * icon->fScale, icon->fHeightFactor * icon->fScale);
673 if (icon->fOrientation != 0)
674 cairo_rotate (pCairoContext, icon->fOrientation);
675
676 cairo_dock_apply_image_buffer_surface_with_offset (&icon->image, pCairoContext, 0, 0, icon->fAlpha);
677
678 cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
679
680 if (pContainer->bUseReflect)
681 {
682 cairo_dock_draw_icon_reflect_cairo (icon, pContainer, pCairoContext);
683 }
684 }
685
686 //\_____________________ On dessine les etiquettes.
687 if (bUseText && icon->label.pSurface != NULL)
688 {
689 cairo_save (pCairoContext);
690 double fOffsetX = (icon->fWidthFactor * icon->fWidth * icon->fScale - icon->label.iWidth) / 2;
691 if (fOffsetX < - icon->fDrawX)
692 fOffsetX = - icon->fDrawX;
693 else if (icon->fDrawX + fOffsetX + icon->label.iWidth > pContainer->iWidth)
694 fOffsetX = pContainer->iWidth - icon->label.iWidth - icon->fDrawX;
695 if (icon->fOrientation != 0)
696 {
697 cairo_rotate (pCairoContext, icon->fOrientation);
698 }
699 cairo_dock_apply_image_buffer_surface_with_offset (&icon->label, pCairoContext,
700 fOffsetX, -icon->label.iHeight, 1.);
701 cairo_restore (pCairoContext); // retour juste apres la translation (fDrawX, fDrawY).
702 }
703
704 //\_____________________ Draw the overlays on top of that.
705 cairo_dock_draw_icon_overlays_cairo (icon, pContainer->fRatio, pCairoContext);
706 }
707
708
709
cairo_dock_draw_string(cairo_t * pCairoContext,CairoDock * pDock,double fStringLineWidth,gboolean bIsLoop,gboolean bForceConstantSeparator)710 void cairo_dock_draw_string (cairo_t *pCairoContext, CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator)
711 {
712 bForceConstantSeparator = bForceConstantSeparator || myIconsParam.bConstantSeparatorSize;
713 GList *ic, *pFirstDrawnElement = pDock->icons;
714 if (pFirstDrawnElement == NULL || fStringLineWidth <= 0)
715 return ;
716
717 cairo_save (pCairoContext);
718 cairo_set_tolerance (pCairoContext, 0.5);
719 Icon *prev_icon = NULL, *next_icon, *icon;
720 double x, y, fCurvature = 0.3;
721 if (bIsLoop)
722 {
723 ic = cairo_dock_get_previous_element (pFirstDrawnElement, pDock->icons);
724 prev_icon = ic->data;
725 }
726 ic = pFirstDrawnElement;
727 icon = ic->data;
728 GList *next_ic;
729 double x1, x2, x3;
730 double y1, y2, y3;
731 double dx, dy;
732 x = icon->fDrawX + icon->fWidth * icon->fScale * icon->fWidthFactor / 2;
733 y = icon->fDrawY + icon->fHeight * icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - 1) / 2 : 0);
734 if (pDock->container.bIsHorizontal)
735 cairo_move_to (pCairoContext, x, y);
736 else
737 cairo_move_to (pCairoContext, y, x);
738 do
739 {
740 if (prev_icon != NULL)
741 {
742 x1 = prev_icon->fDrawX + prev_icon->fWidth * prev_icon->fScale * prev_icon->fWidthFactor / 2;
743 y1 = prev_icon->fDrawY + prev_icon->fHeight * prev_icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (prev_icon) ? prev_icon->fHeight * (prev_icon->fScale - 1) / 2 : 0);
744 }
745 else
746 {
747 x1 = x;
748 y1 = y;
749 }
750 prev_icon = icon;
751
752 ic = cairo_dock_get_next_element (ic, pDock->icons);
753 if (ic == pFirstDrawnElement && ! bIsLoop)
754 break;
755 icon = ic->data;
756 x2 = icon->fDrawX + icon->fWidth * icon->fScale * icon->fWidthFactor / 2;
757 y2 = icon->fDrawY + icon->fHeight * icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - 1) / 2 : 0);
758
759 dx = x2 - x;
760 dy = y2 - y;
761
762 next_ic = cairo_dock_get_next_element (ic, pDock->icons);
763 next_icon = (next_ic == pFirstDrawnElement && ! bIsLoop ? NULL : next_ic->data);
764 if (next_icon != NULL)
765 {
766 x3 = next_icon->fDrawX + next_icon->fWidth * next_icon->fScale * next_icon->fWidthFactor / 2;
767 y3 = next_icon->fDrawY + next_icon->fHeight * next_icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (next_icon) ? next_icon->fHeight * (next_icon->fScale - 1) / 2 : 0);
768 }
769 else
770 {
771 x3 = x2;
772 y3 = y2;
773 }
774
775 if (pDock->container.bIsHorizontal)
776 cairo_rel_curve_to (pCairoContext,
777 (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature : 0),
778 (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature * (y - y1) / (x - x1) : 0),
779 (fabs ((x3 - x2) / (y3 - y2)) > .35 ? dx * (1 - fCurvature) : dx),
780 (fabs ((x3 - x2) / (y3 - y2)) > .35 ? MAX (0, MIN (dy, dy - dx * fCurvature * (y3 - y2) / (x3 - x2))) : dy),
781 dx,
782 dy);
783 else
784 cairo_rel_curve_to (pCairoContext,
785 (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature * (y - y1) / (x - x1) : 0),
786 (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature : 0),
787 (fabs ((x3 - x2) / (y3 - y2)) > .35 ? MAX (0, MIN (dy, dy - dx * fCurvature * (y3 - y2) / (x3 - x2))) : dy),
788 (fabs ((x3 - x2) / (y3 - y2)) > .35 ? dx * (1 - fCurvature) : dx),
789 dy,
790 dx);
791 x = x2;
792 y = y2;
793 }
794 while (ic != pFirstDrawnElement);
795
796 cairo_set_line_width (pCairoContext, myIconsParam.iStringLineWidth);
797 cairo_set_source_rgba (pCairoContext, myIconsParam.fStringColor[0], myIconsParam.fStringColor[1], myIconsParam.fStringColor[2], myIconsParam.fStringColor[3]);
798 cairo_stroke (pCairoContext);
799 cairo_restore (pCairoContext);
800 }
801
cairo_dock_render_icons_linear(cairo_t * pCairoContext,CairoDock * pDock)802 void cairo_dock_render_icons_linear (cairo_t *pCairoContext, CairoDock *pDock)
803 {
804 GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
805 if (pFirstDrawnElement == NULL)
806 return;
807
808 double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex); // * pDock->fMagnitudeMax
809 Icon *icon;
810 GList *ic = pFirstDrawnElement;
811 do
812 {
813 icon = ic->data;
814
815 cairo_save (pCairoContext);
816 cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
817 cairo_restore (pCairoContext);
818
819 ic = cairo_dock_get_next_element (ic, pDock->icons);
820 } while (ic != pFirstDrawnElement);
821 }
822
823
824
cairo_dock_draw_surface(cairo_t * pCairoContext,cairo_surface_t * pSurface,int iWidth,int iHeight,gboolean bDirectionUp,gboolean bHorizontal,gdouble fAlpha)825 void cairo_dock_draw_surface (cairo_t *pCairoContext, cairo_surface_t *pSurface, int iWidth, int iHeight, gboolean bDirectionUp, gboolean bHorizontal, gdouble fAlpha)
826 {
827 if (bDirectionUp)
828 {
829 if (bHorizontal)
830 {
831 cairo_set_source_surface (pCairoContext, pSurface, 0., 0.);
832 }
833 else
834 {
835 cairo_rotate (pCairoContext, - G_PI/2);
836 cairo_set_source_surface (pCairoContext, pSurface, - iWidth, 0.);
837 }
838 }
839 else
840 {
841 if (bHorizontal)
842 {
843 cairo_scale (pCairoContext, 1., -1.);
844 cairo_set_source_surface (pCairoContext, pSurface, 0., - iHeight);
845 }
846 else
847 {
848 cairo_rotate (pCairoContext, G_PI/2);
849 cairo_set_source_surface (pCairoContext, pSurface, 0., - iHeight);
850 }
851 }
852 if (fAlpha == -1)
853 cairo_fill_preserve (pCairoContext);
854 else if (fAlpha != 1)
855 cairo_paint_with_alpha (pCairoContext, fAlpha);
856 else
857 cairo_paint (pCairoContext);
858 }
859
860
861
cairo_dock_render_hidden_dock(cairo_t * pCairoContext,CairoDock * pDock)862 void cairo_dock_render_hidden_dock (cairo_t *pCairoContext, CairoDock *pDock)
863 {
864 //\_____________________ on dessine la zone de rappel.
865 if (g_pVisibleZoneBuffer.pSurface != NULL)
866 {
867 cairo_save (pCairoContext);
868 int w = MIN (myDocksParam.iZoneWidth, pDock->container.iWidth);
869 int h = MIN (myDocksParam.iZoneHeight, pDock->container.iHeight);
870
871 if (pDock->container.bIsHorizontal)
872 {
873 if (pDock->container.bDirectionUp)
874 cairo_translate (pCairoContext, (pDock->container.iWidth - w)/2, pDock->container.iHeight - h);
875 else
876 cairo_translate (pCairoContext, (pDock->container.iWidth - w)/2, 0.);
877 }
878 else
879 {
880 if (pDock->container.bDirectionUp)
881 cairo_translate (pCairoContext, pDock->container.iHeight - h, (pDock->container.iWidth - w)/2);
882 else
883 cairo_translate (pCairoContext, 0., (pDock->container.iWidth - w)/2);
884 }
885 cairo_dock_draw_surface (pCairoContext, g_pVisibleZoneBuffer.pSurface,
886 w,
887 h,
888 pDock->container.bDirectionUp, // reverse image with dock.
889 pDock->container.bIsHorizontal,
890 1.);
891 cairo_restore (pCairoContext);
892 }
893
894 //\_____________________ on dessine les icones demandant l'attention.
895 GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
896 if (pFirstDrawnElement == NULL)
897 return;
898 double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
899
900 double y;
901 Icon *icon;
902 GList *ic = pFirstDrawnElement;
903 GldiColor *pHiddenBgColor;
904 const double r = (myDocksParam.bUseDefaultColors ? myStyleParam.iCornerRadius/2 : 4); // corner radius of the background
905 const double gap = 2; // gap to the screen
906 double alpha;
907 double dw = (myIconsParam.iIconGap > 2 ? 2 : 0); // 1px margin around the icons for a better readability (only if icons won't be stuck togather then).
908 double w, h;
909 do
910 {
911 icon = ic->data;
912 if (icon->bIsDemandingAttention || icon->bAlwaysVisible)
913 {
914 y = icon->fDrawY;
915 icon->fDrawY = (pDock->container.bDirectionUp ? pDock->container.iHeight - icon->fHeight * icon->fScale - gap: gap);
916
917 if (icon->bHasHiddenBg)
918 {
919 pHiddenBgColor = NULL;
920 if (icon->pHiddenBgColor) // custom bg color
921 pHiddenBgColor = icon->pHiddenBgColor;
922 else if (! myDocksParam.bUseDefaultColors) // default bg color
923 pHiddenBgColor = &myDocksParam.fHiddenBg;
924 //if (pHiddenBgColor && pHiddenBgColor[3] != 0)
925 {
926 cairo_save (pCairoContext);
927 if (pHiddenBgColor)
928 {
929 gldi_color_set_cairo (pCairoContext, pHiddenBgColor);
930 alpha = pHiddenBgColor->rgba.alpha;
931 }
932 else
933 {
934 gldi_style_colors_set_bg_color (pCairoContext);
935 alpha = .7;
936 }
937 w = icon->fWidth * icon->fScale;
938 h = icon->fHeight * icon->fScale;
939 if (pDock->container.bIsHorizontal)
940 {
941 cairo_translate (pCairoContext, icon->fDrawX - dw / 2, icon->fDrawY);
942 cairo_dock_draw_rounded_rectangle (pCairoContext, r, 0, w - 2*r + dw, h);
943 }
944 else
945 {
946 cairo_translate (pCairoContext, icon->fDrawY - dw / 2, icon->fDrawX);
947 cairo_dock_draw_rounded_rectangle (pCairoContext, r, 0, h - 2*r + dw, w);
948 }
949 ///cairo_fill (pCairoContext);
950 cairo_clip (pCairoContext);
951 cairo_paint_with_alpha (pCairoContext, alpha * pDock->fPostHideOffset);
952 cairo_restore (pCairoContext);
953 }
954 }
955
956 cairo_save (pCairoContext);
957 icon->fAlpha = pDock->fPostHideOffset;
958 cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
959 cairo_restore (pCairoContext);
960 icon->fDrawY = y;
961 }
962 ic = cairo_dock_get_next_element (ic, pDock->icons);
963 } while (ic != pFirstDrawnElement);
964 }
965