65#ifdef GDK_WINDOWING_QUARTZ
69#include <glib-object.h>
86 const gboolean can_clone = (src->
lut
108 for(uint32_t
i = 0;
i < count;
i++)
109 cloned_lut[
i].thumb = NULL;
114 dst->
lut = cloned_lut;
177 if(thumb_a->
rowid > thumb_b->
rowid)
return -1;
205 if(table->
thumb_nb == 0) gtk_widget_queue_draw(table->
grid);
206 return G_SOURCE_REMOVE;
287 for(
int rowid = row_start; rowid <= row_end; rowid++)
292 const gboolean mouse_over = thumb->
mouse_over;
299 gtk_widget_queue_draw(thumb->
widget);
305 for(
int rowid = row_start; rowid <= row_end; rowid++)
424 rowid = table->
rowid;
524 GtkWidgetPath *path = gtk_widget_path_new();
525 gtk_widget_path_append_type(path, GTK_TYPE_EVENT_BOX);
526 gtk_widget_path_iter_add_class(path, -1,
"thumb-cell");
528 GtkStyleContext *ctx = gtk_style_context_new();
529 gtk_style_context_set_path(ctx, path);
531 GtkBorder margin, border;
532 gtk_style_context_get_margin(ctx, GTK_STATE_FLAG_NORMAL, &margin);
533 gtk_style_context_get_border(ctx, GTK_STATE_FLAG_NORMAL, &border);
536 gtk_widget_path_unref(path);
538 return MAX(0, (border.left + border.right) + (margin.left + margin.right));
549 int new_thumbs_per_row = 0;
550 int new_thumb_width = 0;
551 int new_thumb_height = 0;
556 &new_thumb_width, &new_thumb_height);
560 if(new_width < 32 || new_height < 32)
570 const gboolean thumbs_changed = (!table->
configured
582 _grid_configure(table, new_width, new_height, new_thumbs_per_row, new_thumb_width, new_thumb_height);
598 gboolean found =
FALSE;
607 if(g_hash_table_lookup(table->
list, GINT_TO_POINTER(imgid)) == thumb)
622#define CLAMP_ROW(rowid) CLAMP(rowid, 0, table->collection_count - 1)
623#define IS_COLLECTION_EDGE(rowid) (rowid < 0 || rowid >= table->collection_count)
631 const int32_t rowid = thumb->
rowid;
645 const int32_t imgid = table->
lut[rowid].
imgid;
655 gboolean new_item =
TRUE;
656 gboolean new_position =
TRUE;
663 if(mapped_thumb == table->
lut[rowid].
thumb)
665 thumb = mapped_thumb;
666 new_position =
FALSE;
684 thumb->
rowid = rowid;
692 g_hash_table_insert(table->
list, GINT_TO_POINTER(thumb->
info.
id), thumb);
700 if(new_item || size_changed || table->
overlays != thumb->
over)
713 else if(new_position || size_changed)
728 gtk_widget_show(thumb->
widget);
748 gpointer
value = NULL;
749 g_hash_table_iter_init(&iter, table->
list);
750 while(g_hash_table_iter_next(&iter, NULL, &
value))
771 gtk_widget_queue_draw(thumb->
widget);
794 gboolean empty_list = (table->
thumb_nb == 0);
805 const char *
const name = gtk_widget_get_name(table->
grid);
831 gboolean first =
TRUE;
845 if(g_hash_table_lookup(table->
list, GINT_TO_POINTER(table->
lut[rowid].
imgid)) != thumb)
851 const gboolean was_highlighted = thumb->
selected;
863 if(thumb->
selected != was_highlighted)
864 gtk_widget_queue_draw(thumb->
widget);
934 gpointer
value = NULL;
935 g_hash_table_iter_init(&iter, table->
list);
936 while(g_hash_table_iter_next(&iter, NULL, &
value))
964 for(GList *l = g_list_first(imgs); l; l = g_list_next(l))
966 const int32_t imgid = GPOINTER_TO_INT(l->data);
967 if(imgid <= 0)
continue;
984 gtk_widget_queue_draw(thumb->
widget);
1007 while(sqlite3_step(stmt) == SQLITE_ROW)
1009 const int32_t imgid = sqlite3_column_int(stmt, 0);
1010 const int32_t groupid = sqlite3_column_int(stmt, 1);
1025 g_array_append_val(collection, entry);
1040 sqlite3_reset(stmt);
1042 if(
IS_NULL_PTR(collection) || collection->len == 0)
1046 old_lut = table->
lut;
1053 if(collection) g_array_free(collection,
TRUE);
1066 g_array_free(collection,
TRUE);
1074 old_lut = table->
lut;
1075 table->
lut = new_lut;
1081 g_array_free(collection,
TRUE);
1088 size_t len = strlen(query);
1093 hash =
dt_hash(hash, (
char *)&num_pics,
sizeof(uint32_t));
1109 const int next, gpointer user_data)
1115 gboolean collapsing_changed = (table->
collapse_groups != collapse_groups);
1138 "The current filtered collection contains no image. Relax your filters or fetch a non-empty collection"));
1160 return g_strdup(
"dt_overlays_none");
1162 return g_strdup(
"dt_overlays_always");
1165 return g_strdup(
"dt_overlays_hover");
1173 gchar *txt = g_strdup(
"plugins/lighttable/overlays/global");
1184 if(over == table->
overlays)
return;
1205 const guint target_type,
const guint time, gpointer user_data)
1214 const int imgs_nb = g_list_length(table->
drag_list);
1217 uint32_t *imgs = malloc(
sizeof(uint32_t) * imgs_nb);
1219 for(
int i = 0;
i < imgs_nb;
i++)
1221 imgs[
i] = GPOINTER_TO_INT(l->data);
1224 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
1225 _DWORD, (guchar *)imgs, imgs_nb *
sizeof(uint32_t));
1237 gboolean from_cache =
TRUE;
1238 const int id = GPOINTER_TO_INT(l->data);
1240 gchar *uri = g_strdup_printf(
"file://%s", pathname);
1241 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
1242 _BYTE, (guchar *)uri, strlen(uri));
1247 GList *images = NULL;
1248 for(; l; l = g_list_next(l))
1250 const int id = GPOINTER_TO_INT(l->data);
1252 gboolean from_cache =
TRUE;
1254 gchar *uri = g_strdup_printf(
"file://%s", pathname);
1255 images = g_list_prepend(images, uri);
1257 images = g_list_reverse(images);
1261 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
_BYTE,
1262 (guchar *)uri_list, strlen(uri_list));
1278 cairo_surface_t *surface = NULL;
1285 if(thumb->
img_surf && cairo_surface_get_reference_count(thumb->
img_surf) > 0)
1287 surface = cairo_surface_reference(thumb->
img_surf);
1290 hotspot_x =
width / 2;
1297 GtkWidget *image = gtk_image_new_from_surface(surface);
1298 cairo_surface_destroy(surface);
1304 gtk_widget_set_size_request(image,
width,
height);
1306 gtk_widget_show(image);
1307 gtk_drag_set_icon_widget(context, image, hotspot_x, hotspot_y);
1327 fprintf(stdout,
"DND check: no pathname.\n");
1330 fprintf(stdout,
"DND check pathname: %s\n", pathname);
1332 if(g_file_test(pathname, G_FILE_TEST_IS_REGULAR))
1336 files = g_list_prepend(files, g_strdup(pathname));
1340 fprintf(stderr,
"`%s`: Unkonwn format.", pathname);
1342 else if(g_file_test(pathname, G_FILE_TEST_IS_DIR))
1344 fprintf(stderr,
"DND check: Folders are not allowed");
1345 dt_control_log(_(
"'%s': Please use 'File > Import' to import a folder."), pathname);
1349 fprintf(stderr,
"DND check: `%s` not a file or folder.\n", pathname);
1357 gchar **uris = gtk_selection_data_get_uris(selection_data);
1359 GList *files = NULL;
1363 GVfs *vfs = g_vfs_get_default();
1366 GFile *filepath = g_vfs_get_file_for_uri(vfs, uris[
i]);
1367 const gchar *pathname = g_strdup(g_file_get_path(filepath));
1369 g_object_unref(filepath);
1378 .datetime = g_date_time_new_now_local(),
1385 .elements = elements,
1392 else fprintf(stderr,
"No files to import. Check your selection or use 'File > Import'.");
1402 GtkSelectionData *selection_data, guint target_type, guint time,
1405 gboolean success =
FALSE;
1408 && (gtk_selection_data_get_length(selection_data) >= 0))
1413 gtk_drag_finish(context, success,
FALSE, time);
1477 offset = - origin_imgid;
1484 int new_rowid = CLAMP(current_rowid + offset, 0, table->
collection_count - 1);
1487 int new_imgid = table->
lut[new_rowid].
imgid;
1511 GHashTableIter iter;
1512 gpointer
value = NULL;
1513 g_hash_table_iter_init(&iter, table->
list);
1514 while(g_hash_table_iter_next(&iter, NULL, &
value))
1541 if(imgid < 0 && table->
lut)
1551 if(event->keyval != GDK_KEY_Alt_L && event->keyval != GDK_KEY_Alt_R)
1574 case GDK_KEY_Page_Up:
1579 case GDK_KEY_Page_Down:
1594 case GDK_KEY_Return:
1612 case GDK_KEY_Delete:
1639 GtkStyleContext *context = gtk_widget_get_style_context(widget);
1640 GtkAllocation allocation;
1641 gtk_widget_get_allocation(widget, &allocation);
1642 gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height);
1643 gtk_render_frame(context, cr, 0, 0, allocation.width, allocation.height);
1686 gtk_widget_set_name(table->
scroll_window,
"thumbtable-scroll");
1687 gtk_scrolled_window_set_overlay_scrolling(GTK_SCROLLED_WINDOW(table->
scroll_window),
FALSE);
1689 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(table->
scroll_window), GTK_SHADOW_NONE);
1717 if(GTK_IS_VIEWPORT(viewport))
1718 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1721 gtk_widget_set_has_tooltip(table->
grid,
FALSE);
1727 gtk_widget_set_can_focus(table->
grid, can_focus);
1728 gtk_widget_set_focus_on_click(table->
grid, can_focus);
1729 gtk_widget_add_events(table->
grid, GDK_LEAVE_NOTIFY_MASK);
1730 gtk_widget_set_app_paintable(table->
grid,
TRUE);
1731 g_signal_connect(G_OBJECT(table->
grid),
"leave-notify-event", G_CALLBACK(
_event_main_leave), table);
1736 GtkAdjustment *
dummy = gtk_adjustment_new(0., 0., 1., 1., 1., 1.);
1739 gtk_container_set_focus_hadjustment(GTK_CONTAINER(table->
grid),
dummy);
1740 gtk_container_set_focus_vadjustment(GTK_CONTAINER(table->
grid),
dummy);
1741 g_object_unref(
dummy);
1752 gtk_widget_add_events(table->
grid, GDK_STRUCTURE_MASK | GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
1756 gtk_widget_show(table->
grid);
1764 table->
list = g_hash_table_new(g_direct_hash, g_direct_equal);
1788 gtk_widget_set_name(table->
grid,
"thumbtable-filemanager");
1813 GtkAccelGroup *accel_groups[] = {
1819 const char *path_bases[] = {
1820 _(
"Lighttable/Thumbtable"),
1821 _(
"Darkroom/Filmstrip"),
1822 _(
"Print/Filmstrip"),
1827 int first_group = 1, last_group = 4;
1839 for(
int group_index = first_group; group_index < last_group; group_index++)
1841 GtkAccelGroup *accel_group = accel_groups[group_index];
1842 const char *path_base = path_bases[group_index];
1846 path, table->
grid, GDK_KEY_Up, 0);
1850 path, table->
grid, GDK_KEY_Down, 0);
1854 path, table->
grid, GDK_KEY_Left, 0);
1858 path, table->
grid, GDK_KEY_Right, 0);
1862 path, table->
grid, GDK_KEY_Page_Up, 0);
1866 path, table->
grid, GDK_KEY_Page_Down, 0);
1870 path, table->
grid, GDK_KEY_Home, 0);
1874 path, table->
grid, GDK_KEY_End, 0);
1878 path, table->
grid, GDK_KEY_space, 0);
1882 path, table->
grid, GDK_KEY_space, GDK_CONTROL_MASK);
1884 path =
dt_accels_build_path(path_base, _(
"Expand the current selection up to the hovered thumbnail"));
1886 path, table->
grid, GDK_KEY_space, GDK_SHIFT_MASK);
1890 path, table->
grid, GDK_KEY_Return, 0);
1894 path, table->
grid, GDK_KEY_Alt_L, 0);
1900 path, table->
grid, GDK_KEY_Delete, 0);
1919 GList *thumbs = g_hash_table_get_values(table->
list);
1921 g_hash_table_remove_all(table->
list);
1924 for(GList *l = thumbs; l; l = g_list_next(l))
1927 gtk_widget_hide(thumb->
widget);
1930 g_list_free(thumbs);
1966 g_hash_table_destroy(table->
list);
1997 GList *thumbs = g_hash_table_get_values(table->
list);
1999 g_hash_table_remove_all(table->
list);
2002 for(GList *l = thumbs; l; l = g_list_next(l))
2005 gtk_widget_hide(thumb->
widget);
2008 g_list_free(thumbs);
2038 "Selecting all images will only target visible members of image groups.\n"
2039 "Uncollapse groups to select all their members"));
2045 img = g_list_prepend(img, GINT_TO_POINTER(table->
lut[
i].
imgid));
2063 "Selecting a range of images will only target visible members of image groups.\n"
2064 "Uncollapse groups to select all their members"));
2069 size_t rowid_end = 0;
2075 for(GList *s = g_list_first(selected); s; s = g_list_next(s))
2077 int32_t imgid = GPOINTER_TO_INT(s->data);
2079 if(
row < 0)
continue;
2080 if(
row < rowid_start) rowid_start =
row;
2081 if(
row > rowid_end) rowid_end =
row;
2083 g_list_free(selected);
2093 if(rowid_start > rowid_end)
2102 if(rowid > rowid_end && rowid_end < table->collection_count - 1)
2105 for(
int i = rowid_end + 1;
i <= rowid;
i++)
2106 img = g_list_prepend(img, GINT_TO_POINTER(table->
lut[
i].
imgid));
2108 else if(rowid < rowid_start && rowid_start > 0)
2111 for(
int i = rowid_start - 1;
i >= rowid;
i--)
2112 img = g_list_prepend(img, GINT_TO_POINTER(table->
lut[
i].
imgid));
2136 g_list_free(to_deselect);
2147 gint64 current_time = g_get_real_time();
2148 if(
type == GDK_KEY_PRESS ||
type == GDK_KEY_RELEASE)
2157 else if(
type == GDK_ENTER_NOTIFY ||
type == GDK_LEAVE_NOTIFY)
2169 else if(
type == GDK_MOTION_NOTIFY ||
type == GDK_BUTTON_PRESS ||
type == GDK_2BUTTON_PRESS)
2176 fprintf(stderr,
"[dt_thumbtable_dispatch_over] unsupported event type: %i\n",
type);
2186 if(!gtk_widget_has_focus(table->
grid))
2192 gtk_widget_grab_focus(table->
grid);
void dt_accels_new_virtual_shortcut(dt_accels_t *accels, GtkAccelGroup *accel_group, const gchar *accel_path, GtkWidget *widget, guint key_val, GdkModifierType accel_mods)
Add a new virtual shortcut. Virtual shortcuts are immutable, read-only and don't trigger any action....
gchar * dt_accels_build_path(const gchar *scope, const gchar *feature)
Handle default and user-set shortcuts (accelerators)
#define DT_ACCELS_WIDGET_TOOLTIP_DISABLED_KEY
GList * dt_act_on_get_images()
const gchar * dt_collection_get_query(const dt_collection_t *collection)
uint32_t dt_collection_get_count(const dt_collection_t *collection)
dt_collection_properties_t
@ DT_COLLECTION_PROP_GROUPING
dt_iop_colorout_gui_data_t dummy
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_image_init(dt_image_t *img)
void dt_image_full_path(const int32_t imgid, char *pathname, size_t pathname_len, gboolean *from_cache, const char *calling_func)
Get the full path of an image out of the database.
int dt_conf_get_bool(const char *name)
gchar * dt_conf_get_string(const char *name)
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
int32_t dt_control_get_mouse_over_id()
void dt_control_set_mouse_over_id(int32_t value)
void dt_control_log(const char *msg,...)
int32_t dt_control_get_keyboard_over_id()
void dt_control_set_keyboard_over_id(int32_t value)
gboolean dt_control_remove_images()
gboolean dt_supported_image(const gchar *filename)
check if file is a supported image
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define g_list_is_singleton(list)
static void dt_free_gpointer(gpointer ptr)
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
static const dt_aligned_pixel_simd_t value
static double dt_get_wtime(void)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static const GtkTargetEntry target_list_all[]
static const guint n_targets_all
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
const dt_thumbtable_layout_ops_t * dt_thumbtable_grid_ops(void)
const dt_thumbtable_layout_ops_t * dt_thumbtable_filmstrip_ops(void)
static guint dt_keys_mainpad_alternatives(const guint key_val)
Remap keypad keys to usual mainpad ones.
void dt_gui_remove_class(GtkWidget *widget, const gchar *class_name)
void dt_gui_add_help_link(GtkWidget *widget, char *link)
void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)
static gboolean enable(dt_image_t *image)
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
void dt_image_from_stmt(dt_image_t *img, sqlite3_stmt *stmt)
dt_image_t * dt_image_cache_testget(dt_image_cache_t *cache, const int32_t imgid, char mode)
int dt_control_import(dt_control_import_t data)
Process a list of images to import with or without copying the files on an arbitrary hard-drive.
int32_t dt_selection_get_first_id(struct dt_selection_t *selection)
void dt_selection_deselect_list(struct dt_selection_t *selection, const GList *const l)
GList * dt_selection_get_list(struct dt_selection_t *selection)
void dt_selection_select_list(struct dt_selection_t *selection, const GList *const l)
void dt_selection_deselect(dt_selection_t *selection, int32_t imgid)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_VIEWMANAGER_THUMBTABLE_ACTIVATE
@ DT_SIGNAL_ACTIVE_IMAGES_CHANGE
This signal is raised when image shown in the main view change no param, no returned value.
@ DT_SIGNAL_CONTROL_PROFILE_USER_CHANGED
This signal is raised when a profile is changed by the user 1 uint32_t : the profile type that has ch...
@ DT_SIGNAL_MOUSE_OVER_IMAGE_CHANGE
This signal is raised when mouse hovers over image thumbs both on lighttable and in the filmstrip....
@ DT_SIGNAL_IMAGE_INFO_CHANGED
This signal is raised when any of image info has changed
@ DT_SIGNAL_SELECTION_CHANGED
This signal is raised when the selection is changed no param, no returned value.
@ DT_SIGNAL_COLLECTION_CHANGED
This signal is raised when collection changed. To avoid leaking the list, dt_collection_t is connecte...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
unsigned __int64 uint64_t
struct dt_gui_gtk_t * gui
struct dt_collection_t * collection
struct dt_selection_t * selection
struct dt_control_signal_t * signals
struct dt_image_cache_t * image_cache
struct dt_view_manager_t * view_manager
GtkAccelGroup * map_accels
GtkAccelGroup * global_accels
GtkAccelGroup * print_accels
GtkAccelGroup * lighttable_accels
GtkAccelGroup * darkroom_accels
dt_thumbnail_overlay_t over
cairo_surface_t * img_surf
Cache entry for a single thumbnail.
Per-mode layout strategy. One instance per frontend, shared (const) by all tables of that mode and st...
void(* pre_activate)(dt_thumbtable_t *table, int32_t imgid)
void(* on_drag_begin)(dt_thumbtable_t *table, int32_t imgid)
int(* position_to_rowid)(dt_thumbtable_t *table, const double x, const double y)
void(* configure_dims)(dt_thumbtable_t *table, int *new_width, int *new_height, int *per_row, int *thumb_width, int *thumb_height)
void(* get_row_ids)(dt_thumbtable_t *table, int *rowid_min, int *rowid_max)
gboolean(* wants_page_size_notify)(dt_thumbtable_t *table, GObject *object)
void(* move_child)(dt_thumbtable_t *table, dt_thumbnail_t *thumb)
void(* group_borders)(dt_thumbtable_t *table, dt_thumbnail_t *thumb, dt_thumbnail_border_t *borders)
gboolean(* wants_scroll_value)(dt_thumbtable_t *table, GtkAdjustment *adjustment)
void(* update_content_size)(dt_thumbtable_t *table)
void(* grab_focus)(dt_thumbtable_t *table)
gboolean(* is_rowid_visible)(dt_thumbtable_t *table, int rowid)
void(* rowid_to_position)(dt_thumbtable_t *table, int rowid, int *x, int *y)
void(* on_thumbnail_added)(dt_thumbtable_t *table, dt_thumbnail_t *thumb)
gboolean(* relevant_scrollbar_changed)(dt_thumbtable_t *table, GtkWidget *widget, GtkAllocation *allocation)
gboolean(* is_thumb_highlighted)(dt_thumbtable_t *table, int32_t imgid)
GtkWidget *(* create_content_widget)(void)
gboolean(* handle_key)(dt_thumbtable_t *table, GdkEventKey *event, guint key, int32_t imgid)
void(* place_child)(dt_thumbtable_t *table, dt_thumbnail_t *thumb)
void(* setup_parent)(dt_thumbtable_t *table)
const dt_thumbtable_layout_ops_t * ops
gboolean collection_inited
dt_thumbtable_mode_t mode
int last_h_scrollbar_height
GtkAdjustment * v_scrollbar
int last_v_scrollbar_width
GtkWidget * scroll_window
dt_thumbtable_cache_t * lut
GtkAdjustment * h_scrollbar
dt_thumbnail_overlay_t overlays
gboolean reset_collection
GtkWidget * parent_overlay
gboolean draw_group_borders
dt_thumbtable_t * thumbtable_lighttable
dt_thumbtable_t * thumbtable_filmstrip
typedef double((*spd)(unsigned long int wavelength, double TempK))
dt_thumbnail_t * dt_thumbnail_new(int rowid, dt_thumbnail_overlay_t over, dt_thumbtable_t *table, dt_image_t *info)
void dt_thumbnail_set_mouseover(dt_thumbnail_t *thumb, gboolean over)
void dt_thumbnail_resync_info(dt_thumbnail_t *thumb, const dt_image_t *const info)
void dt_thumbnail_set_overlay(dt_thumbnail_t *thumb, dt_thumbnail_overlay_t mode)
void dt_thumbnail_set_group_border(dt_thumbnail_t *thumb, dt_thumbnail_border_t border)
int dt_thumbnail_destroy(dt_thumbnail_t *thumb)
void dt_thumbnail_update_gui(dt_thumbnail_t *thumb)
void dt_thumbnail_update_selection(dt_thumbnail_t *thumb, gboolean selected)
void dt_thumbnail_alternative_mode(dt_thumbnail_t *thumb, gboolean enable)
void dt_thumbnail_resize(dt_thumbnail_t *thumb, int width, int height)
#define dt_thumbnail_image_refresh(thumb)
static dt_thumbnail_overlay_t sanitize_overlays(dt_thumbnail_overlay_t overlays)
@ DT_THUMBNAIL_OVERLAYS_HOVER_NORMAL
@ DT_THUMBNAIL_OVERLAYS_ALWAYS_NORMAL
@ DT_THUMBNAIL_OVERLAYS_NONE
static int _position_to_rowid(dt_thumbtable_t *table, const double x, const double y)
void _add_thumbnail_at_rowid(dt_thumbtable_t *table, const size_t rowid, const int32_t mouse_over)
static void _scrollbar_page_size_notify(GObject *object, GParamSpec *pspec, gpointer user_data)
int dt_thumbtable_scroll_to_selection(dt_thumbtable_t *table)
Scroll to show selected content.
gboolean _event_main_leave(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
int dt_thumbtable_scroll_to_imgid(dt_thumbtable_t *table, int32_t imgid)
Scroll the view to show a specific image.
static void _dt_collection_changed_callback(gpointer instance, dt_collection_change_t query_change, dt_collection_properties_t changed_property, gpointer imgs, const int next, gpointer user_data)
gboolean dt_thumbtable_get_focus_peaking(dt_thumbtable_t *table)
static gboolean _thumbtable_idle_update(gpointer user_data)
void dt_thumbtable_update(dt_thumbtable_t *table)
static void _thumbtable_drag_set_icon(dt_thumbtable_t *table, GdkDragContext *context)
void dt_thumbtable_set_active_rowid(dt_thumbtable_t *table)
Update internal active row tracking.
void dt_thumbtable_get_scroll_position(dt_thumbtable_t *table, double *x, double *y)
static gint _thumb_compare_rowid_desc(gconstpointer a, gconstpointer b)
static int _grab_focus(dt_thumbtable_t *table)
static int dt_thumbtable_scroll_to_position(dt_thumbtable_t *table, const double x, const double y)
static void _thumbs_update_overlays_mode(dt_thumbtable_t *table)
void dt_thumbtable_configure(dt_thumbtable_t *table)
void dt_thumbtable_cleanup(dt_thumbtable_t *table)
static gint64 next_over_time
void _grid_configure(dt_thumbtable_t *table, int width, int height, int per_row, int thumb_width, int thumb_height)
static void _dt_active_images_changed_callback(gpointer instance, gpointer user_data)
gboolean _is_rowid_visible(dt_thumbtable_t *table, int rowid)
int _imgid_to_rowid(dt_thumbtable_t *table, int32_t imgid)
gboolean dt_thumbtable_get_focus_regions(dt_thumbtable_t *table)
void dt_thumbtable_set_focus_peaking(dt_thumbtable_t *table, gboolean enable)
GList * _thumbtable_dnd_import_check(GList *files, const char *pathname, int *elements)
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.
static gboolean _thumbtable_dnd_import(GtkSelectionData *selection_data)
static void _scrollbar_widget_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data)
static void _dt_collection_lut(dt_thumbtable_t *table)
void _resize_thumbnails(dt_thumbtable_t *table)
void _populate_thumbnails(dt_thumbtable_t *table)
void dt_thumbtable_invert_selection(dt_thumbtable_t *table)
Invert the current selection.
void _dt_thumbtable_empty_list(dt_thumbtable_t *table)
static gboolean _dt_collection_get_hash(dt_thumbtable_t *table)
static void _event_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
gboolean dt_thumbtable_get_thumbnail_info(dt_thumbtable_t *table, int32_t imgid, dt_image_t *out)
gboolean _update_row_ids(dt_thumbtable_t *table)
static void _scrollbar_value_changed(GtkAdjustment *adjustment, gpointer user_data)
static const dt_thumbtable_layout_ops_t * _ops_for_mode(dt_thumbtable_mode_t mode)
static void _thumbtable_schedule_update(dt_thumbtable_t *table)
static void _parent_overlay_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data)
void _add_thumbnail_group_borders(dt_thumbtable_t *table, dt_thumbnail_t *thumb)
void dt_thumbtable_stop(dt_thumbtable_t *table)
void dt_thumbtable_set_focus_regions(dt_thumbtable_t *table, gboolean enable)
static void dt_thumbtable_scroll_to_rowid(dt_thumbtable_t *table, int rowid)
void _update_grid_area(dt_thumbtable_t *table)
int dt_thumbtable_scroll_to_active_rowid(dt_thumbtable_t *table)
Scroll to show the active row.
gboolean dt_thumbtable_get_draw_group_borders(dt_thumbtable_t *table)
int dt_thumbtable_thumb_cell_decoration(void)
void dt_thumbtable_dispatch_over(dt_thumbtable_t *table, GdkEventType type, int32_t imgid)
Update the mouse-over image ID with conflict resolution.
static gboolean _thumbtable_clone_lut(dt_thumbtable_t *dst)
void _alternative_mode(dt_thumbtable_t *table, gboolean enable)
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.
static void _rowid_to_position(dt_thumbtable_t *table, int rowid, int *x, int *y)
static gboolean _draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data)
static void _dt_profile_change_callback(gpointer instance, int type, gpointer user_data)
static gboolean _get_row_ids(dt_thumbtable_t *table, int *rowid_min, int *rowid_max)
void dt_thumbtable_schedule_focus(dt_thumbtable_t *table, const gint priority)
void dt_thumbtable_refresh_thumbnail_real(dt_thumbtable_t *table, int32_t imgid, gboolean reinit)
void dt_thumbtable_select_all(dt_thumbtable_t *table)
Select all images in the current grid.
static void _dt_selection_changed_callback(gpointer instance, gpointer user_data)
void dt_thumbtable_reset_collection(dt_thumbtable_t *table)
gboolean dt_thumbtable_key_released_grid(GtkWidget *self, GdkEventKey *event, gpointer user_data)
int dt_thumbtable_find_rowid_from_imgid(dt_thumbtable_t *table, const int32_t imgid)
static void _event_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
static gboolean _set_thumb_position(dt_thumbtable_t *table, dt_thumbnail_t *thumb)
static void _event_dnd_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, const guint target_type, const guint time, gpointer user_data)
void dt_thumbtable_move_in_grid(dt_thumbtable_t *table, GdkEventKey *event, dt_thumbtable_direction_t direction, int origin_imgid)
void dt_thumbtable_set_parent(dt_thumbtable_t *table, dt_thumbtable_mode_t mode)
static gchar * _thumbs_get_overlays_class(dt_thumbnail_overlay_t over)
void dt_thumbtable_queue_update(dt_thumbtable_t *table)
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)
void _mouse_over_image_callback(gpointer instance, gpointer user_data)
void dt_thumbtable_select_range(dt_thumbtable_t *table, const int rowid)
Select a range of images in the collection.
static void _dt_image_info_changed_callback(gpointer instance, gpointer imgs, gpointer user_data)
static void _refresh_highlights(dt_thumbtable_t *table)
dt_thumbnail_t * _find_thumb_by_imgid(dt_thumbtable_t *table, const int32_t imgid)
void dt_thumbtable_update_parent(dt_thumbtable_t *table)
A widget to manage and display image thumbnails in Ansel's lighttable and filmstrip views.
dt_thumbtable_mode_t
Display modes for the thumbnail table.
@ DT_THUMBTABLE_MODE_FILMSTRIP
@ DT_THUMBTABLE_MODE_FILEMANAGER
#define dt_thumbtable_refresh_thumbnail(table, imgid, reinit)
void dt_thumbtable_info_cleanup(void)
void dt_thumbtable_info_debug_assert_matches_cache(const dt_image_t *sql_info)
void dt_thumbtable_info_seed_image_cache(const dt_image_t *info)
sqlite3_stmt * dt_thumbtable_info_get_collection_stmt(void)
static gboolean dt_thumbtable_info_is_grouped(const dt_image_t info)
Private interface shared between the thumbtable engine (thumbtable.c) and its two frontends (filemana...
dt_thumbtable_direction_t
@ DT_TT_MOVE_PREVIOUS_PAGE
char * dt_get_help_url(char *name)
gchar * dt_util_glist_to_str(const gchar *separator, GList *items)
void dt_view_image_info_update(int32_t imgid)