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