~cairo-dock-team/ubuntu/oneiric/cairo-dock/2.3.0-3

« back to all changes in this revision

Viewing changes to src/cairo-dock-emblem.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
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.
11
 
*
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/>.
18
 
*/
19
 
 
20
 
#include <math.h>
21
 
#include <string.h>
22
 
#include <stdlib.h>
23
 
#include <cairo.h>
24
 
 
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"
32
 
 
33
 
extern CairoDockImageBuffer g_pIconBackgroundBuffer;
34
 
extern CairoDockImageBuffer g_pBoxAboveBuffer;
35
 
extern CairoDockImageBuffer g_pBoxBelowBuffer;
36
 
extern gboolean g_bUseOpenGL;
37
 
 
38
 
static double a = .5;
39
 
 
40
 
//merci a Necropotame et ChAnGFu !
41
 
 
42
 
CairoEmblem *cairo_dock_make_emblem (const gchar *cImageFile, Icon *pIcon, CairoContainer *pContainer, cairo_t *pSourceContext)
43
 
{
44
 
        CairoEmblem *pEmblem = g_new0 (CairoEmblem, 1);
45
 
        
46
 
        //\___________ On calcule les dimensions de l'embleme.
47
 
        int w, h;
48
 
        cairo_dock_get_icon_extent (pIcon, pContainer, &w, &h);
49
 
        pEmblem->iWidth = a * w;
50
 
        pEmblem->iHeight = a * h;
51
 
        
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);
54
 
        
55
 
        if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pEmblemSurface)
56
 
        {
57
 
                pEmblem->iTexture = cairo_dock_create_texture_from_surface (pEmblemSurface);
58
 
                cairo_surface_destroy (pEmblemSurface);
59
 
        }
60
 
        else
61
 
                pEmblem->pSurface = pEmblemSurface;
62
 
        
63
 
        return pEmblem;
64
 
}
65
 
 
66
 
CairoEmblem *cairo_dock_make_emblem_from_surface (cairo_surface_t *pSurface, int iSurfaceWidth, int iSurfaceHeight, Icon *pIcon, CairoContainer *pContainer)
67
 
{
68
 
        CairoEmblem *pEmblem = g_new0 (CairoEmblem, 1);
69
 
        
70
 
        int w, h;
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;
75
 
        return pEmblem;
76
 
}
77
 
 
78
 
CairoEmblem *cairo_dock_make_emblem_from_texture (GLuint iTexture, Icon *pIcon, CairoContainer *pContainer)
79
 
{
80
 
        CairoEmblem *pEmblem = g_new0 (CairoEmblem, 1);
81
 
        
82
 
        pEmblem->iTexture = iTexture;  // inutile de connaitre la taille de la texture.
83
 
        return pEmblem;
84
 
}
85
 
 
86
 
 
87
 
void cairo_dock_free_emblem (CairoEmblem *pEmblem)
88
 
{
89
 
        if (pEmblem == NULL)
90
 
                return;
91
 
        
92
 
        if (pEmblem->pSurface != NULL)
93
 
                cairo_surface_destroy (pEmblem->pSurface);
94
 
        if (pEmblem->iTexture != 0)
95
 
                _cairo_dock_delete_texture (pEmblem->iTexture);
96
 
        g_free (pEmblem);
97
 
}
98
 
 
99
 
 
100
 
static void _cairo_dock_apply_emblem_texture (CairoEmblem *pEmblem, int w, int h)
101
 
{
102
 
        double x, y;
103
 
        switch (pEmblem->iPosition)
104
 
        {
105
 
                case CAIRO_DOCK_EMBLEM_UPPER_RIGHT:
106
 
                        x = w/2 * (1 - a);
107
 
                        y = h/2 * (1 - a);
108
 
                break;
109
 
                case CAIRO_DOCK_EMBLEM_LOWER_RIGHT:
110
 
                        x = w/2 * (1 - a);
111
 
                        y = -h/2 * (1 - a);
112
 
                break;
113
 
                case CAIRO_DOCK_EMBLEM_UPPER_LEFT:
114
 
                        x = -(double)w/2 * (1 - a);
115
 
                        y = (double)h/2 * (1 - a);
116
 
                break;
117
 
                case CAIRO_DOCK_EMBLEM_LOWER_LEFT:
118
 
                default:
119
 
                        x = -w/2 * (1 - a);
120
 
                        y = -h/2 * (1 - a);
121
 
                break;
122
 
                case CAIRO_DOCK_EMBLEM_MIDDLE:
123
 
                        x = 0.;
124
 
                        y = 0.;
125
 
                break;
126
 
        }
127
 
        glBindTexture (GL_TEXTURE_2D, pEmblem->iTexture);
128
 
        _cairo_dock_apply_current_texture_at_size_with_offset (a*w, a*h, x, y);
129
 
}
130
 
static void _cairo_dock_apply_emblem_surface (CairoEmblem *pEmblem, int w, int h, cairo_t *pCairoContext)
131
 
{
132
 
        double zx = (double) a*w / pEmblem->iWidth;
133
 
        double zy = (double) a*h / pEmblem->iHeight;
134
 
        cairo_scale (pCairoContext, zx, zy);
135
 
        
136
 
        double x, y;
137
 
        switch (pEmblem->iPosition)
138
 
        {
139
 
                case CAIRO_DOCK_EMBLEM_UPPER_RIGHT:
140
 
                        x = w * (1 - a);
141
 
                        y = 0.;
142
 
                break;
143
 
                case CAIRO_DOCK_EMBLEM_LOWER_RIGHT:
144
 
                        x = w * (1 - a);
145
 
                        y = h * (1 - a);
146
 
                break;
147
 
                case CAIRO_DOCK_EMBLEM_UPPER_LEFT:
148
 
                        x = 0.;
149
 
                        y = 0.;
150
 
                break;
151
 
                case CAIRO_DOCK_EMBLEM_LOWER_LEFT:
152
 
                default:
153
 
                        x = 0.;
154
 
                        y = h * (1 - a);
155
 
                break;
156
 
                case CAIRO_DOCK_EMBLEM_MIDDLE:
157
 
                        x = w/2 * (1 - a);
158
 
                        y = h/2 * (1 - a);
159
 
                break;
160
 
        }
161
 
        cairo_set_source_surface (pCairoContext, pEmblem->pSurface, x/zx, y/zy);
162
 
        cairo_paint (pCairoContext);
163
 
}
164
 
void cairo_dock_draw_emblem_on_icon (CairoEmblem *pEmblem, Icon *pIcon, CairoContainer *pContainer)
165
 
{
166
 
        g_return_if_fail (pEmblem != NULL);
167
 
        
168
 
        int w, h;
169
 
        cairo_dock_get_icon_extent (pIcon, pContainer, &w, &h);
170
 
        
171
 
        if (pIcon->iIconTexture != 0 && pEmblem->iTexture != 0)  // dessin opengl : on dessine sur la texture de l'icone avec le mecanisme habituel.
172
 
        {
173
 
                if (! cairo_dock_begin_draw_icon (pIcon, pContainer))
174
 
                        return ;
175
 
                
176
 
                _cairo_dock_enable_texture ();
177
 
                
178
 
                _cairo_dock_set_blend_source ();
179
 
                
180
 
                _cairo_dock_apply_texture_at_size (pIcon->iIconTexture, w, h);
181
 
                
182
 
                _cairo_dock_set_blend_alpha ();
183
 
                
184
 
                _cairo_dock_apply_emblem_texture (pEmblem, w, h);
185
 
                
186
 
                _cairo_dock_disable_texture ();
187
 
                
188
 
                cairo_dock_end_draw_icon (pIcon, pContainer);
189
 
        }
190
 
        else if (pIcon->pIconBuffer != NULL && pEmblem->pSurface != NULL)
191
 
        {
192
 
                cairo_t *pCairoContext = cairo_create (pIcon->pIconBuffer);
193
 
                g_return_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS);
194
 
                
195
 
                _cairo_dock_apply_emblem_surface (pEmblem, w, h, pCairoContext);
196
 
                
197
 
                cairo_paint (pCairoContext);
198
 
                
199
 
                cairo_destroy (pCairoContext);
200
 
        }
201
 
}
202
 
 
203
 
 
204
 
static void _cairo_dock_draw_subdock_content_as_emblem (Icon *pIcon, CairoDock *pDock, int w, int h, cairo_t *pCairoContext)
205
 
{
206
 
        //\______________ On dessine les 4 premieres icones du sous-dock en embleme.
207
 
        CairoEmblem e;
208
 
        memset (&e, 0, sizeof (CairoEmblem));
209
 
        int i;
210
 
        Icon *icon;
211
 
        GList *ic;
212
 
        for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 4; ic = ic->next, i++)
213
 
        {
214
 
                icon = ic->data;
215
 
                if (CAIRO_DOCK_IS_SEPARATOR (icon))
216
 
                {
217
 
                        i --;
218
 
                        continue;
219
 
                }
220
 
                e.iPosition = i;
221
 
                if (pCairoContext == NULL)
222
 
                {
223
 
                        e.iTexture = icon->iIconTexture;
224
 
                        _cairo_dock_apply_emblem_texture (&e, w, h);
225
 
                }
226
 
                else
227
 
                {
228
 
                        e.pSurface = icon->pIconBuffer;
229
 
                        cairo_dock_get_icon_extent (icon, CAIRO_CONTAINER (pIcon->pSubDock), &e.iWidth, &e.iHeight);
230
 
                        
231
 
                        cairo_save (pCairoContext);
232
 
                        _cairo_dock_apply_emblem_surface (&e, w, h, pCairoContext);
233
 
                        cairo_restore (pCairoContext);
234
 
                }
235
 
        }
236
 
}
237
 
 
238
 
 
239
 
 
240
 
static void _cairo_dock_draw_subdock_content_as_stack (Icon *pIcon, CairoDock *pDock, int w, int h, cairo_t *pCairoContext)
241
 
{
242
 
        //\______________ On dessine les 4 premieres icones du sous-dock en pile.
243
 
        CairoEmblem e;
244
 
        memset (&e, 0, sizeof (CairoEmblem));
245
 
        double a_ = a;
246
 
        a = .8;
247
 
        int i;
248
 
        Icon *icon;
249
 
        GList *ic;
250
 
        for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 3; ic = ic->next, i++)
251
 
        {
252
 
                icon = ic->data;
253
 
                if (CAIRO_DOCK_IS_SEPARATOR (icon))
254
 
                {
255
 
                        i --;
256
 
                        continue;
257
 
                }
258
 
                switch (i)
259
 
                {
260
 
                        case 0:
261
 
                                e.iPosition = CAIRO_DOCK_EMBLEM_UPPER_RIGHT;
262
 
                        break;
263
 
                        case 1:
264
 
                                if (ic->next == NULL)
265
 
                                        e.iPosition = CAIRO_DOCK_EMBLEM_LOWER_LEFT;
266
 
                                else
267
 
                                        e.iPosition = CAIRO_DOCK_EMBLEM_MIDDLE;
268
 
                        break;
269
 
                        case 2:
270
 
                                e.iPosition = CAIRO_DOCK_EMBLEM_LOWER_LEFT;
271
 
                        break;
272
 
                        default : break;
273
 
                }
274
 
                if (pIcon->iIconTexture != 0)
275
 
                {
276
 
                        e.iTexture = icon->iIconTexture;
277
 
                        _cairo_dock_apply_emblem_texture (&e, w, h);
278
 
                }
279
 
                else
280
 
                {
281
 
                        e.pSurface = icon->pIconBuffer;
282
 
                        cairo_dock_get_icon_extent (icon, CAIRO_CONTAINER (pIcon->pSubDock), &e.iWidth, &e.iHeight);
283
 
                        
284
 
                        cairo_save (pCairoContext);
285
 
                        _cairo_dock_apply_emblem_surface (&e, w, h, pCairoContext);
286
 
                        cairo_restore (pCairoContext);
287
 
                }
288
 
        }
289
 
        a = a_;
290
 
}
291
 
 
292
 
 
293
 
/*static void _cairo_dock_draw_subdock_content_as_box (Icon *pIcon, CairoDock *pDock, int w, int h, cairo_t *pCairoContext)
294
 
{
295
 
        if (pCairoContext)
296
 
        {
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,
304
 
                        0.,
305
 
                        0.);
306
 
                cairo_paint (pCairoContext);
307
 
                cairo_restore (pCairoContext);
308
 
                
309
 
                cairo_save (pCairoContext);
310
 
                cairo_scale(pCairoContext,
311
 
                        .8,
312
 
                        .8);
313
 
                int i;
314
 
                Icon *icon;
315
 
                GList *ic;
316
 
                for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 3; ic = ic->next, i++)
317
 
                {
318
 
                        icon = ic->data;
319
 
                        if (CAIRO_DOCK_IS_SEPARATOR (icon))
320
 
                        {
321
 
                                i --;
322
 
                                continue;
323
 
                        }
324
 
                        
325
 
                        cairo_set_source_surface (pCairoContext,
326
 
                                icon->pIconBuffer,
327
 
                                .1*w,
328
 
                                .1*i*h);
329
 
                        cairo_paint (pCairoContext);
330
 
                }
331
 
                cairo_restore (pCairoContext);
332
 
                
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,
338
 
                        0.,
339
 
                        0.);
340
 
                cairo_paint (pCairoContext);
341
 
        }
342
 
        else
343
 
        {
344
 
                _cairo_dock_set_blend_source ();
345
 
                _cairo_dock_apply_texture_at_size (g_pBoxBelowBuffer.iTexture, w, h);
346
 
                
347
 
                _cairo_dock_set_blend_alpha ();
348
 
                int i;
349
 
                Icon *icon;
350
 
                GList *ic;
351
 
                for (ic = pIcon->pSubDock->icons, i = 0; ic != NULL && i < 3; ic = ic->next, i++)
352
 
                {
353
 
                        icon = ic->data;
354
 
                        if (CAIRO_DOCK_IS_SEPARATOR (icon))
355
 
                        {
356
 
                                i --;
357
 
                                continue;
358
 
                        }
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);
361
 
                }
362
 
                
363
 
                _cairo_dock_apply_texture_at_size (g_pBoxAboveBuffer.iTexture, w, h);
364
 
        }
365
 
}*/  // 2.1.4
366
 
 
367
 
void cairo_dock_draw_subdock_content_on_icon (Icon *pIcon, CairoDock *pDock)
368
 
{
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);
371
 
        
372
 
        int w, h;
373
 
        cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pDock), &w, &h);
374
 
        
375
 
        //\______________ On efface le dessin existant.
376
 
        cairo_t *pCairoContext = NULL;
377
 
        if (pIcon->iIconTexture != 0)  // dessin opengl
378
 
        {
379
 
                if (! cairo_dock_begin_draw_icon (pIcon, CAIRO_CONTAINER (pDock)))
380
 
                        return ;
381
 
                
382
 
                _cairo_dock_set_blend_source ();
383
 
                if (g_pIconBackgroundBuffer.iTexture != 0)  // on ecrase le dessin existant avec l'image de fond des icones.
384
 
                {
385
 
                        _cairo_dock_enable_texture ();
386
 
                        _cairo_dock_set_alpha (1.);
387
 
                        _cairo_dock_apply_texture_at_size (g_pIconBackgroundBuffer.iTexture, w, h);
388
 
                }
389
 
                else  // sinon on efface juste ce qu'il y'avait.
390
 
                {
391
 
                        glPolygonMode (GL_FRONT, GL_FILL);
392
 
                        _cairo_dock_set_alpha (0.);
393
 
                        glBegin(GL_QUADS);
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.);
398
 
                        glEnd();
399
 
                        _cairo_dock_enable_texture ();
400
 
                        _cairo_dock_set_alpha (1.);
401
 
                }
402
 
                _cairo_dock_set_blend_alpha ();
403
 
        }
404
 
        else if (pIcon->pIconBuffer != NULL)  // dessin cairo
405
 
        {
406
 
                pCairoContext = cairo_create (pIcon->pIconBuffer);
407
 
                g_return_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS);
408
 
                
409
 
                if (g_pIconBackgroundBuffer.pSurface != NULL)  // on ecrase le dessin existant avec l'image de fond des icones.
410
 
                {
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,
417
 
                                0.,
418
 
                                0.);
419
 
                        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
420
 
                        cairo_paint (pCairoContext);
421
 
                        cairo_restore (pCairoContext);
422
 
                }
423
 
                else  // sinon on efface juste ce qu'il y'avait.
424
 
                {
425
 
                        cairo_dock_erase_cairo_context (pCairoContext);
426
 
                }
427
 
                cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
428
 
        }
429
 
        else
430
 
                return ;
431
 
        
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);
435
 
        else
436
 
        {
437
 
                switch (pIcon->iSubdockViewType)
438
 
                {
439
 
                        case 1 :
440
 
                                _cairo_dock_draw_subdock_content_as_emblem (pIcon, pDock, w, h, pCairoContext);
441
 
                        break;
442
 
                        case 2:
443
 
                                _cairo_dock_draw_subdock_content_as_stack (pIcon, pDock, w, h, pCairoContext);
444
 
                        break;
445
 
                        /*case 3:
446
 
                                _cairo_dock_draw_subdock_content_as_box (pIcon, pDock, w, h, pCairoContext);
447
 
                        break;*/  // 2.1.4
448
 
                        default:
449
 
                                cd_warning ("invalid sub-dock content view for %s", pIcon->cName);
450
 
                        break;
451
 
                }
452
 
        }
453
 
        
454
 
        //\______________ On finit le dessin.
455
 
        if (pIcon->iIconTexture != 0)
456
 
        {
457
 
                _cairo_dock_disable_texture ();
458
 
                cairo_dock_end_draw_icon (pIcon, CAIRO_CONTAINER (pDock));
459
 
        }
460
 
        else
461
 
        {
462
 
                if (g_bUseOpenGL)
463
 
                        cairo_dock_update_icon_texture (pIcon);
464
 
                else
465
 
                        cairo_dock_add_reflection_to_icon (pCairoContext, pIcon, CAIRO_CONTAINER (pDock));
466
 
                cairo_destroy (pCairoContext);
467
 
        }
468
 
}