[evince/30-null-page-in-thumbnail-display-desirable] sidebar-thumbnails: display a first blank thumbnail
- From: Germán Poo-Caamaño <gpoo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/30-null-page-in-thumbnail-display-desirable] sidebar-thumbnails: display a first blank thumbnail
- Date: Mon, 7 Jan 2019 19:22:41 +0000 (UTC)
commit c2d3dea6e8262e4588397a9888809b10f64bb077
Author: Nelson Benítez León <nbenitezl gmail com>
Date: Tue Sep 25 00:05:04 2018 +0500
sidebar-thumbnails: display a first blank thumbnail
when following conditions are met:
- We are in dual page mode
- Option for "odd pages on left side" is off
- We are using the GtkIconView (TODO: GtkTreeView implementation)
- GtkIconView is displaying two columns of thumbnails
This blank thumbnail can't be selected, and we make sure
the page count logic (when relying on number of items in IconView)
is updated accordingly when we are displaying the blank thumbnail.
The blank thumbnail item can be distinguished among all other items
in the GtkIconView as it's the only one which has the COLUMN_SURFACE
as NULL while COLUMN_THUMBNAIL_SET is set to TRUE.
Fixes Issue #30
shell/ev-sidebar-thumbnails.c | 177 +++++++++++++++++++++++++++++++++++++++++-
shell/ev-window.c | 16 ++++
shell/ev-window.h | 1 +
3 files changed, 193 insertions(+), 1 deletion(-)
---
diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c
index a0a27f75..7aa20077 100644
--- a/shell/ev-sidebar-thumbnails.c
+++ b/shell/ev-sidebar-thumbnails.c
@@ -75,7 +75,8 @@ struct _EvSidebarThumbnailsPrivate {
int rotation;
gboolean inverted_colors;
-
+ gboolean blank_first_dual_mode; /* flag for when we're using a blank first thumbnail
+ * for dual mode with !odd_left preference. Issue #30 */
/* Visible pages */
gint start_page, end_page;
};
@@ -104,6 +105,7 @@ static void thumbnail_job_completed_callback (EvJobThumbnail
EvSidebarThumbnails *sidebar_thumbnails);
static void ev_sidebar_thumbnails_reload (EvSidebarThumbnails *sidebar_thumbnails);
static void adjustment_changed_cb (EvSidebarThumbnails *sidebar_thumbnails);
+static void check_toggle_blank_first_dual_mode (EvSidebarThumbnails *sidebar_thumbnails);
G_DEFINE_TYPE_EXTENDED (EvSidebarThumbnails,
ev_sidebar_thumbnails,
@@ -515,6 +517,9 @@ add_range (EvSidebarThumbnails *sidebar_thumbnails,
g_assert (start_page <= end_page);
+ if (priv->blank_first_dual_mode)
+ page--;
+
path = gtk_tree_path_new_from_indices (start_page, -1);
for (result = gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->list_store), &iter, path);
result && page <= end_page;
@@ -729,6 +734,17 @@ ev_sidebar_icon_selection_changed (GtkIconView *icon_view,
path = selected->data;
page = gtk_tree_path_get_indices (path)[0];
+ if (priv->blank_first_dual_mode) {
+ if (page == 0) {
+ gtk_icon_view_unselect_path (icon_view, path);
+ gtk_tree_path_free (path);
+ g_list_free (selected);
+ return;
+ }
+ page--;
+
+ }
+
gtk_tree_path_free (path);
g_list_free (selected);
@@ -796,6 +812,18 @@ ev_sidebar_init_icon_view (EvSidebarThumbnails *ev_sidebar_thumbnails)
g_signal_connect (priv->icon_view, "selection-changed",
G_CALLBACK (ev_sidebar_icon_selection_changed), ev_sidebar_thumbnails);
+ g_signal_connect_swapped (priv->icon_view, "size-allocate",
+ G_CALLBACK (check_toggle_blank_first_dual_mode), ev_sidebar_thumbnails);
+
+ g_signal_connect_data (priv->model, "notify::dual-page",
+ G_CALLBACK (check_toggle_blank_first_dual_mode), ev_sidebar_thumbnails,
+ NULL, G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+ g_signal_connect_data (priv->model, "notify::dual-odd-left",
+ G_CALLBACK (check_toggle_blank_first_dual_mode), ev_sidebar_thumbnails,
+ NULL, G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+ check_toggle_blank_first_dual_mode (ev_sidebar_thumbnails);
gtk_container_add (GTK_CONTAINER (priv->swindow), priv->icon_view);
gtk_widget_show (priv->icon_view);
}
@@ -839,6 +867,7 @@ ev_sidebar_thumbnails_init (EvSidebarThumbnails *ev_sidebar_thumbnails)
guint signal_id;
priv = ev_sidebar_thumbnails->priv = EV_SIDEBAR_THUMBNAILS_GET_PRIVATE (ev_sidebar_thumbnails);
+ priv->blank_first_dual_mode = FALSE;
priv->list_store = gtk_list_store_new (NUM_COLUMNS,
G_TYPE_STRING,
@@ -879,6 +908,9 @@ ev_sidebar_thumbnails_set_current_page (EvSidebarThumbnails *sidebar,
GtkTreeView *tree_view;
GtkTreePath *path;
+ if (sidebar->priv->blank_first_dual_mode)
+ page++;
+
path = gtk_tree_path_new_from_indices (page, -1);
if (sidebar->priv->tree_view) {
@@ -1145,3 +1177,146 @@ ev_sidebar_thumbnails_page_iface_init (EvSidebarPageInterface *iface)
iface->set_model = ev_sidebar_thumbnails_set_model;
iface->get_label = ev_sidebar_thumbnails_get_label;
}
+
+static gboolean
+iter_is_blank_thumbnail (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ cairo_surface_t *surface = NULL;
+ EvJob *job = NULL;
+ gboolean thumbnail_set = FALSE;
+
+ gtk_tree_model_get (tree_model, iter,
+ COLUMN_SURFACE, &surface,
+ COLUMN_THUMBNAIL_SET, &thumbnail_set,
+ COLUMN_JOB, &job, -1);
+
+ /* The blank thumbnail item can be distinguished among all
+ * other items in the GtkIconView as it's the only one which
+ * has the COLUMN_SURFACE as NULL while COLUMN_THUMBNAIL_SET
+ * is set to TRUE. */
+ return surface == NULL && job == NULL && thumbnail_set;
+}
+
+/* Returns the total horizontal(left+right) width of thumbnail frames.
+ * As it was added in ev_document_misc_render_thumbnail_frame() */
+static gint
+ev_sidebar_thumbnails_frame_horizontal_width (EvSidebarThumbnails *sidebar)
+{
+ GtkWidget *widget;
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder border = {0, };
+ gint offset;
+
+ widget = GTK_WIDGET (sidebar);
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_widget_get_state_flags (widget);
+
+ gtk_style_context_save (context);
+
+ gtk_style_context_add_class (context, "page-thumbnail");
+ gtk_style_context_get_border (context, state, &border);
+ offset = border.left + border.right;
+
+ gtk_style_context_restore (context);
+
+ return offset;
+}
+
+/* Returns whether the thumbnail sidebar is currently showing
+ * items in a two columns layout */
+static gboolean
+ev_sidebar_thumbnails_is_two_columns (EvSidebarThumbnails *sidebar)
+{
+ EvSidebarThumbnailsPrivate *priv;
+ GtkWidget *window;
+ GtkIconView *icon_view;
+ gint sidebar_width, two_columns_width, three_columns_width;
+ gint margin, column_spacing, item_padding, thumbnail_width;
+ static gint frame_horizontal_width;
+
+ if (!ev_sidebar_thumbnails_use_icon_view (sidebar))
+ return FALSE;
+
+ priv = sidebar->priv;
+ icon_view = GTK_ICON_VIEW (priv->icon_view);
+
+ ev_thumbnails_size_cache_get_size (priv->size_cache, 0,
+ priv->rotation,
+ &thumbnail_width, NULL);
+
+ margin = gtk_icon_view_get_margin (icon_view);
+ column_spacing = gtk_icon_view_get_column_spacing (icon_view);
+ item_padding = gtk_icon_view_get_item_padding (icon_view);
+ frame_horizontal_width = ev_sidebar_thumbnails_frame_horizontal_width (sidebar);
+
+ two_columns_width = 2 * margin +
+ 4 * item_padding +
+ 2 * frame_horizontal_width +
+ 2 * thumbnail_width +
+ column_spacing;
+
+ three_columns_width = 2 * margin +
+ 6 * item_padding +
+ 3 * frame_horizontal_width +
+ 3 * thumbnail_width +
+ 2 * column_spacing;
+
+ if (priv->width == 0) {
+ window = gtk_widget_get_toplevel (GTK_WIDGET (sidebar));
+ sidebar_width = ev_window_get_metadata_sidebar_size (EV_WINDOW (window));
+ } else {
+ sidebar_width = priv->width;
+ }
+
+ return sidebar_width >= two_columns_width &&
+ sidebar_width < three_columns_width;
+}
+
+/* Checks whether the conditions for 'blank first dual mode' are met,
+ * and activates/deactivates the mode accordingly. */
+static void
+check_toggle_blank_first_dual_mode (EvSidebarThumbnails *sidebar_thumbnails)
+{
+ EvSidebarThumbnailsPrivate *priv;
+ GtkTreeModel *tree_model;
+ GtkTreeIter first;
+ gboolean should_be_enabled;
+
+ priv = sidebar_thumbnails->priv;
+
+ should_be_enabled = ev_document_model_get_dual_page (priv->model) &&
+ !ev_document_model_get_dual_page_odd_pages_left (priv->model) &&
+ ev_sidebar_thumbnails_is_two_columns (sidebar_thumbnails);
+
+ if (should_be_enabled && !priv->blank_first_dual_mode) {
+ /* Do enable it */
+ tree_model = GTK_TREE_MODEL (priv->list_store);
+
+ if (!gtk_tree_model_get_iter_first (tree_model, &first))
+ return;
+
+ priv->blank_first_dual_mode = TRUE;
+ if (iter_is_blank_thumbnail (tree_model, &first))
+ return; /* extra check */
+
+ gtk_list_store_insert_with_values (priv->list_store, &first, 0,
+ COLUMN_SURFACE, NULL,
+ COLUMN_THUMBNAIL_SET, TRUE,
+ COLUMN_JOB, NULL,
+ -1);
+ } else if (!should_be_enabled && priv->blank_first_dual_mode) {
+ /* Do disable it */
+ tree_model = GTK_TREE_MODEL (priv->list_store);
+
+ if (!gtk_tree_model_get_iter_first (tree_model, &first))
+ return;
+
+ priv->blank_first_dual_mode = FALSE;
+ if (!iter_is_blank_thumbnail (tree_model, &first))
+ return; /* extra check */
+
+ gtk_list_store_remove (priv->list_store, &first);
+ }
+}
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 86bc7070..21bb599b 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -7852,3 +7852,19 @@ ev_window_get_metadata (EvWindow *ev_window)
return priv->metadata;
}
+
+gint
+ev_window_get_metadata_sidebar_size (EvWindow *ev_window)
+{
+ EvWindowPrivate *priv;
+ gint sidebar_size;
+
+ g_return_val_if_fail (EV_WINDOW (ev_window), 0);
+
+ priv = GET_PRIVATE (ev_window);
+
+ if (ev_metadata_get_int (priv->metadata, "sidebar_size", &sidebar_size))
+ return sidebar_size;
+
+ return 0;
+}
diff --git a/shell/ev-window.h b/shell/ev-window.h
index e8a8cdda..3b8be3ae 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -96,6 +96,7 @@ GtkWidget *ev_window_get_toolbar (EvWindow *ev_window);
void ev_window_handle_annot_popup (EvWindow *ev_window,
EvAnnotation *annot);
EvMetadata *ev_window_get_metadata (EvWindow *ev_window);
+gint ev_window_get_metadata_sidebar_size (EvWindow *ev_window);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]