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/>.
20
/*********************************************************************************
22
This file is a part of the cairo-dock program,
23
released under the terms of the GNU General Public License.
25
Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
27
*********************************************************************************/
37
#include "rendering-rainbow.h"
39
extern int my_iSpaceBetweenRows;
40
extern int my_iSpaceBetweenIcons;
41
extern double my_fRainbowMagnitude;
42
extern int my_iRainbowNbIconsMin;
43
extern double my_fRainbowConeOffset;
44
extern double my_fRainbowColor[4];
45
extern double my_fRainbowLineColor[4];
47
void cd_rendering_calculate_max_dock_size_rainbow (CairoDock *pDock)
49
pDock->fMagnitudeMax = my_fRainbowMagnitude;
50
pDock->pFirstDrawnElement = cairo_dock_calculate_icons_positions_at_rest_linear (pDock->icons, pDock->fFlatDockWidth, pDock->iScrollOffset);
52
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
53
int iMaxIconWidth = pDock->iMaxIconHeight + my_iSpaceBetweenIcons;
54
double fCone = G_PI - 2 * my_fRainbowConeOffset;
55
int iNbIcons = g_list_length (pDock->icons);
56
int iMinRadius = MIN (my_iRainbowNbIconsMin, iNbIcons) * iMaxIconWidth * fMaxScale / fCone;
58
int iNbRows = (int) ceil (sqrt (2 * iNbIcons / fCone / fMaxScale) + .5); /// approximation, utiliser la formule complete...
60
pDock->iMaxDockHeight = iNbRows * (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale + iMinRadius;
61
pDock->iMaxDockWidth = 2 * (pDock->iMaxDockHeight * cos (my_fRainbowConeOffset));
62
cd_debug ("iNbRows : %d => %dx%d (iMaxIconHeight = %d ; iMinRadius = %d ; fMaxScale = %.2f)\n", iNbRows, pDock->iMaxDockWidth, pDock->iMaxDockHeight, pDock->iMaxIconHeight, iMinRadius, fMaxScale);
64
pDock->iDecorationsWidth = 0;
65
pDock->iDecorationsHeight = 0;
67
pDock->iMinDockWidth = pDock->fFlatDockWidth;
68
pDock->iMinDockHeight = pDock->iMaxIconHeight;
72
void cd_rendering_render_rainbow (cairo_t *pCairoContext, CairoDock *pDock)
74
//g_print ("pDock->fFoldingFactor : %.2f\n", pDock->fFoldingFactor);
75
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
77
if (my_fRainbowColor[3] != 0)
79
cairo_save (pCairoContext);
80
if (! pDock->bHorizontalDock)
82
cairo_translate (pCairoContext, pDock->iCurrentHeight/2, pDock->iCurrentWidth/2);
83
cairo_rotate (pCairoContext, -G_PI/2);
84
cairo_translate (pCairoContext, -pDock->iCurrentWidth/2, -pDock->iCurrentHeight/2);
86
if (!pDock->bDirectionUp)
88
cairo_translate (pCairoContext, 0., pDock->iCurrentHeight);
89
cairo_scale (pCairoContext, 1., -1.);
91
//\____________________ On trace le cadre.
92
cairo_move_to (pCairoContext, 0., pDock->iCurrentHeight * (1 - sin (my_fRainbowConeOffset)));
93
cairo_line_to (pCairoContext, pDock->iCurrentWidth/2, pDock->iCurrentHeight);
94
cairo_line_to (pCairoContext, pDock->iCurrentWidth, pDock->iCurrentHeight * (1 - sin (my_fRainbowConeOffset)));
95
cairo_line_to (pCairoContext, pDock->iCurrentWidth, 0.);
96
cairo_line_to (pCairoContext, 0., 0.);
97
cairo_close_path (pCairoContext);
98
cairo_clip (pCairoContext);
100
//\____________________ On dessine les decorations dedans.
101
cairo_pattern_t *pGradationPattern = cairo_pattern_create_radial (pDock->iCurrentWidth/2,
102
pDock->iCurrentHeight,
104
pDock->iCurrentWidth/2,
105
pDock->iCurrentHeight,
106
pDock->iCurrentHeight);
107
g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
109
cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
110
cairo_pattern_add_color_stop_rgba (pGradationPattern,
117
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
118
GList *ic = pFirstDrawnElement;
119
Icon *pFirstIcon = pFirstDrawnElement->data;
120
double fCurrentRadius=0;
125
fRadius = icon->fX - (pDock->bDirectionUp ? pDock->iMaxIconHeight * fMaxScale : 0);
126
if (fRadius != fCurrentRadius)
128
if (fCurrentRadius == 0) // 1er coup.
130
cairo_pattern_add_color_stop_rgba (pGradationPattern,
131
(fRadius - my_iSpaceBetweenRows/2)/ pDock->iCurrentHeight,
138
cairo_pattern_add_color_stop_rgba (pGradationPattern,
139
(fRadius + .5 * pDock->iMaxIconHeight * fMaxScale)/ pDock->iCurrentHeight,
143
my_fRainbowColor[3]);
144
cairo_pattern_add_color_stop_rgba (pGradationPattern,
145
(fRadius + pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2)/ pDock->iCurrentHeight,
150
fCurrentRadius = fRadius;
152
ic = cairo_dock_get_next_element (ic, pDock->icons);
153
} while (ic != pFirstDrawnElement);
155
cairo_set_source (pCairoContext, pGradationPattern);
156
cairo_paint (pCairoContext);
157
cairo_pattern_destroy (pGradationPattern);
158
cairo_restore (pCairoContext);
161
//\____________________ On dessine le cadre.
164
Icon *icon = cairo_dock_get_last_drawn_icon (pDock);
166
fRadius = icon->fX - (pDock->bDirectionUp ? pDock->iMaxIconHeight * fMaxScale : 0);
168
fRadius += .5 * pDock->iMaxIconHeight * fMaxScale;
169
if (my_fRainbowLineColor[3] != 0)
171
cairo_save (pCairoContext);
172
if (! pDock->bHorizontalDock)
174
cairo_translate (pCairoContext, pDock->iCurrentHeight/2, pDock->iCurrentWidth/2);
175
cairo_rotate (pCairoContext, -G_PI/2);
176
cairo_translate (pCairoContext, -pDock->iCurrentWidth/2, -pDock->iCurrentHeight/2);
178
if (!pDock->bDirectionUp)
180
cairo_translate (pCairoContext, 0., pDock->iCurrentHeight);
181
cairo_scale (pCairoContext, 1., -1.);
183
cairo_set_line_width (pCairoContext, myBackground.iDockLineWidth);
184
cairo_move_to (pCairoContext, pDock->iCurrentWidth/2 - fRadius * cos (my_fRainbowConeOffset), pDock->iCurrentHeight - fRadius * sin (my_fRainbowConeOffset));
185
cairo_line_to (pCairoContext, pDock->iCurrentWidth/2, pDock->iCurrentHeight);
186
cairo_line_to (pCairoContext, pDock->iCurrentWidth/2 + fRadius * cos (my_fRainbowConeOffset), pDock->iCurrentHeight - fRadius * sin (my_fRainbowConeOffset));
187
cairo_set_source_rgba (pCairoContext,
188
my_fRainbowLineColor[0],
189
my_fRainbowLineColor[1],
190
my_fRainbowLineColor[2],
191
my_fRainbowLineColor[3]);
192
cairo_stroke (pCairoContext);
193
cairo_restore (pCairoContext);
196
//\____________________ On dessine la ficelle qui les joint.
198
//\____________________ On dessine les icones avec leurs etiquettes.
199
///cairo_dock_render_icons_linear (pCairoContext, pDock, fRatio);
200
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
201
if (pFirstDrawnElement == NULL)
204
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex)/** * pDock->fMagnitudeMax*/;
206
int iWidth = pDock->iCurrentWidth;
207
gboolean bHorizontalDock = pDock->bHorizontalDock;
208
GList *ic = pFirstDrawnElement;
213
cairo_save (pCairoContext);
215
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
217
cairo_restore (pCairoContext);
219
ic = cairo_dock_get_next_element (ic, pDock->icons);
220
} while (ic != pFirstDrawnElement);
224
static void cd_rendering_get_polar_coords (CairoDock *pDock, double *fRadius, double *fTheta)
226
double x = pDock->iMouseX - pDock->iCurrentWidth / 2, y = (pDock->bDirectionUp ? pDock->iCurrentHeight - pDock->iMouseY : pDock->iMouseY);
228
*fRadius = sqrt (x * x + y * y);
229
*fTheta = atan2 (x, y);
232
static double _calculate_wave_offset (int x_abs, int iMaxIconHeight, double fMagnitude, double fFlatDockWidth, int iWidth, double fAlign, double fFoldingFactor, double fRatio)
234
int iIconNumber = (x_abs + .5*my_iSpaceBetweenRows) / (iMaxIconHeight + my_iSpaceBetweenRows);
236
int x_cumulated = iIconNumber * (iMaxIconHeight + my_iSpaceBetweenRows);
237
cd_debug (" iIconNumber : %d ; x_cumulated : %d\n", iIconNumber, x_cumulated);
238
double fXMiddle = x_cumulated + iMaxIconHeight / 2;
239
double fPhase = (fXMiddle - x_abs) / myIcons.iSinusoidWidth / fRatio * G_PI + G_PI / 2;
244
else if (fPhase > G_PI)
248
double fScale = 1 + fMagnitude * g_fAmplitude * sin (fPhase);
249
double fX = x_cumulated - 0*(fFlatDockWidth - iWidth) / 2 + (1 - fScale) * (x_abs - x_cumulated + .5*my_iSpaceBetweenRows);
250
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
252
while (iIconNumber > 0)
255
x_cumulated = iIconNumber * (iMaxIconHeight + my_iSpaceBetweenRows);
256
//cd_debug (" %d) x_cumulated = %d\n", iIconNumber, x_cumulated);
257
fXMiddle = x_cumulated + iMaxIconHeight / 2;
258
fPhase = (fXMiddle - x_abs) / myIcons.iSinusoidWidth / fRatio * G_PI + G_PI / 2;
263
else if (fPhase > G_PI)
267
fScale = 1 + fMagnitude * g_fAmplitude * sin (fPhase);
269
fX = fX - (iMaxIconHeight + my_iSpaceBetweenRows) * fScale;
270
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
274
static double cd_rendering_calculate_wave_position (CairoDock *pDock, double fCurvilignAbscisse, double fMagnitude)
276
cd_debug ("%s (%.2f)\n", __func__, fCurvilignAbscisse);
278
if (pDock->icons == NULL || fCurvilignAbscisse <= 0)
280
double fWaveOffset, fWaveExtrema;
281
double x_abs = fCurvilignAbscisse;
283
double fRatio = pDock->fRatio;
287
//cd_debug (" x_abs : %.2f\n", x_abs);
288
fWaveOffset = _calculate_wave_offset (x_abs, pDock->iMaxIconHeight, fMagnitude, pDock->fFlatDockWidth, pDock->fFlatDockWidth, 0*pDock->fAlign, pDock->fFoldingFactor, fRatio);
290
fWaveExtrema = fWaveOffset + x_abs;
291
if (fWaveExtrema >= 0)
292
x_abs += (fCurvilignAbscisse - fWaveExtrema) / 2;
294
x_abs = MAX (0, x_abs - (fCurvilignAbscisse - fWaveExtrema) / 2);
295
if (x_abs > (int) pDock->fFlatDockWidth)
297
x_abs = (int) pDock->fFlatDockWidth;
300
//cd_debug (" -> fWaveOffset : %.2f, fWaveExtrema : %.2f\n", fWaveOffset, fWaveExtrema);
304
while (fabs (fWaveExtrema - fCurvilignAbscisse) > 1 && nb_iter < 15);
309
static int cd_rendering_calculate_wave_on_each_lines (int x_abs, int iMaxIconHeight, double fMagnitude, double fFlatDockWidth, int iWidth, double fAlign, double fFoldingFactor, double fRatio, int iNbRows, double *pScales) // (fScale,fX)
313
cd_debug ("%s (%d, %.2f, %.2f, %d)\n", __func__, x_abs, fMagnitude, fFoldingFactor, iNbRows);
314
if (x_abs < 0 && iWidth > 0) // ces cas limite sont la pour empecher les icones de retrecir trop rapidement quend on sort par les cotes.
316
else if (x_abs > fFlatDockWidth && iWidth > 0)
317
x_abs = fFlatDockWidth+1;
319
float x_cumulated = 0, fXMiddle, fDeltaExtremum;
320
double fPhase, fScale, fX;
321
int iNumRow, iPointedRow=-1;
322
for (iNumRow = 0; iNumRow < iNbRows; iNumRow ++)
324
//cd_debug (" ligne %d\n", iNumRow);
325
fXMiddle = x_cumulated + .5*iMaxIconHeight;
327
fPhase = (fXMiddle - x_abs) / myIcons.iSinusoidWidth / fRatio * G_PI + G_PI / 2;
330
else if (fPhase > G_PI)
332
fScale = 1 + fMagnitude * g_fAmplitude * sin (fPhase);
333
pScales[2*iNumRow] = fScale;
334
//cd_debug (" fScale : %.2f\n", fScale);
336
if (iPointedRow != -1)
338
fX = pScales[2*(iNumRow-1)+1] + (iMaxIconHeight + my_iSpaceBetweenRows) * pScales[2*(iNumRow-1)];
339
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
340
pScales[2*iNumRow+1] = fX;
341
//cd_debug (" fX : %.2f (prev : %.2f , %.2f)\n", fX, pScales[2*(iNumRow-1)+1], pScales[2*(iNumRow-1)]);
344
if (x_cumulated + iMaxIconHeight + .5*my_iSpaceBetweenRows >= x_abs && x_cumulated - .5*my_iSpaceBetweenRows <= x_abs && iPointedRow == -1) // on a trouve la ligne sur laquelle on pointe.
346
iPointedRow = iNumRow;
347
fX = x_cumulated - 0*(fFlatDockWidth - iWidth) / 2 + (1 - fScale) * (x_abs - x_cumulated + .5*my_iSpaceBetweenRows);
348
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
349
//cd_debug (" ligne pointee : %d\n", iPointedRow);
350
pScales[2*iNumRow+1] = fX;
351
//cd_debug (" fX : %.2f\n", fX);
354
x_cumulated += iMaxIconHeight;
357
if (iPointedRow == -1) // on est en dehors du disque.
359
iPointedRow = iNbRows - 1;
361
fX = x_cumulated - (fFlatDockWidth - iWidth) / 2 + (1 - fScale) * (iMaxIconHeight + .5*my_iSpaceBetweenRows);
362
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1 - fFoldingFactor);
363
pScales[2*iNumRow+1] = fX;
364
//cd_debug (" fX : %.2f\n", fX);
367
for (iNumRow = iPointedRow-1; iNumRow >= 0; iNumRow --)
369
fX = pScales[2*(iNumRow+1)+1] - (iMaxIconHeight + my_iSpaceBetweenRows) * pScales[2*iNumRow];
370
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
371
pScales[2*iNumRow+1] = fX;
372
//cd_debug (" fX : %.2f\n", fX);
376
for (iNumRow = 0; iNumRow < iNbRows; iNumRow ++)
378
pScales[2*iNumRow+1] -= fX;
384
Icon *cd_rendering_calculate_icons_rainbow (CairoDock *pDock)
386
if (pDock->icons == NULL)
389
//\____________________ On se place en coordonnees polaires.
390
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
391
int iMaxIconWidth = pDock->iMaxIconHeight + my_iSpaceBetweenIcons;
392
double fCone = G_PI - 2 * my_fRainbowConeOffset;
393
int iNbIcons = g_list_length (pDock->icons);
394
int iMinRadius = MIN (my_iRainbowNbIconsMin, iNbIcons) * iMaxIconWidth * fMaxScale / fCone;
395
double fRatio = pDock->fRatio;
396
double w = pDock->iCurrentWidth;
397
double h = pDock->iCurrentHeight;
398
double fRadius, fTheta;
399
cd_debug (" mouse : (%d ; %d)\n", pDock->iMouseX, pDock->iMouseY);
400
cd_rendering_get_polar_coords (pDock, &fRadius, &fTheta);
401
cd_debug (" polar : (%.2f ; %.2f)\n", fRadius, fTheta/G_PI*180.);
403
double fCurvilignAbscisse = (fTheta > -G_PI/2 && fTheta < G_PI/2 ? MAX (0, fRadius - iMinRadius): 0);
405
//\____________________ On en deduit ou appliquer la vague pour que la crete soit a la position du curseur.
406
Icon *pPointedIcon = NULL;
407
double fMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex) * pDock->fMagnitudeMax;
408
int x_abs = (int) round (cd_rendering_calculate_wave_position (pDock, fCurvilignAbscisse, fMagnitude));
409
cd_debug (" => x_abs : %d (fMagnitude:%.2f ; fFoldingFactor:%.2f)\n", x_abs, fMagnitude, pDock->fFoldingFactor);
411
//\_______________ On en deduit l'amplitude de chaque ligne.
412
int iNbRows = round ((pDock->iMaxDockHeight- iMinRadius) / ((pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale));
413
cd_debug ("iNbRows : %d\n", iNbRows);
414
double fFlatDockWidth = iNbRows * (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale;
415
double *pScales = g_new0 (double, 2*iNbRows+2);
416
cd_rendering_calculate_wave_on_each_lines (x_abs, pDock->iMaxIconHeight, fMagnitude, fFlatDockWidth, fFlatDockWidth, 0*pDock->fAlign, pDock->fFoldingFactor, fRatio, iNbRows, pScales);
418
//\____________________ On en deduit les position/etirements/alpha des icones.
419
Icon* icon, *prev_icon;
422
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
423
ic = pFirstDrawnElement;
424
Icon *pFirstIcon = pFirstDrawnElement->data;
426
int iNbRow = -1, iNbIconsOnRow = 0, iNbInsertedIcons = 0;
427
double fCurrentRadius=0, fNormalRadius=0, fCurrentTheta, fThetaStart, fDeltaTheta, fCurrentScale;
432
if (iNbInsertedIcons == iNbIconsOnRow)
435
if (iNbRow == iNbRows)
437
iNbInsertedIcons = 0;
438
fCurrentRadius = iMinRadius * (1 - pDock->fFoldingFactor) + pScales[2*iNbRow+1];
439
fCurrentScale = pScales[2*iNbRow] * (1 - pDock->fFoldingFactor);
440
fNormalRadius = iMinRadius + iNbRow * (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale;
441
fDeltaTheta = 2 * atan (iMaxIconWidth * fMaxScale / 2 / fNormalRadius);
442
iNbIconsOnRow = (int) (fCone / fDeltaTheta);
443
fThetaStart = - G_PI/2 + my_fRainbowConeOffset + (fCone - iNbIconsOnRow * fDeltaTheta) / 2 + fDeltaTheta / 2;
444
cd_debug ("on passe a la ligne %d (%d icones, fThetaStart = %.2fdeg, fCurrentRadius = %.2f(%.2f), fDeltaTheta = %.2f, fCurrentScale = %.2f)\n", iNbRow, iNbIconsOnRow, fThetaStart/G_PI*180, fCurrentRadius, fNormalRadius, fDeltaTheta/G_PI*180, fCurrentScale);
447
icon->fX = fCurrentRadius + (pDock->bDirectionUp ? pDock->iMaxIconHeight * fCurrentScale : 0);
449
fCurrentTheta = fThetaStart + iNbInsertedIcons * fDeltaTheta;
450
icon->fOrientation = (pDock->bDirectionUp ? fCurrentTheta : - fCurrentTheta);
451
if (! pDock->bHorizontalDock)
453
icon->fOrientation = -icon->fOrientation + 0;
455
if (pPointedIcon == NULL && fRadius < fCurrentRadius + (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fCurrentScale && fRadius > fCurrentRadius && fTheta > fCurrentTheta - fDeltaTheta/2 && fTheta < fCurrentTheta + fDeltaTheta/2)
457
icon->bPointed = TRUE;
459
cd_debug (" POINTED ICON : %s\n", pPointedIcon->acName);
462
icon->bPointed = FALSE;
464
//if (pDock->bHorizontalDock)
466
icon->fDrawY = icon->fX * cos (fCurrentTheta) + icon->fWidth/2 * fCurrentScale * sin (fCurrentTheta);
467
if (pDock->bDirectionUp)
468
icon->fDrawY = pDock->iCurrentHeight - icon->fDrawY;
469
icon->fDrawX = icon->fX * sin (fCurrentTheta) - icon->fWidth/2 * fCurrentScale * cos (fCurrentTheta) + pDock->iCurrentWidth / 2;
473
icon->fDrawX = icon->fX * cos (fCurrentTheta) + icon->fWidth/2 * fCurrentScale * sin (fCurrentTheta);
474
if (!pDock->bDirectionUp)
475
icon->fDrawX = pDock->iCurrentWidth - icon->fDrawX;
476
icon->fDrawY = icon->fX * sin (fCurrentTheta) - icon->fWidth/2 * fCurrentScale * cos (fCurrentTheta) + pDock->iCurrentHeight / 2;
479
cd_debug (" %.2fdeg ; (%.2f;%.2f)\n", fCurrentTheta/G_PI*180, icon->fDrawX, icon->fDrawY);
481
icon->fScale = fCurrentScale;
483
icon->fWidthFactor = 1.;
484
icon->fHeightFactor = 1.;
490
ic = cairo_dock_get_next_element (ic, pDock->icons);
491
} while (ic != pFirstDrawnElement);
494
//g_print ("fRadius : %.2f ; limite : %.2f\n", fRadius, fCurrentRadius + pDock->iMaxIconHeight * fCurrentScale);
495
if (! pDock->bInside ||
496
fRadius > fCurrentRadius + pDock->iMaxIconHeight * fCurrentScale + myLabels.iLabelSize - (pDock->fFoldingFactor > 0 ? 20 : 0) ||
497
(fTheta < - G_PI/2 + my_fRainbowConeOffset || fTheta > G_PI/2 - my_fRainbowConeOffset) && fRadius > iMinRadius + .5 * pDock->iMaxIconHeight * fMaxScale)
499
cd_debug ("<<< on sort du demi-disque >>>\n");
500
pDock->iMousePositionType = CAIRO_DOCK_MOUSE_OUTSIDE;
501
if (pDock->bIsDragging)
502
pDock->bCanDrop = TRUE;
506
pDock->iMousePositionType = CAIRO_DOCK_MOUSE_INSIDE;
507
pDock->bCanDrop = FALSE;
514
static double *_generate_cos_sin (double fConeOffset, double fDelta, double *pTabValues)
516
int i, n = (int) ceil ((G_PI/2 - fConeOffset) / fDelta);
517
pTabValues[2*n] = 0.; // point au milieu.
518
pTabValues[2*n+1] = 1.;
521
for (i = 0; i < n; i ++)
523
fTheta = (i == 0 ? G_PI/2 - fConeOffset : (n - i) * fDelta);
524
pTabValues[2*i] = sin (fTheta);
525
pTabValues[2*i+1] = cos (fTheta);
527
pTabValues[2*(2*n-i)] = - pTabValues[2*i];
528
pTabValues[2*(2*n-i)+1] = pTabValues[2*i+1];
532
static GLfloat *_generate_sector_path (double fConeOffset, double fRadius1, double fRadius2, double fDelta, double *pCosSinTab, GLfloat *pTabValues)
534
int i, n = (int) ceil ((G_PI/2 - fConeOffset) / fDelta), N = (2*n+1) * 2;
535
for (i = 0; i < 2*n+1; i ++)
537
pTabValues[3*(2*i)] = fRadius1 * pCosSinTab[2*i+0];
538
pTabValues[3*(2*i)+1] = fRadius1 * pCosSinTab[2*i+1];
539
pTabValues[3*(2*i+1)] = fRadius2 * pCosSinTab[2*i+0];
540
pTabValues[3*(2*i+1)+1] = fRadius2 * pCosSinTab[2*i+1];
541
//g_print ("%.2f;%.2f\n", pTabValues[3*i], pTabValues[3*i+1]);
543
pTabValues[3*N] = pTabValues[3*0];
544
pTabValues[3*N+1] = pTabValues[3*0+1];
545
pTabValues[3*(N+1)] = pTabValues[3*1];
546
pTabValues[3*(N+1)+1] = pTabValues[3*1+1];
551
static double *pCosSinTab = NULL;
552
static GLfloat *pVertexTab = NULL;
553
static GLfloat* pColorTab = NULL;
554
void cd_rendering_reload_rainbow_buffers (void)
562
void cd_rendering_render_rainbow_opengl (CairoDock *pDock)
564
static double fDelta = 1.;
565
if (pCosSinTab == NULL)
567
pCosSinTab = g_new0 (double, (180./fDelta+1) * 2);
568
_generate_cos_sin (my_fRainbowConeOffset, fDelta/180.*G_PI, pCosSinTab);
570
if (pVertexTab == NULL)
571
pVertexTab = g_new0 (GLfloat, ((180./fDelta+1) * 2) * 3);
572
if (pColorTab == NULL)
574
pColorTab = g_new0 (GLfloat, ((180./fDelta+1) * 2) * 4);
576
for (i = 0; i < (180./fDelta+1); i ++)
578
pColorTab[4*2*i+0] = my_fRainbowColor[0];
579
pColorTab[4*2*i+1] = my_fRainbowColor[1];
580
pColorTab[4*2*i+2] = my_fRainbowColor[2];
581
pColorTab[4*2*i+3] = my_fRainbowColor[3];
585
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
587
if (my_fRainbowColor[3] != 0)
589
//\____________________ On trace le cadre.
590
//\____________________ On dessine les decorations dedans.
591
glEnable (GL_LINE_SMOOTH);
592
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
593
///_cairo_dock_set_blend_alpha (); // qqch cloche ...
594
_cairo_dock_set_blend_over ();
597
glPolygonMode(GL_FRONT, GL_FILL); // GL_FILL
598
glEnableClientState(GL_VERTEX_ARRAY);
599
glEnableClientState(GL_COLOR_ARRAY);
602
int i, n = (int) ceil ((G_PI/2 - my_fRainbowConeOffset) / (fDelta/180.*G_PI)), N = (2*n+1) * 2;
605
if (! pDock->bHorizontalDock)
607
glTranslatef (pDock->iCurrentHeight/2, pDock->iCurrentWidth/2, 0.);
608
glRotatef (90., 0., 0., 1.);
609
glTranslatef (0., -pDock->iCurrentHeight/2, 0.);
612
glTranslatef (pDock->iCurrentWidth/2, 0., 0.);
613
if (!pDock->bDirectionUp)
615
glTranslatef (0., pDock->iCurrentHeight, 0.);
616
glScalef (1., -1., 1.);
619
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
620
GList *ic = pFirstDrawnElement;
621
Icon *pFirstIcon = pFirstDrawnElement->data;
622
double fCurrentRadius=0;
629
fRadius = icon->fX - (pDock->bDirectionUp ? pDock->iMaxIconHeight * icon->fScale : 0);
630
if (fRadius != fCurrentRadius)
632
_generate_sector_path (my_fRainbowConeOffset,
633
fRadius + .5 * pDock->iMaxIconHeight * fMaxScale,
634
fRadius - my_iSpaceBetweenRows/2,
636
fDelta/180.*G_PI, pCosSinTab, pVertexTab);
638
glVertexPointer(3, GL_FLOAT, 0, pVertexTab);
639
glColorPointer(4, GL_FLOAT, 0, pColorTab);
640
glDrawArrays(GL_QUAD_STRIP, 0, N);
642
_generate_sector_path (my_fRainbowConeOffset,
643
fRadius + .5 * pDock->iMaxIconHeight * fMaxScale,
644
fRadius + pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2,
645
fDelta/180.*G_PI, pCosSinTab, pVertexTab);
647
glVertexPointer(3, GL_FLOAT, 0, pVertexTab);
648
glColorPointer(4, GL_FLOAT, 0, pColorTab);
649
glDrawArrays(GL_QUAD_STRIP, 0, N);
651
fCurrentRadius = fRadius;
653
ic = cairo_dock_get_next_element (ic, pDock->icons);
654
} while (ic != pFirstDrawnElement);
657
glDisableClientState(GL_VERTEX_ARRAY);
658
glDisableClientState(GL_COLOR_ARRAY);
659
glDisable(GL_POLYGON_SMOOTH);
663
//\____________________ On dessine le cadre.
666
Icon *icon = cairo_dock_get_last_drawn_icon (pDock);
668
fRadius = icon->fX - (pDock->bDirectionUp ? pDock->iMaxIconHeight * fMaxScale : 0);
670
fRadius += .5 * pDock->iMaxIconHeight * fMaxScale;
671
if (my_fRainbowLineColor[3] != 0)
674
if (! pDock->bHorizontalDock)
676
glTranslatef (pDock->iCurrentHeight/2, pDock->iCurrentWidth/2, 0.);
677
glRotatef (90., 0., 0., 1.);
678
glTranslatef (0., -pDock->iCurrentHeight/2, 0.);
681
glTranslatef (pDock->iCurrentWidth/2, 0., 0.);
682
if (!pDock->bDirectionUp)
684
glTranslatef (0., pDock->iCurrentHeight, 0.);
685
glScalef (1., -1., 1.);
687
GLfloat color[4*5] = {my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], 0.,
688
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], my_fRainbowLineColor[3],
689
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], my_fRainbowLineColor[3],
690
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], my_fRainbowLineColor[3],
691
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], 0.};
692
glEnableClientState(GL_COLOR_ARRAY);
693
glColorPointer(4, GL_FLOAT, 0, color);
694
glVertexPointer(3, GL_FLOAT, 0, pVertexTab);
696
pVertexTab[3*0+0] = - (fRadius + .5 * pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2) * pCosSinTab[2*0];
697
pVertexTab[3*0+1] = (fRadius + .5 * pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2) * pCosSinTab[2*0+1];
698
pVertexTab[3*1+0] = - fRadius * cos (my_fRainbowConeOffset);
699
pVertexTab[3*1+1] = fRadius * sin (my_fRainbowConeOffset);
700
pVertexTab[3*2+0] = 0.;
701
pVertexTab[3*2+1] = 0.;
702
pVertexTab[3*3+0] = - pVertexTab[3*1+0];
703
pVertexTab[3*3+1] = pVertexTab[3*1+1];
704
pVertexTab[3*4+0] = - pVertexTab[3*0+0];
705
pVertexTab[3*4+1] = pVertexTab[3*0+1];
707
cairo_dock_draw_current_path_opengl (myBackground.iDockLineWidth, my_fRainbowLineColor, 5);
709
glDisableClientState(GL_COLOR_ARRAY);
713
//\____________________ On dessine les icones.
714
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
715
if (pFirstDrawnElement == NULL)
718
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex)/** * pDock->fMagnitudeMax*/;
720
int iWidth = pDock->iCurrentWidth;
721
gboolean bHorizontalDock = pDock->bHorizontalDock;
722
GList *ic = pFirstDrawnElement;
728
cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE); // ! mySystem.bTextAlwaysHorizontal
731
ic = cairo_dock_get_next_element (ic, pDock->icons);
732
} while (ic != pFirstDrawnElement);
736
void cd_rendering_register_rainbow_renderer (const gchar *cRendererName)
738
CairoDockRenderer *pRenderer = g_new0 (CairoDockRenderer, 1);
739
pRenderer->cReadmeFilePath = g_strdup_printf ("%s/readme-rainbow-view", MY_APPLET_SHARE_DATA_DIR);
740
pRenderer->cPreviewFilePath = g_strdup_printf ("%s/preview-rainbow.jpg", MY_APPLET_SHARE_DATA_DIR);
741
pRenderer->calculate_max_dock_size = cd_rendering_calculate_max_dock_size_rainbow;
742
pRenderer->calculate_icons = cd_rendering_calculate_icons_rainbow;
743
pRenderer->render = cd_rendering_render_rainbow;
744
pRenderer->render_optimized = NULL;
745
pRenderer->render_opengl = cd_rendering_render_rainbow_opengl;
746
pRenderer->set_subdock_position = cairo_dock_set_subdock_position_linear;
747
pRenderer->cDisplayedName = D_ (cRendererName);
749
cairo_dock_register_renderer (cRendererName, pRenderer);