~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy

« back to all changes in this revision

Viewing changes to clock/src/applet-theme.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
ImportĀ upstreamĀ versionĀ 2.0.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
/**********************************************************************************
 
21
 
 
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.
 
25
 
 
26
Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
 
27
 
 
28
**********************************************************************************/
 
29
#include <stdlib.h>
 
30
#define __USE_POSIX
 
31
#include <time.h>
 
32
#include <signal.h>
 
33
 
 
34
#include "applet-struct.h"
 
35
#include "applet-theme.h"
 
36
 
 
37
static char s_cFileNames[CLOCK_ELEMENTS][30] = {
 
38
        "clock-drop-shadow.svg",
 
39
        "clock-face.svg",
 
40
        "clock-marks.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",
 
48
        "clock-glass.svg",
 
49
        "clock-frame.svg" };
 
50
 
 
51
 
 
52
void cd_clock_load_theme (CairoDockModuleInstance *myApplet)
 
53
{
 
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)
 
57
        {
 
58
                GString *sElementPath = g_string_new ("");
 
59
                int i;
 
60
                for (i = 0; i < CLOCK_ELEMENTS; i ++)
 
61
                {
 
62
                        g_string_printf (sElementPath, "%s/%s", myConfig.cThemePath, s_cFileNames[i]);
 
63
                        myData.pSvgHandles[i] = rsvg_handle_new_from_file (sElementPath->str, NULL);
 
64
                }
 
65
                i = 0;
 
66
                while (i < CLOCK_FRAME && myData.pSvgHandles[i] == NULL)
 
67
                {
 
68
                        i ++;
 
69
                        if (i == CLOCK_HOUR_HAND_SHADOW)
 
70
                                i = CLOCK_FACE_SHADOW;
 
71
                }
 
72
                if (i != CLOCK_FRAME)
 
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);
 
78
                
 
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);
 
82
                if (pKeyFile != NULL)
 
83
                {
 
84
                        GError *erreur = NULL;
 
85
                        myData.iNeedleRealHeight = g_key_file_get_integer (pKeyFile, "Needle", "height", &erreur);
 
86
                        if (erreur != NULL)
 
87
                        {
 
88
                                cd_warning (erreur->message);
 
89
                                g_error_free (erreur);
 
90
                                erreur = NULL;
 
91
                        }
 
92
                        myData.iNeedleOffsetX = g_key_file_get_double (pKeyFile, "Needle", "offset x", &erreur);
 
93
                        if (erreur != NULL)
 
94
                        {
 
95
                                cd_warning (erreur->message);
 
96
                                g_error_free (erreur);
 
97
                                erreur = NULL;
 
98
                        }
 
99
                        g_key_file_free (pKeyFile);
 
100
                }
 
101
                else  // on prend des valeurs par defaut assez larges.
 
102
                {
 
103
                        g_print ("clock : default needle size\n");
 
104
                        myData.iNeedleRealHeight = .5 * myData.needleDimension.height;
 
105
                        myData.iNeedleOffsetX = .5 * myData.needleDimension.width;
 
106
                }
 
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);
 
110
                
 
111
                g_string_free (sElementPath, TRUE);
 
112
        }
 
113
        else
 
114
        {
 
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;
 
119
        }
 
120
}
 
121
 
 
122
 
 
123
static void paint_background (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
 
124
{
 
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);
 
131
}
 
132
static void paint_foreground (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
 
133
{
 
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);
 
140
}
 
141
static cairo_surface_t* cd_clock_create_bg_surface (CairoDockModuleInstance *myApplet, cairo_t* pSourceContext, int iWidth, int iHeight, SurfaceKind kind)
 
142
{
 
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);
 
146
        
 
147
        cairo_t* pDrawingContext = cairo_create (pNewSurface);
 
148
        g_return_val_if_fail (cairo_status (pDrawingContext) == CAIRO_STATUS_SUCCESS, NULL);
 
149
        
 
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);
 
153
        
 
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);
 
158
        
 
159
        switch (kind)
 
160
        {
 
161
                case KIND_BACKGROUND :
 
162
                        paint_background (myApplet, pDrawingContext);
 
163
                break;
 
164
                
 
165
                case KIND_FOREGROUND :
 
166
                        paint_foreground (myApplet, pDrawingContext);
 
167
                break;
 
168
                
 
169
                default :
 
170
                return NULL;
 
171
        }
 
172
        
 
173
        cairo_destroy (pDrawingContext);
 
174
        
 
175
        return pNewSurface;
 
176
}
 
177
 
 
178
static void paint_hour (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
 
179
{
 
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);
 
189
}
 
190
static void paint_minute (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
 
191
{
 
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);
 
201
}
 
202
static void paint_second (CairoDockModuleInstance *myApplet, cairo_t* pDrawingContext)
 
203
{
 
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);
 
213
}
 
214
static cairo_surface_t *create_needle_surface (CairoDockModuleInstance *myApplet, cairo_t* pSourceContext, SurfaceKind kind)
 
215
{
 
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);
 
218
        
 
219
        cairo_t* pDrawingContext = cairo_create (pNewSurface);
 
220
        g_return_val_if_fail (cairo_status (pDrawingContext) == CAIRO_STATUS_SUCCESS, NULL);
 
221
        
 
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);
 
225
        
 
226
        cairo_set_operator (pDrawingContext, CAIRO_OPERATOR_OVER);
 
227
        
 
228
        cairo_scale (pDrawingContext, myData.fNeedleScale, myData.fNeedleScale);
 
229
        cairo_translate (pDrawingContext, myData.iNeedleOffsetX, myData.iNeedleOffsetY);
 
230
        switch (kind)
 
231
        {
 
232
                case KIND_HOUR :
 
233
                        paint_hour (myApplet, pDrawingContext);
 
234
                break;
 
235
                
 
236
                case KIND_MINUTE :
 
237
                        paint_minute (myApplet, pDrawingContext);
 
238
                break;
 
239
                
 
240
                case KIND_SECOND :
 
241
                        paint_second (myApplet, pDrawingContext);
 
242
                break;
 
243
                
 
244
                default :
 
245
                return NULL;
 
246
        }
 
247
        
 
248
        cairo_destroy (pDrawingContext);
 
249
        return pNewSurface;
 
250
}
 
251
 
 
252
void cd_clock_load_back_and_fore_ground (CairoDockModuleInstance *myApplet)
 
253
{
 
254
        int iWidth, iHeight;
 
255
        CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
 
256
 
 
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,
 
259
                myDrawContext,
 
260
                iWidth,
 
261
                iHeight,
 
262
                KIND_BACKGROUND);
 
263
        myData.pForegroundSurface = cd_clock_create_bg_surface (myApplet,
 
264
                myDrawContext,
 
265
                iWidth,
 
266
                iHeight,
 
267
                KIND_FOREGROUND);
 
268
}
 
269
 
 
270
void cd_clock_load_textures (CairoDockModuleInstance *myApplet)
 
271
{
 
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);
 
276
        
 
277
        int iWidth, iHeight;
 
278
        CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
 
279
        
 
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;
 
284
        
 
285
        cairo_surface_t *pNeedleSurface = create_needle_surface (myApplet,
 
286
                myDrawContext,
 
287
                KIND_HOUR);
 
288
        if (pNeedleSurface != NULL)
 
289
        {
 
290
                myData.iHourNeedleTexture = cairo_dock_create_texture_from_surface (pNeedleSurface);
 
291
                cairo_surface_destroy (pNeedleSurface);
 
292
        }
 
293
        
 
294
        pNeedleSurface = create_needle_surface (myApplet,
 
295
                myDrawContext,
 
296
                KIND_MINUTE);
 
297
        if (pNeedleSurface != NULL)
 
298
        {
 
299
                myData.iMinuteNeedleTexture = cairo_dock_create_texture_from_surface (pNeedleSurface);
 
300
                cairo_surface_destroy (pNeedleSurface);
 
301
        }
 
302
        
 
303
        pNeedleSurface = create_needle_surface (myApplet,
 
304
                myDrawContext,
 
305
                KIND_SECOND);
 
306
        if (pNeedleSurface != NULL)
 
307
        {
 
308
                myData.iSecondNeedleTexture = cairo_dock_create_texture_from_surface (pNeedleSurface);
 
309
                cairo_surface_destroy (pNeedleSurface);
 
310
        }
 
311
}
 
312
 
 
313
 
 
314
 
 
315
void cd_clock_clear_theme (CairoDockModuleInstance *myApplet, gboolean bClearAll)
 
316
{
 
317
        if (myData.pBackgroundSurface != NULL)
 
318
        {
 
319
                cairo_surface_destroy (myData.pBackgroundSurface);
 
320
                myData.pBackgroundSurface = NULL;
 
321
        }
 
322
        if (myData.pForegroundSurface != NULL)
 
323
        {
 
324
                cairo_surface_destroy (myData.pForegroundSurface);
 
325
                myData.pForegroundSurface = NULL;
 
326
        }
 
327
        if (myData.iBgTexture != 0)
 
328
        {
 
329
                _cairo_dock_delete_texture (myData.iBgTexture);
 
330
                myData.iBgTexture = 0;
 
331
        }
 
332
        if (myData.iFgTexture != 0)
 
333
        {
 
334
                _cairo_dock_delete_texture (myData.iFgTexture);
 
335
                myData.iFgTexture = 0;
 
336
        }
 
337
        if (myData.iHourNeedleTexture != 0)
 
338
        {
 
339
                _cairo_dock_delete_texture (myData.iHourNeedleTexture);
 
340
                myData.iHourNeedleTexture = 0;
 
341
        }
 
342
        if (myData.iMinuteNeedleTexture != 0)
 
343
        {
 
344
                _cairo_dock_delete_texture (myData.iMinuteNeedleTexture);
 
345
                myData.iMinuteNeedleTexture = 0;
 
346
        }
 
347
        if (myData.iSecondNeedleTexture != 0)
 
348
        {
 
349
                _cairo_dock_delete_texture (myData.iSecondNeedleTexture);
 
350
                myData.iSecondNeedleTexture = 0;
 
351
        }
 
352
        if (myData.iDateTexture != 0)
 
353
        {
 
354
                _cairo_dock_delete_texture (myData.iDateTexture);
 
355
                myData.iDateTexture = 0;
 
356
        }
 
357
        
 
358
        if (bClearAll)
 
359
        {
 
360
                int i;
 
361
                for (i = 0; i < CLOCK_ELEMENTS; i ++)
 
362
                {
 
363
                        if (myData.pSvgHandles[i] != NULL)
 
364
                        {
 
365
                                rsvg_handle_free (myData.pSvgHandles[i]);
 
366
                                myData.pSvgHandles[i] = NULL;
 
367
                        }
 
368
                }
 
369
        }
 
370
}