1 /*
2     This file is part of darktable,
3     Copyright (C) 2009-2021 darktable developers.
4 
5     darktable is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     darktable is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with darktable.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 
21 #include "common/history.h"
22 #include "common/image.h"
23 #ifdef HAVE_PRINT
24 #include "common/cups_print.h"
25 #endif
26 #ifdef HAVE_MAP
27 #include "common/geo.h"
28 #include "common/map_locations.h"
29 #include <osm-gps-map.h>
30 #endif
31 #include <cairo.h>
32 #include <gmodule.h>
33 #include <gui/gtk.h>
34 #include <inttypes.h>
35 #include <sqlite3.h>
36 #ifdef USE_LUA
37 #include "lua/call.h"
38 #include "lua/events.h"
39 #include "lua/modules.h"
40 #include "lua/types.h"
41 #include "lua/view.h"
42 #endif
43 
44 /** available views flags, a view should return its type and
45     is also used in modules flags available in src/libs to
46     control which view the module should be available in also
47     which placement in the panels the module have.
48 */
49 typedef enum
50 {
51   DT_VIEW_LIGHTTABLE = 1,
52   DT_VIEW_DARKROOM = 2,
53   DT_VIEW_TETHERING = 4,
54   DT_VIEW_MAP = 8,
55   DT_VIEW_SLIDESHOW = 16,
56   DT_VIEW_PRINT = 32,
57   DT_VIEW_KNIGHT = 64
58 } dt_view_type_flags_t;
59 
60 // flags that a view can set in flags()
61 typedef enum dt_view_flags_t
62 {
63   VIEW_FLAGS_NONE = 0,
64   VIEW_FLAGS_HIDDEN = 1 << 0,       // Hide the view from userinterface
65 } dt_view_flags_t;
66 
67 typedef enum dt_lighttable_layout_t
68 {
69   DT_LIGHTTABLE_LAYOUT_FIRST = -1,
70   DT_LIGHTTABLE_LAYOUT_ZOOMABLE = 0,
71   DT_LIGHTTABLE_LAYOUT_FILEMANAGER = 1,
72   DT_LIGHTTABLE_LAYOUT_CULLING = 2,
73   DT_LIGHTTABLE_LAYOUT_CULLING_DYNAMIC = 3,
74   DT_LIGHTTABLE_LAYOUT_PREVIEW = 4,
75   DT_LIGHTTABLE_LAYOUT_LAST = 5
76 } dt_lighttable_layout_t;
77 
78 typedef enum dt_darkroom_layout_t
79 {
80   DT_DARKROOM_LAYOUT_FIRST = -1,
81   DT_DARKROOM_LAYOUT_EDITING = 0,
82   DT_DARKROOM_LAYOUT_COLOR_ASSESMENT = 1,
83   DT_DARKROOM_LAYOUT_LAST = 3
84 } dt_darkroom_layout_t;
85 
86 // mouse actions struct
87 typedef enum dt_mouse_action_type_t
88 {
89   DT_MOUSE_ACTION_LEFT = 0,
90   DT_MOUSE_ACTION_RIGHT,
91   DT_MOUSE_ACTION_MIDDLE,
92   DT_MOUSE_ACTION_SCROLL,
93   DT_MOUSE_ACTION_DOUBLE_LEFT,
94   DT_MOUSE_ACTION_DOUBLE_RIGHT,
95   DT_MOUSE_ACTION_DRAG_DROP,
96   DT_MOUSE_ACTION_LEFT_DRAG,
97   DT_MOUSE_ACTION_RIGHT_DRAG
98 } dt_mouse_action_type_t;
99 
100 // flags that a view can set in flags()
101 typedef enum dt_view_surface_value_t
102 {
103   DT_VIEW_SURFACE_OK = 0,
104   DT_VIEW_SURFACE_KO,
105   DT_VIEW_SURFACE_SMALLER
106 } dt_view_surface_value_t;
107 
108 typedef struct dt_mouse_action_t
109 {
110   GtkAccelKey key;
111   dt_mouse_action_type_t action;
112   gchar name[256];
113 } dt_mouse_action_t;
114 
115 #define DT_VIEW_ALL                                                                              \
116   (DT_VIEW_LIGHTTABLE | DT_VIEW_DARKROOM | DT_VIEW_TETHERING | DT_VIEW_MAP | DT_VIEW_SLIDESHOW | \
117    DT_VIEW_PRINT | DT_VIEW_KNIGHT)
118 
119 /* maximum zoom factor for the lighttable */
120 #define DT_LIGHTTABLE_MAX_ZOOM 25
121 
122 /**
123  * main dt view module (as lighttable or darkroom)
124  */
125 struct dt_view_t;
126 typedef struct dt_view_t
127 {
128 #define INCLUDE_API_FROM_MODULE_H
129 #include "views/view_api.h"
130 
131   char module_name[64];
132   // dlopened module
133   GModule *module;
134   // custom data for module
135   void *data;
136   // width and height of allocation
137   uint32_t width, height;
138   // scroll bar control
139   float vscroll_size, vscroll_lower, vscroll_viewport_size, vscroll_pos;
140   float hscroll_size, hscroll_lower, hscroll_viewport_size, hscroll_pos;
141 
142   GSList *accel_closures;
143   GtkWidget *dynamic_accel_current;
144 } dt_view_t;
145 
146 typedef enum dt_view_image_over_t
147 {
148   DT_VIEW_ERR     = -1,
149   DT_VIEW_DESERT  =  0,
150   DT_VIEW_STAR_1  =  1,
151   DT_VIEW_STAR_2  =  2,
152   DT_VIEW_STAR_3  =  3,
153   DT_VIEW_STAR_4  =  4,
154   DT_VIEW_STAR_5  =  5,
155   DT_VIEW_REJECT  =  6,
156   DT_VIEW_GROUP   =  7,
157   DT_VIEW_AUDIO   =  8,
158   DT_VIEW_ALTERED =  9,
159   DT_VIEW_END     = 10, // placeholder for the end of the list
160 } dt_view_image_over_t;
161 
162 // get images to act on for gloabals change (via libs or accels)
163 // no need to free the list - done internally
164 const GList *dt_view_get_images_to_act_on(const gboolean only_visible, const gboolean force,
165                                           const gboolean ordered);
166 gchar *dt_view_get_images_to_act_on_query(const gboolean only_visible);
167 // get the main image to act on during global changes (libs, accels)
168 int dt_view_get_image_to_act_on();
169 
170 /** returns an uppercase string of file extension **plus** some flag information **/
171 char* dt_view_extend_modes_str(const char * name, const gboolean is_hdr, const gboolean is_bw, const gboolean is_bw_flow);
172 /** expose an image and return a cair0_surface. */
173 dt_view_surface_value_t dt_view_image_get_surface(int imgid, int width, int height, cairo_surface_t **surface,
174                                                   const gboolean quality);
175 
176 
177 /** Set the selection bit to a given value for the specified image */
178 void dt_view_set_selection(int imgid, int value);
179 /** toggle selection of given image. */
180 void dt_view_toggle_selection(int imgid);
181 
182 /**
183  * holds all relevant data needed to manage the view
184  * modules.
185  */
186 typedef struct dt_view_manager_t
187 {
188   GList *views;
189   dt_view_t *current_view;
190 
191   // images currently active in the main view (there can be more than 1 in culling)
192   GSList *active_images;
193 
194   // copy/paste history structure
195   dt_history_copy_item_t copy_paste;
196 
197   struct
198   {
199     GtkWidget *window;
200     GtkWidget *sticky_btn;
201     GtkWidget *flow_box;
202     gboolean sticky;
203     gboolean prevent_refresh;
204   } accels_window;
205 
206   struct
207   {
208     GList *images;
209     gboolean ok;
210     int image_over;
211     gboolean inside_table;
212     GSList *active_imgs;
213     gboolean image_over_inside_sel;
214     gboolean ordered;
215   } act_on;
216 
217   /* reusable db statements
218    * TODO: reconsider creating a common/database helper API
219    *       instead of having this spread around in sources..
220    */
221   struct
222   {
223     /* select num from history where imgid = ?1*/
224     sqlite3_stmt *have_history;
225     /* select * from selected_images where imgid = ?1 */
226     sqlite3_stmt *is_selected;
227     /* delete from selected_images where imgid = ?1 */
228     sqlite3_stmt *delete_from_selected;
229     /* insert into selected_images values (?1) */
230     sqlite3_stmt *make_selected;
231     /* select color from color_labels where imgid=?1 */
232     sqlite3_stmt *get_color;
233     /* select images in group from images where imgid=?1 (also bind to ?2) */
234     sqlite3_stmt *get_grouped;
235   } statements;
236 
237   struct
238   {
239     GPid audio_player_pid;   // the pid of the child process
240     int32_t audio_player_id; // the imgid of the image the audio is played for
241     guint audio_player_event_source;
242   } audio;
243 
244   /*
245    * Proxy
246    */
247   struct
248   {
249 
250     /* view toolbox proxy object */
251     struct
252     {
253       struct dt_lib_module_t *module;
254       void (*add)(struct dt_lib_module_t *, GtkWidget *, dt_view_type_flags_t );
255     } view_toolbox;
256 
257     /* module toolbox proxy object */
258     struct
259     {
260       struct dt_lib_module_t *module;
261       void (*add)(struct dt_lib_module_t *, GtkWidget *, dt_view_type_flags_t);
262     } module_toolbox;
263 
264     /* filter toolbox proxy object */
265     struct
266     {
267       struct dt_lib_module_t *module;
268       void (*reset_filter)(struct dt_lib_module_t *, gboolean smart_filter);
269     } filter;
270 
271     /* module collection proxy object */
272     struct
273     {
274       struct dt_lib_module_t *module;
275       void (*update)(struct dt_lib_module_t *);
276     } module_collect;
277 
278     /* filmstrip proxy object */
279     struct
280     {
281       struct dt_lib_module_t *module;
282     } filmstrip;
283 
284     /* darkroom view proxy object */
285     struct
286     {
287       struct dt_view_t *view;
288       dt_darkroom_layout_t (*get_layout)(struct dt_view_t *view);
289     } darkroom;
290 
291     /* lighttable view proxy object */
292     struct
293     {
294       struct dt_lib_module_t *module;
295       struct dt_view_t *view;
296       void (*set_zoom)(struct dt_lib_module_t *module, gint zoom);
297       gint (*get_zoom)(struct dt_lib_module_t *module);
298       dt_lighttable_layout_t (*get_layout)(struct dt_lib_module_t *module);
299       void (*set_layout)(struct dt_lib_module_t *module, dt_lighttable_layout_t layout);
300       void (*culling_init_mode)(struct dt_view_t *view);
301       void (*culling_preview_refresh)(struct dt_view_t *view);
302       void (*culling_preview_reload_overlays)(struct dt_view_t *view);
303       gboolean (*get_preview_state)(struct dt_view_t *view);
304       void (*set_preview_state)(struct dt_view_t *view, gboolean state, gboolean focus);
305       void (*change_offset)(struct dt_view_t *view, gboolean reset, gint imgid);
306     } lighttable;
307 
308     /* tethering view proxy object */
309     struct
310     {
311       struct dt_view_t *view;
312       const char *(*get_job_code)(const dt_view_t *view);
313       void (*set_job_code)(const dt_view_t *view, const char *name);
314       int32_t (*get_selected_imgid)(const dt_view_t *view);
315     } tethering;
316 
317     /* timeline module proxy */
318     struct
319     {
320       struct dt_lib_module_t *module;
321     } timeline;
322 
323 
324 /* map view proxy object */
325 #ifdef HAVE_MAP
326     struct
327     {
328       struct dt_view_t *view;
329       void (*center_on_location)(const dt_view_t *view, gdouble lon, gdouble lat, double zoom);
330       void (*center_on_bbox)(const dt_view_t *view, gdouble lon1, gdouble lat1, gdouble lon2, gdouble lat2);
331       void (*show_osd)(const dt_view_t *view);
332       void (*set_map_source)(const dt_view_t *view, OsmGpsMapSource_t map_source);
333       GObject *(*add_marker)(const dt_view_t *view, dt_geo_map_display_t type, GList *points);
334       gboolean (*remove_marker)(const dt_view_t *view, dt_geo_map_display_t type, GObject *marker);
335       void (*add_location)(const dt_view_t *view, dt_map_location_data_t *p, const guint posid);
336       void (*location_action)(const dt_view_t *view, const int action);
337       void (*drag_set_icon)(const dt_view_t *view, GdkDragContext *context, const int imgid, const int count);
338       gboolean (*redraw)(gpointer user_data);
339       gboolean (*display_selected)(gpointer user_data);
340     } map;
341 #endif
342 
343     /* map view proxy object */
344 #ifdef HAVE_PRINT
345     struct
346     {
347       struct dt_view_t *view;
348       void (*print_settings)(const dt_view_t *view, dt_print_info_t *pinfo);
349     } print;
350 #endif
351   } proxy;
352 
353 
354 } dt_view_manager_t;
355 
356 void dt_view_manager_init(dt_view_manager_t *vm);
357 void dt_view_manager_gui_init(dt_view_manager_t *vm);
358 void dt_view_manager_cleanup(dt_view_manager_t *vm);
359 
360 /** return translated name. */
361 const char *dt_view_manager_name(dt_view_manager_t *vm);
362 /** switch to this module. returns non-null if the module fails to change. */
363 int dt_view_manager_switch(dt_view_manager_t *vm, const char *view_name);
364 int dt_view_manager_switch_by_view(dt_view_manager_t *vm, const dt_view_t *new_view);
365 /** expose current module. */
366 void dt_view_manager_expose(dt_view_manager_t *vm, cairo_t *cr, int32_t width, int32_t height,
367                             int32_t pointerx, int32_t pointery);
368 /** reset current view. */
369 void dt_view_manager_reset(dt_view_manager_t *vm);
370 /** get current view of the view manager. */
371 const dt_view_t *dt_view_manager_get_current_view(dt_view_manager_t *vm);
372 
373 void dt_view_manager_mouse_enter(dt_view_manager_t *vm);
374 void dt_view_manager_mouse_leave(dt_view_manager_t *vm);
375 void dt_view_manager_mouse_moved(dt_view_manager_t *vm, double x, double y, double pressure, int which);
376 int dt_view_manager_button_released(dt_view_manager_t *vm, double x, double y, int which, uint32_t state);
377 int dt_view_manager_button_pressed(dt_view_manager_t *vm, double x, double y, double pressure, int which,
378                                    int type, uint32_t state);
379 int dt_view_manager_key_pressed(dt_view_manager_t *vm, guint key, guint state);
380 int dt_view_manager_key_released(dt_view_manager_t *vm, guint key, guint state);
381 void dt_view_manager_configure(dt_view_manager_t *vm, int width, int height);
382 void dt_view_manager_scrolled(dt_view_manager_t *vm, double x, double y, int up, int state);
383 void dt_view_manager_scrollbar_changed(dt_view_manager_t *vm, double x, double y);
384 
385 /** add widget to the current view toolbox */
386 void dt_view_manager_view_toolbox_add(dt_view_manager_t *vm, GtkWidget *tool, dt_view_type_flags_t view);
387 
388 /** add widget to the current module toolbox */
389 void dt_view_manager_module_toolbox_add(dt_view_manager_t *vm, GtkWidget *tool, dt_view_type_flags_t view);
390 
391 /** set scrollbar positions, gui method. */
392 void dt_view_set_scrollbar(dt_view_t *view, float hpos, float hscroll_lower, float hsize, float hwinsize,
393                            float vpos, float vscroll_lower, float vsize, float vwinsize);
394 
395 /** add mouse action record to list of mouse actions */
396 GSList *dt_mouse_action_create_simple(GSList *actions, dt_mouse_action_type_t type, GdkModifierType accel,
397                                       const char *const description);
398 GSList *dt_mouse_action_create_format(GSList *actions, dt_mouse_action_type_t type, GdkModifierType accel,
399                                       const char *const format_string, const char *const replacement);
400 
401 /*
402  * Tethering View PROXY
403  */
404 /** get the current selected image id for tethering session */
405 int32_t dt_view_tethering_get_selected_imgid(const dt_view_manager_t *vm);
406 /** set the current jobcode for tethering session */
407 void dt_view_tethering_set_job_code(const dt_view_manager_t *vm, const char *name);
408 /** get the current jobcode for tethering session */
409 const char *dt_view_tethering_get_job_code(const dt_view_manager_t *vm);
410 
411 /** update the collection module */
412 void dt_view_collection_update(const dt_view_manager_t *vm);
413 
414 /*
415  * Filter dropdown proxy
416  */
417 void dt_view_filter_reset(const dt_view_manager_t *vm, gboolean smart_filter);
418 
419 // active images functions
420 void dt_view_active_images_reset(gboolean raise);
421 void dt_view_active_images_add(int imgid, gboolean raise);
422 GSList *dt_view_active_images_get();
423 
424 /** get the lighttable current layout */
425 dt_lighttable_layout_t dt_view_lighttable_get_layout(dt_view_manager_t *vm);
426 /** get the darkroom current layout */
427 dt_darkroom_layout_t dt_view_darkroom_get_layout(dt_view_manager_t *vm);
428 /** get the lighttable full preview state */
429 gboolean dt_view_lighttable_preview_state(dt_view_manager_t *vm);
430 /** set the lighttable full preview state */
431 void dt_view_lighttable_set_preview_state(dt_view_manager_t *vm, gboolean state, gboolean focus);
432 /** sets the lighttable image in row zoom */
433 void dt_view_lighttable_set_zoom(dt_view_manager_t *vm, gint zoom);
434 /** gets the lighttable image in row zoom */
435 gint dt_view_lighttable_get_zoom(dt_view_manager_t *vm);
436 /** reinit culling for new mode */
437 void dt_view_lighttable_culling_init_mode(dt_view_manager_t *vm);
438 /** force refresh of culling and/or preview */
439 void dt_view_lighttable_culling_preview_refresh(dt_view_manager_t *vm);
440 /** force refresh of culling and/or preview overlays */
441 void dt_view_lighttable_culling_preview_reload_overlays(dt_view_manager_t *vm);
442 /** sets the offset image (for culling and full preview) */
443 void dt_view_lighttable_change_offset(dt_view_manager_t *vm, gboolean reset, gint imgid);
444 
445 /* accel window */
446 void dt_view_accels_show(dt_view_manager_t *vm);
447 void dt_view_accels_hide(dt_view_manager_t *vm);
448 void dt_view_accels_refresh(dt_view_manager_t *vm);
449 
450 /* audio */
451 void dt_view_audio_start(dt_view_manager_t *vm, int imgid);
452 void dt_view_audio_stop(dt_view_manager_t *vm);
453 
454 /*
455  * Map View Proxy
456  */
457 #ifdef HAVE_MAP
458 void dt_view_map_center_on_location(const dt_view_manager_t *vm, gdouble lon, gdouble lat, gdouble zoom);
459 void dt_view_map_center_on_bbox(const dt_view_manager_t *vm, gdouble lon1, gdouble lat1, gdouble lon2, gdouble lat2);
460 void dt_view_map_show_osd(const dt_view_manager_t *vm);
461 void dt_view_map_set_map_source(const dt_view_manager_t *vm, OsmGpsMapSource_t map_source);
462 GObject *dt_view_map_add_marker(const dt_view_manager_t *vm, dt_geo_map_display_t type, GList *points);
463 gboolean dt_view_map_remove_marker(const dt_view_manager_t *vm, dt_geo_map_display_t type, GObject *marker);
464 void dt_view_map_add_location(const dt_view_manager_t *vm, dt_map_location_data_t *p, const guint posid);
465 void dt_view_map_location_action(const dt_view_manager_t *vm, const int action);
466 void dt_view_map_drag_set_icon(const dt_view_manager_t *vm, GdkDragContext *context, const int imgid, const int count);
467 #endif
468 
469 /*
470  * Print View Proxy
471  */
472 #ifdef HAVE_PRINT
473 void dt_view_print_settings(const dt_view_manager_t *vm, dt_print_info_t *pinfo);
474 #endif
475 
476 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
477 // vim: shiftwidth=2 expandtab tabstop=2 cindent
478 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
479