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-rainbow.h"
31
extern int my_iSpaceBetweenRows;
32
extern int my_iSpaceBetweenIcons;
33
extern double my_fRainbowMagnitude;
34
extern int my_iRainbowNbIconsMin;
35
extern double my_fRainbowConeOffset;
36
extern double my_fRainbowColor[4];
37
extern double my_fRainbowLineColor[4];
39
static double *pCosSinTab = NULL;
40
static GLfloat *pVertexTab = NULL;
41
static GLfloat* pColorTab = NULL;
43
static void cd_rendering_calculate_max_dock_size_rainbow (CairoDock *pDock)
45
pDock->fMagnitudeMax = my_fRainbowMagnitude;
46
pDock->pFirstDrawnElement = cairo_dock_calculate_icons_positions_at_rest_linear (pDock->icons, pDock->fFlatDockWidth, pDock->iScrollOffset);
48
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
49
int iMaxIconWidth = pDock->iMaxIconHeight + my_iSpaceBetweenIcons;
50
double fCone = G_PI - 2 * my_fRainbowConeOffset;
51
int iNbIcons = g_list_length (pDock->icons);
52
int iMinRadius = MIN (my_iRainbowNbIconsMin, iNbIcons) * iMaxIconWidth * fMaxScale / fCone;
54
int iNbRows = (int) ceil (sqrt (2 * iNbIcons / fCone / fMaxScale) + .5); /// approximation, utiliser la formule complete...
56
pDock->iMaxDockHeight = iNbRows * (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale + iMinRadius;
57
pDock->iMaxDockWidth = 2 * (pDock->iMaxDockHeight * cos (my_fRainbowConeOffset));
58
cd_debug ("iNbRows : %d => %dx%d (iMaxIconHeight = %d ; iMinRadius = %d ; fMaxScale = %.2f)\n", iNbRows, pDock->iMaxDockWidth, pDock->iMaxDockHeight, pDock->iMaxIconHeight, iMinRadius, fMaxScale);
60
pDock->iDecorationsWidth = 0;
61
pDock->iDecorationsHeight = 0;
63
pDock->iMinDockWidth = pDock->fFlatDockWidth;
64
pDock->iMinDockHeight = pDock->iMaxIconHeight;
68
static void cd_rendering_render_rainbow (cairo_t *pCairoContext, CairoDock *pDock)
70
//g_print ("pDock->fFoldingFactor : %.2f\n", pDock->fFoldingFactor);
71
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
73
if (my_fRainbowColor[3] != 0 && pDock->icons != NULL)
75
cairo_save (pCairoContext);
76
if (! pDock->container.bIsHorizontal)
78
cairo_translate (pCairoContext, pDock->container.iHeight/2, pDock->container.iWidth/2);
79
cairo_rotate (pCairoContext, -G_PI/2);
80
cairo_translate (pCairoContext, -pDock->container.iWidth/2, -pDock->container.iHeight/2);
82
if (!pDock->container.bDirectionUp)
84
cairo_translate (pCairoContext, 0., pDock->container.iHeight);
85
cairo_scale (pCairoContext, 1., -1.);
87
//\____________________ On fait un clip du cone.
88
cairo_move_to (pCairoContext, 0., pDock->container.iHeight * (1 - sin (my_fRainbowConeOffset)));
89
cairo_line_to (pCairoContext, pDock->container.iWidth/2, pDock->container.iHeight);
90
cairo_line_to (pCairoContext, pDock->container.iWidth, pDock->container.iHeight * (1 - sin (my_fRainbowConeOffset)));
91
cairo_line_to (pCairoContext, pDock->container.iWidth, 0.);
92
cairo_line_to (pCairoContext, 0., 0.);
93
cairo_close_path (pCairoContext);
94
cairo_clip (pCairoContext);
96
//\____________________ On dessine chaque rayure dedans.
97
cairo_pattern_t *pGradationPattern = cairo_pattern_create_radial (pDock->container.iWidth/2,
98
pDock->container.iHeight,
100
pDock->container.iWidth/2,
101
pDock->container.iHeight,
102
pDock->container.iHeight);
103
g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
105
cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
106
cairo_pattern_add_color_stop_rgba (pGradationPattern,
113
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
114
GList *ic = pFirstDrawnElement;
115
Icon *pFirstIcon = pFirstDrawnElement->data;
116
double fCurrentRadius=0;
121
fRadius = icon->fX - (pDock->container.bDirectionUp ? pDock->iMaxIconHeight * fMaxScale : 0);
122
if (fRadius != fCurrentRadius)
124
if (fCurrentRadius == 0) // 1er coup.
126
cairo_pattern_add_color_stop_rgba (pGradationPattern,
127
(fRadius - my_iSpaceBetweenRows/2)/ pDock->container.iHeight,
134
cairo_pattern_add_color_stop_rgba (pGradationPattern,
135
(fRadius + .5 * pDock->iMaxIconHeight * fMaxScale)/ pDock->container.iHeight,
139
my_fRainbowColor[3]);
140
cairo_pattern_add_color_stop_rgba (pGradationPattern,
141
(fRadius + pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2)/ pDock->container.iHeight,
146
fCurrentRadius = fRadius;
148
ic = cairo_dock_get_next_element (ic, pDock->icons);
149
} while (ic != pFirstDrawnElement);
151
cairo_set_source (pCairoContext, pGradationPattern);
152
cairo_paint (pCairoContext);
153
cairo_pattern_destroy (pGradationPattern);
154
cairo_restore (pCairoContext);
157
//\____________________ On dessine le cadre.
160
Icon *icon = cairo_dock_get_last_drawn_icon (pDock);
162
fRadius = icon->fX - (pDock->container.bDirectionUp ? pDock->iMaxIconHeight * fMaxScale : 0);
164
fRadius += .5 * pDock->iMaxIconHeight * fMaxScale;
165
if (my_fRainbowLineColor[3] != 0)
167
cairo_save (pCairoContext);
168
if (! pDock->container.bIsHorizontal)
170
cairo_translate (pCairoContext, pDock->container.iHeight/2, pDock->container.iWidth/2);
171
cairo_rotate (pCairoContext, -G_PI/2);
172
cairo_translate (pCairoContext, -pDock->container.iWidth/2, -pDock->container.iHeight/2);
174
if (!pDock->container.bDirectionUp)
176
cairo_translate (pCairoContext, 0., pDock->container.iHeight);
177
cairo_scale (pCairoContext, 1., -1.);
179
cairo_set_line_width (pCairoContext, myBackground.iDockLineWidth);
180
cairo_move_to (pCairoContext, pDock->container.iWidth/2 - fRadius * cos (my_fRainbowConeOffset), pDock->container.iHeight - fRadius * sin (my_fRainbowConeOffset));
181
cairo_line_to (pCairoContext, pDock->container.iWidth/2, pDock->container.iHeight);
182
cairo_line_to (pCairoContext, pDock->container.iWidth/2 + fRadius * cos (my_fRainbowConeOffset), pDock->container.iHeight - fRadius * sin (my_fRainbowConeOffset));
183
cairo_set_source_rgba (pCairoContext,
184
my_fRainbowLineColor[0],
185
my_fRainbowLineColor[1],
186
my_fRainbowLineColor[2],
187
my_fRainbowLineColor[3]);
188
cairo_stroke (pCairoContext);
189
cairo_restore (pCairoContext);
192
//\____________________ On dessine la ficelle qui les joint.
194
//\____________________ On dessine les icones avec leurs etiquettes.
195
///cairo_dock_render_icons_linear (pCairoContext, pDock, fRatio);
196
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
197
if (pFirstDrawnElement == NULL)
200
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex)/** * pDock->fMagnitudeMax*/;
202
int iWidth = pDock->container.iWidth;
203
gboolean bIsHorizontal = pDock->container.bIsHorizontal;
204
GList *ic = pFirstDrawnElement;
209
cairo_save (pCairoContext);
210
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
211
cairo_restore (pCairoContext);
213
ic = cairo_dock_get_next_element (ic, pDock->icons);
214
} while (ic != pFirstDrawnElement);
218
static void cd_rendering_get_polar_coords (CairoDock *pDock, double *fRadius, double *fTheta)
220
double x = pDock->container.iMouseX - pDock->container.iWidth / 2, y = (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->container.iMouseY : pDock->container.iMouseY);
222
*fRadius = sqrt (x * x + y * y);
223
*fTheta = atan2 (x, y);
226
static double _calculate_wave_offset (int x_abs, int iMaxIconHeight, double fMagnitude, double fFlatDockWidth, int iWidth, double fAlign, double fFoldingFactor, double fRatio)
228
int iIconNumber = (x_abs + .5*my_iSpaceBetweenRows) / (iMaxIconHeight + my_iSpaceBetweenRows);
230
int x_cumulated = iIconNumber * (iMaxIconHeight + my_iSpaceBetweenRows);
231
cd_debug (" iIconNumber : %d ; x_cumulated : %d\n", iIconNumber, x_cumulated);
232
double fXMiddle = x_cumulated + iMaxIconHeight / 2;
233
double fPhase = (fXMiddle - x_abs) / myIcons.iSinusoidWidth / fRatio * G_PI + G_PI / 2;
238
else if (fPhase > G_PI)
242
double fScale = 1 + fMagnitude * g_fAmplitude * sin (fPhase);
243
double fX = x_cumulated - 0*(fFlatDockWidth - iWidth) / 2 + (1 - fScale) * (x_abs - x_cumulated + .5*my_iSpaceBetweenRows);
244
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
246
while (iIconNumber > 0)
249
x_cumulated = iIconNumber * (iMaxIconHeight + my_iSpaceBetweenRows);
250
//cd_debug (" %d) x_cumulated = %d\n", iIconNumber, x_cumulated);
251
fXMiddle = x_cumulated + iMaxIconHeight / 2;
252
fPhase = (fXMiddle - x_abs) / myIcons.iSinusoidWidth / fRatio * G_PI + G_PI / 2;
257
else if (fPhase > G_PI)
261
fScale = 1 + fMagnitude * g_fAmplitude * sin (fPhase);
263
fX = fX - (iMaxIconHeight + my_iSpaceBetweenRows) * fScale;
264
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
268
static double cd_rendering_calculate_wave_position (CairoDock *pDock, double fCurvilignAbscisse, double fMagnitude)
270
cd_debug ("%s (%.2f)\n", __func__, fCurvilignAbscisse);
272
if (pDock->icons == NULL || fCurvilignAbscisse <= 0)
274
double fWaveOffset, fWaveExtrema;
275
double x_abs = fCurvilignAbscisse;
277
double fRatio = pDock->container.fRatio;
281
//cd_debug (" x_abs : %.2f\n", x_abs);
282
fWaveOffset = _calculate_wave_offset (x_abs, pDock->iMaxIconHeight, fMagnitude, pDock->fFlatDockWidth, pDock->fFlatDockWidth, 0*pDock->fAlign, pDock->fFoldingFactor, fRatio);
284
fWaveExtrema = fWaveOffset + x_abs;
285
if (fWaveExtrema >= 0)
286
x_abs += (fCurvilignAbscisse - fWaveExtrema) / 2;
288
x_abs = MAX (0, x_abs - (fCurvilignAbscisse - fWaveExtrema) / 2);
289
if (x_abs > (int) pDock->fFlatDockWidth)
291
x_abs = (int) pDock->fFlatDockWidth;
294
//cd_debug (" -> fWaveOffset : %.2f, fWaveExtrema : %.2f\n", fWaveOffset, fWaveExtrema);
298
while (fabs (fWaveExtrema - fCurvilignAbscisse) > 1 && nb_iter < 15);
303
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)
307
cd_debug ("%s (%d, %.2f, %.2f, %d)\n", __func__, x_abs, fMagnitude, fFoldingFactor, iNbRows);
308
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.
310
else if (x_abs > fFlatDockWidth && iWidth > 0)
311
x_abs = fFlatDockWidth+1;
313
float x_cumulated = 0, fXMiddle, fDeltaExtremum;
314
double fPhase, fScale, fX;
315
int iNumRow, iPointedRow=-1;
316
for (iNumRow = 0; iNumRow < iNbRows; iNumRow ++)
318
//cd_debug (" ligne %d\n", iNumRow);
319
fXMiddle = x_cumulated + .5*iMaxIconHeight;
321
fPhase = (fXMiddle - x_abs) / myIcons.iSinusoidWidth / fRatio * G_PI + G_PI / 2;
324
else if (fPhase > G_PI)
326
fScale = 1 + fMagnitude * g_fAmplitude * sin (fPhase);
327
pScales[2*iNumRow] = fScale;
328
//cd_debug (" fScale : %.2f\n", fScale);
330
if (iPointedRow != -1)
332
fX = pScales[2*(iNumRow-1)+1] + (iMaxIconHeight + my_iSpaceBetweenRows) * pScales[2*(iNumRow-1)];
333
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
334
pScales[2*iNumRow+1] = fX;
335
//cd_debug (" fX : %.2f (prev : %.2f , %.2f)\n", fX, pScales[2*(iNumRow-1)+1], pScales[2*(iNumRow-1)]);
338
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.
340
iPointedRow = iNumRow;
341
fX = x_cumulated - 0*(fFlatDockWidth - iWidth) / 2 + (1 - fScale) * (x_abs - x_cumulated + .5*my_iSpaceBetweenRows);
342
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
343
//cd_debug (" ligne pointee : %d\n", iPointedRow);
344
pScales[2*iNumRow+1] = fX;
345
//cd_debug (" fX : %.2f\n", fX);
348
x_cumulated += iMaxIconHeight;
351
if (iPointedRow == -1) // on est en dehors du disque.
353
iPointedRow = iNbRows - 1;
355
fX = x_cumulated - (fFlatDockWidth - iWidth) / 2 + (1 - fScale) * (iMaxIconHeight + .5*my_iSpaceBetweenRows);
356
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1 - fFoldingFactor);
357
pScales[2*iNumRow+1] = fX;
358
//cd_debug (" fX : %.2f\n", fX);
361
for (iNumRow = iPointedRow-1; iNumRow >= 0; iNumRow --)
363
fX = pScales[2*(iNumRow+1)+1] - (iMaxIconHeight + my_iSpaceBetweenRows) * pScales[2*iNumRow];
364
fX = fAlign * iWidth + (fX - fAlign * iWidth) * (1. - fFoldingFactor);
365
pScales[2*iNumRow+1] = fX;
366
//cd_debug (" fX : %.2f\n", fX);
370
for (iNumRow = 0; iNumRow < iNbRows; iNumRow ++)
372
pScales[2*iNumRow+1] -= fX;
378
static Icon *cd_rendering_calculate_icons_rainbow (CairoDock *pDock)
380
if (pDock->icons == NULL)
383
//\____________________ On se place en coordonnees polaires.
384
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
385
int iMaxIconWidth = pDock->iMaxIconHeight + my_iSpaceBetweenIcons;
386
double fCone = G_PI - 2 * my_fRainbowConeOffset;
387
int iNbIcons = g_list_length (pDock->icons);
388
int iMinRadius = MIN (my_iRainbowNbIconsMin, iNbIcons) * iMaxIconWidth * fMaxScale / fCone;
389
double fRatio = pDock->container.fRatio;
390
double w = pDock->container.iWidth;
391
double h = pDock->container.iHeight;
392
double fRadius, fTheta;
393
cd_debug (" mouse : (%d ; %d)\n", pDock->container.iMouseX, pDock->container.iMouseY);
394
cd_rendering_get_polar_coords (pDock, &fRadius, &fTheta);
395
cd_debug (" polar : (%.2f ; %.2f)\n", fRadius, fTheta/G_PI*180.);
397
double fCurvilignAbscisse = (fTheta > -G_PI/2 && fTheta < G_PI/2 ? MAX (0, fRadius - iMinRadius): 0);
399
//\____________________ On en deduit ou appliquer la vague pour que la crete soit a la position du curseur.
400
Icon *pPointedIcon = NULL;
401
double fMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex) * pDock->fMagnitudeMax;
402
int x_abs = (int) round (cd_rendering_calculate_wave_position (pDock, fCurvilignAbscisse, fMagnitude));
403
cd_debug (" => x_abs : %d (fMagnitude:%.2f ; fFoldingFactor:%.2f)\n", x_abs, fMagnitude, pDock->fFoldingFactor);
405
//\_______________ On en deduit l'amplitude de chaque ligne.
406
int iNbRows = round ((pDock->iMaxDockHeight- iMinRadius) / ((pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale));
407
cd_debug ("iNbRows : %d\n", iNbRows);
408
double fFlatDockWidth = iNbRows * (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale;
409
double *pScales = g_new0 (double, 2*iNbRows+2);
410
cd_rendering_calculate_wave_on_each_lines (x_abs, pDock->iMaxIconHeight, fMagnitude, fFlatDockWidth, fFlatDockWidth, 0*pDock->fAlign, pDock->fFoldingFactor, fRatio, iNbRows, pScales);
412
//\____________________ On en deduit les position/etirements/alpha des icones.
413
Icon* icon, *prev_icon;
416
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
417
ic = pFirstDrawnElement;
418
Icon *pFirstIcon = pFirstDrawnElement->data;
420
int iNbRow = -1, iNbIconsOnRow = 0, iNbInsertedIcons = 0;
421
double fCurrentRadius=0, fNormalRadius=0, fCurrentTheta, fThetaStart=0, fDeltaTheta=0, fCurrentScale=1;
426
if (iNbInsertedIcons == iNbIconsOnRow)
429
if (iNbRow == iNbRows)
431
iNbInsertedIcons = 0;
432
fCurrentRadius = iMinRadius * (1 - pDock->fFoldingFactor) + pScales[2*iNbRow+1];
433
fCurrentScale = pScales[2*iNbRow] * (1 - pDock->fFoldingFactor);
434
fNormalRadius = iMinRadius + iNbRow * (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fMaxScale;
435
fDeltaTheta = 2 * atan (iMaxIconWidth * fMaxScale / 2 / fNormalRadius);
436
iNbIconsOnRow = (int) (fCone / fDeltaTheta);
437
fThetaStart = - G_PI/2 + my_fRainbowConeOffset + (fCone - iNbIconsOnRow * fDeltaTheta) / 2 + fDeltaTheta / 2;
438
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);
441
icon->fX = fCurrentRadius + (pDock->container.bDirectionUp ? pDock->iMaxIconHeight * fCurrentScale : 0);
443
fCurrentTheta = fThetaStart + iNbInsertedIcons * fDeltaTheta;
444
icon->fOrientation = (pDock->container.bDirectionUp ? fCurrentTheta : - fCurrentTheta);
445
if (! pDock->container.bIsHorizontal)
447
icon->fOrientation = -icon->fOrientation + 0;
449
if (pPointedIcon == NULL && fRadius < fCurrentRadius + (pDock->iMaxIconHeight + my_iSpaceBetweenRows) * fCurrentScale && fRadius > fCurrentRadius && fTheta > fCurrentTheta - fDeltaTheta/2 && fTheta < fCurrentTheta + fDeltaTheta/2)
451
icon->bPointed = TRUE;
453
cd_debug (" POINTED ICON : %s\n", pPointedIcon->cName);
456
icon->bPointed = FALSE;
458
//if (pDock->container.bIsHorizontal)
460
icon->fDrawY = icon->fX * cos (fCurrentTheta) + icon->fWidth/2 * fCurrentScale * sin (fCurrentTheta);
461
if (pDock->container.bDirectionUp)
462
icon->fDrawY = pDock->container.iHeight - icon->fDrawY;
463
icon->fDrawX = icon->fX * sin (fCurrentTheta) - icon->fWidth/2 * fCurrentScale * cos (fCurrentTheta) + pDock->container.iWidth / 2;
467
icon->fDrawX = icon->fX * cos (fCurrentTheta) + icon->fWidth/2 * fCurrentScale * sin (fCurrentTheta);
468
if (!pDock->container.bDirectionUp)
469
icon->fDrawX = pDock->container.iWidth - icon->fDrawX;
470
icon->fDrawY = icon->fX * sin (fCurrentTheta) - icon->fWidth/2 * fCurrentScale * cos (fCurrentTheta) + pDock->container.iHeight / 2;
473
cd_debug (" %.2fdeg ; (%.2f;%.2f)\n", fCurrentTheta/G_PI*180, icon->fDrawX, icon->fDrawY);
475
icon->fScale = fCurrentScale;
477
icon->fWidthFactor = 1.;
478
icon->fHeightFactor = 1.;
484
ic = cairo_dock_get_next_element (ic, pDock->icons);
485
} while (ic != pFirstDrawnElement);
488
//g_print ("fRadius : %.2f ; limite : %.2f\n", fRadius, fCurrentRadius + pDock->iMaxIconHeight * fCurrentScale);
489
if (! pDock->container.bInside ||
490
fRadius > fCurrentRadius + pDock->iMaxIconHeight * fCurrentScale + myLabels.iLabelSize - (pDock->fFoldingFactor > 0 ? 20 : 0) ||
491
(fTheta < - G_PI/2 + my_fRainbowConeOffset || fTheta > G_PI/2 - my_fRainbowConeOffset) && fRadius > iMinRadius + .5 * pDock->iMaxIconHeight * fMaxScale)
493
cd_debug ("<<< on sort du demi-disque >>>\n");
494
pDock->iMousePositionType = CAIRO_DOCK_MOUSE_OUTSIDE;
495
pDock->bCanDrop = FALSE;
499
pDock->iMousePositionType = CAIRO_DOCK_MOUSE_INSIDE;
500
if (pDock->bIsDragging)
501
pDock->bCanDrop = TRUE;
508
static void _generate_cos_sin (double fConeOffset, double fDelta, double *pTabValues)
510
int i, n = (int) ceil ((G_PI/2 - fConeOffset) / fDelta);
511
pTabValues[2*n] = 0.; // point au milieu.
512
pTabValues[2*n+1] = 1.;
515
for (i = 0; i < n; i ++)
517
fTheta = (i == 0 ? G_PI/2 - fConeOffset : (n - i) * fDelta);
518
pTabValues[2*i] = sin (fTheta);
519
pTabValues[2*i+1] = cos (fTheta);
521
pTabValues[2*(2*n-i)] = - pTabValues[2*i];
522
pTabValues[2*(2*n-i)+1] = pTabValues[2*i+1];
525
static void _generate_sector_path (double fConeOffset, double fRadius1, double fRadius2, double fDelta, double *pCosSinTab, GLfloat *pTabValues)
527
int i, n = (int) ceil ((G_PI/2 - fConeOffset) / fDelta), N = (2*n+1) * 2;
528
for (i = 0; i < 2*n+1; i ++)
530
pTabValues[3*(2*i)] = fRadius1 * pCosSinTab[2*i+0];
531
pTabValues[3*(2*i)+1] = fRadius1 * pCosSinTab[2*i+1];
532
pTabValues[3*(2*i+1)] = fRadius2 * pCosSinTab[2*i+0];
533
pTabValues[3*(2*i+1)+1] = fRadius2 * pCosSinTab[2*i+1];
534
//g_print ("%.2f;%.2f\n", pTabValues[3*i], pTabValues[3*i+1]);
536
pTabValues[3*N] = pTabValues[3*0];
537
pTabValues[3*N+1] = pTabValues[3*0+1];
538
pTabValues[3*(N+1)] = pTabValues[3*1];
539
pTabValues[3*(N+1)+1] = pTabValues[3*1+1];
542
static void cd_rendering_render_rainbow_opengl (CairoDock *pDock)
544
static double fDelta = 1.;
545
int n = ceil (180./fDelta+1) + 1; // nb points max, +1 for safety with rounded calculations.
546
if (pCosSinTab == NULL)
548
pCosSinTab = g_new0 (double, n * 2);
549
_generate_cos_sin (my_fRainbowConeOffset, fDelta/180.*G_PI, pCosSinTab);
551
if (pVertexTab == NULL)
552
pVertexTab = g_new0 (GLfloat, (n * 2) * 3);
553
if (pColorTab == NULL)
555
pColorTab = g_new0 (GLfloat, (n * 2) * 4);
557
for (i = 0; i < n; i ++)
559
pColorTab[4*2*i+0] = my_fRainbowColor[0];
560
pColorTab[4*2*i+1] = my_fRainbowColor[1];
561
pColorTab[4*2*i+2] = my_fRainbowColor[2];
562
pColorTab[4*2*i+3] = my_fRainbowColor[3];
566
double fMaxScale = 1. + my_fRainbowMagnitude * g_fAmplitude;
568
if (my_fRainbowColor[3] != 0 && pDock->icons != NULL)
570
//\____________________ On trace le cadre.
571
//\____________________ On dessine les decorations dedans.
572
glEnable (GL_LINE_SMOOTH);
573
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
574
///_cairo_dock_set_blend_alpha (); // qqch cloche ...
575
_cairo_dock_set_blend_over ();
578
glPolygonMode(GL_FRONT, GL_FILL); // GL_FILL
579
glEnableClientState(GL_VERTEX_ARRAY);
580
glEnableClientState(GL_COLOR_ARRAY);
583
int n = (int) ceil ((G_PI/2 - my_fRainbowConeOffset) / (fDelta/180.*G_PI)), N = (2*n+1) * 2;
586
if (! pDock->container.bIsHorizontal)
588
glTranslatef (pDock->container.iHeight/2, pDock->container.iWidth/2, 0.);
589
glRotatef (90., 0., 0., 1.);
590
glTranslatef (0., -pDock->container.iHeight/2, 0.);
593
glTranslatef (pDock->container.iWidth/2, 0., 0.);
594
if (!pDock->container.bDirectionUp)
596
glTranslatef (0., pDock->container.iHeight, 0.);
597
glScalef (1., -1., 1.);
600
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
601
GList *ic = pFirstDrawnElement;
602
Icon *pFirstIcon = pFirstDrawnElement->data;
603
double fCurrentRadius=0;
610
fRadius = icon->fX - (pDock->container.bDirectionUp ? pDock->iMaxIconHeight * icon->fScale : 0);
611
if (fRadius != fCurrentRadius)
613
_generate_sector_path (my_fRainbowConeOffset,
614
fRadius + .5 * pDock->iMaxIconHeight * fMaxScale,
615
fRadius - my_iSpaceBetweenRows/2,
616
fDelta/180.*G_PI, pCosSinTab, pVertexTab);
618
glVertexPointer(3, GL_FLOAT, 0, pVertexTab);
619
glColorPointer(4, GL_FLOAT, 0, pColorTab);
620
glDrawArrays(GL_QUAD_STRIP, 0, N);
622
_generate_sector_path (my_fRainbowConeOffset,
623
fRadius + .5 * pDock->iMaxIconHeight * fMaxScale,
624
fRadius + pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2,
625
fDelta/180.*G_PI, pCosSinTab, pVertexTab);
627
glVertexPointer(3, GL_FLOAT, 0, pVertexTab);
628
glColorPointer(4, GL_FLOAT, 0, pColorTab);
629
glDrawArrays(GL_QUAD_STRIP, 0, N);
631
fCurrentRadius = fRadius;
633
ic = cairo_dock_get_next_element (ic, pDock->icons);
634
} while (ic != pFirstDrawnElement);
637
glDisableClientState(GL_VERTEX_ARRAY);
638
glDisableClientState(GL_COLOR_ARRAY);
639
glDisable(GL_POLYGON_SMOOTH);
643
//\____________________ On dessine le cadre.
646
Icon *icon = cairo_dock_get_last_drawn_icon (pDock);
648
fRadius = icon->fX - (pDock->container.bDirectionUp ? pDock->iMaxIconHeight * fMaxScale : 0);
650
fRadius += .5 * pDock->iMaxIconHeight * fMaxScale;
651
if (my_fRainbowLineColor[3] != 0)
654
if (! pDock->container.bIsHorizontal)
656
glTranslatef (pDock->container.iHeight/2, pDock->container.iWidth/2, 0.);
657
glRotatef (90., 0., 0., 1.);
658
glTranslatef (0., -pDock->container.iHeight/2, 0.);
661
glTranslatef (pDock->container.iWidth/2, 0., 0.);
662
if (!pDock->container.bDirectionUp)
664
glTranslatef (0., pDock->container.iHeight, 0.);
665
glScalef (1., -1., 1.);
667
GLfloat color[4*5] = {my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], 0.,
668
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], my_fRainbowLineColor[3],
669
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], my_fRainbowLineColor[3],
670
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], my_fRainbowLineColor[3],
671
my_fRainbowLineColor[0], my_fRainbowLineColor[1], my_fRainbowLineColor[2], 0.};
672
glEnableClientState(GL_COLOR_ARRAY);
673
glColorPointer(4, GL_FLOAT, 0, color);
674
glVertexPointer(2, GL_FLOAT, 0, pVertexTab);
676
pVertexTab[2*0+0] = - (fRadius + .5 * pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2) * pCosSinTab[2*0];
677
pVertexTab[2*0+1] = (fRadius + .5 * pDock->iMaxIconHeight * fMaxScale + my_iSpaceBetweenRows/2) * pCosSinTab[2*0+1];
678
pVertexTab[2*1+0] = - fRadius * cos (my_fRainbowConeOffset);
679
pVertexTab[2*1+1] = fRadius * sin (my_fRainbowConeOffset);
680
pVertexTab[2*2+0] = 0.;
681
pVertexTab[2*2+1] = 0.;
682
pVertexTab[2*3+0] = - pVertexTab[2*1+0];
683
pVertexTab[2*3+1] = pVertexTab[2*1+1];
684
pVertexTab[2*4+0] = - pVertexTab[2*0+0];
685
pVertexTab[2*4+1] = pVertexTab[2*0+1];
687
cairo_dock_draw_current_path_opengl (myBackground.iDockLineWidth, my_fRainbowLineColor, 5);
689
glDisableClientState(GL_COLOR_ARRAY);
693
//\____________________ On dessine les icones.
694
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
695
if (pFirstDrawnElement == NULL)
698
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex)/** * pDock->fMagnitudeMax*/;
700
int iWidth = pDock->container.iWidth;
701
gboolean bIsHorizontal = pDock->container.bIsHorizontal;
702
GList *ic = pFirstDrawnElement;
708
cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE); // ! mySystem.bTextAlwaysHorizontal
711
ic = cairo_dock_get_next_element (ic, pDock->icons);
712
} while (ic != pFirstDrawnElement);
717
void cd_rendering_reload_rainbow_buffers (void)
728
void cd_rendering_register_rainbow_renderer (const gchar *cRendererName)
730
CairoDockRenderer *pRenderer = g_new0 (CairoDockRenderer, 1);
732
pRenderer->compute_size = cd_rendering_calculate_max_dock_size_rainbow;
733
pRenderer->calculate_icons = cd_rendering_calculate_icons_rainbow;
734
pRenderer->render = cd_rendering_render_rainbow;
735
pRenderer->render_optimized = NULL;
736
pRenderer->render_opengl = cd_rendering_render_rainbow_opengl;
737
pRenderer->set_subdock_position = cairo_dock_set_subdock_position_linear;
739
pRenderer->cDisplayedName = D_ (cRendererName);
740
pRenderer->cReadmeFilePath = g_strdup (MY_APPLET_SHARE_DATA_DIR"/readme-rainbow-view");
741
pRenderer->cPreviewFilePath = g_strdup (MY_APPLET_SHARE_DATA_DIR"/preview-rainbow.jpg");
743
cairo_dock_register_renderer (cRendererName, pRenderer);