]> www.fi.muni.cz Git - evince.git/blob - libview/ev-loading-window.c
Fix introspection build for library renames
[evince.git] / libview / ev-loading-window.c
1 /* ev-loading-window.c
2  *  this file is part of evince, a gnome document viewer
3  *
4  * Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
5  *
6  * Evince is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Evince is distributed in the hope that it will be useful, but
12  * 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 License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24 #include <glib/gi18n.h>
25 #include "ev-loading-window.h"
26
27 enum {
28         PROP_0,
29         PROP_PARENT
30 };
31
32 struct _EvLoadingWindow {
33         GtkWindow  base_instance;
34
35         GtkWindow *parent;
36
37         gint       x;
38         gint       y;
39         gint       width;
40         gint       height;
41 };
42
43 struct _EvLoadingWindowClass {
44         GtkWindowClass base_class;
45 };
46
47 G_DEFINE_TYPE (EvLoadingWindow, ev_loading_window, GTK_TYPE_WINDOW)
48
49 static void
50 ev_loading_window_set_property (GObject      *object,
51                                 guint         prop_id,
52                                 const GValue *value,
53                                 GParamSpec   *pspec)
54 {
55         EvLoadingWindow *window = EV_LOADING_WINDOW (object);
56
57         switch (prop_id) {
58         case PROP_PARENT:
59                 window->parent = g_value_get_object (value);
60                 break;
61         default:
62                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
63         }
64 }
65
66 static void
67 ev_loading_window_init (EvLoadingWindow *window)
68 {
69         GtkWindow   *gtk_window = GTK_WINDOW (window);
70         GtkWidget   *widget = GTK_WIDGET (window);
71         GtkWidget   *hbox;
72         GtkWidget   *spinner;
73         GtkWidget   *label;
74         GtkStyle    *style;
75         GdkColor    fg, bg;
76         const gchar *loading_text = _("Loading…");
77         const gchar *fg_color_name = "info_fg_color";
78         const gchar *bg_color_name = "info_bg_color";
79
80         hbox = gtk_hbox_new (FALSE, 12);
81
82         spinner = gtk_spinner_new ();
83         gtk_spinner_start (GTK_SPINNER (spinner));
84         gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0);
85         gtk_widget_show (spinner);
86
87         label = gtk_label_new (loading_text);
88         gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
89         gtk_widget_show (label);
90
91         gtk_container_add (GTK_CONTAINER (window), hbox);
92         gtk_widget_show (hbox);
93
94         gtk_widget_set_app_paintable (widget, TRUE);
95
96         gtk_container_set_border_width (GTK_CONTAINER (window), 10);
97
98         gtk_window_set_type_hint (gtk_window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);
99         gtk_window_set_accept_focus (gtk_window, FALSE);
100         gtk_window_set_decorated (gtk_window, FALSE);
101         gtk_window_set_resizable (gtk_window, FALSE);
102
103         style = gtk_widget_get_style (widget);
104         if (!gtk_style_lookup_color (style, fg_color_name, &fg) ||
105             !gtk_style_lookup_color (style, bg_color_name, &bg)) {
106                 fg.pixel = 0;
107                 fg.red = 0xb800;
108                 fg.green = 0xad00;
109                 fg.blue = 0x9d00;
110
111                 bg.pixel = 0;
112                 bg.red = 0xff00;
113                 bg.green = 0xff00;
114                 bg.blue = 0xbf00;
115         }
116
117         if (!gdk_color_equal (&bg, &style->bg[GTK_STATE_NORMAL]))
118                 gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &bg);
119         if (!gdk_color_equal (&fg, &style->fg[GTK_STATE_NORMAL]))
120                 gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, &fg);
121 }
122
123 static GObject *
124 ev_loading_window_constructor (GType                  type,
125                                guint                  n_construct_properties,
126                                GObjectConstructParam *construct_params)
127 {
128         GObject         *object;
129         EvLoadingWindow *window;
130         GtkWindow       *gtk_window;
131
132         object = G_OBJECT_CLASS (ev_loading_window_parent_class)->constructor (type,
133                                                                                n_construct_properties,
134                                                                                construct_params);
135         window = EV_LOADING_WINDOW (object);
136         gtk_window = GTK_WINDOW (window);
137
138         gtk_window_set_transient_for (gtk_window, window->parent);
139         gtk_window_set_destroy_with_parent (gtk_window, TRUE);
140
141         return object;
142 }
143
144 static void
145 _cairo_rounded_rectangle (cairo_t *cr,
146                           gint     width,
147                           gint     height,
148                           gdouble  radius)
149 {
150         cairo_move_to (cr, radius, 0);
151         cairo_line_to (cr, width - radius, 0);
152         cairo_curve_to (cr,
153                         width, 0,
154                         width, 0,
155                         width,
156                         radius);
157         cairo_line_to (cr, width, height - radius);
158         cairo_curve_to (cr,
159                         width,height,
160                         width, height,
161                         width - radius,
162                         height);
163         cairo_line_to (cr, radius, height);
164         cairo_curve_to (cr,
165                         0, height,
166                         0, height,
167                         0, height - radius);
168         cairo_line_to (cr, 0, radius);
169         cairo_curve_to (cr,
170                         0, 0,
171                         0, 0,
172                         radius, 0);
173 }
174
175 static void
176 ev_loading_window_size_allocate (GtkWidget      *widget,
177                                  GtkAllocation  *allocation)
178 {
179         EvLoadingWindow *window = EV_LOADING_WINDOW (widget);
180 #if GTK_CHECK_VERSION (2, 90, 8)
181         cairo_surface_t *surface;
182         cairo_region_t *shape;
183 #else
184         GdkPixmap *mask;
185 #endif
186         cairo_t         *cr;
187         double           r;
188
189         GTK_WIDGET_CLASS (ev_loading_window_parent_class)->size_allocate (widget, allocation);
190
191         if (allocation->width == window->width && allocation->height == window->height)
192                 return;
193
194         window->width = allocation->width;
195         window->height = allocation->height;
196
197 #if GTK_CHECK_VERSION (2, 90, 8)
198         surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
199                                               window->width,
200                                               window->height);
201         cr = cairo_create (surface);
202 #else
203         mask = gdk_pixmap_new (NULL, window->width, window->height, 1);
204         cr = gdk_cairo_create (GDK_DRAWABLE (mask));
205 #endif
206
207         cairo_save (cr);
208         cairo_rectangle (cr, 0, 0, window->width, window->height);
209         cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
210         cairo_fill (cr);
211         cairo_restore (cr);
212
213         cairo_set_source_rgb (cr, 1., 1., 1.);
214         r = MIN (window->width, window->height) / 2.;
215         _cairo_rounded_rectangle (cr, window->width, window->height, r);
216         cairo_fill (cr);
217
218         cairo_destroy (cr);
219
220 #if GTK_CHECK_VERSION (2, 90, 8)
221         shape = gdk_cairo_region_create_from_surface (surface);
222         cairo_surface_destroy (surface);
223
224         gtk_widget_shape_combine_region (widget, shape);
225         cairo_region_destroy (shape);
226 #else
227         gtk_widget_shape_combine_mask (widget, mask, 0, 0);
228         g_object_unref (mask);
229 #endif
230 }
231
232 static void
233 ev_loading_window_hide (GtkWidget *widget)
234 {
235         EvLoadingWindow *window = EV_LOADING_WINDOW (widget);
236
237         window->x = window->y = 0;
238
239         GTK_WIDGET_CLASS (ev_loading_window_parent_class)->hide (widget);
240 }
241
242 static void
243 ev_loading_window_class_init (EvLoadingWindowClass *klass)
244 {
245         GObjectClass   *g_object_class = G_OBJECT_CLASS (klass);
246         GtkWidgetClass *gtk_widget_class = GTK_WIDGET_CLASS (klass);
247
248         g_object_class->constructor = ev_loading_window_constructor;
249         g_object_class->set_property = ev_loading_window_set_property;
250
251         gtk_widget_class->size_allocate = ev_loading_window_size_allocate;
252         gtk_widget_class->hide = ev_loading_window_hide;
253
254         g_object_class_install_property (g_object_class,
255                                          PROP_PARENT,
256                                          g_param_spec_object ("parent",
257                                                               "Parent",
258                                                               "The parent window",
259                                                               GTK_TYPE_WINDOW,
260                                                               G_PARAM_WRITABLE |
261                                                               G_PARAM_CONSTRUCT_ONLY));
262 }
263
264 /* Public methods */
265 GtkWidget *
266 ev_loading_window_new (GtkWindow *parent)
267 {
268         GtkWidget *window;
269
270         g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
271
272         window = g_object_new (EV_TYPE_LOADING_WINDOW,
273                                "parent", parent,
274                                NULL);
275         return window;
276 }
277
278 void
279 ev_loading_window_get_size (EvLoadingWindow *window,
280                             gint            *width,
281                             gint            *height)
282 {
283         if (width) *width = window->width;
284         if (height) *height = window->height;
285 }
286
287 void
288 ev_loading_window_move (EvLoadingWindow *window,
289                         gint             x,
290                         gint             y)
291 {
292         if (x == window->x && y == window->y)
293                 return;
294
295         window->x = x;
296         window->y = y;
297         gtk_window_move (GTK_WINDOW (window), x, y);
298 }