~cairo-dock-team/cairo-dock-plug-ins/plug-ins

« back to all changes in this revision

Viewing changes to switcher/src/applet-draw.c

  • Committer: Matthieu Baerts
  • Date: 2014-10-19 00:26:10 UTC
  • Revision ID: matttbe@gmail.com-20141019002610-ulf26s9b4c4rw10r
We just switched from BZR to Git.
Follow us on Github: https://github.com/Cairo-Dock

Note: we will only use Github to manage our source code and all pull requests.
Please continue to report your bugs/ideas/messages on our forum or Launchpad! 

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 <string.h>
21
 
#include <glib/gstdio.h>
22
 
#include <math.h>
23
 
 
24
 
#include "applet-struct.h"
25
 
#include "applet-load-icons.h"
26
 
#include "applet-desktops.h"
27
 
#include "applet-draw.h"
28
 
 
29
 
typedef struct {
30
 
        gint iNumDesktop;
31
 
        gint iNumViewportX;
32
 
        gint iNumViewportY;
33
 
        gint iOneViewportWidth;
34
 
        gint iOneViewportHeight;
35
 
        cairo_t *pCairoContext;
36
 
        } CDSwitcherDesktop;
37
 
 
38
 
static void _cd_switcher_draw_windows_on_viewport (Icon *pIcon, CDSwitcherDesktop *data)
39
 
{
40
 
        if (pIcon == NULL || pIcon->fInsertRemoveFactor > 0)
41
 
                return ;
42
 
        GldiWindowActor *actor = pIcon->pAppli;
43
 
        if (actor->bIsHidden && ! myConfig.bDisplayHiddenWindows)
44
 
                return ;
45
 
        int iNumDesktop = data->iNumDesktop;
46
 
        int iNumViewportX = data->iNumViewportX;
47
 
        int iNumViewportY = data->iNumViewportY;
48
 
        int iOneViewportWidth = data->iOneViewportWidth;
49
 
        int iOneViewportHeight = data->iOneViewportHeight;
50
 
        cairo_t *pCairoContext = data->pCairoContext;
51
 
        
52
 
        // On calcule les coordonnees en repere absolu.
53
 
        int x = actor->windowGeometry.x;  // par rapport au viewport courant.
54
 
        x += myData.switcher.iCurrentViewportX * g_desktopGeometry.Xscreen.width;  // repere absolu
55
 
        if (x < 0)
56
 
                x += g_desktopGeometry.iNbViewportX * g_desktopGeometry.Xscreen.width;
57
 
        int y = actor->windowGeometry.y;
58
 
        y += myData.switcher.iCurrentViewportY * g_desktopGeometry.Xscreen.height;
59
 
        if (y < 0)
60
 
                y += g_desktopGeometry.iNbViewportY * g_desktopGeometry.Xscreen.height;
61
 
        int w = actor->windowGeometry.width, h = actor->windowGeometry.height;
62
 
        
63
 
        // test d'intersection avec le viewport donne.
64
 
        //g_print (" %s : (%d;%d) %dx%d\n", pIcon->cName, x, y, w, h);
65
 
        if ((actor->iNumDesktop != -1 && actor->iNumDesktop != iNumDesktop) ||
66
 
                x + w <= iNumViewportX * g_desktopGeometry.Xscreen.width ||
67
 
                x >= (iNumViewportX + 1) * g_desktopGeometry.Xscreen.width ||
68
 
                y + h <= iNumViewportY * g_desktopGeometry.Xscreen.height ||
69
 
                y >= (iNumViewportY + 1) * g_desktopGeometry.Xscreen.height)
70
 
                return ;
71
 
        
72
 
        // on dessine ses traits.
73
 
        cairo_save (pCairoContext);
74
 
 
75
 
        GldiWindowActor *pActiveWindow = gldi_windows_get_active ();
76
 
        
77
 
        if (myConfig.bFillAllWindows && actor != pActiveWindow)
78
 
                cairo_set_source_rgba (pCairoContext, myConfig.RGBWFillColors[0], myConfig.RGBWFillColors[1], myConfig.RGBWFillColors[2], myConfig.RGBWFillColors[3]);
79
 
        else
80
 
        {
81
 
                if (myConfig.bUseDefaultColors)
82
 
                        gldi_style_colors_set_line_color (myDrawContext);
83
 
                else
84
 
                        cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
85
 
        }
86
 
        cairo_rectangle (pCairoContext,
87
 
                (1.*x/g_desktopGeometry.Xscreen.width - iNumViewportX)*iOneViewportWidth,
88
 
                (1.*y/g_desktopGeometry.Xscreen.height - iNumViewportY)*iOneViewportHeight,
89
 
                1.*w/g_desktopGeometry.Xscreen.width*iOneViewportWidth,
90
 
                1.*h/g_desktopGeometry.Xscreen.height*iOneViewportHeight);
91
 
 
92
 
        if (myConfig.bFillAllWindows || actor == pActiveWindow)
93
 
        {
94
 
                //g_print (" %s est la fenetre active\n", pIcon->cName);
95
 
                cairo_fill (pCairoContext);
96
 
        }
97
 
        else
98
 
        {
99
 
                cairo_stroke (pCairoContext);
100
 
        }
101
 
        
102
 
        if (myConfig.bDrawIcons)
103
 
        {
104
 
                const CairoDockImageBuffer *pImage = gldi_appli_icon_get_image_buffer (pIcon);
105
 
                if (pImage && pImage->pSurface)
106
 
                {
107
 
                        double fZoomX = (double) w/g_desktopGeometry.Xscreen.width*iOneViewportWidth / pImage->iWidth;
108
 
                        double fZoomY = (double) h/g_desktopGeometry.Xscreen.height*iOneViewportHeight / pImage->iHeight;
109
 
                        double fZoom = MIN (fZoomX, fZoomY);  // on garde le ratio.
110
 
                        
111
 
                        cairo_translate (pCairoContext,
112
 
                                (1.*x/g_desktopGeometry.Xscreen.width - iNumViewportX)*iOneViewportWidth + (fZoomX - fZoom) * pImage->iWidth/2,
113
 
                                (1.*y/g_desktopGeometry.Xscreen.height - iNumViewportY)*iOneViewportHeight + (fZoomY - fZoom) * pImage->iHeight/2);
114
 
                        cairo_scale (pCairoContext,
115
 
                                fZoom,
116
 
                                fZoom);
117
 
                        cairo_set_source_surface (pCairoContext,
118
 
                                pImage->pSurface,
119
 
                                0.,
120
 
                                0.);
121
 
                        cairo_paint (pCairoContext);
122
 
                }
123
 
        }
124
 
        
125
 
        cairo_restore (pCairoContext);
126
 
}
127
 
 
128
 
 
129
 
static int _compare_icons_stack_order (Icon *icon1, Icon *icon2)
130
 
{
131
 
        if (icon1 == NULL)  // les icones nulles vont a la fin.
132
 
                return 1;
133
 
        if (icon2 == NULL)
134
 
                return -1;
135
 
        if (icon1->pAppli->iStackOrder < icon2->pAppli->iStackOrder)  // ordre petit => dessus => dessinee en dernier.
136
 
                return -1;
137
 
        else
138
 
                return 1;
139
 
}
140
 
void cd_switcher_draw_main_icon_compact_mode (void)
141
 
{
142
 
        if (myData.switcher.iNbColumns == 0 || myData.switcher.iNbLines == 0)  // may happen in desklet mode with a cube desktop, when the desklet is still 0x0.
143
 
                return;
144
 
        CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN_CAIRO ();
145
 
        ///g_return_if_fail (myDrawContext != NULL);
146
 
        //g_print ("%s (%d;%d)\n", __func__, myData.switcher.iCurrentLine, myData.switcher.iCurrentColumn);
147
 
        // On efface l'icone.
148
 
        ///cairo_dock_erase_cairo_context (myDrawContext);
149
 
        
150
 
        // definition des parametres de dessin.
151
 
        int iWidth, iHeight;
152
 
        CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
153
 
        
154
 
        myData.switcher.fOneViewportHeight = (double) (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
155
 
        myData.switcher.fOneViewportWidth = (double) (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.
156
 
        double dx=0, dy=0;
157
 
        double w = iWidth, h = iHeight;
158
 
        if (myConfig.bPreserveScreenRatio)
159
 
        {
160
 
                double r = (double) g_desktopGeometry.Xscreen.width / g_desktopGeometry.Xscreen.height;
161
 
                double r_ = myData.switcher.fOneViewportWidth / myData.switcher.fOneViewportHeight;
162
 
                if (r_ > r)  // on etire trop en largeur.
163
 
                {
164
 
                        myData.switcher.fOneViewportWidth /= r_ / r;
165
 
                        w = myData.switcher.fOneViewportWidth * myData.switcher.iNbColumns + 2 * myConfig.iLineSize + (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize;
166
 
                        dx = (double) (iWidth - w) / 2;
167
 
                }
168
 
                else
169
 
                {
170
 
                        myData.switcher.fOneViewportHeight /= r / r_;
171
 
                        h = myData.switcher.fOneViewportHeight * myData.switcher.iNbLines + 2 * myConfig.iLineSize + (myData.switcher.iNbLines - 1) * myConfig.iInLineSize;
172
 
                        dy = (iHeight - h) / 2;
173
 
                }
174
 
        }
175
 
        myData.switcher.fOffsetX = dx;
176
 
        myData.switcher.fOffsetY = dy;
177
 
        
178
 
        cairo_save (myDrawContext);
179
 
        cairo_translate (myDrawContext, dx, dy);
180
 
        
181
 
        cairo_surface_t *pSurface = NULL;
182
 
        double fZoomX, fZoomY;
183
 
        if (myConfig.iIconDrawing == SWICTHER_MAP_WALLPAPER)
184
 
        {
185
 
                pSurface = myData.pDesktopBgMapSurface;
186
 
        }
187
 
        if (pSurface == NULL)
188
 
        {
189
 
                pSurface = myData.pDefaultMapSurface;
190
 
        }
191
 
        fZoomX = (double) myData.switcher.fOneViewportWidth / myData.iSurfaceWidth;  // both surfaces are loaded at the same size.
192
 
        fZoomY= (double) myData.switcher.fOneViewportHeight / myData.iSurfaceHeight;
193
 
        
194
 
        // cadre exterieur.
195
 
        cairo_set_line_width (myDrawContext,myConfig.iLineSize);
196
 
        if (myConfig.bUseDefaultColors)
197
 
                gldi_style_colors_set_line_color (myDrawContext);
198
 
        else
199
 
                cairo_set_source_rgba(myDrawContext,myConfig.RGBLineColors[0],myConfig.RGBLineColors[1],myConfig.RGBLineColors[2],myConfig.RGBLineColors[3]);
200
 
        cairo_rectangle(myDrawContext,
201
 
                .5*myConfig.iLineSize,
202
 
                .5*myConfig.iLineSize,
203
 
                w - myConfig.iLineSize,
204
 
                h - myConfig.iLineSize);
205
 
 
206
 
        cairo_stroke (myDrawContext);
207
 
        
208
 
        // lignes interieures.
209
 
        cairo_set_line_width (myDrawContext,myConfig.iInLineSize);
210
 
        if (myConfig.bUseDefaultColors)
211
 
                gldi_style_colors_set_line_color (myDrawContext);
212
 
        else
213
 
                cairo_set_source_rgba (myDrawContext,myConfig.RGBInLineColors[0],myConfig.RGBInLineColors[1],myConfig.RGBInLineColors[2],myConfig.RGBInLineColors[3]);
214
 
        double xi, yj;
215
 
        int i, j;
216
 
        for (i = 1; i < myData.switcher.iNbColumns; i ++)  // lignes verticales.
217
 
        {
218
 
                xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
219
 
                cairo_move_to (myDrawContext, xi, myConfig.iLineSize);
220
 
                cairo_rel_line_to (myDrawContext, 0, h - 2*myConfig.iLineSize);
221
 
                cairo_stroke (myDrawContext);
222
 
        }
223
 
        for (j = 1; j < myData.switcher.iNbLines; j ++)  // lignes horizontales.
224
 
        {
225
 
                yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
226
 
                cairo_move_to (myDrawContext, myConfig.iLineSize, yj);
227
 
                cairo_rel_line_to (myDrawContext, w - 2*myConfig.iLineSize, 0);
228
 
                cairo_stroke (myDrawContext);
229
 
        }
230
 
        
231
 
        GList *pWindowList = NULL;
232
 
        if (myConfig.bDrawWindows)
233
 
        {
234
 
                pWindowList = cairo_dock_get_current_applis_list ();
235
 
                pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
236
 
        }
237
 
        
238
 
        // chaque bureau/viewport.
239
 
        int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
240
 
        int k = 0, N = g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY;
241
 
        for (j = 0; j < myData.switcher.iNbLines && k < N; j ++)
242
 
        {
243
 
                for (i = 0; i < myData.switcher.iNbColumns && k < N; i ++)
244
 
                {
245
 
                        cairo_save (myDrawContext);
246
 
 
247
 
                        xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
248
 
                        yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);
249
 
 
250
 
                        cairo_translate (myDrawContext,
251
 
                                xi,
252
 
                                yj);
253
 
 
254
 
                        cairo_scale (myDrawContext,
255
 
                                fZoomX,
256
 
                                fZoomY);
257
 
                        cairo_set_source_surface (myDrawContext,
258
 
                                pSurface,
259
 
                                0.,
260
 
                                0.);
261
 
                        cairo_paint(myDrawContext);
262
 
                        
263
 
                        cairo_restore (myDrawContext);
264
 
                        
265
 
                        if ((myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL_INVERTED && (i != myData.switcher.iCurrentColumn || j != myData.switcher.iCurrentLine))
266
 
                        || (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL && (i == myData.switcher.iCurrentColumn && j == myData.switcher.iCurrentLine)))
267
 
                        {
268
 
                                cairo_save (myDrawContext);
269
 
                                
270
 
                                if (myConfig.bUseDefaultColors)
271
 
                                        gldi_style_colors_set_selected_bg_color (myDrawContext);
272
 
                                else
273
 
                                        cairo_set_source_rgba (myDrawContext, myConfig.RGBIndColors[0], myConfig.RGBIndColors[1], myConfig.RGBIndColors[2], myConfig.RGBIndColors[3]);
274
 
                                cairo_rectangle(myDrawContext,
275
 
                                        xi - .5*myConfig.iLineSize,
276
 
                                        yj - .5*myConfig.iLineSize,
277
 
                                        myData.switcher.fOneViewportWidth + myConfig.iLineSize,
278
 
                                        myData.switcher.fOneViewportHeight + myConfig.iLineSize);
279
 
                                cairo_fill (myDrawContext);
280
 
                                
281
 
                                cairo_restore (myDrawContext);
282
 
                        }
283
 
                        
284
 
                        if (myConfig.bDrawWindows)
285
 
                        {
286
 
                                cairo_save (myDrawContext);
287
 
                                
288
 
                                cairo_translate (myDrawContext,
289
 
                                        xi,
290
 
                                        yj);
291
 
                                cairo_set_line_width (myDrawContext, 1.);
292
 
                                cairo_rectangle (myDrawContext,
293
 
                                        0.,
294
 
                                        0.,
295
 
                                        myData.switcher.fOneViewportWidth,
296
 
                                        myData.switcher.fOneViewportHeight);
297
 
                                cairo_clip (myDrawContext);
298
 
                                
299
 
                                //g_print (" dessin des fenetres du bureau (%d;%d;%d) ...\n", iNumDesktop, iNumViewportX, iNumViewportY);
300
 
                                CDSwitcherDesktop data = {iNumDesktop, iNumViewportX, iNumViewportY, (int) myData.switcher.fOneViewportWidth, (int) myData.switcher.fOneViewportHeight, myDrawContext};
301
 
                                g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, &data);
302
 
                                
303
 
                                cairo_restore (myDrawContext);
304
 
                        }
305
 
                        
306
 
                        iNumViewportX ++;
307
 
                        if (iNumViewportX == g_desktopGeometry.iNbViewportX)
308
 
                        {
309
 
                                iNumViewportX = 0;
310
 
                                iNumViewportY ++;
311
 
                                if (iNumViewportY == g_desktopGeometry.iNbViewportY)
312
 
                                {
313
 
                                        iNumViewportY = 0;
314
 
                                        iNumDesktop ++;
315
 
                                }
316
 
                        }
317
 
                        k ++;
318
 
                }
319
 
        }
320
 
        
321
 
        // dessin de l'indicateur sur le bureau courant (on le fait maintenant car dans le cas ou la ligne interieure est plus petite que la ligne de l'indicateur, les surfaces suivantes recouvreraient en partie la ligne.
322
 
        if (myConfig.iDrawCurrentDesktopMode == SWICTHER_DRAW_FRAME)
323
 
        {
324
 
                i = myData.switcher.iCurrentColumn;
325
 
                j = myData.switcher.iCurrentLine;
326
 
                xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
327
 
                yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);
328
 
                
329
 
                cairo_set_line_width (myDrawContext,myConfig.iLineSize);
330
 
                if (myConfig.bUseDefaultColors)
331
 
                        gldi_style_colors_set_selected_bg_color (myDrawContext);
332
 
                else
333
 
                        cairo_set_source_rgba (myDrawContext,myConfig.RGBIndColors[0],myConfig.RGBIndColors[1],myConfig.RGBIndColors[2],myConfig.RGBIndColors[3]);
334
 
                cairo_rectangle(myDrawContext,
335
 
                        xi - .5*myConfig.iLineSize,
336
 
                        yj - .5*myConfig.iLineSize,
337
 
                        myData.switcher.fOneViewportWidth + myConfig.iLineSize,
338
 
                        myData.switcher.fOneViewportHeight + myConfig.iLineSize);
339
 
                
340
 
                if (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL)
341
 
                        cairo_fill (myDrawContext);  // maybe we need to fill it with an alpha pattern in case we use the global style color ?...
342
 
                else
343
 
                {
344
 
                        cairo_set_line_width (myDrawContext, MIN (4, 2*myConfig.iLineSize));
345
 
                        cairo_stroke(myDrawContext);
346
 
                }
347
 
        }
348
 
        
349
 
        cairo_restore (myDrawContext);
350
 
        g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
351
 
        
352
 
        CD_APPLET_FINISH_DRAWING_MY_ICON_CAIRO;
353
 
}
354
 
 
355
 
 
356
 
void cd_switcher_draw_main_icon_expanded_mode (void)
357
 
{
358
 
        // apply the desktop bg or the user image on the main icon, in dock mode
359
 
        int iWidth, iHeight;
360
 
        
361
 
        if (myDock)
362
 
        {
363
 
                CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
364
 
                myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
365
 
                myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.
366
 
 
367
 
                cairo_surface_t *pSurface = NULL;
368
 
                double fZoomX, fZoomY;
369
 
                if (myConfig.iIconDrawing == SWICTHER_MAP_WALLPAPER)
370
 
                {
371
 
                        cairo_dock_erase_cairo_context (myDrawContext);
372
 
 
373
 
                        pSurface = myData.pDesktopBgMapSurface;
374
 
                        fZoomX = 1. * iWidth / myData.iSurfaceWidth;
375
 
                        fZoomY= 1. * iHeight / myData.iSurfaceHeight;
376
 
                        cairo_translate (myDrawContext,
377
 
                                0.,
378
 
                                0.);
379
 
 
380
 
                        cairo_save (myDrawContext);
381
 
                        cairo_scale (myDrawContext,
382
 
                                fZoomX ,
383
 
                                fZoomY );
384
 
                        cairo_set_source_surface (myDrawContext,
385
 
                                pSurface,
386
 
                                0.,
387
 
                                0.);
388
 
                        cairo_paint(myDrawContext);
389
 
                        cairo_restore (myDrawContext);
390
 
 
391
 
                        if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
392
 
                                cairo_dock_update_icon_texture (myIcon);
393
 
                }
394
 
                else
395
 
                {
396
 
                        CD_APPLET_SET_IMAGE_ON_MY_ICON (MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
397
 
                }
398
 
        }
399
 
        
400
 
        if (myConfig.bDrawWindows)
401
 
        {
402
 
                GList *pWindowList = cairo_dock_get_current_applis_list ();
403
 
                pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
404
 
                
405
 
                CDSwitcherDesktop data;
406
 
                int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
407
 
                cairo_t *pCairoContext;
408
 
                Icon *pIcon;
409
 
                GList *pIconsList = CD_APPLET_MY_ICONS_LIST;
410
 
                GList *ic;
411
 
                for (ic = pIconsList; ic != NULL; ic = ic->next)
412
 
                {
413
 
                        pIcon = ic->data;
414
 
                        cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
415
 
                        
416
 
                        pCairoContext = cairo_create (pIcon->image.pSurface);
417
 
                        cairo_set_line_width (pCairoContext, 1.);
418
 
                        if (myConfig.bUseDefaultColors)
419
 
                                gldi_style_colors_set_line_color (myDrawContext);
420
 
                        else
421
 
                                cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
422
 
                        
423
 
                        data.iNumDesktop = iNumDesktop;
424
 
                        data.iNumViewportX = iNumViewportX;
425
 
                        data.iNumViewportY = iNumViewportY;
426
 
                        data.iOneViewportWidth = iWidth;
427
 
                        data.iOneViewportHeight = iHeight;
428
 
                        data.pCairoContext = pCairoContext;
429
 
                        g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, &data);
430
 
                        
431
 
                        iNumViewportX ++;
432
 
                        if (iNumViewportX == g_desktopGeometry.iNbViewportX)
433
 
                        {
434
 
                                iNumViewportY ++;
435
 
                                if (iNumViewportY == g_desktopGeometry.iNbViewportY)
436
 
                                        iNumDesktop ++;
437
 
                        }
438
 
                        cairo_destroy (pCairoContext);
439
 
                }
440
 
                g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
441
 
        }
442
 
}
443
 
 
444
 
/*Fonction de base pour toutes les autres*/
445
 
void cd_switcher_draw_main_icon (void)
446
 
{
447
 
        cd_message ("%s (%d)", __func__, myConfig.bCompactView);
448
 
        if (myConfig.bCompactView)
449
 
        {
450
 
                cd_switcher_draw_main_icon_compact_mode ();
451
 
        }
452
 
        else
453
 
        {
454
 
                cd_switcher_draw_main_icon_expanded_mode ();
455
 
        }
456
 
        
457
 
        CD_APPLET_REDRAW_MY_ICON;
458
 
}
459
 
 
460
 
 
461
 
void cd_switcher_draw_desktops_bounding_box (CairoDesklet *pDesklet)
462
 
{
463
 
        CD_APPLET_ENTER;
464
 
        //g_print ("%s (%.2Fx%.2f)\n", __func__, myData.switcher.fOneViewportWidth, myData.switcher.fOneViewportHeight);
465
 
        double x, y, w, h;
466
 
        glTranslatef (-pDesklet->container.iWidth/2, -pDesklet->container.iHeight/2, 0.);
467
 
        
468
 
        w = myData.switcher.fOneViewportWidth/2;
469
 
        h = myData.switcher.fOneViewportHeight/2;
470
 
        int i, j;
471
 
        int k = 0, N = g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY;
472
 
        
473
 
        for (j = 0; j < myData.switcher.iNbLines; j ++)  // lignes horizontales.
474
 
        {
475
 
                y = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
476
 
                y = pDesklet->container.iHeight - (y + h + myData.switcher.fOffsetY);   
477
 
                
478
 
                for (i = 0; i < myData.switcher.iNbColumns; i ++)  // lignes verticales.
479
 
                {
480
 
                        x = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
481
 
                        x += w + myData.switcher.fOffsetX;
482
 
                        
483
 
                        glLoadName(i * myData.switcher.iNbLines + j + 1);  // +1 pour ne pas avoir 0.
484
 
                        
485
 
                        glBegin(GL_QUADS);
486
 
                        glVertex3f(x-w, y+h, 0.);
487
 
                        glVertex3f(x+w, y+h, 0.);
488
 
                        glVertex3f(x+w, y-h, 0.);
489
 
                        glVertex3f(x-w, y-h, 0.);
490
 
                        glEnd();
491
 
                        
492
 
                        k ++;
493
 
                        if (k == N)
494
 
                                break;
495
 
                }
496
 
        }
497
 
        CD_APPLET_LEAVE ();
498
 
}
499
 
 
500
 
void cd_switcher_extract_viewport_coords_from_picked_object (CairoDesklet *pDesklet, int *iCoordX, int *iCoordY)
501
 
{
502
 
        //g_print ("%s (%d)\n", __func__, pDesklet->iPickedObject);
503
 
        if (pDesklet->iPickedObject != 0)
504
 
        {
505
 
                pDesklet->iPickedObject --;  // cf le +1
506
 
                int i, j;
507
 
                i = pDesklet->iPickedObject / myData.switcher.iNbLines;
508
 
                j = pDesklet->iPickedObject % myData.switcher.iNbLines;
509
 
                //g_print ("bureau (%d;%d)\n", i, j);
510
 
                
511
 
                double x, y, w, h;
512
 
                w = myData.switcher.fOneViewportWidth/2;
513
 
                h = myData.switcher.fOneViewportHeight/2;
514
 
                x = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
515
 
                x += w + myData.switcher.fOffsetX;
516
 
                y = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
517
 
                y += h + myData.switcher.fOffsetY;
518
 
                *iCoordX = x;
519
 
                *iCoordY = y;
520
 
        }
521
 
}
522
 
 
523
 
 
524
 
static void _show_window (GtkMenuItem *menu_item, Icon *pIcon)
525
 
{
526
 
        CD_APPLET_ENTER;
527
 
        gldi_window_show (pIcon->pAppli);
528
 
        CD_APPLET_LEAVE ();
529
 
}
530
 
 
531
 
static void _show_desktop (GtkMenuItem *menu_item, gpointer data)
532
 
{
533
 
        CD_APPLET_ENTER;
534
 
        int iIndex = GPOINTER_TO_INT (data);
535
 
        int iNumDesktop, iNumViewportX, iNumViewportY;
536
 
        cd_switcher_compute_desktop_from_index (iIndex, &iNumDesktop, &iNumViewportX, &iNumViewportY);
537
 
        
538
 
        if (iNumViewportX != myData.switcher.iCurrentViewportX
539
 
        || iNumViewportY != myData.switcher.iCurrentViewportY
540
 
        || iNumDesktop != myData.switcher.iCurrentDesktop)
541
 
                gldi_desktop_set_current (iNumDesktop, iNumViewportX, iNumViewportY);
542
 
        CD_APPLET_LEAVE ();
543
 
}
544
 
static void _cd_switcher_add_window_on_viewport (Icon *pIcon, int iNumDesktop, int iNumViewportX, int iNumViewportY, GtkWidget *pMenu)
545
 
{
546
 
        //g_print (" + %s\n", pIcon->cName);
547
 
        
548
 
        // on cree une copie de la surface de l'icone a la taille du menu.
549
 
        GdkPixbuf *pixbuf = cairo_dock_icon_buffer_to_pixbuf (pIcon);
550
 
        if (pixbuf == NULL)  // icon not loaded (because not in a dock, because inhibited)
551
 
        {
552
 
                const gchar *cIcon = cairo_dock_get_class_icon (pIcon->cClass);
553
 
                gint iDesiredIconSize = cairo_dock_search_icon_size (GTK_ICON_SIZE_LARGE_TOOLBAR); // 24px
554
 
                gchar *cIconPath = cairo_dock_search_icon_s_path (cIcon, iDesiredIconSize);
555
 
                if (cIconPath)
556
 
                {
557
 
                        pixbuf = gdk_pixbuf_new_from_file_at_size (cIconPath,
558
 
                                iDesiredIconSize,
559
 
                                iDesiredIconSize,
560
 
                                NULL);
561
 
                }
562
 
        }
563
 
        
564
 
        // on ajoute une entree au menu avec le pixbuf.
565
 
        gchar *cLabel = cairo_dock_cut_string (pIcon->cName, 50);
566
 
        GtkWidget *pMenuItem = gldi_menu_add_item (pMenu, cLabel, "", G_CALLBACK (_show_window), pIcon);
567
 
        g_free (cLabel);
568
 
        
569
 
        if (pixbuf)
570
 
        {
571
 
                GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf);
572
 
                gldi_menu_item_set_image (pMenuItem, image);
573
 
                g_object_unref (pixbuf);
574
 
        }
575
 
}
576
 
void cd_switcher_build_windows_list (GtkWidget *pMenu)
577
 
{
578
 
        GList *pWindowList = NULL;
579
 
        pWindowList = cairo_dock_get_current_applis_list ();
580
 
        pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
581
 
        
582
 
        // chaque bureau/viewport.
583
 
        int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
584
 
        int k = 0, N = g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY;
585
 
        int iIndex = cd_switcher_compute_index_from_desktop (myData.switcher.iCurrentDesktop, myData.switcher.iCurrentViewportX, myData.switcher.iCurrentViewportY);
586
 
        GString *sDesktopName = g_string_new ("");
587
 
        int i, j;
588
 
        for (j = 0; j < myData.switcher.iNbLines; j ++)
589
 
        {
590
 
                for (i = 0; i < myData.switcher.iNbColumns; i ++)
591
 
                {
592
 
                        // on ajoute le nom du bureau/viewport dans le menu.
593
 
                        GtkWidget *pMenuItem = gtk_separator_menu_item_new ();
594
 
                        gtk_menu_shell_append(GTK_MENU_SHELL (pMenu), pMenuItem);
595
 
                        g_object_set (pMenuItem, "height-request", 3, NULL);
596
 
                        
597
 
                        if (k < myData.iNbNames)
598
 
                        {
599
 
                                if (k == iIndex)
600
 
                                        g_string_printf (sDesktopName, "<b>%s (%s)</b>", myData.cDesktopNames[k], D_("Current"));
601
 
                                else
602
 
                                        g_string_printf (sDesktopName, "<b>%s</b>", myData.cDesktopNames[k]);
603
 
                        }
604
 
                        else
605
 
                        {
606
 
                                if (k == iIndex)
607
 
                                        g_string_printf (sDesktopName, "<b>%s %d (%s)</b>", D_("Desktop"), k+1, D_("Current"));
608
 
                                else
609
 
                                        g_string_printf (sDesktopName, "<b>%s %d</b>", D_("Desktop"), k+1);
610
 
                        }
611
 
                        pMenuItem = gldi_menu_add_item (pMenu, sDesktopName->str, NULL, G_CALLBACK (_show_desktop), GINT_TO_POINTER (k));
612
 
                        GtkWidget *pLabel = gtk_bin_get_child (GTK_BIN(pMenuItem));
613
 
                        gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE);
614
 
                        gtk_misc_set_alignment (GTK_MISC (pLabel), .5, .5);
615
 
                        
616
 
                        pMenuItem = gtk_separator_menu_item_new ();
617
 
                        gtk_menu_shell_append(GTK_MENU_SHELL (pMenu), pMenuItem);
618
 
                        g_object_set (pMenuItem, "height-request", 3, NULL);
619
 
                        
620
 
                        // on ajoute les fenetres du viewport au menu.
621
 
                        cd_debug ("Windows' listing (%d;%d;%d) ...", iNumDesktop, iNumViewportX, iNumViewportY);
622
 
                        cd_switcher_foreach_window_on_viewport (iNumDesktop,
623
 
                                iNumViewportX,
624
 
                                iNumViewportY,
625
 
                                (CDSwitcherActionOnViewportFunc) _cd_switcher_add_window_on_viewport,
626
 
                                pMenu);
627
 
                        
628
 
                        // on passe au viewport suivant.
629
 
                        iNumViewportX ++;
630
 
                        if (iNumViewportX == g_desktopGeometry.iNbViewportX)
631
 
                        {
632
 
                                iNumViewportX = 0;
633
 
                                iNumViewportY ++;
634
 
                                if (iNumViewportY == g_desktopGeometry.iNbViewportY)
635
 
                                {
636
 
                                        iNumViewportY = 0;
637
 
                                        iNumDesktop ++;
638
 
                                }
639
 
                        }
640
 
                        k ++;
641
 
                        if (k == N)
642
 
                                break ;
643
 
                }
644
 
        }
645
 
        g_string_free (sDesktopName, TRUE);
646
 
}
647
 
 
648
 
 
649
 
 
650
 
static void _cd_switcher_move_window_to_viewport (Icon *pIcon, int iNumDesktop, int iNumViewportX, int iNumViewportY, gint *data)
651
 
{
652
 
        int iDestNumDesktop = data[0];
653
 
        int iDestNumViewportX = data[1];
654
 
        int iDestNumViewportY = data[2];
655
 
        
656
 
        gldi_window_move_to_desktop (pIcon->pAppli,
657
 
                iDestNumDesktop,
658
 
                (iDestNumViewportX - myData.switcher.iCurrentViewportX) * g_desktopGeometry.Xscreen.width,
659
 
                (iDestNumViewportY - myData.switcher.iCurrentViewportY) * g_desktopGeometry.Xscreen.height);
660
 
}
661
 
void cd_switcher_move_current_desktop_to (int iNumDesktop, int iNumViewportX, int iNumViewportY)
662
 
{
663
 
        gint data[3] = {iNumDesktop, iNumViewportX, iNumViewportY};
664
 
        cd_switcher_foreach_window_on_viewport (myData.switcher.iCurrentDesktop,
665
 
                myData.switcher.iCurrentViewportX,
666
 
                myData.switcher.iCurrentViewportY,
667
 
                (CDSwitcherActionOnViewportFunc) _cd_switcher_move_window_to_viewport,
668
 
                data);
669
 
}