Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
studio_capture.c File Reference
#include "common/atomic.h"
#include "common/collection.h"
#include "common/darktable.h"
#include "common/debug.h"
#include "common/selection.h"
#include "control/conf.h"
#include "control/control.h"
#include "develop/develop.h"
#include "develop/dev_history.h"
#include "develop/dev_pixelpipe.h"
#include "develop/imageop.h"
#include "develop/masks.h"
#include "develop/pixelpipe_cache.h"
#include "develop/pixelpipe_hb.h"
#include "dtgtk/thumbtable.h"
#include "gui/color_picker_proxy.h"
#include "gui/gdkkeys.h"
#include "gui/gtk.h"
#include "gui/guides.h"
#include "libs/colorpicker.h"
#include "libs/lib.h"
#include "views/dev_backbuf.h"
#include "views/dev_toolbox.h"
#include "views/view.h"
#include "views/view_api.h"
#include <gdk/gdkkeysyms.h>
#include <math.h>
+ Include dependency graph for studio_capture.c:

Go to the source code of this file.

Data Structures

struct  dt_studio_capture_t
 

Typedefs

typedef struct dt_studio_capture_t dt_studio_capture_t
 

Functions

const char * name (const dt_view_t *self)
 
uint32_t view (const dt_view_t *self)
 
void init (dt_view_t *self)
 
void gui_init (dt_view_t *self)
 
void cleanup (dt_view_t *self)
 
int try_enter (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_dev_setup (dt_studio_capture_t *d, const int32_t imgid)
 
static void _studio_dev_teardown (dt_studio_capture_t *d)
 Tear down the viewer develop pipelines and per-image resources.
 
static void _studio_set_image (dt_studio_capture_t *d, const int32_t imgid)
 Switch the displayed image and reset the viewport to fit.
 
static void _studio_filmstrip_activate_callback (gpointer instance, int32_t imgid, gpointer user_data)
 
static gboolean _studio_deferred_refresh (gpointer user_data)
 Re-fetch the displayed surface once, after auto-styles had time to land.
 
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.
 
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 the Style module).
 
void enter (dt_view_t *self)
 
void leave (dt_view_t *self)
 
void configure (dt_view_t *self, int width, int height)
 
void reset (dt_view_t *self)
 
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.
 
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.
 
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.
 
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 dark 3px outline under a lighter 1px stroke (2x for the selected sample), corner handles / a circle handle on the primary sample, dashing on non-primary/non-selected boxes, and a filled swatch showing the picked color.
 
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_draw rendering and its visibility rules (live samples show when "display all" is on, or a single sample is hover-highlighted from the Scopes panel list).
 
void expose (dt_view_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
 
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.
 
void mouse_moved (dt_view_t *self, double x, double y, double pressure, int which)
 
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.
 
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 (mirrors darkroom's button_pressed which==3 branch), or reset the box to a default centered area.
 
int button_pressed (dt_view_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
 
int button_released (dt_view_t *self, double x, double y, int which, uint32_t state)
 
int scrolled (dt_view_t *self, double x, double y, int up, int state, int delta_y)
 
int key_pressed (dt_view_t *self, GdkEventKey *event)
 

Typedef Documentation

◆ dt_studio_capture_t

Studio Capture view: monitor a folder, import incoming shots, auto-apply styles and preview the active image full-size with the filmstrip at the bottom. The center view renders the processed image through the async surface fetcher (fit-to-window or 100% with panning); the darkroom editing panels are intentionally absent: this is a viewer, not an editor.

Function Documentation

◆ _studio_clamp_pan()

static void _studio_clamp_pan ( dt_studio_capture_t d,
const double  logical_width,
const double  logical_height 
)
static

Clamp the pan offsets so the viewport never leaves the surface.

Definition at line 624 of file studio_capture.c.

References d, and MAX.

Referenced by expose().

◆ _studio_configure_dev_roi()

static void _studio_configure_dev_roi ( dt_studio_capture_t d,
int  width,
int  height 
)
static

Load an image into the viewer develop and start its pipelines.

This mirrors the pipeline-relevant subset of darkroom's enter: it loads the processing modules and history, then starts the pipelines. It deliberately omits the darkroom editing layer (IOP module GUIs, color picker, undo, accels), which this viewer does not use.

Requires darktable.develop == d->dev (set by enter()).

Feed the current center allocation into the dev's ROI and re-derive border_size from dev->iso_12646.enabled (dt_dev_toolbox_apply_iso_12646_size() calls dt_dev_configure() internally). Centralizes what _studio_dev_setup(), configure() and expose()'s resize catch-up all need, so toggling ISO 12646 survives a resize instead of being stomped back to border_size=0.

Definition at line 224 of file studio_capture.c.

References d, dt_dev_toolbox_apply_iso_12646_size(), height, and width.

Referenced by _studio_dev_setup(), configure(), and expose().

◆ _studio_deferred_refresh()

static gboolean _studio_deferred_refresh ( gpointer  user_data)
static

Re-fetch the displayed surface once, after auto-styles had time to land.

Definition at line 438 of file studio_capture.c.

References d, dt_control_queue_redraw_center(), dt_view_image_surface_fetcher_invalidate(), and dt_studio_capture_t::refresh_timeout.

Referenced by _studio_image_imported_callback().

◆ _studio_dev_setup()

◆ _studio_dev_teardown()

static void _studio_dev_teardown ( dt_studio_capture_t d)
static

Tear down the viewer develop pipelines and per-image resources.

Faithful subset of darkroom's leave: shut the pipes down, wait on each busy lock, drop the nodes and cached buffers, then free history, modules and masks. Safe to call when only the modules were loaded (image load failed): the pipeline teardown is harmless on pipes that never started.

dt_iop_gui_cleanup_module() runs for every module before dt_free(), even though this viewer itself never calls dt_iop_gui_init(): darktable.develop is swapped to point at this view's dev while active (see enter()), and global menu actions that read darktable.develop directly instead of a locally-scoped dev (dt_menu_apply_dev_history_update() callers in gui/actions/edit.c, styles.c) can reach dt_dev_history_gui_update() on THIS dev – gui_attached is TRUE here too, so nothing stops it from running dt_iop_gui_init()/dt_iop_gui_set_expander() on these modules. Skipping gui_cleanup_module() then left header/expander widgets (each g_object_weak_ref()-ed back to the module in dt_iop_gui_set_expander()) outliving the dt_free(module) below, use-after-freed the next time something destroyed those widgets (ASan heap-use-after-free in _iop_gui_widget_gone(), imageop.c:2020, freed by this loop, allocated by dt_dev_load_modules() in _studio_dev_setup()).

Definition at line 285 of file studio_capture.c.

References dt_develop_t::allforms, dt_develop_t::alliop, dt_dev_pixelpipe_t::backbuf, dt_dev_pixelpipe_t::busy_mutex, d, darktable, dt_develop_t::display_histogram, dt_atomic_set_int(), dt_dev_backbuf_get_hash(), dt_dev_backbuf_set_hash(), dt_dev_history_free_history(), dt_dev_pixelpipe_cache_flush_clmem_for_pipe(), dt_dev_pixelpipe_cache_unref_hash(), dt_dev_pixelpipe_cache_wait_cleanup(), dt_dev_pixelpipe_cleanup_nodes(), dt_dev_release_locked_surface(), dt_dev_set_backbuf(), dt_free, dt_iop_cleanup_module(), dt_iop_gui_cleanup_module(), dt_iop_is_hidden(), dt_masks_free_form(), dt_masks_gui_cleanup(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_unlock(), dt_pthread_rwlock_wrlock(), dt_develop_t::exit, FALSE, dt_develop_t::form_gui, dt_develop_t::forms, dt_develop_t::gui_module, dt_develop_t::history_mutex, dt_image_t::id, dt_develop_t::image_storage, dt_develop_t::iop, dt_dev_pixelpipe_t::last_devid, m, dt_develop_t::masks_mutex, dt_develop_t::output_histogram, dt_develop_t::pipe, dt_develop_t::pipelines_started, darktable_t::pixelpipe_cache, dt_develop_t::preview_pipe, dt_develop_t::raw_histogram, dt_dev_pixelpipe_t::shutdown, TRUE, dt_develop_t::virtual_pipe, and void().

Referenced by _studio_set_image(), and leave().

◆ _studio_draw_one_sample()

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 
)
static

Draw one point or box color picker sample, matching darkroom's _darkroom_pickers_draw visual style: a dark 3px outline under a lighter 1px stroke (2x for the selected sample), corner handles / a circle handle on the primary sample, dashing on non-primary/non-selected boxes, and a filled swatch showing the picked color.

Darkroom scales these constants by the darkroom zoom level so they stay a constant LOGICAL pixel size on screen; our surface is drawn directly in widget space, so plain device-pixel constants already achieve the same "constant apparent size" effect without needing a zoom-scale factor.

Definition at line 713 of file studio_capture.c.

References _studio_image_norm_to_widget(), dt_colorpicker_sample_t::box, d, dt_dev_coordinates_raw_norm_to_image_norm(), DT_LIB_COLORPICKER_SIZE_BOX, M_PI, dt_colorpicker_sample_t::point, dt_colorpicker_sample_t::size, and dt_colorpicker_sample_t::swatch.

Referenced by _studio_draw_pickers().

◆ _studio_draw_pickers()

static void _studio_draw_pickers ( dt_studio_capture_t d,
cairo_t *  cr 
)
static

Draw the live samples list, then the active picker, matching darkroom's two-pass _darkroom_pickers_draw rendering and its visibility rules (live samples show when "display all" is on, or a single sample is hover-highlighted from the Scopes panel list).

Definition at line 796 of file studio_capture.c.

References _studio_draw_one_sample(), dt_develop_t::color_picker, d, dt_develop_t::display_samples, dt_iop_color_picker_is_visible(), FALSE, IS_NULL_PTR, dt_develop_t::primary_sample, dt_develop_t::samples, dt_develop_t::selected_sample, and TRUE.

Referenced by expose().

◆ _studio_filmstrip_activate_callback()

static void _studio_filmstrip_activate_callback ( gpointer  instance,
int32_t  imgid,
gpointer  user_data 
)
static

Definition at line 429 of file studio_capture.c.

References _studio_set_image(), dt_view_t::data, and UNKNOWN_IMAGE.

Referenced by enter(), and leave().

◆ _studio_history_changed_callback()

static void _studio_history_changed_callback ( gpointer  instance,
gpointer  user_data 
)
static

Refresh the display when the history of the shown image changes (e.g. styles re-applied manually from the Style module).

Definition at line 469 of file studio_capture.c.

References d, darktable, dt_view_t::data, darktable_t::develop, dt_control_queue_redraw_center(), dt_dev_history_pixelpipe_update(), dt_dev_reload_history_items(), dt_view_image_surface_fetcher_invalidate(), TRUE, and UNKNOWN_IMAGE.

Referenced by enter(), and leave().

◆ _studio_image_imported_callback()

static void _studio_image_imported_callback ( gpointer  instance,
int32_t  imgid,
gpointer  user_data 
)
static

Follow the shooting session: every new import becomes the displayed image.

Definition at line 450 of file studio_capture.c.

References _studio_deferred_refresh(), _studio_set_image(), d, dt_view_t::data, and UNKNOWN_IMAGE.

Referenced by enter(), and leave().

◆ _studio_image_norm_to_widget()

static gboolean _studio_image_norm_to_widget ( const dt_studio_capture_t d,
const float  point[2],
double x,
double y 
)
static

Inverse of _studio_widget_to_image_norm(), for drawing the picker overlay.

Definition at line 690 of file studio_capture.c.

References _studio_surface_geometry(), d, FALSE, TRUE, and x.

Referenced by _studio_draw_one_sample().

◆ _studio_picker_left_click()

static void _studio_picker_left_click ( dt_studio_capture_t d,
const float  point[2],
const double  logical_width,
const double  logical_height 
)
static

Left-click handling while the color picker is active.

Point vs. box mode is decided by sample->size, which the picker button's own ctrl+click/right-click already sets (shared code in gui/color_picker_proxy.c, unrelated to this handler). Mirrors darkroom's button_pressed: clicking near an existing box corner grabs it (the opposite corner becomes the drag anchor); clicking elsewhere starts a fresh small default box centered on the click.

Definition at line 1027 of file studio_capture.c.

References dt_colorpicker_sample_t::box, d, darktable, delta, dt_control_change_cursor, dt_dev_coordinates_raw_norm_to_image_norm(), dt_lib_colorpicker_set_box_area(), dt_lib_colorpicker_set_point(), DT_LIB_COLORPICKER_SIZE_BOX, FALSE, darktable_t::lib, dt_colorpicker_sample_t::size, and TRUE.

Referenced by button_pressed().

◆ _studio_picker_right_click()

static void _studio_picker_right_click ( dt_studio_capture_t d,
const float  point[2],
const double  logical_width,
const double  logical_height 
)
static

◆ _studio_set_image()

◆ _studio_surface_geometry()

static gboolean _studio_surface_geometry ( const dt_studio_capture_t d,
double tr_x,
double tr_y,
double logical_width,
double logical_height 
)
static

Compute where the displayed surface currently sits in widget space.

Mirrors the placement expose() paints with: fit-to-window centers the surface, 100% pans it by -pan_x/-pan_y (or centers it when it fits). Shared by expose(), the zoom-anchor computation and the color picker coordinate mapping so all three agree on the same on-screen geometry.

Returns
FALSE when there is no surface to place yet.

Definition at line 642 of file studio_capture.c.

References d, DT_THUMBTABLE_ZOOM_FIT, FALSE, IS_NULL_PTR, and TRUE.

Referenced by _studio_image_norm_to_widget(), _studio_toggle_zoom(), _studio_widget_to_image_norm(), button_pressed(), and expose().

◆ _studio_toggle_zoom()

static void _studio_toggle_zoom ( dt_studio_capture_t d,
const double  x,
const double  y 
)
static

Toggle between fit and 100%, anchoring the zoom on the pointer.

Definition at line 942 of file studio_capture.c.

References _studio_surface_geometry(), d, dt_control_queue_redraw_center(), DT_THUMBTABLE_ZOOM_FIT, DT_THUMBTABLE_ZOOM_FULL, FALSE, TRUE, UNKNOWN_IMAGE, and x.

Referenced by button_pressed(), key_pressed(), and scrolled().

◆ _studio_widget_to_image_norm()

static gboolean _studio_widget_to_image_norm ( const dt_studio_capture_t d,
const double  x,
const double  y,
float  point[2] 
)
static

Convert a widget-space point to a normalized [0,1] image point.

The result is normalized over the displayed surface, which shares the same crop/orientation as the viewer's own develop pipeline: this is therefore a valid "image norm" point for dt_lib_colorpicker_set_point/set_box_area, regardless of the surface's own pixel resolution (fit thumbnail vs 100%).

Definition at line 675 of file studio_capture.c.

References _studio_surface_geometry(), d, FALSE, TRUE, and x.

Referenced by button_pressed(), and mouse_moved().

◆ button_pressed()

◆ button_released()

int button_released ( dt_view_t self,
double  x,
double  y,
int  which,
uint32_t  state 
)

◆ cleanup()

◆ configure()

void configure ( dt_view_t self,
int  width,
int  height 
)

◆ enter()

◆ expose()

◆ gui_init()

◆ init()

◆ key_pressed()

◆ leave()

◆ mouse_moved()

◆ name()

const char * name ( const dt_view_t self)

Definition at line 130 of file studio_capture.c.

◆ reset()

void reset ( dt_view_t self)

Definition at line 615 of file studio_capture.c.

References _studio_set_image(), d, dt_view_t::data, and UNKNOWN_IMAGE.

Referenced by _studio_picker_right_click().

◆ scrolled()

int scrolled ( dt_view_t self,
double  x,
double  y,
int  up,
int  state,
int  delta_y 
)

◆ try_enter()

int try_enter ( dt_view_t self)

Definition at line 200 of file studio_capture.c.

◆ view()

uint32_t view ( const dt_view_t self)

Definition at line 135 of file studio_capture.c.

References DT_VIEW_STUDIO_CAPTURE.