2
* Copyright (C) 2007 Intel
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
19
* Authored by Neil Jagdish Patel <njp@o-hand.com>
20
* Neil Jagdish Patel <neil.patel@canonical.com>
21
* - Updated to use default GNOME gconf keys
30
#include <gconf/gconf.h>
31
#include <gconf/gconf-client.h>
33
#include "launcher-background.h"
34
#include "launcher-behave.h"
36
G_DEFINE_TYPE (LauncherBackground, launcher_background, CLUTTER_TYPE_GROUP)
38
#define LAUNCHER_BACKGROUND_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
39
LAUNCHER_TYPE_BACKGROUND, LauncherBackgroundPrivate))
42
#define BG_PATH "/desktop/gnome/background"
43
#define BG_FILE BG_PATH "/picture_filename" /* string */
44
#define BG_OPTION BG_PATH "/picture_options"
45
/* none|wallpaper|centred|scaled|stretched|zoom */
47
#define BG_DEFAULT PKGDATADIR "/default.svg"
49
struct _LauncherBackgroundPrivate
51
ClutterActor *texture;
57
ClutterTimeline *timeline;
59
ClutterBehaviour *behave;
65
* Just load the file normally,if its larger than the stage, clip it */
67
load_normal (const gchar *filename, ClutterActor *texture)
69
GdkPixbuf *pixbuf = NULL;
72
gint subw = 0, subh = 0;
74
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
78
g_warning (error->message);
83
width = gdk_pixbuf_get_width (pixbuf);
84
height = gdk_pixbuf_get_height (pixbuf);
86
if (width > CLUTTER_STAGE_WIDTH ())
87
subw = CLUTTER_STAGE_WIDTH ();
91
if (height > CLUTTER_STAGE_HEIGHT ())
92
subh = CLUTTER_STAGE_HEIGHT ();
98
GdkPixbuf *temp = pixbuf;
100
pixbuf = gdk_pixbuf_new_subpixbuf (temp, 0, 0, subw, subh);
101
g_object_unref (temp);
104
clutter_texture_set_pixbuf (CLUTTER_TEXTURE (texture), pixbuf, NULL);
105
clutter_actor_set_size (texture,
106
CLUTTER_STAGE_WIDTH (),
107
CLUTTER_STAGE_HEIGHT ());
108
clutter_actor_set_position (texture, 0, 0);
110
g_object_unref (pixbuf);
114
* Simply return a stretched version of the image
117
load_stretched (const gchar *filename, ClutterActor *texture)
119
GdkPixbuf *pixbuf = NULL;
120
GError *error = NULL;
122
pixbuf = gdk_pixbuf_new_from_file_at_scale (filename,
123
CLUTTER_STAGE_WIDTH (),
124
CLUTTER_STAGE_HEIGHT (),
129
g_warning (error->message);
130
g_error_free (error);
133
clutter_texture_set_pixbuf (CLUTTER_TEXTURE (texture), pixbuf, NULL);
134
clutter_actor_set_size (texture,
135
CLUTTER_STAGE_WIDTH (),
136
CLUTTER_STAGE_HEIGHT ());
137
clutter_actor_set_position (texture, 0, 0);
139
g_object_unref (pixbuf);
143
* Center the image on the stage
146
load_centred (const gchar *filename, ClutterActor *texture)
148
GdkPixbuf *pixbuf = NULL;
149
GError *error = NULL;
152
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
156
g_warning (error->message);
157
g_error_free (error);
161
clutter_texture_set_pixbuf (CLUTTER_TEXTURE (texture), pixbuf, NULL);
163
w = gdk_pixbuf_get_width (pixbuf);
164
h = gdk_pixbuf_get_height (pixbuf);
165
x = (CLUTTER_STAGE_WIDTH ()/2) - (w/2);
166
y = (CLUTTER_STAGE_HEIGHT ()/2) - (h/2);
168
clutter_actor_set_size (texture, w, h);
169
clutter_actor_set_position (texture, x, y);
171
g_object_unref (pixbuf);
175
* Load the image scaled with the correct aspect ratio
178
load_scaled (const gchar *filename, ClutterActor *texture)
180
GdkPixbuf *pixbuf = NULL;
181
GError *error = NULL;
184
pixbuf = gdk_pixbuf_new_from_file_at_scale (filename,
185
CLUTTER_STAGE_WIDTH (),
186
CLUTTER_STAGE_HEIGHT (),
191
g_warning (error->message);
192
g_error_free (error);
195
clutter_texture_set_pixbuf (CLUTTER_TEXTURE (texture), pixbuf, NULL);
197
w = gdk_pixbuf_get_width (pixbuf);
198
h = gdk_pixbuf_get_height (pixbuf);
199
x = (CLUTTER_STAGE_WIDTH ()/2) - (w/2);
200
y = (CLUTTER_STAGE_HEIGHT ()/2) - (h/2);
202
clutter_actor_set_size (texture, w, h);
203
clutter_actor_set_position (texture, x, y);
205
g_object_unref (pixbuf);
209
* Load the image, and then tile it until it covers the entire stage
212
load_wallpaper (const gchar *filename, ClutterActor *texture)
214
GdkPixbuf *pixbuf = NULL;
215
GdkPixbuf *tiled = NULL;
216
GError *error = NULL;
218
gint rows, cols, r, c;
220
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
224
g_warning (error->message);
225
g_error_free (error);
231
w = gdk_pixbuf_get_width (pixbuf);
232
h = gdk_pixbuf_get_height (pixbuf);
234
/* Find the number of rows and columns */
235
if (w < CLUTTER_STAGE_WIDTH ())
236
cols = (gint)ceil (CLUTTER_STAGE_WIDTH () / (gdouble)w);
238
if (h < CLUTTER_STAGE_HEIGHT ())
239
rows = (gint)ceil (CLUTTER_STAGE_HEIGHT () / (gdouble)h);
241
/* Create the new pixbuf */
242
tiled = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, w*cols, h*rows);
244
/* For the number of rows, tile the cols */
245
for (r = 0; r < rows; r++)
247
for (c = 0; c < cols; c++)
249
gdk_pixbuf_composite (pixbuf, tiled, x, y, w, h, x, y, 1, 1,
250
GDK_INTERP_BILINEAR, 255);
257
g_object_unref (pixbuf);
259
clutter_texture_set_pixbuf (CLUTTER_TEXTURE (texture), tiled, NULL);
260
clutter_actor_set_position (texture, 0, 0);
264
* Use the filename and option values to create a background pixbuf, and set
265
* the internal tetxures pixbuf.
266
* We try and get the smallest possible pixbuf to make sure we don't abuse
270
ensure_layout (LauncherBackground *bg)
272
LauncherBackgroundPrivate *priv;
274
g_return_if_fail (LAUNCHER_IS_BACKGROUND (bg));
277
if (priv->filename == NULL || strcmp (priv->filename, "default") == 0)
278
priv->filename = g_strdup (BG_DEFAULT);
280
if (priv->option == NULL)
281
priv->option = g_strdup ("stretched");
283
if (priv->option == NULL || strcmp (priv->option, "none") == 0)
285
load_normal (priv->filename, priv->texture);
287
else if (strcmp (priv->option, "wallpaper") == 0)
289
load_wallpaper (priv->filename, priv->texture);
291
else if (strcmp (priv->option, "centred") == 0)
293
load_centred (priv->filename, priv->texture);
295
else if (strcmp (priv->option, "scaled") == 0)
297
load_scaled (priv->filename, priv->texture);
299
else if (strcmp (priv->option, "zoom") == 0)
301
load_scaled (priv->filename, priv->texture);
305
load_stretched (priv->filename, priv->texture);
308
clutter_actor_queue_redraw (CLUTTER_ACTOR (bg));
312
* The animation function. At the moment, we just to a simple fade in/fade out
315
alpha_func (ClutterBehaviour *behave,
317
LauncherBackground *bg)
319
LauncherBackgroundPrivate *priv;
322
g_return_if_fail (LAUNCHER_IS_BACKGROUND (bg));
325
factor = (gfloat)alpha_value / CLUTTER_ALPHA_MAX_ALPHA;
328
clutter_actor_set_opacity (CLUTTER_ACTOR (bg), 255 - (255*factor));
330
clutter_actor_set_opacity (CLUTTER_ACTOR (bg), 255 * factor);
332
clutter_actor_queue_redraw (CLUTTER_ACTOR (bg));
336
on_timeline_completed (ClutterTimeline *timeline, LauncherBackground *bg)
338
LauncherBackgroundPrivate *priv;
340
g_return_if_fail (LAUNCHER_IS_BACKGROUND (bg));
346
priv->fade_out = FALSE;
347
clutter_timeline_start (priv->timeline);
351
priv->fade_out = TRUE;
355
/* Gconf callbacks */
357
on_bg_filename_changed (GConfClient *client,
360
LauncherBackground *bg)
362
LauncherBackgroundPrivate *priv;
363
GConfValue *value = NULL;
365
g_return_if_fail (LAUNCHER_IS_BACKGROUND (bg));
368
value = gconf_entry_get_value (entry);
370
g_free (priv->filename);
372
priv->filename = g_strdup (gconf_value_get_string (value));
374
clutter_timeline_start (priv->timeline);
378
on_bg_option_changed (GConfClient *client,
381
LauncherBackground *bg)
383
LauncherBackgroundPrivate *priv;
384
GConfValue *value = NULL;
386
g_return_if_fail (LAUNCHER_IS_BACKGROUND (bg));
389
value = gconf_entry_get_value (entry);
391
g_free (priv->option);
393
priv->option = g_strdup (gconf_value_get_string (value));
395
clutter_timeline_start (priv->timeline);
397
/* GObject functions */
399
launcher_background_dispose (GObject *object)
401
G_OBJECT_CLASS (launcher_background_parent_class)->dispose (object);
405
launcher_background_finalize (GObject *background)
407
LauncherBackgroundPrivate *priv;
409
g_return_if_fail (LAUNCHER_IS_BACKGROUND (background));
410
priv = LAUNCHER_BACKGROUND (background)->priv;
413
G_OBJECT_CLASS (launcher_background_parent_class)->finalize (background);
418
launcher_background_class_init (LauncherBackgroundClass *klass)
420
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
422
obj_class->finalize = launcher_background_finalize;
423
obj_class->dispose = launcher_background_dispose;
425
g_type_class_add_private (obj_class, sizeof (LauncherBackgroundPrivate));
429
launcher_background_init (LauncherBackground *background)
431
LauncherBackgroundPrivate *priv;
432
GConfClient *client = gconf_client_get_default ();
434
priv = background->priv = LAUNCHER_BACKGROUND_GET_PRIVATE (background);
435
priv->fade_out = TRUE;
437
priv->texture = clutter_texture_new ();
438
clutter_container_add_actor (CLUTTER_CONTAINER (background), priv->texture);
439
clutter_actor_set_size (priv->texture,
440
CLUTTER_STAGE_WIDTH (),
441
CLUTTER_STAGE_HEIGHT ());
442
clutter_actor_set_position (priv->texture, 0, 0);
443
clutter_actor_show (priv->texture);
445
gconf_client_add_dir (client, BG_PATH, GCONF_CLIENT_PRELOAD_NONE, NULL);
447
priv->filename = g_strdup (gconf_client_get_string (client, BG_FILE, NULL));
448
gconf_client_notify_add (client, BG_FILE,
449
(GConfClientNotifyFunc)on_bg_filename_changed,
450
background, NULL, NULL);
452
priv->option = g_strdup (gconf_client_get_string (client, BG_OPTION, NULL));
453
gconf_client_notify_add (client, BG_OPTION,
454
(GConfClientNotifyFunc)on_bg_option_changed,
455
background, NULL, NULL);
458
priv->timeline = clutter_timeline_new (40, 80);
459
priv->alpha = clutter_alpha_new_full (priv->timeline,
460
clutter_sine_inc_func,
462
priv->behave = launcher_behave_new (priv->alpha,
463
(LauncherBehaveAlphaFunc)alpha_func,
464
(gpointer)background);
466
g_signal_connect (priv->timeline, "completed",
467
G_CALLBACK (on_timeline_completed), (gpointer)background);
469
ensure_layout (background);
473
launcher_background_new (void)
475
ClutterActor *background;
477
background = g_object_new (LAUNCHER_TYPE_BACKGROUND,