[evince] libview: Make page layout a mode
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] libview: Make page layout a mode
- Date: Thu, 10 Jan 2013 17:36:26 +0000 (UTC)
commit 42f6d4b3a24e4524bc0b4295bae4c3ab744c5b20
Author: William Jon McCann <jmccann redhat com>
Date: Thu Jan 10 18:35:04 2013 +0100
libview: Make page layout a mode
Instead of having a few different mutually exclusive booleans it
makes sense to have it be a mode with the following options:
automatic, single, dual.
This allows us to have a way to automatically determine if dual page
mode should be used when the window is large enough.
https://bugzilla.gnome.org/show_bug.cgi?id=689468
help/reference/libview/libevview.types | 1 +
libview/ev-document-model.c | 72 ++++++++++++++--
libview/ev-document-model.h | 20 ++++-
libview/ev-view-private.h | 2 +-
libview/ev-view.c | 146 +++++++++++++++++++++++---------
5 files changed, 188 insertions(+), 53 deletions(-)
---
diff --git a/help/reference/libview/libevview.types b/help/reference/libview/libevview.types
index 668b715..311e9c7 100644
--- a/help/reference/libview/libevview.types
+++ b/help/reference/libview/libevview.types
@@ -24,6 +24,7 @@ ev_job_thumbnail_get_type
ev_page_cache_get_type
ev_print_operation_get_type
ev_sizing_mode_get_type
+ev_page_layout_get_type
ev_view_get_type
ev_view_presentation_get_type
ev_view_selection_mode_get_type
diff --git a/libview/ev-document-model.c b/libview/ev-document-model.c
index 1a21338..5e22d3f 100644
--- a/libview/ev-document-model.c
+++ b/libview/ev-document-model.c
@@ -35,6 +35,7 @@ struct _EvDocumentModel
gint rotation;
gdouble scale;
EvSizingMode sizing_mode;
+ EvPageLayout page_layout;
guint continuous : 1;
guint dual_page : 1;
guint dual_page_odd_left : 1;
@@ -68,7 +69,8 @@ enum {
PROP_DUAL_PAGE_ODD_LEFT,
PROP_FULLSCREEN,
PROP_MIN_SCALE,
- PROP_MAX_SCALE
+ PROP_MAX_SCALE,
+ PROP_PAGE_LAYOUT
};
enum
@@ -133,6 +135,9 @@ ev_document_model_set_property (GObject *object,
case PROP_CONTINUOUS:
ev_document_model_set_continuous (model, g_value_get_boolean (value));
break;
+ case PROP_PAGE_LAYOUT:
+ ev_document_model_set_page_layout (model, g_value_get_enum (value));
+ break;
case PROP_DUAL_PAGE:
ev_document_model_set_dual_page (model, g_value_get_boolean (value));
break;
@@ -183,6 +188,9 @@ ev_document_model_get_property (GObject *object,
case PROP_CONTINUOUS:
g_value_set_boolean (value, ev_document_model_get_continuous (model));
break;
+ case PROP_PAGE_LAYOUT:
+ g_value_set_enum (value, model->page_layout);
+ break;
case PROP_DUAL_PAGE:
g_value_set_boolean (value, ev_document_model_get_dual_page (model));
break;
@@ -273,6 +281,15 @@ ev_document_model_class_init (EvDocumentModelClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (g_object_class,
+ PROP_PAGE_LAYOUT,
+ g_param_spec_enum ("page-layout",
+ "Page Layout",
+ "Current page layout",
+ EV_TYPE_PAGE_LAYOUT,
+ EV_PAGE_LAYOUT_SINGLE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (g_object_class,
PROP_CONTINUOUS,
g_param_spec_boolean ("continuous",
"Continuous",
@@ -519,6 +536,47 @@ ev_document_model_get_sizing_mode (EvDocumentModel *model)
return model->sizing_mode;
}
+static void
+_ev_document_model_set_dual_page_internal (EvDocumentModel *model,
+ gboolean dual_page)
+{
+ g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
+
+ dual_page = dual_page != FALSE;
+
+ if (dual_page == model->dual_page)
+ return;
+
+ model->dual_page = dual_page;
+
+ g_object_notify (G_OBJECT (model), "dual-page");
+}
+
+void
+ev_document_model_set_page_layout (EvDocumentModel *model,
+ EvPageLayout layout)
+{
+ g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
+
+ if (layout == model->page_layout)
+ return;
+
+ model->page_layout = layout;
+
+ g_object_notify (G_OBJECT (model), "page-layout");
+
+ /* set deprecated property as well */
+ _ev_document_model_set_dual_page_internal (model, layout == EV_PAGE_LAYOUT_DUAL);
+}
+
+EvPageLayout
+ev_document_model_get_page_layout (EvDocumentModel *model)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), EV_PAGE_LAYOUT_SINGLE);
+
+ return model->page_layout;
+}
+
void
ev_document_model_set_rotation (EvDocumentModel *model,
gint rotation)
@@ -596,16 +654,12 @@ void
ev_document_model_set_dual_page (EvDocumentModel *model,
gboolean dual_page)
{
- g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
-
- dual_page = dual_page != FALSE;
-
- if (dual_page == model->dual_page)
- return;
+ EvPageLayout layout;
- model->dual_page = dual_page;
+ g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
- g_object_notify (G_OBJECT (model), "dual-page");
+ layout = dual_page ? EV_PAGE_LAYOUT_DUAL : EV_PAGE_LAYOUT_SINGLE;
+ ev_document_model_set_page_layout (model, layout);
}
gboolean
diff --git a/libview/ev-document-model.h b/libview/ev-document-model.h
index b371d8b..1d12b4a 100644
--- a/libview/ev-document-model.h
+++ b/libview/ev-document-model.h
@@ -41,6 +41,12 @@ typedef enum {
EV_SIZING_AUTOMATIC,
} EvSizingMode;
+typedef enum {
+ EV_PAGE_LAYOUT_SINGLE,
+ EV_PAGE_LAYOUT_DUAL,
+ EV_PAGE_LAYOUT_AUTOMATIC,
+} EvPageLayout;
+
typedef struct _EvDocumentModel EvDocumentModel;
typedef struct _EvDocumentModelClass EvDocumentModelClass;
@@ -68,6 +74,9 @@ gdouble ev_document_model_get_min_scale (EvDocumentModel *model);
void ev_document_model_set_sizing_mode (EvDocumentModel *model,
EvSizingMode mode);
EvSizingMode ev_document_model_get_sizing_mode (EvDocumentModel *model);
+void ev_document_model_set_page_layout (EvDocumentModel *model,
+ EvPageLayout layout);
+EvPageLayout ev_document_model_get_page_layout (EvDocumentModel *model);
void ev_document_model_set_rotation (EvDocumentModel *model,
gint rotation);
gint ev_document_model_get_rotation (EvDocumentModel *model);
@@ -77,9 +86,6 @@ gboolean ev_document_model_get_inverted_colors (EvDocumentModel *model);
void ev_document_model_set_continuous (EvDocumentModel *model,
gboolean continuous);
gboolean ev_document_model_get_continuous (EvDocumentModel *model);
-void ev_document_model_set_dual_page (EvDocumentModel *model,
- gboolean dual_page);
-gboolean ev_document_model_get_dual_page (EvDocumentModel *model);
void ev_document_model_set_dual_page_odd_pages_left (EvDocumentModel *model,
gboolean odd_left);
gboolean ev_document_model_get_dual_page_odd_pages_left (EvDocumentModel *model);
@@ -87,6 +93,14 @@ void ev_document_model_set_fullscreen (EvDocumentModel *model,
gboolean fullscreen);
gboolean ev_document_model_get_fullscreen (EvDocumentModel *model);
+/* deprecated */
+
+EV_DEPRECATED_FOR(ev_document_model_set_page_layout)
+void ev_document_model_set_dual_page (EvDocumentModel *model,
+ gboolean dual_page);
+EV_DEPRECATED_FOR(ev_document_model_get_page_layout)
+gboolean ev_document_model_get_dual_page (EvDocumentModel *model);
+
G_END_DECLS
#endif /* __EV_DOCUMENT_MODEL_H__ */
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 75cac9a..9313a0d 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -163,10 +163,10 @@ struct _EvView {
gboolean can_zoom_in;
gboolean can_zoom_out;
gboolean continuous;
- gboolean dual_page;
gboolean dual_even_left;
gboolean fullscreen;
EvSizingMode sizing_mode;
+ EvPageLayout page_layout;
GtkWidget *loading_window;
guint loading_timeout;
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 7aa2c73..cc676ec 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -497,6 +497,54 @@ ev_view_get_scrollbar_size (EvView *view,
return (orientation == GTK_ORIENTATION_VERTICAL ? req.width : req.height) + spacing;
}
+static gboolean
+is_dual_page (EvView *view,
+ gboolean *odd_left_out)
+{
+ gboolean dual = FALSE;
+ gboolean odd_left = FALSE;
+
+ switch (view->page_layout) {
+ case EV_PAGE_LAYOUT_AUTOMATIC: {
+ GdkScreen *screen;
+ double scale;
+ double doc_width;
+ double doc_height;
+ GtkAllocation allocation;
+ int n_pages;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (view));
+ scale = ev_document_misc_get_screen_dpi (screen) / 72.0;
+
+ ev_document_get_max_page_size (view->document, &doc_width, &doc_height);
+ gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+
+ /* If the width is ok and the height is pretty close, try to fit it in */
+ if (ev_document_get_n_pages (view->document) > 1 &&
+ doc_width < doc_height &&
+ allocation.width > (2 * doc_width * scale) &&
+ allocation.height > (doc_height * scale * 0.9)) {
+ odd_left = !view->dual_even_left;
+ dual = TRUE;
+ }
+ }
+ break;
+ case EV_PAGE_LAYOUT_DUAL:
+ odd_left = !view->dual_even_left;
+ dual = TRUE;
+ break;
+ case EV_PAGE_LAYOUT_SINGLE:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (odd_left_out)
+ *odd_left_out = odd_left;
+
+ return dual;
+}
+
static void
scroll_to_point (EvView *view,
gdouble x,
@@ -524,7 +572,7 @@ scroll_to_point (EvView *view,
upper = gtk_adjustment_get_upper (view->hadjustment);
lower = gtk_adjustment_get_lower (view->hadjustment);
- if (view->dual_page) {
+ if (is_dual_page (view, NULL)) {
gtk_adjustment_clamp_page (view->hadjustment, x,
x + page_size);
} else {
@@ -647,6 +695,7 @@ view_update_range_and_current_page (EvView *view)
{
gint start = view->start_page;
gint end = view->end_page;
+ gboolean odd_left;
if (ev_document_get_n_pages (view->document) <= 0 ||
!ev_document_check_dimensions (view->document))
@@ -689,7 +738,7 @@ view_update_range_and_current_page (EvView *view)
view->end_page = i;
j = 0;
} else if (found && view->current_page <= view->end_page) {
- if (view->dual_page && j < 1) {
+ if (is_dual_page (view, NULL) && j < 1) {
/* In dual mode we stop searching
* after two consecutive non-visible pages.
*/
@@ -709,8 +758,8 @@ view_update_range_and_current_page (EvView *view)
ev_document_model_set_page (view->model, best_current_page);
}
}
- } else if (view->dual_page) {
- if (view->current_page % 2 == view->dual_even_left) {
+ } else if (is_dual_page (view, &odd_left)) {
+ if (view->current_page % 2 == !odd_left) {
view->start_page = view->current_page;
if (view->current_page + 1 < ev_document_get_n_pages (view->document))
view->end_page = view->start_page + 1;
@@ -1096,15 +1145,16 @@ get_page_y_offset (EvView *view, int page, int *y_offset)
{
int offset = 0;
GtkBorder border;
+ gboolean odd_left;
g_return_if_fail (y_offset != NULL);
compute_border (view, &border);
- if (view->dual_page) {
+ if (is_dual_page (view, &odd_left)) {
ev_view_get_height_to_page (view, page, NULL, &offset);
- offset += ((page + view->dual_even_left) / 2 + 1) * view->spacing +
- ((page + view->dual_even_left) / 2 ) * (border.top + border.bottom);
+ offset += ((page + !odd_left) / 2 + 1) * view->spacing +
+ ((page + !odd_left) / 2 ) * (border.top + border.bottom);
} else {
ev_view_get_height_to_page (view, page, &offset, NULL);
offset += (page + 1) * view->spacing + page * (border.top + border.bottom);
@@ -1136,14 +1186,15 @@ ev_view_get_page_extents (EvView *view,
if (view->continuous) {
gint max_width;
gint x, y;
+ gboolean odd_left;
ev_view_get_max_page_size (view, &max_width, NULL);
max_width = max_width + border->left + border->right;
/* Get the location of the bounding box */
- if (view->dual_page) {
- x = view->spacing + ((page % 2 == view->dual_even_left) ? 0 : 1) * (max_width + view->spacing);
+ if (is_dual_page (view, &odd_left)) {
+ x = view->spacing + ((page % 2 == !odd_left) ? 0 : 1) * (max_width + view->spacing);
x = x + MAX (0, allocation.width - (max_width * 2 + view->spacing * 3)) / 2;
- if (page % 2 == view->dual_even_left)
+ if (page % 2 == !odd_left)
x = x + (max_width - width - border->left - border->right);
} else {
x = view->spacing;
@@ -1156,14 +1207,16 @@ ev_view_get_page_extents (EvView *view,
page_area->y = y;
} else {
gint x, y;
- if (view->dual_page) {
+ gboolean odd_left;
+
+ if (is_dual_page (view, &odd_left)) {
gint width_2, height_2;
gint max_width = width;
gint max_height = height;
GtkBorder overall_border;
gint other_page;
- other_page = (page % 2 == view->dual_even_left) ? page + 1: page - 1;
+ other_page = (page % 2 == !odd_left) ? page + 1: page - 1;
/* First, we get the bounding box of the two pages */
if (other_page < ev_document_get_n_pages (view->document)
@@ -1182,7 +1235,7 @@ ev_view_get_page_extents (EvView *view,
y = view->spacing;
/* Adjust for being the left or right page */
- if (page % 2 == view->dual_even_left)
+ if (page % 2 == !odd_left)
x = x + max_width - width;
else
x = x + (max_width + overall_border.left + overall_border.right) + view->spacing;
@@ -3155,6 +3208,7 @@ ev_view_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
EvView *view = EV_VIEW (widget);
+ gboolean dual_page;
if (view->document == NULL) {
view->requisition.width = 1;
@@ -3180,11 +3234,12 @@ ev_view_size_request (GtkWidget *widget,
allocation.height);
}
- if (view->continuous && view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (view->continuous && dual_page)
ev_view_size_request_continuous_dual_page (view, &view->requisition);
else if (view->continuous)
ev_view_size_request_continuous (view, &view->requisition);
- else if (view->dual_page)
+ else if (dual_page)
ev_view_size_request_dual_page (view, &view->requisition);
else
ev_view_size_request_single_page (view, &view->requisition);
@@ -4935,10 +4990,10 @@ ev_view_init (EvView *view)
view->selection_info.in_drag = FALSE;
view->selection_mode = EV_VIEW_SELECTION_TEXT;
view->continuous = TRUE;
- view->dual_page = FALSE;
view->dual_even_left = TRUE;
view->fullscreen = FALSE;
view->sizing_mode = EV_SIZING_FIT_WIDTH;
+ view->page_layout = EV_PAGE_LAYOUT_SINGLE;
view->pending_scroll = SCROLL_TO_KEEP_POSITION;
view->jump_to_find_result = TRUE;
view->highlight_find_results = FALSE;
@@ -5327,6 +5382,23 @@ update_can_zoom (EvView *view)
}
}
+static void
+ev_view_page_layout_changed_cb (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvView *view)
+{
+ EvPageLayout layout = ev_document_model_get_page_layout (model);
+
+ view->page_layout = layout;
+
+ view->pending_scroll = SCROLL_TO_PAGE_POSITION;
+ gtk_widget_queue_resize (GTK_WIDGET (view));
+
+ /* FIXME: if we're keeping the pixbuf cache around, we should extend the
+ * preload_cache_size to be 2 if dual_page is set.
+ */
+}
+
#define EPSILON 0.0000001
static void
ev_view_scale_changed_cb (EvDocumentModel *model,
@@ -5376,19 +5448,6 @@ ev_view_continuous_changed_cb (EvDocumentModel *model,
}
static void
-ev_view_dual_page_changed_cb (EvDocumentModel *model,
- GParamSpec *pspec,
- EvView *view)
-{
- view->dual_page = ev_document_model_get_dual_page (model);
- view->pending_scroll = SCROLL_TO_PAGE_POSITION;
- /* FIXME: if we're keeping the pixbuf cache around, we should extend the
- * preload_cache_size to be 2 if dual_page is set.
- */
- gtk_widget_queue_resize (GTK_WIDGET (view));
-}
-
-static void
ev_view_dual_odd_left_changed_cb (EvDocumentModel *model,
GParamSpec *pspec,
EvView *view)
@@ -5430,7 +5489,7 @@ ev_view_set_model (EvView *view,
view->sizing_mode = ev_document_model_get_sizing_mode (view->model);
view->scale = ev_document_model_get_scale (view->model);
view->continuous = ev_document_model_get_continuous (view->model);
- view->dual_page = ev_document_model_get_dual_page (view->model);
+ view->page_layout = ev_document_model_get_page_layout (view->model);
view->fullscreen = ev_document_model_get_fullscreen (view->model);
ev_view_document_changed_cb (view->model, NULL, view);
@@ -5446,6 +5505,9 @@ ev_view_set_model (EvView *view,
g_signal_connect (view->model, "notify::sizing-mode",
G_CALLBACK (ev_view_sizing_mode_changed_cb),
view);
+ g_signal_connect (view->model, "notify::page-layout",
+ G_CALLBACK (ev_view_page_layout_changed_cb),
+ view);
g_signal_connect (view->model, "notify::scale",
G_CALLBACK (ev_view_scale_changed_cb),
view);
@@ -5458,9 +5520,6 @@ ev_view_set_model (EvView *view,
g_signal_connect (view->model, "notify::continuous",
G_CALLBACK (ev_view_continuous_changed_cb),
view);
- g_signal_connect (view->model, "notify::dual-page",
- G_CALLBACK (ev_view_dual_page_changed_cb),
- view);
g_signal_connect (view->model, "notify::dual-odd-left",
G_CALLBACK (ev_view_dual_odd_left_changed_cb),
view);
@@ -5771,6 +5830,8 @@ ev_view_zoom_for_size (EvView *view,
int width,
int height)
{
+ gboolean dual_page;
+
g_return_if_fail (EV_IS_VIEW (view));
g_return_if_fail (view->sizing_mode == EV_SIZING_FIT_WIDTH ||
view->sizing_mode == EV_SIZING_FIT_PAGE ||
@@ -5781,11 +5842,12 @@ ev_view_zoom_for_size (EvView *view,
if (view->document == NULL)
return;
- if (view->continuous && view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (view->continuous && dual_page)
ev_view_zoom_for_size_continuous_and_dual_page (view, width, height);
else if (view->continuous)
ev_view_zoom_for_size_continuous (view, width, height);
- else if (view->dual_page)
+ else if (dual_page)
ev_view_zoom_for_size_dual_page (view, width, height);
else
ev_view_zoom_for_size_single_page (view, width, height);
@@ -6061,7 +6123,7 @@ compute_new_selection_text (EvView *view,
if (view->continuous) {
start_page = 0;
end_page = n_pages;
- } else if (view->dual_page) {
+ } else if (is_dual_page (view, NULL)) {
start_page = view->start_page;
end_page = view->end_page + 1;
} else {
@@ -6537,6 +6599,7 @@ gboolean
ev_view_next_page (EvView *view)
{
int page, n_pages;
+ gboolean dual_page;
g_return_val_if_fail (EV_IS_VIEW (view), FALSE);
@@ -6546,7 +6609,8 @@ ev_view_next_page (EvView *view)
page = ev_document_model_get_page (view->model);
n_pages = ev_document_get_n_pages (view->document);
- if (view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (dual_page)
page = page + 2;
else
page = page + 1;
@@ -6554,7 +6618,7 @@ ev_view_next_page (EvView *view)
if (page < n_pages) {
ev_document_model_set_page (view->model, page);
return TRUE;
- } else if (view->dual_page && page == n_pages) {
+ } else if (dual_page && page == n_pages) {
ev_document_model_set_page (view->model, page - 1);
return TRUE;
} else {
@@ -6566,6 +6630,7 @@ gboolean
ev_view_previous_page (EvView *view)
{
int page;
+ gboolean dual_page;
g_return_val_if_fail (EV_IS_VIEW (view), FALSE);
@@ -6574,7 +6639,8 @@ ev_view_previous_page (EvView *view)
page = ev_document_model_get_page (view->model);
- if (view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (dual_page)
page = page - 2;
else
page = page - 1;
@@ -6582,7 +6648,7 @@ ev_view_previous_page (EvView *view)
if (page >= 0) {
ev_document_model_set_page (view->model, page);
return TRUE;
- } else if (view->dual_page && page == -1) {
+ } else if (dual_page && page == -1) {
ev_document_model_set_page (view->model, 0);
return TRUE;
} else {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]