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/>.
25
#include "cairo-dock-icons.h"
26
#include "cairo-dock-draw.h"
27
#include "cairo-dock-draw-opengl.h"
28
#include "cairo-dock-renderer-manager.h"
29
#include "cairo-dock-load.h"
30
#include "cairo-dock-log.h"
31
#include "cairo-dock-emblem.h"
33
extern CairoDockImageBuffer g_pIconBackgroundBuffer;
34
extern CairoDockImageBuffer g_pBoxAboveBuffer;
35
extern CairoDockImageBuffer g_pBoxBelowBuffer;
36
extern gboolean g_bUseOpenGL;
40
//merci a Necropotame et ChAnGFu !
42
CairoEmblem *cairo_dock_make_emblem (const gchar *cImageFile, Icon *pIcon, CairoContainer *pContainer, cairo_t *pSourceContext)
44
CairoEmblem *pEmblem = g_new0 (CairoEmblem, 1);
46
//\___________ On calcule les dimensions de l'embleme.
48
cairo_dock_get_icon_extent (pIcon, pContainer, &w, &h);
49
pEmblem->iWidth = a * w;
50
pEmblem->iHeight = a * h;
52
//\___________ On cree la surface/texture a cette taille.
53
cairo_surface_t *pEmblemSurface = cairo_dock_create_surface_from_image_simple (cImageFile, pSourceContext, pEmblem->iWidth, pEmblem->iHeight);
55
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pEmblemSurface)
57
pEmblem->iTexture = cairo_dock_create_texture_from_surface (pEmblemSurface);
58
cairo_surface_destroy (pEmblemSurface);
61
pEmblem->pSurface = pEmblemSurface;
66
CairoEmblem *cairo_dock_make_emblem_from_surface (cairo_surface_t *pSurface, int iSurfaceWidth, int iSurfaceHeight, Icon *pIcon, CairoContainer *pContainer)
68
CairoEmblem *pEmblem = g_new0 (CairoEmblem, 1);
71
cairo_dock_get_icon_extent (pIcon, pContainer, &w, &h);
72
pEmblem->iWidth = (iSurfaceWidth > 0 ? iSurfaceWidth : w);
73
pEmblem->iHeight = (iSurfaceHeight > 0 ? iSurfaceHeight : h);
74
pEmblem->pSurface = pSurface;
78
CairoEmblem *cairo_dock_make_emblem_from_texture (GLuint iTexture, Icon *pIcon, CairoContainer *pContainer)
80
CairoEmblem *pEmblem = g_new0 (CairoEmblem, 1);
82
pEmblem->iTexture = iTexture; // inutile de connaitre la taille de la texture.
87
void cairo_dock_free_emblem (CairoEmblem *pEmblem)
92
if (pEmblem->pSurface != NULL)
93
cairo_surface_destroy (pEmblem->pSurface);
94
if (pEmblem->iTexture != 0)
95
_cairo_dock_delete_texture (pEmblem->iTexture);
100
static void _cairo_dock_apply_emblem_texture (CairoEmblem *pEmblem, int w, int h)
103
switch (pEmblem->iPosition)
105
case CAIRO_DOCK_EMBLEM_UPPER_RIGHT:
109
case CAIRO_DOCK_EMBLEM_LOWER_RIGHT:
113
case CAIRO_DOCK_EMBLEM_UPPER_LEFT:
114
x = -(double)w/2 * (1 - a);
115
y = (double)h/2 * (1 - a);
117
case CAIRO_DOCK_EMBLEM_LOWER_LEFT:
122
case CAIRO_DOCK_EMBLEM_MIDDLE:
127
glBindTexture (GL_TEXTURE_2D, pEmblem->iTexture);
128
_cairo_dock_apply_current_texture_at_size_with_offset (a*w, a*h, x, y);
130
static void _cairo_dock_apply_emblem_surface (CairoEmblem *pEmblem, int w, int h, cairo_t *pCairoContext)
132
double zx = (double) a*w / pEmblem->iWidth;
133
double zy = (double) a*h / pEmblem->iHeight;
134
cairo_scale (pCairoContext, zx, zy);
137
switch (pEmblem->iPosition)
139
case CAIRO_DOCK_EMBLEM_UPPER_RIGHT:
143
case CAIRO_DOCK_EMBLEM_LOWER_RIGHT:
147
case CAIRO_DOCK_EMBLEM_UPPER_LEFT:
151
case CAIRO_DOCK_EMBLEM_LOWER_LEFT:
156
case CAIRO_DOCK_EMBLEM_MIDDLE:
161
cairo_set_source_surface (pCairoContext, pEmblem->pSurface, x/zx, y/zy);
162
cairo_paint (pCairoContext);
164
void cairo_dock_draw_emblem_on_icon (CairoEmblem *pEmblem, Icon *pIcon, CairoContainer *pContainer)
166
g_return_if_fail (pEmblem != NULL);
169
cairo_dock_get_icon_extent (pIcon, pContainer, &w, &h);
171
if (pIcon->iIconTexture != 0 && pEmblem->iTexture != 0) // dessin opengl : on dessine sur la texture de l'icone avec le mecanisme habituel.
173
if (! cairo_dock_begin_draw_icon (pIcon, pContainer))
176
_cairo_dock_enable_texture ();
178
_cairo_dock_set_blend_source ();
180
_cairo_dock_apply_texture_at_size (pIcon->iIconTexture, w, h);
182
_cairo_dock_set_blend_alpha ();
184
_cairo_dock_apply_emblem_texture (pEmblem, w, h);
186
_cairo_dock_disable_texture ();
188
cairo_dock_end_draw_icon (pIcon, pContainer);
190
else if (pIcon->pIconBuffer != NULL && pEmblem->pSurface != NULL)
192
cairo_t *pCairoContext = cairo_create (pIcon->pIconBuffer);
193
g_return_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS);
195
_cairo_dock_apply_emblem_surface (pEmblem, w, h, pCairoContext);
197
cairo_paint (pCairoContext);
199
cairo_destroy (pCairoContext);
204
static void _cairo_dock_draw_subdock_content_as_emblem (Icon *pIcon, CairoDock *pDock, int w, int h, cairo_t *pCairoContext)
206
//\______________ On dessine les 4 premieres icones du sous-dock en embleme.
208
memset (&e, 0, sizeof (CairoEmblem));
212
for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 4; ic = ic->next, i++)
215
if (CAIRO_DOCK_IS_SEPARATOR (icon))
221
if (pCairoContext == NULL)
223
e.iTexture = icon->iIconTexture;
224
_cairo_dock_apply_emblem_texture (&e, w, h);
228
e.pSurface = icon->pIconBuffer;
229
cairo_dock_get_icon_extent (icon, CAIRO_CONTAINER (pIcon->pSubDock), &e.iWidth, &e.iHeight);
231
cairo_save (pCairoContext);
232
_cairo_dock_apply_emblem_surface (&e, w, h, pCairoContext);
233
cairo_restore (pCairoContext);
240
static void _cairo_dock_draw_subdock_content_as_stack (Icon *pIcon, CairoDock *pDock, int w, int h, cairo_t *pCairoContext)
242
//\______________ On dessine les 4 premieres icones du sous-dock en pile.
244
memset (&e, 0, sizeof (CairoEmblem));
250
for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 3; ic = ic->next, i++)
253
if (CAIRO_DOCK_IS_SEPARATOR (icon))
261
e.iPosition = CAIRO_DOCK_EMBLEM_UPPER_RIGHT;
264
if (ic->next == NULL)
265
e.iPosition = CAIRO_DOCK_EMBLEM_LOWER_LEFT;
267
e.iPosition = CAIRO_DOCK_EMBLEM_MIDDLE;
270
e.iPosition = CAIRO_DOCK_EMBLEM_LOWER_LEFT;
274
if (pIcon->iIconTexture != 0)
276
e.iTexture = icon->iIconTexture;
277
_cairo_dock_apply_emblem_texture (&e, w, h);
281
e.pSurface = icon->pIconBuffer;
282
cairo_dock_get_icon_extent (icon, CAIRO_CONTAINER (pIcon->pSubDock), &e.iWidth, &e.iHeight);
284
cairo_save (pCairoContext);
285
_cairo_dock_apply_emblem_surface (&e, w, h, pCairoContext);
286
cairo_restore (pCairoContext);
293
/*static void _cairo_dock_draw_subdock_content_as_box (Icon *pIcon, CairoDock *pDock, int w, int h, cairo_t *pCairoContext)
297
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
298
cairo_save (pCairoContext);
299
cairo_scale(pCairoContext,
300
(double) w / g_pBoxBelowBuffer.iWidth,
301
(double) h / g_pBoxBelowBuffer.iHeight);
302
cairo_set_source_surface (pCairoContext,
303
g_pBoxBelowBuffer.pSurface,
306
cairo_paint (pCairoContext);
307
cairo_restore (pCairoContext);
309
cairo_save (pCairoContext);
310
cairo_scale(pCairoContext,
316
for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 3; ic = ic->next, i++)
319
if (CAIRO_DOCK_IS_SEPARATOR (icon))
325
cairo_set_source_surface (pCairoContext,
329
cairo_paint (pCairoContext);
331
cairo_restore (pCairoContext);
333
cairo_scale(pCairoContext,
334
(double) w / g_pBoxAboveBuffer.iWidth,
335
(double) h / g_pBoxAboveBuffer.iHeight);
336
cairo_set_source_surface (pCairoContext,
337
g_pBoxAboveBuffer.pSurface,
340
cairo_paint (pCairoContext);
344
_cairo_dock_set_blend_source ();
345
_cairo_dock_apply_texture_at_size (g_pBoxBelowBuffer.iTexture, w, h);
347
_cairo_dock_set_blend_alpha ();
351
for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 3; ic = ic->next, i++)
354
if (CAIRO_DOCK_IS_SEPARATOR (icon))
359
glBindTexture (GL_TEXTURE_2D, icon->iIconTexture);
360
_cairo_dock_apply_current_texture_at_size_with_offset (.8*w, .8*h, 0., .1*(1-i)*h);
363
_cairo_dock_apply_texture_at_size (g_pBoxAboveBuffer.iTexture, w, h);
367
void cairo_dock_draw_subdock_content_on_icon (Icon *pIcon, CairoDock *pDock)
369
g_return_if_fail (pIcon != NULL && pIcon->pSubDock != NULL && (pIcon->pIconBuffer != NULL || pIcon->iIconTexture != 0));
370
//g_print ("%s (%s)\n", __func__, pIcon->cName);
373
cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pDock), &w, &h);
375
//\______________ On efface le dessin existant.
376
cairo_t *pCairoContext = NULL;
377
if (pIcon->iIconTexture != 0) // dessin opengl
379
if (! cairo_dock_begin_draw_icon (pIcon, CAIRO_CONTAINER (pDock)))
382
_cairo_dock_set_blend_source ();
383
if (g_pIconBackgroundBuffer.iTexture != 0) // on ecrase le dessin existant avec l'image de fond des icones.
385
_cairo_dock_enable_texture ();
386
_cairo_dock_set_alpha (1.);
387
_cairo_dock_apply_texture_at_size (g_pIconBackgroundBuffer.iTexture, w, h);
389
else // sinon on efface juste ce qu'il y'avait.
391
glPolygonMode (GL_FRONT, GL_FILL);
392
_cairo_dock_set_alpha (0.);
394
glVertex3f(-.5*w, .5*h, 0.);
395
glVertex3f( .5*w, .5*h, 0.);
396
glVertex3f( .5*w, -.5*h, 0.);
397
glVertex3f(-.5*w, -.5*h, 0.);
399
_cairo_dock_enable_texture ();
400
_cairo_dock_set_alpha (1.);
402
_cairo_dock_set_blend_alpha ();
404
else if (pIcon->pIconBuffer != NULL) // dessin cairo
406
pCairoContext = cairo_create (pIcon->pIconBuffer);
407
g_return_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS);
409
if (g_pIconBackgroundBuffer.pSurface != NULL) // on ecrase le dessin existant avec l'image de fond des icones.
411
cairo_save (pCairoContext);
412
cairo_scale(pCairoContext,
413
(double) w / g_pIconBackgroundBuffer.iWidth,
414
(double) h / g_pIconBackgroundBuffer.iHeight);
415
cairo_set_source_surface (pCairoContext,
416
g_pIconBackgroundBuffer.pSurface,
419
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
420
cairo_paint (pCairoContext);
421
cairo_restore (pCairoContext);
423
else // sinon on efface juste ce qu'il y'avait.
425
cairo_dock_erase_cairo_context (pCairoContext);
427
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
432
//\______________ On dessine les 3 ou 4 premieres icones du sous-dock.
433
if (pIcon->cClass != NULL)
434
_cairo_dock_draw_subdock_content_as_stack (pIcon, pDock, w, h, pCairoContext);
437
switch (pIcon->iSubdockViewType)
440
_cairo_dock_draw_subdock_content_as_emblem (pIcon, pDock, w, h, pCairoContext);
443
_cairo_dock_draw_subdock_content_as_stack (pIcon, pDock, w, h, pCairoContext);
446
_cairo_dock_draw_subdock_content_as_box (pIcon, pDock, w, h, pCairoContext);
449
cd_warning ("invalid sub-dock content view for %s", pIcon->cName);
454
//\______________ On finit le dessin.
455
if (pIcon->iIconTexture != 0)
457
_cairo_dock_disable_texture ();
458
cairo_dock_end_draw_icon (pIcon, CAIRO_CONTAINER (pDock));
463
cairo_dock_update_icon_texture (pIcon);
465
cairo_dock_add_reflection_to_icon (pCairoContext, pIcon, CAIRO_CONTAINER (pDock));
466
cairo_destroy (pCairoContext);