2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20
/******************************************************************************
22
This file is a part of the cairo-dock program,
23
released under the terms of the GNU General Public License.
25
Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
27
******************************************************************************/
32
#include <gdk/x11/gdkglx.h>
33
#include <gtk/gtkgl.h>
35
#include "applet-struct.h"
36
#include "applet-notifications.h"
37
#include "bilinear-gradation-texture.h"
40
gboolean cd_drop_indicator_render (gpointer pUserData, CairoDock *pDock, cairo_t *pCairoContext)
42
CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock);
44
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
46
if (pCairoContext != NULL)
48
cairo_save (pCairoContext);
49
double fX = pDock->iMouseX - myData.fDropIndicatorWidth / 2;
50
if (pDock->bHorizontalDock)
51
cairo_rectangle (pCairoContext,
52
(int) pDock->iMouseX - myData.fDropIndicatorWidth/2,
53
(int) (pDock->bDirectionUp ? 0 : pDock->iCurrentHeight - 2*myData.fDropIndicatorHeight),
54
(int) myData.fDropIndicatorWidth,
55
(int) (pDock->bDirectionUp ? 2*myData.fDropIndicatorHeight : pDock->iCurrentHeight));
57
cairo_rectangle (pCairoContext,
58
(int) (pDock->bDirectionUp ? 0 : pDock->iCurrentHeight - 2*myData.fDropIndicatorHeight),
59
(int) pDock->iMouseX - myData.fDropIndicatorWidth/2,
60
(int) (pDock->bDirectionUp ? 2*myData.fDropIndicatorHeight : pDock->iCurrentHeight),
61
(int) myData.fDropIndicatorWidth);
62
cairo_clip (pCairoContext);
64
//cairo_move_to (pCairoContext, fX, 0);
65
if (pDock->bHorizontalDock)
66
cairo_translate (pCairoContext, fX, (pDock->bDirectionUp ? 0 : pDock->iCurrentHeight));
68
cairo_translate (pCairoContext, (pDock->bDirectionUp ? 0 : pDock->iCurrentHeight), fX);
69
double fRotationAngle = (pDock->bHorizontalDock ? (pDock->bDirectionUp ? 0 : G_PI) : (pDock->bDirectionUp ? -G_PI/2 : G_PI/2));
70
cairo_rotate (pCairoContext, fRotationAngle);
72
cairo_translate (pCairoContext, 0, pData->iDropIndicatorOffset);
73
cairo_pattern_t* pPattern = cairo_pattern_create_for_surface (myData.pDropIndicatorSurface);
74
g_return_val_if_fail (cairo_pattern_status (pPattern) == CAIRO_STATUS_SUCCESS, CAIRO_DOCK_LET_PASS_NOTIFICATION);
75
cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_REPEAT);
76
cairo_set_source (pCairoContext, pPattern);
78
cairo_translate (pCairoContext, 0, - pData->iDropIndicatorOffset);
79
cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (0.,
82
2*myData.fDropIndicatorHeight); // de haut en bas.
83
g_return_val_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS, CAIRO_DOCK_LET_PASS_NOTIFICATION);
85
cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
86
cairo_pattern_add_color_stop_rgba (pGradationPattern,
92
cairo_pattern_add_color_stop_rgba (pGradationPattern,
98
cairo_pattern_add_color_stop_rgba (pGradationPattern,
104
cairo_pattern_add_color_stop_rgba (pGradationPattern,
111
cairo_mask (pCairoContext, pGradationPattern);
112
//cairo_paint (pCairoContext);
114
cairo_pattern_destroy (pPattern);
115
cairo_pattern_destroy (pGradationPattern);
116
cairo_restore (pCairoContext);
118
if (pData->fAlphaHover > 0 && myData.pHoverIndicatorSurface != NULL)
120
Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons);
121
if (pIcon != NULL && ! CAIRO_DOCK_IS_SEPARATOR (pIcon))
123
cairo_save (pCairoContext);
124
if (pDock->bHorizontalDock)
125
cairo_translate (pCairoContext,
126
pIcon->fDrawX + 2./3*pIcon->fWidth*pIcon->fScale,
129
cairo_translate (pCairoContext,
131
pIcon->fDrawX + 2./3*pIcon->fWidth*pIcon->fScale);
132
cairo_set_source_surface (pCairoContext, myData.pHoverIndicatorSurface, 0., 0.);
133
cairo_paint_with_alpha (pCairoContext, pData->fAlphaHover);
134
cairo_restore (pCairoContext);
140
double fX = pDock->iMouseX;
141
double fY = (pDock->bDirectionUp ? pDock->iCurrentHeight - myData.fDropIndicatorHeight : myData.fDropIndicatorHeight);
145
if (pDock->bHorizontalDock)
148
fY = (pDock->bDirectionUp ? pDock->iCurrentHeight - myData.fDropIndicatorHeight : myData.fDropIndicatorHeight);
149
glTranslatef (fX, fY, - myData.fDropIndicatorWidth-1.);
150
if (! pDock->bDirectionUp)
151
glScalef (1., -1., 1.);
155
fX = pDock->iCurrentWidth - pDock->iMouseX;
156
fY = (! pDock->bDirectionUp ? pDock->iCurrentHeight - myData.fDropIndicatorHeight : myData.fDropIndicatorHeight);
157
glTranslatef (fY, fX, - myData.fDropIndicatorWidth-1.);
158
glRotatef ((pDock->bDirectionUp ? 90. : -90.), 0., 0., 1.);
161
glRotatef (pData->iDropIndicatorRotation, 0., 1., 0.);
163
//\_________________ On decale la texture vers le bas.
164
glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures
166
glLoadIdentity(); // On la reset
167
glTranslatef(.0, - pData->iDropIndicatorOffset / myData.fDropIndicatorHeight, 0.);
168
glScalef (1., -2., 1.);
169
glMatrixMode(GL_MODELVIEW); // On revient sur la matrice d'affichage
171
//\_________________ On dessine l'indicateur.
173
if (pData->fAlpha != 1)
174
_cairo_dock_set_blend_alpha ();
176
_cairo_dock_set_blend_over();
178
//glEnable(GL_DEPTH_TEST);
179
glScalef (myData.fDropIndicatorWidth, myData.fDropIndicatorHeight, myData.fDropIndicatorWidth);
180
glColor4f(1.0f, 1.0f, 1.0f, pData->fAlpha);
181
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
183
glEnable(GL_TEXTURE);
184
glActiveTextureARB(GL_TEXTURE0_ARB); // Go pour le multitexturing 1ere passe
185
glEnable(GL_TEXTURE_2D); // On active le texturing sur cette passe
186
glBindTexture(GL_TEXTURE_2D, myData.iDropIndicatorTexture);
187
glActiveTextureARB(GL_TEXTURE1_ARB); // Go pour le texturing 2eme passe
188
glEnable(GL_TEXTURE_2D);
189
glBindTexture(GL_TEXTURE_2D, myData.iBilinearGradationTexture);
190
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Le mode de combinaison des textures
191
///glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); // multiplier les alpha.
192
//glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA);
196
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(-0.5, -1., 0.); // Bottom Left Of The Texture and Quad
197
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f( 0.5, -1., 0.); // Bottom Right Of The Texture and Quad
198
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f( 0.5, 1., 0.); // Top Right Of The Texture and Quad
199
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(-0.5, 1., 0.); // Top Left Of The Texture and Quad
201
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 0.); glVertex3f(0., -1., -0.5); // Bottom Left Of The Texture and Quad
202
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 0.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 0.); glVertex3f(0., -1., 0.5); // Bottom Right Of The Texture and Quad
203
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,1., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,1., 1.); glVertex3f(0., 1., 0.5); // Top Right Of The Texture and Quad
204
glMultiTexCoord2fARB( GL_TEXTURE0_ARB,0., 1.); glMultiTexCoord2fARB( GL_TEXTURE1_ARB,0., 1.); glVertex3f(0., 1., -0.5); // Top Left Of The Texture and Quad
207
glActiveTextureARB(GL_TEXTURE1_ARB);
208
glDisable(GL_TEXTURE_2D);
209
glDisable(GL_TEXTURE_GEN_S);
210
glDisable(GL_TEXTURE_GEN_T);
211
glActiveTextureARB(GL_TEXTURE0_ARB);
212
glDisable(GL_TEXTURE_2D);
213
glDisable(GL_TEXTURE_GEN_S);
214
glDisable(GL_TEXTURE_GEN_T);
215
glDisable (GL_BLEND);
216
_cairo_dock_set_blend_alpha ();
219
//\_________________ On remet la matrice des textures.
220
glMatrixMode(GL_TEXTURE);
222
glMatrixMode(GL_MODELVIEW);
224
if (pData->fAlphaHover > 0 && myData.iHoverIndicatorTexture != 0)
226
Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons);
227
if (pIcon != NULL && ! CAIRO_DOCK_IS_SEPARATOR (pIcon))
229
_cairo_dock_enable_texture ();
230
_cairo_dock_set_blend_over ();
232
if (pDock->bHorizontalDock)
233
glTranslatef (pIcon->fDrawX + 5./6*pIcon->fWidth*pIcon->fScale,
234
pDock->iCurrentHeight - pIcon->fDrawY - 1./6*pIcon->fHeight*pIcon->fScale,
237
glTranslatef (pDock->iCurrentHeight - pIcon->fDrawY - 1./6*pIcon->fHeight*pIcon->fScale,
238
pDock->iCurrentWidth - (pIcon->fDrawX + 5./6*pIcon->fWidth*pIcon->fScale),
240
_cairo_dock_apply_texture_at_size_with_alpha (myData.iHoverIndicatorTexture,
241
myData.fHoverIndicatorWidth,
242
myData.fHoverIndicatorHeight,
245
_cairo_dock_disable_texture ();
249
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
253
gboolean cd_drop_indicator_mouse_moved (gpointer pUserData, CairoDock *pDock, gboolean *bStartAnimation)
255
CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock);
257
if (pDock->bIsDragging)
261
pData = g_new0 (CDDropIndicatorData, 1);
262
CD_APPLET_SET_MY_DOCK_DATA (pDock, pData);
267
pData->fAlphaHover = 1.;
269
else if (pData != NULL && pData->fAlpha <= 0 && pData->fAlphaHover <= 0)
273
CD_APPLET_SET_MY_DOCK_DATA (pDock, NULL);
276
*bStartAnimation = (pData != NULL);
277
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
281
gboolean cd_drop_indicator_update_dock (gpointer pUserData, CairoDock *pDock, gboolean *bContinueAnimation)
283
CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock);
285
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
287
pData->iDropIndicatorOffset += myConfig.iSpeed;
288
if (pData->iDropIndicatorOffset > 2*myData.fDropIndicatorHeight)
289
pData->iDropIndicatorOffset -= 2*myData.fDropIndicatorHeight;
290
double dt = (CAIRO_CONTAINER_IS_OPENGL (CAIRO_CONTAINER (pDock)) ? mySystem.iGLAnimationDeltaT : mySystem.iCairoAnimationDeltaT);
291
pData->iDropIndicatorRotation += myConfig.fRotationSpeed * 360. * dt/1e3;
294
pData->fAlphaHover -= .05;
295
*bContinueAnimation = TRUE;
299
pData->fAlpha -= .05;
300
if (!pDock->bIsDragging)
301
pData->fAlphaHover -= .05;
303
if (pData->fAlpha <= 0 && pData->fAlphaHover <= 0)
306
CD_APPLET_SET_MY_DOCK_DATA (pDock, NULL);
309
*bContinueAnimation = TRUE;
312
GdkRectangle rect = {(int) pDock->iMouseX - myData.fDropIndicatorWidth/2,
313
(int) (pDock->bDirectionUp ? 0 : pDock->iCurrentHeight - 2*myData.fDropIndicatorHeight),
314
(int) myData.fDropIndicatorWidth,
315
(int) 2*myData.fDropIndicatorHeight};
316
if (! pDock->bHorizontalDock)
318
rect.x = (int) (pDock->bDirectionUp ? 0 : pDock->iCurrentHeight - 2*myData.fDropIndicatorHeight);
319
rect.y = (int) pDock->iMouseX - myData.fDropIndicatorWidth/2;
320
rect.width = (int) 2*myData.fDropIndicatorHeight;
321
rect.height =(int) myData.fDropIndicatorWidth;
323
//g_print ("rect (%d;%d) (%dx%d)\n", rect.x, rect.y, rect.width, rect.height);
324
if (rect.width > 0 && rect.height > 0)
326
gdk_window_invalidate_rect (pDock->pWidget->window, &rect, FALSE);
329
if (pData->fAlphaHover > 0)
331
Icon *pIcon = cairo_dock_get_pointed_icon (pDock->icons);
333
cairo_dock_redraw_icon (pIcon, pDock);
336
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
340
void cd_drop_indicator_load_drop_indicator (gchar *cImagePath, cairo_t* pSourceContext, int iWidth, int iHeight)
342
cd_message ("%s (%s)\n", __func__, cImagePath);
343
if (myData.pDropIndicatorSurface != NULL)
344
cairo_surface_destroy (myData.pDropIndicatorSurface);
345
if (myData.iDropIndicatorTexture != 0)
347
_cairo_dock_delete_texture (myData.iDropIndicatorTexture);
348
myData.iDropIndicatorTexture = 0;
350
myData.pDropIndicatorSurface = cairo_dock_create_surface_from_image (cImagePath,
355
CAIRO_DOCK_KEEP_RATIO,
356
&myData.fDropIndicatorWidth, &myData.fDropIndicatorHeight,
358
if (g_bUseOpenGL && myData.pDropIndicatorSurface != NULL)
360
myData.iDropIndicatorTexture = cairo_dock_create_texture_from_surface (myData.pDropIndicatorSurface);
362
if (myData.iBilinearGradationTexture == 0)
363
myData.iBilinearGradationTexture = cairo_dock_load_texture_from_raw_data (gradationTex, 1, 32);
367
void cd_drop_indicator_load_hover_indicator (gchar *cImagePath, cairo_t* pSourceContext, int iWidth, int iHeight)
369
cd_message ("%s (%s)\n", __func__, cImagePath);
370
if (myData.pHoverIndicatorSurface != NULL)
371
cairo_surface_destroy (myData.pHoverIndicatorSurface);
372
if (myData.iHoverIndicatorTexture != 0)
374
_cairo_dock_delete_texture (myData.iHoverIndicatorTexture);
375
myData.iHoverIndicatorTexture = 0;
377
myData.pHoverIndicatorSurface = cairo_dock_create_surface_from_image (cImagePath,
382
CAIRO_DOCK_KEEP_RATIO,
383
&myData.fHoverIndicatorWidth, &myData.fHoverIndicatorHeight,
385
if (g_bUseOpenGL && myData.pHoverIndicatorSurface != NULL)
387
myData.iHoverIndicatorTexture = cairo_dock_create_texture_from_surface (myData.pHoverIndicatorSurface);
392
gboolean cd_drop_indicator_stop_dock (gpointer data, CairoDock *pDock)
394
CDDropIndicatorData *pData = CD_APPLET_GET_MY_DOCK_DATA (pDock);
398
CD_APPLET_SET_MY_DOCK_DATA (pDock, NULL);
400
return CAIRO_DOCK_LET_PASS_NOTIFICATION;