Skip to content

Commit 6f00a40

Browse files
Crop module gets orientation proxy support
While developing an image in darkroom we might have set a cropping area, this commit implements functionality to keep the cropped area if we change orientation via the flip module. Three parts in the codebase required additions without changing existing code. 1. `dt_develop_t` got two additions in cropping proxy, `struct dt_iop_module_t *flip_handler` points to the crop module and is setup there. We can't use `exposer` as the proxy because that is dynamically set in pixelpipe code only if enabled and we want to change crop parameters even if crop is disabled. `void (*flip_callback)` is the callback function changing crop parameters, defined in crop. 2. Orientation module uses the `flip_callback(self, orientation)` requesting changes in crop. 3. In crop we have `_crop_handle_flip()` as proxy `flip_callback` with proper logs about action. - It gets the data from self `dt_iop_crop_params_t`, - does the requested action, - updates gui from parameters - adds a new history stack entry (respecting the current `crop->enabled` status).
1 parent d9e1adf commit 6f00a40

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

src/develop/develop.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,16 @@ typedef struct dt_develop_t
289289

290290
dt_dev_chroma_t chroma;
291291

292-
// for exposing the crop
292+
// for exposing and handling the crop
293293
struct
294294
{
295295
// set by dt_dev_pixelpipe_synch() if an enabled crop module is included in history
296296
struct dt_iop_module_t *exposer;
297+
298+
// proxy to change crop settings via flip module
299+
struct dt_iop_module_t *flip_handler;
300+
void (*flip_callback)(struct dt_iop_module_t *crop,
301+
const dt_image_orientation_t flipmode);
297302
} cropping;
298303

299304
// for the overexposure indicator

src/iop/crop.c

+32
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,35 @@ static gchar *_aspect_format(gchar *original,
11111111
return g_strdup_printf("%s %4.2f", original, (float)adim / (float)bdim);
11121112
}
11131113

1114+
static void _crop_handle_flip(dt_iop_module_t *self, const dt_image_orientation_t mode)
1115+
{
1116+
dt_iop_crop_params_t *p = self ? self->params : NULL;
1117+
if(!p) return;
1118+
1119+
dt_print(DT_DEBUG_PIPE, "[crop_handle_flip] origin: %1.3f %1.3f %1.3f %1.3f mode=%s%s",
1120+
p->cx, 1.0f - p->cw, p->cy, 1.0f - p->ch,
1121+
mode == ORIENTATION_ROTATE_CW_90_DEG ? "ROTATE_CW_90_DEG"
1122+
: mode == ORIENTATION_ROTATE_CCW_90_DEG ? "ROTATE_CCW_90_DEG"
1123+
: mode == ORIENTATION_FLIP_HORIZONTALLY ? "FLIP_HORIZONTALLY"
1124+
: mode == ORIENTATION_FLIP_VERTICALLY ? "FLIP_VERTICALLY"
1125+
: "UNKNOWN",
1126+
self->enabled ? "" : ", crop disabled");
1127+
1128+
const float ocx = p->cx;
1129+
const float ocy = p->cy;
1130+
if(mode == ORIENTATION_FLIP_HORIZONTALLY) {p->cx = 1.f-p->cw; p->cw = 1.f-ocx;}
1131+
else if(mode == ORIENTATION_FLIP_VERTICALLY) {p->cy = 1.f-p->ch; p->ch = 1.f-ocy;}
1132+
else if(mode == ORIENTATION_ROTATE_CW_90_DEG) {p->cx = 1.f-p->ch; p->ch = p->cw; p->cw = 1.f-p->cy; p->cy = ocx;}
1133+
else if(mode == ORIENTATION_ROTATE_CCW_90_DEG) {p->cx = p->cy; p->cy = 1.f-p->cw; p->cw = p->ch; p->ch = 1.f-ocx;}
1134+
1135+
dt_iop_gui_update(self);
1136+
gui_changed(self, NULL, NULL);
1137+
dt_dev_add_new_history_item(darktable.develop, self, self->enabled);
1138+
1139+
dt_print(DT_DEBUG_PIPE, "[crop_handle_flip] result: %1.3f %1.3f %1.3f %1.3f",
1140+
p->cx, 1.0f - p->cw, p->cy, 1.0f - p->ch);
1141+
}
1142+
11141143
void gui_init(dt_iop_module_t *self)
11151144
{
11161145
dt_iop_crop_gui_data_t *g = IOP_GUI_ALLOC(crop);
@@ -1302,6 +1331,9 @@ void gui_init(dt_iop_module_t *self)
13021331
_("the bottom margin cannot overlap with the top margin"));
13031332

13041333
self->widget = box_enabled;
1334+
1335+
darktable.develop->cropping.flip_handler = self;
1336+
darktable.develop->cropping.flip_callback = _crop_handle_flip;
13051337
}
13061338

13071339
static void _aspect_free(gpointer data)

src/iop/flip.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ void commit_params(dt_iop_module_t *self,
431431
d->orientation = p->orientation;
432432

433433
if(d->orientation == ORIENTATION_NONE)
434-
piece->enabled = 0;
434+
piece->enabled = FALSE;
435435
}
436436

437437
void init_pipe(dt_iop_module_t *self,
@@ -518,6 +518,14 @@ void reload_defaults(dt_iop_module_t *self)
518518
}
519519
}
520520

521+
static void _crop_callback(const int mode)
522+
{
523+
dt_develop_t *dev = darktable.develop;
524+
dt_iop_module_t *cropper = dev->cropping.flip_handler;
525+
if(cropper && dev->cropping.flip_callback)
526+
dev->cropping.flip_callback(cropper, mode);
527+
}
528+
521529
static void do_rotate(dt_iop_module_t *self, uint32_t cw)
522530
{
523531
dt_iop_flip_params_t *p = self->params;
@@ -544,6 +552,7 @@ static void do_rotate(dt_iop_module_t *self, uint32_t cw)
544552

545553
p->orientation = orientation;
546554
dt_dev_add_history_item(darktable.develop, self, TRUE);
555+
_crop_callback(cw ? ORIENTATION_ROTATE_CW_90_DEG : ORIENTATION_ROTATE_CCW_90_DEG);
547556
}
548557

549558
static void rotate_cw(GtkWidget *widget, dt_iop_module_t *self)
@@ -570,6 +579,7 @@ static void _flip_h(GtkWidget *widget, dt_iop_module_t *self)
570579
p->orientation = orientation ^ ORIENTATION_FLIP_HORIZONTALLY;
571580

572581
dt_dev_add_history_item(darktable.develop, self, TRUE);
582+
_crop_callback(ORIENTATION_FLIP_HORIZONTALLY);
573583
}
574584

575585
static void _flip_v(GtkWidget *widget, dt_iop_module_t *self)
@@ -587,6 +597,7 @@ static void _flip_v(GtkWidget *widget, dt_iop_module_t *self)
587597
p->orientation = orientation ^ ORIENTATION_FLIP_VERTICALLY;
588598

589599
dt_dev_add_history_item(darktable.develop, self, TRUE);
600+
_crop_callback(ORIENTATION_FLIP_VERTICALLY);
590601
}
591602

592603
void gui_init(dt_iop_module_t *self)

0 commit comments

Comments
 (0)