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