Skip to content

Commit

Permalink
Merge pull request #17051 from darktable-org/po/colorpicker-edit
Browse files Browse the repository at this point in the history
po/colorpicker edit - edit area & point
  • Loading branch information
TurboGit authored Nov 16, 2024
2 parents b004bff + 51f7060 commit 0badacf
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 9 deletions.
34 changes: 34 additions & 0 deletions src/gui/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -4426,6 +4426,40 @@ void dt_gui_process_events()
continue;
}

void dt_gui_simulate_button_event(GtkWidget *widget,
const GdkEventType eventtype,
const int button)
{
gboolean res = FALSE;

// Create the event GdkEventButton
GdkEventButton event;
memset(&event, 0, sizeof(event));

event.type = eventtype;
event.window = gtk_widget_get_window(widget);
event.send_event = TRUE;
event.time = GDK_CURRENT_TIME;
event.x = 0; // not important in this case
event.y = 0; // not important in this case
event.button = button;
event.device =
gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display_get_default()));

if (event.window != NULL)
{
g_object_ref(event.window);
}

// send signal
g_signal_emit_by_name(G_OBJECT(widget), "button-press-event", &event, &res, NULL);

if (event.window != NULL)
{
g_object_unref(event.window);
}
}

// clang-format off
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
// vim: shiftwidth=2 expandtab tabstop=2 cindent
Expand Down
5 changes: 5 additions & 0 deletions src/gui/gtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,11 @@ void dt_gui_cursor_clear_busy();
// (i.e. the current function will do a lot of work before returning)
void dt_gui_process_events();

// Simulate a mouse button event (button is 1, 2, 3 - mouse button) sent to a Widget
void dt_gui_simulate_button_event(GtkWidget *widget,
const GdkEventType eventtype,
const int button);

#ifdef __cplusplus
} // extern "C"
#endif /* __cplusplus */
Expand Down
130 changes: 122 additions & 8 deletions src/libs/colorpicker.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef struct dt_lib_colorpicker_t
GtkWidget *add_sample_button;
GtkWidget *display_samples_check_box;
dt_colorpicker_sample_t primary_sample;
dt_colorpicker_sample_t *target_sample;
} dt_lib_colorpicker_t;

const char *name(dt_lib_module_t *self)
Expand Down Expand Up @@ -91,6 +92,48 @@ int position(const dt_lib_module_t *self)
return 800;
}

#if 0
// kept for debug session
static void _dump_sample(char* ctx, dt_colorpicker_sample_t *sample)
{
const gboolean isbox = sample->size == DT_LIB_COLORPICKER_SIZE_BOX;
printf(">>> %s KIND : %s (%lx)\n", ctx, isbox ? "box" : "point", (uint64_t)sample);
printf(" ");
if(isbox)
{
for(int k = 0; k < 8; k++)
printf("%1.2f ", sample->box[k]);
}
else
{
printf("%1.2f %1.2f", sample->point[0], sample->point[1]);
}
printf("\n");
}

static void _dump(char* ctx, dt_lib_module_t *self)
{
dt_lib_colorpicker_t *data = self->data;

{
char *txt = g_strdup_printf("primary sample (%s)", ctx);
_dump_sample(txt, &data->primary_sample);
g_free(txt);
}

int k = 0;
for(GSList *samples = darktable.lib->proxy.colorpicker.live_samples;
samples;
samples = g_slist_next(samples))
{
char *txt = g_strdup_printf("live sample (%d)", ++k);
dt_colorpicker_sample_t *sample = samples->data;
_dump_sample(txt, sample);
g_free(txt);
}
}
#endif

// GUI callbacks

static gboolean _sample_draw_callback(GtkWidget *widget,
Expand Down Expand Up @@ -121,6 +164,23 @@ static gboolean _sample_draw_callback(GtkWidget *widget,
}
}

// if the sample is locked we want to add a lock
if(sample->copied)
{
const int border = DT_PIXEL_APPLY_DPI(2);
const int icon_width = width - 2 * border;
const int icon_height = height - 2 * border;
if(icon_width > 0 && icon_height > 0)
{
GdkRGBA fg_color;
gtk_style_context_get_color(gtk_widget_get_style_context(widget),
gtk_widget_get_state_flags(widget), &fg_color);

gdk_cairo_set_source_rgba(cr, &fg_color);
dtgtk_cairo_paint_store(cr, border, border, icon_width, icon_height, 0, NULL);
}
}

return FALSE;
}

Expand Down Expand Up @@ -219,6 +279,16 @@ static gboolean _large_patch_toggle(GtkWidget *widget,
static void _picker_button_toggled(GtkToggleButton *button,
dt_lib_colorpicker_t *data)
{
const gboolean is_active = gtk_toggle_button_get_active(button);

// reset copy target
if(!is_active && data->target_sample)
{
gtk_widget_queue_draw(data->target_sample->container);
data->target_sample->copied = FALSE;
data->target_sample = NULL;
}

gtk_widget_set_sensitive(GTK_WIDGET(data->add_sample_button),
gtk_toggle_button_get_active(button));
}
Expand Down Expand Up @@ -458,18 +528,54 @@ static gboolean _live_sample_button(GtkWidget *widget,
// copy to active picker
dt_lib_module_t *self = darktable.lib->proxy.colorpicker.module;
dt_iop_color_picker_t *picker = darktable.lib->proxy.colorpicker.picker_proxy;
dt_lib_colorpicker_t *data = self->data;

// no active picker, too much iffy GTK work to activate a default
if(!picker) return FALSE;
const gboolean is_active =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->picker_button));
const gboolean simulate_event = !is_active || data->target_sample;

if(sample->size == DT_LIB_COLORPICKER_SIZE_POINT)
_set_sample_point(self, sample->point);
else if(sample->size == DT_LIB_COLORPICKER_SIZE_BOX)
_set_sample_box_area(self, sample->box);
if(data->target_sample)
{
// we have a target sample, so we are editing a live sample.
// copy back the edited sample (primary_sample) into the target
// sample on which we clicked.
memcpy(&sample->point,
&data->primary_sample.point,
sizeof(data->primary_sample.point));
memcpy(&sample->box,
&data->primary_sample.box,
sizeof(data->primary_sample.box));

sample->size = data->primary_sample.size;
data->target_sample->copied = FALSE;
data->target_sample = NULL;
}
else
return FALSE;
{
// we don't have a target sample, copy the sample into
// the primary sample to be edited.
data->target_sample = sample;
sample->copied = TRUE;
darktable.lib->proxy.colorpicker.module = self;

if(sample->size == DT_LIB_COLORPICKER_SIZE_POINT)
_set_sample_point(self, sample->point);
else if(sample->size == DT_LIB_COLORPICKER_SIZE_BOX)
_set_sample_box_area(self, sample->box);
}

if(picker->module)
if(simulate_event)
{
dt_gui_simulate_button_event
(data->picker_button,
GDK_BUTTON_PRESS,
/* button 1 to create use a point and 3 for a box */
data->primary_sample.size == DT_LIB_COLORPICKER_SIZE_POINT
? 1
: 3);
}

if(picker && picker->module)
{
picker->module->dev->preview_pipe->status = DT_DEV_PIXELPIPE_DIRTY;
}
Expand All @@ -491,8 +597,16 @@ static void _add_sample(GtkButton *widget,
dt_lib_colorpicker_t *data = self->data;
dt_colorpicker_sample_t *sample = malloc(sizeof(dt_colorpicker_sample_t));

// reset copy target
if(data->target_sample)
{
data->target_sample->copied = FALSE;
data->target_sample = NULL;
}

memcpy(sample, &data->primary_sample, sizeof(dt_colorpicker_sample_t));
sample->locked = FALSE;
sample->copied = FALSE;

sample->container = gtk_event_box_new();
gtk_widget_add_events(sample->container,
Expand Down
2 changes: 1 addition & 1 deletion src/libs/colorpicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef struct dt_colorpicker_sample_t
gboolean pick_output;
// NOTE: only applies to live samples
gboolean locked;
gboolean copied;

/** The actual picked colors */
// picked color in display profile, as picked from preview pixelpipe
Expand All @@ -76,4 +77,3 @@ typedef struct dt_colorpicker_sample_t
// vim: shiftwidth=2 expandtab tabstop=2 cindent
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
// clang-format on

0 comments on commit 0badacf

Please sign in to comment.