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/>.
24
#include "cairo-dock-log.h"
25
#include "cairo-dock-renderer-manager.h"
26
#include "cairo-dock-notifications.h"
27
#include "cairo-dock-draw-opengl.h"
28
#include "cairo-dock-animations.h"
29
#include "cairo-dock-surface-factory.h"
30
#include "cairo-dock-draw.h"
31
#include "cairo-dock-container.h"
32
#include "cairo-dock-icons.h"
33
#include "cairo-dock-load.h"
34
#include "cairo-dock-data-renderer.h"
36
extern gboolean g_bUseOpenGL;
37
extern CairoDock *g_pMainDock;
39
#define cairo_dock_set_data_renderer_on_icon(pIcon, pRenderer) (pIcon)->pDataRenderer = pRenderer
40
#define cairo_dock_get_icon_data_renderer(pIcon) (pIcon)->pDataRenderer
43
static CairoDockGLFont *s_pFont = NULL;
45
#define _init_data_renderer_font(...) s_pFont = cairo_dock_load_textured_font ("Monospace Bold 12", 0, 184) // on va jusqu'a Ćø
47
CairoDockGLFont *cairo_dock_get_default_data_renderer_font (void)
50
_init_data_renderer_font ();
54
void cairo_dock_unload_default_data_renderer_font (void)
56
cairo_dock_free_gl_font (s_pFont);
61
CairoDataRenderer *cairo_dock_new_data_renderer (const gchar *cRendererName)
63
CairoDataRendererNewFunc init = cairo_dock_get_data_renderer_entry_point (cRendererName);
64
g_return_val_if_fail (init != NULL, NULL);
66
if (g_pMainDock && s_pFont == NULL)
68
_init_data_renderer_font ();
74
void cairo_dock_init_data_renderer (CairoDataRenderer *pRenderer, cairo_t *pSourceContext, CairoContainer *pContainer, CairoDataRendererAttribute *pAttribute)
76
//\_______________ On alloue la structure des donnees.
77
pRenderer->data.iNbValues = MAX (1, pAttribute->iNbValues);
78
pRenderer->data.iMemorySize = MAX (2, pAttribute->iMemorySize); // au moins la derniere valeur et la nouvelle.
79
pRenderer->data.pValuesBuffer = g_new0 (gdouble, pRenderer->data.iNbValues * pRenderer->data.iMemorySize);
80
pRenderer->data.pTabValues = g_new (gdouble *, pRenderer->data.iMemorySize);
82
for (i = 0; i < pRenderer->data.iMemorySize; i ++)
84
pRenderer->data.pTabValues[i] = &pRenderer->data.pValuesBuffer[i*pRenderer->data.iNbValues];
86
pRenderer->data.iCurrentIndex = -1;
87
pRenderer->data.pMinMaxValues = g_new (gdouble, 2 * pRenderer->data.iNbValues);
88
if (pAttribute->pMinMaxValues != NULL)
90
memcpy (pRenderer->data.pMinMaxValues, pAttribute->pMinMaxValues, 2 * pRenderer->data.iNbValues * sizeof (gdouble));
94
if (pAttribute->bUpdateMinMax)
96
for (i = 0; i < pRenderer->data.iNbValues; i ++)
98
pRenderer->data.pMinMaxValues[2*i] = 1.e6;
99
pRenderer->data.pMinMaxValues[2*i+1] = -1.e6;
104
for (i = 0; i < pRenderer->data.iNbValues; i ++)
106
pRenderer->data.pMinMaxValues[2*i] = 0.;
107
pRenderer->data.pMinMaxValues[2*i+1] = 1.;
112
//\_______________ On charge les parametres generaux.
113
pRenderer->bUpdateMinMax = pAttribute->bUpdateMinMax;
114
pRenderer->bWriteValues = pAttribute->bWriteValues;
115
pRenderer->iLatencyTime = pAttribute->iLatencyTime;
116
pRenderer->iSmoothAnimationStep = 0;
117
pRenderer->format_value = pAttribute->format_value;
118
pRenderer->pFormatData = pAttribute->pFormatData;
119
pRenderer->cTitles = pAttribute->cTitles;
120
memcpy (pRenderer->fTextColor, pAttribute->fTextColor, sizeof (pRenderer->fTextColor));
121
pRenderer->cEmblems = pAttribute->cEmblems;
124
static void _cairo_dock_render_to_texture (CairoDataRenderer *pDataRenderer, Icon *pIcon, CairoContainer *pContainer)
126
if (! cairo_dock_begin_draw_icon (pIcon, pContainer))
129
pDataRenderer->interface.render_opengl (pDataRenderer);
131
cairo_dock_end_draw_icon (pIcon, pContainer);
133
static void _cairo_dock_render_to_context (CairoDataRenderer *pDataRenderer, Icon *pIcon, CairoContainer *pContainer, cairo_t *pCairoContext)
135
//\________________ On efface tout.
136
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
137
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
138
cairo_paint (pCairoContext);
139
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
141
//\________________ On dessine.
142
cairo_save (pCairoContext);
143
pDataRenderer->interface.render (pDataRenderer, pCairoContext);
144
cairo_restore (pCairoContext);
146
if (pContainer->bUseReflect)
148
cairo_dock_add_reflection_to_icon (pCairoContext, pIcon, pContainer);
151
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer))
152
cairo_dock_update_icon_texture (pIcon);
155
static gboolean cairo_dock_update_icon_data_renderer_notification (gpointer pUserData, Icon *pIcon, CairoContainer *pContainer, gboolean *bContinueAnimation)
157
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
158
if (pRenderer == NULL)
159
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
161
if (pRenderer->iSmoothAnimationStep > 0)
163
pRenderer->iSmoothAnimationStep --;
164
int iDeltaT = cairo_dock_get_slow_animation_delta_t (pContainer);
165
int iNbIterations = pRenderer->iLatencyTime / iDeltaT;
167
pRenderer->fLatency = (double) pRenderer->iSmoothAnimationStep / iNbIterations;
168
_cairo_dock_render_to_texture (pRenderer, pIcon, pContainer);
169
cairo_dock_redraw_icon (pIcon, pContainer);
171
if (pRenderer->iSmoothAnimationStep < iNbIterations)
172
*bContinueAnimation = TRUE;
175
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
178
void cairo_dock_add_new_data_renderer_on_icon (Icon *pIcon, CairoContainer *pContainer, cairo_t *pSourceContext, CairoDataRendererAttribute *pAttribute)
180
CairoDataRenderer *pRenderer = cairo_dock_new_data_renderer (pAttribute->cModelName);
182
cairo_dock_set_data_renderer_on_icon (pIcon, pRenderer);
183
if (pRenderer == NULL)
186
cairo_dock_init_data_renderer (pRenderer, pSourceContext, pContainer, pAttribute);
188
cairo_dock_get_icon_extent (pIcon, pContainer, &pRenderer->iWidth, &pRenderer->iHeight);
189
if (pAttribute->cEmblems != NULL)
190
pRenderer->pEmblems = g_new0 (CairoDataRendererEmblem, pAttribute->iNbValues);
191
pRenderer->pTextZones = g_new0 (CairoDataRendererTextZone, pAttribute->iNbValues);
193
pRenderer->interface.load (pRenderer, pSourceContext, pContainer, pAttribute);
195
gboolean bLoadTextures = FALSE;
196
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pRenderer->interface.render_opengl)
198
bLoadTextures = TRUE;
199
cairo_dock_register_notification_on_icon (pIcon, CAIRO_DOCK_UPDATE_ICON_SLOW,
200
(CairoDockNotificationFunc) cairo_dock_update_icon_data_renderer_notification,
201
CAIRO_DOCK_RUN_AFTER, NULL);
204
if (pRenderer->pEmblems != NULL)
206
CairoDataRendererEmblem *pEmblem;
207
cairo_surface_t *pSurface;
209
for (i = 0; i < pAttribute->iNbValues; i ++)
211
pEmblem = &pRenderer->pEmblems[i];
212
if (pEmblem->fWidth != 0 && pEmblem->fHeight != 0)
214
pSurface = cairo_dock_create_surface_from_image_simple (pAttribute->cEmblems[i],
216
pEmblem->fWidth * pRenderer->iWidth,
217
pEmblem->fHeight * pRenderer->iHeight);
220
pEmblem->iTexture = cairo_dock_create_texture_from_surface (pSurface);
221
cairo_surface_destroy (pSurface);
224
pEmblem->pSurface = pSurface;
233
void cairo_dock_render_new_data_on_icon (Icon *pIcon, CairoContainer *pContainer, cairo_t *pCairoContext, double *pNewValues)
235
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
236
g_return_if_fail (pRenderer != NULL);
238
//\___________________ On met a jour les valeurs du renderer.
239
CairoDataToRenderer *pData = cairo_data_renderer_get_data (pRenderer);
240
pData->iCurrentIndex ++;
241
if (pData->iCurrentIndex >= pData->iMemorySize)
242
pData->iCurrentIndex -= pData->iMemorySize;
245
for (i = 0; i < pData->iNbValues; i ++)
247
fNewValue = pNewValues[i];
248
if (pRenderer->bUpdateMinMax)
250
if (fNewValue < pData->pMinMaxValues[2*i])
251
pData->pMinMaxValues[2*i] = fNewValue;
252
if (fNewValue > pData->pMinMaxValues[2*i+1])
253
pData->pMinMaxValues[2*i+1] = fNewValue;
255
pData->pTabValues[pData->iCurrentIndex][i] = fNewValue;
258
//\___________________ On met a jour le dessin de l'icone.
259
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pRenderer->interface.render_opengl)
261
if (pRenderer->iLatencyTime > 0)
263
int iDeltaT = cairo_dock_get_slow_animation_delta_t (pContainer);
264
int iNbIterations = pRenderer->iLatencyTime / iDeltaT;
265
pRenderer->iSmoothAnimationStep = iNbIterations;
266
cairo_dock_launch_animation (pContainer);
270
pRenderer->fLatency = 0;
271
_cairo_dock_render_to_texture (pRenderer, pIcon, pContainer);
276
_cairo_dock_render_to_context (pRenderer, pIcon, pContainer, pCairoContext);
279
//\___________________ On met a jour l'info rapide si le renderer n'a pu ecrire les valeurs.
280
if (! pRenderer->bCanRenderValueAsText && pRenderer->bWriteValues) // on prend en charge l'ecriture des valeurs.
283
gchar *cBuffer = g_new0 (gchar, pData->iNbValues * (CAIRO_DOCK_DATA_FORMAT_MAX_LEN+1));
285
for (i = 0; i < pData->iNbValues; i ++)
287
fValue = cairo_data_renderer_get_normalized_current_value (pRenderer, i);
288
cairo_data_renderer_format_value_full (pRenderer, fValue, i, str);
290
if (i+1 < pData->iNbValues)
298
cairo_dock_set_quick_info (pCairoContext, pIcon, pContainer, cBuffer);
302
cairo_dock_redraw_icon (pIcon, pContainer);
307
void cairo_dock_free_data_renderer (CairoDataRenderer *pRenderer)
309
if (pRenderer == NULL)
312
g_free (pRenderer->data.pValuesBuffer);
313
g_free (pRenderer->data.pTabValues);
314
g_free (pRenderer->data.pMinMaxValues);
316
if (pRenderer->pEmblems != NULL)
318
CairoDataRendererEmblem *pEmblem;
320
for (i = 0; i < pRenderer->data.iNbValues; i ++)
322
pEmblem = &pRenderer->pEmblems[i];
323
if (pEmblem->pSurface != NULL)
324
cairo_surface_destroy (pEmblem->pSurface);
325
if (pEmblem->iTexture != 0)
326
_cairo_dock_delete_texture (pEmblem->iTexture);
328
g_free (pRenderer->pEmblems);
331
if (pRenderer->pTextZones != NULL)
332
g_free (pRenderer->pTextZones);
334
pRenderer->interface.free (pRenderer);
337
void cairo_dock_remove_data_renderer_on_icon (Icon *pIcon)
339
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
341
cairo_dock_remove_notification_func_on_icon (pIcon, CAIRO_DOCK_UPDATE_ICON_SLOW, (CairoDockNotificationFunc) cairo_dock_update_icon_data_renderer_notification, NULL);
343
cairo_dock_free_data_renderer (pRenderer);
344
cairo_dock_set_data_renderer_on_icon (pIcon, NULL);
349
void cairo_dock_reload_data_renderer_on_icon (Icon *pIcon, CairoContainer *pContainer, cairo_t *pSourceContext, CairoDataRendererAttribute *pAttribute)
351
//\_____________ On recupere les donnees de l'actuel renderer.
352
CairoDataToRenderer *pData = NULL;
353
CairoDataRenderer *pOldRenderer = cairo_dock_get_icon_data_renderer (pIcon);
354
g_return_if_fail (pOldRenderer != NULL || pAttribute != NULL);
356
if (pAttribute == NULL) // rien ne change dans les parametres du data-renderer, on se contente de le recharger a la taille de l'icone.
358
g_return_if_fail (pOldRenderer->interface.reload != NULL);
359
cairo_dock_get_icon_extent (pIcon, pContainer, &pOldRenderer->iWidth, &pOldRenderer->iHeight);
360
pOldRenderer->interface.reload (pOldRenderer, pSourceContext);
362
else // on recree le data-renderer avec les nouveaux attributs.
364
pAttribute->iNbValues = MAX (1, pAttribute->iNbValues);
365
//\_____________ On recupere les donnees courantes.
366
if (pOldRenderer && pOldRenderer->data.iNbValues == pAttribute->iNbValues)
368
pData = g_memdup (&pOldRenderer->data, sizeof (CairoDataToRenderer));
369
memset (&pOldRenderer->data, 0, sizeof (CairoDataToRenderer));
371
pAttribute->iMemorySize = MAX (2, pAttribute->iMemorySize);
372
if (pData->iMemorySize != pAttribute->iMemorySize) // on redimensionne le tampon des valeurs.
374
int iOldMemorySize = pData->iMemorySize;
375
pData->iMemorySize = pAttribute->iMemorySize;
376
pData->pValuesBuffer = g_realloc (pData->pValuesBuffer, pData->iMemorySize * pData->iNbValues * sizeof (gdouble));
377
if (pData->iMemorySize > iOldMemorySize)
379
memset (&pData->pValuesBuffer[iOldMemorySize * pData->iNbValues], 0, (pData->iMemorySize - iOldMemorySize) * pData->iNbValues * sizeof (gdouble));
382
g_free (pData->pTabValues);
383
pData->pTabValues = g_new (gdouble *, pData->iMemorySize);
385
for (i = 0; i < pData->iMemorySize; i ++)
387
pData->pTabValues[i] = &pData->pValuesBuffer[i*pData->iNbValues];
389
if (pData->iCurrentIndex >= pData->iMemorySize)
390
pData->iCurrentIndex = pData->iMemorySize - 1;
394
//\_____________ On supprime l'ancien.
395
cairo_dock_remove_data_renderer_on_icon (pIcon);
397
//\_____________ On en cree un nouveau.
398
cairo_dock_add_new_data_renderer_on_icon (pIcon, pContainer, pSourceContext, pAttribute);
400
//\_____________ On lui remet les valeurs actuelles.
401
CairoDataRenderer *pNewRenderer = cairo_dock_get_icon_data_renderer (pIcon);
402
if (pNewRenderer != NULL && pData != NULL)
403
memcpy (&pNewRenderer->data, pData, sizeof (CairoDataToRenderer));
409
void cairo_dock_resize_data_renderer_history (Icon *pIcon, int iNewMemorySize)
411
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
412
g_return_if_fail (pRenderer != NULL);
413
CairoDataToRenderer *pData = cairo_data_renderer_get_data (pRenderer);
415
iNewMemorySize = MAX (2, iNewMemorySize);
416
g_print ("iMemorySize : %d -> %d\n", pData->iMemorySize, iNewMemorySize);
417
if (pData->iMemorySize == iNewMemorySize)
420
int iOldMemorySize = pData->iMemorySize;
421
pData->iMemorySize = iNewMemorySize;
422
pData->pValuesBuffer = g_realloc (pData->pValuesBuffer, pData->iMemorySize * pData->iNbValues * sizeof (gdouble));
423
if (iNewMemorySize > iOldMemorySize)
425
memset (&pData->pValuesBuffer[iOldMemorySize * pData->iNbValues], 0, (iNewMemorySize - iOldMemorySize) * pData->iNbValues * sizeof (gdouble));
428
g_free (pData->pTabValues);
429
pData->pTabValues = g_new (gdouble *, pData->iMemorySize);
431
for (i = 0; i < pData->iMemorySize; i ++)
433
pData->pTabValues[i] = &pData->pValuesBuffer[i*pData->iNbValues];
435
if (pData->iCurrentIndex >= pData->iMemorySize)
436
pData->iCurrentIndex = pData->iMemorySize - 1;
439
void cairo_dock_refresh_data_renderer (Icon *pIcon, CairoContainer *pContainer, cairo_t *pSourceContex)
441
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
442
g_return_if_fail (pRenderer != NULL);
444
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pRenderer->interface.render_opengl)
446
_cairo_dock_render_to_texture (pRenderer, pIcon, pContainer);
450
_cairo_dock_render_to_context (pRenderer, pIcon, pContainer, pSourceContex);