2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
29
#include "rendering-panel.h"
31
extern gdouble my_fPanelRadius;
32
extern gdouble my_fPanelInclination;
33
extern gdouble my_fPanelRatio;
34
const int iNbCurveSteps = 10;
36
static void cd_compute_size (CairoDock *pDock)
38
//\_____________ On calcule le nombre de groupes et la place qu'ils occupent.
39
int iNbGroups = 1, iCurrentOrder = -1;
40
double fCurrentGroupWidth = - myIcons.iIconGap, fGroupsWidth = 0.;
43
for (ic = pDock->icons; ic != NULL; ic = ic->next)
46
if (CAIRO_DOCK_IS_SEPARATOR (pIcon))
48
if (CAIRO_DOCK_IS_USER_SEPARATOR (pIcon)) // si c'est un separateur automatique, le changement de groupe incrementera le compteur a l'icone suivante.
50
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
53
fGroupsWidth += MAX (0, fCurrentGroupWidth);
54
//g_print ("fGroupsWidth += %.2f\n", fCurrentGroupWidth);
55
fCurrentGroupWidth = - myIcons.iIconGap;
60
if (iCurrentOrder != (int)cairo_dock_get_icon_order (pIcon))
62
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
65
fGroupsWidth += MAX (0, fCurrentGroupWidth);
66
//g_print ("fGroupsWidth += %.2f\n", fCurrentGroupWidth);
67
fCurrentGroupWidth = - myIcons.iIconGap;
70
iCurrentOrder = cairo_dock_get_icon_order (pIcon);
71
fCurrentGroupWidth += pIcon->fWidth * my_fPanelRatio + myIcons.iIconGap;
72
//g_print ("fCurrentGroupWidth <- %.2f\n", fCurrentGroupWidth);
74
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste un separateur a la fin.
76
fGroupsWidth += MAX (0, fCurrentGroupWidth);
77
//g_print ("fGroupsWidth += %.2f\n", fCurrentGroupWidth);
82
//\_____________ On en deduit l'ecart entre les groupes d'icones.
83
double W = cairo_dock_get_max_authorized_dock_width (pDock);
84
double fScreenBorderGap = myBackground.iDockRadius + myBackground.iDockLineWidth; // on laisse un ecart avec le bord de l'ecran.
85
double fGroupGap = (iNbGroups > 1 ? (W - 2*fScreenBorderGap - fGroupsWidth) / (iNbGroups - 1) : W - fScreenBorderGap - fGroupsWidth);
86
if (fGroupGap < myIcons.iIconGap) // les icones depassent en largeur.
87
fGroupGap = myIcons.iIconGap;
88
//g_print (" -> %d groups, %d/%d\nfGroupGap = %.2f\n", iNbGroups, (int)fGroupsWidth, (int)W, fGroupGap);
90
//\_____________ On calcule la position au repos des icones et la taille du dock.
91
double xg = fScreenBorderGap; // abscisse de l'icone courante, et abscisse du debut du groupe courant.
93
fCurrentGroupWidth = - myIcons.iIconGap;
95
for (ic = pDock->icons; ic != NULL; ic = ic->next)
98
if (CAIRO_DOCK_IS_SEPARATOR (pIcon))
100
if (CAIRO_DOCK_IS_USER_SEPARATOR (pIcon)) // si c'est un separateur automatique, le changement de groupe incrementera le compteur a l'icone suivante.
102
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
104
xg += fCurrentGroupWidth + fGroupGap;
106
//g_print ("jump to %.2f\n", x);
107
fCurrentGroupWidth = - myIcons.iIconGap;
112
if (iCurrentOrder != (int)cairo_dock_get_icon_order (pIcon))
114
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
116
xg += fCurrentGroupWidth + fGroupGap;
118
//g_print ("jump to %.2f\n", x);
119
fCurrentGroupWidth = - myIcons.iIconGap;
122
iCurrentOrder = cairo_dock_get_icon_order (pIcon);
123
fCurrentGroupWidth += pIcon->fWidth * my_fPanelRatio + myIcons.iIconGap;
125
//g_print ("icon at %.2f\n", x);
127
x += pIcon->fWidth * my_fPanelRatio + myIcons.iIconGap;
130
pDock->fMagnitudeMax = 0.; // pas de vague.
132
pDock->pFirstDrawnElement = pDock->icons;
134
double hicon = pDock->iMaxIconHeight * my_fPanelRatio;
135
pDock->iDecorationsHeight = hicon * pDock->container.fRatio + 2 * myBackground.iFrameMargin;
137
pDock->iMaxDockWidth = pDock->fFlatDockWidth = pDock->iMinDockWidth = MAX (W, x);
138
//g_print ("iMaxDockWidth : %d (%.2f)\n", pDock->iMaxDockWidth, pDock->container.fRatio);
140
pDock->iMaxDockHeight = myBackground.iDockLineWidth + myBackground.iFrameMargin + hicon * pDock->container.fRatio + myBackground.iFrameMargin + myBackground.iDockLineWidth + myLabels.iLabelSize;
142
pDock->iMaxDockHeight = MAX (pDock->iMaxDockHeight, hicon * (1 + myIcons.fAmplitude)); // au moins la taille du FBO.
144
pDock->iDecorationsWidth = pDock->iMaxDockWidth;
145
pDock->iMinDockHeight = 2 * (myBackground.iDockLineWidth + myBackground.iFrameMargin) + hicon * pDock->container.fRatio;
149
static void cd_render (cairo_t *pCairoContext, CairoDock *pDock)
151
//\____________________ On trace le cadre.
152
double fLineWidth = myBackground.iDockLineWidth;
153
double fMargin = myBackground.iFrameMargin;
154
double fRadius = (pDock->iDecorationsHeight + fLineWidth - 2 * myBackground.iDockRadius > 0 ? myBackground.iDockRadius : (pDock->iDecorationsHeight + fLineWidth) / 2 - 1);
155
double fExtraWidth = 2 * fRadius + fLineWidth;
158
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
159
if (cairo_dock_is_extended_dock (pDock)) // mode panel etendu.
161
fDockWidth = pDock->container.iWidth - fExtraWidth;
162
fDockOffsetX = fExtraWidth / 2;
166
fDockWidth = cairo_dock_get_current_dock_width_linear (pDock);
167
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
168
fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - fMargin : fExtraWidth / 2);
169
if (fDockOffsetX < fExtraWidth / 2)
170
fDockOffsetX = fExtraWidth / 2;
171
if (fDockOffsetX + fDockWidth + fExtraWidth / 2 > pDock->container.iWidth)
172
fDockWidth = pDock->container.iWidth - fDockOffsetX - fExtraWidth / 2;
174
if (pDock->container.bDirectionUp)
177
fDockOffsetY = pDock->container.iHeight - pDock->iDecorationsHeight - 1.5 * fLineWidth;
182
fDockOffsetY = pDock->iDecorationsHeight + 1.5 * fLineWidth;
185
cairo_save (pCairoContext);
186
double fDeltaXTrapeze = cairo_dock_draw_frame (pCairoContext, fRadius, fLineWidth, fDockWidth, pDock->iDecorationsHeight, fDockOffsetX, fDockOffsetY, sens, 0., pDock->container.bIsHorizontal, myBackground.bRoundedBottomCorner);
188
//\____________________ On dessine les decorations dedans.
189
fDockOffsetY = (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
190
cairo_dock_render_decorations_in_frame (pCairoContext, pDock, fDockOffsetY, fDockOffsetX - fDeltaXTrapeze, fDockWidth + 2*fDeltaXTrapeze);
192
//\____________________ On dessine le cadre.
195
cairo_set_line_width (pCairoContext, fLineWidth);
196
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
197
cairo_stroke (pCairoContext);
200
cairo_new_path (pCairoContext);
201
cairo_restore (pCairoContext);
203
//\____________________ On dessine les separateurs physiques.
204
cairo_save (pCairoContext);
205
if (pDock->container.bIsHorizontal)
207
if (! pDock->container.bDirectionUp)
209
cairo_translate (pCairoContext, 0., pDock->container.iHeight);
210
cairo_scale (pCairoContext, 1., -1.);
215
cairo_translate (pCairoContext, pDock->container.iHeight/2., pDock->container.iWidth/2.);
216
cairo_rotate (pCairoContext, G_PI/2);
217
if (pDock->container.bDirectionUp)
218
cairo_scale (pCairoContext, 1., -1.);
219
cairo_translate (pCairoContext, -pDock->container.iWidth/2., -pDock->container.iHeight/2.);
222
double x1, x2, dx, delta, h = pDock->iDecorationsHeight + 2*fLineWidth, h_ = h - fLineWidth;
225
for (ic = pDock->icons; ic != NULL; ic = ic->next)
228
if (CAIRO_DOCK_IS_SEPARATOR (pIcon))
230
x1 = pIcon->fDrawX = pIcon->fX;
233
for (ic = ic->next; ic != NULL; ic = ic->next)
236
if (!CAIRO_DOCK_IS_SEPARATOR (pIcon))
247
dx = MIN (my_fPanelRadius, (x2 - x1) / 2);
248
delta = dx + h*tan(my_fPanelInclination)/2;
249
if (delta > (x2 - x1) / 2)
250
delta = (x2 - x1) / 2;
252
cairo_move_to (pCairoContext, x1, pDock->iMaxDockHeight - h);
253
cairo_rel_curve_to (pCairoContext,
257
cairo_rel_line_to (pCairoContext,
258
x2 - x1 - 2*delta, 0.);
259
cairo_rel_curve_to (pCairoContext,
263
cairo_close_path (pCairoContext);
265
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_DEST_OUT);
266
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 1.0);
267
cairo_fill (pCairoContext);
271
cairo_move_to (pCairoContext, x1, pDock->iMaxDockHeight - h_ - fLineWidth/2);
272
cairo_rel_curve_to (pCairoContext,
276
cairo_rel_line_to (pCairoContext,
277
x2 - x1 - 2*delta, 0.);
278
cairo_rel_curve_to (pCairoContext,
283
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
284
cairo_set_line_width (pCairoContext, fLineWidth);
285
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
286
cairo_stroke (pCairoContext);
290
cairo_restore (pCairoContext);
292
//\____________________ On dessine la ficelle qui les joint.
293
if (myIcons.iStringLineWidth > 0)
294
cairo_dock_draw_string (pCairoContext, pDock, myIcons.iStringLineWidth, FALSE, FALSE);
296
//\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan.
297
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
298
if (pFirstDrawnElement == NULL)
301
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex); // * pDock->fMagnitudeMax
302
ic = pFirstDrawnElement;
307
if (! CAIRO_DOCK_IS_SEPARATOR (pIcon))
309
cairo_save (pCairoContext);
310
cairo_dock_render_one_icon (pIcon, pDock, pCairoContext, fDockMagnitude, pIcon->bPointed);
311
cairo_restore (pCairoContext);
313
ic = cairo_dock_get_next_element (ic, pDock->icons);
314
} while (ic != pFirstDrawnElement);
319
static void cd_render_optimized (cairo_t *pCairoContext, CairoDock *pDock, GdkRectangle *pArea)
321
//g_print ("%s ((%d;%d) x (%d;%d) / (%dx%d))\n", __func__, pArea->x, pArea->y, pArea->width, pArea->height, pDock->container.iWidth, pDock->container.iHeight);
322
double fLineWidth = myBackground.iDockLineWidth;
323
double fMargin = myBackground.iFrameMargin;
324
int iWidth = pDock->container.iWidth;
325
int iHeight = pDock->container.iHeight;
327
//\____________________ On dessine les decorations du fond sur la portion de fenetre.
328
cairo_save (pCairoContext);
330
double fDockOffsetX, fDockOffsetY;
331
if (pDock->container.bIsHorizontal)
333
fDockOffsetX = pArea->x;
334
fDockOffsetY = (pDock->container.bDirectionUp ? iHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
338
fDockOffsetX = (pDock->container.bDirectionUp ? iHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
339
fDockOffsetY = pArea->y;
342
if (pDock->container.bIsHorizontal)
343
cairo_rectangle (pCairoContext, fDockOffsetX, fDockOffsetY, pArea->width, pDock->iDecorationsHeight);
345
cairo_rectangle (pCairoContext, fDockOffsetX, fDockOffsetY, pDock->iDecorationsHeight, pArea->height);
347
fDockOffsetY = (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
349
double fRadius = MIN (myBackground.iDockRadius, (pDock->iDecorationsHeight + myBackground.iDockLineWidth) / 2 - 1);
351
if (cairo_dock_is_extended_dock (pDock)) // mode panel etendu.
353
fOffsetX = fRadius + fLineWidth / 2;
357
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
358
fOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - fMargin : fRadius + fLineWidth / 2);
360
double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock);
361
double fDeltaXTrapeze = fRadius;
362
cairo_dock_render_decorations_in_frame (pCairoContext, pDock, fDockOffsetY, fOffsetX - fDeltaXTrapeze, fDockWidth + 2*fDeltaXTrapeze);
364
//\____________________ On dessine la partie du cadre qui va bien.
365
cairo_new_path (pCairoContext);
367
if (pDock->container.bIsHorizontal)
369
cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY - fLineWidth / 2);
370
cairo_rel_line_to (pCairoContext, pArea->width, 0);
371
cairo_set_line_width (pCairoContext, fLineWidth);
372
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
373
cairo_stroke (pCairoContext);
375
cairo_new_path (pCairoContext);
376
cairo_move_to (pCairoContext, fDockOffsetX, (pDock->container.bDirectionUp ? iHeight - fLineWidth / 2 : pDock->iDecorationsHeight + 1.5 * fLineWidth));
377
cairo_rel_line_to (pCairoContext, pArea->width, 0);
378
cairo_set_line_width (pCairoContext, fLineWidth);
379
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
383
cairo_move_to (pCairoContext, fDockOffsetX - fLineWidth / 2, fDockOffsetY);
384
cairo_rel_line_to (pCairoContext, 0, pArea->height);
385
cairo_set_line_width (pCairoContext, fLineWidth);
386
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
387
cairo_stroke (pCairoContext);
389
cairo_new_path (pCairoContext);
390
cairo_move_to (pCairoContext, (pDock->container.bDirectionUp ? iHeight - fLineWidth / 2 : pDock->iDecorationsHeight + 1.5 * fLineWidth), fDockOffsetY);
391
cairo_rel_line_to (pCairoContext, 0, pArea->height);
392
cairo_set_line_width (pCairoContext, fLineWidth);
393
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
395
cairo_stroke (pCairoContext);
397
cairo_restore (pCairoContext);
399
//\____________________ On dessine les icones impactees.
400
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
402
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
403
if (pFirstDrawnElement != NULL)
405
double fXMin = (pDock->container.bIsHorizontal ? pArea->x : pArea->y), fXMax = (pDock->container.bIsHorizontal ? pArea->x + pArea->width : pArea->y + pArea->height);
406
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
407
double fRatio = pDock->container.fRatio;
408
double fXLeft, fXRight;
410
//g_print ("redraw [%d -> %d]\n", (int) fXMin, (int) fXMax);
412
GList *ic = pFirstDrawnElement;
417
fXLeft = icon->fDrawX + icon->fScale + 1;
418
fXRight = icon->fDrawX + (icon->fWidth - 1) * icon->fScale * icon->fWidthFactor - 1;
420
if (fXLeft < fXMax && fXRight > fXMin)
422
cairo_save (pCairoContext);
423
//g_print ("dessin optimise de %s [%.2f -> %.2f]\n", icon->cName, fXLeft, fXRight);
426
if (icon->iAnimationState == CAIRO_DOCK_STATE_AVOID_MOUSE)
431
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, icon->bPointed);
432
cairo_restore (pCairoContext);
435
ic = cairo_dock_get_next_element (ic, pDock->icons);
436
} while (ic != pFirstDrawnElement);
441
static void cd_render_opengl (CairoDock *pDock)
443
//\_____________ On definit notre rectangle.
444
double fLineWidth = myBackground.iDockLineWidth;
445
double fMargin = myBackground.iFrameMargin;
446
double fRadius = (pDock->iDecorationsHeight + fLineWidth - 2 * myBackground.iDockRadius > 0 ? myBackground.iDockRadius : (pDock->iDecorationsHeight + fLineWidth) / 2 - 1);
447
double fExtraWidth = 2 * fRadius + fLineWidth;
449
double fFrameHeight = pDock->iDecorationsHeight + fLineWidth;
451
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
452
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
453
if (pFirstDrawnElement == NULL)
455
if (cairo_dock_is_extended_dock (pDock)) // mode panel etendu.
457
fDockWidth = pDock->container.iWidth - fExtraWidth;
458
fDockOffsetX = fLineWidth / 2;
462
fDockWidth = cairo_dock_get_current_dock_width_linear (pDock);
463
Icon *pFirstIcon = pFirstDrawnElement->data;
464
fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX + 0 - fMargin - fRadius : fLineWidth / 2);
465
if (fDockOffsetX - fLineWidth/2 < 0)
466
fDockOffsetX = fLineWidth / 2;
467
if (fDockOffsetX + fDockWidth + (2*fRadius + fLineWidth) > pDock->container.iWidth)
468
fDockWidth = pDock->container.iWidth - fDockOffsetX - (2*fRadius + fLineWidth);
471
fDockOffsetY = pDock->iDecorationsHeight + 1.5 * fLineWidth;
473
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
475
//\_____________ On genere les coordonnees du contour.
476
const CairoDockGLPath *pFramePath = cairo_dock_generate_rectangle_path (fDockWidth, fFrameHeight, fRadius, myBackground.bRoundedBottomCorner);
478
//\_____________ On remplit avec le fond.
480
cairo_dock_set_container_orientation_opengl (CAIRO_CONTAINER (pDock));
481
glTranslatef (fDockOffsetX + (fDockWidth+2*fRadius)/2,
482
fDockOffsetY - fFrameHeight/2,
485
_cairo_dock_set_blend_source ();
486
cairo_dock_fill_gl_path (pFramePath, pDock->backgroundBuffer.iTexture);
488
//\_____________ On trace le contour.
491
glLineWidth (fLineWidth);
492
glColor4f (myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
493
cairo_dock_stroke_gl_path (pFramePath, TRUE);
498
//\_____________ On trace les separateurs physiques.
500
cairo_dock_set_container_orientation_opengl (CAIRO_CONTAINER (pDock));
502
double x1, x2, dx, delta, h = pDock->iDecorationsHeight + 2*fLineWidth, h_ = h - fLineWidth;
505
for (ic = pDock->icons; ic != NULL; ic = ic->next)
508
if (CAIRO_DOCK_IS_SEPARATOR (pIcon))
510
x1 = pIcon->fDrawX = pIcon->fX;
513
for (ic = ic->next; ic != NULL; ic = ic->next)
516
if (!CAIRO_DOCK_IS_SEPARATOR (pIcon))
527
CairoDockGLPath *pPath = cairo_dock_new_gl_path (2*(iNbCurveSteps+1) + 1, (x1+x2)/2, h, 0., 0.); // on part du milieu en haut pour que les triangles soient contenus dans l'enveloppe.
529
dx = MIN (my_fPanelRadius, (x2 - x1) / 2);
530
delta = dx + h*tan(my_fPanelInclination)/2;
531
if (delta > (x2 - x1) / 2)
532
delta = (x2 - x1) / 2;
534
cairo_dock_gl_path_rel_line_to (pPath,
536
cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
540
cairo_dock_gl_path_rel_line_to (pPath,
541
x2 - x1 - 2*delta, 0.);
542
cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
547
glBlendFunc (GL_ONE, GL_ZERO);
548
glColor4f (0., 0., 0., 0.);
549
cairo_dock_fill_gl_path (pPath, 0);
550
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
554
cairo_dock_gl_path_move_to (pPath, x1, h - fLineWidth/2); // on part du haut/gauche, le nombre de points est ok.
555
cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
559
cairo_dock_gl_path_rel_line_to (pPath,
560
x2 - x1 - 2*delta, 0.);
561
cairo_dock_gl_path_rel_curve_to (pPath, iNbCurveSteps,
565
glLineWidth (fLineWidth);
566
glColor4f (myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
567
cairo_dock_stroke_gl_path (pPath, FALSE);
570
cairo_dock_free_gl_path (pPath);
576
//\_____________ On dessine la ficelle.
577
if (myIcons.iStringLineWidth > 0)
578
cairo_dock_draw_string_opengl (pDock, myIcons.iStringLineWidth, FALSE, FALSE);
581
//\_____________ On dessine les icones.
582
pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
583
if (pFirstDrawnElement == NULL)
586
ic = pFirstDrawnElement;
592
cairo_dock_render_one_icon_opengl (pIcon, pDock, fDockMagnitude, pIcon->bPointed);
595
ic = cairo_dock_get_next_element (ic, pDock->icons);
596
} while (ic != pFirstDrawnElement);
597
//glDisable (GL_LIGHTING);
601
static Icon *cd_calculate_icons (CairoDock *pDock)
603
//\_____________ On calcule le nombre de groupes et la place qu'ils occupent.
604
int iNbGroups = 1, iCurrentOrder = -1;
605
double fCurrentGroupWidth = - myIcons.iIconGap, fGroupsWidth = 0.;
606
double fSeparatorsPonderation = 0;
609
for (ic = pDock->icons; ic != NULL; ic = ic->next)
612
if (CAIRO_DOCK_IS_SEPARATOR (pIcon))
615
if (pIcon->fInsertRemoveFactor != 0)
617
if (pIcon->fInsertRemoveFactor > 0)
618
pIcon->fScale *= pIcon->fInsertRemoveFactor;
620
pIcon->fScale *= (1 + pIcon->fInsertRemoveFactor);
623
if (CAIRO_DOCK_IS_USER_SEPARATOR (pIcon)) // si c'est un separateur automatique, le changement de groupe incrementera le compteur a l'icone suivante.
625
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
628
fSeparatorsPonderation += pIcon->fScale;
629
fGroupsWidth += MAX (0, fCurrentGroupWidth);
630
fCurrentGroupWidth = - myIcons.iIconGap;
635
if (iCurrentOrder != (int)cairo_dock_get_icon_order (pIcon))
637
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
640
fSeparatorsPonderation ++; // seuls les separateurs utilisateurs peuvent zoomer.
641
fGroupsWidth += MAX (0, fCurrentGroupWidth);
642
fCurrentGroupWidth = - myIcons.iIconGap;
646
pIcon->fScale = my_fPanelRatio;
647
if (pIcon->fInsertRemoveFactor != 0)
649
if (pIcon->fInsertRemoveFactor > 0)
650
pIcon->fScale *= pIcon->fInsertRemoveFactor;
652
pIcon->fScale *= (1 + pIcon->fInsertRemoveFactor);
655
iCurrentOrder = cairo_dock_get_icon_order (pIcon);
656
fCurrentGroupWidth += pIcon->fWidth * pIcon->fScale + myIcons.iIconGap;
658
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste un separateur a la fin.
660
fGroupsWidth += MAX (0, fCurrentGroupWidth);
662
if (fGroupsWidth < 0)
665
//\_____________ On en deduit l'ecart entre les groupes d'icones.
666
double W = cairo_dock_get_max_authorized_dock_width (pDock);
667
double fScreenBorderGap = myBackground.iDockRadius + myBackground.iDockLineWidth; // on laisse un ecart avec le bord de l'ecran.
671
fGroupGap = (W - 2*fScreenBorderGap - fGroupsWidth) / (iNbGroups - 1);
672
if (fSeparatorsPonderation != 0 && iNbGroups > 2)
673
fGroupGap /= fSeparatorsPonderation / (iNbGroups - 1);
676
fGroupGap = W - fScreenBorderGap - fGroupsWidth;
678
//\_____________ On determine la position de chaque icone.
679
Icon *pPointedIcon = NULL;
680
double xm = pDock->container.iMouseX;
681
double xg = fScreenBorderGap; // abscisse de l'icone courante, et abscisse du debut du groupe courant.
683
fCurrentGroupWidth = - myIcons.iIconGap;
685
for (ic = pDock->icons; ic != NULL; ic = ic->next)
688
if (CAIRO_DOCK_IS_SEPARATOR (pIcon))
691
pIcon->fDrawX = pIcon->fX;
692
if (CAIRO_DOCK_IS_USER_SEPARATOR (pIcon)) // si c'est un separateur automatique, le changement de groupe incrementera le compteur a l'icone suivante.
694
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
696
xg += fCurrentGroupWidth + fGroupGap * pIcon->fScale;
697
if (pPointedIcon == NULL && xm > x && xm < xg)
699
pIcon->bPointed = TRUE;
700
pPointedIcon = pIcon;
703
pIcon->bPointed = FALSE;
705
fCurrentGroupWidth = - myIcons.iIconGap;
710
if (iCurrentOrder != (int)cairo_dock_get_icon_order (pIcon))
712
if (fCurrentGroupWidth > 0) // le groupe courant est non vide, sinon c'est juste 2 separateurs cote a cote.
714
xg += fCurrentGroupWidth + fGroupGap;
716
fCurrentGroupWidth = - myIcons.iIconGap;
719
iCurrentOrder = cairo_dock_get_icon_order (pIcon);
720
fCurrentGroupWidth += pIcon->fWidth * pIcon->fScale + myIcons.iIconGap;
723
if (pPointedIcon == NULL && xm > pIcon->fX - .5*myIcons.iIconGap && xm <= pIcon->fX + pIcon->fWidth * pIcon->fScale + .5*myIcons.iIconGap)
725
pIcon->bPointed = TRUE;
726
pPointedIcon = pIcon;
729
pIcon->bPointed = FALSE;
730
pIcon->fDrawX = pIcon->fX;
732
if (pDock->container.bDirectionUp)
733
pIcon->fY = pDock->iMaxDockHeight - (myBackground.iDockLineWidth + myBackground.iFrameMargin + pIcon->fHeight * my_fPanelRatio);
735
pIcon->fY = myBackground.iDockLineWidth + myBackground.iFrameMargin;
736
pIcon->fDrawY = pIcon->fY;
738
pIcon->fWidthFactor = 1.;
739
pIcon->fHeightFactor = 1.;
740
pIcon->fOrientation = 0.;
743
x += pIcon->fWidth * pIcon->fScale + myIcons.iIconGap;
746
cairo_dock_check_if_mouse_inside_linear (pDock);
748
cairo_dock_check_can_drop_linear (pDock);
754
void cd_rendering_register_panel_renderer (const gchar *cRendererName)
756
CairoDockRenderer *pRenderer = g_new0 (CairoDockRenderer, 1);
757
pRenderer->cReadmeFilePath = g_strdup_printf ("%s/readme-panel-view", MY_APPLET_SHARE_DATA_DIR);
758
pRenderer->cPreviewFilePath = g_strdup_printf ("%s/preview-panel.png", MY_APPLET_SHARE_DATA_DIR);
759
pRenderer->compute_size = cd_compute_size;
760
pRenderer->calculate_icons = cd_calculate_icons;
761
pRenderer->render = cd_render;
762
pRenderer->render_optimized = cd_render_optimized;
763
pRenderer->render_opengl = cd_render_opengl;
764
pRenderer->set_subdock_position = cairo_dock_set_subdock_position_linear;
765
pRenderer->bUseReflect = FALSE;
766
pRenderer->cDisplayedName = D_ (cRendererName);
768
cairo_dock_register_renderer (cRendererName, pRenderer);