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/>.
24
#include "applet-struct.h"
25
#include "applet-session.h"
26
#include "applet-draw.h"
28
#define STATIC_ANGLE 20.
30
#define _alpha_prompt(k,n) cos (G_PI/2*fabs ((double) ((k % (2*n)) - n) / n));
32
const int s_iNbPromptAnimationSteps = 40;
34
static inline int _cd_do_get_matching_icons_width (int *iNbIcons)
36
int i = 0, iIconsWidth = 0;
37
CairoDock *pParentDock;
42
for (ic = myData.pMatchingIcons; ic != NULL; ic = ic->next)
45
if (pIcon->pIconBuffer == NULL && pIcon->iIconTexture == 0) // icone pas encore chargee.
47
pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
48
cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pParentDock), &iWidth, &iHeight);
51
fZoom = (double) g_pMainDock->iHeight/2 / iHeight;
52
iIconsWidth += iWidth * fZoom;
60
static inline int _cd_do_get_icon_x (GList *pElement)
63
CairoDock *pParentDock;
68
for (ic = myData.pMatchingIcons; ic != NULL && ic != pElement; ic = ic->next)
71
if (pIcon->pIconBuffer == NULL && pIcon->iIconTexture == 0) // icone pas encore chargee.
73
pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
74
cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pParentDock), &iWidth, &iHeight);
77
fZoom = (double) g_pMainDock->iHeight/2 / iHeight;
78
iOffset += iWidth * fZoom;
84
void cd_do_render_cairo (CairoDock *pMainDock, cairo_t *pCairoContext)
87
if (myData.iCloseTime != 0) // animation de fin
88
fAlpha = (double) myData.iCloseTime / myConfig.iCloseDuration;
92
double fDockMagnitude = cairo_dock_calculate_magnitude (pMainDock->iMagnitudeIndex);
93
double fScale = (1. + fDockMagnitude * g_fAmplitude) / (1 + g_fAmplitude);
95
if (myData.pCharList == NULL && myData.pListingHistory == NULL) // aucune lettre de tapee => on montre le prompt.
97
if (! myData.bNavigationMode && myData.pPromptSurface != NULL)
99
double fFrameWidth = myData.iPromptWidth * fScale;
100
double fFrameHeight = myData.iPromptHeight * fScale;
102
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du prompt.
103
fDockOffsetX = (pMainDock->iWidth - fFrameWidth) / 2;
104
fDockOffsetY = (pMainDock->iHeight - fFrameHeight) / 2; // centre verticalement.
106
fAlpha *= _alpha_prompt (myData.iPromptAnimationCount, s_iNbPromptAnimationSteps);
110
cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY);
112
cairo_scale (pCairoContext, fScale, fScale);
113
cairo_set_source_surface (pCairoContext, myData.pPromptSurface, 0., 0.);
114
cairo_paint_with_alpha (pCairoContext, fAlpha);
117
else if (myData.bNavigationMode && myData.pArrowSurface != NULL)
119
double fFrameWidth = myData.iArrowWidth * fScale;
120
double fFrameHeight = myData.iArrowHeight * fScale;
122
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du prompt.
123
fDockOffsetX = (pMainDock->iWidth - fFrameWidth) / 2;
124
fDockOffsetY = (pMainDock->iHeight - fFrameHeight) / 2;
126
fAlpha *= _alpha_prompt (myData.iPromptAnimationCount, s_iNbPromptAnimationSteps);
130
cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY);
132
cairo_scale (pCairoContext, fScale, fScale);
133
cairo_set_source_surface (pCairoContext, myData.pArrowSurface, 0., 0.);
134
cairo_paint_with_alpha (pCairoContext, fAlpha);
138
else // si du texte a ete entre, on le dessine, ainsi que eventuellement la liste des icones correspondantes.
140
// dessin des icones correspondantes.
141
int iIconsWidth = 0, iNbIcons = 0;
142
if (myData.pMatchingIcons != NULL)
144
// on determine au prealable la largeur des icones pour pouvoir les centrer.
145
iIconsWidth = _cd_do_get_matching_icons_width (&iNbIcons);
147
// dessin du fond des icones.
148
double fFrameWidth = iIconsWidth * fScale;
149
double fFrameHeight = pMainDock->iHeight/2 * fScale;
150
double fRadius = fFrameHeight / 10;
151
double fLineWidth = 0.;
152
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
153
fDockOffsetX = (pMainDock->iWidth - fFrameWidth) / 2;
154
fDockOffsetY = (!myConfig.bTextOnTop ? 0. : pMainDock->iHeight - fFrameHeight);
156
cairo_save (pCairoContext);
157
cairo_translate (pCairoContext, fDockOffsetX -fRadius, fDockOffsetY);
158
cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight);
159
cairo_set_line_width (pCairoContext, fLineWidth);
160
cairo_set_source_rgba (pCairoContext, myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha);
161
cairo_fill (pCairoContext);
162
cairo_restore (pCairoContext);
165
//int iOffsetX = _cd_do_get_icon_x (myData.pCurrentMatchingElement) + myData.iCurrentMatchingOffset * myData.iCurrentMatchingDirection - iIconsWidth/2; // ecart au centre du debut de l'icone courante.
166
//iOffsetX = - iOffsetX;
167
int iOffsetX = myData.iCurrentMatchingOffset + iIconsWidth/2;
168
while (iOffsetX > iIconsWidth)
169
iOffsetX -= iIconsWidth;
171
iOffsetX += iIconsWidth;
173
double fIconScale = (iIconsWidth * fScale > pMainDock->iWidth ? (double) pMainDock->iWidth / (iIconsWidth * fScale) : 1.);
174
double x0 = (pMainDock->iWidth - iIconsWidth * fScale * fIconScale) / 2;
175
double x = x0 + iOffsetX * fIconScale * fScale; // abscisse de l'icone courante.
176
CairoDock *pParentDock;
180
gboolean bRound = FALSE;
182
for (ic = myData.pMatchingIcons; ic != NULL; ic = ic->next)
185
if (pIcon->pIconBuffer == NULL) // icone pas encore chargee.
187
pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
188
cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pParentDock), &iWidth, &iHeight);
189
fZoom = fIconScale * pMainDock->iHeight/2 / iHeight;
190
cairo_save (pCairoContext);
197
x += iIconsWidth * fIconScale * fScale;
199
else if (x > x0 + iIconsWidth * fIconScale * fScale)
201
x -= iIconsWidth * fIconScale * fScale;
205
cairo_translate (pCairoContext,
206
x - (iNbIcons & 1 ? iWidth * fZoom * fScale * fIconScale / 2 : 0.),
207
(myConfig.bTextOnTop ?
208
pMainDock->iHeight/2 :
210
cairo_scale (pCairoContext,
213
cairo_set_source_surface (pCairoContext, pIcon->pIconBuffer, 0., 0.);
214
cairo_paint_with_alpha (pCairoContext, (myData.pCurrentMatchingElement == ic ? 1. : .7));
216
if (myData.pCurrentMatchingElement == ic)
219
cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth-2*fRadius, iHeight-fLineWidth);
220
cairo_set_line_width (pCairoContext, fLineWidth);
221
cairo_set_source_rgba (pCairoContext, myConfig.pFrameColor[0]+.1, myConfig.pFrameColor[1]+.1, myConfig.pFrameColor[2]+.1, 1.);
222
cairo_stroke (pCairoContext);
225
cairo_restore (pCairoContext);
226
x += iWidth * fZoom * fScale;
230
// dessin du fond du texte.
231
double fFrameWidth = myData.iTextWidth * fScale;
232
double fTextScale = (fFrameWidth > pMainDock->iWidth ? (double) pMainDock->iWidth / fFrameWidth : 1.);
233
double fFrameHeight = myData.iTextHeight * fScale;
234
double fRadius = fFrameHeight / 5 * myConfig.fFontSizeRatio;
235
double fLineWidth = 0.;
236
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
237
fDockOffsetX = (pMainDock->iWidth - fFrameWidth * fTextScale) / 2;
238
fDockOffsetY = (myConfig.bTextOnTop ? 0. : pMainDock->iHeight - fFrameHeight);
240
cairo_save (pCairoContext);
241
cairo_translate (pCairoContext, fDockOffsetX -fRadius, fDockOffsetY);
242
cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight);
243
cairo_set_line_width (pCairoContext, fLineWidth);
244
cairo_set_source_rgba (pCairoContext, myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha);
245
cairo_fill (pCairoContext);
246
cairo_restore (pCairoContext);
248
// dessin des lettres.
251
for (c = myData.pCharList; c != NULL; c = c->next)
254
cairo_save (pCairoContext);
256
cairo_translate (pCairoContext,
257
(pChar->iCurrentX * fScale * fTextScale + pMainDock->iWidth/2),
258
pChar->iCurrentY + (myConfig.bTextOnTop ?
259
(myData.iTextHeight - pChar->iHeight) * fScale :
260
pMainDock->iHeight - pChar->iHeight * fScale)); // aligne en bas.
262
if (fScale * fTextScale != 1)
263
cairo_scale (pCairoContext, fScale*fTextScale, fScale*fTextScale);
264
cairo_set_source_surface (pCairoContext, pChar->pSurface, 0., 0.);
265
cairo_paint_with_alpha (pCairoContext, fAlpha);
267
cairo_restore (pCairoContext);
273
void cd_do_render_opengl (CairoDock *pMainDock)
276
if (myData.iCloseTime != 0) // animation de fin
277
fAlpha = (double) myData.iCloseTime / myConfig.iCloseDuration;
281
double fDockMagnitude = cairo_dock_calculate_magnitude (pMainDock->iMagnitudeIndex);
282
double fScale = (1. + fDockMagnitude * g_fAmplitude) / (1 + g_fAmplitude);
284
if (myData.pCharList == NULL && myData.pListingHistory == NULL) // aucune lettre de tapee => on montre le prompt.
286
if (! myData.bNavigationMode && myData.iPromptTexture != 0)
288
double fFrameWidth = myData.iPromptWidth * fScale;
289
double fFrameHeight = myData.iPromptHeight * fScale;
291
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du prompt.
292
fDockOffsetX = (pMainDock->iWidth - fFrameWidth) / 2;
293
fDockOffsetY = (pMainDock->iHeight - fFrameHeight) / 2;
295
fAlpha *= _alpha_prompt (myData.iPromptAnimationCount, s_iNbPromptAnimationSteps);
300
glTranslatef (pMainDock->iWidth/2, pMainDock->iHeight/2, 0.);
302
_cairo_dock_enable_texture ();
303
_cairo_dock_set_blend_alpha ();
305
_cairo_dock_apply_texture_at_size_with_alpha (myData.iPromptTexture, fFrameWidth, fFrameHeight, fAlpha);
307
_cairo_dock_disable_texture ();
312
else if (myData.bNavigationMode && myData.iArrowTexture != 0)
314
double fFrameWidth = myData.iArrowWidth * fScale;
315
double fFrameHeight = myData.iArrowHeight * fScale;
317
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du prompt.
318
fDockOffsetX = (pMainDock->iWidth - fFrameWidth) / 2;
319
fDockOffsetY = (pMainDock->iHeight - fFrameHeight) / 2;
321
fAlpha *= _alpha_prompt (myData.iPromptAnimationCount, s_iNbPromptAnimationSteps);
326
glTranslatef (pMainDock->iWidth/2, pMainDock->iHeight/2, 0.);
328
_cairo_dock_enable_texture ();
329
_cairo_dock_set_blend_alpha ();
331
_cairo_dock_apply_texture_at_size_with_alpha (myData.iArrowTexture, fFrameWidth, fFrameHeight, fAlpha);
333
_cairo_dock_disable_texture ();
339
else // si du texte a ete entre, on le dessine, ainsi que eventuellement la liste des icones correspondantes.
341
// dessin des icones correspondantes.
342
int iIconsWidth = 0, iNbIcons = 0;
343
if (myData.pMatchingIcons != NULL)
345
// on determine au prealable la largeur des icones pour povouir les centrer.
346
iIconsWidth = _cd_do_get_matching_icons_width (&iNbIcons);
348
// dessin du fond des icones.
349
double fFrameWidth = iIconsWidth * fScale;
350
double fFrameHeight = pMainDock->iHeight/2 * fScale;
351
double fRadius = fFrameHeight / 10;
352
double fLineWidth = 0.;
353
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
354
fDockOffsetX = pMainDock->iWidth/2 - fFrameWidth / 2 - fRadius;
355
fDockOffsetY = (!myConfig.bTextOnTop ? pMainDock->iHeight : fFrameHeight);
356
double fFrameColor[4] = {myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha};
358
cairo_dock_draw_rounded_rectangle_opengl (fRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, fFrameColor);
362
//int iOffsetX = _cd_do_get_icon_x (myData.pCurrentMatchingElement) + myData.iCurrentMatchingOffset * myData.iCurrentMatchingDirection - iIconsWidth/2; // ecart au centre du debut de l'icone courante.
363
//iOffsetX = - iOffsetX;
364
//g_print ("myData.iCurrentMatchingOffset : %d\n", myData.iCurrentMatchingOffset);
365
int iOffsetX = myData.iCurrentMatchingOffset + iIconsWidth/2;
366
while (iOffsetX > iIconsWidth)
367
iOffsetX -= iIconsWidth;
369
iOffsetX += iIconsWidth;
371
double fIconScale = (iIconsWidth * fScale > pMainDock->iWidth ? (double) pMainDock->iWidth / (iIconsWidth * fScale) : 1.);
372
double x0 = (pMainDock->iWidth - iIconsWidth * fScale * fIconScale) / 2;
373
double x = x0 - iOffsetX * fIconScale * fScale; // abscisse de l'icone courante.
374
CairoDock *pParentDock;
378
gboolean bRound = FALSE;
381
_cairo_dock_enable_texture ();
382
_cairo_dock_set_blend_alpha ();
383
_cairo_dock_set_alpha (1.);
384
for (ic = myData.pMatchingIcons; ic != NULL; ic = ic->next)
387
if (pIcon->iIconTexture == 0) // icone pas encore chargee.
389
pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
390
cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pParentDock), &iWidth, &iHeight);
391
fZoom = (double) pMainDock->iHeight/2 / iHeight;
399
x += iIconsWidth * fIconScale * fScale;
401
else if (x > x0 + iIconsWidth * fIconScale * fScale)
403
x -= iIconsWidth * fIconScale * fScale;
407
glTranslatef (x + (iNbIcons & 1 ? 0. : iWidth * fZoom/2 * fScale * fIconScale),
408
(myConfig.bTextOnTop ?
409
pMainDock->iHeight/4 :
410
pMainDock->iHeight - iHeight * fZoom/2 * fScale),
412
_cairo_dock_apply_texture_at_size_with_alpha (pIcon->iIconTexture,
413
iWidth * fZoom * fScale * fIconScale,
414
pMainDock->iHeight/2 * fScale * fIconScale,
415
(myData.pCurrentMatchingElement == ic ? 1. : .7));
417
if (myData.pCurrentMatchingElement == ic)
419
_cairo_dock_disable_texture ();
421
double fFrameColor[4] = {myConfig.pFrameColor[0]+.1, myConfig.pFrameColor[1]+.1, myConfig.pFrameColor[2]+.1, 1.};
422
cairo_dock_draw_rounded_rectangle_opengl (fRadius, fLineWidth, iWidth * fZoom * fScale * fIconScale - fLineWidth, iHeight * fZoom * fScale * fIconScale - fLineWidth, -iWidth/2 * fZoom * fScale * fIconScale + fLineWidth/2, iHeight * fZoom/2 * fScale * fIconScale - fLineWidth/2, fFrameColor);
423
_cairo_dock_enable_texture ();
424
_cairo_dock_set_blend_over ();
425
_cairo_dock_set_alpha (1.);
429
x += iWidth * fZoom * fScale * fIconScale;
431
_cairo_dock_disable_texture ();
434
// dessin du fond du texte.
435
double fFrameWidth = myData.iTextWidth * fScale;
436
double fTextScale = (fFrameWidth > pMainDock->iWidth ? (double) pMainDock->iWidth / fFrameWidth : 1.);
437
double fFrameHeight = myData.iTextHeight * fScale;
438
double fRadius = myBackground.iDockRadius * myConfig.fFontSizeRatio;
439
double fLineWidth = 0.;
441
double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre.
442
fDockOffsetX = pMainDock->iWidth/2 - fFrameWidth * fTextScale / 2 - fRadius;
443
fDockOffsetY = (myConfig.bTextOnTop ? pMainDock->iHeight : fFrameHeight);
446
double fFrameColor[4] = {myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha};
447
cairo_dock_draw_rounded_rectangle_opengl (fRadius, 0, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, fFrameColor);
450
// dessin des lettres.
451
_cairo_dock_enable_texture ();
452
_cairo_dock_set_blend_alpha ();
453
_cairo_dock_set_alpha (fAlpha);
455
cairo_dock_set_perspective_view (pMainDock->iWidth, pMainDock->iHeight);
456
glTranslatef (-pMainDock->iWidth/2, -pMainDock->iHeight/2, 0.);
457
glEnable (GL_DEPTH_TEST);
461
for (c = myData.pCharList; c != NULL; c = c->next)
466
glTranslatef (pChar->iCurrentX * fScale * fTextScale + pMainDock->iWidth/2 + pChar->iWidth/2,
467
(myConfig.bTextOnTop ?
468
pMainDock->iHeight - (myData.iTextHeight - pChar->iHeight/2) * fScale :
469
pChar->iHeight/2 * fScale),
470
0.); // aligne en bas.
472
double fRotationAngle = pChar->fRotationAngle;
473
if (myConfig.iAppearanceDuration != 0)
475
glBindTexture (GL_TEXTURE_2D, pChar->iTexture);
477
glScalef (pChar->iWidth * fScale * fTextScale, pChar->iHeight * fScale * fTextScale, 1.);
479
glRotatef (fRotationAngle, 1., 0., 0.);
480
glRotatef (MIN (fRotationAngle/3, STATIC_ANGLE), 0., 0., 1.);
481
glRotatef (MIN (fRotationAngle/3, STATIC_ANGLE), 0., 1., 0.);
483
glPolygonMode (GL_FRONT, GL_FILL);
484
double a = .5 / sqrt (2);
486
// Front Face (note that the texture's corners have to match the quad's corners)
488
glTexCoord2f (0., 0.); glVertex3f(-a, a, a); // Bottom Left Of The Texture and Quad
489
glTexCoord2f (1., 0.); glVertex3f( a, a, a); // Bottom Right Of The Texture and Quad
490
glTexCoord2f (1., 1.); glVertex3f( a, -a, a); // Top Right Of The Texture and Quad
491
glTexCoord2f (0., 1.); glVertex3f(-a, -a, a); // Top Left Of The Texture and Quad
494
glTexCoord2f (1., 0.); glVertex3f( -a, a, -a); // Bottom Right Of The Texture and Quad
495
glTexCoord2f (1., 1.); glVertex3f( -a, -a, -a); // Top Right Of The Texture and Quad
496
glTexCoord2f (0., 1.); glVertex3f(a, -a, -a); // Top Left Of The Texture and Quad
497
glTexCoord2f (0., 0.); glVertex3f(a, a, -a); // Bottom Left Of The Texture and Quad
500
glTexCoord2f (0., 1.); glVertex3f(-a, a, a); // Top Left Of The Texture and Quad
501
glTexCoord2f (0., 0.); glVertex3f(-a, a, -a); // Bottom Left Of The Texture and Quad
502
glTexCoord2f (1., 0.); glVertex3f( a, a, -a); // Bottom Right Of The Texture and Quad
503
glTexCoord2f (1., 1.); glVertex3f( a, a, a); // Top Right Of The Texture and Quad
506
glTexCoord2f (1., 1.); glVertex3f( a, -a, -a); // Top Right Of The Texture and Quad
507
glTexCoord2f (0., 1.); glVertex3f(-a, -a, -a); // Top Left Of The Texture and Quad
508
glTexCoord2f (0., 0.); glVertex3f(-a, -a, a); // Bottom Left Of The Texture and Quad
509
glTexCoord2f (1., 0.); glVertex3f( a, -a, a); // Bottom Right Of The Texture and Quad
512
glTexCoord2f (1., 0.); glVertex3f( a, a, -a); // Bottom Right Of The Texture and Quad
513
glTexCoord2f (1., 1.); glVertex3f( a, -a, -a); // Top Right Of The Texture and Quad
514
glTexCoord2f (0., 1.); glVertex3f( a, -a, a); // Top Left Of The Texture and Quad
515
glTexCoord2f (0., 0.); glVertex3f( a, a, a); // Bottom Left Of The Texture and Quad
518
glTexCoord2f (0., 0.); glVertex3f(-a, a, -a); // Bottom Left Of The Texture and Quad
519
glTexCoord2f (1., 0.); glVertex3f(-a, a, a); // Bottom Right Of The Texture and Quad
520
glTexCoord2f (1., 1.); glVertex3f(-a, -a, a); // Top Right Of The Texture and Quad
521
glTexCoord2f (0., 1.); glVertex3f(-a, -a, -a); // Top Left Of The Texture and Quad
526
_cairo_dock_apply_texture_at_size (pChar->iTexture, pChar->iWidth, pChar->iHeight);
531
cairo_dock_set_ortho_view (pMainDock->iWidth, pMainDock->iHeight);
532
glTranslatef (-pMainDock->iWidth/2, -pMainDock->iHeight/2, 0.);
533
glDisable (GL_DEPTH_TEST);