Logo Search packages:      
Sourcecode: cairo-dock-plug-ins version File versions

applet-notifications.c

/**
* 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 <http://www.gnu.org/licenses/>.
*/

/******************************************************************************

This file is a part of the cairo-dock program, 
released under the terms of the GNU General Public License.

Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)

******************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "applet-notifications.h"
#include "star-tex.h"

static double fRadius = .33;
static double a = .2;


gboolean cd_show_mouse_render (gpointer pUserData, CairoContainer *pContainer, cairo_t *pCairoContext)
{
      CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
      if (pData == NULL)
            return CAIRO_DOCK_LET_PASS_NOTIFICATION;
      
      glPushMatrix();
      
      if (CAIRO_DOCK_IS_DESKLET (pContainer))
      {
            CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
            glTranslatef (-pDesklet->iWidth/2, -pDesklet->iHeight/2, -pDesklet->iHeight*(sqrt(3)/2));
      }
      if (pContainer->bIsHorizontal)
            glTranslatef (pContainer->iMouseX, pContainer->iHeight - pContainer->iMouseY, 0.);
      else
            glTranslatef (pContainer->iMouseY, pContainer->iWidth - pContainer->iMouseX, 0.);
      cairo_dock_render_particles (pData->pSystem);
      
      glPopMatrix();
      
      return CAIRO_DOCK_LET_PASS_NOTIFICATION;
}


#define _compute_area(area, pContainer, pData) do {\
if (pContainer->bIsHorizontal) {\
      area.x = pContainer->iMouseX - pData->pSystem->fWidth/2;\
      area.y = MAX (0, pContainer->iMouseY - pData->pSystem->fHeight);\
      area.width = pData->pSystem->fWidth;\
      area.height = pData->pSystem->fHeight*2; }\
else {\
      area.y = pContainer->iMouseX - pData->pSystem->fWidth/2;\
      area.x = MAX (0, pContainer->iMouseY - pData->pSystem->fHeight);\
      area.height = pData->pSystem->fWidth;\
      area.width = pData->pSystem->fHeight*2; } } while (0)
gboolean cd_show_mouse_update_container (gpointer pUserData, CairoContainer *pContainer, gboolean *bContinueAnimation)
{
      CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
      if (pData == NULL)
            return CAIRO_DOCK_LET_PASS_NOTIFICATION;
      
      GdkRectangle area;
      if (! pContainer->bInside)
      {
            pData->fAlpha -= .05;
            if (pData->fAlpha <= 0)
            {
                  _compute_area (area, pContainer, pData);
                  cairo_dock_redraw_container_area (pContainer, &area);
                  
                  cairo_dock_free_particle_system (pData->pSystem);
                  g_free (pData);
                  CD_APPLET_SET_MY_CONTAINER_DATA (pContainer, NULL);
                  
                  return CAIRO_DOCK_LET_PASS_NOTIFICATION;
            }
      }
      else if (pData->fAlpha != 1)
            pData->fAlpha = MIN (1., pData->fAlpha + .05);
      
      pData->fRotationAngle += 2*G_PI * myConfig.fRotationSpeed * mySystem.iGLAnimationDeltaT / 1000.;
      
      cd_show_mouse_update_sources (pData);
      pData->pSystem->fWidth = 2 * MIN (96, pContainer->iHeight);
      pData->pSystem->fHeight =  MIN (96, pContainer->iHeight);
      cd_show_mouse_update_particle_system (pData->pSystem, pData);
      
      _compute_area (area, pContainer, pData);
      cairo_dock_redraw_container_area (pContainer, &area);
      
      *bContinueAnimation = TRUE;
      return CAIRO_DOCK_LET_PASS_NOTIFICATION;
}


gboolean cd_show_mouse_enter_container (gpointer pUserData, CairoContainer *pContainer, gboolean *bStartAnimation)
{
      if (! CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer))
            return CAIRO_DOCK_LET_PASS_NOTIFICATION;
      
      CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
      if (pData == NULL)
      {
            pData = g_new0 (CDShowMouseData, 1);
            pData->fAlpha = 1.;
            
            double dt = mySystem.iGLAnimationDeltaT;
            pData->pSourceCoords = cd_show_mouse_init_sources ();
            pData->pSystem = cd_show_mouse_init_system (pContainer, dt, pData->pSourceCoords);
            
            CD_APPLET_SET_MY_CONTAINER_DATA (pContainer, pData);
      }
      
      
      *bStartAnimation = TRUE;
      return CAIRO_DOCK_LET_PASS_NOTIFICATION;
}



gdouble *cd_show_mouse_init_sources (void)
{
      double *pSourceCoords = g_new (double, myConfig.iNbSources * 2);
      double fTheta;
      int i;
      for (i = 0; i < myConfig.iNbSources; i ++)
      {
            fTheta = 2*G_PI * i / myConfig.iNbSources;
            pSourceCoords[2*i] = fRadius * cos (fTheta);
            pSourceCoords[2*i+1] = fRadius * sin (fTheta);
      }
      return pSourceCoords;
}

CairoParticleSystem *cd_show_mouse_init_system (CairoContainer *pContainer, double dt, double *pSourceCoords)
{
      if (myData.iTexture == 0)
            myData.iTexture = cairo_dock_load_texture_from_raw_data (starTex, 32, 32);  /// 32 = sqrt (4096/4)
      double fHeight = pContainer->iHeight;  // iMaxDockHeight ?
      CairoParticleSystem *pParticleSystem = cairo_dock_create_particle_system (myConfig.iNbParticles * myConfig.iNbSources, myData.iTexture, 2*fHeight, fHeight);
      pParticleSystem->dt = dt;
      
      int iNumSource;
      double fBlend;
      double r = myConfig.iParticleSize / (1 + a);
      double sigma = myConfig.fScattering;
      CairoParticle *p;
      int i;
      for (i = 0; i < pParticleSystem->iNbParticles; i ++)
      {
            p = &(pParticleSystem->pParticles[i]);
            
            iNumSource = i / myConfig.iNbParticles;
            
            p->x = pSourceCoords[2*iNumSource];
            p->y = pSourceCoords[2*iNumSource+1];
            p->z = 0;
            p->fWidth = r * (a + g_random_double ());
            p->fHeight = p->fWidth;
            
            p->vx = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
            p->vy = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
            p->iInitialLife = ceil (myConfig.iParticleLifeTime / dt);
            p->iLife = g_random_int_range (1, p->iInitialLife+1);
            
            if (myConfig.bMysticalFire)
            {
                  p->color[0] = g_random_double ();
                  p->color[1] = g_random_double ();
                  p->color[2] = g_random_double ();
            }
            else
            {
                  fBlend = g_random_double ();
                  p->color[0] = fBlend * myConfig.pColor1[0] + (1 - fBlend) * myConfig.pColor2[0];
                  p->color[1] = fBlend * myConfig.pColor1[1] + (1 - fBlend) * myConfig.pColor2[1];
                  p->color[2] = fBlend * myConfig.pColor1[2] + (1 - fBlend) * myConfig.pColor2[2];
            }
            p->color[3] = 1.;
            
            p->fSizeFactor = 1.;
            p->fResizeSpeed = .5 / myConfig.iParticleLifeTime * dt;  // zoom 1.5 a la fin.
      }
      
      return pParticleSystem;
      
}

void cd_show_mouse_update_sources (CDShowMouseData *pData)
{
      double *pSourceCoords = pData->pSourceCoords;
      double fTheta;
      int i;
      for (i = 0; i < myConfig.iNbSources; i ++)
      {
            fTheta = 2*G_PI * i / myConfig.iNbSources + pData->fRotationAngle;
            pSourceCoords[2*i] = fRadius * cos (fTheta);
            pSourceCoords[2*i+1] = fRadius * sin (fTheta);
      }
}


void cd_show_mouse_update_particle_system (CairoParticleSystem *pParticleSystem, CDShowMouseData *pData)
{
      double *pSourceCoords = pData->pSourceCoords;
      CairoParticle *p;
      double dt = pParticleSystem->dt;
      int i;
      double sigma = myConfig.fScattering;
      for (i = 0; i < pParticleSystem->iNbParticles; i ++)
      {
            p = &(pParticleSystem->pParticles[i]);
            
            p->x += p->vx;
            p->y += p->vy;
            p->color[3] = pData->fAlpha * p->iLife / p->iInitialLife;
            p->fSizeFactor += p->fResizeSpeed;
            if (p->iLife > 0)
            {
                  p->iLife --;
                  if (p->iLife == 0)
                  {
                        int iNumSource = i / myConfig.iNbParticles;
                        p->x = pSourceCoords[2*iNumSource];
                        p->y = pSourceCoords[2*iNumSource+1];
                        
                        p->vx = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
                        p->vy = sigma * (2 * g_random_double () - 1) * dt / myConfig.iParticleLifeTime;
                        
                        p->color[3] = pData->fAlpha;
                        p->fSizeFactor = 1.;
                        
                        p->iLife = g_random_int_range (1, p->iInitialLife+1);
                  }
            }
      }
}

gboolean cd_show_mouse_free_data (gpointer pUserData, CairoContainer *pContainer)
{
      cd_message ("");
      CDShowMouseData *pData = CD_APPLET_GET_MY_CONTAINER_DATA (pContainer);
      if (pData == NULL)
            return CAIRO_DOCK_LET_PASS_NOTIFICATION;
      
      cairo_dock_free_particle_system (pData->pSystem);
      g_free (pData);
      CD_APPLET_SET_MY_CONTAINER_DATA (pContainer, NULL);
      return CAIRO_DOCK_LET_PASS_NOTIFICATION;
}

Generated by  Doxygen 1.6.0   Back to index