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
******************************************************************************/
33
#include "applet-notifications.h"
36
static double fRadius = .33;
40
gboolean cd_show_mouse_render (gpointer pUserData, CairoContainer *pContainer, cairo_t *pCairoContext)
42
CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
44
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
48
if (CAIRO_DOCK_IS_DESKLET (pContainer))
50
CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
51
glTranslatef (-pDesklet->iWidth/2, -pDesklet->iHeight/2, -pDesklet->iHeight*(sqrt(3)/2));
53
if (pContainer->bIsHorizontal)
54
glTranslatef (pContainer->iMouseX, pContainer->iHeight - pContainer->iMouseY, 0.);
56
glTranslatef (pContainer->iMouseY, pContainer->iWidth - pContainer->iMouseX, 0.);
57
cairo_dock_render_particles (pData->pSystem);
61
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
65
#define _compute_area(area, pContainer, pData) do {\
66
if (pContainer->bIsHorizontal) {\
67
area.x = pContainer->iMouseX - pData->pSystem->fWidth/2;\
68
area.y = MAX (0, pContainer->iMouseY - pData->pSystem->fHeight);\
69
area.width = pData->pSystem->fWidth;\
70
area.height = pData->pSystem->fHeight*2; }\
72
area.y = pContainer->iMouseX - pData->pSystem->fWidth/2;\
73
area.x = MAX (0, pContainer->iMouseY - pData->pSystem->fHeight);\
74
area.height = pData->pSystem->fWidth;\
75
area.width = pData->pSystem->fHeight*2; } } while (0)
76
gboolean cd_show_mouse_update_container (gpointer pUserData, CairoContainer *pContainer, gboolean *bContinueAnimation)
78
CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
80
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
83
if (! pContainer->bInside)
86
if (pData->fAlpha <= 0)
88
_compute_area (area, pContainer, pData);
89
cairo_dock_redraw_container_area (pContainer, &area);
91
cairo_dock_free_particle_system (pData->pSystem);
93
CD_APPLET_SET_MY_CONTAINER_DATA (pContainer, NULL);
95
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
98
else if (pData->fAlpha != 1)
99
pData->fAlpha = MIN (1., pData->fAlpha + .05);
101
pData->fRotationAngle += 2*G_PI * myConfig.fRotationSpeed * mySystem.iGLAnimationDeltaT / 1000.;
103
cd_show_mouse_update_sources (pData);
104
pData->pSystem->fWidth = 2 * MIN (96, pContainer->iHeight);
105
pData->pSystem->fHeight = MIN (96, pContainer->iHeight);
106
cd_show_mouse_update_particle_system (pData->pSystem, pData);
108
_compute_area (area, pContainer, pData);
109
cairo_dock_redraw_container_area (pContainer, &area);
111
*bContinueAnimation = TRUE;
112
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
116
gboolean cd_show_mouse_enter_container (gpointer pUserData, CairoContainer *pContainer, gboolean *bStartAnimation)
118
if (! CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer))
119
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
121
CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
124
pData = g_new0 (CDShowMouseData, 1);
127
double dt = mySystem.iGLAnimationDeltaT;
128
pData->pSourceCoords = cd_show_mouse_init_sources ();
129
pData->pSystem = cd_show_mouse_init_system (pContainer, dt, pData->pSourceCoords);
131
CD_APPLET_SET_MY_CONTAINER_DATA (pContainer, pData);
135
*bStartAnimation = TRUE;
136
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
141
gdouble *cd_show_mouse_init_sources (void)
143
double *pSourceCoords = g_new (double, myConfig.iNbSources * 2);
146
for (i = 0; i < myConfig.iNbSources; i ++)
148
fTheta = 2*G_PI * i / myConfig.iNbSources;
149
pSourceCoords[2*i] = fRadius * cos (fTheta);
150
pSourceCoords[2*i+1] = fRadius * sin (fTheta);
152
return pSourceCoords;
155
CairoParticleSystem *cd_show_mouse_init_system (CairoContainer *pContainer, double dt, double *pSourceCoords)
157
if (myData.iTexture == 0)
158
myData.iTexture = cairo_dock_load_texture_from_raw_data (starTex, 32, 32); /// 32 = sqrt (4096/4)
159
double fHeight = pContainer->iHeight; // iMaxDockHeight ?
160
CairoParticleSystem *pParticleSystem = cairo_dock_create_particle_system (myConfig.iNbParticles * myConfig.iNbSources, myData.iTexture, 2*fHeight, fHeight);
161
pParticleSystem->dt = dt;
165
double r = myConfig.iParticleSize / (1 + a);
166
double sigma = myConfig.fScattering;
169
for (i = 0; i < pParticleSystem->iNbParticles; i ++)
171
p = &(pParticleSystem->pParticles[i]);
173
iNumSource = i / myConfig.iNbParticles;
175
p->x = pSourceCoords[2*iNumSource];
176
p->y = pSourceCoords[2*iNumSource+1];
178
p->fWidth = r * (a + g_random_double ());
179
p->fHeight = p->fWidth;
181
p->vx = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
182
p->vy = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
183
p->iInitialLife = ceil (myConfig.iParticleLifeTime / dt);
184
p->iLife = g_random_int_range (1, p->iInitialLife+1);
186
if (myConfig.bMysticalFire)
188
p->color[0] = g_random_double ();
189
p->color[1] = g_random_double ();
190
p->color[2] = g_random_double ();
194
fBlend = g_random_double ();
195
p->color[0] = fBlend * myConfig.pColor1[0] + (1 - fBlend) * myConfig.pColor2[0];
196
p->color[1] = fBlend * myConfig.pColor1[1] + (1 - fBlend) * myConfig.pColor2[1];
197
p->color[2] = fBlend * myConfig.pColor1[2] + (1 - fBlend) * myConfig.pColor2[2];
202
p->fResizeSpeed = .5 / myConfig.iParticleLifeTime * dt; // zoom 1.5 a la fin.
205
return pParticleSystem;
209
void cd_show_mouse_update_sources (CDShowMouseData *pData)
211
double *pSourceCoords = pData->pSourceCoords;
214
for (i = 0; i < myConfig.iNbSources; i ++)
216
fTheta = 2*G_PI * i / myConfig.iNbSources + pData->fRotationAngle;
217
pSourceCoords[2*i] = fRadius * cos (fTheta);
218
pSourceCoords[2*i+1] = fRadius * sin (fTheta);
223
void cd_show_mouse_update_particle_system (CairoParticleSystem *pParticleSystem, CDShowMouseData *pData)
225
double *pSourceCoords = pData->pSourceCoords;
227
double dt = pParticleSystem->dt;
229
double sigma = myConfig.fScattering;
230
for (i = 0; i < pParticleSystem->iNbParticles; i ++)
232
p = &(pParticleSystem->pParticles[i]);
236
p->color[3] = pData->fAlpha * p->iLife / p->iInitialLife;
237
p->fSizeFactor += p->fResizeSpeed;
243
int iNumSource = i / myConfig.iNbParticles;
244
p->x = pSourceCoords[2*iNumSource];
245
p->y = pSourceCoords[2*iNumSource+1];
247
p->vx = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
248
p->vy = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
250
p->color[3] = pData->fAlpha;
253
p->iLife = g_random_int_range (1, p->iInitialLife+1);
259
gboolean cd_show_mouse_free_data (gpointer pUserData, CairoContainer *pContainer)
262
CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
264
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
266
cairo_dock_free_particle_system (pData->pSystem);
268
CD_APPLET_SET_MY_CONTAINER_DATA (pContainer, NULL);
269
return CAIRO_DOCK_LET_PASS_NOTIFICATION;