1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* e-splash.c
3  *
4  * Copyright (C) 2000, 2001 Ximian, Inc.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * Author: Ettore Perazzoli
22  */
23 
24 /**
25  * SECTION:e-splash
26  * @short_description: Splash screen
27  * @see_also:
28  * @stability: Unstable
29  * @include: libanjuta/e-splash.h
30  *
31  */
32 
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36 
37 #include <gtk/gtk.h>
38 
39 #include "e-splash.h"
40 
41 struct _ESplashPrivate {
42 	GdkPixbuf *splash_image_pixbuf;
43 	GdkPixbuf *icon_pixbuf;
44 	gchar *title;
45 	gint progressbar_position;
46 	gfloat progress_percentage;
47 };
48 
G_DEFINE_TYPE(ESplash,e_splash,GTK_TYPE_WINDOW)49 G_DEFINE_TYPE(ESplash, e_splash, GTK_TYPE_WINDOW)
50 
51 /* Layout constants.  These need to be changed if the splash changes.  */
52 
53 #define ICON_Y    80
54 #define ICON_X    32
55 #define ICON_SIZE 48
56 #define PROGRESS_SIZE 10
57 
58 /* GtkObject methods.  */
59 
60 static void
61 impl_destroy (GtkWidget *object)
62 {
63 	ESplash *splash;
64 	ESplashPrivate *priv;
65 
66 	splash = E_SPLASH (object);
67 	priv = splash->priv;
68 
69 	if (priv->splash_image_pixbuf != NULL)
70 		g_object_unref (priv->splash_image_pixbuf);
71 	if (priv->icon_pixbuf != NULL)
72 		g_object_unref (priv->icon_pixbuf);
73 	g_free (priv->title);
74 
75 	g_free (priv);
76 }
77 
78 static void
e_splash_finalize(GObject * obj)79 e_splash_finalize (GObject *obj)
80 {
81 	G_OBJECT_CLASS (e_splash_parent_class)->finalize (obj);
82 }
83 
84 static void
e_splash_class_init(ESplashClass * klass)85 e_splash_class_init (ESplashClass *klass)
86 {
87 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
88 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
89 
90 	widget_class->destroy = impl_destroy;
91 
92 	object_class->finalize = e_splash_finalize;
93 }
94 
95 static void
e_splash_init(ESplash * splash)96 e_splash_init (ESplash *splash)
97 {
98 	ESplashPrivate *priv;
99 
100 	priv = g_new0 (ESplashPrivate, 1);
101 	priv->progressbar_position = ICON_Y;
102 	splash->priv = priv;
103 }
104 
105 static gboolean
button_press_event(GtkWidget * widget,GdkEventButton * event,gpointer data)106 button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
107 {
108 	ESplash *splash = (ESplash *) data;
109 
110 	gtk_widget_hide (GTK_WIDGET (splash));
111 
112 	return TRUE;
113 }
114 
115 static gboolean
on_draw_cb(GtkWidget * widget,cairo_t * cr,ESplash * splash)116 on_draw_cb (GtkWidget *widget, cairo_t *cr,
117             ESplash *splash)
118 {
119 	ESplashPrivate *priv;
120 	gint inc_width;
121 
122 	priv = splash->priv;
123 
124 	/* draw the background pixbuf */
125 	cairo_save (cr);
126 	gdk_cairo_set_source_pixbuf (cr, priv->splash_image_pixbuf, 0, 0);
127 
128 	cairo_paint (cr);
129 	cairo_restore (cr);
130 
131 	/* draw the plugin icon */
132 	if (priv->icon_pixbuf)
133 	{
134 		cairo_save (cr);
135 		gdk_cairo_set_source_pixbuf (cr, priv->icon_pixbuf, ICON_X, ICON_Y);
136 
137 		cairo_paint (cr);
138 		cairo_restore (cr);
139 	}
140 
141 	/* draw the plugin text */
142 	if (priv->title)
143 	{
144 		PangoContext *pc;
145 		PangoLayout *layout;
146 		gint layout_height;
147 
148 		cairo_save (cr);
149 		/* Aluminium 6 Tango */
150 		cairo_set_source_rgba (cr, 46/255, 52/255, 54/255, 1.0);
151 
152 		pc = gtk_widget_get_pango_context (widget);
153 		layout = pango_layout_new (pc);
154 		pango_layout_set_markup (layout, priv->title, -1);
155 		pango_layout_get_size (layout, NULL, &layout_height);
156 
157 		cairo_move_to (cr, ICON_X + ICON_SIZE + 25,
158 		               ICON_Y + ICON_SIZE - PANGO_PIXELS (layout_height) - 5);
159 
160 		pango_cairo_show_layout (cr, layout);
161 
162 		g_object_unref (layout);
163 		cairo_restore (cr);
164 	}
165 
166 	/* draw the progress bar */
167 	inc_width = gdk_pixbuf_get_width (priv->splash_image_pixbuf);
168 	inc_width -= (ICON_X + ICON_SIZE + 35);
169 
170 	/* Aluminium 6 (Tango) */
171 	cairo_set_source_rgba (cr, 46/255, 52/255, 54/255, 1.0);
172 	cairo_rectangle (cr, ICON_X + ICON_SIZE + 25, ICON_Y + ICON_SIZE - 5,
173 	                 (priv->progress_percentage * inc_width), PROGRESS_SIZE);
174 
175 	cairo_fill (cr);
176 
177 	return TRUE;
178 }
179 
180 
181 /**
182  * e_splash_construct:
183  * @splash: A pointer to an ESplash widget
184  * @splash_image_pixbuf: The pixbuf for the image to appear in the splash dialog
185  *
186  * Construct @splash with @splash_image_pixbuf as the splash image.
187  **/
188 void
e_splash_construct(ESplash * splash,GdkPixbuf * splash_image_pixbuf,gint progressbar_position)189 e_splash_construct (ESplash *splash,
190                     GdkPixbuf *splash_image_pixbuf,
191                     gint progressbar_position)
192 {
193 	ESplashPrivate *priv;
194 	int image_width, image_height;
195 
196 	g_return_if_fail (splash != NULL);
197 	g_return_if_fail (E_IS_SPLASH (splash));
198 	g_return_if_fail (splash_image_pixbuf != NULL);
199 
200 	priv = splash->priv;
201 	priv->progressbar_position = progressbar_position;
202 	priv->splash_image_pixbuf = g_object_ref (splash_image_pixbuf);
203 
204 	image_width = gdk_pixbuf_get_width (splash_image_pixbuf);
205 	image_height = gdk_pixbuf_get_height (splash_image_pixbuf);
206 
207 	gtk_widget_set_size_request (GTK_WIDGET (splash), image_width, image_height);
208 
209 	g_signal_connect (G_OBJECT (splash), "draw",
210 	                  G_CALLBACK (on_draw_cb), splash);
211 	g_signal_connect (G_OBJECT (splash), "button-press-event",
212 			  G_CALLBACK (button_press_event), splash);
213 
214 	gtk_window_set_decorated(GTK_WINDOW(splash), FALSE);
215 	gtk_window_set_position (GTK_WINDOW (splash), GTK_WIN_POS_CENTER);
216 	gtk_window_set_resizable (GTK_WINDOW (splash), FALSE);
217 	gtk_window_set_default_size (GTK_WINDOW (splash), image_width, image_height);
218 	gtk_window_set_title (GTK_WINDOW (splash), PACKAGE_NAME);
219 
220 }
221 
222 /**
223  * e_splash_new:
224  * @image_file: Splash image file
225  *
226  * Create a new ESplash widget.
227  *
228  * Return value: A pointer to the newly created ESplash widget.
229  **/
230 GtkWidget *
e_splash_new(const char * image_file,gint progressbar_position)231 e_splash_new (const char *image_file, gint progressbar_position)
232 {
233 	ESplash *splash;
234 	GdkPixbuf *splash_image_pixbuf;
235 
236 	splash_image_pixbuf = gdk_pixbuf_new_from_file (image_file, NULL);
237 	g_return_val_if_fail (splash_image_pixbuf != NULL, NULL);
238 
239 	splash = g_object_new (E_TYPE_SPLASH, "type", GTK_WINDOW_TOPLEVEL, NULL);
240 	e_splash_construct (splash, splash_image_pixbuf, progressbar_position);
241 
242 	return GTK_WIDGET (splash);
243 }
244 
245 /**
246  * e_splash_set:
247  * @splash: A pointer to an ESplash widget
248  * @icon_pixbuf: Pixbuf for the icon to be added
249  * @title: Title.
250  * @desc: Description.
251  * @progress_percentage: percentage of progress.
252  *
253  * Set the current progress/icon/text.
254  **/
255 void
e_splash_set(ESplash * splash,GdkPixbuf * icon_pixbuf,const gchar * title,const gchar * desc,gfloat progress_percentage)256 e_splash_set  (ESplash *splash, GdkPixbuf *icon_pixbuf,
257                const gchar *title, const gchar *desc,
258                gfloat progress_percentage)
259 {
260 	ESplashPrivate *priv;
261 
262 	g_return_if_fail (splash != NULL);
263 	g_return_if_fail (E_IS_SPLASH (splash));
264 
265 	priv = splash->priv;
266 
267 	if (icon_pixbuf)
268 	{
269 		GdkPixbuf *scaled_pixbuf;
270 
271 		scaled_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,
272 		                                8, ICON_SIZE, ICON_SIZE);
273 		gdk_pixbuf_scale (icon_pixbuf, scaled_pixbuf,
274 		                  0, 0,
275 		                  ICON_SIZE, ICON_SIZE,
276 		                  0, 0,
277 		                  (double) ICON_SIZE / gdk_pixbuf_get_width (icon_pixbuf),
278 		                  (double) ICON_SIZE / gdk_pixbuf_get_height (icon_pixbuf),
279 		                  GDK_INTERP_HYPER);
280 		if (priv->icon_pixbuf)
281 			g_object_unref (priv->icon_pixbuf);
282 		priv->icon_pixbuf = scaled_pixbuf;
283 	}
284 
285 	if (title)
286 	{
287 		g_free (priv->title);
288 		priv->title = g_strdup (title);
289 	}
290 
291 	priv->progress_percentage = progress_percentage;
292 
293 	gtk_widget_queue_draw (GTK_WIDGET (splash));
294 }
295