diff options
author | Ettore Perazzoli <ettore@src.gnome.org> | 2000-10-15 00:18:52 +0800 |
---|---|---|
committer | Ettore Perazzoli <ettore@src.gnome.org> | 2000-10-15 00:18:52 +0800 |
commit | c9a857200fb492f78f416f3afaf99e48a2960144 (patch) | |
tree | 9cca8a36d881644752570d946bcb1ffa371fa565 /shell/e-splash.c | |
parent | fdeef7a7fb2f01cb3ead55ad74f032419123b1f9 (diff) | |
download | gsoc2013-evolution-c9a857200fb492f78f416f3afaf99e48a2960144.tar.gz gsoc2013-evolution-c9a857200fb492f78f416f3afaf99e48a2960144.tar.zst gsoc2013-evolution-c9a857200fb492f78f416f3afaf99e48a2960144.zip |
31337 splash screen for the shell's startup sequence.
svn path=/trunk/; revision=5912
Diffstat (limited to 'shell/e-splash.c')
-rw-r--r-- | shell/e-splash.c | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/shell/e-splash.c b/shell/e-splash.c new file mode 100644 index 0000000000..535eafa2ed --- /dev/null +++ b/shell/e-splash.c @@ -0,0 +1,395 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-splash.c + * + * Copyright (C) 2000 Helix Code, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gnome.h> +#include <gdk-pixbuf/gnome-canvas-pixbuf.h> +#include <gal/util/e-util.h> + +#include "e-splash.h" + + +#define PARENT_TYPE gtk_window_get_type () +static GtkWindowClass *parent_class = NULL; + +struct _Icon { + GdkPixbuf *dark_pixbuf; + GdkPixbuf *light_pixbuf; + GnomeCanvasItem *canvas_item; +}; +typedef struct _Icon Icon; + +struct _ESplashPrivate { + GnomeCanvas *canvas; + GdkPixbuf *splash_image_pixbuf; + + GList *icons; /* (Icon *) */ + int num_icons; + + int layout_idle_id; +}; + + +/* Layout constants. These need to be changed if the splash changes. */ + +#define ICON_Y 256 +#define ICON_SIZE 32 + + +/* Icon management. */ + +static GdkPixbuf * +create_darkened_pixbuf (GdkPixbuf *pixbuf) +{ + GdkPixbuf *new; + unsigned char *rowp; + int width, height; + int rowstride; + int i, j; + + new = gdk_pixbuf_copy (pixbuf); + if (! gdk_pixbuf_get_has_alpha (new)) + return new; + + width = gdk_pixbuf_get_width (new); + height = gdk_pixbuf_get_height (new); + rowstride = gdk_pixbuf_get_rowstride (new); + + rowp = gdk_pixbuf_get_pixels (new); + for (i = 0; i < height; i ++) { + unsigned char *p; + + p = rowp; + for (j = 0; j < width; j++) { + p[3] *= .25; + p += 4; + } + + rowp += rowstride; + } + + return new; +} + +static Icon * +icon_new (ESplash *splash, + GdkPixbuf *image_pixbuf) +{ + ESplashPrivate *priv; + GnomeCanvasGroup *canvas_root_group; + Icon *icon; + + priv = splash->priv; + + icon = g_new (Icon, 1); + + icon->light_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, ICON_SIZE, ICON_SIZE); + gdk_pixbuf_scale (image_pixbuf, icon->light_pixbuf, + 0, 0, + ICON_SIZE, ICON_SIZE, + 0, 0, + (double) ICON_SIZE / gdk_pixbuf_get_width (image_pixbuf), + (double) ICON_SIZE / gdk_pixbuf_get_height (image_pixbuf), + GDK_INTERP_HYPER); + + icon->dark_pixbuf = create_darkened_pixbuf (icon->light_pixbuf); + + /* Set up the canvas item to point to the dark pixbuf initially. */ + + canvas_root_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (priv->canvas)->root); + + icon->canvas_item = gnome_canvas_item_new (canvas_root_group, + GNOME_TYPE_CANVAS_PIXBUF, + "pixbuf", icon->dark_pixbuf, + NULL); + + return icon; +} + +static void +icon_free (Icon *icon) +{ + gdk_pixbuf_unref (icon->dark_pixbuf); + gdk_pixbuf_unref (icon->light_pixbuf); + gtk_object_unref (GTK_OBJECT (icon->canvas_item)); + + g_free (icon); +} + + +/* Icon layout management. */ + +static void +layout_icons (ESplash *splash) +{ + ESplashPrivate *priv; + GList *p; + double x_step; + double x, y; + + priv = splash->priv; + + x_step = ((double) gdk_pixbuf_get_width (priv->splash_image_pixbuf)) / priv->num_icons; + + x = (x_step - ICON_SIZE) / 2.0; + y = ICON_Y; + + for (p = priv->icons; p != NULL; p = p->next) { + Icon *icon; + + icon = (Icon *) p->data; + + gtk_object_set (GTK_OBJECT (icon->canvas_item), + "x", (double) x, + "y", (double) ICON_Y, + NULL); + + x += x_step; + } +} + +static int +layout_idle_cb (void *data) +{ + ESplash *splash; + ESplashPrivate *priv; + + splash = E_SPLASH (data); + priv = splash->priv; + + layout_icons (splash); + + priv->layout_idle_id = 0; + + return FALSE; +} + +static void +schedule_relayout (ESplash *splash) +{ + ESplashPrivate *priv; + + priv = splash->priv; + + if (priv->layout_idle_id != 0) + return; + + priv->layout_idle_id = gtk_idle_add (layout_idle_cb, splash); +} + + +/* GtkObject methods. */ + +static void +impl_destroy (GtkObject *object) +{ + ESplash *splash; + ESplashPrivate *priv; + GList *p; + + splash = E_SPLASH (object); + priv = splash->priv; + + if (priv->splash_image_pixbuf != NULL) + gdk_pixbuf_unref (priv->splash_image_pixbuf); + + for (p = priv->icons; p != NULL; p = p->next) { + Icon *icon; + + icon = (Icon *) p->data; + icon_free (icon); + } + + g_list_free (priv->icons); + + if (priv->layout_idle_id != 0) + gtk_idle_remove (priv->layout_idle_id); + + g_free (priv); +} + + +static void +class_init (ESplashClass *klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (klass); + object_class->destroy = impl_destroy; + + parent_class = gtk_type_class (gtk_window_get_type ()); +} + +static void +init (ESplash *splash) +{ + ESplashPrivate *priv; + + priv = g_new (ESplashPrivate, 1); + priv->canvas = NULL; + priv->splash_image_pixbuf = NULL; + priv->icons = NULL; + priv->num_icons = 0; + priv->layout_idle_id = 0; + + splash->priv = priv; +} + + +/** + * e_splash_construct: + * @splash: A pointer to an ESplash widget + * @splash_image_pixbuf: The pixbuf for the image to appear in the splash dialog + * + * Construct @splash with @splash_image_pixbuf as the splash image. + **/ +void +e_splash_construct (ESplash *splash, + GdkPixbuf *splash_image_pixbuf) +{ + ESplashPrivate *priv; + GtkWidget *canvas; + int image_width, image_height; + + g_return_if_fail (splash != NULL); + g_return_if_fail (E_IS_SPLASH (splash)); + g_return_if_fail (splash_image_pixbuf != NULL); + + priv = splash->priv; + + priv->splash_image_pixbuf = gdk_pixbuf_ref (splash_image_pixbuf); + + canvas = gnome_canvas_new_aa (); + priv->canvas = GNOME_CANVAS (canvas); + + image_width = gdk_pixbuf_get_width (splash_image_pixbuf); + image_height = gdk_pixbuf_get_height (splash_image_pixbuf); + + gtk_widget_set_usize (canvas, image_width, image_height); + gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), 0, 0, image_width, image_height); + gtk_widget_show (canvas); + + gtk_container_add (GTK_CONTAINER (splash), canvas); + + gnome_canvas_item_new (GNOME_CANVAS_GROUP (priv->canvas->root), + GNOME_TYPE_CANVAS_PIXBUF, + "pixbuf", splash_image_pixbuf, + NULL); + + gtk_object_set (GTK_OBJECT (splash), "type", GTK_WINDOW_POPUP, NULL); + gtk_window_set_position (GTK_WINDOW (splash), GTK_WIN_POS_CENTER); + gtk_window_set_policy (GTK_WINDOW (splash), FALSE, FALSE, FALSE); + gtk_window_set_default_size (GTK_WINDOW (splash), image_width, image_height); +} + +/** + * e_splash_new: + * + * Create a new ESplash widget. + * + * Return value: A pointer to the newly created ESplash widget. + **/ +GtkWidget * +e_splash_new (void) +{ + ESplash *new; + GdkPixbuf *splash_image_pixbuf; + + splash_image_pixbuf = gdk_pixbuf_new_from_file (EVOLUTION_IMAGES "/splash.png"); + g_return_val_if_fail (splash_image_pixbuf != NULL, NULL); + + new = gtk_type_new (e_splash_get_type ()); + e_splash_construct (new, splash_image_pixbuf); + + gdk_pixbuf_unref (splash_image_pixbuf); + + return GTK_WIDGET (new); +} + + +/** + * e_splash_add_icon: + * @splash: A pointer to an ESplash widget + * @icon_pixbuf: Pixbuf for the icon to be added + * + * Add @icon_pixbuf to the @splash. + * + * Return value: The total number of icons in the splash after the new icon has + * been added. + **/ +int +e_splash_add_icon (ESplash *splash, + GdkPixbuf *icon_pixbuf) +{ + ESplashPrivate *priv; + Icon *icon; + + g_return_val_if_fail (splash != NULL, 0); + g_return_val_if_fail (E_IS_SPLASH (splash), 0); + g_return_val_if_fail (icon_pixbuf != NULL, 0); + + priv = splash->priv; + + icon = icon_new (splash, icon_pixbuf); + priv->icons = g_list_append (priv->icons, icon); + + priv->num_icons ++; + + schedule_relayout (splash); + + return priv->num_icons; +} + +/** + * e_splash_set_icon_highlight: + * @splash: A pointer to an ESplash widget + * @num: Number of the icon whose highlight state must be changed + * @highlight: Whether the icon must be highlit or not + * + * Change the highlight state of the @num-th icon. + **/ +void +e_splash_set_icon_highlight (ESplash *splash, + int num, + gboolean highlight) +{ + ESplashPrivate *priv; + Icon *icon; + + g_return_if_fail (splash != NULL); + g_return_if_fail (E_IS_SPLASH (splash)); + + priv = splash->priv; + + icon = (Icon *) g_list_nth (priv->icons, num)->data; + + gtk_object_set (GTK_OBJECT (icon->canvas_item), + "pixbuf", highlight ? icon->light_pixbuf : icon->dark_pixbuf, + NULL); +} + + +E_MAKE_TYPE (e_splash, "ESplash", ESplash, class_init, init, PARENT_TYPE) |