/**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include "applet-struct.h"
#include "applet-rays.h"
#include "applet-notifications.h"
#include "applet-spot.h"
static void init (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, double dt, gboolean bUseOpenGL)
{
if (myData.iSpotTexture == 0)
myData.iSpotTexture = cd_animation_load_spot_texture ();
if (myData.iHaloTexture == 0)
myData.iHaloTexture = cd_animation_load_halo_texture ();
if (myData.iSpotFrontTexture == 0 && myConfig.cSpotFrontImage != NULL)
myData.iSpotFrontTexture = cd_animation_load_spot_front_texture ();
if (myData.iRaysTexture == 0)
myData.iRaysTexture = cd_animations_load_rays_texture ();
if (pData->pRaysSystem == NULL && myConfig.iNbRaysParticles != 0)
pData->pRaysSystem = cd_animations_init_rays (pIcon, pDock, dt);
pData->fRadiusFactor = .001;
pData->fHaloRotationAngle = 0;
pData->bGrowingSpot = TRUE;
}
static void _cd_animations_render_rays (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, int iDepth)
{
glPushMatrix ();
if (pDock->container.bIsHorizontal)
glTranslatef (0., - pIcon->fHeight * pIcon->fScale/2, 0.);
else
glTranslatef (- pIcon->fHeight * pIcon->fScale/2, 0., 0.);
if (! pDock->container.bIsHorizontal)
glRotatef (-90, 0., 0., 1.);
if (pData->pRaysSystem != NULL)
{
cairo_dock_render_particles_full (pData->pRaysSystem, iDepth);
}
glPopMatrix ();
}
static void cd_animation_render_spot (Icon *pIcon, CairoDock *pDock, gdouble fRadiusFactor)
{
glPushMatrix ();
//\___________________On se place au bas de l'icone.
if (! pDock->container.bIsHorizontal)
glRotatef (90, 0., 0., 1.);
double fY = (- pIcon->fHeight + CD_ANIMATIONS_SPOT_HEIGHT) * pIcon->fScale/2; // * fRadiusFactor
if (pDock->container.bUseReflect)
fY -= MIN (pDock->iIconSize * myIconsParam.fReflectHeightRatio, CD_ANIMATIONS_SPOT_HEIGHT/2);
if (! pDock->container.bDirectionUp)
fY = -fY;
glTranslatef (0., fY, 0.);
if (! pDock->container.bDirectionUp)
glScalef (1., -1., 1.);
glColor4f (myConfig.pSpotColor[0], myConfig.pSpotColor[1], myConfig.pSpotColor[2], .9 * fRadiusFactor * pIcon->fAlpha);
//cairo_dock_draw_texture (myData.iSpotTexture, fRadiusFactor * pIcon->fWidth * pIcon->fScale, fRadiusFactor * CD_ANIMATIONS_SPOT_HEIGHT * pIcon->fScale);
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_alpha ();
_cairo_dock_apply_texture_at_size (myData.iSpotTexture,
pIcon->fWidth * pIcon->fScale,
CD_ANIMATIONS_SPOT_HEIGHT * pIcon->fScale);
_cairo_dock_disable_texture ();
glPopMatrix ();
}
static void cd_animation_render_halo (Icon *pIcon, CairoDock *pDock, gdouble fRadiusFactor, int fHaloRotationAngle)
{
glPushMatrix ();
//\___________________On se place au bas de l'icone.
if (! pDock->container.bIsHorizontal)
glRotatef (90, 0., 0., 1.);
double fY = CD_ANIMATIONS_SPOT_HEIGHT * (1 + cos (G_PI * fHaloRotationAngle / 180.))/2 - pIcon->fHeight * pIcon->fScale/2; // * fRadiusFactor
if (pDock->container.bUseReflect)
fY -= MIN (pDock->iIconSize * myIconsParam.fReflectHeightRatio, CD_ANIMATIONS_SPOT_HEIGHT/2);
if (! pDock->container.bDirectionUp)
fY = -fY;
double fX = .9 * pIcon->fWidth * pIcon->fScale/2; // * fRadiusFactor
glRotatef (fHaloRotationAngle, 0., 1., 0.);
glTranslatef (0., fY, fX);
if (! pDock->container.bDirectionUp)
glScalef (1., -1., 1.);
glColor4f (myConfig.pHaloColor[0], myConfig.pHaloColor[1], myConfig.pHaloColor[2], pIcon->fAlpha * fRadiusFactor);
//cairo_dock_draw_texture (myData.iHaloTexture, pIcon->fWidth * pIcon->fScale*.25, 6); // taille qui rend pas trop mal.
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_over ();
_cairo_dock_apply_texture_at_size (myData.iHaloTexture,
pIcon->fWidth * pIcon->fScale * .25,
6.); // taille qui rend pas trop mal.
_cairo_dock_disable_texture ();
glPopMatrix ();
}
static void cd_animation_render_spot_front (Icon *pIcon, CairoDock *pDock, gdouble fRadiusFactor)
{
if (myData.iSpotFrontTexture == 0)
return ;
glPushMatrix ();
//\___________________On se place au-dessus du spot.
if (! pDock->container.bIsHorizontal)
glRotatef (90, 0., 0., 1.);
double fY = (- pIcon->fHeight + CD_ANIMATIONS_SPOT_HEIGHT/2 + pIcon->fHeight * fRadiusFactor) * pIcon->fScale/2; // CD_ANIMATIONS_SPOT_HEIGHT/2 * fRadiusFactor
if (pDock->container.bUseReflect)
fY -= MIN (pDock->iIconSize * myIconsParam.fReflectHeightRatio, CD_ANIMATIONS_SPOT_HEIGHT/2);
if (! pDock->container.bDirectionUp)
fY = -fY;
glTranslatef (0., fY, 0.);
if (! pDock->container.bDirectionUp)
glScalef (1., -1., 1.);
glColor4f (myConfig.pSpotColor[0], myConfig.pSpotColor[1], myConfig.pSpotColor[2], pIcon->fAlpha);
//cairo_dock_draw_texture (myData.iSpotFrontTexture, fRadiusFactor * pIcon->fWidth * pIcon->fScale, fRadiusFactor * pIcon->fHeight * pIcon->fScale);
_cairo_dock_enable_texture ();
_cairo_dock_set_blend_over ();
glBindTexture (GL_TEXTURE_2D, myData.iSpotFrontTexture);
_cairo_dock_apply_current_texture_portion_at_size_with_offset (0., 0.,
1., fRadiusFactor,
pIcon->fWidth * pIcon->fScale, pIcon->fHeight * pIcon->fScale * fRadiusFactor, // * fRadiusFactor
0., 0.);
_cairo_dock_disable_texture ();
glPopMatrix ();
}
static void render (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, cairo_t *pCairoContext)
{
if (pCairoContext == NULL) // no cairo rendering (yet).
{
cd_animation_render_spot (pIcon, pDock, pData->fRadiusFactor);
if (pData->fHaloRotationAngle <= 90 || pData->fHaloRotationAngle >= 270)
cd_animation_render_halo (pIcon, pDock, pData->fRadiusFactor, pData->fHaloRotationAngle);
if (pData->pRaysSystem != NULL)
_cd_animations_render_rays (pIcon, pDock, pData, 1);
if (pDock->container.bIsHorizontal)
glTranslatef (0., pData->fIconOffsetY * (pDock->container.bDirectionUp ? 1 : -1), 0.);
else
glTranslatef (pData->fIconOffsetY * (pDock->container.bDirectionUp ? -1 : 1), 0., 0.);
}
}
static void post_render (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, cairo_t *pCairoContext)
{
if (pCairoContext == NULL) // no cairo rendering (yet).
{
if (pDock->container.bIsHorizontal)
glTranslatef (0., - pData->fIconOffsetY * (pDock->container.bDirectionUp ? 1 : -1), 0.);
else
glTranslatef (- pData->fIconOffsetY * (pDock->container.bDirectionUp ? -1 : 1), 0., 0.);
if (pData->pRaysSystem != NULL)
_cd_animations_render_rays (pIcon, pDock, pData, 1);
cd_animation_render_spot_front (pIcon, pDock, pData->fRadiusFactor);
if (pData->fHaloRotationAngle > 90 && pData->fHaloRotationAngle < 270)
cd_animation_render_halo (pIcon, pDock, pData->fRadiusFactor, pData->fHaloRotationAngle);
}
}
static gboolean update (Icon *pIcon, CairoDock *pDock, CDAnimationData *pData, double dt, gboolean bUseOpenGL, gboolean bRepeat)
{
if (!bUseOpenGL) // no cairo rendering (yet).
return FALSE;
gboolean bContinueAnimation = bRepeat;
if (pData->bGrowingSpot)
{
bContinueAnimation = TRUE;
pData->fRadiusFactor += 1./myConfig.iSpotDuration * dt;
if (pData->fRadiusFactor > 1)
{
pData->fRadiusFactor = 1.;
if (!bRepeat)
pData->bGrowingSpot = FALSE;
}
pData->fIconOffsetY += 1.*myIconsParam.iconTextDescription.iSize / myConfig.iSpotDuration * dt;
if (pData->fIconOffsetY > myIconsParam.iconTextDescription.iSize)
pData->fIconOffsetY = myIconsParam.iconTextDescription.iSize;
}
else
{
pData->fRadiusFactor -= 1./myConfig.iSpotDuration * dt;
if (pData->fRadiusFactor < 0)
pData->fRadiusFactor = 0.;
else
bContinueAnimation = TRUE;
pData->fIconOffsetY -= 1.*myIconsParam.iconTextDescription.iSize / myConfig.iSpotDuration * dt;
if (pData->fIconOffsetY < 0)
pData->fIconOffsetY = 0.;
else
bContinueAnimation = TRUE;
}
///pData->fIconOffsetY *= cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
pIcon->fDeltaYReflection += 2 * pData->fIconOffsetY;
pData->fHaloRotationAngle += 360. / myConfig.iSpotDuration * dt;
if (pData->pRaysSystem != NULL)
{
gboolean bContinueSpot = cd_animations_update_rays_system (pData->pRaysSystem, bRepeat);
pData->pRaysSystem->fWidth = pIcon->fWidth * pIcon->fScale * pData->fRadiusFactor;
if (bContinueSpot)
bContinueAnimation = TRUE;
else
{
cairo_dock_free_particle_system (pData->pRaysSystem);
pData->pRaysSystem = NULL;
}
}
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
if (pData->fHaloRotationAngle > 360) // un tour est passe.
{
pData->fHaloRotationAngle -= 360;
if (pData->iNumRound > 0)
{
pData->iNumRound --;
}
}
return bContinueAnimation;
}
void cd_animations_register_spot (void)
{
CDAnimation *pAnimation = &myData.pAnimations[CD_ANIMATIONS_SPOT];
pAnimation->cName = "spot";
pAnimation->cDisplayedName = D_("Spot");
pAnimation->id = CD_ANIMATIONS_SPOT;
pAnimation->bDrawIcon = FALSE;
pAnimation->bDrawReflect = FALSE;
pAnimation->init = init;
pAnimation->update = update;
pAnimation->render = render;
pAnimation->post_render = post_render;
cd_animations_register_animation (pAnimation);
}