diff options
-rw-r--r-- | shell/ChangeLog | 17 | ||||
-rw-r--r-- | shell/Makefile.am | 2 | ||||
-rw-r--r-- | shell/e-shell.c | 64 | ||||
-rw-r--r-- | shell/e-splash.c | 395 | ||||
-rw-r--r-- | shell/e-splash.h | 76 |
5 files changed, 549 insertions, 5 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index a2e7826966..79776b3a3f 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,6 +1,17 @@ -2000-10-13 Anna Marie Dirks <anna@helixcode.com> - *e-shell-folder-creation-dialog.glade: Added focus to the folder-name - text entry. +2000-10-14 Ettore Perazzoli <ettore@helixcode.com> + + * e-shell.c (e_shell_construct): Display a splash screen. + (setup_components): New arg @splash, pointer to an ESplash. + Display the icons of the components in the splash and highlight + them as the components are activated. + + * e-splash.c: New. + * e-splash.h: New. + +2000-10-13 Anna Marie Dirks <anna@helixcode.com> + + * e-shell-folder-creation-dialog.glade: Added focus to the + folder-name text entry. 2000-10-11 Christopher James Lahey <clahey@helixcode.com> diff --git a/shell/Makefile.am b/shell/Makefile.am index aa3037bced..d8ef0ec80e 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -111,6 +111,8 @@ evolution_SOURCES = \ e-shortcuts-view.h \ e-shortcuts.c \ e-shortcuts.h \ + e-splash.c \ + e-splash.h \ e-storage-set-view.c \ e-storage-set-view.h \ e-storage-set.c \ diff --git a/shell/e-shell.c b/shell/e-shell.c index a7c1a2d2c0..08581c9ea4 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -42,6 +42,9 @@ #include "e-shell-view.h" #include "e-shortcuts.h" #include "e-storage-set.h" +#include "e-splash.h" + +#include "evolution-storage-set-view-factory.h" #include "e-shell.h" @@ -343,8 +346,31 @@ setup_local_storage (EShell *shell) /* Initialization of the components. */ +static char * +get_icon_path_for_component_info (const OAF_ServerInfo *info) +{ + OAF_Property *property; + const char *shell_component_icon_value; + + /* FIXME: liboaf is not const-safe. */ + property = oaf_server_info_prop_find ((OAF_ServerInfo *) info, + "evolution:shell-component-icon"); + + if (property == NULL || property->v._d != OAF_P_STRING) + return gnome_pixmap_file ("gnome-question.png"); + + shell_component_icon_value = property->v._u.value_string; + + if (g_path_is_absolute (shell_component_icon_value)) + return g_strdup (shell_component_icon_value); + + else + return g_concat_dir_and_file (EVOLUTION_IMAGES, shell_component_icon_value); +} + static void -setup_components (EShell *shell) +setup_components (EShell *shell, + ESplash *splash) { EShellPrivate *priv; OAF_ServerInfoList *info_list; @@ -363,6 +389,25 @@ setup_components (EShell *shell) for (i = 0; i < info_list->_length; i++) { const OAF_ServerInfo *info; + GdkPixbuf *icon_pixbuf; + char *icon_path; + + info = info_list->_buffer + i; + + icon_path = get_icon_path_for_component_info (info); + + icon_pixbuf = gdk_pixbuf_new_from_file (icon_path); + e_splash_add_icon (splash, icon_pixbuf); + gdk_pixbuf_unref (icon_pixbuf); + + g_free (icon_path); + } + + while (gtk_events_pending ()) + gtk_main_iteration (); + + for (i = 0; i < info_list->_length; i++) { + const OAF_ServerInfo *info; info = info_list->_buffer + i; @@ -370,6 +415,11 @@ setup_components (EShell *shell) g_warning ("Cannot activate Evolution component -- %s", info->iid); else g_print ("Evolution component activated successfully -- %s\n", info->iid); + + e_splash_set_icon_highlight (splash, i, TRUE); + + while (gtk_events_pending ()) + gtk_main_iteration (); } if (info_list->_length == 0) @@ -568,6 +618,7 @@ e_shell_construct (EShell *shell, Evolution_Shell corba_object, const char *local_directory) { + GtkWidget *splash; EShellPrivate *priv; gchar *shortcut_path; @@ -577,6 +628,12 @@ e_shell_construct (EShell *shell, g_return_if_fail (local_directory != NULL); g_return_if_fail (g_path_is_absolute (local_directory)); + splash = e_splash_new (); + gtk_widget_show (splash); + + while (gtk_events_pending ()) + gtk_main_iteration (); + bonobo_object_construct (BONOBO_OBJECT (shell), corba_object); priv = shell->priv; @@ -593,7 +650,7 @@ e_shell_construct (EShell *shell, if (! setup_corba_storages (shell)) return; - setup_components (shell); + setup_components (shell, E_SPLASH (splash)); /* The local storage depends on the component registry. */ setup_local_storage (shell); @@ -612,6 +669,9 @@ e_shell_construct (EShell *shell, gtk_object_ref (GTK_OBJECT (priv->shortcuts)); g_free (shortcut_path); + + sleep (2); + gtk_widget_destroy (splash); } /** 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) diff --git a/shell/e-splash.h b/shell/e-splash.h new file mode 100644 index 0000000000..4eb58d7692 --- /dev/null +++ b/shell/e-splash.h @@ -0,0 +1,76 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-splash.h + * + * 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 + */ + +#ifndef _E_SPLASH_H_ +#define _E_SPLASH_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gtk/gtkwindow.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_SPLASH (e_splash_get_type ()) +#define E_SPLASH(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SPLASH, ESplash)) +#define E_SPLASH_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SPLASH, ESplashClass)) +#define E_IS_SPLASH(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SPLASH)) +#define E_IS_SPLASH_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_SPLASH)) + + +typedef struct _ESplash ESplash; +typedef struct _ESplashPrivate ESplashPrivate; +typedef struct _ESplashClass ESplashClass; + +struct _ESplash { + GtkWindow parent; + + ESplashPrivate *priv; +}; + +struct _ESplashClass { + GtkWindowClass parent_class; +}; + + +GtkType e_splash_get_type (void); +void e_splash_construct (ESplash *splash, + GdkPixbuf *splash_image); +GtkWidget *e_splash_new (void); + +int e_splash_add_icon (ESplash *splash, + GdkPixbuf *icon); +void e_splash_set_icon_highlight (ESplash *splash, + int num, + gboolean highlight); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _E_SPLASH_H_ */ |