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
This rendering has been written by parAdOxxx_ZeRo (http://paradoxxx.zero.free.fr)
30
******************************************************************************/
40
#include "rendering-commons.h"
41
#include "rendering-curve.h"
42
#include "rendering-3D-plane.h"
45
static double *s_pReferenceCurveS = NULL;
46
static double *s_pReferenceCurveX = NULL;
47
static double *s_pReferenceCurveY = NULL;
48
int iVanishingPointY = 200;
50
extern cairo_surface_t *my_pFlatSeparatorSurface[2];
52
extern CDSpeparatorType my_curve_iDrawSeparator3D;
54
extern gdouble my_fCurveCurvature;
55
extern gint my_iCurveAmplitude;
57
//const guint curveOffsetX = 75;
58
// OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
59
// Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
61
#define xCurve(a, t) (t * (t * t + 1.5 * (1 - t) * (1 - a + 2 * a * t)))
62
#define yCurve(t) (3 * t * (1 - t))
63
#define XCurve(W, a, t) (W * xCurve (a, t))
64
#define YCurve(h, t) (h * yCurve (t))
66
void cd_rendering_calculate_max_dock_size_curve (CairoDock *pDock)
68
static double fCurveCurvature= 0;
69
if (s_pReferenceCurveS == NULL || my_fCurveCurvature != fCurveCurvature)
71
fCurveCurvature = my_fCurveCurvature;
72
cd_rendering_calculate_reference_curve (my_fCurveCurvature);
75
pDock->pFirstDrawnElement = cairo_dock_calculate_icons_positions_at_rest_linear (pDock->icons, pDock->fFlatDockWidth, pDock->iScrollOffset);
77
pDock->iDecorationsHeight = myBackground.iFrameMargin + my_iCurveAmplitude + .5 * pDock->iMaxIconHeight; // de bas en haut.
79
pDock->iMaxDockWidth = ceil (cairo_dock_calculate_max_dock_width (pDock, pDock->pFirstDrawnElement, pDock->fFlatDockWidth, 1., 0.)); // etendue max des icones, sans le cadre.
80
//g_print ("iMaxDockWidth : %d\n", pDock->iMaxDockWidth);
82
double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth); // hauteur de controle de la courbe de Bezier, de telle facon qu'elle atteigne 'iDecorationsHeight'.
83
double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1; // hauteur de la courbe a la 1ere icone.
84
double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0.01)));
85
double xi = xCurve (my_fCurveCurvature, ti);
86
double fDeltaX = pDock->iMaxDockWidth * xi / (1 - 2 * xi); // abscisse de la 1ere icone pour satisfaire a la contrainte y=hi.
87
//g_print ("ti = %.2f => xi = %.2f => fDeltaX = %.2f\n", ti, xi, fDeltaX);
88
//g_print ("my_fCurveCurvature:%.2f\n", my_fCurveCurvature);
89
pDock->iMaxDockWidth += 2*fDeltaX;
90
double tan_theta = (my_fCurveCurvature != 1 ? h / ((1 - my_fCurveCurvature) * pDock->iMaxDockWidth / 2) : 1e6); // la tangente a une courbe de Bezier en son origine est la droite reliant les deux premiers points de controle.
91
double fDeltaTip = .5 * myBackground.iDockLineWidth * sqrt (1 + tan_theta * tan_theta) / tan_theta; // prolongement de la pointe.
92
pDock->iMaxDockWidth += 2 * fDeltaTip;
93
pDock->iMaxDockWidth = ceil (cairo_dock_calculate_max_dock_width (pDock, pDock->pFirstDrawnElement, pDock->fFlatDockWidth, 1., 2*(fDeltaX+fDeltaTip)));
94
//g_print ("fDeltaTip : %.2f\n", fDeltaTip);
96
pDock->iMaxDockHeight = myBackground.iDockLineWidth + myBackground.iFrameMargin + my_iCurveAmplitude + (1 + g_fAmplitude) * pDock->iMaxIconHeight + myLabels.iLabelSize; // de bas en haut.
98
pDock->iDecorationsWidth = pDock->iMaxDockWidth - 4 * fDeltaTip;
100
pDock->iMinDockWidth = pDock->fFlatDockWidth / (1 - 2 * xi) + 2 * fDeltaTip;
101
//g_print ("pDock->fFlatDockWidth = %.2f => pDock->iMinDockWidth = %d\n", pDock->fFlatDockWidth, pDock->iMinDockWidth);
103
pDock->iMinDockHeight = myBackground.iDockLineWidth + myBackground.iFrameMargin + my_iCurveAmplitude + pDock->iMaxIconHeight; // de bas en haut.
105
if (my_pFlatSeparatorSurface[0] == NULL && (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR))
106
cd_rendering_load_flat_separator (CAIRO_CONTAINER (g_pMainDock));
108
pDock->inputArea.x = fDeltaX+fDeltaTip;
109
pDock->inputArea.y = 0;
110
pDock->inputArea.width = pDock->iMinDockWidth - 2 * (fDeltaX+fDeltaTip);
111
pDock->inputArea.height = pDock->iMinDockHeight;
115
static void cd_rendering_make_3D_curve_separator (Icon *icon, cairo_t *pCairoContext, CairoDock *pDock, gboolean bIncludeEdges, gboolean bBackGround)
117
double fLineWidth = myBackground.iDockLineWidth;
118
double fMargin = myBackground.iFrameMargin;
121
Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
122
if (pPrevIcon == NULL)
124
Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
125
if (pNextIcon == NULL)
128
double fVanishingDistanceLeft, fVanishingDistanceRight;
129
double fDeltaInterIconLeft, fDeltaInterIconRight;
130
if (pDock->bDirectionUp)
132
hi = pDock->iCurrentHeight - (icon->fDrawY + icon->fHeight * icon->fScale);
133
fVanishingDistanceLeft = iVanishingPointY + pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale;
134
fVanishingDistanceRight = iVanishingPointY + pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale;
136
fDeltaInterIconLeft = (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale) - (icon->fDrawY + icon->fHeight * icon->fScale);
137
fDeltaInterIconRight = (icon->fDrawY + icon->fHeight * icon->fScale) - (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale);
142
fVanishingDistanceLeft = iVanishingPointY + pDock->iCurrentHeight - pPrevIcon->fDrawY;
143
fVanishingDistanceRight = iVanishingPointY + pDock->iCurrentHeight - pNextIcon->fDrawY;
145
fDeltaInterIconLeft = (pPrevIcon->fDrawY) - (icon->fDrawY);
146
fDeltaInterIconRight = (icon->fDrawY) - (pNextIcon->fDrawY);
148
double fLeftInclination = (icon->fDrawX - pDock->iCurrentWidth / 2) / fVanishingDistanceLeft;
149
double fRightInclination = (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / fVanishingDistanceRight;
151
if (bBackGround || ! bIncludeEdges) // pour s'arreter sur la courbe, on realise un clippage.
153
//\________________ On se ramene au cas du dessin optimise.
154
double x0, y0, xf, yf, w0, h0;
155
if (pDock->bDirectionUp)
157
x0 = icon->fDrawX - MAX (0, fLeftInclination * (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale));
158
xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale));
162
x0 = icon->fDrawX - MAX (0, fLeftInclination * (pDock->iCurrentHeight - (pPrevIcon->fDrawY)));
163
xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pDock->iCurrentHeight - (pNextIcon->fDrawY)));
165
if (! bIncludeEdges) // on prolonge jusqu'en bas.
167
if (pDock->bDirectionUp)
169
x0 += MIN (0, fLeftInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
170
xf += MAX (0, fRightInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
174
x0 += MIN (0, fLeftInclination * (pPrevIcon->fDrawY));
175
xf += MAX (0, fRightInclination * (pNextIcon->fDrawY));
178
//g_print ("x0:%.2f -> xf:%.2f\n", x0, xf);
185
double fDockOffsetY; // Offset du coin haut gauche du cadre.
186
if (pDock->bDirectionUp)
189
fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
194
fDockOffsetY = .5 * fLineWidth;
197
double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
199
double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
200
double hi_ = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
201
double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi_ / h, 0)));
202
double xi = xCurve (my_fCurveCurvature, ti);
203
double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
205
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
206
double fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fDrawX - curveOffsetX : fLineWidth / 2);
209
//\________________ On approche le morceau de courbe de Bezier par des trapezes.
210
double x = (x0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
211
double s = cd_rendering_interpol_curve_parameter (x);
212
double y = yCurve (s);
213
double x_ = (x0 + w0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
214
double s_ = cd_rendering_interpol_curve_parameter (x_);
215
double y_ = yCurve (s_);
216
int i, iNbMidPoints = MAX (0, w0 / 20 - 1); // nombre de points intermediaires a calculer.
217
double *pMidPointCoord = g_new (double, 2 * (iNbMidPoints+2));
218
pMidPointCoord[0] = x0 - fDockOffsetX;
219
pMidPointCoord[1] = y * h;
220
pMidPointCoord[2*(iNbMidPoints+1)] = x0 + w0 - fDockOffsetX;
221
pMidPointCoord[2*(iNbMidPoints+1)+1] = y_ * h;
222
double si=s, ds = (s_ - s) / (iNbMidPoints+1);
223
for (i = 1; i < iNbMidPoints+1; i ++)
226
pMidPointCoord[2*i] = (fDockWidth + 2 * curveOffsetX) * xCurve (my_fCurveCurvature, si);
227
pMidPointCoord[2*i+1] = h * yCurve (si);
230
cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
231
cairo_save (pCairoContext);
232
double fDeltaLineWidth = 0.;
235
double tan_theta = MAX (fabs (pMidPointCoord[1] - pMidPointCoord[3]) / (pMidPointCoord[2] - pMidPointCoord[0]), fabs (pMidPointCoord[2*iNbMidPoints+1] - pMidPointCoord[2*iNbMidPoints+3]) / (pMidPointCoord[2*iNbMidPoints+2] - pMidPointCoord[2*iNbMidPoints]));
236
fDeltaLineWidth = (fLineWidth / 2 + .1) * sqrt (1. + tan_theta*tan_theta);
238
if (pDock->bHorizontalDock)
240
cairo_move_to (pCairoContext, x0, fDockOffsetY - sens * (y * h + fDeltaLineWidth));
241
for (i = 0; i < iNbMidPoints+1; i ++)
242
cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
243
cairo_rel_line_to (pCairoContext, 0, sens * (y_ * h + fDeltaLineWidth));
244
cairo_rel_line_to (pCairoContext, - w0, 0);
245
cairo_rel_line_to (pCairoContext, 0, - sens * (y * h + fDeltaLineWidth));
249
cairo_move_to (pCairoContext, fDockOffsetY - sens * (y * h + fDeltaLineWidth), x0);
250
for (i = 0; i < iNbMidPoints+1; i ++)
251
cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
252
cairo_rel_line_to (pCairoContext, sens * (y_ * h + fDeltaLineWidth), 0);
253
cairo_rel_line_to (pCairoContext, 0, - w0);
254
cairo_rel_line_to (pCairoContext, - sens * (y * h + fDeltaLineWidth), 0);
257
g_free (pMidPointCoord);
258
cairo_clip (pCairoContext);
262
double fHeight, fBigWidth, fLittleWidth;
265
fHeight = (bBackGround ? pDock->iDecorationsHeight - hi : hi) + myBackground.iDockLineWidth;
266
fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
267
fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
271
fHeight = pDock->iDecorationsHeight - myBackground.iDockLineWidth;
272
fBigWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi);
273
fLittleWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi - fHeight);
275
double fDeltaXLeft = fHeight * fLeftInclination;
276
double fDeltaXRight = fHeight * fRightInclination;
277
//g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
280
double fDockOffsetX, fDockOffsetY;
281
if (pDock->bDirectionUp)
285
fDockOffsetY = pDock->iCurrentHeight - fHeight - (bBackGround ? myBackground.iDockLineWidth + hi : 0);
287
fDockOffsetY = pDock->iCurrentHeight - fHeight - myBackground.iDockLineWidth;
293
fDockOffsetY = fHeight + (bBackGround ? myBackground.iDockLineWidth + hi : 0);
295
fDockOffsetY = fHeight + myBackground.iDockLineWidth;
299
fDockOffsetX = icon->fDrawX - (bBackGround ? fHeight * fLeftInclination : 0);
301
fDockOffsetX = (pDock->bDirectionUp ? icon->fDrawX - (fHeight - hi) * fLeftInclination : icon->fDrawX - (fHeight - hi) * fLeftInclination);
302
fDockOffsetX -= fDeltaInterIconLeft * fLeftInclination*sens;
304
if (pDock->bHorizontalDock)
306
cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY); // coin haut gauche.
307
cairo_move_to (pCairoContext, 0, 0); // coin haut gauche.
309
cairo_rel_line_to (pCairoContext, fLittleWidth, 0);
310
cairo_rel_line_to (pCairoContext, fDeltaXRight, sens * fHeight);
311
cairo_rel_line_to (pCairoContext, - fBigWidth, 0);
312
cairo_rel_line_to (pCairoContext, - fDeltaXLeft, - sens * fHeight);
314
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
316
if (! pDock->bDirectionUp)
317
cairo_scale (pCairoContext, 1, -1);
318
cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_HORIZONTAL], MIN (0, (fHeight + hi) * fLeftInclination), 0);
323
cairo_translate (pCairoContext, fDockOffsetY, fDockOffsetX); // coin haut gauche.
324
cairo_move_to (pCairoContext, 0, 0); // coin haut gauche.
326
cairo_rel_line_to (pCairoContext, 0, fLittleWidth);
327
cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXRight);
328
cairo_rel_line_to (pCairoContext, 0, - fBigWidth);
329
cairo_rel_line_to (pCairoContext, - sens * fHeight, - fDeltaXLeft);
331
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
333
if (! pDock->bDirectionUp)
334
cairo_scale (pCairoContext, -1, 1);
335
cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_VERTICAL], 0, MIN (0, (fHeight + hi) * fLeftInclination));
340
static void cd_rendering_draw_3D_curve_separator_edge (Icon *icon, cairo_t *pCairoContext, CairoDock *pDock, gboolean bBackGround)
342
Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
343
if (pPrevIcon == NULL)
345
Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
346
if (pNextIcon == NULL)
349
double hi, fVanishingDistanceLeft, fVanishingDistanceRight;
350
if (pDock->bDirectionUp)
352
hi = pDock->iCurrentHeight - (icon->fDrawY + icon->fHeight * icon->fScale);
353
fVanishingDistanceLeft = iVanishingPointY + pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale;
354
fVanishingDistanceRight = iVanishingPointY + pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale;
359
fVanishingDistanceLeft = iVanishingPointY + pDock->iCurrentHeight - pPrevIcon->fDrawY;
360
fVanishingDistanceRight = iVanishingPointY + pDock->iCurrentHeight - pNextIcon->fDrawY;
362
double fLeftInclination = (icon->fDrawX - pDock->iCurrentWidth / 2) / fVanishingDistanceLeft;
363
double fRightInclination = (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / fVanishingDistanceRight;
366
double fHeight, fBigWidth, fLittleWidth;
367
fHeight = (bBackGround ? pDock->iDecorationsHeight - hi - 0.5*myBackground.iDockLineWidth : hi + 1.5*myBackground.iDockLineWidth);
368
fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
369
fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
371
double fDeltaXLeft = fHeight * fLeftInclination;
372
double fDeltaXRight = fHeight * fRightInclination;
373
//g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
376
double fDockOffsetX, fDockOffsetY;
377
if (pDock->bDirectionUp)
380
fDockOffsetY = (bBackGround ? 0.5*myBackground.iDockLineWidth : - 1.*myBackground.iDockLineWidth);
385
fDockOffsetY = (bBackGround ? - 0.5*myBackground.iDockLineWidth : 1.*myBackground.iDockLineWidth);
387
fDockOffsetX = (bBackGround ? .5*myBackground.iDockLineWidth * fLeftInclination + 1.*fLeftInclination : - 0.5 * myBackground.iDockLineWidth * fLeftInclination);
388
//fDockOffsetX = -.5*myBackground.iDockLineWidth;
390
if (pDock->bHorizontalDock)
392
cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY); // coin haut droit.
394
cairo_move_to (pCairoContext, fLittleWidth, 0);
395
cairo_rel_line_to (pCairoContext, fDeltaXRight, sens * fHeight);
397
cairo_move_to (pCairoContext, 0, 0);
398
cairo_rel_line_to (pCairoContext, fDeltaXLeft, sens * fHeight);
402
cairo_translate (pCairoContext, fDockOffsetY, fDockOffsetX); // coin haut droit.
404
cairo_move_to (pCairoContext, 0, fLittleWidth);
405
cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXRight);
407
cairo_move_to (pCairoContext, 0, 0);
408
cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXLeft);
413
static void cd_rendering_draw_3D_curve_separator (Icon *icon, cairo_t *pCairoContext, CairoDock *pDock, gboolean bHorizontal, gboolean bBackGround)
415
cd_rendering_make_3D_curve_separator (icon, pCairoContext, pDock, (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR), bBackGround);
417
if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
419
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_DEST_OUT);
420
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 1.0);
421
cairo_fill (pCairoContext);
423
cd_rendering_draw_3D_curve_separator_edge (icon, pCairoContext, pDock, bBackGround);
425
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
426
cairo_set_line_width (pCairoContext, myBackground.iDockLineWidth);
427
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
428
cairo_stroke (pCairoContext);
432
cairo_fill (pCairoContext);
438
void cd_rendering_render_curve (cairo_t *pCairoContext, CairoDock *pDock)
440
//\____________________ On trace le cadre.
441
double fLineWidth = myBackground.iDockLineWidth;
442
double fMargin = myBackground.iFrameMargin;
443
double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
445
double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
446
double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
447
double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
448
double xi = xCurve (my_fCurveCurvature, ti);
449
double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
452
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
453
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
454
fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fDrawX - curveOffsetX : fLineWidth / 2);
455
if (pDock->bDirectionUp)
458
fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
463
fDockOffsetY = .5 * fLineWidth;
466
cairo_save (pCairoContext);
468
cairo_dock_draw_curved_frame (pCairoContext, fDockWidth + 2 * curveOffsetX, h, fDockOffsetX, fDockOffsetY, pDock->bHorizontalDock, sens);
470
//\____________________ On dessine les decorations dedans.
471
fDockOffsetY = (pDock->bDirectionUp ? pDock->iCurrentHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
472
cairo_dock_render_decorations_in_frame (pCairoContext, pDock, fDockOffsetY, fDockOffsetX, fDockWidth + 2 * curveOffsetX);
474
//\____________________ On dessine le cadre.
477
cairo_set_line_width (pCairoContext, fLineWidth);
478
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
479
cairo_stroke (pCairoContext);
482
cairo_new_path (pCairoContext);
483
cairo_restore (pCairoContext);
485
//\____________________ On dessine la ficelle qui les joint.
486
if (myIcons.iStringLineWidth > 0)
487
cairo_dock_draw_string (pCairoContext, pDock, myIcons.iStringLineWidth, FALSE, (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR));
489
//\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan.
490
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
491
if (pFirstDrawnElement == NULL)
494
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
496
GList *ic = pFirstDrawnElement;
498
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
500
cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
505
if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
507
cairo_save (pCairoContext);
508
cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, TRUE);
509
cairo_restore (pCairoContext);
512
ic = cairo_dock_get_next_element (ic, pDock->icons);
513
} while (ic != pFirstDrawnElement);
519
if (icon->acFileName != NULL || ! CAIRO_DOCK_IS_SEPARATOR (icon))
521
cairo_save (pCairoContext);
522
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
523
cairo_restore (pCairoContext);
526
ic = cairo_dock_get_next_element (ic, pDock->icons);
527
} while (ic != pFirstDrawnElement);
529
if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
535
if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
537
cairo_save (pCairoContext);
538
cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, FALSE);
539
cairo_restore (pCairoContext);
542
ic = cairo_dock_get_next_element (ic, pDock->icons);
543
} while (ic != pFirstDrawnElement);
552
cairo_save (pCairoContext);
553
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
554
cairo_restore (pCairoContext);
556
ic = cairo_dock_get_next_element (ic, pDock->icons);
557
} while (ic != pFirstDrawnElement);
563
static gboolean _cd_separator_is_impacted (Icon *icon, CairoDock *pDock, double fXMin, double fXMax, gboolean bBackGround, gboolean bIncludeEdges)
565
double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
566
double fLeftInclination = fabs (icon->fDrawX - pDock->iCurrentWidth / 2) / iVanishingPointY;
567
double fRightInclination = fabs (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / iVanishingPointY;
569
double fHeight, fBigWidth, fLittleWidth;
572
fHeight = (bBackGround ? pDock->iDecorationsHeight - hi : hi) + (bIncludeEdges ? myBackground.iDockLineWidth : 0);
573
fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
574
fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
578
fHeight = pDock->iDecorationsHeight;
579
fBigWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + fHeight);
580
fLittleWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY - fHeight);
582
double fDeltaXLeft = fHeight * fLeftInclination;
583
double fDeltaXRight = fHeight * fRightInclination;
584
double fDeltaX = MAX (fDeltaXLeft, fDeltaXRight);
585
//g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
588
double fDockOffsetX, fDockOffsetY;
589
if (pDock->bDirectionUp)
593
fDockOffsetY = pDock->iCurrentHeight - fHeight - (bBackGround ? myBackground.iDockLineWidth + hi : 0);
595
fDockOffsetY = pDock->iCurrentHeight - fHeight;
601
fDockOffsetY = fHeight + (bBackGround ? myBackground.iDockLineWidth + hi : 0);
603
fDockOffsetY = fHeight;
607
fDockOffsetX = icon->fDrawX - (bBackGround ? fHeight * fLeftInclination : 0);
609
fDockOffsetX = icon->fDrawX - (fHeight - hi) * fLeftInclination;
610
double fXLeft, fXRight;
611
if (icon->fDrawX + icon->fWidth * icon->fScale / 2 > pDock->iCurrentWidth / 2) // on est a droite.
617
fXLeft = icon->fDrawX - fHeight * fLeftInclination;
618
fXRight = icon->fDrawX + icon->fWidth * icon->fScale;
622
fXLeft = icon->fDrawX;
623
fXRight = icon->fDrawX + icon->fWidth * icon->fScale + fHeight * fRightInclination;
628
fXLeft = icon->fDrawX - (fHeight - hi) * fLeftInclination;
629
fXRight = icon->fDrawX + icon->fWidth * icon->fScale + hi * fRightInclination;
638
fXLeft = icon->fDrawX;
639
fXRight = icon->fDrawX + icon->fWidth * icon->fScale + fHeight * fRightInclination;
643
fXLeft = icon->fDrawX - fHeight * fLeftInclination;
644
fXRight = icon->fDrawX + icon->fWidth * icon->fScale;
649
fXLeft = icon->fDrawX - hi * fLeftInclination;
650
fXRight = icon->fDrawX + icon->fWidth * icon->fScale +(fHeight - hi) * fRightInclination;
654
return (fXLeft <= fXMax && floor (fXRight) > fXMin);
657
void cd_rendering_render_optimized_curve (cairo_t *pCairoContext, CairoDock *pDock, GdkRectangle *pArea)
659
//\____________________ On trace le cadre.
660
double fLineWidth = myBackground.iDockLineWidth;
661
double fMargin = myBackground.iFrameMargin;
662
double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
664
double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
665
double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
666
double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
667
double xi = xCurve (my_fCurveCurvature, ti);
668
double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
671
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
672
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
673
fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - curveOffsetX : fLineWidth / 2);
675
if (pDock->bHorizontalDock)
690
if (pDock->bDirectionUp)
693
fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
698
fDockOffsetY = .5 * fLineWidth;
701
//\________________ On approche le morceau de courbe de Bezier par des trapezes.
702
double x = (x0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
703
double s = cd_rendering_interpol_curve_parameter (x);
704
double y = yCurve (s);
705
double x_ = (x0 + w0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
706
double s_ = cd_rendering_interpol_curve_parameter (x_);
707
double y_ = yCurve (s_);
708
int i, iNbMidPoints = MAX (0, w0 / 20 - 1); // nombre de points intermediaires a calculer.
709
double *pMidPointCoord = g_new (double, 2 * (iNbMidPoints+2));
710
pMidPointCoord[0] = x0 - fDockOffsetX;
711
pMidPointCoord[1] = y * h;
712
pMidPointCoord[2*(iNbMidPoints+1)] = x0 + w0 - fDockOffsetX;
713
pMidPointCoord[2*(iNbMidPoints+1)+1] = y_ * h;
714
double si=s, ds = (s_ - s) / (iNbMidPoints+1);
715
for (i = 1; i < iNbMidPoints+1; i ++)
718
pMidPointCoord[2*i] = (fDockWidth + 2 * curveOffsetX) * xCurve (my_fCurveCurvature, si);
719
pMidPointCoord[2*i+1] = h * yCurve (si);
722
cairo_save (pCairoContext);
723
if (pDock->bHorizontalDock)
725
cairo_move_to (pCairoContext, pArea->x, fDockOffsetY - sens * y * h);
726
for (i = 0; i < iNbMidPoints+1; i ++)
727
cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
728
cairo_rel_line_to (pCairoContext, 0, sens * y_ * h);
729
cairo_rel_line_to (pCairoContext, - pArea->width, 0);
730
cairo_rel_line_to (pCairoContext, 0, - sens * y * h);
734
cairo_move_to (pCairoContext, fDockOffsetY - sens * y * h, pArea->y);
735
for (i = 0; i < iNbMidPoints+1; i ++)
736
cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
737
cairo_rel_line_to (pCairoContext, sens * y_ * h, 0);
738
cairo_rel_line_to (pCairoContext, 0, - pArea->height);
739
cairo_rel_line_to (pCairoContext, - sens * y * h, 0);
741
//\____________________ On dessine les decorations dedans.
742
fDockOffsetY = (pDock->bDirectionUp ? pDock->iCurrentHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
743
cairo_dock_render_decorations_in_frame (pCairoContext, pDock, fDockOffsetY, fDockOffsetX, fDockWidth + 2 * curveOffsetX);
745
//\____________________ On dessine le cadre.
746
cairo_new_path (pCairoContext);
749
cairo_set_line_width (pCairoContext, fLineWidth);
750
cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
752
fDockOffsetY = (pDock->bDirectionUp ? pDock->iCurrentHeight - .5 * fLineWidth : .5 * fLineWidth);
754
if (pDock->bHorizontalDock)
756
cairo_move_to (pCairoContext, pArea->x, fDockOffsetY - sens * y * h);
757
for (i = 0; i < iNbMidPoints+1; i ++)
758
cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
759
cairo_stroke (pCairoContext);
761
cairo_new_path (pCairoContext);
762
cairo_move_to (pCairoContext, pArea->x, fDockOffsetY);
763
cairo_rel_line_to (pCairoContext, pArea->width, 0);
767
cairo_move_to (pCairoContext, fDockOffsetY - sens * y * h, pArea->y);
768
for (i = 0; i < iNbMidPoints+1; i ++)
769
cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
770
cairo_stroke (pCairoContext);
772
cairo_new_path (pCairoContext);
773
cairo_move_to (pCairoContext, fDockOffsetY, pArea->y);
774
cairo_rel_line_to (pCairoContext, 0, pArea->height);
776
cairo_stroke (pCairoContext);
778
g_free (pMidPointCoord);
780
cairo_restore (pCairoContext);
782
/*double x = (fDockOffsetX - pFirstIcon->fX + curveOffsetX) / (fDockWidth + 2 * curveOffsetX);
784
double b = (1 - my_fCurveCurvature) / 3 / (1 - 3 * my_fCurveCurvature);
785
double c = - x / (1 - 3 * my_fCurveCurvature);
788
double c_ = b*b - a*c;
789
double u = (-b_ + sqrt (b_*b_ - 4 * a_ * c_)) / (2 * a_);
790
double v = (-b_ - sqrt (b_*b_ - 4 * a_ * c_)) / (2 * a_);
791
double lambda = - (a + u) / (a + v);
792
double t = v + (u - v) / (1 + pow (lambda, 1./3));
793
//g_print ("x : %.2f => t : %.2f\n", x, t);*/
795
//\____________________ On dessine les icones impactees.
796
GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
797
if (pFirstDrawnElement != NULL)
799
double fXMin = (pDock->bHorizontalDock ? pArea->x : pArea->y), fXMax = (pDock->bHorizontalDock ? pArea->x + pArea->width : pArea->y + pArea->height);
800
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
801
double fXLeft, fXRight;
803
GList *ic = pFirstDrawnElement;
805
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
807
cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
812
if (CAIRO_DOCK_IS_SEPARATOR (icon) && icon->acFileName == NULL)
814
if (_cd_separator_is_impacted (icon, pDock, fXMin, fXMax, TRUE, (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)))
816
cairo_save (pCairoContext);
817
cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, TRUE);
818
cairo_restore (pCairoContext);
822
ic = cairo_dock_get_next_element (ic, pDock->icons);
823
} while (ic != pFirstDrawnElement);
828
if (! CAIRO_DOCK_IS_SEPARATOR (icon) || icon->acFileName != NULL)
830
fXLeft = icon->fDrawX + icon->fScale + 1;
831
fXRight = icon->fDrawX + (icon->fWidth - 1) * icon->fScale * icon->fWidthFactor - 1;
833
if (fXLeft <= fXMax && floor (fXRight) > fXMin)
835
if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth)
840
cairo_save (pCairoContext);
842
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
844
cairo_restore (pCairoContext);
847
ic = cairo_dock_get_next_element (ic, pDock->icons);
848
} while (ic != pFirstDrawnElement);
850
if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
856
if (CAIRO_DOCK_IS_SEPARATOR (icon) && icon->acFileName == NULL)
858
if (_cd_separator_is_impacted (icon, pDock, fXMin, fXMax, FALSE, (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)))
860
cairo_save (pCairoContext);
861
cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, FALSE);
862
cairo_restore (pCairoContext);
866
ic = cairo_dock_get_next_element (ic, pDock->icons);
867
} while (ic != pFirstDrawnElement);
875
fXLeft = icon->fDrawX + icon->fScale + 1;
876
fXRight = icon->fDrawX + (icon->fWidth - 1) * icon->fScale * icon->fWidthFactor - 1;
878
if (fXLeft <= fXMax && floor (fXRight) > fXMin)
880
if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth)
885
cairo_save (pCairoContext);
887
cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
889
cairo_restore (pCairoContext);
891
ic = cairo_dock_get_next_element (ic, pDock->icons);
892
} while (ic != pFirstDrawnElement);
898
Icon *cd_rendering_calculate_icons_curve (CairoDock *pDock)
900
Icon *pPointedIcon = cairo_dock_apply_wave_effect (pDock);
902
cairo_dock_check_if_mouse_inside_linear (pDock);
904
//\____________________ On calcule les position/etirements/alpha des icones.
905
double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
906
double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
907
double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
908
double xi = xCurve (my_fCurveCurvature, ti);
909
double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
910
double curveOffsetX = fDockWidth * xi; // pDock->iMaxDockWidth
912
gint sens, fDockOffsetY;
913
sens = pDock->bDirectionUp ? 1 : -1;
914
double fReflectionOffsetY = (pDock->bDirectionUp ? -1 : 1) * myIcons.fReflectSize;
915
// On va calculer une parabole pour approcher la courbe de bƩzier :
916
// Soient A: (xa,ya) B: (xb,yb) C: (xc,yc) trois points qui appartiennent Ć la parabole. xa, xb et xc sont distincts.
917
// P1(x)=(x-xb)(x-xc)
918
// P2(x)=(x-xa)(x-xc)
919
// P3(x)=(x-xa)(x-xb)
920
// p(x)=k1p1(x)+k2p2(x)+k3p3(x).
921
// avec k1=ya/((xa-xb)(xa-xc)) car p(xa)=ya p2(xa)=p3(xa)=0
923
// on calcule donc k1, k2, k3 :
924
gdouble xa, xb, xc, ya, yb, yc, k1, k2, k3;
925
if(pDock->icons == NULL)
927
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
928
Icon *pLastIcon = cairo_dock_get_last_drawn_icon (pDock);
929
xa = 0 ; // icone de gauche
931
xc = pLastIcon->fX - pFirstIcon->fX; // icone de droite
934
yb = -my_iCurveAmplitude;
936
if (xa != xb && xa != xc && xb != xc)
938
k1 = ya/((xa-xb)*(xa-xc));
939
k2 = yb/((xb-xa)*(xb-xc));
940
k3 = yc/((xc-xa)*(xc-xb));
950
for (ic = pDock->icons; ic != NULL; ic = ic->next)
953
double x = icon->fX - pFirstIcon->fX;
954
double y = k1*(x-xb)*(x-xc) + k2*(x-xa)*(x-xc) + k3*(x-xa)*(x-xb);
956
icon->fDrawX = icon->fX;
957
icon->fDrawY = icon->fY + sens * y;
958
//g_print ("y : %.2f -> fDrawY = %.2f\n", y, icon->fDrawY);
959
icon->fWidthFactor = 1.;
960
icon->fHeightFactor = 1.;
961
///icon->fDeltaYReflection = 0.;
962
icon->fOrientation = 0.;
963
if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth)
967
//g_print ("fDrawX:%.2f / %d (%.2f)\n", icon->fDrawX, pDock->iCurrentWidth, icon->fAlpha);
970
cairo_dock_check_can_drop_linear (pDock);
975
void cd_rendering_register_curve_renderer (const gchar *cRendererName)
977
CairoDockRenderer *pRenderer = g_new0 (CairoDockRenderer, 1);
978
pRenderer->cReadmeFilePath = g_strdup_printf ("%s/readme-curve-view", MY_APPLET_SHARE_DATA_DIR);
979
pRenderer->cPreviewFilePath = g_strdup_printf ("%s/preview-curve.jpg", MY_APPLET_SHARE_DATA_DIR);
980
pRenderer->calculate_max_dock_size = cd_rendering_calculate_max_dock_size_curve;
981
pRenderer->calculate_icons = cd_rendering_calculate_icons_curve;
982
pRenderer->render = cd_rendering_render_curve;
983
pRenderer->render_optimized = cd_rendering_render_optimized_curve;
984
pRenderer->render_opengl = cd_rendering_render_curve_opengl;
985
pRenderer->set_subdock_position = cairo_dock_set_subdock_position_linear;
986
pRenderer->bUseReflect = TRUE;
987
pRenderer->bUseStencil = TRUE;
988
pRenderer->cDisplayedName = D_ (cRendererName);
990
cairo_dock_register_renderer (cRendererName, pRenderer);
994
static void cairo_dock_draw_curved_frame_horizontal (cairo_t *pCairoContext, double fFrameWidth, double fControlHeight, double fDockOffsetX, double fDockOffsetY, int sens)
996
cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
997
cairo_rel_curve_to (pCairoContext,
998
(1 - my_fCurveCurvature) * fFrameWidth / 2, -sens * fControlHeight,
999
(1 + my_fCurveCurvature) * fFrameWidth / 2, -sens * fControlHeight,
1002
// on trace la ligne du bas
1003
cairo_rel_line_to (pCairoContext, -fFrameWidth, 0);
1005
static void cairo_dock_draw_curved_frame_vertical (cairo_t *pCairoContext, double fFrameWidth, double fControlHeight, double fDockOffsetX, double fDockOffsetY, int sens)
1007
cairo_move_to (pCairoContext, fDockOffsetY, fDockOffsetX);
1008
cairo_rel_curve_to (pCairoContext,
1009
-sens * fControlHeight, (1 - my_fCurveCurvature) * fFrameWidth / 2,
1010
-sens * fControlHeight, (1 + my_fCurveCurvature) * fFrameWidth / 2,
1013
// on trace la ligne du bas
1014
cairo_rel_line_to (pCairoContext, 0, - fFrameWidth);
1016
void cairo_dock_draw_curved_frame (cairo_t *pCairoContext, double fFrameWidth, double fControlHeight, double fDockOffsetX, double fDockOffsetY, gboolean bHorizontal, int sens)
1019
cairo_dock_draw_curved_frame_horizontal (pCairoContext, fFrameWidth, fControlHeight, fDockOffsetX, fDockOffsetY, sens);
1021
cairo_dock_draw_curved_frame_vertical (pCairoContext, fFrameWidth, fControlHeight, fDockOffsetX, fDockOffsetY, sens);
1025
void cd_rendering_calculate_reference_curve (double alpha)
1027
if (s_pReferenceCurveS == NULL)
1029
s_pReferenceCurveS = g_new (double, RENDERING_INTERPOLATION_NB_PTS+1);
1032
if (s_pReferenceCurveX == NULL)
1034
s_pReferenceCurveX = g_new (double, RENDERING_INTERPOLATION_NB_PTS+1);
1037
if (s_pReferenceCurveY == NULL)
1039
s_pReferenceCurveY = g_new (double, RENDERING_INTERPOLATION_NB_PTS+1);
1044
for (i = 0; i < RENDERING_INTERPOLATION_NB_PTS+1; i ++)
1046
s = (double) i / RENDERING_INTERPOLATION_NB_PTS;
1048
s_pReferenceCurveS[i] = s;
1049
s_pReferenceCurveX[i] = xCurve (my_fCurveCurvature, s);
1050
s_pReferenceCurveY[i] = yCurve (s);
1054
double cd_rendering_interpol_curve_parameter (double x)
1056
return cd_rendering_interpol (x, s_pReferenceCurveX, s_pReferenceCurveS);
1059
double cd_rendering_interpol_curve_height (double x)
1061
return cd_rendering_interpol (x, s_pReferenceCurveX, s_pReferenceCurveY);
1069
void cd_rendering_render_curve_opengl (CairoDock *pDock)
1071
//\____________________ On genere le cadre.
1072
double fLineWidth = myBackground.iDockLineWidth;
1073
double fMargin = myBackground.iFrameMargin;
1074
double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
1076
double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
1077
double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
1078
double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
1079
double xi = xCurve (my_fCurveCurvature, ti);
1080
double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
1082
double fFrameHeight = pDock->iDecorationsHeight + fLineWidth;
1083
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
1084
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
1085
fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - curveOffsetX : fLineWidth / 2);
1086
if ((pDock->bHorizontalDock && ! pDock->bDirectionUp) || (! pDock->bHorizontalDock && pDock->bDirectionUp))
1087
fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
1089
fDockOffsetY = pDock->iDecorationsHeight + 1.5 * fLineWidth;
1090
if (! pDock->bHorizontalDock)
1091
fDockOffsetX = pDock->iCurrentWidth - fDockOffsetX + 0;
1093
fDockOffsetX = fDockOffsetX-0;
1096
GLfloat *pVertexTab = cairo_dock_generate_curve_path (4./3, &iNbVertex);
1098
//\________________ On met en place le clipping.
1099
glDisable (GL_DEPTH_TEST);
1100
glEnable (GL_STENCIL_TEST); // active le tampon 'stencil'.
1101
glClear (GL_STENCIL_BUFFER_BIT); // on le remplit de 0.
1102
glStencilFunc (GL_ALWAYS, 1, 1); // valeur de reference = 1, et on ecrira un 1 sans condition.
1103
glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); // on remplace tout ce qui est dedans.
1104
glColorMask (FALSE, FALSE, FALSE, FALSE); // desactive l'ecriture dans toutes les composantes du Tampon Chromatique.
1106
double fEpsilon = (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR ? 2. : 0); // erreur d'arrondi quand tu nous tiens.
1108
cairo_dock_draw_frame_background_opengl (0, fDockWidth+2*curveOffsetX, fFrameHeight+fLineWidth+fEpsilon, fDockOffsetX, fDockOffsetY+(fLineWidth+fEpsilon)/2, pVertexTab, iNbVertex, pDock->bHorizontalDock, pDock->bDirectionUp, pDock->fDecorationsOffsetX); // le cadre est trace au milieu de la ligne, donc on augmente de l la hauteur (et donc de l/2 pixels la hauteur du cadre, car [-.5, .5]), et pour compenser on se translate de l/2.
1111
glColorMask (TRUE, TRUE, TRUE, TRUE);
1112
glStencilFunc (GL_EQUAL, 1, 1); /* draw if ==1 */
1113
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); // read only.
1114
glDisable (GL_STENCIL_TEST);
1116
//\____________________ On dessine les decorations dedans.
1118
cairo_dock_draw_frame_background_opengl (g_iBackgroundTexture, fDockWidth+2*curveOffsetX, fFrameHeight, fDockOffsetX, fDockOffsetY, pVertexTab, iNbVertex, pDock->bHorizontalDock, pDock->bDirectionUp, pDock->fDecorationsOffsetX);
1120
//\____________________ On dessine le cadre.
1122
cairo_dock_draw_current_path_opengl (fLineWidth, myBackground.fLineColor, iNbVertex);
1126
//\____________________ On dessine la ficelle qui les joint.
1127
if (myIcons.iStringLineWidth > 0)
1128
cairo_dock_draw_string_opengl (pDock, myIcons.iStringLineWidth, FALSE, (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR));
1130
//\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan.
1131
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
1132
if (pFirstDrawnElement == NULL)
1135
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
1137
GList *ic = pFirstDrawnElement;
1139
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
1145
if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
1147
glEnable (GL_STENCIL_TEST);
1148
glStencilFunc (GL_EQUAL, 1, 1);
1149
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
1152
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
1153
cd_rendering_draw_flat_separator_opengl (icon, pDock);
1155
cd_rendering_draw_physical_separator_opengl (icon, pDock, TRUE, (ic->prev ? ic->prev->data : NULL), (ic->next ? ic->next : NULL));
1158
glDisable (GL_STENCIL_TEST);
1161
ic = cairo_dock_get_next_element (ic, pDock->icons);
1162
} while (ic != pFirstDrawnElement);
1168
if (icon->acFileName != NULL || ! CAIRO_DOCK_IS_SEPARATOR (icon))
1171
cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
1175
ic = cairo_dock_get_next_element (ic, pDock->icons);
1176
} while (ic != pFirstDrawnElement);
1178
if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
1184
if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
1186
glEnable (GL_STENCIL_TEST);
1187
glStencilFunc (GL_EQUAL, 1, 1);
1188
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
1191
cd_rendering_draw_physical_separator_opengl (icon, pDock, FALSE, (ic->prev ? ic->prev->data : NULL), (ic->next ? ic->next : NULL));
1194
glDisable (GL_STENCIL_TEST);
1197
ic = cairo_dock_get_next_element (ic, pDock->icons);
1198
} while (ic != pFirstDrawnElement);
1208
cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
1211
ic = cairo_dock_get_next_element (ic, pDock->icons);
1212
} while (ic != pFirstDrawnElement);
1217
#define DELTA_ROUND_DEGREE 1
1218
#define RADIAN (G_PI / 180.0) // Conversion Radian/Degres
1219
#define P(t,p,q,r,s) (1-t) * (1-t) * (1-t) * p + 3 * t * (1-t) * (1 - t) * q + 3 * t * t * (1-t) * r + t * t * t * s
1220
GLfloat *cairo_dock_generate_curve_path (double fRelativeControlHeight, int *iNbPoints)
1222
//static GLfloat pVertexTab[((180/DELTA_ROUND_DEGREE+1)+1)*3];
1223
_cairo_dock_define_static_vertex_tab ((180/DELTA_ROUND_DEGREE+1)+1);
1227
double xp = -w, xq = - (1 - my_fCurveCurvature) * w, xr = - xq, xs = - xp;
1228
double yp = 0., yq = fRelativeControlHeight, yr = yq, ys = yp;
1230
//g_print ("%s (%.2f)\n", __func__, yq);
1231
int iPrecision = DELTA_ROUND_DEGREE;
1233
for (t = 0; t <= 180; t += iPrecision, i++)
1235
_cairo_dock_set_vertex_xy (i,
1236
P (t/180., xp, xq, xr, xs),
1237
P (t/180., yp, yq, yr, ys) - h);
1238
//vx(i) = P (t/180., xp, xq, xr, xs);
1239
//vy(i) = P (t/180., yp, yq, yr, ys) - h;
1242
// on trace la ligne du bas.
1243
_cairo_dock_close_path (i); // on boucle.
1244
//vx(i) = vx(0); // on boucle.
1248
_cairo_dock_return_vertex_tab ();
1258
/*static void cd_rendering_draw_curve_flat_separator_opengl (Icon *icon, CairoDock *pDock)
1260
double fLineWidth = myBackground.iDockLineWidth;
1261
double fMargin = myBackground.iFrameMargin;
1264
Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
1265
if (pPrevIcon == NULL)
1267
Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
1268
if (pNextIcon == NULL)
1271
double fVanishingDistanceLeft, fVanishingDistanceRight;
1272
double fDeltaInterIconLeft, fDeltaInterIconRight;
1273
if (pDock->bDirectionUp)
1275
hi = pDock->iCurrentHeight - (icon->fDrawY + icon->fHeight * icon->fScale);
1276
fVanishingDistanceLeft = iVanishingPointY + pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale;
1277
fVanishingDistanceRight = iVanishingPointY + pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale;
1279
fDeltaInterIconLeft = (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale) - (icon->fDrawY + icon->fHeight * icon->fScale);
1280
fDeltaInterIconRight = (icon->fDrawY + icon->fHeight * icon->fScale) - (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale);
1285
fVanishingDistanceLeft = iVanishingPointY + pDock->iCurrentHeight - pPrevIcon->fDrawY;
1286
fVanishingDistanceRight = iVanishingPointY + pDock->iCurrentHeight - pNextIcon->fDrawY;
1288
fDeltaInterIconLeft = (pPrevIcon->fDrawY) - (icon->fDrawY);
1289
fDeltaInterIconRight = (icon->fDrawY) - (pNextIcon->fDrawY);
1291
double fLeftInclination = (icon->fDrawX - pDock->iCurrentWidth / 2) / fVanishingDistanceLeft;
1292
double fRightInclination = (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / fVanishingDistanceRight;
1294
if (bBackGround || ! bIncludeEdges) // pour s'arreter sur la courbe, on realise un clippage.
1296
//\________________ On se ramene au cas du dessin optimise.
1297
double x0, y0, xf, yf, w0, h0;
1298
if (pDock->bDirectionUp)
1300
x0 = icon->fDrawX - MAX (0, fLeftInclination * (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale));
1301
xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale));
1305
x0 = icon->fDrawX - MAX (0, fLeftInclination * (pDock->iCurrentHeight - (pPrevIcon->fDrawY)));
1306
xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pDock->iCurrentHeight - (pNextIcon->fDrawY)));
1308
if (! bIncludeEdges) // on prolonge jusqu'en bas.
1310
if (pDock->bDirectionUp)
1312
x0 += MIN (0, fLeftInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
1313
xf += MAX (0, fRightInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
1317
x0 += MIN (0, fLeftInclination * (pPrevIcon->fDrawY));
1318
xf += MAX (0, fRightInclination * (pNextIcon->fDrawY));
1321
//g_print ("x0:%.2f -> xf:%.2f\n", x0, xf);
1328
double fDockOffsetY; // Offset du coin haut gauche du cadre.
1329
if (pDock->bDirectionUp)
1332
fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
1337
fDockOffsetY = .5 * fLineWidth;
1340
double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
1342
double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
1343
double hi_ = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
1344
double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi_ / h, 0)));
1345
double xi = xCurve (my_fCurveCurvature, ti);
1346
double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
1348
Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
1349
double fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - curveOffsetX : fLineWidth / 2);
1352
//\________________ On approche le morceau de courbe de Bezier par des trapezes.
1353
double x = (x0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
1354
double s = cd_rendering_interpol_curve_parameter (x);
1355
double y = yCurve (s);
1356
double x_ = (x0 + w0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
1357
double s_ = cd_rendering_interpol_curve_parameter (x_);
1358
double y_ = yCurve (s_);
1359
int i, iNbMidPoints = MAX (0, w0 / 20 - 1); // nombre de points intermediaires a calculer.
1360
double *pMidPointCoord = g_new (double, 2 * (iNbMidPoints+2));
1361
pMidPointCoord[0] = x0 - fDockOffsetX;
1362
pMidPointCoord[1] = y * h;
1363
pMidPointCoord[2*(iNbMidPoints+1)] = x0 + w0 - fDockOffsetX;
1364
pMidPointCoord[2*(iNbMidPoints+1)+1] = y_ * h;
1365
double si=s, ds = (s_ - s) / (iNbMidPoints+1);
1366
for (i = 1; i < iNbMidPoints+1; i ++)
1369
pMidPointCoord[2*i] = (fDockWidth + 2 * curveOffsetX) * xCurve (my_fCurveCurvature, si);
1370
pMidPointCoord[2*i+1] = h * yCurve (si);
1373
cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
1374
cairo_save (pCairoContext);
1375
double fDeltaLineWidth = 0.;
1378
double tan_theta = MAX (fabs (pMidPointCoord[1] - pMidPointCoord[3]) / (pMidPointCoord[2] - pMidPointCoord[0]), fabs (pMidPointCoord[2*iNbMidPoints+1] - pMidPointCoord[2*iNbMidPoints+3]) / (pMidPointCoord[2*iNbMidPoints+2] - pMidPointCoord[2*iNbMidPoints]));
1379
fDeltaLineWidth = (fLineWidth / 2 + .1) * sqrt (1. + tan_theta*tan_theta);
1381
if (pDock->bHorizontalDock)
1383
cairo_move_to (pCairoContext, x0, fDockOffsetY - sens * (y * h + fDeltaLineWidth));
1384
for (i = 0; i < iNbMidPoints+1; i ++)
1385
cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
1386
cairo_rel_line_to (pCairoContext, 0, sens * (y_ * h + fDeltaLineWidth));
1387
cairo_rel_line_to (pCairoContext, - w0, 0);
1388
cairo_rel_line_to (pCairoContext, 0, - sens * (y * h + fDeltaLineWidth));
1392
cairo_move_to (pCairoContext, fDockOffsetY - sens * (y * h + fDeltaLineWidth), x0);
1393
for (i = 0; i < iNbMidPoints+1; i ++)
1394
cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
1395
cairo_rel_line_to (pCairoContext, sens * (y_ * h + fDeltaLineWidth), 0);
1396
cairo_rel_line_to (pCairoContext, 0, - w0);
1397
cairo_rel_line_to (pCairoContext, - sens * (y * h + fDeltaLineWidth), 0);
1400
g_free (pMidPointCoord);
1401
cairo_clip (pCairoContext);
1405
double fHeight, fBigWidth, fLittleWidth;
1408
fHeight = (bBackGround ? pDock->iDecorationsHeight - hi : hi) + myBackground.iDockLineWidth;
1409
fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
1410
fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
1414
fHeight = pDock->iDecorationsHeight - myBackground.iDockLineWidth;
1415
fBigWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi);
1416
fLittleWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi - fHeight);
1418
double fDeltaXLeft = fHeight * fLeftInclination;
1419
double fDeltaXRight = fHeight * fRightInclination;
1420
//g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
1423
double fDockOffsetX, fDockOffsetY;
1424
if (pDock->bDirectionUp)
1428
fDockOffsetY = pDock->iCurrentHeight - fHeight - (bBackGround ? myBackground.iDockLineWidth + hi : 0);
1430
fDockOffsetY = pDock->iCurrentHeight - fHeight - myBackground.iDockLineWidth;
1436
fDockOffsetY = fHeight + (bBackGround ? myBackground.iDockLineWidth + hi : 0);
1438
fDockOffsetY = fHeight + myBackground.iDockLineWidth;
1442
fDockOffsetX = icon->fDrawX - (bBackGround ? fHeight * fLeftInclination : 0);
1444
fDockOffsetX = (pDock->bDirectionUp ? icon->fDrawX - (fHeight - hi) * fLeftInclination : icon->fDrawX - (fHeight - hi) * fLeftInclination);
1445
fDockOffsetX -= fDeltaInterIconLeft * fLeftInclination*sens;
1447
if (pDock->bHorizontalDock)
1449
cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY); // coin haut gauche.
1450
cairo_move_to (pCairoContext, 0, 0); // coin haut gauche.
1452
cairo_rel_line_to (pCairoContext, fLittleWidth, 0);
1453
cairo_rel_line_to (pCairoContext, fDeltaXRight, sens * fHeight);
1454
cairo_rel_line_to (pCairoContext, - fBigWidth, 0);
1455
cairo_rel_line_to (pCairoContext, - fDeltaXLeft, - sens * fHeight);
1457
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
1459
if (! pDock->bDirectionUp)
1460
cairo_scale (pCairoContext, 1, -1);
1461
cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_HORIZONTAL], MIN (0, (fHeight + hi) * fLeftInclination), 0);
1466
cairo_translate (pCairoContext, fDockOffsetY, fDockOffsetX); // coin haut gauche.
1467
cairo_move_to (pCairoContext, 0, 0); // coin haut gauche.
1469
cairo_rel_line_to (pCairoContext, 0, fLittleWidth);
1470
cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXRight);
1471
cairo_rel_line_to (pCairoContext, 0, - fBigWidth);
1472
cairo_rel_line_to (pCairoContext, - sens * fHeight, - fDeltaXLeft);
1474
if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
1476
if (! pDock->bDirectionUp)
1477
cairo_scale (pCairoContext, -1, 1);
1478
cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_VERTICAL], 0, MIN (0, (fHeight + hi) * fLeftInclination));