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/>.
20
/**********************************************************************************
22
This file is a part of the cairo-dock clock applet,
23
released under the terms of the GNU General Public License.
24
The analogic display comes from Cairo-Clock.
26
Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
28
**********************************************************************************/
34
#include "applet-struct.h"
35
#include "applet-theme.h"
37
static char s_cFileNames[CLOCK_ELEMENTS][30] = {
38
"clock-drop-shadow.svg",
41
"clock-hour-hand-shadow.svg",
42
"clock-minute-hand-shadow.svg",
43
"clock-second-hand-shadow.svg",
44
"clock-hour-hand.svg",
45
"clock-minute-hand.svg",
46
"clock-second-hand.svg",
47
"clock-face-shadow.svg",
52
void cd_clock_load_theme (CairoDockModuleInstance *myApplet)
54
cd_message ("%s (%s)", __func__, myConfig.cThemePath);
55
//\_______________ On charge le theme choisi (on n'a pas besoin de connaitre les dimmensions de l'icone).
56
if (myConfig.cThemePath != NULL)
58
GString *sElementPath = g_string_new ("");
60
for (i = 0; i < CLOCK_ELEMENTS; i ++)
62
g_string_printf (sElementPath, "%s/%s", myConfig.cThemePath, s_cFileNames[i]);
63
myData.pSvgHandles[i] = rsvg_handle_new_from_file (sElementPath->str, NULL);
66
while (i < CLOCK_FRAME && myData.pSvgHandles[i] == NULL)
69
if (i == CLOCK_HOUR_HAND_SHADOW)
70
i = CLOCK_FACE_SHADOW;
73
rsvg_handle_get_dimensions (myData.pSvgHandles[i], &myData.DimensionData);
74
if (myData.pSvgHandles[CLOCK_HOUR_HAND] != NULL)
75
rsvg_handle_get_dimensions (myData.pSvgHandles[CLOCK_HOUR_HAND], &myData.needleDimension);
76
cd_debug ("clock bg dimension : %dx%d", (int) myData.DimensionData.width, (int) myData.DimensionData.height);
77
cd_debug ("clock needle dimension : %dx%d", (int) myData.needleDimension.width, (int) myData.needleDimension.height);
79
// recuperation des parametres des aiguilles.
80
g_string_printf (sElementPath, "%s/%s", myConfig.cThemePath, "theme.conf");
81
GKeyFile *pKeyFile = cairo_dock_open_key_file (sElementPath->str);
84
GError *erreur = NULL;
85
myData.iNeedleRealHeight = g_key_file_get_integer (pKeyFile, "Needle", "height", &erreur);
88
cd_warning (erreur->message);
89
g_error_free (erreur);
92
myData.iNeedleOffsetX = g_key_file_get_double (pKeyFile, "Needle", "offset x", &erreur);
95
cd_warning (erreur->message);
96
g_error_free (erreur);
99
g_key_file_free (pKeyFile);
101
else // on prend des valeurs par defaut assez larges.
103
g_print ("clock : default needle size\n");
104
myData.iNeedleRealHeight = .5 * myData.needleDimension.height;
105
myData.iNeedleOffsetX = .5 * myData.needleDimension.width;
107
myData.iNeedleRealWidth = myData.needleDimension.width/2 + myData.iNeedleOffsetX;
108
myData.iNeedleOffsetY = .5 * myData.iNeedleRealHeight;
109
cd_debug ("clock needle : H=%d; dx=%d\n", myData.iNeedleRealHeight, myData.iNeedleOffsetX);
111
g_string_free (sElementPath, TRUE);
115
myData.DimensionData.width = 48; // valeurs par defaut si aucun theme trouve.
116
myData.DimensionData.height = 48;
117
myData.needleDimension.width = 48;
118
myData.needleDimension.height = 48;
123
static void paint_background (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
125
if (myData.pSvgHandles[CLOCK_DROP_SHADOW] != NULL)
126
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_DROP_SHADOW], pDrawingContext);
127
if (myData.pSvgHandles[CLOCK_FACE] != NULL)
128
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_FACE], pDrawingContext);
129
if (myData.pSvgHandles[CLOCK_MARKS] != NULL)
130
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_MARKS], pDrawingContext);
132
static void paint_foreground (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
134
if (myData.pSvgHandles[CLOCK_FACE_SHADOW] != NULL)
135
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_FACE_SHADOW], pDrawingContext);
136
if (myData.pSvgHandles[CLOCK_GLASS] != NULL)
137
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_GLASS], pDrawingContext);
138
if (myData.pSvgHandles[CLOCK_FRAME] != NULL)
139
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_FRAME], pDrawingContext);
141
static cairo_surface_t* cd_clock_create_bg_surface (CairoDockModuleInstance *myApplet, cairo_t* pSourceContext, int iWidth, int iHeight, SurfaceKind kind)
143
//g_print ("%s (%dx%d)\n", __func__, iWidth, iHeight);
144
cairo_surface_t* pNewSurface =_cairo_dock_create_blank_surface (pSourceContext, iWidth, iHeight);
145
g_return_val_if_fail (cairo_surface_status (pNewSurface) == CAIRO_STATUS_SUCCESS, NULL);
147
cairo_t* pDrawingContext = cairo_create (pNewSurface);
148
g_return_val_if_fail (cairo_status (pDrawingContext) == CAIRO_STATUS_SUCCESS, NULL);
150
cairo_set_operator (pDrawingContext, CAIRO_OPERATOR_SOURCE);
151
cairo_set_source_rgba (pDrawingContext, 1.0f, 1.0f, 1.0f, 0.0f);
152
cairo_paint (pDrawingContext);
154
cairo_set_operator (pDrawingContext, CAIRO_OPERATOR_OVER);
155
cairo_scale (pDrawingContext,
156
(double) iWidth / (double) myData.DimensionData.width,
157
(double) iHeight / (double) myData.DimensionData.height);
161
case KIND_BACKGROUND :
162
paint_background (myApplet, pDrawingContext);
165
case KIND_FOREGROUND :
166
paint_foreground (myApplet, pDrawingContext);
173
cairo_destroy (pDrawingContext);
178
static void paint_hour (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
180
double fShadowOffsetX = -0.75f;
181
double fShadowOffsetY = 0.75f;
182
cairo_save (pDrawingContext);
183
cairo_translate(pDrawingContext, fShadowOffsetX, fShadowOffsetY);
184
if (myData.pSvgHandles[CLOCK_HOUR_HAND_SHADOW] != NULL)
185
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_HOUR_HAND_SHADOW], pDrawingContext);
186
cairo_restore (pDrawingContext);
187
if (myData.pSvgHandles[CLOCK_HOUR_HAND] != NULL)
188
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_HOUR_HAND], pDrawingContext);
190
static void paint_minute (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
192
double fShadowOffsetX = -0.75f;
193
double fShadowOffsetY = 0.75f;
194
cairo_save (pDrawingContext);
195
cairo_translate(pDrawingContext, fShadowOffsetX, fShadowOffsetY);
196
if (myData.pSvgHandles[CLOCK_MINUTE_HAND_SHADOW] != NULL)
197
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_MINUTE_HAND_SHADOW], pDrawingContext);
198
cairo_restore (pDrawingContext);
199
if (myData.pSvgHandles[CLOCK_MINUTE_HAND] != NULL)
200
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_MINUTE_HAND], pDrawingContext);
202
static void paint_second (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
204
double fShadowOffsetX = -0.75f;
205
double fShadowOffsetY = 0.75f;
206
cairo_save (pDrawingContext);
207
cairo_translate(pDrawingContext, fShadowOffsetX, fShadowOffsetY);
208
if (myData.pSvgHandles[CLOCK_SECOND_HAND_SHADOW] != NULL)
209
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_SECOND_HAND_SHADOW], pDrawingContext);
210
cairo_restore (pDrawingContext);
211
if (myData.pSvgHandles[CLOCK_SECOND_HAND] != NULL)
212
rsvg_handle_render_cairo (myData.pSvgHandles[CLOCK_SECOND_HAND], pDrawingContext);
214
static cairo_surface_t *create_needle_surface (CairoDockModuleInstance *myApplet, cairo_t* pSourceContext, SurfaceKind kind)
216
cairo_surface_t* pNewSurface =_cairo_dock_create_blank_surface (pSourceContext, myData.iNeedleWidth, myData.iNeedleHeight + 0); // +1 pour les ombres.
217
g_return_val_if_fail (cairo_surface_status (pNewSurface) == CAIRO_STATUS_SUCCESS, NULL);
219
cairo_t* pDrawingContext = cairo_create (pNewSurface);
220
g_return_val_if_fail (cairo_status (pDrawingContext) == CAIRO_STATUS_SUCCESS, NULL);
222
cairo_set_operator (pDrawingContext, CAIRO_OPERATOR_SOURCE);
223
cairo_set_source_rgba (pDrawingContext, 1.0f, 1.0f, 1.0f, 0.0f);
224
cairo_paint (pDrawingContext);
226
cairo_set_operator (pDrawingContext, CAIRO_OPERATOR_OVER);
228
cairo_scale (pDrawingContext, myData.fNeedleScale, myData.fNeedleScale);
229
cairo_translate (pDrawingContext, myData.iNeedleOffsetX, myData.iNeedleOffsetY);
233
paint_hour (myApplet, pDrawingContext);
237
paint_minute (myApplet, pDrawingContext);
241
paint_second (myApplet, pDrawingContext);
248
cairo_destroy (pDrawingContext);
252
void cd_clock_load_back_and_fore_ground (CairoDockModuleInstance *myApplet)
255
CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
257
//\_______________ On construit les surfaces d'arriere-plan et d'avant-plan une bonne fois pour toutes.
258
myData.pBackgroundSurface = cd_clock_create_bg_surface (myApplet,
263
myData.pForegroundSurface = cd_clock_create_bg_surface (myApplet,
270
void cd_clock_load_textures (CairoDockModuleInstance *myApplet)
272
if (myData.pBackgroundSurface != NULL)
273
myData.iBgTexture = cairo_dock_create_texture_from_surface (myData.pBackgroundSurface);
274
if (myData.pForegroundSurface != NULL)
275
myData.iFgTexture = cairo_dock_create_texture_from_surface (myData.pForegroundSurface);
278
CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
280
int iSize = MIN (iWidth, iHeight);
281
myData.fNeedleScale = (double) iSize / (double) myData.needleDimension.width; // car l'aiguille est a l'horizontale dans le fichier svg.
282
myData.iNeedleWidth = (double) myData.iNeedleRealWidth * myData.fNeedleScale;
283
myData.iNeedleHeight = (double) myData.iNeedleRealHeight * myData.fNeedleScale;
285
cairo_surface_t *pNeedleSurface = create_needle_surface (myApplet,
288
if (pNeedleSurface != NULL)
290
myData.iHourNeedleTexture = cairo_dock_create_texture_from_surface (pNeedleSurface);
291
cairo_surface_destroy (pNeedleSurface);
294
pNeedleSurface = create_needle_surface (myApplet,
297
if (pNeedleSurface != NULL)
299
myData.iMinuteNeedleTexture = cairo_dock_create_texture_from_surface (pNeedleSurface);
300
cairo_surface_destroy (pNeedleSurface);
303
pNeedleSurface = create_needle_surface (myApplet,
306
if (pNeedleSurface != NULL)
308
myData.iSecondNeedleTexture = cairo_dock_create_texture_from_surface (pNeedleSurface);
309
cairo_surface_destroy (pNeedleSurface);
315
void cd_clock_clear_theme (CairoDockModuleInstance *myApplet, gboolean bClearAll)
317
if (myData.pBackgroundSurface != NULL)
319
cairo_surface_destroy (myData.pBackgroundSurface);
320
myData.pBackgroundSurface = NULL;
322
if (myData.pForegroundSurface != NULL)
324
cairo_surface_destroy (myData.pForegroundSurface);
325
myData.pForegroundSurface = NULL;
327
if (myData.iBgTexture != 0)
329
_cairo_dock_delete_texture (myData.iBgTexture);
330
myData.iBgTexture = 0;
332
if (myData.iFgTexture != 0)
334
_cairo_dock_delete_texture (myData.iFgTexture);
335
myData.iFgTexture = 0;
337
if (myData.iHourNeedleTexture != 0)
339
_cairo_dock_delete_texture (myData.iHourNeedleTexture);
340
myData.iHourNeedleTexture = 0;
342
if (myData.iMinuteNeedleTexture != 0)
344
_cairo_dock_delete_texture (myData.iMinuteNeedleTexture);
345
myData.iMinuteNeedleTexture = 0;
347
if (myData.iSecondNeedleTexture != 0)
349
_cairo_dock_delete_texture (myData.iSecondNeedleTexture);
350
myData.iSecondNeedleTexture = 0;
352
if (myData.iDateTexture != 0)
354
_cairo_dock_delete_texture (myData.iDateTexture);
355
myData.iDateTexture = 0;
361
for (i = 0; i < CLOCK_ELEMENTS; i ++)
363
if (myData.pSvgHandles[i] != NULL)
365
rsvg_handle_free (myData.pSvgHandles[i]);
366
myData.pSvgHandles[i] = NULL;