Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
slideshow.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2013-2016 johannes hanika.
4 Copyright (C) 2014, 2019-2021 Aldric Renaudin.
5 Copyright (C) 2014 Moritz Lipp.
6 Copyright (C) 2014 parafin.
7 Copyright (C) 2014-2016 Roman Lebedev.
8 Copyright (C) 2014-2017, 2019-2020 Tobias Ellinghaus.
9 Copyright (C) 2015 Edouard Gomez.
10 Copyright (C) 2015, 2019-2021 Pascal Obry.
11 Copyright (C) 2019-2020, 2022-2023, 2025-2026 Aurélien PIERRE.
12 Copyright (C) 2019 Denis Dyakov.
13 Copyright (C) 2019 Philippe Weyland.
14 Copyright (C) 2020 Hanno Schwalm.
15 Copyright (C) 2020 quovadit.
16 Copyright (C) 2021-2022 Diederik Ter Rahe.
17 Copyright (C) 2021 Ralf Brown.
18 Copyright (C) 2022 Martin Bařinka.
19 Copyright (C) 2024 Alynx Zhou.
20
21 darktable is free software: you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation, either version 3 of the License, or
24 (at your option) any later version.
25
26 darktable is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
30
31 You should have received a copy of the GNU General Public License
32 along with darktable. If not, see <http://www.gnu.org/licenses/>.
33*/
34
35#include "database/database.h"
38#include "common/image.h"
39#include "system/macros.h"
40#include "system/mem_alloc.h"
42#include "common/collection.h"
43#include "common/selection.h"
44#include "system/dtpthread.h"
45#include "common/conf.h"
46#include "control/control.h"
48
49#include "gui/application.h"
50#include "views/view.h"
51#include "views/view_api.h"
52
53#include <gdk/gdkkeysyms.h>
54#include <stdint.h>
55
56DT_MODULE(1)
57
63
71
72typedef struct _slideshow_buf_t
73{
75 int32_t imgid;
76 int32_t rank;
77 gboolean invalidated;
79
85
86typedef struct dt_slideshow_t
87{
88 int32_t col_count;
89 uint32_t width, height;
91 GList *playlist;
92
93 // buffers
96
97 // state machine stuff for image transitions:
98 dt_pthread_mutex_t lock;
99
100 gboolean auto_advance;
101 int delay;
103
104 // some magic to hide the mouse pointer
107
108// fwd declare state machine mechanics:
110
112{
113 dt_slideshow_cache_t *tmp_cache = d->buf[S_LEFT].cache;
114
115 for(int k=S_LEFT; k<S_RIGHT; k++)
116 {
117 d->buf[k].cache = d->buf[k+1].cache;
118 d->buf[k].imgid = d->buf[k+1].imgid;
119 d->buf[k].rank = d->buf[k+1].rank;
120 d->buf[k].invalidated = d->buf[k+1].invalidated;
121 }
122 d->buf[S_RIGHT].invalidated = TRUE;
123 d->buf[S_RIGHT].imgid = UNKNOWN_IMAGE;
124 d->buf[S_RIGHT].rank = d->buf[S_CURRENT].rank + 1;
125 d->buf[S_RIGHT].cache = tmp_cache;
126}
127
129{
130 dt_slideshow_cache_t *tmp_cache = d->buf[S_RIGHT].cache;
131
132 for(int k=S_RIGHT; k>S_LEFT; k--)
133 {
134 d->buf[k].cache = d->buf[k-1].cache;
135 d->buf[k].imgid = d->buf[k-1].imgid;
136 d->buf[k].rank = d->buf[k-1].rank;
137 d->buf[k].invalidated = d->buf[k-1].invalidated;
138 }
139 d->buf[S_LEFT].invalidated = TRUE;
140 d->buf[S_LEFT].imgid = UNKNOWN_IMAGE;
141 d->buf[S_LEFT].rank = d->buf[S_CURRENT].rank - 1;
142 d->buf[S_LEFT].cache = tmp_cache;
143}
144
146{
147 d->delay = CLAMP(d->delay + value, 1, 60);
148 dt_conf_set_int("slideshow_delay", d->delay);
149}
150
151static int32_t _slideshow_get_imgid_from_rank(const dt_slideshow_t *d, const int32_t rank)
152{
153 if(rank < 0) return UNKNOWN_IMAGE;
154
155 if(d->playlist)
156 {
157 const GList *link = g_list_nth(d->playlist, rank);
158 return link ? GPOINTER_TO_INT(link->data) : UNKNOWN_IMAGE;
159 }
160
161 const int32_t id = dt_collection_query_get_nth(rank);
162 return id;
163}
164
166{
167 dt_slideshow_buf_t *buffer = &d->buf[slot];
168 if(buffer->rank < 0 || buffer->rank >= d->col_count)
169 {
170 buffer->imgid = UNKNOWN_IMAGE;
171 buffer->invalidated = FALSE;
173 return DT_VIEW_SURFACE_KO;
174 }
175
176 const int32_t imgid = _slideshow_get_imgid_from_rank(d, buffer->rank);
177 if(imgid <= UNKNOWN_IMAGE)
178 {
179 buffer->imgid = UNKNOWN_IMAGE;
180 buffer->invalidated = TRUE;
182 return DT_VIEW_SURFACE_KO;
183 }
184
185 buffer->imgid = imgid;
186 const int width = MAX(2, (int)d->width);
187 const int height = MAX(2, (int)d->height);
191 buffer->invalidated = (res != DT_VIEW_SURFACE_OK);
192 return res;
193}
194
195static gboolean auto_advance(gpointer user_data)
196{
197 dt_slideshow_t *d = (dt_slideshow_t *)user_data;
199 if(!d->auto_advance) return FALSE;
200
201 dt_pthread_mutex_lock(&d->lock);
205 const gboolean can_advance = d->buf[S_RIGHT].rank >= 0 && d->buf[S_RIGHT].rank < d->col_count
206 && !d->buf[S_RIGHT].invalidated && d->buf[S_RIGHT].cache->surface;
207 const gboolean at_end = d->buf[S_CURRENT].rank >= d->col_count - 1;
209
210 if(can_advance || at_end)
211 {
213 return FALSE;
214 }
215
216 /* Autoplay waits for the next slot surface instead of stepping onto an
217 * empty screen. Keep the right-hand prefetch alive and poll shortly until it
218 * lands, then the normal delayed cadence resumes from _step_state(). */
220 d->auto_advance_timeout = g_timeout_add(200, auto_advance, d);
221 return FALSE;
222}
223
231
232// state machine stepping
234{
235 dt_pthread_mutex_lock(&d->lock);
236
237 if(event == S_REQUEST_STEP)
238 {
239 if(d->buf[S_CURRENT].rank < d->col_count - 1)
240 {
241 shift_left(d);
242 if(!d->playlist)
243 {
244 d->buf[S_CURRENT].imgid = _slideshow_get_imgid_from_rank(d, d->buf[S_CURRENT].rank);
246 if(d->buf[S_CURRENT].imgid > UNKNOWN_IMAGE) dt_view_active_images_add(d->buf[S_CURRENT].imgid, FALSE);
247 }
248 d->buf[S_RIGHT].rank = d->buf[S_CURRENT].rank + 1;
249 d->buf[S_RIGHT].invalidated = d->buf[S_RIGHT].rank < d->col_count;
251 }
252 else
253 {
254 dt_control_log(_("end of images"));
255 d->auto_advance = FALSE;
256 }
257 }
258 else if(event == S_REQUEST_STEP_BACK)
259 {
260 if(d->buf[S_CURRENT].rank > 0)
261 {
262 shift_right(d);
263 if(!d->playlist)
264 {
265 d->buf[S_CURRENT].imgid = _slideshow_get_imgid_from_rank(d, d->buf[S_CURRENT].rank);
267 if(d->buf[S_CURRENT].imgid > UNKNOWN_IMAGE) dt_view_active_images_add(d->buf[S_CURRENT].imgid, FALSE);
268 }
269 d->buf[S_LEFT].rank = d->buf[S_CURRENT].rank - 1;
270 d->buf[S_LEFT].invalidated = d->buf[S_LEFT].rank >= 0;
272 }
273 else
274 {
275 dt_control_log(_("end of images. press any key to return to lighttable mode"));
276 d->auto_advance = FALSE;
277 }
278 }
279
281
282 if(d->auto_advance)
283 {
284 if(d->auto_advance_timeout > 0) g_source_remove(d->auto_advance_timeout);
285 d->auto_advance_timeout = g_timeout_add_seconds(d->delay, auto_advance, d);
286 }
287}
288
289// callbacks for a view module:
290
291const char *name(const dt_view_t *self)
292{
293 return _("slideshow");
294}
295
296uint32_t view(const dt_view_t *self)
297{
298 return DT_VIEW_SLIDESHOW;
299}
300
301void init(dt_view_t *self)
302{
303 self->data = calloc(1, sizeof(dt_slideshow_t));
304 dt_slideshow_t *lib = (dt_slideshow_t *)self->data;
305 dt_pthread_mutex_init(&lib->lock, 0);
306 for(int k = S_LEFT; k < S_SLOT_LAST; k++)
307 {
308 lib->buf[k].cache = &lib->cache[k];
309 lib->buf[k].imgid = UNKNOWN_IMAGE;
310 lib->buf[k].rank = -1;
311 lib->buf[k].invalidated = TRUE;
313 }
314}
315
316
318{
319 dt_slideshow_t *lib = (dt_slideshow_t *)self->data;
320 if(lib->mouse_timeout > 0) g_source_remove(lib->mouse_timeout);
321 if(lib->auto_advance_timeout > 0) g_source_remove(lib->auto_advance_timeout);
322 g_list_free(lib->incoming_selection);
323 g_list_free(lib->playlist);
324 for(int k = S_LEFT; k < S_SLOT_LAST; k++)
327 dt_free(self->data);
328}
329
331{
333 g_list_free(d->incoming_selection);
334 d->incoming_selection = dt_selection_get_list(dt_selection_get_global());
335 if(!d->incoming_selection && dt_view_active_images_get_all())
336 d->incoming_selection = g_list_copy((GList *)dt_view_active_images_get_all());
337
338 if(d->incoming_selection || dt_collection_get_count(dt_collection_get_global()) != 0) return 0;
339
340 dt_control_log(_("there are no images in this collection"));
341 return 1;
342}
343
344void enter(dt_view_t *self)
345{
347
348 dt_control_change_cursor(GDK_BLANK_CURSOR);
349 d->mouse_timeout = 0;
350 d->auto_advance_timeout = 0;
351
354
359
360 // also hide arrows
362
364 GdkRectangle rect;
365
366 GdkDisplay *display = gtk_widget_get_display(window);
367 GdkMonitor *mon = gdk_display_get_monitor_at_window(display, gtk_widget_get_window(window));
368 gdk_monitor_get_geometry(mon, &rect);
369
370 dt_pthread_mutex_lock(&d->lock);
371
372 d->width = rect.width;
373 d->height = rect.height;
374
376 g_list_free(d->playlist);
377 d->playlist = NULL;
378 if(d->incoming_selection)
379 {
380 /* Slideshow keeps either the incoming selection list or a single current
381 * image as its working set while the global selection stays cleared. */
382 dt_view_active_images_set(d->incoming_selection, FALSE);
383 d->incoming_selection = NULL;
384 d->playlist = g_list_copy(dt_view_active_images_get_all());
385 }
386
387 d->col_count = d->playlist ? g_list_length(d->playlist) : dt_collection_get_count(dt_collection_get_global());
388
389 for(int k = S_LEFT; k < S_SLOT_LAST; k++)
390 {
391 dt_view_image_surface_fetcher_invalidate(&d->cache[k].fetcher, &d->cache[k].surface);
392 d->buf[k].imgid = UNKNOWN_IMAGE;
393 d->buf[k].rank = -1;
394 d->buf[k].invalidated = TRUE;
395 }
396
397 if(d->playlist)
398 {
399 d->buf[S_CURRENT].rank = 0;
400 d->buf[S_CURRENT].imgid = GPOINTER_TO_INT(d->playlist->data);
401 }
402 else if(d->col_count > 0)
403 {
404 d->buf[S_CURRENT].rank = 0;
406 if(d->buf[S_CURRENT].imgid > UNKNOWN_IMAGE)
407 {
409 }
410 }
411
412 d->buf[S_LEFT].rank = d->buf[S_CURRENT].rank - 1;
413 d->buf[S_RIGHT].rank = d->buf[S_CURRENT].rank + 1;
414
415 d->auto_advance = FALSE;
416 d->delay = dt_conf_get_int("slideshow_delay");
418
420
423 dt_control_log(_("waiting to start slideshow"));
424}
425
426void leave(dt_view_t *self)
427{
429
430 if(d->mouse_timeout > 0) g_source_remove(d->mouse_timeout);
431 d->mouse_timeout = 0;
432 if(d->auto_advance_timeout > 0) g_source_remove(d->auto_advance_timeout);
433 d->auto_advance_timeout = 0;
434 dt_control_change_cursor(GDK_LEFT_PTR);
435 d->auto_advance = FALSE;
437
442 g_list_free(d->incoming_selection);
443 d->incoming_selection = NULL;
444 g_list_free(d->playlist);
445 d->playlist = NULL;
446 for(int k = S_LEFT; k < S_SLOT_LAST; k++)
447 {
448 dt_view_image_surface_fetcher_invalidate(&d->cache[k].fetcher, &d->cache[k].surface);
449 d->buf[k].imgid = UNKNOWN_IMAGE;
450 d->buf[k].rank = -1;
451 d->buf[k].invalidated = TRUE;
452 }
453}
454
455void expose(dt_view_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
456{
457 // draw front buffer.
459
460 dt_pthread_mutex_lock(&d->lock);
461 cairo_paint(cr);
462 d->width = width;
463 d->height = height;
467
468 const dt_slideshow_buf_t *slot = &(d->buf[S_CURRENT]);
469 cairo_surface_t *surface = slot->cache->surface;
470 if(surface && slot->rank >= 0 && !slot->invalidated)
471 {
472 const int surface_width = cairo_image_surface_get_width(surface);
473 const int surface_height = cairo_image_surface_get_height(surface);
474 double sx = 1.0, sy = 1.0;
475 cairo_surface_get_device_scale(surface, &sx, &sy);
476 const double logical_width = surface_width / sx;
477 const double logical_height = surface_height / sy;
478 // cope with possible resize of the window
479 const float tr_width = (width < logical_width) ? 0.f : (width - logical_width) * .5f;
480 const float tr_height = (height < logical_height) ? 0.f : (height - logical_height) * .5f;
481
482 cairo_save(cr);
483 cairo_translate(cr, tr_width, tr_height);
484 cairo_set_source_surface(cr, surface, 0, 0);
485 cairo_pattern_set_filter(cairo_get_source(cr), dt_widget_image_filter());
486 cairo_rectangle(cr, 0, 0, logical_width, logical_height);
487 cairo_fill(cr);
488 cairo_restore(cr);
489 }
490 else
491 {
493 }
495}
496
497int key_pressed(dt_view_t *self, GdkEventKey *event)
498{
499 if(!gtk_window_is_active(GTK_WINDOW(dt_gui_get_ui()->main_window))) return FALSE;
500
501 switch(event->keyval)
502 {
503 case GDK_KEY_Escape:
504 {
505 dt_ctl_switch_mode_to("lighttable");
506 return TRUE;
507 }
508 }
509
510 return 0;
511}
512
518static gboolean _slideshow_start_stop_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval,
519 GdkModifierType mods, gpointer user_data)
520{
521 dt_view_t *self = (dt_view_t *)user_data;
523 if(!d->auto_advance)
524 {
525 d->auto_advance = TRUE;
526 if(d->auto_advance_timeout > 0) g_source_remove(d->auto_advance_timeout);
527 d->auto_advance_timeout = g_timeout_add_seconds(d->delay, auto_advance, d);
528 dt_control_log(_("slideshow started"));
529 }
530 else
531 {
532 d->auto_advance = FALSE;
533 if(d->auto_advance_timeout > 0) g_source_remove(d->auto_advance_timeout);
534 d->auto_advance_timeout = 0;
535 dt_control_log(_("slideshow paused"));
536 }
537 return TRUE;
538}
539
544static gboolean _slideshow_slow_down_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval,
545 GdkModifierType mods, gpointer user_data)
546{
547 dt_view_t *self = (dt_view_t *)user_data;
549 _set_delay(d, 1);
550 dt_control_log(ngettext("slideshow delay set to %d second", "slideshow delay set to %d seconds", d->delay),
551 d->delay);
552 return TRUE;
553}
554
559static gboolean _slideshow_speed_up_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval,
560 GdkModifierType mods, gpointer user_data)
561{
562 dt_view_t *self = (dt_view_t *)user_data;
564 _set_delay(d, -1);
565 dt_control_log(ngettext("slideshow delay set to %d second", "slideshow delay set to %d seconds", d->delay),
566 d->delay);
567 return TRUE;
568}
569
574static gboolean _slideshow_step_forward_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval,
575 GdkModifierType mods, gpointer user_data)
576{
577 dt_view_t *self = (dt_view_t *)user_data;
579 if(d->auto_advance) dt_control_log(_("slideshow paused"));
580 d->auto_advance = FALSE;
581 if(d->auto_advance_timeout > 0) g_source_remove(d->auto_advance_timeout);
582 d->auto_advance_timeout = 0;
584 return TRUE;
585}
586
591static gboolean _slideshow_step_back_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval,
592 GdkModifierType mods, gpointer user_data)
593{
594 dt_view_t *self = (dt_view_t *)user_data;
596 if(d->auto_advance) dt_control_log(_("slideshow paused"));
597 d->auto_advance = FALSE;
598 if(d->auto_advance_timeout > 0) g_source_remove(d->auto_advance_timeout);
599 d->auto_advance_timeout = 0;
601 return TRUE;
602}
603
604static gboolean _hide_mouse(gpointer user_data)
605{
606 dt_view_t *self = (dt_view_t *)user_data;
608 d->mouse_timeout = 0;
609 dt_control_change_cursor(GDK_BLANK_CURSOR);
610 return FALSE;
611}
612
613
614void mouse_moved(dt_view_t *self, double x, double y, double pressure, int which)
615{
617
618 if(d->mouse_timeout > 0) g_source_remove(d->mouse_timeout);
619 else dt_control_change_cursor(GDK_LEFT_PTR);
620 d->mouse_timeout = g_timeout_add_seconds(1, _hide_mouse, self);
621}
622
623
624int button_released(dt_view_t *self, double x, double y, int which, uint32_t state)
625{
626 return 0;
627}
628
629
630int button_pressed(dt_view_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
631{
633
634 if(which == 1)
636 else if(which == 3)
638 else
639 return 1;
640
641 return 0;
642}
643
645{
646 dt_accels_new_slideshow_action(_slideshow_start_stop_accel, self, NULL, N_("Slideshow/Actions"),
647 N_("Start and stop"), GDK_KEY_space, 0,
648 _("Toggles slideshow auto-advance"));
649 dt_accels_new_slideshow_action(_slideshow_slow_down_accel, self, NULL, N_("Slideshow/Actions"),
650 N_("Slow down"), GDK_KEY_Up, 0,
651 _("Increases the slideshow delay"));
652 dt_accels_new_slideshow_action(_slideshow_slow_down_accel, self, NULL, N_("Slideshow/Actions"),
653 N_("Slow down"), GDK_KEY_KP_Add, 0,
654 _("Increases the slideshow delay"));
655 dt_accels_new_slideshow_action(_slideshow_slow_down_accel, self, NULL, N_("Slideshow/Actions"),
656 N_("Slow down"), GDK_KEY_plus, 0,
657 _("Increases the slideshow delay"));
658 dt_accels_new_slideshow_action(_slideshow_speed_up_accel, self, NULL, N_("Slideshow/Actions"),
659 N_("Speed up"), GDK_KEY_Down, 0,
660 _("Decreases the slideshow delay"));
661 dt_accels_new_slideshow_action(_slideshow_speed_up_accel, self, NULL, N_("Slideshow/Actions"),
662 N_("Speed up"), GDK_KEY_KP_Subtract, 0,
663 _("Decreases the slideshow delay"));
664 dt_accels_new_slideshow_action(_slideshow_speed_up_accel, self, NULL, N_("Slideshow/Actions"),
665 N_("Speed up"), GDK_KEY_minus, 0,
666 _("Decreases the slideshow delay"));
667 dt_accels_new_slideshow_action(_slideshow_step_back_accel, self, NULL, N_("Slideshow/Actions"),
668 N_("Step back"), GDK_KEY_Left, 0,
669 _("Displays the previous image"));
670 dt_accels_new_slideshow_action(_slideshow_step_forward_accel, self, NULL, N_("Slideshow/Actions"),
671 N_("Step forward"), GDK_KEY_Right, 0,
672 _("Displays the next image"));
673}
674
675// clang-format off
676// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
677// vim: shiftwidth=2 expandtab tabstop=2 cindent
678// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
679// clang-format on
void dt_accels_connect_accels(dt_accels_t *accels)
Actually enable accelerators after having loaded user config.
void dt_accels_connect_active_group(dt_accels_t *accels, const gchar *group)
Connect the contextual active accels group to the window. Views can declare their own set of contextu...
void dt_accels_disconnect_active_group(dt_accels_t *accels)
Disconnect the contextual active accels group from the window.
GtkWidget * dt_gui_main_window(void)
struct dt_accels_t * dt_gui_get_accels(void)
struct dt_ui_t * dt_gui_get_ui(void)
GtkWidget * dt_gui_center_widget(void)
void dt_gui_refocus_center()
#define dt_accels_new_slideshow_action(a, b, w, c, d, e, f, g)
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
dt_collection_t * dt_collection_get_global(void)
Definition collection.c:138
uint32_t dt_collection_get_count(const dt_collection_t *collection)
Definition collection.c:269
int32_t dt_collection_query_get_nth(const int nth)
static const float x
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
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_ctl_switch_mode_to(const char *mode)
Definition control.c:701
void dt_control_draw_busy_msg(cairo_t *cr, int width, int height)
Definition control.c:530
void dt_control_log(const char *msg,...)
Definition control.c:824
void dt_control_queue_redraw_center()
Request a redraw of the centre view.
Definition control.c:924
void dt_control_queue_redraw()
Request a redraw of the whole workspace.
Definition control.c:919
#define dt_control_change_cursor(cursor)
Definition control.h:121
void dt_ui_panel_show(dt_ui_t *ui, const dt_ui_panel_t p, gboolean show, gboolean write)
shows/hide a panel
Definition display.c:129
GtkWidget * window
GtkWidget * view
the tree view
const int res
Definition dtpthread.h:351
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:127
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 ...
Definition dtpthread.h:104
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
Definition dtpthread.h:132
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:117
#define UNKNOWN_IMAGE
Definition image.h:78
_lib_location_type_t type
Definition location.c:1
float *const restrict const size_t k
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
#define DT_MODULE(MODVER)
Instantiate the version handshake every module must export. Use once, at file scope,...
const char * name
Definition pdf.h:90
struct dt_selection_t * dt_selection_get_global(void)
Definition selection.c:80
GList * dt_selection_get_list(struct dt_selection_t *selection)
Definition selection.c:185
void dt_selection_select_list(struct dt_selection_t *selection, const GList *const l)
Definition selection.c:330
void dt_selection_clear(dt_selection_t *selection)
Definition selection.c:271
static const dt_aligned_pixel_simd_t value
Definition simd.h:144
void init(dt_view_t *self)
Definition slideshow.c:301
static gboolean _slideshow_start_stop_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType mods, gpointer user_data)
Toggle slideshow auto-advance using the same stepping code path as manual navigation,...
Definition slideshow.c:518
static gboolean _slideshow_slow_down_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType mods, gpointer user_data)
Increase the slideshow delay and store it immediately so repeated keyboard adjustments persist across...
Definition slideshow.c:544
static gboolean _slideshow_step_forward_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType mods, gpointer user_data)
Advance the slideshow while keeping auto-advance and global actions synced with the image currently d...
Definition slideshow.c:574
void leave(dt_view_t *self)
Definition slideshow.c:426
dt_slideshow_slot_t
Definition slideshow.c:65
@ S_SLOT_LAST
Definition slideshow.c:69
@ S_CURRENT
Definition slideshow.c:67
@ S_RIGHT
Definition slideshow.c:68
@ S_LEFT
Definition slideshow.c:66
static int32_t _slideshow_get_imgid_from_rank(const dt_slideshow_t *d, const int32_t rank)
Definition slideshow.c:151
int button_pressed(dt_view_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
Definition slideshow.c:630
static void shift_right(dt_slideshow_t *d)
Definition slideshow.c:128
void cleanup(dt_view_t *self)
Definition slideshow.c:317
dt_slideshow_event_t
Definition slideshow.c:59
@ S_REQUEST_STEP_BACK
Definition slideshow.c:61
@ S_REQUEST_STEP
Definition slideshow.c:60
static gboolean _slideshow_step_back_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType mods, gpointer user_data)
Step back in slideshow mode and keep the fullscreen image as the sole active image when the selection...
Definition slideshow.c:591
static gboolean auto_advance(gpointer user_data)
Definition slideshow.c:195
void expose(dt_view_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
Definition slideshow.c:455
int key_pressed(dt_view_t *self, GdkEventKey *event)
Definition slideshow.c:497
static gboolean _hide_mouse(gpointer user_data)
Definition slideshow.c:604
void mouse_moved(dt_view_t *self, double x, double y, double pressure, int which)
Definition slideshow.c:614
int button_released(dt_view_t *self, double x, double y, int which, uint32_t state)
Definition slideshow.c:624
struct _slideshow_buf_t dt_slideshow_buf_t
static void _refresh_display(dt_slideshow_t *d)
Definition slideshow.c:224
void enter(dt_view_t *self)
Definition slideshow.c:344
static void _set_delay(dt_slideshow_t *d, int value)
Definition slideshow.c:145
static void _step_state(dt_slideshow_t *d, dt_slideshow_event_t event)
Definition slideshow.c:233
void gui_init(dt_view_t *self)
Definition slideshow.c:644
static gboolean _slideshow_speed_up_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType mods, gpointer user_data)
Decrease the slideshow delay and store it immediately so the current playback cadence matches the per...
Definition slideshow.c:559
static dt_view_surface_value_t _slideshow_request_slot(dt_slideshow_t *d, const dt_slideshow_slot_t slot)
Definition slideshow.c:165
int try_enter(dt_view_t *self)
Definition slideshow.c:330
static void shift_left(dt_slideshow_t *d)
Definition slideshow.c:111
const float uint32_t state[4]
static const char *const mon[12]
Definition strptime.c:99
gboolean invalidated
Definition slideshow.c:77
struct dt_slideshow_cache_t * cache
Definition slideshow.c:74
dt_view_image_surface_fetcher_t fetcher
Definition slideshow.c:83
cairo_surface_t * surface
Definition slideshow.c:82
uint32_t height
Definition slideshow.c:89
int32_t col_count
Definition slideshow.c:88
uint32_t width
Definition slideshow.c:89
guint mouse_timeout
Definition slideshow.c:105
gboolean auto_advance
Definition slideshow.c:100
GList * playlist
Definition slideshow.c:91
dt_pthread_mutex_t lock
Definition slideshow.c:98
dt_slideshow_buf_t buf[S_SLOT_LAST]
Definition slideshow.c:94
GList * incoming_selection
Definition slideshow.c:90
guint auto_advance_timeout
Definition slideshow.c:102
dt_slideshow_cache_t cache[S_SLOT_LAST]
Definition slideshow.c:95
Track one asynchronous Cairo surface fetch request for a GUI widget.
Definition view.h:119
GModule *void * data
Definition view.h:159
double width
#define MAX(a, b)
Definition thinplate.c:29
A widget to manage and display image thumbnails in Ansel's lighttable and filmstrip views.
@ DT_THUMBTABLE_ZOOM_FIT
Definition thumbtable.h:77
void dt_view_image_surface_fetcher_invalidate(dt_view_image_surface_fetcher_t *fetcher, cairo_surface_t **target)
Definition view.c:871
void dt_view_image_surface_fetcher_cleanup(dt_view_image_surface_fetcher_t *fetcher)
Definition view.c:847
void dt_view_image_surface_fetcher_init(dt_view_image_surface_fetcher_t *fetcher)
Definition view.c:836
dt_view_surface_value_t dt_view_image_get_surface_async(dt_view_image_surface_fetcher_t *fetcher, int32_t imgid, int width, int height, cairo_surface_t **target, GtkWidget *widget, int zoom)
Definition view.c:892
void dt_view_active_images_add(int32_t imgid, gboolean raise)
Definition view.c:1276
void dt_view_active_images_reset(gboolean raise)
Definition view.c:1266
GList * dt_view_active_images_get_all()
Definition view.c:1302
void dt_view_active_images_set(GList *images, gboolean raise)
Definition view.c:1314
@ DT_VIEW_SLIDESHOW
Definition view.h:81
dt_view_surface_value_t
Definition view.h:104
@ DT_VIEW_SURFACE_OK
Definition view.h:105
@ DT_VIEW_SURFACE_KO
Definition view.h:106
cairo_filter_t dt_widget_image_filter(void)
@ DT_UI_PANEL_TOP
@ DT_UI_PANEL_BOTTOM
@ DT_UI_PANEL_LEFT
@ DT_UI_PANEL_RIGHT