51#include <gdk/gdkkeysyms.h>
91 float picker_box_anchor[2];
132 return _(
"Studio Capture");
154 d->own_primary_sample =
d->dev->color_picker.primary_sample;
175 G_N_ELEMENTS(studio_capture_toolbox_buttons));
176 gtk_widget_show_all(gtk_bin_get_child(GTK_BIN(
d->dev->display.floating_window)));
182 studio_capture_toolbox_buttons, G_N_ELEMENTS(studio_capture_toolbox_buttons));
188 if(
d->refresh_timeout) g_source_remove(
d->refresh_timeout);
194 d->dev->color_picker.primary_sample =
d->own_primary_sample;
226 d->dev->roi.orig_width =
width;
227 d->dev->roi.orig_height =
height;
242 d->dev_loaded =
TRUE;
246 dt_control_log(_(
"Studio capture: could not load the image in the viewer."));
256 if(
d->dev_width > 0 &&
d->dev_height > 0)
287 if(!
d->dev_loaded)
return;
304 for(GList *
m = dev->
iop;
m;
m = g_list_next(
m))
307 if(mod && mod->quiesce) mod->quiesce(mod);
350 dev->
iop = g_list_delete_link(dev->
iop, dev->
iop);
394 if(imgid ==
d->imgid)
return;
401 d->pan_x =
d->pan_y = 0.0;
402 d->anchor_pending =
FALSE;
444 return G_SOURCE_REMOVE;
461 if(
d->refresh_timeout) g_source_remove(
d->refresh_timeout);
568 if(
d->refresh_timeout)
570 g_source_remove(
d->refresh_timeout);
571 d->refresh_timeout = 0;
577 if(
d->dev->color_picker.picker)
579 d->picker_dragging_box =
FALSE;
583 d->dev->color_picker.primary_sample =
d->own_primary_sample;
626 const double max_x =
MAX(0.0, logical_width -
d->width);
627 const double max_y =
MAX(0.0, logical_height -
d->height);
628 d->pan_x = CLAMP(
d->pan_x, 0.0, max_x);
629 d->pan_y = CLAMP(
d->pan_y, 0.0, max_y);
643 double *logical_width,
double *logical_height)
647 const int surface_width = cairo_image_surface_get_width(
d->surface);
648 const int surface_height = cairo_image_surface_get_height(
d->surface);
649 double sx = 1.0, sy = 1.0;
650 cairo_surface_get_device_scale(
d->surface, &sx, &sy);
651 *logical_width = surface_width / sx;
652 *logical_height = surface_height / sy;
656 *tr_x = (
d->width < *logical_width) ? 0.0 : (
d->width - *logical_width) * .5;
657 *tr_y = (
d->height < *logical_height) ? 0.0 : (
d->height - *logical_height) * .5;
661 *tr_x = (*logical_width <=
d->width) ? (
d->width - *logical_width) * .5 : -
d->pan_x;
662 *tr_y = (*logical_height <=
d->height) ? (
d->height - *logical_height) * .5 : -
d->pan_y;
678 double tr_x = 0.0, tr_y = 0.0, logical_width = 0.0, logical_height = 0.0;
680 if(logical_width <= 0.0 || logical_height <= 0.0)
return FALSE;
682 point[0] = CLAMP((
float)((
x - tr_x) / logical_width), 0.0f, 1.0f);
683 point[1] = CLAMP((
float)((y - tr_y) / logical_height), 0.0f, 1.0f);
693 double tr_x = 0.0, tr_y = 0.0, logical_width = 0.0, logical_height = 0.0;
696 *
x = tr_x +
point[0] * logical_width;
697 *y = tr_y +
point[1] * logical_height;
714 const gboolean is_primary_sample,
const gboolean selected)
716 const double line_scale = selected ? 2.0 : 1.0;
720 float image_box[4] = { sample->
box[0], sample->
box[1], sample->
box[2], sample->
box[3] };
722 double x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0;
727 cairo_rectangle(cr, x0, y0, x1 - x0, y1 - y0);
728 if(is_primary_sample)
730 const double hw = 5.0;
731 cairo_rectangle(cr, x0 - hw, y0 - hw, 2. * hw, 2. * hw);
732 cairo_rectangle(cr, x0 - hw, y1 - hw, 2. * hw, 2. * hw);
733 cairo_rectangle(cr, x1 - hw, y0 - hw, 2. * hw, 2. * hw);
734 cairo_rectangle(cr, x1 - hw, y1 - hw, 2. * hw, 2. * hw);
737 cairo_set_line_width(cr, 3.0 * line_scale);
738 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.4);
739 cairo_stroke_preserve(cr);
741 const gboolean draw_dashed = !is_primary_sample && !selected;
742 const double dashes[1] = { 4.0 };
743 cairo_set_line_width(cr, line_scale);
744 cairo_set_dash(cr, dashes, draw_dashed ? 1 : 0, 0.0);
745 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.8);
747 cairo_set_dash(cr, NULL, 0, 0.0);
753 float image_point[2] = { sample->
point[0], sample->
point[1] };
755 double px = 0.0, py = 0.0;
760 const double half_px = 4.0;
761 double crosshair = (is_primary_sample ? 4.0 : 5.0) * half_px;
762 if(selected) crosshair *= 2.0;
764 if(is_primary_sample) cairo_arc(cr, px, py, crosshair, 0., 2. *
M_PI);
765 cairo_move_to(cr, px - crosshair, py);
766 cairo_line_to(cr, px + crosshair, py);
767 cairo_move_to(cr, px, py - crosshair);
768 cairo_line_to(cr, px, py + crosshair);
770 cairo_set_line_width(cr, 3.0 * line_scale);
771 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.4);
772 cairo_stroke_preserve(cr);
774 cairo_set_line_width(cr, line_scale);
775 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.8);
783 cairo_arc(cr, px, py, selected ? half_px * 2.0 : half_px, 0., 2. *
M_PI);
784 cairo_set_source_rgba(cr, sample->
swatch.red, sample->
swatch.green, sample->
swatch.blue,
802 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
812 if(only_selected && sample != selected_sample)
continue;
833 if(
d->dev_loaded && (
d->dev_width !=
width ||
d->dev_height !=
height))
842 cairo_set_source_rgb(cr, bg_color[0], bg_color[1], bg_color[2]);
862 double tr_x = 0.0, tr_y = 0.0, logical_width = 0.0, logical_height = 0.0;
868 const int surface_width = cairo_image_surface_get_width(
d->surface);
869 const int surface_height = cairo_image_surface_get_height(
d->surface);
870 double sx = 1.0, sy = 1.0;
871 cairo_surface_get_device_scale(
d->surface, &sx, &sy);
872 d->pan_x =
d->anchor_rel_x * (surface_width / sx) -
d->anchor_px;
873 d->pan_y =
d->anchor_rel_y * (surface_height / sy) -
d->anchor_py;
874 d->anchor_pending =
FALSE;
886 gboolean drew_live =
FALSE;
889 &&
d->main_locked.surface)
897 d->dev->roi.border_size, bg_color);
904 cairo_translate(cr, tr_x, tr_y);
907 cairo_set_source_surface(cr,
d->surface, 0, 0);
909 cairo_rectangle(cr, 0, 0, logical_width, logical_height);
921 const float wd =
d->dev->roi.preview_width;
922 const float ht =
d->dev->roi.preview_height;
952 d->anchor_rel_x = 0.5;
953 d->anchor_rel_y = 0.5;
954 double tr_x = 0.0, tr_y = 0.0, logical_width = 0.0, logical_height = 0.0;
956 && logical_height > 0.0)
958 d->anchor_rel_x = CLAMP((
x - tr_x) / logical_width, 0.0, 1.0);
959 d->anchor_rel_y = CLAMP((y - tr_y) / logical_height, 0.0, 1.0);
963 d->anchor_pending =
TRUE;
968 d->anchor_pending =
FALSE;
971 d->pan_x =
d->pan_y = 0.0;
983 if(
d->picker_dragging_box)
985 float point[2] = { 0.0f };
991 MAX(
d->picker_box_anchor[1],
point[1]) };
1000 float point[2] = { 0.0f };
1010 if(!
d->panning)
return;
1012 d->pan_x =
d->pan_start_x - (
x -
d->drag_start_x);
1013 d->pan_y =
d->pan_start_y - (y -
d->drag_start_y);
1028 const double logical_height)
1034 d->picker_dragging_box =
FALSE;
1039 float image_box[4] = { sample->
box[0], sample->
box[1], sample->
box[2], sample->
box[3] };
1043 const float handle_x = (logical_width > 0.0) ? (
float)(6.0 / logical_width) : 0.02f;
1044 const float handle_y = (logical_height > 0.0) ? (
float)(6.0 / logical_height) : 0.02f;
1046 gboolean on_corner =
TRUE;
1047 float opposite[2] = { 0.0f };
1048 if(fabsf(
point[0] - image_box[0]) <= handle_x) opposite[0] = image_box[2];
1049 else if(fabsf(
point[0] - image_box[2]) <= handle_x) opposite[0] = image_box[0];
1050 else on_corner =
FALSE;
1052 if(fabsf(
point[1] - image_box[1]) <= handle_y) opposite[1] = image_box[3];
1053 else if(fabsf(
point[1] - image_box[3]) <= handle_y) opposite[1] = image_box[1];
1054 else on_corner =
FALSE;
1058 d->picker_box_anchor[0] = opposite[0];
1059 d->picker_box_anchor[1] = opposite[1];
1064 const float delta = 0.01f;
1065 d->picker_box_anchor[0] =
point[0];
1066 d->picker_box_anchor[1] =
point[1];
1072 d->picker_dragging_box =
TRUE;
1082 const double logical_height)
1089 const float slop_x = (logical_width > 0.0) ? (
float)(20.0 / logical_width) : 0.05f;
1090 const float slop_y = (logical_height > 0.0) ? (
float)(20.0 / logical_height) : 0.05f;
1097 float live_box[4] = { live_sample->
box[0], live_sample->
box[1], live_sample->
box[2],
1098 live_sample->
box[3] };
1100 if(
point[0] < live_box[0] ||
point[0] > live_box[2] ||
point[1] < live_box[1] ||
point[1] > live_box[3])
1107 float live_point[2] = { live_sample->
point[0], live_sample->
point[1] };
1109 if(fabsf(
point[0] - live_point[0]) > slop_x || fabsf(
point[1] - live_point[1]) > slop_y)
continue;
1131 float point[2] = { 0.0f };
1132 double tr_x = 0.0, tr_y = 0.0, logical_width = 0.0, logical_height = 0.0;
1146 if(which == 2 || (which == 1 &&
type == GDK_2BUTTON_PRESS))
1155 d->drag_start_x =
x;
1156 d->drag_start_y = y;
1157 d->pan_start_x =
d->pan_x;
1158 d->pan_start_y =
d->pan_y;
1173 d->picker_dragging_box =
FALSE;
1178 if(
d->panning && which == 1)
1208 const gboolean shift =
dt_modifier_is(event->state, GDK_SHIFT_MASK);
1209 const gboolean ctrl =
dt_modifier_is(event->state, GDK_CONTROL_MASK);
1218 if(ctrl_any && (
key == GDK_KEY_plus ||
key == GDK_KEY_minus))
1225 const double multiplier = shift ? 4.0 : ctrl ? 0.5 : 1.0;
1226 const double step = 10.0 * multiplier;
1230 case GDK_KEY_Return:
1269 case GDK_KEY_Escape:
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.
void dt_atomic_set_int(dt_atomic_int *var, int value)
static const float scaling
void dt_collection_update_query(const dt_collection_t *collection, dt_collection_change_t query_change, dt_collection_properties_t changed_property, GList *list)
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_CHANGE_RELOAD
void dt_iop_color_picker_init(void)
void dt_iop_color_picker_cleanup(void)
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
gboolean dt_iop_color_picker_is_visible(const dt_develop_t *dev)
@ DT_LIB_COLORPICKER_SIZE_POINT
@ DT_LIB_COLORPICKER_SIZE_BOX
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_ctl_switch_mode_to(const char *mode)
void dt_control_draw_busy_msg(cairo_t *cr, int width, int height)
void dt_control_set_mouse_over_id(int32_t value)
void dt_control_log(const char *msg,...)
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
void dt_control_set_keyboard_over_id(int32_t value)
#define dt_control_change_cursor(cursor)
static gboolean dt_modifiers_include(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
float dt_boundingbox_t[4]
#define DT_MODULE(MODVER)
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
void dt_dev_draw_iso12646_border(cairo_t *cr, double width, double height, int border)
gboolean dt_dev_lock_pipe_surface(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, dt_dev_locked_surface_t *locked, dt_dev_pixelpipe_cache_wait_t *wait, const char *wait_owner_tag, gboolean keep_previous_on_fail)
gboolean dt_dev_render_locked_surface(cairo_t *cr, const dt_develop_t *dev, dt_dev_locked_surface_t *locked, const int width, const int height, const int border, const dt_aligned_pixel_t bg_color)
void dt_dev_get_background_color(const dt_develop_t *dev, dt_aligned_pixel_t bg_color)
void dt_dev_release_locked_surface(dt_dev_locked_surface_t *locked)
void dt_dev_draw_profile_mode_label(cairo_t *cri, int height)
void dt_dev_history_free_history(dt_develop_t *dev)
Free the whole history list attached to dev->history.
void dt_dev_pop_history_items(dt_develop_t *dev)
Thread-safe wrapper around dt_dev_pop_history_items_ext(), then update GUI.
void dt_dev_history_pixelpipe_update(dt_develop_t *dev, gboolean rebuild)
Rebuild or resync pixelpipes after backend history changes.
gboolean dt_dev_reload_history_items(dt_develop_t *dev, const int32_t imgid)
Reload history from DB and rebuild pipelines/GUI state.
void dt_dev_pixelpipe_cache_wait_cleanup(dt_dev_pixelpipe_cache_wait_t *wait, const char *reason)
Cancel one pending GUI cache wait request and clear its runtime state.
#define dt_dev_pixelpipe_rebuild_all(dev)
int dt_dev_get_thumbnail_size(dt_develop_t *dev)
void dt_dev_cleanup(dt_develop_t *dev)
float dt_dev_get_overlay_scale(dt_develop_t *dev)
Get the overlay scale factor in GUI logical coordinates.
dt_dev_image_storage_t dt_dev_load_image(dt_develop_t *dev, const int32_t imgid)
void dt_dev_init(dt_develop_t *dev, int32_t gui_attached)
void dt_dev_coordinates_raw_norm_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
GList * dt_dev_load_modules(dt_develop_t *dev)
void dt_dev_set_backbuf(dt_backbuf_t *backbuf, const int width, const int height, const size_t bpp, const int64_t hash, const int64_t history_hash)
gboolean dt_dev_clip_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Clip the view to the ROI. WARNING: this must be done before any translation.
gboolean dt_dev_rescale_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Scale the ROI to fit within given width/height, centered.
void dt_dev_start_all_pipelines(dt_develop_t *dev)
void dt_ui_panel_show(dt_ui_t *ui, const dt_ui_panel_t p, gboolean show, gboolean write)
shows/hide a panel
static int dt_pthread_rwlock_unlock(dt_pthread_rwlock_t *rwlock)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_rwlock_wrlock(dt_pthread_rwlock_t *rwlock)
static guint dt_keys_mainpad_alternatives(const guint key_val)
Remap keypad keys to usual mainpad ones.
void dt_gui_refocus_center()
GtkWidget * dt_ui_center(dt_ui_t *ui)
get the center drawable widget
void dt_guides_draw(cairo_t *cr, const float left, const float top, const float width, const float height, const float zoom_scale)
void dt_iop_gui_cleanup_module(dt_iop_module_t *module)
void dt_iop_cleanup_module(dt_iop_module_t *module)
gboolean dt_iop_is_hidden(dt_iop_module_t *module)
void dt_lib_colorpicker_set_box_area(dt_lib_t *lib, const dt_boundingbox_t box)
void dt_lib_colorpicker_set_point(dt_lib_t *lib, const float pos[2])
void dt_masks_free_form(dt_masks_form_t *form)
void dt_masks_gui_init(struct dt_develop_t *dev)
void dt_masks_gui_cleanup(struct dt_develop_t *dev)
float dt_aligned_pixel_t[4]
void dt_dev_pixelpipe_cache_unref_hash(dt_dev_pixelpipe_cache_t *cache, const uint64_t hash)
Find the entry matching hash, and decrease its ref_count if found.
void dt_dev_pixelpipe_cache_flush_clmem_for_pipe(dt_dev_pixelpipe_cache_t *cache, const int devid)
Like dt_dev_pixelpipe_cache_flush_clmem(), for callers that do not hold darktable....
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define DT_PIXELPIPE_CACHE_HASH_INVALID
void dt_dev_pixelpipe_cleanup_nodes(dt_dev_pixelpipe_t *pipe)
static void dt_dev_backbuf_set_hash(dt_backbuf_t *backbuf, const uint64_t hash)
static uint64_t dt_dev_backbuf_get_hash(const dt_backbuf_t *backbuf)
int32_t dt_selection_get_first_id(struct dt_selection_t *selection)
void dt_selection_select_single(dt_selection_t *selection, int32_t imgid)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
@ DT_SIGNAL_VIEWMANAGER_THUMBTABLE_ACTIVATE
@ DT_SIGNAL_DEVELOP_HISTORY_CHANGE
This signal is raised when develop history is changed no param, no returned value.
@ DT_SIGNAL_IMAGE_IMPORT
This signal is raised when a new image is imported (not cloned) 1 uint32_t : the new image id no retu...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
const float uint32_t state[4]
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
struct dt_gui_gtk_t * gui
struct dt_collection_t * collection
struct dt_selection_t * selection
struct dt_control_signal_t * signals
struct dt_develop_t * develop
struct dt_view_manager_t * view_manager
struct dt_control_t * control
GtkAccelGroup * lighttable_accels
dt_lib_colorpicker_size_t size
dt_pthread_mutex_t busy_mutex
struct dt_develop_t::@21 color_picker
Authoritative darkroom color-picker state.
struct dt_colorpicker_sample_t * primary_sample
dt_backbuf_t display_histogram
dt_backbuf_t output_histogram
gboolean(* refresh_global_picker)(struct dt_lib_module_t *self)
struct dt_iop_module_t * gui_module
dt_pthread_rwlock_t history_mutex
struct dt_dev_pixelpipe_t * preview_pipe
gboolean pipelines_started
struct dt_dev_pixelpipe_t * virtual_pipe
struct dt_iop_module_t *struct dt_iop_color_picker_t * picker
dt_backbuf_t raw_histogram
struct dt_masks_form_gui_t * form_gui
struct dt_colorpicker_sample_t * selected_sample
struct dt_lib_module_t * histogram_module
dt_pthread_rwlock_t masks_mutex
struct dt_dev_pixelpipe_t * pipe
cairo_filter_t filter_image
gboolean picker_dragging_box
dt_view_image_surface_fetcher_t fetcher
dt_thumbtable_zoom_t zoom
dt_develop_t * saved_develop
cairo_surface_t * surface
dt_colorpicker_sample_t * own_primary_sample
dt_dev_locked_surface_t main_locked
dt_dev_pixelpipe_cache_wait_t main_wait
dt_thumbtable_t * thumbtable_filmstrip
Track one asynchronous Cairo surface fetch request for a GUI widget.
struct dt_view_manager_t::@69 proxy
struct dt_view_manager_t::@69::@72 darkroom
void init(dt_view_t *self)
static gboolean _studio_deferred_refresh(gpointer user_data)
Re-fetch the displayed surface once, after auto-styles had time to land.
void leave(dt_view_t *self)
int button_pressed(dt_view_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
static void _studio_clamp_pan(dt_studio_capture_t *d, const double logical_width, const double logical_height)
Clamp the pan offsets so the viewport never leaves the surface.
void cleanup(dt_view_t *self)
static void _studio_history_changed_callback(gpointer instance, gpointer user_data)
Refresh the display when the history of the shown image changes (e.g. styles re-applied manually from...
static void _studio_set_image(dt_studio_capture_t *d, const int32_t imgid)
Switch the displayed image and reset the viewport to fit.
void reset(dt_view_t *self)
static void _studio_configure_dev_roi(dt_studio_capture_t *d, int width, int height)
Load an image into the viewer develop and start its pipelines.
static void _studio_image_imported_callback(gpointer instance, int32_t imgid, gpointer user_data)
Follow the shooting session: every new import becomes the displayed image.
void expose(dt_view_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
int scrolled(dt_view_t *self, double x, double y, int up, int state, int delta_y)
static void _studio_toggle_zoom(dt_studio_capture_t *d, const double x, const double y)
Toggle between fit and 100%, anchoring the zoom on the pointer.
int key_pressed(dt_view_t *self, GdkEventKey *event)
void mouse_moved(dt_view_t *self, double x, double y, double pressure, int which)
static void _studio_filmstrip_activate_callback(gpointer instance, int32_t imgid, gpointer user_data)
static void _studio_dev_setup(dt_studio_capture_t *d, const int32_t imgid)
uint32_t view(const dt_view_t *self)
static gboolean _studio_surface_geometry(const dt_studio_capture_t *d, double *tr_x, double *tr_y, double *logical_width, double *logical_height)
Compute where the displayed surface currently sits in widget space.
int button_released(dt_view_t *self, double x, double y, int which, uint32_t state)
void enter(dt_view_t *self)
static void _studio_draw_one_sample(dt_studio_capture_t *d, cairo_t *cr, dt_colorpicker_sample_t *sample, const gboolean is_primary_sample, const gboolean selected)
Draw one point or box color picker sample, matching darkroom's _darkroom_pickers_draw visual style: a...
static void _studio_picker_left_click(dt_studio_capture_t *d, const float point[2], const double logical_width, const double logical_height)
Left-click handling while the color picker is active.
void configure(dt_view_t *self, int width, int height)
static void _studio_draw_pickers(dt_studio_capture_t *d, cairo_t *cr)
Draw the live samples list, then the active picker, matching darkroom's two-pass _darkroom_pickers_dr...
static void _studio_dev_teardown(dt_studio_capture_t *d)
Tear down the viewer develop pipelines and per-image resources.
void gui_init(dt_view_t *self)
static gboolean _studio_widget_to_image_norm(const dt_studio_capture_t *d, const double x, const double y, float point[2])
Convert a widget-space point to a normalized [0,1] image point.
static gboolean _studio_image_norm_to_widget(const dt_studio_capture_t *d, const float point[2], double *x, double *y)
Inverse of _studio_widget_to_image_norm(), for drawing the picker overlay.
int try_enter(dt_view_t *self)
static void _studio_picker_right_click(dt_studio_capture_t *d, const float point[2], const double logical_width, const double logical_height)
Right-click handling while the color picker is active: reuse an overlapping live sample's geometry (m...
int dt_thumbtable_scroll_to_selection(dt_thumbtable_t *table)
Scroll to show selected content.
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_zoom_t
Zoom levels for thumbnail display.
@ DT_THUMBTABLE_ZOOM_FULL
static void dt_thumbtable_show(dt_thumbtable_t *table)
Show the thumbnail table widget.
static void dt_thumbtable_hide(dt_thumbtable_t *table)
Hide the thumbnail table widget.
void dt_view_image_surface_fetcher_invalidate(dt_view_image_surface_fetcher_t *fetcher, cairo_surface_t **target)
void dt_view_image_surface_fetcher_cleanup(dt_view_image_surface_fetcher_t *fetcher)
void dt_view_image_surface_fetcher_init(dt_view_image_surface_fetcher_t *fetcher)
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)
void dt_view_active_images_add(int32_t imgid, gboolean raise)
void dt_view_active_images_reset(gboolean raise)
int dt_view_manager_switch(dt_view_manager_t *vm, const char *view_name)
const dt_view_t * dt_view_manager_get_current_view(dt_view_manager_t *vm)