[gthumb] grid view: use an array instead of a list to save the items
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] grid view: use an array instead of a list to save the items
- Date: Sat, 19 Jun 2021 18:10:39 +0000 (UTC)
commit 5dfbb9e7cb5e25d24c60ff6d72960d92d4360e59
Author: Paolo Bacchilega <paobac src gnome org>
Date: Fri May 21 20:03:46 2021 +0200
grid view: use an array instead of a list to save the items
This speeds up navigation when a directory contains
thousands of images.
gthumb/gth-grid-view.c | 214 ++++++++++++++++---------------------------------
1 file changed, 68 insertions(+), 146 deletions(-)
---
diff --git a/gthumb/gth-grid-view.c b/gthumb/gth-grid-view.c
index a10cc3e9..fc9e4cb8 100644
--- a/gthumb/gth-grid-view.c
+++ b/gthumb/gth-grid-view.c
@@ -131,7 +131,7 @@ typedef struct {
struct _GthGridViewPrivate {
GtkTreeModel *model;
- GList *items;
+ GPtrArray *itemv;
int n_items;
GList *lines;
GList *selection;
@@ -397,9 +397,9 @@ _gth_grid_view_free_lines (GthGridView *self)
static void
_gth_grid_view_free_items (GthGridView *self)
{
- g_list_foreach (self->priv->items, (GFunc) gth_grid_view_item_unref, NULL);
- g_list_free (self->priv->items);
- self->priv->items = NULL;
+ g_ptr_array_unref (self->priv->itemv);
+ self->priv->itemv = NULL;
+ self->priv->n_items = 0;
g_list_free (self->priv->selection);
self->priv->selection = NULL;
@@ -838,18 +838,14 @@ _gth_grid_view_relayout_at (GthGridView *self,
int items_per_line;
GList *items;
int max_height;
- GList *scan;
int n;
new_lines = NULL;
items_per_line = gth_grid_view_get_items_per_line (self);
items = NULL;
max_height = 0;
- for (scan = g_list_nth (self->priv->items, pos), n = pos;
- scan;
- scan = scan->next, n++)
- {
- GthGridViewItem *item = scan->data;
+ for (n = pos; n < self->priv->n_items; n++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, n);
if ((n % items_per_line) == 0) {
if (items != NULL) {
@@ -1660,7 +1656,7 @@ _gth_grid_view_draw_drop_target (GthGridView *self,
style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
- item = g_list_nth (self->priv->items, self->priv->drop_item)->data;
+ item = g_ptr_array_index (self->priv->itemv, self->priv->drop_item);
x = 0;
if (self->priv->drop_pos == GTH_DROP_POSITION_LEFT)
@@ -1711,17 +1707,14 @@ gth_grid_view_draw (GtkWidget *widget,
first_visible = gth_grid_view_get_first_visible (GTH_FILE_VIEW (self));
if (first_visible >= 0) {
- int last_visible;
- int i;
- GList *scan;
+ int last_visible;
+ int i;
last_visible = gth_grid_view_get_last_visible (GTH_FILE_VIEW (self));
- for (i = first_visible, scan = g_list_nth (self->priv->items, first_visible);
- (i <= last_visible) && scan;
- i++, scan = scan->next)
- {
- _gth_grid_view_draw_item (self, GTH_GRID_VIEW_ITEM (scan->data), cr);
+ for (i = first_visible; i <= last_visible; i++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, i);
+ _gth_grid_view_draw_item (self, item, cr);
}
if (self->priv->selecting || self->priv->multi_selecting_with_keyboard)
@@ -1856,7 +1849,6 @@ static void
_gth_grid_view_select_item (GthGridView *self,
int pos)
{
- GList *link;
GthGridViewItem *item;
g_return_if_fail ((pos >= 0) && (pos < self->priv->n_items));
@@ -1864,10 +1856,7 @@ _gth_grid_view_select_item (GthGridView *self,
if (self->priv->selection_mode == GTK_SELECTION_NONE)
return;
- link = g_list_nth (self->priv->items, pos);
- g_return_if_fail (link != NULL);
-
- item = link->data;
+ item = g_ptr_array_index (self->priv->itemv, pos);
if (item->state & GTK_STATE_FLAG_SELECTED)
return;
@@ -1883,7 +1872,6 @@ static void
_gth_grid_view_unselect_item (GthGridView *self,
int pos)
{
- GList *link;
GthGridViewItem *item;
g_return_if_fail ((pos >= 0) && (pos < self->priv->n_items));
@@ -1891,11 +1879,7 @@ _gth_grid_view_unselect_item (GthGridView *self,
if (self->priv->selection_mode == GTK_SELECTION_NONE)
return;
- link = g_list_nth (self->priv->items, pos);
- g_return_if_fail (link != NULL);
-
- item = link->data;
-
+ item = g_ptr_array_index (self->priv->itemv, pos);
if (! (item->state & GTK_STATE_FLAG_SELECTED))
return;
@@ -1943,17 +1927,12 @@ static int
_gth_grid_view_unselect_all (GthGridView *self,
gpointer keep_selected)
{
- GthGridViewPrivate *priv = self->priv;
- int idx;
- GList *scan;
- int i;
+ int idx;
+ int i;
idx = 0;
- for (scan = priv->items, i = 0;
- scan != NULL;
- scan = scan->next, i++)
- {
- GthGridViewItem *item = scan->data;
+ for (i = 0; i < self->priv->n_items; i++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, i);
if (item == keep_selected)
idx = i;
@@ -1970,16 +1949,12 @@ gth_grid_view_select (GthFileSelection *selection,
int pos)
{
GthGridView *self = GTH_GRID_VIEW (selection);
- GList *list;
int i;
switch (self->priv->selection_mode) {
case GTK_SELECTION_SINGLE:
- for (list = self->priv->items, i = 0;
- list != NULL;
- list = list->next, i++)
- {
- GthGridViewItem *item = list->data;
+ for (i = 0; i < self->priv->n_items; i++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, i);
if ((i != pos) && (item->state & GTK_STATE_FLAG_SELECTED))
_gth_grid_view_set_item_selected (self, FALSE, i);
@@ -2012,14 +1987,10 @@ gth_grid_view_unselect (GthFileSelection *selection,
static void
_gth_grid_view_select_all (GthGridView *self)
{
- GList *scan;
- int i;
+ int i;
- for (scan = self->priv->items, i = 0;
- scan != NULL;
- scan = scan->next, i++)
- {
- GthGridViewItem *item = scan->data;
+ for (i = 0; i < self->priv->n_items; i++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, i);
if (! (item->state & GTK_STATE_FLAG_SELECTED))
_gth_grid_view_set_item_selected (self, TRUE, i);
@@ -2118,7 +2089,6 @@ model_row_changed_cb (GtkTreeModel *tree_model,
{
GthGridView *self = user_data;
int pos;
- GList *link;
GthFileData *file_data;
cairo_surface_t *thumbnail;
gboolean is_icon;
@@ -2132,10 +2102,7 @@ model_row_changed_cb (GtkTreeModel *tree_model,
-1);
pos = gtk_tree_path_get_indices (path)[0];
- link = g_list_nth (self->priv->items, pos);
- g_return_if_fail (link != NULL);
-
- item = GTH_GRID_VIEW_ITEM (link->data);
+ item = g_ptr_array_index (self->priv->itemv, pos);
gth_grid_view_item_set_file_data (item, file_data);
gth_grid_view_item_set_thumbnail (item, thumbnail);
item->is_icon = is_icon;
@@ -2155,14 +2122,12 @@ model_row_deleted_cb (GtkTreeModel *tree_model,
{
GthGridView *self = user_data;
int pos;
- GList *link;
GList *scan;
GList *selected_link;
pos = gtk_tree_path_get_indices (path)[0];
- link = g_list_nth (self->priv->items, pos);
- self->priv->items = g_list_remove_link (self->priv->items, link);
- self->priv->n_items--;
+ g_ptr_array_remove_index (self->priv->itemv, pos);
+ self->priv->n_items = (int) self->priv->itemv->len;
/* update the selection */
@@ -2196,9 +2161,6 @@ model_row_deleted_cb (GtkTreeModel *tree_model,
/* relayout from the minimum changed position */
_gth_grid_view_queue_relayout_from_position (self, pos);
-
- gth_grid_view_item_unref (GTH_GRID_VIEW_ITEM (link->data));
- g_list_free (link);
}
@@ -2228,8 +2190,8 @@ model_row_inserted_cb (GtkTreeModel *tree_model,
is_icon,
self->priv->caption_attributes_v);
pos = gtk_tree_path_get_indices (path)[0];
- self->priv->items = g_list_insert (self->priv->items, item, pos);
- self->priv->n_items++;
+ g_ptr_array_insert (self->priv->itemv, pos, item);
+ self->priv->n_items = (int) self->priv->itemv->len;
/* update the selection */
@@ -2266,7 +2228,7 @@ model_rows_reordered_cb (GtkTreeModel *tree_model,
gpointer user_data)
{
GthGridView *self = user_data;
- GList *items;
+ GPtrArray *itemv;
int i;
int min_changed_pos;
gboolean focused_updated = FALSE;
@@ -2275,10 +2237,10 @@ model_rows_reordered_cb (GtkTreeModel *tree_model,
/* change the order of the items list */
min_changed_pos = -1;
- items = NULL;
+ itemv = g_ptr_array_new_full (self->priv->n_items, (GDestroyNotify) gth_grid_view_item_unref);
for (i = 0; i < self->priv->n_items; i++) {
- GList *link;
- int old_pos;
+ int old_pos;
+ GthGridViewItem *item;
old_pos = ((int *) new_order)[i];
if ((min_changed_pos == -1) && (old_pos != i))
@@ -2291,14 +2253,13 @@ model_rows_reordered_cb (GtkTreeModel *tree_model,
focused_updated = TRUE;
}
- link = g_list_nth (self->priv->items, old_pos);
- g_return_if_fail (link != NULL);
- items = g_list_prepend (items, link->data);
+ item = g_ptr_array_index (self->priv->itemv, old_pos);
+ g_ptr_array_add (itemv, gth_grid_view_item_ref (item));
}
- items = g_list_reverse (items);
- g_list_free (self->priv->items);
- self->priv->items = items;
+ g_ptr_array_unref (self->priv->itemv);
+ self->priv->itemv = itemv;
+ self->priv->n_items = (int) self->priv->itemv->len;
/* update the selection */
@@ -2330,7 +2291,6 @@ model_thumbnail_changed_cb (GtkTreeModel *tree_model,
{
GthGridView *self = user_data;
int pos;
- GList *link;
cairo_surface_t *thumbnail;
gboolean is_icon;
GthGridViewItem *item;
@@ -2342,10 +2302,7 @@ model_thumbnail_changed_cb (GtkTreeModel *tree_model,
-1);
pos = gtk_tree_path_get_indices (path)[0];
- link = g_list_nth (self->priv->items, pos);
- g_return_if_fail (link != NULL);
-
- item = GTH_GRID_VIEW_ITEM (link->data);
+ item = g_ptr_array_index (self->priv->itemv, pos);
gth_grid_view_item_set_thumbnail (item, thumbnail);
item->is_icon = is_icon;
@@ -2404,14 +2361,10 @@ _gth_grid_view_get_at_position (GthGridView *self,
int y,
GthGridViewItem **item_ref)
{
- GList *scan;
- int n;
+ int n;
- for (scan = self->priv->items, n = 0;
- scan != NULL;
- scan = scan->next, n++)
- {
- GthGridViewItem *item = scan->data;
+ for (n = 0; n < self->priv->n_items; n++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, n);
if (_cairo_rectangle_contains_point (&item->thumbnail_area, x, y)
|| _cairo_rectangle_contains_point (&item->caption_area, x, y))
@@ -2443,29 +2396,20 @@ gth_grid_view_cursor_changed (GthFileView *file_view,
int pos)
{
GthGridView *self = GTH_GRID_VIEW (file_view);
- GList *link;
GthGridViewItem *new_item;
- if (pos != self->priv->focused_item) {
+ if ((pos != self->priv->focused_item) && (self->priv->focused_item >= 0)) {
GthGridViewItem *old_item = NULL;
- if (self->priv->focused_item >= 0) {
- link = g_list_nth (self->priv->items, self->priv->focused_item);
- if (link != NULL)
- old_item = link->data;
- }
+ old_item = g_ptr_array_index (self->priv->itemv, self->priv->focused_item);
if (old_item != NULL) {
old_item->state ^= GTK_STATE_FLAG_FOCUSED | GTK_STATE_FLAG_ACTIVE;
_gth_grid_view_queue_draw_item (self, old_item);
}
}
- link = g_list_nth (self->priv->items, pos);
- g_return_if_fail (link != NULL);
-
self->priv->focused_item = pos;
-
- new_item = link->data;
+ new_item = g_ptr_array_index (self->priv->itemv, pos);
new_item->state |= GTK_STATE_FLAG_FOCUSED | GTK_STATE_FLAG_ACTIVE;
_gth_grid_view_queue_draw_item (self, new_item);
@@ -2603,7 +2547,7 @@ gth_grid_view_set_drag_dest_pos (GthFileView *file_view,
drop_pos = GTH_DROP_POSITION_RIGHT;
}
else {
- GthGridViewItem *item = g_list_nth (self->priv->items, drop_image)->data;
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, drop_image);
if (x - item->area.x > self->priv->cell_size / 2)
drop_pos = GTH_DROP_POSITION_RIGHT;
else
@@ -2661,8 +2605,7 @@ _gth_grid_view_select_range (GthGridView *self,
GthGridViewItem *item,
int pos)
{
- int a, b;
- GList *scan;
+ int a, b;
if (self->priv->last_selected_pos == -1)
self->priv->last_selected_pos = pos;
@@ -2676,11 +2619,8 @@ _gth_grid_view_select_range (GthGridView *self,
b = pos;
}
- for (scan = g_list_nth (self->priv->items, a);
- (a <= b) && (scan != NULL);
- a++, scan = scan->next)
- {
- GthGridViewItem *item = scan->data;
+ for (/* void */; a <= b; a++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, a);
if (! (item->state & GTK_STATE_FLAG_SELECTED))
_gth_grid_view_set_item_selected (self, TRUE, a);
@@ -2751,10 +2691,10 @@ _gth_grid_view_select_multiple (GthGridView *self,
static void
gth_grid_view_store_items_state (GthGridView *self)
{
- GList *scan;
+ int i;
- for (scan = self->priv->items; scan; scan = scan->next) {
- GthGridViewItem *item = scan->data;
+ for (i = 0; i < self->priv->n_items; i++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, i);
item->tmp_state = item->state;
}
}
@@ -2898,7 +2838,6 @@ _gth_grid_view_update_mouse_selection (GthGridView *self,
gboolean additive;
gboolean invert;
int min_y, max_y;
- GList *l, *begin, *end;
int i, begin_idx, end_idx;
old_selection_area = self->priv->selection_area;
@@ -2973,13 +2912,9 @@ _gth_grid_view_update_mouse_selection (GthGridView *self,
max_y = self->priv->selection_area.y + self->priv->selection_area.height;
begin_idx = get_first_visible_at_offset (self, min_y);
- begin = g_list_nth (self->priv->items, begin_idx);
-
end_idx = get_last_visible_at_offset (self, max_y);
- end = g_list_nth (self->priv->items, end_idx);
-
- if (end != NULL)
- end = end->next;
+ if ((begin_idx == -1) || (end_idx == -1))
+ return;
gdk_window_freeze_updates (self->priv->bin_window);
@@ -2988,8 +2923,8 @@ _gth_grid_view_update_mouse_selection (GthGridView *self,
x2 = x1 + self->priv->selection_area.width;
y2 = y1 + self->priv->selection_area.height;
- for (l = begin, i = begin_idx; l != end; l = l->next, i++) {
- GthGridViewItem *item = l->data;
+ for (i = begin_idx; i <= end_idx; i++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, i);
gboolean selection_changed;
selection_changed = (item->state & GTK_STATE_FLAG_SELECTED) != (item->tmp_state &
GTK_STATE_FLAG_SELECTED);
@@ -3226,26 +3161,19 @@ static void
select_range_with_keyboard (GthGridView *self,
int next_focused_item)
{
- int begin_idx;
- int end_idx;
- GList *begin;
- GList *end;
- int i;
- GList *link;
+ int begin_idx;
+ int end_idx;
+ int i;
if (self->priv->focused_item == -1)
return;
begin_idx = MIN (MIN (self->priv->first_focused_item, self->priv->focused_item), next_focused_item);
end_idx = MAX (MAX (self->priv->first_focused_item, self->priv->focused_item), next_focused_item);
- begin = g_list_nth (self->priv->items, begin_idx);
- end = g_list_nth (self->priv->items, end_idx);
- if (end != NULL)
- end = end->next;
gdk_window_freeze_updates (self->priv->bin_window);
- for (link = begin, i = begin_idx; link != end; link = link->next, i++) {
+ for (i = begin_idx; i <= end_idx; i++) {
if (next_focused_item > self->priv->first_focused_item) {
if ((i >= self->priv->first_focused_item) && (i <= next_focused_item))
_gth_grid_view_select_item (self, i);
@@ -3270,14 +3198,10 @@ static GList *
_gth_grid_view_get_line_at_position (GthGridView *self,
int pos)
{
- GList *link;
GthGridViewItem *item;
GList *scan;
- link = g_list_nth (self->priv->items, pos);
- g_return_val_if_fail (link != NULL, NULL);
-
- item = link->data;
+ item = g_ptr_array_index (self->priv->itemv, pos);
for (scan = self->priv->lines; scan; scan = scan->next) {
GthGridViewLine *line = scan->data;
@@ -3420,7 +3344,7 @@ gth_grid_view_select_cursor_item (GthGridView *self)
if (self->priv->focused_item == -1)
return FALSE;
- item = g_list_nth (self->priv->items, self->priv->focused_item)->data;
+ item = g_ptr_array_index (self->priv->itemv, self->priv->focused_item);
g_return_val_if_fail (item != NULL, FALSE);
_gth_grid_view_unselect_all (self, item);
@@ -3435,16 +3359,12 @@ gth_grid_view_select_cursor_item (GthGridView *self)
static gboolean
gth_grid_view_toggle_cursor_item (GthGridView *self)
{
- GList *link;
GthGridViewItem *item;
if (self->priv->focused_item == -1)
return FALSE;
- link = g_list_nth (self->priv->items, self->priv->focused_item);
- g_return_val_if_fail (link != NULL, FALSE);
-
- item = link->data;
+ item = g_ptr_array_index (self->priv->itemv, self->priv->focused_item);
if (item->state & GTK_STATE_FLAG_SELECTED)
_gth_grid_view_unselect_item (self, self->priv->focused_item);
else
@@ -3558,7 +3478,7 @@ static void
_gth_grid_view_set_caption (GthGridView *self,
const char *attributes)
{
- GList *scan;
+ int i;
g_free (self->priv->caption_attributes);
self->priv->caption_attributes = g_strdup (attributes);
@@ -3572,8 +3492,10 @@ _gth_grid_view_set_caption (GthGridView *self,
self->priv->no_caption = (self->priv->caption_attributes_v == NULL) ||
(self->priv->caption_attributes_v[0] == NULL) || (g_strcmp0 (self->priv->caption_attributes_v[0], "none") ==
0);
- for (scan = self->priv->items; scan; scan = scan->next)
- gth_grid_view_item_update_caption (GTH_GRID_VIEW_ITEM (scan->data),
self->priv->caption_attributes_v);
+ for (i = 0; i < self->priv->n_items; i++) {
+ GthGridViewItem *item = g_ptr_array_index (self->priv->itemv, i);
+ gth_grid_view_item_update_caption (item, self->priv->caption_attributes_v);
+ }
self->priv->update_caption_height = TRUE;
g_object_notify (G_OBJECT (self), "caption");
@@ -3908,7 +3830,7 @@ gth_grid_view_init (GthGridView *self)
self->priv = gth_grid_view_get_instance_private (self);
/* self->priv->model = NULL; */
- self->priv->items = NULL;
+ self->priv->itemv = g_ptr_array_new_with_free_func ((GDestroyNotify) gth_grid_view_item_unref);
self->priv->n_items = 0;
self->priv->lines = NULL;
self->priv->selection = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]