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

« back to all changes in this revision

Viewing changes to src/cairo-dock-dock-facility.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 <stdio.h>
23
 
#include <stdlib.h>
24
 
 
25
 
#include <glib/gstdio.h>
26
 
#include <gtk/gtk.h>
27
 
#include <gdk/gdkx.h>
28
 
 
29
 
#include <cairo.h>
30
 
#include <pango/pango.h>
31
 
#include <librsvg/rsvg.h>
32
 
#include <librsvg/rsvg-cairo.h>
33
 
 
34
 
#ifdef HAVE_GLITZ
35
 
#include <glitz-glx.h>
36
 
#include <cairo-glitz.h>
37
 
#endif
38
 
 
39
 
#include <gtk/gtkgl.h>
40
 
#include <X11/extensions/Xrender.h>
41
 
#include <X11/extensions/shape.h>
42
 
#include <GL/gl.h> 
43
 
#include <GL/glu.h> 
44
 
#include <GL/glx.h> 
45
 
#include <gdk/x11/gdkglx.h>
46
 
 
47
 
#include "cairo-dock-draw.h"
48
 
#include "cairo-dock-applications-manager.h"
49
 
#include "cairo-dock-load.h"
50
 
#include "cairo-dock-config.h"
51
 
#include "cairo-dock-modules.h"
52
 
#include "cairo-dock-callbacks.h"
53
 
#include "cairo-dock-icons.h"
54
 
#include "cairo-dock-separator-factory.h"
55
 
#include "cairo-dock-launcher-factory.h"
56
 
#include "cairo-dock-renderer-manager.h"
57
 
#include "cairo-dock-file-manager.h"
58
 
#include "cairo-dock-X-utilities.h"
59
 
#include "cairo-dock-log.h"
60
 
#include "cairo-dock-keyfile-utilities.h"
61
 
#include "cairo-dock-dock-manager.h"
62
 
#include "cairo-dock-notifications.h"
63
 
#include "cairo-dock-class-manager.h"
64
 
#include "cairo-dock-internal-accessibility.h"
65
 
#include "cairo-dock-internal-icons.h"
66
 
#include "cairo-dock-internal-system.h"
67
 
#include "cairo-dock-internal-views.h"
68
 
///#include "cairo-dock-internal-labels.h"
69
 
#include "cairo-dock-internal-background.h"
70
 
#include "cairo-dock-animations.h"
71
 
#include "cairo-dock-emblem.h"
72
 
#include "cairo-dock-dock-facility.h"
73
 
 
74
 
extern int g_iScreenWidth[2], g_iScreenHeight[2];
75
 
 
76
 
void cairo_dock_reload_reflects_in_dock (CairoDock *pDock)
77
 
{
78
 
        cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDock));
79
 
        Icon *icon;
80
 
        GList *ic;
81
 
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
82
 
        {
83
 
                icon = ic->data;
84
 
                if (icon->pReflectionBuffer != NULL)
85
 
                {
86
 
                        cairo_dock_add_reflection_to_icon (pCairoContext, icon, CAIRO_CONTAINER (pDock));
87
 
                }
88
 
        }
89
 
        cairo_destroy (pCairoContext);
90
 
}
91
 
 
92
 
 
93
 
void cairo_dock_update_dock_size (CairoDock *pDock)  // iMaxIconHeight et fFlatDockWidth doivent avoir ete mis a jour au prealable.
94
 
{
95
 
        g_return_if_fail (pDock != NULL);
96
 
        int iPrevMaxDockHeight = pDock->iMaxDockHeight;
97
 
        int iPrevMaxDockWidth = pDock->iMaxDockWidth;
98
 
        
99
 
        
100
 
        if (pDock->container.fRatio != 0/* && pDock->container.fRatio != 1*/)  // on remet leur taille reelle aux icones, sinon le calcul de max_dock_size sera biaise.
101
 
        {
102
 
                GList *ic;
103
 
                Icon *icon;
104
 
                pDock->fFlatDockWidth = -myIcons.iIconGap;
105
 
                pDock->iMaxIconHeight = 0;
106
 
                for (ic = pDock->icons; ic != NULL; ic = ic->next)
107
 
                {
108
 
                        icon = ic->data;
109
 
                        icon->fWidth /= pDock->container.fRatio;
110
 
                        icon->fHeight /= pDock->container.fRatio;
111
 
                        pDock->fFlatDockWidth += icon->fWidth + myIcons.iIconGap;
112
 
                        pDock->iMaxIconHeight = MAX (pDock->iMaxIconHeight, icon->fHeight);
113
 
                }
114
 
                pDock->container.fRatio = 1.;
115
 
        }
116
 
        pDock->pRenderer->compute_size (pDock);
117
 
        
118
 
        double hmax = pDock->iMaxIconHeight;
119
 
        int iMaxAuthorizedWidth = cairo_dock_get_max_authorized_dock_width (pDock);
120
 
        int n = 0;
121
 
        do
122
 
        {
123
 
                double fPrevRatio = pDock->container.fRatio;
124
 
                //g_print ("  %s (%d / %d)\n", __func__, (int)pDock->iMaxDockWidth, iMaxAuthorizedWidth);
125
 
                if (pDock->iMaxDockWidth > iMaxAuthorizedWidth)
126
 
                {
127
 
                        pDock->container.fRatio *= 1. * iMaxAuthorizedWidth / pDock->iMaxDockWidth;
128
 
                }
129
 
                else
130
 
                {
131
 
                        double fMaxRatio = (pDock->iRefCount == 0 ? 1 : myViews.fSubDockSizeRatio);
132
 
                        if (pDock->container.fRatio < fMaxRatio)
133
 
                        {
134
 
                                pDock->container.fRatio *= 1. * iMaxAuthorizedWidth / pDock->iMaxDockWidth;
135
 
                                pDock->container.fRatio = MIN (pDock->container.fRatio, fMaxRatio);
136
 
                        }
137
 
                        else
138
 
                                pDock->container.fRatio = fMaxRatio;
139
 
                }
140
 
                
141
 
                if (pDock->iMaxDockHeight > g_iScreenHeight[pDock->container.bIsHorizontal])
142
 
                {
143
 
                        pDock->container.fRatio = MIN (pDock->container.fRatio, fPrevRatio * g_iScreenHeight[pDock->container.bIsHorizontal] / pDock->iMaxDockHeight);
144
 
                }
145
 
                
146
 
                if (fPrevRatio != pDock->container.fRatio)
147
 
                {
148
 
                        //g_print ("  -> changement du ratio : %.3f -> %.3f (%d, %d try)\n", fPrevRatio, pDock->container.fRatio, pDock->iRefCount, n);
149
 
                        Icon *icon;
150
 
                        GList *ic;
151
 
                        pDock->fFlatDockWidth = -myIcons.iIconGap;
152
 
                        for (ic = pDock->icons; ic != NULL; ic = ic->next)
153
 
                        {
154
 
                                icon = ic->data;
155
 
                                icon->fWidth *= pDock->container.fRatio / fPrevRatio;
156
 
                                icon->fHeight *= pDock->container.fRatio / fPrevRatio;
157
 
                                pDock->fFlatDockWidth += icon->fWidth + myIcons.iIconGap;
158
 
                        }
159
 
                        hmax *= pDock->container.fRatio / fPrevRatio;
160
 
                        
161
 
                        pDock->pRenderer->compute_size (pDock);
162
 
                }
163
 
                
164
 
                //g_print ("*** ratio : %.3f -> %.3f\n", fPrevRatio, pDock->container.fRatio);
165
 
                n ++;
166
 
        } while ((pDock->iMaxDockWidth > iMaxAuthorizedWidth || pDock->iMaxDockHeight > g_iScreenHeight[pDock->container.bIsHorizontal] || (pDock->container.fRatio < 1 && pDock->iMaxDockWidth < iMaxAuthorizedWidth-5)) && n < 8);
167
 
        pDock->iMaxIconHeight = hmax;
168
 
        //g_print (">>> iMaxIconHeight : %d, ratio : %.2f, fFlatDockWidth : %.2f\n", (int) pDock->iMaxIconHeight, pDock->container.fRatio, pDock->fFlatDockWidth);
169
 
        
170
 
        pDock->pRenderer->calculate_icons (pDock);  // le calcul de max_dock_size a altere les fX et fY.
171
 
        
172
 
        pDock->bWMIconsNeedUpdate = TRUE;
173
 
        ///cairo_dock_trigger_set_WM_icons_geometry (pDock);
174
 
        
175
 
        cairo_dock_update_input_shape (pDock);
176
 
        
177
 
        if (GTK_WIDGET_VISIBLE (pDock->container.pWidget) && (iPrevMaxDockHeight != pDock->iMaxDockHeight || iPrevMaxDockWidth != pDock->iMaxDockWidth))
178
 
        {
179
 
                //g_print ("*******%s (%dx%d -> %dx%d)\n", __func__, iPrevMaxDockWidth, iPrevMaxDockHeight, pDock->iMaxDockWidth, pDock->iMaxDockHeight);
180
 
                cairo_dock_move_resize_dock (pDock);  /// gele le dock ?....
181
 
        }
182
 
        
183
 
        cairo_dock_update_background_decorations_if_necessary (pDock, pDock->iDecorationsWidth, pDock->iDecorationsHeight);
184
 
        
185
 
        if (pDock->iRefCount == 0 && myAccessibility.bReserveSpace && ! pDock->bAutoHide && iPrevMaxDockHeight != pDock->iMaxDockHeight)
186
 
                cairo_dock_reserve_space_for_dock (pDock, TRUE);
187
 
}
188
 
 
189
 
Icon *cairo_dock_calculate_dock_icons (CairoDock *pDock)
190
 
{
191
 
        Icon *pPointedIcon = pDock->pRenderer->calculate_icons (pDock);
192
 
        cairo_dock_manage_mouse_position (pDock);
193
 
        return (pDock->iMousePositionType == CAIRO_DOCK_MOUSE_INSIDE ? pPointedIcon : NULL);
194
 
}
195
 
 
196
 
 
197
 
 
198
 
  ////////////////////////////////
199
 
 /// WINDOW SIZE AND POSITION ///
200
 
////////////////////////////////
201
 
 
202
 
void cairo_dock_reserve_space_for_dock (CairoDock *pDock, gboolean bReserve)
203
 
{
204
 
        Window Xid = GDK_WINDOW_XID (pDock->container.pWidget->window);
205
 
        int left=0, right=0, top=0, bottom=0;
206
 
        int left_start_y=0, left_end_y=0, right_start_y=0, right_end_y=0, top_start_x=0, top_end_x=0, bottom_start_x=0, bottom_end_x=0;
207
 
        int iHeight, iWidth;
208
 
 
209
 
        if (bReserve)
210
 
        {
211
 
                int iWindowPositionX = pDock->container.iWindowPositionX, iWindowPositionY = pDock->container.iWindowPositionY;
212
 
                
213
 
                int w = pDock->iMinDockWidth;
214
 
                int h = pDock->iMinDockHeight;
215
 
                int x, y;  // position qu'aurait la fenetre du dock s'il avait la taille minimale.
216
 
                cairo_dock_get_window_position_at_balance (pDock, w, h, &x, &y);
217
 
                
218
 
                if (pDock->container.bDirectionUp)
219
 
                {
220
 
                        if (pDock->container.bIsHorizontal)
221
 
                        {
222
 
                                bottom = h + pDock->iGapY;
223
 
                                bottom_start_x = x;
224
 
                                bottom_end_x = x + w;
225
 
                        }
226
 
                        else
227
 
                        {
228
 
                                right = h + pDock->iGapY;
229
 
                                right_start_y = x;
230
 
                                right_end_y = x + w;
231
 
                        }
232
 
                }
233
 
                else
234
 
                {
235
 
                        if (pDock->container.bIsHorizontal)
236
 
                        {
237
 
                                top = h + pDock->iGapY;
238
 
                                top_start_x = x;
239
 
                                top_end_x = x + w;
240
 
                        }
241
 
                        else
242
 
                        {
243
 
                                left = h + pDock->iGapY;
244
 
                                left_start_y = x;
245
 
                                left_end_y = x + iWidth;
246
 
                        }
247
 
                }
248
 
        }
249
 
        
250
 
        cairo_dock_set_strut_partial (Xid, left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x);
251
 
        /*if ((bReserve && ! pDock->container.bDirectionUp) || (g_iWmHint == GDK_WINDOW_TYPE_HINT_DOCK))  // merci a Robrob pour le patch !
252
 
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_DOCK");  // gtk_window_set_type_hint ne marche que sur une fenetre avant de la rendre visible !
253
 
        else if (g_iWmHint == GDK_WINDOW_TYPE_HINT_NORMAL)
254
 
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_NORMAL");  // idem.
255
 
        else if (g_iWmHint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
256
 
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_TOOLBAR");  // idem.*/
257
 
}
258
 
 
259
 
void cairo_dock_prevent_dock_from_out_of_screen (CairoDock *pDock)
260
 
{
261
 
        int x, y;  // position du point invariant du dock.
262
 
        x = pDock->container.iWindowPositionX +  pDock->container.iWidth * pDock->fAlign;
263
 
        y = (pDock->container.bDirectionUp ? pDock->container.iWindowPositionY + pDock->container.iHeight : pDock->container.iWindowPositionY);
264
 
        cd_debug ("%s (%d;%d)", __func__, x, y);
265
 
        
266
 
        pDock->iGapX = x - g_iScreenWidth[pDock->container.bIsHorizontal] * pDock->fAlign;
267
 
        pDock->iGapY = (pDock->container.bDirectionUp ? g_iScreenHeight[pDock->container.bIsHorizontal] - y : y);
268
 
        cd_debug (" -> (%d;%d)", pDock->iGapX, pDock->iGapY);
269
 
        
270
 
        if (pDock->iGapX < - g_iScreenWidth[pDock->container.bIsHorizontal]/2)
271
 
                pDock->iGapX = - g_iScreenWidth[pDock->container.bIsHorizontal]/2;
272
 
        if (pDock->iGapX > g_iScreenWidth[pDock->container.bIsHorizontal]/2)
273
 
                pDock->iGapX = g_iScreenWidth[pDock->container.bIsHorizontal]/2;
274
 
        if (pDock->iGapY < 0)
275
 
                pDock->iGapY = 0;
276
 
        if (pDock->iGapY > g_iScreenHeight[pDock->container.bIsHorizontal])
277
 
                pDock->iGapY = g_iScreenHeight[pDock->container.bIsHorizontal];
278
 
}
279
 
 
280
 
#define CD_VISIBILITY_MARGIN 20
281
 
void cairo_dock_get_window_position_at_balance (CairoDock *pDock, int iNewWidth, int iNewHeight, int *iNewPositionX, int *iNewPositionY)
282
 
{
283
 
        int iWindowPositionX = (g_iScreenWidth[pDock->container.bIsHorizontal] - iNewWidth) * pDock->fAlign + pDock->iGapX;
284
 
        if (pDock->iRefCount == 0 && pDock->fAlign != .5)
285
 
                iWindowPositionX += (.5 - pDock->fAlign) * (pDock->iMaxDockWidth - iNewWidth);
286
 
        int iWindowPositionY = (pDock->container.bDirectionUp ? g_iScreenHeight[pDock->container.bIsHorizontal] - iNewHeight - pDock->iGapY : pDock->iGapY);
287
 
        //g_print ("pDock->iGapX : %d => iWindowPositionX <- %d\n", pDock->iGapX, iWindowPositionX);
288
 
        //g_print ("iNewHeight : %d -> pDock->container.iWindowPositionY <- %d\n", iNewHeight, iWindowPositionY);
289
 
        
290
 
        if (pDock->iRefCount == 0)
291
 
        {
292
 
                if (iWindowPositionX + iNewWidth < CD_VISIBILITY_MARGIN)
293
 
                        iWindowPositionX = CD_VISIBILITY_MARGIN - iNewWidth;
294
 
                else if (iWindowPositionX > g_iScreenWidth[pDock->container.bIsHorizontal] - CD_VISIBILITY_MARGIN)
295
 
                        iWindowPositionX = g_iScreenWidth[pDock->container.bIsHorizontal] - CD_VISIBILITY_MARGIN;
296
 
        }
297
 
        else
298
 
        {
299
 
                if (iWindowPositionX < - pDock->iLeftMargin)
300
 
                        iWindowPositionX = - pDock->iLeftMargin;
301
 
                else if (iWindowPositionX > g_iScreenWidth[pDock->container.bIsHorizontal] - iNewWidth + pDock->iMinRightMargin)
302
 
                        iWindowPositionX = g_iScreenWidth[pDock->container.bIsHorizontal] - iNewWidth + pDock->iMinRightMargin;
303
 
        }
304
 
        if (iWindowPositionY < - pDock->iMaxIconHeight)
305
 
                iWindowPositionY = - pDock->iMaxIconHeight;
306
 
        else if (iWindowPositionY > g_iScreenHeight[pDock->container.bIsHorizontal] - iNewHeight + pDock->iMaxIconHeight)
307
 
                iWindowPositionY = g_iScreenHeight[pDock->container.bIsHorizontal] - iNewHeight + pDock->iMaxIconHeight;
308
 
        
309
 
        *iNewPositionX = iWindowPositionX + pDock->iScreenOffsetX;
310
 
        *iNewPositionY = iWindowPositionY + pDock->iScreenOffsetY;
311
 
}
312
 
 
313
 
static gboolean _move_resize_dock (CairoDock *pDock)
314
 
{
315
 
        int iNewWidth = pDock->iMaxDockWidth;
316
 
        int iNewHeight = pDock->iMaxDockHeight;
317
 
        int iNewPositionX, iNewPositionY;
318
 
        cairo_dock_get_window_position_at_balance (pDock, iNewWidth, iNewHeight, &iNewPositionX, &iNewPositionY);  // on ne peut pas intercepter le cas ou les nouvelles dimensions sont egales aux dimensions courantes de la fenetre, car il se peut qu'il y'ait 2 redimensionnements d'affilee s'annulant mutuellement (remove + insert d'une icone). Il faut donc avoir les 2 configure, sinon la taille reste bloquee aux valeurs fournies par le 1er configure.
319
 
        
320
 
        //g_print (" -> %dx%d, %d;%d\n", iNewWidth, iNewHeight, iNewPositionX, iNewPositionY);
321
 
        
322
 
        if (pDock->container.bIsHorizontal)
323
 
        {
324
 
                gdk_window_move_resize (pDock->container.pWidget->window,
325
 
                        iNewPositionX,
326
 
                        iNewPositionY,
327
 
                        iNewWidth,
328
 
                        iNewHeight);  // lorsqu'on a 2 gdk_window_move_resize d'affilee, Compiz deconne et bloque le dock (il est toujours actif mais n'est plus redessine). Compiz envoit un configure de trop par rapport a Metacity.
329
 
        }
330
 
        else
331
 
        {
332
 
                gdk_window_move_resize (pDock->container.pWidget->window,
333
 
                        iNewPositionY,
334
 
                        iNewPositionX,
335
 
                        iNewHeight,
336
 
                        iNewWidth);
337
 
        }
338
 
        pDock->iSidMoveResize = 0;
339
 
        return FALSE;
340
 
}
341
 
 
342
 
void cairo_dock_move_resize_dock (CairoDock *pDock)
343
 
{
344
 
        //g_print ("*********%s (current : %dx%d, %d;%d)\n", __func__, pDock->container.iWidth, pDock->container.iHeight, pDock->container.iWindowPositionX, pDock->container.iWindowPositionY);
345
 
        if (pDock->iSidMoveResize == 0)
346
 
        {
347
 
                pDock->iSidMoveResize = g_idle_add ((GSourceFunc)_move_resize_dock, pDock);
348
 
        }
349
 
        return ;
350
 
}
351
 
 
352
 
void cairo_dock_place_root_dock (CairoDock *pDock)
353
 
{
354
 
        //g_print ("%s ()\n", __func__);
355
 
        pDock->fFoldingFactor = (pDock->bAutoHide && pDock->iRefCount == 0 && mySystem.bAnimateOnAutoHide ? .99 : 0.);
356
 
        cairo_dock_move_resize_dock (pDock);
357
 
}
358
 
 
359
 
 
360
 
  ///////////////////
361
 
 /// INPUT SHAPE ///
362
 
///////////////////
363
 
 
364
 
GdkBitmap *cairo_dock_create_input_shape (CairoDock *pDock, int w, int h)
365
 
{
366
 
        int W = pDock->iMaxDockWidth;
367
 
        int H = pDock->iMaxDockHeight;
368
 
        
369
 
        GdkBitmap *pShapeBitmap = (GdkBitmap*) gdk_pixmap_new (NULL,
370
 
                pDock->container.bIsHorizontal ? W : H,
371
 
                pDock->container.bIsHorizontal ? H : W,
372
 
                1);
373
 
        
374
 
        cairo_t *pCairoContext = gdk_cairo_create (pShapeBitmap);
375
 
        cairo_set_source_rgba (pCairoContext, 0.0f, 0.0f, 0.0f, 0.0f);
376
 
        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
377
 
        cairo_paint (pCairoContext);
378
 
        cairo_set_source_rgba (pCairoContext, 1., 1., 1., 1.);
379
 
        if (pDock->container.bIsHorizontal)
380
 
        {
381
 
                cairo_rectangle (pCairoContext,
382
 
                        (W - w) / 2,  // centre en x.
383
 
                        pDock->container.bDirectionUp ? H - h : 0,
384
 
                        w,
385
 
                        h);
386
 
        }
387
 
        else
388
 
        {
389
 
                cairo_rectangle (pCairoContext,
390
 
                        pDock->container.bDirectionUp ? H - h : 0,
391
 
                        (W - w) / 2,  // centre en x.
392
 
                        h,
393
 
                        w);
394
 
        }
395
 
        cairo_fill (pCairoContext);
396
 
        cairo_destroy (pCairoContext);
397
 
 
398
 
        return pShapeBitmap;
399
 
}
400
 
 
401
 
void cairo_dock_update_input_shape (CairoDock *pDock)
402
 
{
403
 
        //\_______________ On detruit les zones d'input actuelles.
404
 
        if (pDock->pShapeBitmap != NULL)
405
 
        {
406
 
                g_object_unref ((gpointer) pDock->pShapeBitmap);
407
 
                pDock->pShapeBitmap = NULL;
408
 
        }
409
 
        if (pDock->pHiddenShapeBitmap != NULL)
410
 
        {
411
 
                g_object_unref ((gpointer) pDock->pHiddenShapeBitmap);
412
 
                pDock->pHiddenShapeBitmap = NULL;
413
 
        }
414
 
        
415
 
        //\_______________ on definit les tailles des zones.
416
 
        int W = pDock->iMaxDockWidth;
417
 
        int H = pDock->iMaxDockHeight;
418
 
        int w = pDock->iMinDockWidth;
419
 
        int h = pDock->iMinDockHeight;
420
 
        int w_ = MIN (myAccessibility.iVisibleZoneWidth, pDock->iMaxDockWidth);
421
 
        int h_ = MIN (myAccessibility.iVisibleZoneHeight, pDock->iMaxDockHeight);
422
 
        
423
 
        //\_______________ on verifie que les conditions sont toujours remplies.
424
 
        if (w == 0 || h == 0 || pDock->iRefCount > 0 || W == 0 || H == 0)
425
 
        {
426
 
                if (pDock->iInputState != CAIRO_DOCK_INPUT_ACTIVE)
427
 
                {
428
 
                        //g_print ("+++ input shape active on update input shape\n");
429
 
                        gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
430
 
                                NULL,
431
 
                                0,
432
 
                                0);
433
 
                        pDock->iInputState = CAIRO_DOCK_INPUT_ACTIVE;
434
 
                }
435
 
                return ;
436
 
        }
437
 
        
438
 
        //\_______________ on cree les zones.
439
 
        pDock->pShapeBitmap = cairo_dock_create_input_shape (pDock, w, h);
440
 
        
441
 
        pDock->pHiddenShapeBitmap = cairo_dock_create_input_shape (pDock, w_, h_);
442
 
}
443
 
 
444
 
 
445
 
 
446
 
  ///////////////////
447
 
 /// LINEAR DOCK ///
448
 
///////////////////
449
 
 
450
 
GList *cairo_dock_calculate_icons_positions_at_rest_linear (GList *pIconList, double fFlatDockWidth, int iXOffset)
451
 
{
452
 
        //g_print ("%s (%d, +%d)\n", __func__, fFlatDockWidth, iXOffset);
453
 
        double x_cumulated = iXOffset;
454
 
        double fXMin = 99999;
455
 
        GList* ic, *pFirstDrawnElement = NULL;
456
 
        Icon *icon;
457
 
        for (ic = pIconList; ic != NULL; ic = ic->next)
458
 
        {
459
 
                icon = ic->data;
460
 
 
461
 
                if (x_cumulated + icon->fWidth / 2 < 0)
462
 
                        icon->fXAtRest = x_cumulated + fFlatDockWidth;
463
 
                else if (x_cumulated + icon->fWidth / 2 > fFlatDockWidth)
464
 
                        icon->fXAtRest = x_cumulated - fFlatDockWidth;
465
 
                else
466
 
                        icon->fXAtRest = x_cumulated;
467
 
 
468
 
                if (icon->fXAtRest < fXMin)
469
 
                {
470
 
                        fXMin = icon->fXAtRest;
471
 
                        pFirstDrawnElement = ic;
472
 
                }
473
 
                //g_print ("%s : fXAtRest = %.2f\n", icon->cName, icon->fXAtRest);
474
 
 
475
 
                x_cumulated += icon->fWidth + myIcons.iIconGap;
476
 
        }
477
 
 
478
 
        return pFirstDrawnElement;
479
 
}
480
 
 
481
 
double cairo_dock_calculate_max_dock_width (CairoDock *pDock, GList *pFirstDrawnElementGiven, double fFlatDockWidth, double fWidthConstraintFactor, double fExtraWidth)
482
 
{
483
 
        double fMaxDockWidth = 0.;
484
 
        //g_print ("%s (%d)\n", __func__, fFlatDockWidth);
485
 
        GList *pIconList = pDock->icons;
486
 
        if (pIconList == NULL)
487
 
                return 2 * myBackground.iDockRadius + myBackground.iDockLineWidth + 2 * myBackground.iFrameMargin;
488
 
 
489
 
        //\_______________ On remet a zero les positions extremales des icones.
490
 
        GList* ic;
491
 
        Icon *icon;
492
 
        for (ic = pIconList; ic != NULL; ic = ic->next)
493
 
        {
494
 
                icon = ic->data;
495
 
                icon->fXMax = -1e4;
496
 
                icon->fXMin = 1e4;
497
 
        }
498
 
 
499
 
        //\_______________ On simule le passage du curseur sur toute la largeur du dock, et on chope la largeur maximale qui s'en degage, ainsi que les positions d'equilibre de chaque icone.
500
 
        GList *pFirstDrawnElement = (pFirstDrawnElementGiven != NULL ? pFirstDrawnElementGiven : pIconList);
501
 
        //for (int iVirtualMouseX = 0; iVirtualMouseX < fFlatDockWidth; iVirtualMouseX ++)
502
 
        GList *ic2;
503
 
        for (ic = pIconList; ic != NULL; ic = ic->next)
504
 
        {
505
 
                icon = ic->data;
506
 
 
507
 
                cairo_dock_calculate_wave_with_position_linear (pIconList, pFirstDrawnElement, icon->fXAtRest, pDock->fMagnitudeMax, fFlatDockWidth, 0, 0, 0.5, 0, pDock->container.bDirectionUp);
508
 
                ic2 = pFirstDrawnElement;
509
 
                do
510
 
                {
511
 
                        icon = ic2->data;
512
 
 
513
 
                        if (icon->fX + icon->fWidth * icon->fScale > icon->fXMax)
514
 
                                icon->fXMax = icon->fX + icon->fWidth * icon->fScale;
515
 
                        if (icon->fX < icon->fXMin)
516
 
                                icon->fXMin = icon->fX;
517
 
 
518
 
                        ic2 = cairo_dock_get_next_element (ic2, pDock->icons);
519
 
                } while (ic2 != pFirstDrawnElement);
520
 
        }
521
 
        cairo_dock_calculate_wave_with_position_linear (pIconList, pFirstDrawnElement, fFlatDockWidth - 1, pDock->fMagnitudeMax, fFlatDockWidth, 0, 0, pDock->fAlign, 0, pDock->container.bDirectionUp);  // pDock->fFoldingFactor
522
 
        ic = pFirstDrawnElement;
523
 
        do
524
 
        {
525
 
                icon = ic->data;
526
 
 
527
 
                if (icon->fX + icon->fWidth * icon->fScale > icon->fXMax)
528
 
                        icon->fXMax = icon->fX + icon->fWidth * icon->fScale;
529
 
                if (icon->fX < icon->fXMin)
530
 
                        icon->fXMin = icon->fX;
531
 
 
532
 
                ic = cairo_dock_get_next_element (ic, pDock->icons);
533
 
        } while (ic != pFirstDrawnElement);
534
 
 
535
 
        fMaxDockWidth = (icon->fXMax - ((Icon *) pFirstDrawnElement->data)->fXMin) * fWidthConstraintFactor + fExtraWidth;
536
 
        fMaxDockWidth = ceil (fMaxDockWidth) + 1;
537
 
 
538
 
        for (ic = pIconList; ic != NULL; ic = ic->next)
539
 
        {
540
 
                icon = ic->data;
541
 
                icon->fXMin += fMaxDockWidth / 2;
542
 
                icon->fXMax += fMaxDockWidth / 2;
543
 
                //g_print ("%s : [%d;%d]\n", icon->cName, (int) icon->fXMin, (int) icon->fXMax);
544
 
                icon->fX = icon->fXAtRest;
545
 
                icon->fScale = 1;
546
 
        }
547
 
 
548
 
        return fMaxDockWidth;
549
 
}
550
 
 
551
 
Icon * cairo_dock_calculate_wave_with_position_linear (GList *pIconList, GList *pFirstDrawnElementGiven, int x_abs, gdouble fMagnitude, double fFlatDockWidth, int iWidth, int iHeight, double fAlign, double fFoldingFactor, gboolean bDirectionUp)
552
 
{
553
 
        //g_print (">>>>>%s (%d/%.2f, %dx%d, %.2f, %.2f)\n", __func__, x_abs, fFlatDockWidth, iWidth, iHeight, fAlign, fFoldingFactor);
554
 
        if (pIconList == NULL)
555
 
                return NULL;
556
 
        if (x_abs < 0 && iWidth > 0)  // ces cas limite sont la pour empecher les icones de retrecir trop rapidement quand on sort par les cotes.
557
 
                ///x_abs = -1;
558
 
                x_abs = 0;
559
 
        else if (x_abs > fFlatDockWidth && iWidth > 0)
560
 
                ///x_abs = fFlatDockWidth+1;
561
 
                x_abs = (int) fFlatDockWidth;
562
 
        
563
 
        
564
 
        float x_cumulated = 0, fXMiddle, fDeltaExtremum;
565
 
        GList* ic, *pointed_ic;
566
 
        Icon *icon, *prev_icon;
567
 
 
568
 
        double fScale = 0.;
569
 
        double offset = 0.;
570
 
        GList *pFirstDrawnElement = (pFirstDrawnElementGiven != NULL ? pFirstDrawnElementGiven : pIconList);
571
 
        ic = pFirstDrawnElement;
572
 
        pointed_ic = (x_abs < 0 ? ic : NULL);
573
 
        do
574
 
        {
575
 
                icon = ic->data;
576
 
                x_cumulated = icon->fXAtRest;
577
 
                fXMiddle = icon->fXAtRest + icon->fWidth / 2;
578
 
 
579
 
                //\_______________ On calcule sa phase (pi/2 au niveau du curseur).
580
 
                icon->fPhase = (fXMiddle - x_abs) / myIcons.iSinusoidWidth * G_PI + G_PI / 2;
581
 
                if (icon->fPhase < 0)
582
 
                {
583
 
                        icon->fPhase = 0;
584
 
                }
585
 
                else if (icon->fPhase > G_PI)
586
 
                {
587
 
                        icon->fPhase = G_PI;
588
 
                }
589
 
                
590
 
                //\_______________ On en deduit l'amplitude de la sinusoide au niveau de cette icone, et donc son echelle.
591
 
                icon->fScale = 1 + fMagnitude * myIcons.fAmplitude * sin (icon->fPhase);
592
 
                if (iWidth > 0 && icon->fInsertRemoveFactor != 0)
593
 
                {
594
 
                        fScale = icon->fScale;
595
 
                        ///offset += (icon->fWidth * icon->fScale) * (pointed_ic == NULL ? 1 : -1);
596
 
                        if (icon->fInsertRemoveFactor > 0)
597
 
                                icon->fScale *= icon->fInsertRemoveFactor;
598
 
                        else
599
 
                                icon->fScale *= (1 + icon->fInsertRemoveFactor);
600
 
                        ///offset -= (icon->fWidth * icon->fScale) * (pointed_ic == NULL ? 1 : -1);
601
 
                }
602
 
                
603
 
                icon->fY = (bDirectionUp ? iHeight - myBackground.iDockLineWidth - myBackground.iFrameMargin - icon->fScale * icon->fHeight : myBackground.iDockLineWidth + myBackground.iFrameMargin);
604
 
                
605
 
                //\_______________ Si on avait deja defini l'icone pointee, on peut placer l'icone courante par rapport a la precedente.
606
 
                if (pointed_ic != NULL)
607
 
                {
608
 
                        if (ic == pFirstDrawnElement)  // peut arriver si on est en dehors a gauche du dock.
609
 
                        {
610
 
                                icon->fX = x_cumulated - 1. * (fFlatDockWidth - iWidth) / 2;
611
 
                                //g_print ("  en dehors a gauche : icon->fX = %.2f (%.2f)\n", icon->fX, x_cumulated);
612
 
                        }
613
 
                        else
614
 
                        {
615
 
                                prev_icon = (ic->prev != NULL ? ic->prev->data : cairo_dock_get_last_icon (pIconList));
616
 
                                icon->fX = prev_icon->fX + (prev_icon->fWidth + myIcons.iIconGap) * prev_icon->fScale;
617
 
 
618
 
                                if (icon->fX + icon->fWidth * icon->fScale > icon->fXMax - myIcons.fAmplitude * fMagnitude * (icon->fWidth + 1.5*myIcons.iIconGap) / 8 && iWidth != 0)
619
 
                                {
620
 
                                        //g_print ("  on contraint %s (fXMax=%.2f , fX=%.2f\n", prev_icon->cName, prev_icon->fXMax, prev_icon->fX);
621
 
                                        fDeltaExtremum = icon->fX + icon->fWidth * icon->fScale - (icon->fXMax - myIcons.fAmplitude * fMagnitude * (icon->fWidth + 1.5*myIcons.iIconGap) / 16);
622
 
                                        if (myIcons.fAmplitude != 0)
623
 
                                                icon->fX -= fDeltaExtremum * (1 - (icon->fScale - 1) / myIcons.fAmplitude) * fMagnitude;
624
 
                                }
625
 
                        }
626
 
                        icon->fX = fAlign * iWidth + (icon->fX - fAlign * iWidth) * (1. - fFoldingFactor);
627
 
                        //g_print ("  a droite : icon->fX = %.2f (%.2f)\n", icon->fX, x_cumulated);
628
 
                }
629
 
                
630
 
                //\_______________ On regarde si on pointe sur cette icone.
631
 
                if (x_cumulated + icon->fWidth + .5*myIcons.iIconGap >= x_abs && x_cumulated - .5*myIcons.iIconGap <= x_abs && pointed_ic == NULL)  // on a trouve l'icone sur laquelle on pointe.
632
 
                {
633
 
                        pointed_ic = ic;
634
 
                        ///icon->bPointed = TRUE;
635
 
                        icon->bPointed = (x_abs != (int) fFlatDockWidth && x_abs != 0);
636
 
                        icon->fX = x_cumulated - (fFlatDockWidth - iWidth) / 2 + (1 - icon->fScale) * (x_abs - x_cumulated + .5*myIcons.iIconGap);
637
 
                        icon->fX = fAlign * iWidth + (icon->fX - fAlign * iWidth) * (1. - fFoldingFactor);
638
 
                        //g_print ("  icone pointee : fX = %.2f (%.2f, %d)\n", icon->fX, x_cumulated, icon->bPointed);
639
 
                }
640
 
                else
641
 
                        icon->bPointed = FALSE;
642
 
                
643
 
                if (iWidth > 0 && icon->fInsertRemoveFactor != 0)
644
 
                {
645
 
                        if (!icon->bPointed)
646
 
                                offset += (icon->fWidth * (fScale - icon->fScale)) * (pointed_ic == NULL ? 1 : -1);
647
 
                        else
648
 
                                offset += (2*(fXMiddle - x_abs) * (fScale - icon->fScale)) * (pointed_ic == NULL ? 1 : -1);
649
 
                }
650
 
                
651
 
                ic = cairo_dock_get_next_element (ic, pIconList);
652
 
        } while (ic != pFirstDrawnElement);
653
 
        
654
 
        //\_______________ On place les icones precedant l'icone pointee par rapport a celle-ci.
655
 
        if (pointed_ic == NULL)  // on est a droite des icones.
656
 
        {
657
 
                pointed_ic = (pFirstDrawnElement->prev == NULL ? g_list_last (pIconList) : pFirstDrawnElement->prev);
658
 
                icon = pointed_ic->data;
659
 
                icon->fX = x_cumulated - (fFlatDockWidth - iWidth) / 2 + (1 - icon->fScale) * (icon->fWidth + .5*myIcons.iIconGap);
660
 
                icon->fX = fAlign * iWidth + (icon->fX - fAlign * iWidth) * (1 - fFoldingFactor);
661
 
                //g_print ("  en dehors a droite : icon->fX = %.2f (%.2f)\n", icon->fX, x_cumulated);
662
 
        }
663
 
        
664
 
        ic = pointed_ic;
665
 
        while (ic != pFirstDrawnElement)
666
 
        {
667
 
                icon = ic->data;
668
 
                
669
 
                ic = ic->prev;
670
 
                if (ic == NULL)
671
 
                        ic = g_list_last (pIconList);
672
 
                        
673
 
                prev_icon = ic->data;
674
 
                
675
 
                prev_icon->fX = icon->fX - (prev_icon->fWidth + myIcons.iIconGap) * prev_icon->fScale;
676
 
                //g_print ("fX <- %.2f; fXMin : %.2f\n", prev_icon->fX, prev_icon->fXMin);
677
 
                if (prev_icon->fX < prev_icon->fXMin + myIcons.fAmplitude * fMagnitude * (prev_icon->fWidth + 1.5*myIcons.iIconGap) / 8 && iWidth != 0 && x_abs < iWidth && fMagnitude > 0)  /// && prev_icon->fPhase == 0   // on rajoute 'fMagnitude > 0' sinon il y'a un leger "saut" du aux contraintes a gauche de l'icone pointee.
678
 
                {
679
 
                        //g_print ("  on contraint %s (fXMin=%.2f , fX=%.2f\n", prev_icon->cName, prev_icon->fXMin, prev_icon->fX);
680
 
                        fDeltaExtremum = prev_icon->fX - (prev_icon->fXMin + myIcons.fAmplitude * fMagnitude * (prev_icon->fWidth + 1.5*myIcons.iIconGap) / 16);
681
 
                        if (myIcons.fAmplitude != 0)
682
 
                                prev_icon->fX -= fDeltaExtremum * (1 - (prev_icon->fScale - 1) / myIcons.fAmplitude) * fMagnitude;
683
 
                }
684
 
                prev_icon->fX = fAlign * iWidth + (prev_icon->fX - fAlign * iWidth) * (1. - fFoldingFactor);
685
 
                //g_print ("  prev_icon->fX : %.2f\n", prev_icon->fX);
686
 
        }
687
 
        
688
 
        if (offset != 0)
689
 
        {
690
 
                offset /= 2;
691
 
                //g_print ("offset : %.2f (pointed:%s)\n", offset, pointed_ic?((Icon*)pointed_ic->data)->cName:"none");
692
 
                for (ic = pIconList; ic != NULL; ic = ic->next)
693
 
                {
694
 
                        icon = ic->data;
695
 
                        //if (ic == pIconList)
696
 
                        //      g_print ("fX : %.2f - %.2f\n", icon->fX, offset);
697
 
                        icon->fX -= offset;
698
 
                }
699
 
        }
700
 
        
701
 
        return pointed_ic->data;
702
 
}
703
 
 
704
 
Icon *cairo_dock_apply_wave_effect_linear (CairoDock *pDock)
705
 
{
706
 
        //\_______________ On calcule la position du curseur dans le referentiel du dock a plat.
707
 
        int dx = pDock->container.iMouseX - (pDock->iOffsetForExtend * (pDock->fAlign - .5) * 2) - pDock->container.iWidth / 2;  // ecart par rapport au milieu du dock a plat.
708
 
        int x_abs = dx + pDock->fFlatDockWidth / 2;  // ecart par rapport a la gauche du dock minimal  plat.
709
 
        //g_print ("%s (flat:%d, w:%d, x:%d)\n", __func__, (int)pDock->fFlatDockWidth, pDock->container.iWidth, pDock->container.iMouseX);
710
 
        //\_______________ On calcule l'ensemble des parametres des icones.
711
 
        double fMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex) * pDock->fMagnitudeMax;
712
 
        Icon *pPointedIcon = cairo_dock_calculate_wave_with_position_linear (pDock->icons, pDock->pFirstDrawnElement, x_abs, fMagnitude, pDock->fFlatDockWidth, pDock->container.iWidth, pDock->container.iHeight, pDock->fAlign, pDock->fFoldingFactor, pDock->container.bDirectionUp);  // iMaxDockWidth
713
 
        return pPointedIcon;
714
 
}
715
 
 
716
 
double cairo_dock_get_current_dock_width_linear (CairoDock *pDock)
717
 
{
718
 
        if (pDock->icons == NULL)
719
 
                //return 2 * myBackground.iDockRadius + myBackground.iDockLineWidth + 2 * myBackground.iFrameMargin;
720
 
                return 1 + 2 * myBackground.iFrameMargin;
721
 
 
722
 
        Icon *pLastIcon = cairo_dock_get_last_drawn_icon (pDock);
723
 
        Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
724
 
        double fWidth = pLastIcon->fX - pFirstIcon->fX + pLastIcon->fWidth * pLastIcon->fScale + 2 * myBackground.iFrameMargin;  //  + 2 * myBackground.iDockRadius + myBackground.iDockLineWidth + 2 * myBackground.iFrameMargin
725
 
 
726
 
        return fWidth;
727
 
}
728
 
 
729
 
 
730
 
void cairo_dock_check_if_mouse_inside_linear (CairoDock *pDock)
731
 
{
732
 
        CairoDockMousePositionType iMousePositionType;
733
 
        int iWidth = pDock->container.iWidth;
734
 
        int iHeight = pDock->container.iHeight;
735
 
        ///int iExtraHeight = (pDock->bAtBottom ? 0 : myLabels.iLabelSize);
736
 
        int iExtraHeight = 0;  /// il faudrait voir si on a un sous-dock ou un dialogue au dessus :-/
737
 
        int iMouseX = pDock->container.iMouseX;
738
 
        int iMouseY = pDock->container.iMouseY;
739
 
        //g_print ("%s (%dx%d, %dx%d, %f)\n", __func__, iMouseX, iMouseY, iWidth, iHeight, pDock->fFoldingFactor);
740
 
 
741
 
        //\_______________ On regarde si le curseur est dans le dock ou pas, et on joue sur la taille des icones en consequence.
742
 
        int x_abs = pDock->container.iMouseX + (pDock->fFlatDockWidth - iWidth) / 2;  // abscisse par rapport a la gauche du dock minimal plat.
743
 
        gboolean bMouseInsideDock = (x_abs >= 0 && x_abs <= pDock->fFlatDockWidth && iMouseX > 0 && iMouseX < iWidth);
744
 
        //g_print ("bMouseInsideDock : %d (%d;%d/%.2f)\n", bMouseInsideDock, pDock->container.bInside, x_abs, pDock->fFlatDockWidth);
745
 
 
746
 
        if (! bMouseInsideDock)
747
 
        {
748
 
                if (/*cairo_dock_is_extended_dock (pDock) && */pDock->bAutoHide)  // ca peut etre assez penible de sortir du dock juste apres y etre rentre.
749
 
                {
750
 
                        iMousePositionType = CAIRO_DOCK_MOUSE_INSIDE;
751
 
                }
752
 
                else
753
 
                {
754
 
                        double fSideMargin = fabs (pDock->fAlign - .5) * (iWidth - pDock->fFlatDockWidth);
755
 
                        if (x_abs < - fSideMargin || x_abs > pDock->fFlatDockWidth + fSideMargin)
756
 
                                iMousePositionType = CAIRO_DOCK_MOUSE_OUTSIDE;
757
 
                        else
758
 
                                iMousePositionType = CAIRO_DOCK_MOUSE_ON_THE_EDGE;
759
 
                }
760
 
        }
761
 
        else if ((pDock->container.bDirectionUp && iMouseY >= iExtraHeight && iMouseY < iHeight) || (!pDock->container.bDirectionUp && iMouseY >= 0 && iMouseY < iHeight - iExtraHeight))  // et en plus on est dedans en y.  //  && pPointedIcon != NULL
762
 
        {
763
 
                //g_print ("on est dedans en x et en y (iMouseX=%d => x_abs=%d ; iMouseY=%d/%d)\n", iMouseX, x_abs, iMouseY, iHeight);
764
 
                //pDock->container.bInside = TRUE;
765
 
                iMousePositionType = CAIRO_DOCK_MOUSE_INSIDE;
766
 
        }
767
 
        else
768
 
                iMousePositionType = CAIRO_DOCK_MOUSE_OUTSIDE;
769
 
 
770
 
        pDock->iMousePositionType = iMousePositionType;
771
 
}
772
 
 
773
 
void cairo_dock_manage_mouse_position (CairoDock *pDock)
774
 
{
775
 
        static gboolean bReturn = FALSE;
776
 
        switch (pDock->iMousePositionType)
777
 
        {
778
 
                case CAIRO_DOCK_MOUSE_INSIDE :
779
 
                        //g_print ("INSIDE (%d;%d;%d;%d;%.2f)\n", cairo_dock_entrance_is_allowed (pDock), pDock->iMagnitudeIndex, pDock->bIsGrowingUp, pDock->bIsShrinkingDown, pDock->fFoldingFactor);
780
 
                        if (cairo_dock_entrance_is_allowed (pDock) && ((pDock->iMagnitudeIndex < CAIRO_DOCK_NB_MAX_ITERATIONS && ! pDock->bIsGrowingUp) || pDock->bIsShrinkingDown) && pDock->iInputState != CAIRO_DOCK_INPUT_HIDDEN && (pDock->iInputState != CAIRO_DOCK_INPUT_AT_REST || pDock->bIsDragging))  // on est dedans et la taille des icones est non maximale bien que le dock ne soit pas en train de grossir.  ///  && pDock->iSidMoveDown == 0
781
 
                        {
782
 
                                //g_print ("on est dedans en x et en y et la taille des icones est non maximale bien qu'aucune icone  ne soit animee (%d;%d)\n", pDock->iMagnitudeIndex, pDock->container.bInside);
783
 
                                //pDock->container.bInside = TRUE;
784
 
                                ///if ((pDock->bAtBottom && pDock->iRefCount == 0 && ! pDock->bAutoHide) || (pDock->container.iWidth != pDock->iMaxDockWidth || pDock->container.iHeight != pDock->iMaxDockHeight) || (!pDock->container.bInside))  // on le fait pas avec l'auto-hide, car un signal d'entree est deja emis a cause des mouvements/redimensionnements de la fenetre, et en rajouter un ici fout le boxon.  // !pDock->container.bInside ajoute pour le bug du chgt de bureau.
785
 
                                if ((pDock->iMagnitudeIndex == 0 && pDock->iRefCount == 0 && ! pDock->bAutoHide) || !pDock->container.bInside)
786
 
                                {
787
 
                                        //g_print ("  on emule une re-rentree (pDock->iMagnitudeIndex:%d)\n", pDock->iMagnitudeIndex);
788
 
                                        g_signal_emit_by_name (pDock->container.pWidget, "enter-notify-event", NULL, &bReturn);
789
 
                                }
790
 
                                else // on se contente de faire grossir les icones.
791
 
                                {
792
 
                                        g_print ("  on se contente de faire grossir les icones\n");
793
 
                                        cairo_dock_start_growing (pDock);
794
 
                                        if (pDock->bAutoHide && pDock->iRefCount == 0)
795
 
                                                cairo_dock_start_showing (pDock);
796
 
                                }
797
 
                        }
798
 
                break ;
799
 
 
800
 
                case CAIRO_DOCK_MOUSE_ON_THE_EDGE :
801
 
                        ///pDock->fDecorationsOffsetX = - pDock->container.iWidth / 2;  // on fixe les decorations.
802
 
                        if (pDock->iMagnitudeIndex > 0 && ! pDock->bIsGrowingUp)
803
 
                                cairo_dock_start_shrinking (pDock);
804
 
                break ;
805
 
 
806
 
                case CAIRO_DOCK_MOUSE_OUTSIDE :
807
 
                        //g_print ("en dehors du dock (bIsShrinkingDown:%d;bIsGrowingUp:%d;iMagnitudeIndex:%d;bAtBottom:%d)\n", pDock->bIsShrinkingDown, pDock->bIsGrowingUp, pDock->iMagnitudeIndex, pDock->bAtBottom);
808
 
                        ///pDock->fDecorationsOffsetX = - pDock->container.iWidth / 2;  // on fixe les decorations.
809
 
                        if (! pDock->bIsGrowingUp && ! pDock->bIsShrinkingDown && pDock->iSidLeaveDemand == 0 && pDock->iMagnitudeIndex > 0 && ! pDock->bIconIsFlyingAway)
810
 
                        {
811
 
                                //g_print ("on force a quitter (iRefCount:%d)\n", pDock->iRefCount);
812
 
                                if (pDock->iRefCount > 0 && myAccessibility.iLeaveSubDockDelay > 0)
813
 
                                        pDock->iSidLeaveDemand = g_timeout_add (myAccessibility.iLeaveSubDockDelay, (GSourceFunc) cairo_dock_emit_leave_signal, (gpointer) pDock);
814
 
                                else
815
 
                                        cairo_dock_emit_leave_signal (pDock);
816
 
                        }
817
 
                break ;
818
 
        }
819
 
}
820
 
 
821
 
#define make_icon_avoid_mouse(icon) \
822
 
        cairo_dock_mark_icon_as_avoiding_mouse (icon);\
823
 
        icon->fAlpha = 0.75;\
824
 
        if (myIcons.fAmplitude != 0)\
825
 
                icon->fDrawX += icon->fWidth / 2 * (icon->fScale - 1) / myIcons.fAmplitude * (icon->fPhase < G_PI/2 ? -1 : 1);
826
 
 
827
 
static gboolean _cairo_dock_check_can_drop_linear (CairoDock *pDock, CairoDockIconType iType, double fMargin)
828
 
{
829
 
        gboolean bCanDrop = FALSE;
830
 
        Icon *icon;
831
 
        GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
832
 
        GList *ic = pFirstDrawnElement;
833
 
        do
834
 
        {
835
 
                icon = ic->data;
836
 
                if (icon->bPointed)  // && icon->iAnimationState != CAIRO_DOCK_FOLLOW_MOUSE
837
 
                {
838
 
                        if (pDock->container.iMouseX < icon->fDrawX + icon->fWidth * icon->fScale * fMargin)  // on est a gauche.  // fDrawXAtRest
839
 
                        {
840
 
                                Icon *prev_icon = cairo_dock_get_previous_element (ic, pDock->icons) -> data;
841
 
                                if ((cairo_dock_get_icon_order (icon) == cairo_dock_get_group_order (iType) || cairo_dock_get_icon_order (prev_icon) == cairo_dock_get_group_order (iType)))  // && prev_icon->iAnimationType != CAIRO_DOCK_FOLLOW_MOUSE
842
 
                                {
843
 
                                        make_icon_avoid_mouse (icon);
844
 
                                        make_icon_avoid_mouse (prev_icon);
845
 
                                        //g_print ("%s> <%s\n", prev_icon->cName, icon->cName);
846
 
                                        bCanDrop = TRUE;
847
 
                                }
848
 
                        }
849
 
                        else if (pDock->container.iMouseX > icon->fDrawX + icon->fWidth * icon->fScale * (1 - fMargin))  // on est a droite.  // fDrawXAtRest
850
 
                        {
851
 
                                Icon *next_icon = cairo_dock_get_next_element (ic, pDock->icons) -> data;
852
 
                                if ((icon->iType == iType || next_icon->iType == iType))  // && next_icon->iAnimationType != CAIRO_DOCK_FOLLOW_MOUSE
853
 
                                {
854
 
                                        make_icon_avoid_mouse (icon);
855
 
                                        make_icon_avoid_mouse (next_icon);
856
 
                                        //g_print ("%s> <%s\n", icon->cName, next_icon->cName);
857
 
                                        bCanDrop = TRUE;
858
 
                                }
859
 
                                ic = cairo_dock_get_next_element (ic, pDock->icons);  // on la saute.
860
 
                                if (ic == pFirstDrawnElement)
861
 
                                        break ;
862
 
                        }  // else on est dessus.
863
 
                }
864
 
                else
865
 
                        cairo_dock_stop_marking_icon_as_avoiding_mouse (icon);
866
 
                
867
 
                ic = cairo_dock_get_next_element (ic, pDock->icons);
868
 
        } while (ic != pFirstDrawnElement);
869
 
        
870
 
        return bCanDrop;
871
 
}
872
 
 
873
 
 
874
 
void cairo_dock_check_can_drop_linear (CairoDock *pDock)
875
 
{
876
 
        if (pDock->icons == NULL)
877
 
                return;
878
 
        
879
 
        if (pDock->bIsDragging)
880
 
                pDock->bCanDrop = _cairo_dock_check_can_drop_linear (pDock, pDock->iAvoidingMouseIconType, pDock->fAvoidingMouseMargin);
881
 
        else
882
 
                pDock->bCanDrop = FALSE;
883
 
}
884
 
 
885
 
void cairo_dock_stop_marking_icons (CairoDock *pDock)
886
 
{
887
 
        if (pDock->icons == NULL)
888
 
                return;
889
 
        //g_print ("%s (%d)\n", __func__, iType);
890
 
 
891
 
        Icon *icon;
892
 
        GList *ic;
893
 
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
894
 
        {
895
 
                icon = ic->data;
896
 
                cairo_dock_stop_marking_icon_as_avoiding_mouse (icon);
897
 
        }
898
 
}
899
 
 
900
 
 
901
 
void cairo_dock_set_subdock_position_linear (Icon *pPointedIcon, CairoDock *pDock)
902
 
{
903
 
        CairoDock *pSubDock = pPointedIcon->pSubDock;
904
 
        int iX = pPointedIcon->fXAtRest - (pDock->fFlatDockWidth - pDock->iMaxDockWidth) / 2 + pPointedIcon->fWidth / 2 + (pDock->iOffsetForExtend * (pDock->fAlign - .5) * 2);
905
 
        if (pSubDock->container.bIsHorizontal == pDock->container.bIsHorizontal)
906
 
        {
907
 
                pSubDock->fAlign = 0.5;
908
 
                pSubDock->iGapX = iX + pDock->container.iWindowPositionX - (pDock->container.bIsHorizontal ? pDock->iScreenOffsetX : pDock->iScreenOffsetY) - g_iScreenWidth[pDock->container.bIsHorizontal] / 2;  // ici les sous-dock ont un alignement egal a 0.5
909
 
                pSubDock->iGapY = pDock->iGapY + pDock->iMaxDockHeight;
910
 
        }
911
 
        else
912
 
        {
913
 
                pSubDock->fAlign = (pDock->container.bDirectionUp ? 1 : 0);
914
 
                pSubDock->iGapX = (pDock->iGapY + pDock->iMaxDockHeight) * (pDock->container.bDirectionUp ? -1 : 1);
915
 
                if (pDock->container.bDirectionUp)
916
 
                        pSubDock->iGapY = g_iScreenWidth[pDock->container.bIsHorizontal] - (iX + pDock->container.iWindowPositionX - (pDock->container.bIsHorizontal ? pDock->iScreenOffsetX : pDock->iScreenOffsetY)) - pSubDock->iMaxDockHeight / 2;  // les sous-dock ont un alignement egal a 1.
917
 
                else
918
 
                        pSubDock->iGapY = iX + pDock->container.iWindowPositionX - pSubDock->iMaxDockHeight / 2;  // les sous-dock ont un alignement egal a 0.
919
 
        }
920
 
}
921
 
 
922
 
 
923
 
GList *cairo_dock_get_first_drawn_element_linear (GList *icons)
924
 
{
925
 
        Icon *icon;
926
 
        GList *ic;
927
 
        GList *pFirstDrawnElement = NULL;
928
 
        for (ic = icons; ic != NULL; ic = ic->next)
929
 
        {
930
 
                icon = ic->data;
931
 
                if (icon->bPointed)
932
 
                        break ;
933
 
        }
934
 
        
935
 
        if (ic == NULL || ic->next == NULL)  // derniere icone ou aucune pointee.
936
 
                pFirstDrawnElement = icons;
937
 
        else
938
 
                pFirstDrawnElement = ic->next;
939
 
        return pFirstDrawnElement;
940
 
}
941
 
 
942
 
 
943
 
void cairo_dock_show_subdock (Icon *pPointedIcon, CairoDock *pParentDock, gboolean bUpdateBefore)
944
 
{
945
 
        cd_debug ("on montre le dock fils");
946
 
        CairoDock *pSubDock = pPointedIcon->pSubDock;
947
 
        g_return_if_fail (pSubDock != NULL);
948
 
        
949
 
        if (GTK_WIDGET_VISIBLE (pSubDock->container.pWidget))  // il est deja visible.
950
 
        {
951
 
                if (pSubDock->bIsShrinkingDown)  // il est en cours de diminution, on renverse le processus.
952
 
                {
953
 
                        cairo_dock_start_growing (pSubDock);
954
 
                }
955
 
                return ;
956
 
        }
957
 
        
958
 
        if (bUpdateBefore)
959
 
        {
960
 
                pParentDock->pRenderer->calculate_icons (pParentDock);  // c'est un peu un hack pourri, l'idee c'est de recalculer la position exacte de l'icone pointee pour pouvoir placer le sous-dock precisement, car sa derniere position connue est decalee d'un coup de molette par rapport a la nouvelle, ce qui fait beaucoup. L'ideal etant de le faire que pour l'icone concernee ...
961
 
        }
962
 
        
963
 
        pSubDock->pRenderer->set_subdock_position (pPointedIcon, pParentDock);
964
 
        
965
 
        if (pSubDock->icons != NULL)
966
 
        {
967
 
                pSubDock->fFoldingFactor = (mySystem.bAnimateSubDock ? .99 : 0.);
968
 
                /*cairo_dock_notify_on_icon (pPointedIcon, CAIRO_DOCK_UNFOLD_SUBDOCK, pPointedIcon);*/  // 2.1.4
969
 
        }
970
 
        
971
 
        int iNewWidth = pSubDock->iMaxDockWidth;
972
 
        int iNewHeight = pSubDock->iMaxDockHeight;
973
 
        int iNewPositionX, iNewPositionY;
974
 
        cairo_dock_get_window_position_at_balance (pSubDock, iNewWidth, iNewHeight, &iNewPositionX, &iNewPositionY);
975
 
        
976
 
        gtk_window_present (GTK_WINDOW (pSubDock->container.pWidget));
977
 
        
978
 
        if (pSubDock->container.bIsHorizontal)
979
 
                        gdk_window_move_resize (pSubDock->container.pWidget->window,
980
 
                        iNewPositionX,
981
 
                        iNewPositionY,
982
 
                        iNewWidth,
983
 
                        iNewHeight);
984
 
        else
985
 
                gdk_window_move_resize (pSubDock->container.pWidget->window,
986
 
                        iNewPositionY,
987
 
                        iNewPositionX,
988
 
                        iNewHeight,
989
 
                        iNewWidth);
990
 
        
991
 
        if (pSubDock->fFoldingFactor == 0.)
992
 
        {
993
 
                cd_debug ("  on montre le sous-dock sans animation");
994
 
        }
995
 
        else
996
 
        {
997
 
                cd_debug ("  on montre le sous-dock avec animation");
998
 
                cairo_dock_start_growing (pSubDock);  // on commence a faire grossir les icones.
999
 
                pSubDock->pRenderer->calculate_icons (pSubDock);  // on recalcule les icones car sinon le 1er dessin se fait avec les parametres tels qu'ils etaient lorsque le dock s'est cache; or l'animation de pliage peut prendre plus de temps que celle de cachage.
1000
 
        }
1001
 
        //g_print ("  -> Gap %d;%d -> W(%d;%d) (%d)\n", pSubDock->iGapX, pSubDock->iGapY, pSubDock->container.iWindowPositionX, pSubDock->container.iWindowPositionY, pSubDock->container.bIsHorizontal);
1002
 
        
1003
 
        gtk_window_set_keep_above (GTK_WINDOW (pSubDock->container.pWidget), myAccessibility.bPopUp);
1004
 
        
1005
 
        cairo_dock_replace_all_dialogs ();
1006
 
}
1007
 
 
1008
 
 
1009
 
 
1010
 
static gboolean _redraw_subdock_content (Icon *pIcon)
1011
 
{
1012
 
        if (pIcon->pSubDock != NULL)
1013
 
        {
1014
 
                CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
1015
 
                if (pDock != NULL)
1016
 
                {
1017
 
                        cairo_dock_draw_subdock_content_on_icon (pIcon, pDock);
1018
 
                        cairo_dock_redraw_icon (pIcon, CAIRO_CONTAINER (pDock));
1019
 
                }
1020
 
        }
1021
 
        else  // l'icone a pu perdre son sous-dock entre-temps (exemple : une classe d'appli contenant 2 icones, dont on enleve l'une des 2.
1022
 
        {
1023
 
                CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
1024
 
                if (pDock != NULL)
1025
 
                {
1026
 
                        cairo_dock_reload_one_icon_buffer_in_dock (pIcon, pDock);
1027
 
                        cairo_dock_redraw_icon (pIcon, CAIRO_CONTAINER (pDock));
1028
 
                }
1029
 
        }
1030
 
        pIcon->iSidRedrawSubdockContent = 0;
1031
 
        return FALSE;
1032
 
}
1033
 
void cairo_dock_trigger_redraw_subdock_content (CairoDock *pDock)
1034
 
{
1035
 
        Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
1036
 
        if (pPointingIcon != NULL && (pPointingIcon->iSubdockViewType != 0 || pPointingIcon->cClass != NULL) && pPointingIcon->iSidRedrawSubdockContent == 0 && CAIRO_DOCK_IS_LAUNCHER (pPointingIcon))
1037
 
                pPointingIcon->iSidRedrawSubdockContent = g_idle_add ((GSourceFunc) _redraw_subdock_content, pPointingIcon);
1038
 
}
1039
 
 
1040
 
void cairo_dock_redraw_subdock_content (CairoDock *pDock)
1041
 
{
1042
 
        CairoDock *pParentDock = NULL;
1043
 
        Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
1044
 
        if (pPointingIcon != NULL && pPointingIcon->iSubdockViewType != 0 && pPointingIcon->iSidRedrawSubdockContent == 0 && pParentDock != NULL)
1045
 
        {
1046
 
                cairo_dock_draw_subdock_content_on_icon (pPointingIcon, pParentDock);
1047
 
                cairo_dock_redraw_icon (pPointingIcon, CAIRO_CONTAINER (pParentDock));
1048
 
        }
1049
 
}
1050
 
 
1051
 
static gboolean _update_WM_icons (CairoDock *pDock)
1052
 
{
1053
 
        cairo_dock_set_icons_geometry_for_window_manager (pDock);
1054
 
        pDock->iSidUpdateWMIcons = 0;
1055
 
        return FALSE;
1056
 
}
1057
 
void cairo_dock_trigger_set_WM_icons_geometry (CairoDock *pDock)
1058
 
{
1059
 
        if (pDock->iSidUpdateWMIcons == 0)
1060
 
        {
1061
 
                pDock->iSidUpdateWMIcons = g_idle_add ((GSourceFunc) _update_WM_icons, pDock);
1062
 
        }
1063
 
}