73#ifdef GDK_WINDOWING_QUARTZ
77#include <glib-object.h>
98 const gboolean can_clone = (src->
lut
120 for(uint32_t
i = 0;
i < count;
i++)
121 cloned_lut[
i].thumb = NULL;
126 dst->
lut = cloned_lut;
189 if(thumb_a->
rowid > thumb_b->
rowid)
return -1;
218 if(table->
thumb_nb == 0) gtk_widget_queue_draw(table->
grid);
219 return G_SOURCE_REMOVE;
300 for(
int rowid = row_start; rowid <= row_end; rowid++)
305 const gboolean mouse_over = thumb->
mouse_over;
312 gtk_widget_queue_draw(thumb->
widget);
318 for(
int rowid = row_start; rowid <= row_end; rowid++)
437 rowid = table->
rowid;
537 GtkWidgetPath *path = gtk_widget_path_new();
538 gtk_widget_path_append_type(path, GTK_TYPE_EVENT_BOX);
539 gtk_widget_path_iter_add_class(path, -1,
"thumb-cell");
541 GtkStyleContext *ctx = gtk_style_context_new();
542 gtk_style_context_set_path(ctx, path);
544 GtkBorder margin, border;
545 gtk_style_context_get_margin(ctx, GTK_STATE_FLAG_NORMAL, &margin);
546 gtk_style_context_get_border(ctx, GTK_STATE_FLAG_NORMAL, &border);
549 gtk_widget_path_unref(path);
551 return MAX(0, (border.left + border.right) + (margin.left + margin.right));
562 int new_thumbs_per_row = 0;
563 int new_thumb_width = 0;
564 int new_thumb_height = 0;
569 &new_thumb_width, &new_thumb_height);
573 if(new_width < 32 || new_height < 32)
583 const gboolean thumbs_changed = (!table->
configured
595 _grid_configure(table, new_width, new_height, new_thumbs_per_row, new_thumb_width, new_thumb_height);
611 gboolean found =
FALSE;
620 if(g_hash_table_lookup(table->
list, GINT_TO_POINTER(imgid)) == thumb)
635#define CLAMP_ROW(rowid) CLAMP(rowid, 0, table->collection_count - 1)
636#define IS_COLLECTION_EDGE(rowid) (rowid < 0 || rowid >= table->collection_count)
644 const int32_t rowid = thumb->
rowid;
658 const int32_t imgid = table->
lut[rowid].
imgid;
668 gboolean new_item =
TRUE;
669 gboolean new_position =
TRUE;
676 if(mapped_thumb == table->
lut[rowid].
thumb)
678 thumb = mapped_thumb;
679 new_position =
FALSE;
697 thumb->
rowid = rowid;
705 g_hash_table_insert(table->
list, GINT_TO_POINTER(thumb->
info.
id), thumb);
713 if(new_item || size_changed || table->
overlays != thumb->
over)
726 else if(new_position || size_changed)
741 gtk_widget_show(thumb->
widget);
761 gpointer
value = NULL;
762 g_hash_table_iter_init(&iter, table->
list);
763 while(g_hash_table_iter_next(&iter, NULL, &
value))
784 gtk_widget_queue_draw(thumb->
widget);
807 gboolean empty_list = (table->
thumb_nb == 0);
818 const char *
const name = gtk_widget_get_name(table->
grid);
844 gboolean first =
TRUE;
858 if(g_hash_table_lookup(table->
list, GINT_TO_POINTER(table->
lut[rowid].
imgid)) != thumb)
864 const gboolean was_highlighted = thumb->
selected;
876 if(thumb->
selected != was_highlighted)
877 gtk_widget_queue_draw(thumb->
widget);
947 gpointer
value = NULL;
948 g_hash_table_iter_init(&iter, table->
list);
949 while(g_hash_table_iter_next(&iter, NULL, &
value))
977 for(GList *l = g_list_first(imgs); l; l = g_list_next(l))
979 const int32_t imgid = GPOINTER_TO_INT(l->data);
980 if(imgid <= 0)
continue;
997 gtk_widget_queue_draw(thumb->
widget);
1018 const int32_t imgid =
row->id;
1019 const int32_t groupid =
row->group_id;
1062 if(
IS_NULL_PTR(collection) || collection->len == 0)
1066 old_lut = table->
lut;
1073 if(collection) g_array_free(collection,
TRUE);
1086 g_array_free(collection,
TRUE);
1094 old_lut = table->
lut;
1095 table->
lut = new_lut;
1101 g_array_free(collection,
TRUE);
1114 hash =
dt_hash(hash, (
char *)&num_pics,
sizeof(uint32_t));
1130 const int next, gpointer user_data)
1136 gboolean collapsing_changed = (table->
collapse_groups != collapse_groups);
1145 gboolean changed = hash_changed || collapsing_changed || grouping_changed;
1147 "[thumbtable] collection_changed_callback: query_change=%d changed_property=%d hash_changed=%d "
1148 "collapsing_changed=%d grouping_changed=%d -> changed=%d\n",
1149 query_change, changed_property, hash_changed, collapsing_changed, grouping_changed, changed);
1164 "The current filtered collection contains no image. Relax your filters or fetch a non-empty collection"));
1193 return g_strdup(
"dt_overlays_none");
1195 return g_strdup(
"dt_overlays_always");
1198 return g_strdup(
"dt_overlays_hover");
1206 gchar *txt = g_strdup(
"plugins/lighttable/overlays/global");
1217 if(over == table->
overlays)
return;
1238 const guint target_type,
const guint time, gpointer user_data)
1247 const int imgs_nb = g_list_length(table->
drag_list);
1250 uint32_t *imgs = malloc(
sizeof(uint32_t) * imgs_nb);
1252 for(
int i = 0;
i < imgs_nb;
i++)
1254 imgs[
i] = GPOINTER_TO_INT(l->data);
1257 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
1258 _DWORD, (guchar *)imgs, imgs_nb *
sizeof(uint32_t));
1270 gboolean from_cache =
TRUE;
1271 const int id = GPOINTER_TO_INT(l->data);
1273 gchar *uri = g_strdup_printf(
"file://%s", pathname);
1274 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
1275 _BYTE, (guchar *)uri, strlen(uri));
1280 GList *images = NULL;
1281 for(; l; l = g_list_next(l))
1283 const int id = GPOINTER_TO_INT(l->data);
1285 gboolean from_cache =
TRUE;
1287 gchar *uri = g_strdup_printf(
"file://%s", pathname);
1288 images = g_list_prepend(images, uri);
1290 images = g_list_reverse(images);
1294 gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data),
_BYTE,
1295 (guchar *)uri_list, strlen(uri_list));
1311 cairo_surface_t *surface = NULL;
1318 if(thumb->
img_surf && cairo_surface_get_reference_count(thumb->
img_surf) > 0)
1320 surface = cairo_surface_reference(thumb->
img_surf);
1323 hotspot_x =
width / 2;
1330 GtkWidget *image = gtk_image_new_from_surface(surface);
1331 cairo_surface_destroy(surface);
1337 gtk_widget_set_size_request(image,
width,
height);
1339 gtk_widget_show(image);
1340 gtk_drag_set_icon_widget(context, image, hotspot_x, hotspot_y);
1364 fprintf(stdout,
"DND check: no pathname.\n");
1367 fprintf(stdout,
"DND check pathname: %s\n", pathname);
1369 if(g_file_test(pathname, G_FILE_TEST_IS_REGULAR))
1373 files = g_list_prepend(files, g_strdup(pathname));
1377 fprintf(stderr,
"`%s`: Unkonwn format.", pathname);
1379 else if(g_file_test(pathname, G_FILE_TEST_IS_DIR))
1381 *folders = g_list_prepend(*folders, g_strdup(pathname));
1385 fprintf(stderr,
"DND check: `%s` not a file or folder.\n", pathname);
1417 GFile *
folder = g_file_new_for_path(folder_path);
1418 GError *
error = NULL;
1419 GFileEnumerator *children = g_file_enumerate_children(
1420 folder, G_FILE_ATTRIBUTE_STANDARD_NAME
"," G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &
error);
1427 g_error_free(
error);
1434 GFile *child = NULL;
1435 GError *iter_error = NULL;
1436 while(g_file_enumerator_iterate(children, NULL, &child, NULL, &iter_error))
1442 gchar *pathname = g_file_get_path(child);
1443 if(pathname && g_file_test(pathname, G_FILE_TEST_IS_REGULAR) &&
dt_import_passes_filter(filter_type, pathname))
1445 *files = g_list_prepend(*files, pathname);
1448 else if(pathname && g_file_test(pathname, G_FILE_TEST_IS_DIR))
1462 dt_print(
DT_DEBUG_IMPORT,
"[import] could not fully scan folder `%s': %s\n", folder_path, iter_error->message);
1463 g_error_free(iter_error);
1467 g_object_unref(children);
1477 GList *files = data->
files;
1480 guint scan_errors = 0;
1481 for(GList *l = data->
folders; l; l = g_list_next(l))
1484 const int elements = g_list_length(files);
1488 .datetime = g_date_time_new_now_local(),
1495 .elements = elements,
1503 dt_control_log(_(
"No matching file found in the dropped folder(s)."));
1507 dt_control_log(ngettext(
"%u folder could not be scanned (permission denied?)",
1508 "%u folders could not be scanned (permission denied?)", scan_errors),
1511 return elements > 0 ? 0 : 1;
1534 GtkWidget *dialog = gtk_message_dialog_new(
1535 GTK_WINDOW(
dt_gui_get_ui()->main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
1536 GTK_BUTTONS_NONE,
"%s",
1537 _(
"The dropped folder(s) will be scanned recursively.\nWhich files should be imported?"));
1538#ifdef GDK_WINDOWING_QUARTZ
1546 gtk_window_set_title(GTK_WINDOW(dialog), _(
"Import folder"));
1547 const gint choice = gtk_dialog_run(GTK_DIALOG(dialog));
1548 gtk_widget_destroy(dialog);
1570 data->
files = files;
1581 gchar **uris = gtk_selection_data_get_uris(selection_data);
1583 GList *files = NULL;
1584 GList *folders = NULL;
1588 GVfs *vfs = g_vfs_get_default();
1591 GFile *filepath = g_vfs_get_file_for_uri(vfs, uris[
i]);
1592 const gchar *pathname = g_strdup(g_file_get_path(filepath));
1594 g_object_unref(filepath);
1605 else if(elements > 0)
1611 .datetime = g_date_time_new_now_local(),
1618 .elements = elements,
1625 else fprintf(stderr,
"No files to import. Check your selection or use 'File > Import'.");
1635 GtkSelectionData *selection_data, guint target_type, guint time,
1638 gboolean success =
FALSE;
1641 && (gtk_selection_data_get_length(selection_data) >= 0))
1646 gtk_drag_finish(context, success,
FALSE, time);
1710 offset = - origin_imgid;
1717 int new_rowid = CLAMP(current_rowid + offset, 0, table->
collection_count - 1);
1720 int new_imgid = table->
lut[new_rowid].
imgid;
1744 GHashTableIter iter;
1745 gpointer
value = NULL;
1746 g_hash_table_iter_init(&iter, table->
list);
1747 while(g_hash_table_iter_next(&iter, NULL, &
value))
1774 if(imgid < 0 && table->
lut)
1784 if(event->keyval != GDK_KEY_Alt_L && event->keyval != GDK_KEY_Alt_R)
1807 case GDK_KEY_Page_Up:
1812 case GDK_KEY_Page_Down:
1827 case GDK_KEY_Return:
1845 case GDK_KEY_Delete:
1872 GtkStyleContext *context = gtk_widget_get_style_context(widget);
1873 GtkAllocation allocation;
1874 gtk_widget_get_allocation(widget, &allocation);
1875 gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height);
1876 gtk_render_frame(context, cr, 0, 0, allocation.width, allocation.height);
1919 gtk_widget_set_name(table->
scroll_window,
"thumbtable-scroll");
1920 gtk_scrolled_window_set_overlay_scrolling(GTK_SCROLLED_WINDOW(table->
scroll_window),
FALSE);
1922 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(table->
scroll_window), GTK_SHADOW_NONE);
1950 if(GTK_IS_VIEWPORT(viewport))
1951 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1954 gtk_widget_set_has_tooltip(table->
grid,
FALSE);
1960 gtk_widget_set_can_focus(table->
grid, can_focus);
1961 gtk_widget_set_focus_on_click(table->
grid, can_focus);
1962 gtk_widget_add_events(table->
grid, GDK_LEAVE_NOTIFY_MASK);
1963 gtk_widget_set_app_paintable(table->
grid,
TRUE);
1964 g_signal_connect(G_OBJECT(table->
grid),
"leave-notify-event", G_CALLBACK(
_event_main_leave), table);
1969 GtkAdjustment *
dummy = gtk_adjustment_new(0., 0., 1., 1., 1., 1.);
1972 gtk_container_set_focus_hadjustment(GTK_CONTAINER(table->
grid),
dummy);
1973 gtk_container_set_focus_vadjustment(GTK_CONTAINER(table->
grid),
dummy);
1974 g_object_unref(
dummy);
1985 gtk_widget_add_events(table->
grid, GDK_STRUCTURE_MASK | GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
1989 gtk_widget_show(table->
grid);
1997 table->
list = g_hash_table_new(g_direct_hash, g_direct_equal);
2021 gtk_widget_set_name(table->
grid,
"thumbtable-filemanager");
2046 GtkAccelGroup *accel_groups[] = {
2052 const char *path_bases[] = {
2053 _(
"Lighttable/Thumbtable"),
2054 _(
"Darkroom/Filmstrip"),
2055 _(
"Print/Filmstrip"),
2060 int first_group = 1, last_group = 4;
2072 for(
int group_index = first_group; group_index < last_group; group_index++)
2074 GtkAccelGroup *accel_group = accel_groups[group_index];
2075 const char *path_base = path_bases[group_index];
2079 path, table->
grid, GDK_KEY_Up, 0);
2083 path, table->
grid, GDK_KEY_Down, 0);
2087 path, table->
grid, GDK_KEY_Left, 0);
2091 path, table->
grid, GDK_KEY_Right, 0);
2095 path, table->
grid, GDK_KEY_Page_Up, 0);
2099 path, table->
grid, GDK_KEY_Page_Down, 0);
2103 path, table->
grid, GDK_KEY_Home, 0);
2107 path, table->
grid, GDK_KEY_End, 0);
2111 path, table->
grid, GDK_KEY_space, 0);
2117 path, table->
grid, GDK_KEY_space, GDK_CONTROL_MASK);
2119 path =
dt_accels_build_path(path_base, _(
"Expand the current selection up to the hovered thumbnail"));
2121 path, table->
grid, GDK_KEY_space, GDK_SHIFT_MASK);
2125 path, table->
grid, GDK_KEY_Return, 0);
2129 path, table->
grid, GDK_KEY_Alt_L, 0);
2135 path, table->
grid, GDK_KEY_Delete, 0);
2154 GList *thumbs = g_hash_table_get_values(table->
list);
2156 g_hash_table_remove_all(table->
list);
2159 for(GList *l = thumbs; l; l = g_list_next(l))
2162 gtk_widget_hide(thumb->
widget);
2165 g_list_free(thumbs);
2199 g_hash_table_destroy(table->
list);
2230 GList *thumbs = g_hash_table_get_values(table->
list);
2232 g_hash_table_remove_all(table->
list);
2235 for(GList *l = thumbs; l; l = g_list_next(l))
2238 gtk_widget_hide(thumb->
widget);
2241 g_list_free(thumbs);
2271 "Selecting all images will only target visible members of image groups.\n"
2272 "Uncollapse groups to select all their members"));
2278 img = g_list_prepend(img, GINT_TO_POINTER(table->
lut[
i].
imgid));
2296 "Selecting a range of images will only target visible members of image groups.\n"
2297 "Uncollapse groups to select all their members"));
2302 size_t rowid_end = 0;
2308 for(GList *s = g_list_first(
selected); s; s = g_list_next(s))
2310 int32_t imgid = GPOINTER_TO_INT(s->data);
2312 if(
row < 0)
continue;
2313 if(
row < rowid_start) rowid_start =
row;
2314 if(
row > rowid_end) rowid_end =
row;
2326 if(rowid_start > rowid_end)
2335 if(rowid > rowid_end && rowid_end < table->collection_count - 1)
2338 for(
int i = rowid_end + 1;
i <= rowid;
i++)
2339 img = g_list_prepend(img, GINT_TO_POINTER(table->
lut[
i].
imgid));
2341 else if(rowid < rowid_start && rowid_start > 0)
2344 for(
int i = rowid_start - 1;
i >= rowid;
i--)
2345 img = g_list_prepend(img, GINT_TO_POINTER(table->
lut[
i].
imgid));
2369 g_list_free(to_deselect);
2380 gint64 current_time = g_get_real_time();
2381 if(
type == GDK_KEY_PRESS ||
type == GDK_KEY_RELEASE)
2390 else if(
type == GDK_ENTER_NOTIFY ||
type == GDK_LEAVE_NOTIFY)
2402 else if(
type == GDK_MOTION_NOTIFY ||
type == GDK_BUTTON_PRESS ||
type == GDK_2BUTTON_PRESS)
2409 fprintf(stderr,
"[dt_thumbtable_dispatch_over] unsupported event type: %i\n",
type);
2419 if(!gtk_widget_has_focus(table->
grid))
2425 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()
struct dt_accels_t * dt_gui_get_accels(void)
struct dt_ui_t * dt_gui_get_ui(void)
void dt_gui_add_help_link(GtkWidget *widget, char *link)
static void error(char *msg)
dt_collection_t * dt_collection_get_global(void)
uint32_t dt_collection_get_count(const dt_collection_t *collection)
dt_collection_properties_t
@ DT_COLLECTION_PROP_GROUPING
@ DT_COLLECTION_CHANGE_BACKGROUND_SYNC
uint64_t dt_collection_query_get_generation(void)
dt_iop_colorout_gui_data_t dummy
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
const dt_colormatrix_t dt_aligned_pixel_t out
int dt_conf_get_bool(const char *name)
gchar * dt_conf_get_string(const char *name)
Read the stored string for name as a private copy.
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
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.
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)
struct dt_control_t * dt_control_get_global(void)
gboolean dt_control_remove_images()
struct dt_view_manager_t * dt_view_manager_get_global(void)
struct dt_gui_gtk_t * dt_gui_get_global(void)
GHashTable * selected
set of checked row labels, mirrored to conf on every change
GtkWidget * folder
destination folder chooser
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)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
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.
#define g_list_is_singleton(list)
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
static gboolean enable(const dt_image_t *image)
dt_image_t * dt_image_cache_testget(const int32_t imgid, char mode)
void dt_image_derive_fields(dt_image_t *img)
Compute the fields the database does not store: rating, monochrome and HDR predicates,...
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
void dt_image_cache_read_release(const dt_image_t *img)
gboolean dt_supported_image(const gchar *filename)
void dt_image_repository_foreach_collected(dt_image_repository_collected_cb cb, void *user_data)
Every image of the current collection, in collection order, already mapped.
Reading and writing one dt_image_t to and from the library database. The SQL half of what used to be ...
gboolean dt_import_passes_filter(const dt_import_filter_type_t filter_type, const gchar *pathname)
@ DT_IMPORT_FILTER_RASTER
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.
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
void * dt_control_job_get_params(const _dt_job_t *job)
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
_lib_location_type_t type
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
#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 void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
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)
struct dt_selection_t * dt_selection_get_global(void)
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,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ 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)
static const dt_aligned_pixel_simd_t value
unsigned __int64 uint64_t
GtkAccelGroup * map_accels
GtkAccelGroup * print_accels
GtkAccelGroup * lighttable_accels
GtkAccelGroup * darkroom_accels
dt_import_filter_type_t filter_type
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)
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)
@ _DT_DND_IMPORT_CHOICE_RASTER
@ _DT_DND_IMPORT_CHOICE_RAW
@ _DT_DND_IMPORT_CHOICE_ALL
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)
static void _collection_lut_row(void *user_data, const dt_image_t *row)
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_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.
void dt_thumbtable_schedule_focus_real(dt_thumbtable_t *table, const gint priority)
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)
static void _dnd_folder_import_job_cleanup(void *p)
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 _dnd_recurse_folder(const char *folder_path, dt_import_filter_type_t filter_type, GList **files, guint *scan_errors)
static void _thumbtable_dnd_scan_folders_and_import(GList *folders, GList *files)
GList * _thumbtable_dnd_import_check(GList *files, const char *pathname, int *elements, GList **folders)
static int32_t _dnd_folder_import_job_run(dt_job_t *job)
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_debug_assert_matches_cache(const dt_image_t *sql_info)
void dt_thumbtable_info_seed_image_cache(const dt_image_t *info)
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...
#define dt_thumbtable_schedule_focus(table, priority)
dt_thumbtable_direction_t
@ DT_TT_MOVE_PREVIOUS_PAGE
static double dt_get_wtime(void)
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)