From e9eb52f51edd782850c526f4014fada8f5568fcf Mon Sep 17 00:00:00 2001 From: Benedikt Meurer <benny@xfce.org> Date: Tue, 28 Feb 2006 12:12:51 +0000 Subject: [PATCH] 2006-02-28 Benedikt Meurer <benny@xfce.org> * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, thunar/thunar-standard-view.{c,h}: Remember the scroll offset when changing directory and apply saved scroll offset once a folder is loaded again. (Old svn revision: 20131) --- ChangeLog | 7 +++ thunar/thunar-details-view.c | 32 ++++++++++-- thunar/thunar-icon-view.c | 27 ++++++++-- thunar/thunar-standard-view.c | 93 +++++++++++++++++++++++++++++++---- thunar/thunar-standard-view.h | 10 +++- 5 files changed, 152 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c6095383..82f8e94b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-02-28 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-details-view.c, thunar/thunar-icon-view.c, + thunar/thunar-standard-view.{c,h}: Remember the scroll offset when + changing directory and apply saved scroll offset once a folder is + loaded again. + 2006-02-27 Benedikt Meurer <benny@xfce.org> * thunar/thunar-path-entry.c(thunar_path_entry_common_prefix_append): Do diff --git a/thunar/thunar-details-view.c b/thunar/thunar-details-view.c index c27107836..b68f27f52 100644 --- a/thunar/thunar-details-view.c +++ b/thunar/thunar-details-view.c @@ -40,10 +40,16 @@ static void thunar_details_view_set_cursor (ThunarStandardVie GtkTreePath *path, gboolean start_editing); static void thunar_details_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path); + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align); static GtkTreePath *thunar_details_view_get_path_at_pos (ThunarStandardView *standard_view, gint x, gint y); +static gboolean thunar_details_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path); static void thunar_details_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path); static void thunar_details_view_notify_model (GtkTreeView *tree_view, @@ -128,6 +134,7 @@ thunar_details_view_class_init (ThunarDetailsViewClass *klass) thunarstandard_view_class->set_cursor = thunar_details_view_set_cursor; thunarstandard_view_class->scroll_to_path = thunar_details_view_scroll_to_path; thunarstandard_view_class->get_path_at_pos = thunar_details_view_get_path_at_pos; + thunarstandard_view_class->get_visible_range = thunar_details_view_get_visible_range; thunarstandard_view_class->highlight_path = thunar_details_view_highlight_path; thunarstandard_view_class->zoom_level_property_name = "last-details-view-zoom-level"; } @@ -349,7 +356,10 @@ thunar_details_view_set_cursor (ThunarStandardView *standard_view, static void thunar_details_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path) + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align) { GtkTreeViewColumn *column; @@ -357,7 +367,7 @@ thunar_details_view_scroll_to_path (ThunarStandardView *standard_view, /* tell the tree view to scroll to the given row */ column = gtk_tree_view_get_column (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), 0); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), path, column, FALSE, 0.0f, 0.0f); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), path, column, use_align, row_align, col_align); } @@ -379,6 +389,22 @@ thunar_details_view_get_path_at_pos (ThunarStandardView *standard_view, +static gboolean +thunar_details_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path) +{ + g_return_val_if_fail (THUNAR_IS_DETAILS_VIEW (standard_view), FALSE); + +#if GTK_CHECK_VERSION(2,8,0) + return gtk_tree_view_get_visible_range (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), start_path, end_path); +#else + return FALSE; +#endif +} + + + static void thunar_details_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path) diff --git a/thunar/thunar-icon-view.c b/thunar/thunar-icon-view.c index 552471230..f6da88414 100644 --- a/thunar/thunar-icon-view.c +++ b/thunar/thunar-icon-view.c @@ -59,10 +59,16 @@ static void thunar_icon_view_set_cursor (ThunarStandardView GtkTreePath *path, gboolean start_editing); static void thunar_icon_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path); + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align); static GtkTreePath *thunar_icon_view_get_path_at_pos (ThunarStandardView *standard_view, gint x, gint y); +static gboolean thunar_icon_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path); static void thunar_icon_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path); static GtkAction *thunar_icon_view_gesture_action (ThunarIconView *icon_view); @@ -200,6 +206,7 @@ thunar_icon_view_class_init (ThunarIconViewClass *klass) thunarstandard_view_class->set_cursor = thunar_icon_view_set_cursor; thunarstandard_view_class->scroll_to_path = thunar_icon_view_scroll_to_path; thunarstandard_view_class->get_path_at_pos = thunar_icon_view_get_path_at_pos; + thunarstandard_view_class->get_visible_range = thunar_icon_view_get_visible_range; thunarstandard_view_class->highlight_path = thunar_icon_view_highlight_path; thunarstandard_view_class->zoom_level_property_name = "last-icon-view-zoom-level"; @@ -423,10 +430,13 @@ thunar_icon_view_set_cursor (ThunarStandardView *standard_view, static void thunar_icon_view_scroll_to_path (ThunarStandardView *standard_view, - GtkTreePath *path) + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align) { g_return_if_fail (THUNAR_IS_ICON_VIEW (standard_view)); - exo_icon_view_scroll_to_path (EXO_ICON_VIEW (GTK_BIN (standard_view)->child), path, FALSE, 0.0f, 0.0f); + exo_icon_view_scroll_to_path (EXO_ICON_VIEW (GTK_BIN (standard_view)->child), path, use_align, row_align, col_align); } @@ -442,6 +452,17 @@ thunar_icon_view_get_path_at_pos (ThunarStandardView *standard_view, +static gboolean +thunar_icon_view_get_visible_range (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path) +{ + g_return_val_if_fail (THUNAR_IS_ICON_VIEW (standard_view), FALSE); + return exo_icon_view_get_visible_range (EXO_ICON_VIEW (GTK_BIN (standard_view)->child), start_path, end_path); +} + + + static void thunar_icon_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path) diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c index cb94ec318..07d326d17 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -113,6 +113,8 @@ static ThunarFile *thunar_standard_view_get_current_directory (Thu static void thunar_standard_view_set_current_directory (ThunarNavigator *navigator, ThunarFile *current_directory); static gboolean thunar_standard_view_get_loading (ThunarView *view); +static void thunar_standard_view_set_loading (ThunarStandardView *standard_view, + gboolean loading); static const gchar *thunar_standard_view_get_statusbar_text (ThunarView *view); static gboolean thunar_standard_view_get_show_hidden (ThunarView *view); static void thunar_standard_view_set_show_hidden (ThunarView *view, @@ -276,6 +278,9 @@ struct _ThunarStandardViewPrivate * new files are created by a ThunarVfsJob associated with this view */ GClosure *new_files_closure; + + /* scroll offsets (-> GtkTreePath indices) per VFS path */ + GHashTable *scroll_offsets; }; @@ -513,6 +518,10 @@ thunar_standard_view_init (ThunarStandardView *standard_view) standard_view->priv->drag_scroll_timer_id = -1; standard_view->priv->drag_timer_id = -1; + /* setup the scroll paths offset table */ + standard_view->priv->scroll_offsets = g_hash_table_new_full (thunar_vfs_path_hash, thunar_vfs_path_equal, + (GDestroyNotify) thunar_vfs_path_unref, NULL); + /* grab a reference on the preferences */ standard_view->preferences = thunar_preferences_get (); @@ -726,6 +735,9 @@ thunar_standard_view_finalize (GObject *object) /* release our list of currently selected files */ thunar_file_list_free (standard_view->selected_files); + /* destroy the scroll offset table */ + g_hash_table_destroy (standard_view->priv->scroll_offsets); + /* free the statusbar text (if any) */ g_free (standard_view->statusbar_text); @@ -785,7 +797,6 @@ thunar_standard_view_set_property (GObject *object, GParamSpec *pspec) { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (object); - gboolean loading; switch (prop_id) { @@ -794,13 +805,8 @@ thunar_standard_view_set_property (GObject *object, break; case PROP_LOADING: - loading = g_value_get_boolean (value); - if (G_LIKELY (loading != standard_view->loading)) - { - standard_view->loading = loading; - g_object_notify (object, "loading"); - g_object_notify (object, "statusbar-text"); - } + thunar_standard_view_set_loading (standard_view, g_value_get_boolean (value)); + break; break; case PROP_SELECTED_FILES: @@ -973,7 +979,7 @@ thunar_standard_view_set_selected_files (ThunarComponent *component, } /* scroll to the first path (previously determined) */ - (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, first_path); + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, first_path, FALSE, 0.0f, 0.0f); /* release the tree paths */ g_list_foreach (paths, (GFunc) gtk_tree_path_free, NULL); @@ -1084,9 +1090,33 @@ thunar_standard_view_set_current_directory (ThunarNavigator *navigator, { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (navigator); ThunarFolder *folder; + GtkTreePath *path; + ThunarFile *file; + gint offset; g_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); g_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory)); + + /* determine the (previous) current directory */ + file = thunar_navigator_get_current_directory (navigator); + if (G_LIKELY (file != NULL)) + { + /* determine the first visible tree path */ + if ((*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_visible_range) (standard_view, &path, NULL)) + { + /* determine the scroll offset from the tree path */ + offset = gtk_tree_path_get_indices (path)[0] + 1; + gtk_tree_path_free (path); + } + else + { + /* just use the first available path */ + offset = 0; + } + + /* remember the scroll offset for the directory */ + g_hash_table_replace (standard_view->priv->scroll_offsets, thunar_vfs_path_ref (thunar_file_get_path (file)), GINT_TO_POINTER (offset)); + } /* disconnect any previous "loading" binding */ if (G_LIKELY (standard_view->loading_binding != NULL)) @@ -1134,6 +1164,49 @@ thunar_standard_view_get_loading (ThunarView *view) +static void +thunar_standard_view_set_loading (ThunarStandardView *standard_view, + gboolean loading) +{ + GtkTreePath *path; + ThunarFile *file; + gint offset; + + loading = !!loading; + + /* check if we're already in that state */ + if (G_UNLIKELY (standard_view->loading == loading)) + return; + + /* apply the new state */ + standard_view->loading = loading; + + /* check if this state change was due to a "loading complete" event */ + if (G_LIKELY (!loading)) + { + /* determine the current directory */ + file = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); + if (G_LIKELY (file != NULL)) + { + /* determine the scroll offset for this folder */ + offset = GPOINTER_TO_INT (g_hash_table_lookup (standard_view->priv->scroll_offsets, thunar_file_get_path (file))); + if (G_LIKELY (offset > 0)) + { + /* scroll to the path for the offset */ + path = gtk_tree_path_new_from_indices (offset - 1, -1); + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, path, TRUE, 0.0f, 0.0f); + gtk_tree_path_free (path); + } + } + } + + /* notify listeners */ + g_object_notify (G_OBJECT (standard_view), "loading"); + g_object_notify (G_OBJECT (standard_view), "statusbar-text"); +} + + + static const gchar* thunar_standard_view_get_statusbar_text (ThunarView *view) { @@ -2123,7 +2196,7 @@ thunar_standard_view_action_rename (GtkAction *action, if (G_LIKELY (path_list != NULL)) { /* place the cursor on the file and scroll the new position */ - (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, path_list->data); + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->scroll_to_path) (standard_view, path_list->data, FALSE, 0.0f, 0.0f); /* update the selection, so we get updated actions, statusbar, * etc. with the new file name and probably new mime type. diff --git a/thunar/thunar-standard-view.h b/thunar/thunar-standard-view.h index 03c01dcf6..0e3103317 100644 --- a/thunar/thunar-standard-view.h +++ b/thunar/thunar-standard-view.h @@ -78,7 +78,10 @@ struct _ThunarStandardViewClass * scroll the view to the given path. */ void (*scroll_to_path) (ThunarStandardView *standard_view, - GtkTreePath *path); + GtkTreePath *path, + gboolean use_align, + gfloat row_align, + gfloat col_align); /* Returns the path at the given position or NULL if no item/row * is located at that coordinates. The path is freed by the caller. @@ -87,6 +90,11 @@ struct _ThunarStandardViewClass gint x, gint y); + /* Returns the visible range */ + gboolean (*get_visible_range) (ThunarStandardView *standard_view, + GtkTreePath **start_path, + GtkTreePath **end_path); + /* Sets the item/row that is highlighted for feedback. NULL is * passed for path to disable the highlighting. */ -- GitLab