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 <string.h>
21 #include <stdlib.h>
22 #include <math.h>
23
24 #include "cairo-dock-log.h"
25 #include "cairo-dock-surface-factory.h"
26 #include "cairo-dock-dock-factory.h"
27 #include "cairo-dock-backends-manager.h"
28 #include "cairo-dock-draw-opengl.h"
29 #include "cairo-dock-draw.h"
30 #include "cairo-dock-container.h"
31 #include "cairo-dock-icon-manager.h" // myIconsParam.quickInfoTextDescription
32 #include "cairo-dock-graph.h"
33
34 typedef struct _Graph {
35 CairoDataRenderer dataRenderer;
36 CairoDockTypeGraph iType;
37 gdouble *fHighColor; // iNbValues triplets (r,v,b).
38 gdouble *fLowColor; // idem.
39 cairo_pattern_t **pGradationPatterns; // iNbValues patterns.
40 gdouble fBackGroundColor[4];
41 cairo_surface_t *pBackgroundSurface;
42 GLuint iBackgroundTexture;
43 gint iMargin;
44 gboolean bMixGraphs;
45 } Graph;
46
47
48 extern gboolean g_bUseOpenGL;
49
50
render(Graph * pGraph,cairo_t * pCairoContext)51 static void render (Graph *pGraph, cairo_t *pCairoContext)
52 {
53 g_return_if_fail (pGraph != NULL);
54 g_return_if_fail (pCairoContext != NULL && cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS);
55
56 CairoDataRenderer *pRenderer = CAIRO_DATA_RENDERER (pGraph);
57 CairoDataToRenderer *pData = cairo_data_renderer_get_data (pRenderer);
58 int iNbValues = cairo_data_renderer_get_nb_values (pRenderer);
59
60 if (pGraph->pBackgroundSurface != NULL)
61 {
62 cairo_set_source_surface (pCairoContext, pGraph->pBackgroundSurface, 0., 0.);
63 cairo_paint (pCairoContext);
64 }
65
66 g_return_if_fail (pRenderer->iRank != 0); // workaround: FIXME
67 int iNbDrawings = iNbValues / pRenderer->iRank;
68 if (iNbDrawings == 0)
69 return;
70
71 int iMargin = pGraph->iMargin;
72 int iWidth = pRenderer->iWidth - 2*iMargin;
73 double fHeight = pRenderer->iHeight - 2*iMargin;
74 fHeight /= iNbDrawings;
75
76 double fValue;
77 cairo_pattern_t *pGradationPattern;
78 int t, n = MIN (pData->iMemorySize, iWidth); // for iteration over the memorized values.
79 int i, iCurrentGraph, iGraphTop, iGraphBottom, iHeight = 0;
80 for (i = 0; i < iNbValues; i ++)
81 {
82 cairo_save (pCairoContext);
83 if (pGraph->iType == CAIRO_DOCK_GRAPH_CIRCLE || pGraph->iType == CAIRO_DOCK_GRAPH_CIRCLE_PLAIN)
84 {
85 if (! pGraph->bMixGraphs)
86 cairo_translate (pCairoContext,
87 0.,
88 i * fHeight);
89 }
90 else
91 {
92 iCurrentGraph = pGraph->bMixGraphs ? 0 : i;
93 iGraphTop = floor (iCurrentGraph * fHeight) + iMargin; // Position of previous graph axis (if any).
94 iGraphBottom = floor ((iCurrentGraph + 1) * fHeight) + iMargin; // Position of current graph axis
95 iHeight = iGraphBottom - iGraphTop; // Current graph height.
96 cairo_translate (pCairoContext,
97 iMargin,
98 iGraphTop);
99 }
100 pGradationPattern = pGraph->pGradationPatterns[i];
101 if (pGradationPattern != NULL)
102 cairo_set_source (pCairoContext, pGradationPattern);
103 else
104 cairo_set_source_rgb (pCairoContext,
105 pGraph->fLowColor[3*i+0],
106 pGraph->fLowColor[3*i+1],
107 pGraph->fLowColor[3*i+2]);
108
109 switch (pGraph->iType)
110 {
111 case CAIRO_DOCK_GRAPH_LINE:
112 case CAIRO_DOCK_GRAPH_PLAIN:
113 default :
114 cairo_set_line_width (pCairoContext, 1);
115 cairo_set_line_join (pCairoContext, CAIRO_LINE_JOIN_ROUND);
116 fValue = cairo_data_renderer_get_normalized_current_value (pRenderer, i);
117 if (fValue <= CAIRO_DATA_RENDERER_UNDEF_VALUE+1) // undef value -> let's draw 0
118 fValue = 0;
119 cairo_move_to (pCairoContext,
120 iWidth - .5,
121 (1 - fValue) * (iHeight - 1) + .5) ; // - .5 to align line draw on pixel and + 1 px down because size is reduced
122 for (t = 1; t < n; t ++)
123 {
124 fValue = cairo_data_renderer_get_normalized_value (pRenderer, i, -t);
125 if (fValue <= CAIRO_DATA_RENDERER_UNDEF_VALUE+1) // undef value -> let's draw 0
126 fValue = 0;
127 cairo_line_to (pCairoContext,
128 iWidth - t - .5,
129 (1 - fValue) * (iHeight - 1) + .5); // - .5 to align line draw on pixel and + 1 px down because size is reduced
130 }
131 if (pGraph->iType == CAIRO_DOCK_GRAPH_PLAIN)
132 {
133 cairo_line_to (pCairoContext,
134 .5, // - .5 to align line draw on pixel and + 1 to align with last value position
135 iHeight - .5); // - .5 to align next line draw on pixel
136 cairo_rel_line_to (pCairoContext,
137 iWidth - 1,
138 0.);
139 cairo_close_path (pCairoContext);
140 cairo_fill_preserve (pCairoContext);
141 }
142 cairo_stroke (pCairoContext);
143 break;
144
145 case CAIRO_DOCK_GRAPH_BAR:
146 {
147 cairo_set_line_width (pCairoContext, 1);
148 for (t = 0; t < n; t ++)
149 {
150 fValue = cairo_data_renderer_get_normalized_value (pRenderer, i, -t);
151 if (fValue > CAIRO_DATA_RENDERER_UNDEF_VALUE+1) // undef value -> no draw
152 {
153 cairo_move_to (pCairoContext,
154 iWidth - t - .5, // - .5 to align line draw on pixel
155 iHeight);
156 cairo_rel_line_to (pCairoContext,
157 0.,
158 - fValue * iHeight);
159 cairo_stroke (pCairoContext);
160 }
161 }
162 }
163 break;
164
165 case CAIRO_DOCK_GRAPH_CIRCLE:
166 case CAIRO_DOCK_GRAPH_CIRCLE_PLAIN:
167 cairo_set_line_width (pCairoContext, 1);
168 cairo_set_line_join (pCairoContext, CAIRO_LINE_JOIN_ROUND);
169 fValue = cairo_data_renderer_get_normalized_current_value (pRenderer, i);
170 if (fValue <= CAIRO_DATA_RENDERER_UNDEF_VALUE+1) // undef value -> let's draw 0
171 fValue = 0;
172 double angle, radius = MIN (iWidth, fHeight)/2;
173 angle = -2*G_PI*(-.5/pData->iMemorySize);
174 cairo_move_to (pCairoContext,
175 iMargin + iWidth/2 + radius * (fValue * cos (angle)),
176 iMargin + fHeight/2 + radius * (fValue * sin (angle)));
177 angle = -2*G_PI*(.5/pData->iMemorySize);
178 cairo_line_to (pCairoContext,
179 iMargin + iWidth/2 + radius * (fValue * cos (angle)),
180 iMargin + fHeight/2 + radius * (fValue * sin (angle)));
181 for (t = 1; t < n; t ++)
182 {
183 fValue = cairo_data_renderer_get_normalized_value (pRenderer, i, -t);
184 if (fValue <= CAIRO_DATA_RENDERER_UNDEF_VALUE+1) // undef value -> let's draw 0
185 fValue = 0;
186 angle = -2*G_PI*((t-.5)/n);
187 cairo_line_to (pCairoContext,
188 iMargin + iWidth/2 + radius * (fValue * cos (angle)),
189 iMargin + fHeight/2 + radius * (fValue * sin (angle)));
190 angle = -2*G_PI*((t+.5)/n);
191 cairo_line_to (pCairoContext,
192 iMargin + iWidth/2 + radius * (fValue * cos (angle)),
193 iMargin + fHeight/2 + radius * (fValue * sin (angle)));
194 }
195 if (pGraph->iType == CAIRO_DOCK_GRAPH_CIRCLE_PLAIN)
196 {
197 cairo_close_path (pCairoContext);
198 cairo_fill_preserve (pCairoContext);
199 }
200 cairo_stroke (pCairoContext);
201 break;
202 }
203 cairo_restore (pCairoContext);
204
205 cairo_dock_render_overlays_to_context (pRenderer, i, pCairoContext);
206 }
207 }
208 /* not used
209 static void render_opengl (Graph *pGraph)
210 {
211 g_return_if_fail (pGraph != NULL);
212
213 CairoDataRenderer *pRenderer = CAIRO_DATA_RENDERER (pGraph);
214
215 if (pGraph->iBackgroundTexture != 0)
216 {
217 _cairo_dock_enable_texture ();
218 _cairo_dock_set_blend_pbuffer (); // ceci reste un mystere...
219 _cairo_dock_set_alpha (1.);
220 _cairo_dock_apply_texture_at_size_with_alpha (pGraph->iBackgroundTexture, pRenderer->iWidth, pRenderer->iHeight, 1.);
221 _cairo_dock_disable_texture ();
222 }
223
224 /// to be continued ...
225 }
226 */
227
_cairo_dock_create_graph_background(double fWidth,double fHeight,int iMargin,gdouble * pBackGroundColor,CairoDockTypeGraph iType,int iNbDrawings)228 static inline cairo_surface_t *_cairo_dock_create_graph_background (double fWidth, double fHeight, int iMargin, gdouble *pBackGroundColor, CairoDockTypeGraph iType, int iNbDrawings)
229 {
230 // on cree la surface.
231 cairo_surface_t *pBackgroundSurface = cairo_dock_create_blank_surface (
232 fWidth,
233 fHeight);
234 cairo_t *pCairoContext = cairo_create (pBackgroundSurface);
235
236 // on trace le fond : un rectangle au coin arrondi.
237 cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
238 cairo_set_source_rgba (pCairoContext,
239 pBackGroundColor[0],
240 pBackGroundColor[1],
241 pBackGroundColor[2],
242 pBackGroundColor[3]);
243
244 // The first argument is the radius ratio factor to change how corners are displayed.
245 // It can be adjusted between 1 (half radius space unused) to 2 (no radius space reserved).
246 double fRadius = floor (1.5 * iMargin / (1. - sqrt(2)/2));
247 cairo_set_line_width (pCairoContext, fRadius);
248 cairo_set_line_join (pCairoContext, CAIRO_LINE_JOIN_ROUND);
249 cairo_move_to (pCairoContext, .5*fRadius, .5*fRadius);
250 cairo_rel_line_to (pCairoContext, fWidth - (fRadius), 0);
251 cairo_rel_line_to (pCairoContext, 0, fHeight - (fRadius));
252 cairo_rel_line_to (pCairoContext, -(fWidth - (fRadius)) ,0);
253 cairo_close_path (pCairoContext);
254 cairo_stroke (pCairoContext); // on trace d'abord les contours arrondis.
255
256 cairo_rectangle (pCairoContext, fRadius, fRadius, (fWidth - 2*fRadius), (fHeight - 2*fRadius));
257 cairo_fill (pCairoContext); // puis on rempli l'interieur.
258
259 // on trace les axes.
260 cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
261 gldi_color_set_cairo_rgb (pCairoContext,
262 &myIconsParam.quickInfoTextDescription.fBackgroundColor); // meme couleur que le fond des info-rapides, mais opaque.
263 cairo_set_line_width (pCairoContext, 1.);
264 if (iType == CAIRO_DOCK_GRAPH_CIRCLE || iType == CAIRO_DOCK_GRAPH_CIRCLE_PLAIN)
265 {
266 double r = .5 * MIN (fWidth - 2*iMargin, (fHeight - 2*iMargin) / iNbDrawings);
267 int i;
268 for (i = 0; i < iNbDrawings; i ++)
269 {
270 cairo_arc (pCairoContext,
271 fWidth/2,
272 iMargin + r * (2 * i + 1),
273 r,
274 0.,
275 360.);
276 cairo_move_to (pCairoContext, fWidth/2, iMargin + r * (2 * i + 1));
277 cairo_rel_line_to (pCairoContext, r, 0.);
278 cairo_stroke (pCairoContext);
279 }
280 }
281 else
282 {
283 // cairo_move_to (pCairoContext, iMargin-.5, iMargin-.5);
284 // cairo_rel_line_to (pCairoContext, 0., fHeight - 2*iMargin);
285 // cairo_stroke (pCairoContext);
286 int i;
287 for (i = 0; i < iNbDrawings; i ++)
288 {
289 cairo_move_to (pCairoContext,
290 iMargin,
291 floor ((fHeight - 2 * iMargin) * (i + 1) / iNbDrawings) + iMargin - .5);
292 cairo_rel_line_to (pCairoContext, fWidth - 2*iMargin, 0.);
293 cairo_stroke (pCairoContext);
294 }
295 }
296
297 cairo_destroy (pCairoContext);
298 return pBackgroundSurface;
299 }
_cairo_dock_create_graph_pattern(Graph * pGraph,gdouble * fLowColor,gdouble * fHighColor)300 static cairo_pattern_t *_cairo_dock_create_graph_pattern (Graph *pGraph, gdouble *fLowColor, gdouble *fHighColor)
301 {
302 cairo_pattern_t *pGradationPattern = NULL;
303 if (fLowColor[0] != fHighColor[0] || fLowColor[1] != fHighColor[1] || fLowColor[2] != fHighColor[2]) // un degrade existe.
304 {
305 int iMargin = pGraph->iMargin;
306 double fWidth = pGraph->dataRenderer.iWidth - 2*iMargin;
307 double fHeight = pGraph->dataRenderer.iHeight - 2*iMargin;
308 double fHeightPerValue = fHeight / (pGraph->dataRenderer.data.iNbValues / pGraph->dataRenderer.iRank);
309
310 if (pGraph->iType == CAIRO_DOCK_GRAPH_CIRCLE || pGraph->iType == CAIRO_DOCK_GRAPH_CIRCLE_PLAIN)
311 {
312 double radius = MIN (fWidth, fHeightPerValue)/2.;
313 pGradationPattern = cairo_pattern_create_radial (fWidth/2,
314 iMargin + radius,
315 0.,
316 fWidth/2,
317 iMargin + radius,
318 radius);
319 }
320 else
321 {
322 pGradationPattern = cairo_pattern_create_linear (0.,
323 floor (pGraph->bMixGraphs ? fHeight : fHeightPerValue),
324 0.,
325 0.);
326 }
327 g_return_val_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS, NULL);
328
329 cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_PAD);
330 cairo_pattern_add_color_stop_rgba (pGradationPattern,
331 0.,
332 fLowColor[0],
333 fLowColor[1],
334 fLowColor[2],
335 1.);
336 cairo_pattern_add_color_stop_rgba (pGradationPattern,
337 1.,
338 fHighColor[0],
339 fHighColor[1],
340 fHighColor[2],
341 1.);
342 }
343 return pGradationPattern;
344 }
345 #define dc .5
346 #define _guess_color(i) (((pGraph->fLowColor[i] < pGraph->fHighColor[i] && pGraph->fLowColor[i] > dc) || pGraph->fLowColor[i] > 1-dc) ? pGraph->fLowColor[i] - dc : pGraph->fLowColor[i] + dc)
347 //#define _guess_color(i) (1. - pGraph->fLowColor[i])
_set_overlay_zones(Graph * pGraph)348 static void _set_overlay_zones (Graph *pGraph)
349 {
350 CairoDataRenderer *pRenderer = CAIRO_DATA_RENDERER (pGraph);
351 int iNbValues = cairo_data_renderer_get_nb_values (pRenderer);
352 int iWidth = pRenderer->iWidth, iHeight = pRenderer->iHeight;
353 int i;
354
355 // on complete le data-renderer.
356 int iNbDrawings = iNbValues / pRenderer->iRank;
357 int iMargin = pGraph->iMargin;
358 double fOneGraphHeight = iHeight - 2*iMargin;
359 fOneGraphHeight /= iNbDrawings;
360 double fOneGraphWidth = iWidth - 2*iMargin;
361 fOneGraphWidth /= iNbDrawings;
362 int iTextWidth = MIN (48, pRenderer->iWidth/2); // on definit une taille pour les zones de texte.
363 int iTextHeight = MIN (16, fOneGraphHeight/1.5);
364 int iLabelWidth = MIN (48, pRenderer->iWidth/2); // on definit une taille pour les zones de texte.
365 int iLabelHeight = MIN (16, fOneGraphHeight/2.);
366 int h = fOneGraphHeight/8; // ecart du texte au-dessus de l'axe Ox.
367 CairoDataRendererTextParam *pValuesText;
368 CairoDataRendererText *pLabel;
369 for (i = 0; i < iNbValues; i ++)
370 {
371 /// rajouter l'alignement gauche/centre/droit ...
372 if (pRenderer->pLabels) // les labels en haut a gauche.
373 {
374 pLabel = &pRenderer->pLabels[i];
375 if (iLabelHeight > 8) // sinon trop petit, et empiete sur la valeur.
376 {
377 if (pGraph->bMixGraphs)
378 {
379 pLabel->param.fX = (double)(iMargin + i * fOneGraphWidth + iLabelWidth/2) / iWidth - .5;
380 pLabel->param.fY = (double)(iHeight - iMargin - iLabelHeight/2) / iHeight - .5;
381 }
382 else
383 {
384 pLabel->param.fX = (double) (iMargin + iLabelWidth/2) / iWidth - .5;
385 pLabel->param.fY = .5 - (double)(iMargin + h + i * fOneGraphHeight + iLabelHeight/2) / iHeight;
386 }
387 pLabel->param.fWidth = (double)iLabelWidth / iWidth;
388 pLabel->param.fHeight = (double)iLabelHeight / iHeight;
389 pLabel->param.pColor[0] = 1.;
390 pLabel->param.pColor[1] = 1.;
391 pLabel->param.pColor[2] = 1.;
392 pLabel->param.pColor[3] = 1.; // white, a little transparent
393 }
394 else
395 {
396 pLabel->param.fWidth = pLabel->param.fHeight = 0;
397 }
398 }
399 if (pRenderer->pValuesText) // les valeurs en bas au milieu.
400 {
401 pValuesText = &pRenderer->pValuesText[i];
402 if (pGraph->bMixGraphs)
403 {
404 pValuesText->fX = (double)(iMargin + i * fOneGraphWidth + iTextWidth/2) / iWidth - .5;
405 pValuesText->fY = (double)(iMargin + h + iTextHeight/2) / iHeight - .5;
406 }
407 else
408 {
409 pValuesText->fX = (double)0.; // centered.
410 pValuesText->fY = .5 - (double)(iMargin + (i+1) * fOneGraphHeight - iTextHeight/2 - h) / iHeight;
411 }
412 pValuesText->fWidth = (double)iTextWidth / iWidth;
413 pValuesText->fHeight = (double)iTextHeight / iHeight;
414 if (pGraph->fBackGroundColor[3] > .2 && pGraph->fBackGroundColor[3] < .7)
415 {
416 pValuesText->pColor[0] = pGraph->fBackGroundColor[0];
417 pValuesText->pColor[1] = pGraph->fBackGroundColor[1];
418 pValuesText->pColor[2] = pGraph->fBackGroundColor[2];
419 //g_print ("bg color: %.2f;%.2f;%.2f\n", pGraph->fBackGroundColor[0], pGraph->fBackGroundColor[1], pGraph->fBackGroundColor[2]);
420 }
421 else
422 {
423 pValuesText->pColor[0] = _guess_color (0);
424 pValuesText->pColor[1] = _guess_color (1);
425 pValuesText->pColor[2] = _guess_color (2);
426 //g_print ("line color: %.2f;%.2f;%.2f\n", pGraph->fLowColor[0], pGraph->fLowColor[1], pGraph->fLowColor[2]);
427 }
428 //g_print ("text color: %.2f;%.2f;%.2f\n", pValuesText->pColor[0], pValuesText->pColor[1], pValuesText->pColor[2]);
429 pValuesText->pColor[3] = 1.;
430 }
431 }
432 }
433
load(Graph * pGraph,G_GNUC_UNUSED Icon * pIcon,CairoGraphAttribute * pAttribute)434 static void load (Graph *pGraph, G_GNUC_UNUSED Icon *pIcon, CairoGraphAttribute *pAttribute)
435 {
436 CairoDataRenderer *pRenderer = CAIRO_DATA_RENDERER (pGraph);
437
438 int iWidth = pRenderer->iWidth, iHeight = pRenderer->iHeight;
439 if (iWidth == 0 || iHeight == 0)
440 return ;
441
442 int iNbValues = cairo_data_renderer_get_nb_values (pRenderer);
443 pGraph->iType = pAttribute->iType;
444 pGraph->bMixGraphs = pAttribute->bMixGraphs;
445 pRenderer->iRank = (pAttribute->bMixGraphs ? iNbValues : 1);
446
447 pGraph->fHighColor = g_new0 (double, 3 * iNbValues);
448 pGraph->fLowColor = g_new0 (double, 3 * iNbValues);
449
450 int i;
451 pGraph->pGradationPatterns = g_new (cairo_pattern_t *, iNbValues);
452 for (i = 0; i < iNbValues; i ++)
453 {
454 if (pAttribute->fHighColor != NULL)
455 memcpy (&pGraph->fHighColor[3*i], pAttribute->fHighColor, 3 * sizeof (double));
456 if (pAttribute->fLowColor != NULL)
457 memcpy (&pGraph->fLowColor[3*i], pAttribute->fLowColor, 3 * sizeof (double));
458 pGraph->pGradationPatterns[i] = _cairo_dock_create_graph_pattern (pGraph,
459 &pGraph->fLowColor[3*i],
460 &pGraph->fHighColor[3*i]);
461 }
462
463 pGraph->iMargin = floor (MIN (iWidth, iHeight) / 32);
464
465 if (pAttribute->fBackGroundColor != NULL)
466 memcpy (pGraph->fBackGroundColor, pAttribute->fBackGroundColor, 4 * sizeof (double));
467 pGraph->pBackgroundSurface = _cairo_dock_create_graph_background (
468 iWidth,
469 iHeight,
470 pGraph->iMargin,
471 pGraph->fBackGroundColor,
472 pGraph->iType,
473 iNbValues / pRenderer->iRank);
474 if (g_bUseOpenGL && 0)
475 pGraph->iBackgroundTexture = cairo_dock_create_texture_from_surface (pGraph->pBackgroundSurface);
476
477 // on complete le data-renderer.
478 _set_overlay_zones (pGraph);
479 }
480
481
reload(Graph * pGraph)482 static void reload (Graph *pGraph)
483 {
484 CairoDataRenderer *pRenderer = CAIRO_DATA_RENDERER (pGraph);
485 int iNbValues = cairo_data_renderer_get_nb_values (pRenderer);
486 int iWidth = pRenderer->iWidth, iHeight = pRenderer->iHeight;
487 pGraph->iMargin = floor (MIN (iWidth, iHeight) / 32);
488 if (pGraph->pBackgroundSurface != NULL)
489 cairo_surface_destroy (pGraph->pBackgroundSurface);
490 pGraph->pBackgroundSurface = _cairo_dock_create_graph_background (iWidth, iHeight, pGraph->iMargin, pGraph->fBackGroundColor, pGraph->iType, iNbValues / pRenderer->iRank);
491 if (pGraph->iBackgroundTexture != 0)
492 _cairo_dock_delete_texture (pGraph->iBackgroundTexture);
493 if (g_bUseOpenGL && 0)
494 pGraph->iBackgroundTexture = cairo_dock_create_texture_from_surface (pGraph->pBackgroundSurface);
495 else
496 pGraph->iBackgroundTexture = 0;
497 int i;
498 for (i = 0; i < iNbValues; i ++)
499 {
500 if (pGraph->pGradationPatterns[i] != NULL)
501 cairo_pattern_destroy (pGraph->pGradationPatterns[i]);
502 pGraph->pGradationPatterns[i] = _cairo_dock_create_graph_pattern (pGraph,
503 &pGraph->fLowColor[3*i],
504 &pGraph->fHighColor[3*i]);
505 }
506
507 // on re-complete le data-renderer.
508 _set_overlay_zones (pGraph);
509 }
510
511
unload(Graph * pGraph)512 static void unload (Graph *pGraph)
513 {
514 cd_debug ("");
515 if (pGraph->pBackgroundSurface != NULL)
516 cairo_surface_destroy (pGraph->pBackgroundSurface);
517 if (pGraph->iBackgroundTexture != 0)
518 _cairo_dock_delete_texture (pGraph->iBackgroundTexture);
519
520 CairoDataRenderer *pRenderer = CAIRO_DATA_RENDERER (pGraph);
521 int iNbValues = cairo_data_renderer_get_nb_values (pRenderer);
522 int i;
523 for (i = 0; i < iNbValues; i ++)
524 {
525 if (pGraph->pGradationPatterns[i] != NULL)
526 cairo_pattern_destroy (pGraph->pGradationPatterns[i]);
527 }
528
529 g_free (pGraph->pGradationPatterns);
530 g_free (pGraph->fHighColor);
531 g_free (pGraph->fLowColor);
532 }
533
534
535
536 //////////////////////////////////////////
537 /////////////// RENDERER /////////////////
538 //////////////////////////////////////////
cairo_dock_register_data_renderer_graph(void)539 void cairo_dock_register_data_renderer_graph (void)
540 {
541 // create a new record
542 CairoDockDataRendererRecord *pRecord = g_new0 (CairoDockDataRendererRecord, 1);
543
544 // fill the properties we need
545 pRecord->interface.load = (CairoDataRendererLoadFunc) load;
546 pRecord->interface.render = (CairoDataRendererRenderFunc) render;
547 pRecord->interface.render_opengl = (CairoDataRendererRenderOpenGLFunc) NULL;
548 pRecord->interface.reload = (CairoDataRendererReloadFunc) reload;
549 pRecord->interface.unload = (CairoDataRendererUnloadFunc) unload;
550 pRecord->iStructSize = sizeof (Graph);
551 pRecord->cThemeDirName = NULL;
552 pRecord->cDefaultTheme = NULL;
553
554 // register
555 cairo_dock_register_data_renderer ("graph", pRecord);
556 }
557