Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
thumbtable.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2011 johannes hanika.
4 Copyright (C) 2012 Christian Tellefsen.
5 Copyright (C) 2012 Richard Wonka.
6 Copyright (C) 2013-2014, 2016 Tobias Ellinghaus.
7 Copyright (C) 2016 Roman Lebedev.
8 Copyright (C) 2020-2021 Aldric Renaudin.
9 Copyright (C) 2020 Bill Ferguson.
10 Copyright (C) 2020, 2022 Philippe Weyland.
11 Copyright (C) 2021-2022 Diederik Ter Rahe.
12 Copyright (C) 2021 domosbg.
13 Copyright (C) 2021 Erkan Ozgur Yilmaz.
14 Copyright (C) 2021 luzpaz.
15 Copyright (C) 2021 Pascal Obry.
16 Copyright (C) 2022-2023, 2025-2026 Aurélien PIERRE.
17 Copyright (C) 2022 Martin Bařinka.
18 Copyright (C) 2026 Guillaume Stutin.
19
20 darktable is free software: you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation, either version 3 of the License, or
23 (at your option) any later version.
24
25 darktable is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with darktable. If not, see <http://www.gnu.org/licenses/>.
32*/
47#include "gui/dtgtk/thumbnail.h"
48#include "common/debug.h"
49#include "common/logging.h"
50
51#include <gtk/gtk.h>
52#include <gdk/gdk.h>
53#include <stdint.h>
54
55#ifndef DT_GUI_DTGTK_THUMBTABLE_H
56#define DT_GUI_DTGTK_THUMBTABLE_H
57
58
69
70
71
83
84
95
96
97// Per-mode layout strategy; defined privately in dtgtk/thumbtable_internal.h and set once in
98// dt_thumbtable_new(). Stored here as an opaque pointer so external callers keep an intact struct
99// without seeing the vtable internals.
101
102typedef struct dt_thumbtable_t
103{
105
106 // Layout strategy selected from `mode` at construction (grid vs. filmstrip frontend).
108
110
111 GtkWidget *grid; // GtkGrid
112
113 // Store the current number of columns in grid
115
116 // Hash table of thumbnails loaded inside main widget (dt_thumbnail_t), keyed by imgid
117 // for filmstrip and filemanager, this is all the images drawn at screen (even partially)
118 // for zoommable, this is all the images in the row drawn at screen. We don't load laterals images on fly.
119 GHashTable *list;
120
121 int thumbs_per_row; // number of image in a row (1 for filmstrip ; MAX_ZOOM for zoomable)
122 int thumb_width; // demanded thumb size (real size can differ of 1 due to rounding)
124 int view_width, view_height; // last main widget size
125
126 gboolean dragging;
127 int last_x, last_y; // last position of cursor during move
128 int drag_dx, drag_dy; // distance of move of the current dragging session
129 dt_thumbnail_t *drag_thumb; // thumb currently dragged (under the mouse)
130
131 // when performing a drag, we store the list of items to drag here
132 // as this can change during the drag and drop (esp. because of the image_over_id)
133 GList *drag_list;
134
135 // nb of thumbnails loaded
136 uint32_t thumb_nb;
137
138 // Set to TRUE once the current collection has been loaded into thumbnails,
139 // reset to FALSE on collection changed events.
140 // When TRUE, we bypass (re)-init of the thumbnails.
143 gboolean configured;
144
145 // Checksum of the collection query for caching
148
151
152 // Our LUT of collection, mapping rowid (index) to imgid (content)
154
156
157 // References to the scrollbar adjustments belonging to the parent widget
158 GtkAdjustment *v_scrollbar;
159 GtkAdjustment *h_scrollbar;
162
163 // Overlay in which we insert the grid, in central view and filmstrip
165
166 // Since GUI and background signals can init/delete/populate/iterate over the same stuff,
167 // ensure iterations don't happen on stuff being deleted at the same time.
168 // Protect only the loops of dynamic size
169 dt_pthread_mutex_t lock;
170
171 // signal that the current collection needs to be entirely flushed unconditionnaly
173
174 // show extended overlays while holding alt key
176
177 // The rowid (aka index in thumbnail sequence) of the last active thumbnail
178 // used as a fallback for missing imgid to sync scrolling when an image is evicted
179 // from current collection
180 int rowid;
181
182 // Set to TRUE to only display the group leader image
184
185 // Thumbnails inner zoom level
187
188 // Show focus regions on thumbnails
191
193
194 // Coalesce layout/scroll updates outside of draw handlers.
197 // Destroys the thumbnails scrolled away from, once the current page is drawn.
199
200 // Last parent overlay allocation (used to ignore no-op size-allocate signals).
203
204 // Last known scrollbar allocation (used to ignore no-op size-allocate signals).
207
209
210
228
244
259void dt_thumbtable_event_dnd_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint target_type, guint time, gpointer user_data);
260
270
271// set zoom level
274
275// offset all the zoomed thumbnails by the same amount
276void dt_thumbtable_offset_zoom(dt_thumbtable_t *table, const double delta_x, const double delta_y);
277
280
283
286
287// signal that the current collection needs to be flushed entirely before being reloaded
289
290gboolean dt_thumbtable_key_released_grid(GtkWidget *self, GdkEventKey *event, gpointer user_data);
291gboolean dt_thumbtable_key_pressed_grid(GtkWidget *self, GdkEventKey *event, gpointer user_data);
292
293// call this when the history of an image is changed and mipmap cache needs updating.
294// reinit = TRUE will force-flush the existing thumbnail. imgid = -1 applies on all thumbnails in thumbtable.
295void dt_thumbtable_refresh_thumbnail_real(dt_thumbtable_t *table, int32_t imgid, gboolean reinit);
301#define dt_thumbtable_refresh_thumbnail(table, imgid, reinit) DT_DEBUG_TRACE_WRAPPER(DT_DEBUG_LIGHTTABLE, dt_thumbtable_refresh_thumbnail_real, (table), (imgid), (reinit))
302
303// Copy cached thumbnail metadata by image id. Returns TRUE on success.
304gboolean dt_thumbtable_get_thumbnail_info(dt_thumbtable_t *table, int32_t imgid, dt_image_t *out);
305
313
322void dt_thumbtable_select_range(dt_thumbtable_t *table, const int rowid);
323
331
341void dt_thumbtable_dispatch_over(dt_thumbtable_t *table, GdkEventType type, int32_t imgid);
342
349int dt_thumbtable_scroll_to_imgid(dt_thumbtable_t *table, int32_t imgid);
350
357
367
375
376// Scroll to the first-selected image, or default to keyboard "over" then mouse "over", then last active image,
377// in this order.
379
385{
387 gtk_widget_queue_draw(table->grid);
388}
389
390#define dt_thumbtable_redraw(table) DT_DEBUG_TRACE_WRAPPER(DT_DEBUG_LIGHTTABLE, dt_thumbtable_redraw_real, (table))
391
398static inline void dt_thumbtable_show(dt_thumbtable_t *table)
399{
400 gtk_widget_show(table->parent_overlay);
401 gtk_widget_show(table->scroll_window);
402 gtk_widget_show(table->grid);
403
404 // Thumbtable is prevented to configure and update, for
405 // as long as it's hidden. We need to force the update now.
407}
408
413static inline void dt_thumbtable_hide(dt_thumbtable_t *table)
414{
415 gtk_widget_hide(table->parent_overlay);
416 gtk_widget_hide(table->scroll_window);
417 gtk_widget_hide(table->grid);
418}
419
420#endif // DT_GUI_DTGTK_THUMBTABLE_H
421
422// clang-format off
423// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
424// vim: shiftwidth=2 expandtab tabstop=2 cindent
425// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
426// clang-format on
static const float x
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
const dt_colormatrix_t dt_aligned_pixel_t out
Call tracing for functions you do not want to edit every caller of.
static gboolean enable(const dt_image_t *image)
Definition highlights.c:879
_lib_location_type_t type
Definition location.c:1
unsigned __int64 uint64_t
Definition strptime.c:75
Cache entry for a single thumbnail.
Definition thumbtable.h:90
dt_thumbnail_t * thumb
Definition thumbtable.h:91
Per-mode layout strategy. One instance per frontend, shared (const) by all tables of that mode and st...
const dt_thumbtable_layout_ops_t * ops
Definition thumbtable.h:107
GHashTable * list
Definition thumbtable.h:119
gboolean focus_peaking
Definition thumbtable.h:190
gboolean collapse_groups
Definition thumbtable.h:183
GtkWidget * grid
Definition thumbtable.h:111
gboolean alternate_mode
Definition thumbtable.h:175
gboolean collection_inited
Definition thumbtable.h:141
dt_thumbtable_mode_t mode
Definition thumbtable.h:104
dt_pthread_mutex_t lock
Definition thumbtable.h:169
gboolean dragging
Definition thumbtable.h:126
int last_h_scrollbar_height
Definition thumbtable.h:205
GtkAdjustment * v_scrollbar
Definition thumbtable.h:158
dt_thumbtable_zoom_t zoom
Definition thumbtable.h:186
int last_v_scrollbar_width
Definition thumbtable.h:206
gboolean focus_regions
Definition thumbtable.h:189
GList * drag_list
Definition thumbtable.h:133
gboolean configured
Definition thumbtable.h:143
GtkWidget * scroll_window
Definition thumbtable.h:155
dt_thumbtable_cache_t * lut
Definition thumbtable.h:153
dt_thumbnail_t * drag_thumb
Definition thumbtable.h:129
gboolean thumbs_inited
Definition thumbtable.h:142
GtkAdjustment * h_scrollbar
Definition thumbtable.h:159
uint32_t thumb_nb
Definition thumbtable.h:136
dt_thumbnail_overlay_t overlays
Definition thumbtable.h:109
gboolean reset_collection
Definition thumbtable.h:172
GtkWidget * parent_overlay
Definition thumbtable.h:164
uint64_t collection_hash
Definition thumbtable.h:146
gboolean draw_group_borders
Definition thumbtable.h:192
dt_thumbnail_overlay_t
Definition thumbnail.h:59
void dt_thumbtable_set_zoom(dt_thumbtable_t *table, dt_thumbtable_zoom_t level)
int dt_thumbtable_scroll_to_selection(dt_thumbtable_t *table)
Scroll to show selected content.
Definition thumbtable.c:458
int dt_thumbtable_scroll_to_imgid(dt_thumbtable_t *table, int32_t imgid)
Scroll the view to show a specific image.
Definition thumbtable.c:425
gboolean dt_thumbtable_get_focus_peaking(dt_thumbtable_t *table)
Definition thumbtable.c:971
void dt_thumbtable_update(dt_thumbtable_t *table)
Definition thumbtable.c:838
void dt_thumbtable_offset_zoom(dt_thumbtable_t *table, const double delta_x, const double delta_y)
void dt_thumbtable_set_active_rowid(dt_thumbtable_t *table)
Update internal active row tracking.
Definition thumbtable.c:382
dt_thumbtable_mode_t
Display modes for the thumbnail table.
Definition thumbtable.h:64
@ DT_THUMBTABLE_MODE_NONE
Definition thumbtable.h:65
@ DT_THUMBTABLE_MODE_FILMSTRIP
Definition thumbtable.h:67
@ DT_THUMBTABLE_MODE_FILEMANAGER
Definition thumbtable.h:66
void dt_thumbtable_apply_grid_configuration(dt_thumbtable_t *table)
Apply grid configuration changes with proper event synchronization.
void dt_thumbtable_configure(dt_thumbtable_t *table)
Definition thumbtable.c:557
void dt_thumbtable_cleanup(dt_thumbtable_t *table)
static void dt_thumbtable_redraw_real(dt_thumbtable_t *table)
Definition thumbtable.h:384
gboolean dt_thumbtable_get_focus_regions(dt_thumbtable_t *table)
Definition thumbtable.c:960
void dt_thumbtable_set_focus_peaking(dt_thumbtable_t *table, gboolean enable)
Definition thumbtable.c:965
void dt_thumbtable_event_dnd_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint target_type, guint time, gpointer user_data)
Handle drag-and-drop data received.
void dt_thumbtable_invert_selection(dt_thumbtable_t *table)
Invert the current selection.
dt_thumbtable_zoom_t
Zoom levels for thumbnail display.
Definition thumbtable.h:77
@ DT_THUMBTABLE_ZOOM_TWICE
Definition thumbtable.h:81
@ DT_THUMBTABLE_ZOOM_FULL
Definition thumbtable.h:80
@ DT_THUMBTABLE_ZOOM_HALF
Definition thumbtable.h:79
@ DT_THUMBTABLE_ZOOM_FIT
Definition thumbtable.h:78
gboolean dt_thumbtable_get_thumbnail_info(dt_thumbtable_t *table, int32_t imgid, dt_image_t *out)
Definition thumbtable.c:607
static void dt_thumbtable_show(dt_thumbtable_t *table)
Show the thumbnail table widget.
Definition thumbtable.h:398
void dt_thumbtable_stop(dt_thumbtable_t *table)
void dt_thumbtable_set_focus_regions(dt_thumbtable_t *table, gboolean enable)
Definition thumbtable.c:954
int dt_thumbtable_scroll_to_active_rowid(dt_thumbtable_t *table)
Scroll to show the active row.
Definition thumbtable.c:448
gboolean dt_thumbtable_get_draw_group_borders(dt_thumbtable_t *table)
Definition thumbtable.c:984
void dt_thumbtable_dispatch_over(dt_thumbtable_t *table, GdkEventType type, int32_t imgid)
Update the mouse-over image ID with conflict resolution.
gboolean dt_thumbtable_key_pressed_grid(GtkWidget *self, GdkEventKey *event, gpointer user_data)
void dt_thumbtable_set_overlays_mode(dt_thumbtable_t *table, dt_thumbnail_overlay_t over)
Set the overlay display mode for thumbnails.
void dt_thumbtable_refresh_thumbnail_real(dt_thumbtable_t *table, int32_t imgid, gboolean reinit)
Definition thumbtable.c:992
void dt_thumbtable_select_all(dt_thumbtable_t *table)
Select all images in the current grid.
void dt_thumbtable_reset_collection(dt_thumbtable_t *table)
gboolean dt_thumbtable_key_released_grid(GtkWidget *self, GdkEventKey *event, gpointer user_data)
dt_thumbtable_zoom_t dt_thumbtable_get_zoom(dt_thumbtable_t *table)
void dt_thumbtable_set_parent(dt_thumbtable_t *table, dt_thumbtable_mode_t mode)
void dt_thumbtable_queue_update(dt_thumbtable_t *table)
Definition thumbtable.c:231
dt_thumbtable_t * dt_thumbtable_new(dt_thumbtable_mode_t mode)
Create a new thumbnail table widget.
void dt_thumbtable_set_draw_group_borders(dt_thumbtable_t *table, gboolean enable)
Definition thumbtable.c:976
void dt_thumbtable_select_range(dt_thumbtable_t *table, const int rowid)
Select a range of images in the collection.
static void dt_thumbtable_hide(dt_thumbtable_t *table)
Hide the thumbnail table widget.
Definition thumbtable.h:413
void dt_thumbtable_update_parent(dt_thumbtable_t *table)