summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <[email protected]>2012-09-29 16:06:39 +0200
committerraveit65 <[email protected]>2018-03-22 08:27:44 +0100
commita04ab7f1b28fd3e3f767baaa69b0c4eb06a0825a (patch)
tree8b835b9b07383ba4f3b7fb10e204ea00522e7617
parent9ac0d1a788affc0307d837b8011f533d16974841 (diff)
downloadatril-a04ab7f1b28fd3e3f767baaa69b0c4eb06a0825a.tar.bz2
atril-a04ab7f1b28fd3e3f767baaa69b0c4eb06a0825a.tar.xz
Use GtkOverlay to show the loading message
Remove the EvLoadingWindow from libview and move the implementation to the shell using a EvLoadingMessage widget and GtkOverlay. EvView has now a is-loading property that allows the users to implement their own loading notification system. This fixes several realted to the loading window. origin commit: https://git.gnome.org/browse/evince/commit/?h=gnome-3-8&id=035c1cb
-rw-r--r--libview/Makefile.am2
-rw-r--r--libview/ev-loading-window.c294
-rw-r--r--libview/ev-loading-window.h49
-rw-r--r--libview/ev-view.c130
-rw-r--r--libview/ev-view.h2
-rw-r--r--previewer/ev-previewer-window.c2
-rw-r--r--shell/Makefile.am2
-rw-r--r--shell/ev-loading-message.c180
-rw-r--r--shell/ev-loading-message.h45
-rw-r--r--shell/ev-window.c78
10 files changed, 332 insertions, 452 deletions
diff --git a/libview/Makefile.am b/libview/Makefile.am
index 855a1f20..b382810a 100644
--- a/libview/Makefile.am
+++ b/libview/Makefile.am
@@ -6,7 +6,6 @@ NOINST_H_FILES = \
ev-image-accessible.h \
ev-link-accessible.h \
ev-page-accessible.h \
- ev-loading-window.h \
ev-page-cache.h \
ev-pixbuf-cache.h \
ev-timeline.h \
@@ -38,7 +37,6 @@ libatrilview_la_SOURCES = \
ev-document-model.c \
ev-form-field-accessible.c \
ev-image-accessible.c \
- ev-loading-window.c \
ev-jobs.c \
ev-job-scheduler.c \
ev-link-accessible.c \
diff --git a/libview/ev-loading-window.c b/libview/ev-loading-window.c
deleted file mode 100644
index 52de665c..00000000
--- a/libview/ev-loading-window.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/* ev-loading-window.c
- * this file is part of atril, a mate document viewer
- *
- * Copyright (C) 2010 Carlos Garcia Campos <[email protected]>
- *
- * Atril 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.
- *
- * Atril 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <glib/gi18n.h>
-#include "ev-loading-window.h"
-
-enum {
- PROP_0,
- PROP_PARENT
-};
-
-struct _EvLoadingWindow {
- GtkWindow base_instance;
-
- GtkWindow *parent;
- GtkWidget *spinner;
-
- gint x;
- gint y;
- gint width;
- gint height;
-};
-
-struct _EvLoadingWindowClass {
- GtkWindowClass base_class;
-};
-
-G_DEFINE_TYPE (EvLoadingWindow, ev_loading_window, GTK_TYPE_WINDOW)
-
-static void
-ev_loading_window_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EvLoadingWindow *window = EV_LOADING_WINDOW (object);
-
- switch (prop_id) {
- case PROP_PARENT:
- window->parent = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-ev_loading_window_init (EvLoadingWindow *window)
-{
- GtkWindow *gtk_window = GTK_WINDOW (window);
- GtkWidget *widget = GTK_WIDGET (window);
- GtkWidget *hbox;
- GtkWidget *label;
- GtkStyleContext *context;
- GdkRGBA fg, bg;
-
- const gchar *loading_text = _("Loading…");
- const gchar *fg_color_name = "info_fg_color";
- const gchar *bg_color_name = "info_bg_color";
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-
- window->spinner = gtk_spinner_new ();
- gtk_box_pack_start (GTK_BOX (hbox), window->spinner, FALSE, FALSE, 0);
- gtk_widget_show (window->spinner);
-
- label = gtk_label_new (loading_text);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- gtk_container_add (GTK_CONTAINER (window), hbox);
- gtk_widget_show (hbox);
-
- gtk_widget_set_app_paintable (widget, TRUE);
-
- gtk_container_set_border_width (GTK_CONTAINER (window), 10);
-
- gtk_window_set_type_hint (gtk_window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);
- gtk_window_set_accept_focus (gtk_window, FALSE);
- gtk_window_set_decorated (gtk_window, FALSE);
- gtk_window_set_resizable (gtk_window, FALSE);
-
- context = gtk_widget_get_style_context (widget);
- if (!gtk_style_context_lookup_color (context, fg_color_name, &fg) ||
- !gtk_style_context_lookup_color (context, bg_color_name, &bg)) {
- fg.red = 0.7;
- fg.green = 0.67;
- fg.blue = 0.63;
- fg.alpha = 1.0;
-
- bg.red = 0.99;
- bg.green = 0.99;
- bg.blue = 0.71;
- bg.alpha = 1.0;
- }
-
- gtk_widget_override_background_color (widget, GTK_STATE_NORMAL, &bg);
- gtk_widget_override_color (widget, GTK_STATE_NORMAL, &fg);
-}
-
-static GObject *
-ev_loading_window_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_params)
-{
- GObject *object;
- EvLoadingWindow *window;
- GtkWindow *gtk_window;
-
- object = G_OBJECT_CLASS (ev_loading_window_parent_class)->constructor (type,
- n_construct_properties,
- construct_params);
- window = EV_LOADING_WINDOW (object);
- gtk_window = GTK_WINDOW (window);
-
- gtk_window_set_transient_for (gtk_window, window->parent);
- gtk_window_set_destroy_with_parent (gtk_window, TRUE);
-
- return object;
-}
-
-static void
-_cairo_rounded_rectangle (cairo_t *cr,
- gint width,
- gint height,
- gdouble radius)
-{
- cairo_move_to (cr, radius, 0);
- cairo_line_to (cr, width - radius, 0);
- cairo_curve_to (cr,
- width, 0,
- width, 0,
- width,
- radius);
- cairo_line_to (cr, width, height - radius);
- cairo_curve_to (cr,
- width,height,
- width, height,
- width - radius,
- height);
- cairo_line_to (cr, radius, height);
- cairo_curve_to (cr,
- 0, height,
- 0, height,
- 0, height - radius);
- cairo_line_to (cr, 0, radius);
- cairo_curve_to (cr,
- 0, 0,
- 0, 0,
- radius, 0);
-}
-
-static void
-ev_loading_window_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- EvLoadingWindow *window = EV_LOADING_WINDOW (widget);
- cairo_surface_t *surface;
- cairo_region_t *shape;
- cairo_t *cr;
- double r;
-
- GTK_WIDGET_CLASS (ev_loading_window_parent_class)->size_allocate (widget, allocation);
-
- if (allocation->width == window->width && allocation->height == window->height)
- return;
-
- window->width = allocation->width;
- window->height = allocation->height;
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_A8, window->width, window->height);
- cr = cairo_create (surface);
-
- cairo_save (cr);
- cairo_rectangle (cr, 0, 0, window->width, window->height);
- cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
- cairo_fill (cr);
- cairo_restore (cr);
-
- cairo_set_source_rgb (cr, 1., 1., 1.);
- r = MIN (window->width, window->height) / 2.;
- _cairo_rounded_rectangle (cr, window->width, window->height, r);
- cairo_fill (cr);
-
- cairo_destroy (cr);
-
- shape = gdk_cairo_region_create_from_surface (surface);
- cairo_surface_destroy (surface);
-
- gtk_widget_shape_combine_region (widget, shape);
- cairo_region_destroy (shape);
-}
-
-static void
-ev_loading_window_hide (GtkWidget *widget)
-{
- EvLoadingWindow *window = EV_LOADING_WINDOW (widget);
-
- window->x = window->y = 0;
-
- gtk_spinner_stop (GTK_SPINNER (window->spinner));
-
- GTK_WIDGET_CLASS (ev_loading_window_parent_class)->hide (widget);
-}
-
-static void
-ev_loading_window_show (GtkWidget *widget)
-{
- EvLoadingWindow *window = EV_LOADING_WINDOW (widget);
-
- gtk_spinner_start (GTK_SPINNER (window->spinner));
-
- GTK_WIDGET_CLASS (ev_loading_window_parent_class)->show (widget);
-}
-
-static void
-ev_loading_window_class_init (EvLoadingWindowClass *klass)
-{
- GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *gtk_widget_class = GTK_WIDGET_CLASS (klass);
-
- g_object_class->constructor = ev_loading_window_constructor;
- g_object_class->set_property = ev_loading_window_set_property;
-
- gtk_widget_class->size_allocate = ev_loading_window_size_allocate;
- gtk_widget_class->show = ev_loading_window_show;
- gtk_widget_class->hide = ev_loading_window_hide;
-
- g_object_class_install_property (g_object_class,
- PROP_PARENT,
- g_param_spec_object ("parent",
- "Parent",
- "The parent window",
- GTK_TYPE_WINDOW,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY));
-}
-
-/* Public methods */
-GtkWidget *
-ev_loading_window_new (GtkWindow *parent)
-{
- GtkWidget *window;
-
- g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
-
- window = g_object_new (EV_TYPE_LOADING_WINDOW,
- "type", GTK_WINDOW_POPUP,
- "parent", parent,
- NULL);
- return window;
-}
-
-void
-ev_loading_window_get_size (EvLoadingWindow *window,
- gint *width,
- gint *height)
-{
- if (width) *width = window->width;
- if (height) *height = window->height;
-}
-
-void
-ev_loading_window_move (EvLoadingWindow *window,
- gint x,
- gint y)
-{
- if (x == window->x && y == window->y)
- return;
-
- window->x = x;
- window->y = y;
- gtk_window_move (GTK_WINDOW (window), x, y);
-}
diff --git a/libview/ev-loading-window.h b/libview/ev-loading-window.h
deleted file mode 100644
index aac13614..00000000
--- a/libview/ev-loading-window.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ev-loading-window.h
- * this file is part of atril, a mate document viewer
- *
- * Copyright (C) 2010 Carlos Garcia Campos <[email protected]>
- *
- * Atril 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.
- *
- * Atril 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef EV_LOADING_WINDOW_H
-#define EV_LOADING_WINDOW_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-typedef struct _EvLoadingWindow EvLoadingWindow;
-typedef struct _EvLoadingWindowClass EvLoadingWindowClass;
-
-#define EV_TYPE_LOADING_WINDOW (ev_loading_window_get_type())
-#define EV_LOADING_WINDOW(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LOADING_WINDOW, EvLoadingWindow))
-#define EV_LOADING_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LOADING_WINDOW, EvLoadingWindowClass))
-#define EV_IS_LOADING_WINDOW(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LOADING_WINDOW))
-#define EV_IS_LOADING_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LOADING_WINDOW))
-#define EV_LOADING_WINDOW_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LOADING_WINDOW, EvLoadingWindowClass))
-
-GType ev_loading_window_get_type (void) G_GNUC_CONST;
-GtkWidget *ev_loading_window_new (GtkWindow *parent);
-void ev_loading_window_get_size (EvLoadingWindow *window,
- gint *width,
- gint *height);
-void ev_loading_window_move (EvLoadingWindow *window,
- gint x,
- gint y);
-
-G_END_DECLS
-
-#endif /* EV_LOADING_WINDOW_H */
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 6e02efce..a2f368d8 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -41,7 +41,6 @@
#include "ev-view-marshal.h"
#include "ev-document-annotations.h"
#include "ev-annotation-window.h"
-#include "ev-loading-window.h"
#include "ev-view.h"
#include "ev-view-accessible.h"
#include "ev-view-private.h"
@@ -74,6 +73,7 @@ enum {
enum {
PROP_0,
+ PROP_IS_LOADING,
PROP_HADJUSTMENT,
PROP_VADJUSTMENT,
PROP_HSCROLL_POLICY,
@@ -189,12 +189,9 @@ static void draw_one_page (EvView
GtkBorder *border,
GdkRectangle *expose_area,
gboolean *page_ready);
-static void show_loading_window (EvView *view);
-static void hide_loading_window (EvView *view);
static void ev_view_reload_page (EvView *view,
gint page,
cairo_region_t *region);
-static void ev_view_loading_window_move (EvView *view);
/*** Callbacks ***/
static void ev_view_change_page (EvView *view,
@@ -751,7 +748,7 @@ view_update_range_and_current_page (EvView *view)
if (best_current_page >= 0 && view->current_page != best_current_page) {
view->current_page = best_current_page;
- hide_loading_window (view);
+ ev_view_set_loading (view, FALSE);
ev_document_model_set_page (view->model, best_current_page);
}
}
@@ -4046,13 +4043,6 @@ ev_view_draw (GtkWidget *widget,
GdkRectangle *area = &clip_rect;
gint i;
- if (view->loading) {
- show_loading_window (view);
- } else if (view->loading_window &&
- gtk_widget_get_visible (view->loading_window)) {
- ev_view_loading_window_move (view);
- }
-
gtk_render_background (gtk_widget_get_style_context (widget),
cr,
0, 0,
@@ -5691,81 +5681,6 @@ highlight_forward_search_results (EvView *view, cairo_t *cr, int page)
}
static void
-ev_view_loading_window_move (EvView *view)
-{
- GtkWidget *widget = GTK_WIDGET (view);
- EvLoadingWindow *window = EV_LOADING_WINDOW (view->loading_window);
- gint root_x, root_y;
- gint window_width;
- GtkAllocation allocation;
-
- gtk_widget_get_allocation (widget, &allocation);
- gdk_window_get_origin (gtk_widget_get_window (widget), &root_x, &root_y);
- ev_loading_window_get_size (window, &window_width, NULL);
-
- root_x += allocation.width - window_width - 10;
- root_y += 10;
-
- ev_loading_window_move (window, root_x, root_y);
-}
-
-static gboolean
-show_loading_window_cb (EvView *view)
-{
- if (!view->loading_window) {
- GtkWindow *parent;
- GdkScreen *screen;
-
- parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
- view->loading_window = ev_loading_window_new (parent);
-
- /* Show the window off screen to get a valid size asap */
- screen = gtk_widget_get_screen (GTK_WIDGET (view));
- gtk_window_move (GTK_WINDOW (view->loading_window),
- WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) + 1,
- HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) + 1);
- gtk_widget_show (view->loading_window);
- }
-
- ev_view_loading_window_move (view);
-
- gtk_widget_show (view->loading_window);
-
- view->loading_timeout = 0;
-
- return FALSE;
-}
-
-static void
-show_loading_window (EvView *view)
-{
- if (view->loading_window && gtk_widget_get_visible (view->loading_window)) {
- ev_view_loading_window_move (view);
- return;
- }
-
- if (!view->loading_timeout) {
- view->loading_timeout =
- g_timeout_add_full (G_PRIORITY_LOW,
- 0.5, (GSourceFunc)show_loading_window_cb,
- view, NULL);
- }
-}
-
-static void
-hide_loading_window (EvView *view)
-{
- if (view->loading_timeout) {
- g_source_remove (view->loading_timeout);
- view->loading_timeout = 0;
- }
-
- if (view->loading_window && gtk_widget_get_visible (view->loading_window)) {
- gtk_widget_hide (view->loading_window);
- }
-}
-
-static void
draw_surface (cairo_t *cr,
cairo_surface_t *surface,
gint x,
@@ -5894,7 +5809,7 @@ draw_one_page (EvView *view,
if (!page_surface) {
if (page == current_page)
- show_loading_window (view);
+ ev_view_set_loading (view, TRUE);
*page_ready = FALSE;
@@ -5906,7 +5821,7 @@ draw_one_page (EvView *view,
#endif
if (page == current_page)
- hide_loading_window (view);
+ ev_view_set_loading (view, FALSE);
ev_view_get_page_size (view, page, &width, &height);
offset_x = overlap.x - real_page_area.x;
@@ -6027,11 +5942,6 @@ ev_view_dispose (GObject *object)
view->cursor_blink_timeout_id = 0;
}
- if (view->loading_timeout) {
- g_source_remove (view->loading_timeout);
- view->loading_timeout = 0;
- }
-
g_clear_object(&view->accessible);
G_OBJECT_CLASS (ev_view_parent_class)->dispose (object);
@@ -6046,6 +5956,9 @@ ev_view_get_property (GObject *object,
EvView *view = EV_VIEW (object);
switch (prop_id) {
+ case PROP_IS_LOADING:
+ g_value_set_boolean (value, view->loading);
+ break;
case PROP_HADJUSTMENT:
g_value_set_object (value, view->hadjustment);
break;
@@ -6073,6 +5986,9 @@ ev_view_set_property (GObject *object,
EvView *view = EV_VIEW (object);
switch (prop_id) {
+ case PROP_IS_LOADING:
+ ev_view_set_loading (view, g_value_get_boolean (value));
+ break;
case PROP_HADJUSTMENT:
set_scroll_adjustment (view, GTK_ORIENTATION_HORIZONTAL,
(GtkAdjustment *) g_value_get_object (value));
@@ -6309,6 +6225,15 @@ ev_view_class_init (EvViewClass *class)
class->scroll = ev_view_scroll_internal;
class->move_cursor = ev_view_move_cursor;
+ g_object_class_install_property (object_class,
+ PROP_IS_LOADING,
+ g_param_spec_boolean ("is-loading",
+ "Is Loading",
+ "Whether the view is loading",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
/* Scrollable interface */
g_object_class_override_property (object_class, PROP_HADJUSTMENT, "hadjustment");
g_object_class_override_property (object_class, PROP_VADJUSTMENT, "vadjustment");
@@ -6572,7 +6497,7 @@ ev_view_change_page (EvView *view,
view->current_page = new_page;
view->pending_scroll = SCROLL_TO_PAGE_POSITION;
- hide_loading_window (view);
+ ev_view_set_loading (view, FALSE);
ev_document_misc_get_pointer_position (GTK_WIDGET (view), &x, &y);
ev_view_handle_cursor_over_xy (view, x, y);
@@ -6743,10 +6668,17 @@ void
ev_view_set_loading (EvView *view,
gboolean loading)
{
- if (view->loading && !loading)
- hide_loading_window (view);
+ if (view->loading == loading)
+ return;
+
view->loading = loading;
- gtk_widget_queue_draw (GTK_WIDGET (view));
+ g_object_notify (G_OBJECT (view), "is-loading");
+}
+
+gboolean
+ev_view_is_loading (EvView *view)
+{
+ return view->loading;
}
static gboolean
@@ -6841,7 +6773,7 @@ ev_view_document_changed_cb (EvDocumentModel *model,
view->find_result = 0;
if (view->document) {
- view->loading = FALSE;
+ ev_view_set_loading (view, FALSE);
g_object_ref (view->document);
setup_caches (view);
}
diff --git a/libview/ev-view.h b/libview/ev-view.h
index 802b8cb9..ac16211f 100644
--- a/libview/ev-view.h
+++ b/libview/ev-view.h
@@ -45,8 +45,10 @@ GType ev_view_get_type (void) G_GNUC_CONST;
GtkWidget* ev_view_new (void);
void ev_view_set_model (EvView *view,
EvDocumentModel *model);
+EV_DEPRECATED
void ev_view_set_loading (EvView *view,
gboolean loading);
+gboolean ev_view_is_loading (EvView *view);
void ev_view_reload (EvView *view);
void ev_view_set_page_cache_size (EvView *view,
gsize cache_size);
diff --git a/previewer/ev-previewer-window.c b/previewer/ev-previewer-window.c
index 3920d2db..df1cb7a1 100644
--- a/previewer/ev-previewer-window.c
+++ b/previewer/ev-previewer-window.c
@@ -392,7 +392,6 @@ ev_previewer_window_set_document (EvPreviewerWindow *window,
g_signal_connect (model, "notify::sizing-mode",
G_CALLBACK (view_sizing_mode_changed),
window);
- ev_view_set_loading (window->view, FALSE);
gtk_action_group_set_sensitive (window->action_group, TRUE);
gtk_action_group_set_sensitive (window->accels_group, TRUE);
}
@@ -603,7 +602,6 @@ ev_previewer_window_constructor (GType type,
window, 0);
ev_view_set_model (window->view, window->model);
ev_document_model_set_continuous (window->model, FALSE);
- ev_view_set_loading (window->view, TRUE);
gtk_container_add (GTK_CONTAINER (window->swindow), GTK_WIDGET (window->view));
gtk_widget_show (GTK_WIDGET (window->view));
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 3f0309c8..1bf3cba4 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -43,6 +43,8 @@ atril_SOURCES= \
ev-history.h \
ev-keyring.h \
ev-keyring.c \
+ ev-loading-message.c \
+ ev-loading-message.h \
ev-message-area.c \
ev-message-area.h \
ev-metadata.c \
diff --git a/shell/ev-loading-message.c b/shell/ev-loading-message.c
new file mode 100644
index 00000000..b09d3479
--- /dev/null
+++ b/shell/ev-loading-message.c
@@ -0,0 +1,180 @@
+/* ev-loading-message.c
+ * this file is part of atril, a mate document viewer
+ *
+ * Copyright (C) 2010, 2012 Carlos Garcia Campos <[email protected]>
+ *
+ * Atril 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.
+ *
+ * Atril 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "ev-loading-message.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+struct _EvLoadingMessage {
+ GtkBox base_instance;
+
+ GtkWidget *spinner;
+};
+
+struct _EvLoadingMessageClass {
+ GtkBoxClass base_class;
+};
+
+G_DEFINE_TYPE (EvLoadingMessage, ev_loading_message, GTK_TYPE_BOX)
+
+static void
+ev_loading_message_init (EvLoadingMessage *message)
+{
+ GtkWidget *widget = GTK_WIDGET (message);
+ GtkWidget *label;
+ GtkStyleContext *context;
+
+ gtk_container_set_border_width (GTK_CONTAINER (message), 10);
+
+ message->spinner = gtk_spinner_new ();
+ gtk_box_pack_start (GTK_BOX (message), message->spinner, FALSE, FALSE, 0);
+ gtk_widget_show (message->spinner);
+
+ label = gtk_label_new (_("Loading…"));
+ gtk_box_pack_start (GTK_BOX (message), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+}
+
+static void
+get_widget_padding (GtkWidget *widget,
+ GtkBorder *padding)
+{
+ GtkStyleContext *context;
+ GtkStateFlags state;
+
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_style_context_get_state (context);
+ gtk_style_context_get_padding (context, state, padding);
+}
+
+static void
+ev_loading_message_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EvLoadingMessage *message = EV_LOADING_MESSAGE (widget);
+ GtkAllocation child_allocation;
+ GtkBorder padding;
+
+ get_widget_padding (widget, &padding);
+ child_allocation.y = allocation->x + padding.left;
+ child_allocation.x = allocation->y + padding.top;
+ child_allocation.width = MAX (1, allocation->width - (padding.left + padding.right));
+ child_allocation.height = MAX (1, allocation->height - (padding.top + padding.bottom));
+
+ GTK_WIDGET_CLASS (ev_loading_message_parent_class)->size_allocate (widget, &child_allocation);
+ gtk_widget_set_allocation (widget, allocation);
+}
+
+static void
+ev_loading_message_get_preferred_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkBorder padding;
+
+ GTK_WIDGET_CLASS (ev_loading_message_parent_class)->get_preferred_width (widget, minimum_size, natural_size);
+
+ get_widget_padding (widget, &padding);
+ *minimum_size += padding.left + padding.right;
+ *natural_size += padding.left + padding.right;
+}
+
+static void
+ev_loading_message_get_preferred_height (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkBorder padding;
+
+ GTK_WIDGET_CLASS (ev_loading_message_parent_class)->get_preferred_height (widget, minimum_size, natural_size);
+
+ get_widget_padding (widget, &padding);
+ *minimum_size += padding.top + padding.bottom;
+ *natural_size += padding.top + padding.bottom;
+}
+
+static gboolean
+ev_loading_message_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GtkStyleContext *context;
+ gint width, height;
+
+ context = gtk_widget_get_style_context (widget);
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+
+ gtk_render_background (context, cr, 0, 0, width, height);
+ gtk_render_frame (context, cr, 0, 0, width, height);
+
+ GTK_WIDGET_CLASS (ev_loading_message_parent_class)->draw (widget, cr);
+
+ return TRUE;
+}
+
+static void
+ev_loading_message_hide (GtkWidget *widget)
+{
+ EvLoadingMessage *message = EV_LOADING_MESSAGE (widget);
+
+ gtk_spinner_stop (GTK_SPINNER (message->spinner));
+
+ GTK_WIDGET_CLASS (ev_loading_message_parent_class)->hide (widget);
+}
+
+static void
+ev_loading_message_show (GtkWidget *widget)
+{
+ EvLoadingMessage *message = EV_LOADING_MESSAGE (widget);
+
+ gtk_spinner_start (GTK_SPINNER (message->spinner));
+
+ GTK_WIDGET_CLASS (ev_loading_message_parent_class)->show (widget);
+}
+
+static void
+ev_loading_message_class_init (EvLoadingMessageClass *klass)
+{
+ GtkWidgetClass *gtk_widget_class = GTK_WIDGET_CLASS (klass);
+
+ gtk_widget_class->size_allocate = ev_loading_message_size_allocate;
+ gtk_widget_class->get_preferred_width = ev_loading_message_get_preferred_width;
+ gtk_widget_class->get_preferred_height = ev_loading_message_get_preferred_height;
+ gtk_widget_class->draw = ev_loading_message_draw;
+ gtk_widget_class->show = ev_loading_message_show;
+ gtk_widget_class->hide = ev_loading_message_hide;
+}
+
+/* Public methods */
+GtkWidget *
+ev_loading_message_new (void)
+{
+ GtkWidget *message;
+
+ message = g_object_new (EV_TYPE_LOADING_MESSAGE,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ "spacing", 12,
+ NULL);
+ return message;
+}
+
+
diff --git a/shell/ev-loading-message.h b/shell/ev-loading-message.h
new file mode 100644
index 00000000..3034b792
--- /dev/null
+++ b/shell/ev-loading-message.h
@@ -0,0 +1,45 @@
+/* ev-loading-message.h
+ * this file is part of atril, a mate document viewer
+ *
+ * Copyright (C) 2010, 2012 Carlos Garcia Campos <[email protected]>
+ *
+ * Atril 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.
+ *
+ * Atril 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef EV_LOADING_MESSAGE_H
+#define EV_LOADING_MESSAGE_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvLoadingMessage EvLoadingMessage;
+typedef struct _EvLoadingMessageClass EvLoadingMessageClass;
+
+#define EV_TYPE_LOADING_MESSAGE (ev_loading_message_get_type())
+#define EV_LOADING_MESSAGE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LOADING_MESSAGE, EvLoadingMessage))
+#define EV_IS_LOADING_MESSAGE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LOADING_MESSAGE))
+#define EV_LOADING_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LOADING_MESSAGE, EvLoadingMessageClass))
+#define EV_IS_LOADING_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LOADING_MESSAGE))
+#define EV_LOADING_MESSAGE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LOADING_MESSAGE, EvLoadingMessageClass))
+
+GType ev_loading_message_get_type (void) G_GNUC_CONST;
+
+GtkWidget *ev_loading_message_new (void);
+
+G_END_DECLS
+
+#endif /* EV_LOADING_MESSAGE_H */
+
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 820b9f32..f323a4f9 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -68,6 +68,7 @@
#include "ev-image.h"
#include "ev-job-scheduler.h"
#include "ev-jobs.h"
+#include "ev-loading-message.h"
#include "ev-message-area.h"
#include "ev-metadata.h"
#include "ev-navigation-action.h"
@@ -137,6 +138,7 @@ struct _EvWindowPrivate {
GtkWidget *find_bar;
GtkWidget *scrolled_window;
GtkWidget *view;
+ GtkWidget *loading_message;
GtkWidget *presentation_view;
GtkWidget *message_area;
GtkWidget *password_view;
@@ -163,6 +165,9 @@ struct _EvWindowPrivate {
guint progress_idle;
GCancellable *progress_cancellable;
+ /* Loading message */
+ guint loading_message_timeout;
+
/* Dialogs */
GtkWidget *properties;
GtkWidget *print_dialog;
@@ -868,6 +873,35 @@ ev_window_warning_message (EvWindow *window,
ev_window_set_message_area (window, area);
}
+static gboolean
+show_loading_message_cb (EvWindow *window)
+{
+ window->priv->loading_message_timeout = 0;
+ gtk_widget_show (window->priv->loading_message);
+
+ return FALSE;
+}
+
+static void
+ev_window_show_loading_message (EvWindow *window)
+{
+ if (window->priv->loading_message_timeout)
+ return;
+ window->priv->loading_message_timeout =
+ g_timeout_add_full (G_PRIORITY_LOW, 0.5, (GSourceFunc)show_loading_message_cb, window, NULL);
+}
+
+static void
+ev_window_hide_loading_message (EvWindow *window)
+{
+ if (window->priv->loading_message_timeout) {
+ g_source_remove (window->priv->loading_message_timeout);
+ window->priv->loading_message_timeout = 0;
+ }
+
+ gtk_widget_hide (window->priv->loading_message);
+}
+
typedef struct _PageTitleData {
const gchar *page_label;
gchar *page_title;
@@ -1020,6 +1054,17 @@ view_caret_cursor_moved_cb (EvView *view,
}
static void
+view_is_loading_changed_cb (EvView *view,
+ GParamSpec *spec,
+ EvWindow *window)
+{
+ if (ev_view_is_loading (view))
+ ev_window_show_loading_message (window);
+ else
+ ev_window_hide_loading_message (window);
+}
+
+static void
ev_window_page_changed_cb (EvWindow *ev_window,
gint old_page,
gint new_page,
@@ -1833,7 +1878,7 @@ ev_window_load_job_cb (EvJob *job,
g_assert (job_load->uri);
- ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+ ev_window_hide_loading_message (ev_window);
/* Success! */
if (!ev_job_is_failed (job)) {
ev_document_model_set_document (ev_window->priv->model, document);
@@ -2090,7 +2135,7 @@ ev_window_load_remote_failed (EvWindow *ev_window,
{
if ( !ev_window->priv->view ) return;
- ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+ ev_window_hide_loading_message (ev_window);
ev_window->priv->in_reload = FALSE;
ev_window_error_message (ev_window, error,
"%s", _("Unable to open document"));
@@ -2182,7 +2227,7 @@ window_open_file_copy_ready_cb (GFile *source,
ev_window->priv->uri = NULL;
g_object_unref (source);
- ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+ ev_window_hide_loading_message (ev_window);
} else {
ev_window_load_remote_failed (ev_window, error);
g_object_unref (source);
@@ -2346,7 +2391,7 @@ ev_window_open_uri (EvWindow *ev_window,
if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) {
ev_window_load_file_remote (ev_window, source_file);
} else {
- ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE);
+ ev_window_show_loading_message (ev_window);
g_object_unref (source_file);
ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
}
@@ -6021,6 +6066,11 @@ ev_window_dispose (GObject *object)
priv->interface_settings = NULL;
}
+ if (priv->loading_message_timeout) {
+ g_source_remove (priv->loading_message_timeout);
+ priv->loading_message_timeout = 0;
+ }
+
if (priv->monitor) {
g_object_unref (priv->monitor);
priv->monitor = NULL;
@@ -7607,6 +7657,7 @@ ev_window_init (EvWindow *ev_window)
GError *error = NULL;
GtkWidget *sidebar_widget;
GtkWidget *menuitem;
+ GtkWidget *overlay;
GObject *mpkeys;
guint page_cache_mb;
gchar *ui_path;
@@ -7863,14 +7914,26 @@ ev_window_init (EvWindow *ev_window)
sidebar_widget);
ev_window->priv->view_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+
+ overlay = gtk_overlay_new ();
ev_window->priv->scrolled_window =
GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,
"shadow-type", GTK_SHADOW_IN,
NULL));
+ gtk_container_add (GTK_CONTAINER (overlay), ev_window->priv->scrolled_window);
+ gtk_widget_show (ev_window->priv->scrolled_window);
+
+ ev_window->priv->loading_message = ev_loading_message_new ();
+ gtk_widget_set_name (ev_window->priv->loading_message, "ev-loading-message");
+ gtk_widget_set_halign (ev_window->priv->loading_message, GTK_ALIGN_END);
+ gtk_widget_set_valign (ev_window->priv->loading_message, GTK_ALIGN_START);
+ gtk_widget_set_no_show_all (ev_window->priv->loading_message, TRUE);
+ gtk_overlay_add_overlay (GTK_OVERLAY (overlay), ev_window->priv->loading_message);
+
gtk_box_pack_start (GTK_BOX (ev_window->priv->view_box),
- ev_window->priv->scrolled_window,
+ overlay,
TRUE, TRUE, 0);
- gtk_widget_show (ev_window->priv->scrolled_window);
+ gtk_widget_show (overlay);
gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned),
ev_window->priv->view_box);
@@ -7917,6 +7980,9 @@ ev_window_init (EvWindow *ev_window)
g_signal_connect_object (ev_window->priv->view, "layers-changed",
G_CALLBACK (view_layers_changed_cb),
ev_window, 0);
+ g_signal_connect_object (ev_window->priv->view, "notify::is-loading",
+ G_CALLBACK (view_is_loading_changed_cb),
+ ev_window, 0);
g_signal_connect_object (ev_window->priv->view, "cursor-moved",
G_CALLBACK (view_caret_cursor_moved_cb),
ev_window, 0);