From 895ed271b58b245a9ae392dda6d8c7382761f0aa Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Fri, 19 Oct 2001 21:34:36 +0000 Subject: Use EShellAboutBox. (zero_pointer): Removed. * e-shell-view-menu.c (command_about_box): Use EShellAboutBox. (zero_pointer): Removed. * e-shell-about-box.h: New. * e-shell-about-box.c: New. svn path=/trunk/; revision=13804 --- shell/ChangeLog | 8 + shell/Makefile.am | 2 + shell/e-shell-about-box.c | 372 ++++++++++++++++++++++++++++++++++++++++++++++ shell/e-shell-about-box.h | 68 +++++++++ shell/e-shell-view-menu.c | 97 ++++-------- 5 files changed, 483 insertions(+), 64 deletions(-) create mode 100644 shell/e-shell-about-box.c create mode 100644 shell/e-shell-about-box.h diff --git a/shell/ChangeLog b/shell/ChangeLog index 4c3135d9ee..c51a1e9d1b 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,11 @@ +2001-10-19 Ettore Perazzoli + + * e-shell-view-menu.c (command_about_box): Use EShellAboutBox. + (zero_pointer): Removed. + + * e-shell-about-box.h: New. + * e-shell-about-box.c: New. + 2001-10-18 Ettore Perazzoli * Makefile.am (evolution_SOURCES): Ooops. Remove stale files diff --git a/shell/Makefile.am b/shell/Makefile.am index 8829330db2..2a2b847029 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -117,6 +117,8 @@ evolution_SOURCES = \ e-local-storage.h \ e-setup.c \ e-setup.h \ + e-shell-about-box.h \ + e-shell-about-box.c \ e-shell-constants.h \ e-shell-folder-commands.c \ e-shell-folder-commands.h \ diff --git a/shell/e-shell-about-box.c b/shell/e-shell-about-box.c new file mode 100644 index 0000000000..71390c5313 --- /dev/null +++ b/shell/e-shell-about-box.c @@ -0,0 +1,372 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-shell-about-box.c + * + * Copyright (C) 2001 Ximian, 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 +#endif + +#include "e-shell-about-box.h" + +#include + +#include +#include + + +#define PARENT_TYPE gtk_event_box_get_type () +static GtkEventBoxClass *parent_class = NULL; + +static const char *text[] = { + "", + N_("Evolution " VERSION), + N_("Copyright 1999, 2000, 2001 Ximian, Inc."), + "", + N_("Brought to you by"), + "", + "Seth Alves", + "Anders Carlsson", + "Damon Chaplin", + "Clifford R. Conover", + "Anna Dirks", + "Miguel de Icaza", + "Radek Doulik", + "Arturo Espinoza", + "Larry Ewing", + "Nat Friedman", + "Bertrand Guiheneuf", + "Iain Holmes", + "Tuomas Kuosmanen", + "Christopher J. Lahey", + "Jason Leach", + "Matthew Loper", + "Federico Mena", + "Rodrigo Moya", + "Eskil Heyn Olsen", + "Jesse Pavel", + "Ettore Perazzoli", + "JP Rosevear", + "Jeffrey Stedfast", + "Jakub Steiner", + "Russell Steinthal", + "Peter Teichman", + "Chris Toshok", + "Jon Trowbridge", + "Peter Williams", + "Dan Winship", + "Michael Zucchi" +}; +#define NUM_TEXT_LINES (sizeof (text) / sizeof (*text)) + +struct _EShellAboutBoxPrivate { + GdkPixmap *pixmap; + GdkPixmap *text_background_pixmap; + GdkGC *clipped_gc; + int text_y_offset; + int timeout_id; +}; + + +#define ANIMATION_DELAY 40 + +#define WIDTH 400 +#define HEIGHT 200 + +#define TEXT_Y_OFFSET 57 +#define TEXT_X_OFFSET 60 +#define TEXT_WIDTH (WIDTH - 2 * TEXT_X_OFFSET) +#define TEXT_HEIGHT 90 + +#define IMAGE_PATH EVOLUTION_IMAGES "/about-box.png" + + +/* The callback. */ + +static int +timeout_callback (void *data) +{ + EShellAboutBox *about_box; + EShellAboutBoxPrivate *priv; + GdkRectangle redraw_rect; + GtkWidget *widget; + int line_height; + int first_line; + int y; + int i; + + about_box = E_SHELL_ABOUT_BOX (data); + priv = about_box->priv; + + widget = GTK_WIDGET (about_box); + + line_height = widget->style->font->ascent + widget->style->font->descent; + + if (priv->text_y_offset < TEXT_HEIGHT) { + y = TEXT_Y_OFFSET + (TEXT_HEIGHT - priv->text_y_offset); + first_line = 0; + } else { + y = TEXT_Y_OFFSET - ((priv->text_y_offset - TEXT_HEIGHT) % line_height); + first_line = (priv->text_y_offset - TEXT_HEIGHT) / line_height; + } + + gdk_draw_pixmap (priv->pixmap, priv->clipped_gc, priv->text_background_pixmap, + 0, 0, + TEXT_X_OFFSET, TEXT_Y_OFFSET, TEXT_WIDTH, TEXT_HEIGHT); + + for (i = 0; i < TEXT_HEIGHT / line_height + 2; i ++) { + const char *line; + int x; + + if (first_line + i >= NUM_TEXT_LINES) + break; + + if (*text[first_line + i] == '\0') + line = ""; + else + line = _(text[first_line + i]); + + x = TEXT_X_OFFSET + (TEXT_WIDTH - gdk_string_width (widget->style->font, line)) / 2; + + gdk_draw_string (priv->pixmap, widget->style->font, priv->clipped_gc, x, y, line); + + y += line_height; + } + + redraw_rect.x = TEXT_X_OFFSET; + redraw_rect.y = TEXT_Y_OFFSET; + redraw_rect.width = TEXT_WIDTH; + redraw_rect.height = TEXT_HEIGHT; + gtk_widget_draw (widget, &redraw_rect); + + priv->text_y_offset ++; + if (priv->text_y_offset > line_height * NUM_TEXT_LINES + TEXT_HEIGHT) + priv->text_y_offset = 0; + + return TRUE; +} + + +/* GtkObject methods. */ + +static void +impl_destroy (GtkObject *object) +{ + EShellAboutBox *about_box; + EShellAboutBoxPrivate *priv; + + about_box = E_SHELL_ABOUT_BOX (object); + priv = about_box->priv; + + if (priv->pixmap != NULL) { + gdk_pixmap_unref (priv->pixmap); + priv->pixmap = NULL; + } + + if (priv->text_background_pixmap != NULL) { + gdk_pixmap_unref (priv->text_background_pixmap); + priv->text_background_pixmap = NULL; + } + + if (priv->clipped_gc != NULL) { + gdk_gc_unref (priv->clipped_gc); + priv->clipped_gc = NULL; + } + + if (priv->timeout_id != -1) { + g_source_remove (priv->timeout_id); + priv->timeout_id = -1; + } + + g_free (priv); + + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +/* GtkWidget methods. */ + +static void +impl_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + requisition->width = WIDTH; + requisition->height = HEIGHT; +} + +static void +impl_realize (GtkWidget *widget) +{ + EShellAboutBox *about_box; + EShellAboutBoxPrivate *priv; + GdkPixbuf *background_pixbuf; + GdkRectangle clip_rectangle; + + (* GTK_WIDGET_CLASS (parent_class)->realize) (widget); + + about_box = E_SHELL_ABOUT_BOX (widget); + priv = about_box->priv; + + background_pixbuf = gdk_pixbuf_new_from_file (IMAGE_PATH); + g_assert (background_pixbuf != NULL); + g_assert (gdk_pixbuf_get_width (background_pixbuf) == WIDTH); + g_assert (gdk_pixbuf_get_height (background_pixbuf) == HEIGHT); + + g_assert (priv->pixmap == NULL); + priv->pixmap = gdk_pixmap_new (widget->window, WIDTH, HEIGHT, -1); + + gdk_pixbuf_render_to_drawable (background_pixbuf, priv->pixmap, widget->style->black_gc, + 0, 0, 0, 0, WIDTH, HEIGHT, + GDK_RGB_DITHER_MAX, 0, 0); + + g_assert (priv->clipped_gc == NULL); + priv->clipped_gc = gdk_gc_new (widget->window); + gdk_gc_copy (priv->clipped_gc, widget->style->black_gc); + + clip_rectangle.x = TEXT_X_OFFSET; + clip_rectangle.y = TEXT_Y_OFFSET; + clip_rectangle.width = TEXT_WIDTH; + clip_rectangle.height = TEXT_HEIGHT; + gdk_gc_set_clip_rectangle (priv->clipped_gc, & clip_rectangle); + + priv->text_background_pixmap = gdk_pixmap_new (widget->window, clip_rectangle.width, clip_rectangle.height, -1); + gdk_pixbuf_render_to_drawable (background_pixbuf, priv->text_background_pixmap, widget->style->black_gc, + TEXT_X_OFFSET, TEXT_Y_OFFSET, + 0, 0, TEXT_WIDTH, TEXT_HEIGHT, + GDK_RGB_DITHER_MAX, 0, 0); + + g_assert (priv->timeout_id == -1); + priv->timeout_id = g_timeout_add (ANIMATION_DELAY, timeout_callback, about_box); + + gdk_pixbuf_unref (background_pixbuf); +} + +static void +impl_unrealize (GtkWidget *widget) +{ + EShellAboutBox *about_box; + EShellAboutBoxPrivate *priv; + + about_box = E_SHELL_ABOUT_BOX (widget); + priv = about_box->priv; + + (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); + + g_assert (priv->clipped_gc != NULL); + gdk_gc_unref (priv->clipped_gc); + priv->clipped_gc = NULL; + + g_assert (priv->pixmap != NULL); + gdk_pixmap_unref (priv->pixmap); + priv->pixmap = NULL; + + if (priv->timeout_id != -1) { + g_source_remove (priv->timeout_id); + priv->timeout_id = -1; + } +} + +static void +impl_draw (GtkWidget *widget, + GdkRectangle *area) +{ + EShellAboutBox *about_box; + EShellAboutBoxPrivate *priv; + + if (! GTK_WIDGET_DRAWABLE (widget)) + return; + + about_box = E_SHELL_ABOUT_BOX (widget); + priv = about_box->priv; + + gdk_draw_pixmap (widget->window, widget->style->black_gc, priv->pixmap, + area->x, area->y, + area->x, area->y, area->width, area->height); +} + +static int +impl_expose_event (GtkWidget *widget, + GdkEventExpose *event) +{ + if (! GTK_WIDGET_DRAWABLE (widget)) + return FALSE; + + gtk_widget_draw (widget, &event->area); + + return TRUE; +} + + +static void +class_init (GtkObjectClass *object_class) +{ + GtkWidgetClass *widget_class; + + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = impl_destroy; + + widget_class = GTK_WIDGET_CLASS (object_class); + widget_class->size_request = impl_size_request; + widget_class->realize = impl_realize; + widget_class->unrealize = impl_unrealize; + widget_class->draw = impl_draw; + widget_class->expose_event = impl_expose_event; +} + +static void +init (EShellAboutBox *shell_about_box) +{ + EShellAboutBoxPrivate *priv; + + priv = g_new (EShellAboutBoxPrivate, 1); + priv->pixmap = NULL; + priv->text_background_pixmap = NULL; + priv->clipped_gc = NULL; + priv->timeout_id = -1; + priv->text_y_offset = 0; + + shell_about_box->priv = priv; +} + + +void +e_shell_about_box_construct (EShellAboutBox *about_box) +{ + g_return_if_fail (about_box != NULL); + g_return_if_fail (E_IS_SHELL_ABOUT_BOX (about_box)); + + /* Nothing to do here. */ +} + +GtkWidget * +e_shell_about_box_new (void) +{ + EShellAboutBox *about_box; + + about_box = gtk_type_new (e_shell_about_box_get_type ()); + e_shell_about_box_construct (about_box); + + return GTK_WIDGET (about_box); +} + + +E_MAKE_TYPE (e_shell_about_box, "EShellAboutBox", EShellAboutBox, class_init, init, GTK_TYPE_EVENT_BOX) diff --git a/shell/e-shell-about-box.h b/shell/e-shell-about-box.h new file mode 100644 index 0000000000..4ec80b71e8 --- /dev/null +++ b/shell/e-shell-about-box.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-shell-about-box.h + * + * Copyright (C) 2001 Ximian, 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_SHELL_ABOUT_BOX_H_ +#define _E_SHELL_ABOUT_BOX_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_SHELL_ABOUT_BOX (e_shell_about_box_get_type ()) +#define E_SHELL_ABOUT_BOX(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SHELL_ABOUT_BOX, EShellAboutBox)) +#define E_SHELL_ABOUT_BOX_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_ABOUT_BOX, EShellAboutBoxClass)) +#define E_IS_SHELL_ABOUT_BOX(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SHELL_ABOUT_BOX)) +#define E_IS_SHELL_ABOUT_BOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_ABOUT_BOX)) + + +typedef struct _EShellAboutBox EShellAboutBox; +typedef struct _EShellAboutBoxPrivate EShellAboutBoxPrivate; +typedef struct _EShellAboutBoxClass EShellAboutBoxClass; + +struct _EShellAboutBox { + GtkEventBox parent; + + EShellAboutBoxPrivate *priv; +}; + +struct _EShellAboutBoxClass { + GtkEventBoxClass parent_class; +}; + + +GtkType e_shell_about_box_get_type (void); +void e_shell_about_box_construct (EShellAboutBox *about_box); +GtkWidget *e_shell_about_box_new (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _E_SHELL_ABOUT_BOX_H_ */ diff --git a/shell/e-shell-view-menu.c b/shell/e-shell-view-menu.c index ba4db225b3..e32a1a9d92 100644 --- a/shell/e-shell-view-menu.c +++ b/shell/e-shell-view-menu.c @@ -54,47 +54,12 @@ #include "e-shell-view-menu.h" #include "e-shell-importer.h" +#include "e-shell-about-box.h" #include "e-shell-folder-commands.h" #include "evolution-shell-component-utils.h" - -const char *authors[] = { - "Seth Alves", - "Anders Carlsson", - "Damon Chaplin", - "Clifford R. Conover", - "Anna Dirks", - "Miguel de Icaza", - "Radek Doulik", - "Arturo Espinoza", - "Larry Ewing", - "Nat Friedman", - "Bertrand Guiheneuf", - "Iain Holmes", - "Tuomas Kuosmanen", - "Christopher J. Lahey", - "Jason Leach", - "Matthew Loper", - "Federico Mena", - "Rodrigo Moya", - "Eskil Heyn Olsen", - "Jesse Pavel", - "Ettore Perazzoli", - "JP Rosevear", - "Jeffrey Stedfast", - "Jakub Steiner", - "Russell Steinthal", - "Peter Teichman", - "Chris Toshok", - "Jon Trowbridge", - "Peter Williams", - "Dan Winship", - "Michael Zucchi", - NULL -}; - /* Utility functions. */ @@ -209,10 +174,19 @@ command_submit_bug (BonoboUIComponent *uih, gnome_error_dialog (_("Bug buddy could not be run.")); } -static void -zero_pointer(GtkObject *object, void **pointer) +static int +about_box_event_callback (GtkWidget *widget, + GdkEvent *event, + void *data) { - *pointer = NULL; + GtkWidget **widget_pointer; + + widget_pointer = (GtkWidget **) data; + + gtk_widget_destroy (GTK_WIDGET (*widget_pointer)); + *widget_pointer = NULL; + + return TRUE; } static void @@ -220,32 +194,27 @@ command_about_box (BonoboUIComponent *uih, void *data, const char *path) { - static GtkWidget *about_box = NULL; - - if (about_box) { - gdk_window_raise(GTK_WIDGET(about_box)->window); - } else { - char *version; - - if (SUB_VERSION[0] == '\0') - version = g_strdup (VERSION); - else - version = g_strdup_printf ("%s [%s]", VERSION, SUB_VERSION); - - about_box = gnome_about_new(_("Ximian Evolution"), - version, - _("Copyright 1999, 2000, 2001 Ximian, Inc."), - authors, - _("Ximian Evolution is a suite of groupware applications\n" - "for mail, calendaring, and contact management\n" - "within the GNOME desktop environment."), - NULL); - gtk_signal_connect(GTK_OBJECT(about_box), "destroy", - GTK_SIGNAL_FUNC (zero_pointer), &about_box); - gtk_widget_show(about_box); - - g_free (version); + static GtkWidget *about_box_window = NULL; + GtkWidget *about_box; + + if (about_box_window != NULL) { + gdk_window_raise (about_box_window->window); + return; } + + about_box = e_shell_about_box_new (); + gtk_widget_show (about_box); + + about_box_window = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_signal_connect (GTK_OBJECT (about_box_window), "button_press_event", + GTK_SIGNAL_FUNC (about_box_event_callback), &about_box_window); + gtk_signal_connect (GTK_OBJECT (about_box_window), "delete_event", + GTK_SIGNAL_FUNC (about_box_event_callback), &about_box_window); + + gtk_window_set_transient_for (GTK_WINDOW (about_box_window), GTK_WINDOW (data)); + gtk_window_set_title (GTK_WINDOW (about_box_window), _("About Ximian Evolution")); + gtk_container_add (GTK_CONTAINER (about_box_window), about_box); + gtk_widget_show (about_box_window); } static void -- cgit v1.2.3