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 <stdlib.h>
22 #include <string.h>
23
24 #include "applet-struct.h"
25 #include "applet-rays.h"
26 #include "applet-notifications.h"
27 #include "applet-spot.h"
28
29
init(Icon * pIcon,CairoDock * pDock,CDAnimationData * pData,double dt,gboolean bUseOpenGL)30 static void init (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, double dt, gboolean bUseOpenGL)
31 {
32 if (myData.iSpotTexture == 0)
33 myData.iSpotTexture = cd_animation_load_spot_texture ();
34 if (myData.iHaloTexture == 0)
35 myData.iHaloTexture = cd_animation_load_halo_texture ();
36 if (myData.iSpotFrontTexture == 0 && myConfig.cSpotFrontImage != NULL)
37 myData.iSpotFrontTexture = cd_animation_load_spot_front_texture ();
38 if (myData.iRaysTexture == 0)
39 myData.iRaysTexture = cd_animations_load_rays_texture ();
40 if (pData->pRaysSystem == NULL && myConfig.iNbRaysParticles != 0)
41 pData->pRaysSystem = cd_animations_init_rays (pIcon, pDock, dt);
42 pData->fRadiusFactor = .001;
43 pData->fHaloRotationAngle = 0;
44 pData->bGrowingSpot = TRUE;
45 }
46
_cd_animations_render_rays(Icon * pIcon,CairoDock * pDock,CDAnimationData * pData,int iDepth)47 static void _cd_animations_render_rays (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, int iDepth)
48 {
49 glPushMatrix ();
50 if (pDock->container.bIsHorizontal)
51 glTranslatef (0., - pIcon->fHeight * pIcon->fScale/2, 0.);
52 else
53 glTranslatef (- pIcon->fHeight * pIcon->fScale/2, 0., 0.);
54
55 if (! pDock->container.bIsHorizontal)
56 glRotatef (-90, 0., 0., 1.);
57
58 if (pData->pRaysSystem != NULL)
59 {
60 cairo_dock_render_particles_full (pData->pRaysSystem, iDepth);
61 }
62
63 glPopMatrix ();
64 }
65
cd_animation_render_spot(Icon * pIcon,CairoDock * pDock,gdouble fRadiusFactor)66 static void cd_animation_render_spot (Icon *pIcon, CairoDock *pDock, gdouble fRadiusFactor)
67 {
68 glPushMatrix ();
69 //\___________________On se place au bas de l'icone.
70 if (! pDock->container.bIsHorizontal)
71 glRotatef (90, 0., 0., 1.);
72 double fY = (- pIcon->fHeight + CD_ANIMATIONS_SPOT_HEIGHT) * pIcon->fScale/2; // * fRadiusFactor
73 if (pDock->container.bUseReflect)
74 fY -= MIN (pDock->iIconSize * myIconsParam.fReflectHeightRatio, CD_ANIMATIONS_SPOT_HEIGHT/2);
75 if (! pDock->container.bDirectionUp)
76 fY = -fY;
77 glTranslatef (0., fY, 0.);
78 if (! pDock->container.bDirectionUp)
79 glScalef (1., -1., 1.);
80
81 glColor4f (myConfig.pSpotColor[0], myConfig.pSpotColor[1], myConfig.pSpotColor[2], .9 * fRadiusFactor * pIcon->fAlpha);
82 //cairo_dock_draw_texture (myData.iSpotTexture, fRadiusFactor * pIcon->fWidth * pIcon->fScale, fRadiusFactor * CD_ANIMATIONS_SPOT_HEIGHT * pIcon->fScale);
83 _cairo_dock_enable_texture ();
84 _cairo_dock_set_blend_alpha ();
85
86 _cairo_dock_apply_texture_at_size (myData.iSpotTexture,
87 pIcon->fWidth * pIcon->fScale,
88 CD_ANIMATIONS_SPOT_HEIGHT * pIcon->fScale);
89
90 _cairo_dock_disable_texture ();
91
92 glPopMatrix ();
93 }
94
cd_animation_render_halo(Icon * pIcon,CairoDock * pDock,gdouble fRadiusFactor,int fHaloRotationAngle)95 static void cd_animation_render_halo (Icon *pIcon, CairoDock *pDock, gdouble fRadiusFactor, int fHaloRotationAngle)
96 {
97 glPushMatrix ();
98
99 //\___________________On se place au bas de l'icone.
100 if (! pDock->container.bIsHorizontal)
101 glRotatef (90, 0., 0., 1.);
102 double fY = CD_ANIMATIONS_SPOT_HEIGHT * (1 + cos (G_PI * fHaloRotationAngle / 180.))/2 - pIcon->fHeight * pIcon->fScale/2; // * fRadiusFactor
103 if (pDock->container.bUseReflect)
104 fY -= MIN (pDock->iIconSize * myIconsParam.fReflectHeightRatio, CD_ANIMATIONS_SPOT_HEIGHT/2);
105 if (! pDock->container.bDirectionUp)
106 fY = -fY;
107 double fX = .9 * pIcon->fWidth * pIcon->fScale/2; // * fRadiusFactor
108
109 glRotatef (fHaloRotationAngle, 0., 1., 0.);
110 glTranslatef (0., fY, fX);
111 if (! pDock->container.bDirectionUp)
112 glScalef (1., -1., 1.);
113
114 glColor4f (myConfig.pHaloColor[0], myConfig.pHaloColor[1], myConfig.pHaloColor[2], pIcon->fAlpha * fRadiusFactor);
115 //cairo_dock_draw_texture (myData.iHaloTexture, pIcon->fWidth * pIcon->fScale*.25, 6); // taille qui rend pas trop mal.
116 _cairo_dock_enable_texture ();
117 _cairo_dock_set_blend_over ();
118
119 _cairo_dock_apply_texture_at_size (myData.iHaloTexture,
120 pIcon->fWidth * pIcon->fScale * .25,
121 6.); // taille qui rend pas trop mal.
122
123 _cairo_dock_disable_texture ();
124
125 glPopMatrix ();
126 }
127
cd_animation_render_spot_front(Icon * pIcon,CairoDock * pDock,gdouble fRadiusFactor)128 static void cd_animation_render_spot_front (Icon *pIcon, CairoDock *pDock, gdouble fRadiusFactor)
129 {
130 if (myData.iSpotFrontTexture == 0)
131 return ;
132 glPushMatrix ();
133 //\___________________On se place au-dessus du spot.
134 if (! pDock->container.bIsHorizontal)
135 glRotatef (90, 0., 0., 1.);
136 double fY = (- pIcon->fHeight + CD_ANIMATIONS_SPOT_HEIGHT/2 + pIcon->fHeight * fRadiusFactor) * pIcon->fScale/2; // CD_ANIMATIONS_SPOT_HEIGHT/2 * fRadiusFactor
137 if (pDock->container.bUseReflect)
138 fY -= MIN (pDock->iIconSize * myIconsParam.fReflectHeightRatio, CD_ANIMATIONS_SPOT_HEIGHT/2);
139 if (! pDock->container.bDirectionUp)
140 fY = -fY;
141 glTranslatef (0., fY, 0.);
142 if (! pDock->container.bDirectionUp)
143 glScalef (1., -1., 1.);
144
145 glColor4f (myConfig.pSpotColor[0], myConfig.pSpotColor[1], myConfig.pSpotColor[2], pIcon->fAlpha);
146 //cairo_dock_draw_texture (myData.iSpotFrontTexture, fRadiusFactor * pIcon->fWidth * pIcon->fScale, fRadiusFactor * pIcon->fHeight * pIcon->fScale);
147 _cairo_dock_enable_texture ();
148 _cairo_dock_set_blend_over ();
149
150 glBindTexture (GL_TEXTURE_2D, myData.iSpotFrontTexture);
151 _cairo_dock_apply_current_texture_portion_at_size_with_offset (0., 0.,
152 1., fRadiusFactor,
153 pIcon->fWidth * pIcon->fScale, pIcon->fHeight * pIcon->fScale * fRadiusFactor, // * fRadiusFactor
154 0., 0.);
155 _cairo_dock_disable_texture ();
156
157 glPopMatrix ();
158 }
159
160
render(Icon * pIcon,CairoDock * pDock,CDAnimationData * pData,cairo_t * pCairoContext)161 static void render (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, cairo_t *pCairoContext)
162 {
163 if (pCairoContext == NULL) // no cairo rendering (yet).
164 {
165 cd_animation_render_spot (pIcon, pDock, pData->fRadiusFactor);
166 if (pData->fHaloRotationAngle <= 90 || pData->fHaloRotationAngle >= 270)
167 cd_animation_render_halo (pIcon, pDock, pData->fRadiusFactor, pData->fHaloRotationAngle);
168
169 if (pData->pRaysSystem != NULL)
170 _cd_animations_render_rays (pIcon, pDock, pData, 1);
171
172 if (pDock->container.bIsHorizontal)
173 glTranslatef (0., pData->fIconOffsetY * (pDock->container.bDirectionUp ? 1 : -1), 0.);
174 else
175 glTranslatef (pData->fIconOffsetY * (pDock->container.bDirectionUp ? -1 : 1), 0., 0.);
176 }
177 }
178
post_render(Icon * pIcon,CairoDock * pDock,CDAnimationData * pData,cairo_t * pCairoContext)179 static void post_render (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, cairo_t *pCairoContext)
180 {
181 if (pCairoContext == NULL) // no cairo rendering (yet).
182 {
183 if (pDock->container.bIsHorizontal)
184 glTranslatef (0., - pData->fIconOffsetY * (pDock->container.bDirectionUp ? 1 : -1), 0.);
185 else
186 glTranslatef (- pData->fIconOffsetY * (pDock->container.bDirectionUp ? -1 : 1), 0., 0.);
187 if (pData->pRaysSystem != NULL)
188 _cd_animations_render_rays (pIcon, pDock, pData, 1);
189
190 cd_animation_render_spot_front (pIcon, pDock, pData->fRadiusFactor);
191 if (pData->fHaloRotationAngle > 90 && pData->fHaloRotationAngle < 270)
192 cd_animation_render_halo (pIcon, pDock, pData->fRadiusFactor, pData->fHaloRotationAngle);
193 }
194 }
195
update(Icon * pIcon,CairoDock * pDock,CDAnimationData * pData,double dt,gboolean bUseOpenGL,gboolean bRepeat)196 static gboolean update (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, double dt, gboolean bUseOpenGL, gboolean bRepeat)
197 {
198 if (!bUseOpenGL) // no cairo rendering (yet).
199 return FALSE;
200
201 gboolean bContinueAnimation = bRepeat;
202 if (pData->bGrowingSpot)
203 {
204 bContinueAnimation = TRUE;
205 pData->fRadiusFactor += 1./myConfig.iSpotDuration * dt;
206 if (pData->fRadiusFactor > 1)
207 {
208 pData->fRadiusFactor = 1.;
209 if (!bRepeat)
210 pData->bGrowingSpot = FALSE;
211 }
212 pData->fIconOffsetY += 1.*myIconsParam.iconTextDescription.iSize / myConfig.iSpotDuration * dt;
213 if (pData->fIconOffsetY > myIconsParam.iconTextDescription.iSize)
214 pData->fIconOffsetY = myIconsParam.iconTextDescription.iSize;
215 }
216 else
217 {
218 pData->fRadiusFactor -= 1./myConfig.iSpotDuration * dt;
219 if (pData->fRadiusFactor < 0)
220 pData->fRadiusFactor = 0.;
221 else
222 bContinueAnimation = TRUE;
223 pData->fIconOffsetY -= 1.*myIconsParam.iconTextDescription.iSize / myConfig.iSpotDuration * dt;
224 if (pData->fIconOffsetY < 0)
225 pData->fIconOffsetY = 0.;
226 else
227 bContinueAnimation = TRUE;
228 }
229 ///pData->fIconOffsetY *= cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
230 pIcon->fDeltaYReflection += 2 * pData->fIconOffsetY;
231
232 pData->fHaloRotationAngle += 360. / myConfig.iSpotDuration * dt;
233
234 if (pData->pRaysSystem != NULL)
235 {
236 gboolean bContinueSpot = cd_animations_update_rays_system (pData->pRaysSystem, bRepeat);
237 pData->pRaysSystem->fWidth = pIcon->fWidth * pIcon->fScale * pData->fRadiusFactor;
238 if (bContinueSpot)
239 bContinueAnimation = TRUE;
240 else
241 {
242 cairo_dock_free_particle_system (pData->pRaysSystem);
243 pData->pRaysSystem = NULL;
244 }
245 }
246
247 cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
248
249 if (pData->fHaloRotationAngle > 360) // un tour est passe.
250 {
251 pData->fHaloRotationAngle -= 360;
252 if (pData->iNumRound > 0)
253 {
254 pData->iNumRound --;
255 }
256 }
257
258 return bContinueAnimation;
259 }
260
261
cd_animations_register_spot(void)262 void cd_animations_register_spot (void)
263 {
264 CDAnimation *pAnimation = &myData.pAnimations[CD_ANIMATIONS_SPOT];
265 pAnimation->cName = "spot";
266 pAnimation->cDisplayedName = D_("Spot");
267 pAnimation->id = CD_ANIMATIONS_SPOT;
268 pAnimation->bDrawIcon = FALSE;
269 pAnimation->bDrawReflect = FALSE;
270 pAnimation->init = init;
271 pAnimation->update = update;
272 pAnimation->render = render;
273 pAnimation->post_render = post_render;
274 cd_animations_register_animation (pAnimation);
275 }
276