int button_released(struct dt_iop_module_t *self, double x, double y, int which, uint32_t state) { dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; dt_iop_graduatednd_params_t *p = (dt_iop_graduatednd_params_t *)self->params; if(g->dragging > 0) { // dt_iop_graduatednd_params_t *p = (dt_iop_graduatednd_params_t *)self->params; // float wd = self->dev->preview_pipe->backbuf_width; // float ht = self->dev->preview_pipe->backbuf_height; float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; float r = 0.0, o = 0.0; // float pts[4]; // dt_dev_distort_backtransform(self->dev,pts,2); set_grad_from_points(self, g->xa, g->ya, g->xb, g->yb, &r, &o); // if this is a "line dragging, we reset extremities, to be sure they are not outside the image if(g->dragging == 3) { /* * whole line dragging should not change rotation, so we should reuse * old rotation to avoid rounding issues */ r = p->rotation; set_points_from_grad(self, &g->xa, &g->ya, &g->xb, &g->yb, r, o); } self->dt->gui->reset = 1; dt_bauhaus_slider_set(g->scale3, r); // dt_bauhaus_slider_set(g->scale4,o); self->dt->gui->reset = 0; p->rotation = r; p->offset = o; g->dragging = 0; dt_dev_add_history_item(darktable.develop, self, TRUE); } g->dragging = 0; return 0; }
static void mode_callback(GtkWidget *combo, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; if(darktable.gui->reset) return; dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data; dt_iop_exposure_params_t *p = (dt_iop_exposure_params_t *)self->params; const dt_iop_exposure_mode_t new_mode = GPOINTER_TO_UINT(g_list_nth_data(g->modes, dt_bauhaus_combobox_get(combo))); free(g->deflicker_histogram); g->deflicker_histogram = NULL; switch(new_mode) { case EXPOSURE_MODE_DEFLICKER: autoexp_disable(self); if(!dt_image_is_raw(&self->dev->image_storage)) { dt_bauhaus_combobox_set(g->mode, g_list_index(g->modes, GUINT_TO_POINTER(EXPOSURE_MODE_MANUAL))); gtk_widget_hide(GTK_WIDGET(g->mode)); break; } p->mode = EXPOSURE_MODE_DEFLICKER; gtk_widget_hide(GTK_WIDGET(g->vbox_manual)); gtk_widget_show(GTK_WIDGET(g->vbox_deflicker)); if(p->deflicker_histogram_source == DEFLICKER_HISTOGRAM_SOURCE_SOURCEFILE) deflicker_prepare_histogram(self, &g->deflicker_histogram, &g->deflicker_histogram_stats); break; case EXPOSURE_MODE_MANUAL: default: p->mode = EXPOSURE_MODE_MANUAL; gtk_widget_hide(GTK_WIDGET(g->vbox_deflicker)); gtk_widget_show(GTK_WIDGET(g->vbox_manual)); break; } dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void colorpick_callback(GtkColorButton *widget, dt_iop_module_t *self) { if(self->dt->gui->reset) return; dt_iop_splittoning_gui_data_t *g = (dt_iop_splittoning_gui_data_t *)self->gui_data; float color[3], h, s, l; GdkRGBA c; gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &c); color[0] = c.red; color[1] = c.green; color[2] = c.blue; rgb2hsl(color, &h, &s, &l); dt_bauhaus_slider_set((GTK_WIDGET(widget) == g->colorpick1) ? g->gslider1 : g->gslider3, h); dt_bauhaus_slider_set((GTK_WIDGET(widget) == g->colorpick1) ? g->gslider2 : g->gslider4, s); dt_dev_add_history_item(darktable.develop, self, TRUE); }
static gboolean dt_iop_zonesystem_bar_scrolled(GtkWidget *widget, GdkEventScroll *event, dt_iop_module_t *self) { dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params; int cs = CLAMP(p->size, 4, MAX_ZONE_SYSTEM_SIZE); if(event->direction == GDK_SCROLL_UP) p->size += 1; else if(event->direction == GDK_SCROLL_DOWN) p->size -= 1; /* sanity checks */ p->size = CLAMP(p->size, 4, MAX_ZONE_SYSTEM_SIZE); p->zone[cs] = -1; dt_dev_add_history_item(darktable.develop, self, TRUE); gtk_widget_queue_draw(widget); return TRUE; }
static gboolean scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params; dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data; int ch = 0; dt_iop_basecurve_node_t *basecurve = p->basecurve[ch]; if(c->selected >= 0) { if(event->direction == GDK_SCROLL_UP) basecurve[c->selected].y = MAX(0.0f, basecurve[c->selected].y + 0.001f); if(event->direction == GDK_SCROLL_DOWN) basecurve[c->selected].y = MIN(1.0f, basecurve[c->selected].y - 0.001f); dt_dev_add_history_item(darktable.develop, self, TRUE); gtk_widget_queue_draw(widget); } return TRUE; }
static void output_profile_changed(GtkWidget *widget, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; if(self->dt->gui->reset) return; dt_iop_colorout_params_t *p = (dt_iop_colorout_params_t *)self->params; int pos = dt_bauhaus_combobox_get(widget); for(GList *profiles = darktable.color_profiles->profiles; profiles; profiles = g_list_next(profiles)) { dt_colorspaces_color_profile_t *pp = (dt_colorspaces_color_profile_t *)profiles->data; if(pp->out_pos == pos) { p->type = pp->type; g_strlcpy(p->filename, pp->filename, sizeof(p->filename)); dt_dev_add_history_item(darktable.develop, self, TRUE); return; } } fprintf(stderr, "[colorout] color profile %s seems to have disappeared!\n", dt_colorspaces_get_name(p->type, p->filename)); }
static void target_C_callback(GtkWidget *slider, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_colorchecker_params_t *p = (dt_iop_colorchecker_params_t *)self->params; dt_iop_colorchecker_gui_data_t *g = (dt_iop_colorchecker_gui_data_t *)self->gui_data; const float Cin = sqrtf( p->source_a[g->patch]*p->source_a[g->patch] + p->source_b[g->patch]*p->source_b[g->patch]); const float Cout = MAX(1e-4f, sqrtf( p->target_a[g->patch]*p->target_a[g->patch]+ p->target_b[g->patch]*p->target_b[g->patch])); const float Cnew = CLAMP(Cin + dt_bauhaus_slider_get(slider), 0.01, 128.0); p->target_a[g->patch] = CLAMP(p->target_a[g->patch]*Cnew/Cout, -128.0, 128.0); p->target_b[g->patch] = CLAMP(p->target_b[g->patch]*Cnew/Cout, -128.0, 128.0); const int reset = darktable.gui->reset; darktable.gui->reset = 1; // avoid history item dt_bauhaus_slider_set(g->scale_a, p->target_a[g->patch] - p->source_a[g->patch]); dt_bauhaus_slider_set(g->scale_b, p->target_b[g->patch] - p->source_b[g->patch]); darktable.gui->reset = reset; dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void frame_colorpick_callback (GtkDarktableButton *button, dt_iop_module_t *self) { if(self->dt->gui->reset) return; dt_iop_borders_gui_data_t *g = (dt_iop_borders_gui_data_t *)self->gui_data; dt_iop_borders_params_t *p = (dt_iop_borders_params_t *)self->params; // turn off the other color picker so that this tool actually works ... gtk_toggle_button_set_active(g->frame_picker, FALSE); gtk_toggle_button_set_active(g->border_picker, FALSE); GtkColorSelectionDialog *csd = GTK_COLOR_SELECTION_DIALOG(gtk_color_selection_dialog_new(_("select frame line color"))); gtk_window_set_transient_for(GTK_WINDOW(csd), GTK_WINDOW(dt_ui_main_window(darktable.gui->ui))); GtkWidget *okButton, *cancelButton = 0; g_object_get(G_OBJECT(csd), "ok-button", &okButton, NULL); g_object_get(G_OBJECT(csd), "cancel-button", &cancelButton, NULL); g_signal_connect (G_OBJECT (okButton), "clicked", G_CALLBACK (colorpick_button_callback), csd); g_signal_connect (G_OBJECT (cancelButton), "clicked", G_CALLBACK (colorpick_button_callback), csd); GtkColorSelection *cs = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(csd)); GdkColor c; c.red = 65535 * p->frame_color[0]; c.green = 65535 * p->frame_color[1]; c.blue = 65535 * p->frame_color[2]; gtk_color_selection_set_current_color(cs, &c); if(gtk_dialog_run(GTK_DIALOG(csd)) == GTK_RESPONSE_ACCEPT) { gtk_color_selection_get_current_color(cs, &c); p->frame_color[0] = c.red /65535.0; p->frame_color[1] = c.green/65535.0; p->frame_color[2] = c.blue /65535.0; gtk_widget_modify_fg(GTK_WIDGET(g->frame_colorpick), GTK_STATE_NORMAL, &c); } gtk_widget_destroy(GTK_WIDGET(csd)); dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void hue_callback(GtkWidget *slider, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_graduatednd_params_t *p = (dt_iop_graduatednd_params_t *)self->params; dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; const float hue = dt_bauhaus_slider_get(g->gslider1); //fprintf(stderr," hue: %f, saturation: %f\n",hue,dtgtk_gradient_slider_get_value(g->gslider2)); float saturation = 1.0f; float color[3]; hsl2rgb(color, hue, saturation, 0.5f); dt_bauhaus_slider_set_stop(g->gslider2, 1.0f, color[0], color[1], color[2]); // Update saturation end color if(self->dt->gui->reset) return; gtk_widget_draw(GTK_WIDGET(g->gslider2),NULL); p->hue = hue; dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void callback(GtkWidget *widget, gpointer *user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; if(self->dt->gui->reset) return; dt_iop_rawprepare_gui_data_t *g = (dt_iop_rawprepare_gui_data_t *)self->gui_data; dt_iop_rawprepare_params_t *p = (dt_iop_rawprepare_params_t *)self->params; for(int i = 0; i < 4; i++) p->raw_black_level_separate[i] = dt_bauhaus_slider_get(g->black_level_separate[i]); p->raw_white_point = dt_bauhaus_slider_get(g->white_point); if(dt_conf_get_bool("plugins/darkroom/rawprepare/allow_editing_crop")) { for(int i = 0; i < 4; i++) { p->crop.array[i] = dt_bauhaus_slider_get(g->crop[i]); } } dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void dt_iop_exposure_set_white(struct dt_iop_module_t *self, const float white) { dt_iop_exposure_params_t *p = (dt_iop_exposure_params_t *)self->params; if(p->mode == EXPOSURE_MODE_DEFLICKER) { dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data; p->deflicker_target_level = white; darktable.gui->reset = 1; dt_bauhaus_slider_set(g->deflicker_target_level, p->deflicker_target_level); darktable.gui->reset = 0; dt_dev_add_history_item(darktable.develop, self, TRUE); } else { exposure_set_white(self, white); autoexp_disable(self); } }
static gboolean expose (GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *self) { // capture gui color picked event. if(darktable.gui->reset) return FALSE; if(self->picked_color_max[0] < self->picked_color_min[0]) return FALSE; if(!self->request_color_pick) return FALSE; static float old[3] = {0, 0, 0}; const float *grayrgb = self->picked_color; if(grayrgb[0] == old[0] && grayrgb[1] == old[1] && grayrgb[2] == old[2]) return FALSE; for(int k=0; k<3; k++) old[k] = grayrgb[k]; dt_iop_temperature_params_t *p = (dt_iop_temperature_params_t *)self->params; for(int k=0; k<3; k++) p->coeffs[k] = (grayrgb[k] > 0.001f) ? 1.0f/grayrgb[k] : 1.0f; // normalize green: p->coeffs[0] /= p->coeffs[1]; p->coeffs[2] /= p->coeffs[1]; p->coeffs[1] = 1.0; for(int k=0; k<3; k++) p->coeffs[k] = fmaxf(0.0f, fminf(8.0f, p->coeffs[k])); gui_update_from_coeffs(self); dt_dev_add_history_item(darktable.develop, self, TRUE); return FALSE; }
static gboolean scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_tonecurve_params_t *p = (dt_iop_tonecurve_params_t *)self->params; dt_iop_tonecurve_gui_data_t *c = (dt_iop_tonecurve_gui_data_t *)self->gui_data; int ch = c->channel; dt_iop_tonecurve_node_t *tonecurve = p->tonecurve[ch]; int autoscale_ab = p->tonecurve_autoscale_ab; // if autoscale_ab is on: do not modify a and b curves if (autoscale_ab && ch != ch_L) return TRUE; if(c->selected >= 0) { if(event->direction == GDK_SCROLL_UP ) tonecurve[c->selected].y = MAX(0.0f, tonecurve[c->selected].y + 0.001f); if(event->direction == GDK_SCROLL_DOWN) tonecurve[c->selected].y = MIN(1.0f, tonecurve[c->selected].y - 0.001f); dt_dev_add_history_item(darktable.develop, self, TRUE); gtk_widget_queue_draw(widget); } return TRUE; }
static void _blendop_mode_callback (GtkWidget *combo, dt_iop_gui_blend_data_t *data) { data->module->blend_params->mode = data->modes[dt_bauhaus_combobox_get(data->blend_modes_combo)].mode; if(data->module->blend_params->mode != DEVELOP_BLEND_DISABLED) { gtk_widget_show(data->opacity_slider); if(data->blendif_support) { gtk_widget_show(data->blendif_enable); if(dt_bauhaus_combobox_get(data->blendif_enable)) gtk_widget_show(GTK_WIDGET(data->blendif_box)); } } else { gtk_widget_hide(data->opacity_slider); if(data->blendif_support) { /* switch off color picker if it was requested by blendif */ if(data->module->request_color_pick < 0) { data->module->request_color_pick = 0; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->colorpicker), 0); } data->module->request_mask_display = 0; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->showmask), 0); data->module->suppress_mask = 0; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->suppress), 0); gtk_widget_hide(GTK_WIDGET(data->blendif_enable)); gtk_widget_hide(GTK_WIDGET(data->blendif_box)); } } dt_dev_add_history_item(darktable.develop, data->module, TRUE); }
static void hue_callback(GtkWidget *slider, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_splittoning_params_t *p = (dt_iop_splittoning_params_t *)self->params; dt_iop_splittoning_gui_data_t *g = (dt_iop_splittoning_gui_data_t *)self->gui_data; double hue=0; double saturation=0; GtkWidget* colorpicker; GtkWidget* sat_slider=NULL; if( slider == g->gslider1 ) { // Shadows hue = p->shadow_hue = dt_bauhaus_slider_get(slider); saturation = p->shadow_saturation; colorpicker = GTK_WIDGET(g->colorpick1); sat_slider = g->gslider2; update_balance_slider_colors(g->scale1, -1, hue); } else { hue = p->highlight_hue = dt_bauhaus_slider_get(slider); saturation=p->highlight_saturation; colorpicker=GTK_WIDGET(g->colorpick2); sat_slider=g->gslider4; update_balance_slider_colors(g->scale1, hue, -1); } update_colorpicker_fg(colorpicker, hue, saturation); update_saturation_slider_end_color(sat_slider, hue); if(self->dt->gui->reset) return; gtk_widget_queue_draw(GTK_WIDGET(sat_slider)); dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void autoexp_callback(GtkToggleButton *button, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data; if(self->dt->gui->reset) return; self->request_color_pick = gtk_toggle_button_get_active(button) ? DT_REQUEST_COLORPICK_MODULE : DT_REQUEST_COLORPICK_OFF; dt_iop_request_focus(self); if(self->request_color_pick == DT_REQUEST_COLORPICK_MODULE) { dt_lib_colorpicker_set_area(darktable.lib, 0.99); dt_dev_reprocess_all(self->dev); } else dt_control_queue_redraw(); gtk_widget_set_sensitive(GTK_WIDGET(g->autoexpp), gtk_toggle_button_get_active(button)); dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void deflicker_disable(dt_iop_module_t *self) { dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data; dt_iop_exposure_params_t *p = (dt_iop_exposure_params_t *)self->params; gulong signal_id = g_signal_lookup("toggled", GTK_TYPE_CHECK_BUTTON); gulong handler_id = g_signal_handler_find(G_OBJECT(g->deflicker), G_SIGNAL_MATCH_ID, signal_id, 0, NULL, NULL, NULL); g_signal_handler_block(G_OBJECT (g->deflicker), handler_id); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->deflicker), FALSE); g_signal_handler_unblock(G_OBJECT (g->deflicker), handler_id); gtk_widget_set_sensitive(GTK_WIDGET(g->deflicker_percentile), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(g->deflicker_level), FALSE); p->deflicker = FALSE; dt_dev_add_history_item(darktable.develop, self, TRUE); }
static gboolean key_softproof_callback(GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval, GdkModifierType modifier, gpointer data) { dt_iop_module_t* self = (dt_iop_module_t*)data; dt_iop_colorout_gui_data_t *g = (dt_iop_colorout_gui_data_t *)self->gui_data; dt_iop_colorout_params_t *p = (dt_iop_colorout_params_t *)self->params; /* toggle softproofing on/off */ g->softproof_enabled = p->softproof_enabled = !p->softproof_enabled; if(p->softproof_enabled) { int pos = dt_bauhaus_combobox_get(g->cbox5); gchar *filename = _get_profile_from_pos(g->profiles, pos); if (filename) g_strlcpy(p->softproofprofile, filename, sizeof(p->softproofprofile)); } dt_dev_add_history_item(darktable.develop, self, TRUE); dt_control_queue_redraw_center(); return TRUE; }
static void saturation_callback(GtkDarktableGradientSlider *slider, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_splittoning_params_t *p = (dt_iop_splittoning_params_t *)self->params; dt_iop_splittoning_gui_data_t *g = (dt_iop_splittoning_gui_data_t *)self->gui_data; double hue=0; double saturation=0; float color[3]; GtkWidget *preview; if( slider == g->gslider2 ) { // Shadows hue=dtgtk_gradient_slider_get_value(g->gslider1); p->shadow_saturation=saturation=dtgtk_gradient_slider_get_value(slider); preview=GTK_WIDGET(g->colorpick1); } else { hue=dtgtk_gradient_slider_get_value(g->gslider3); p->highlight_saturation=saturation=dtgtk_gradient_slider_get_value(slider); preview=GTK_WIDGET(g->colorpick2); } hsl2rgb(color,hue,saturation,0.5); GdkColor c; c.red=color[0]*65535.0; c.green=color[1]*65535.0; c.blue=color[2]*65535.0; gtk_widget_modify_fg(preview,GTK_STATE_NORMAL,&c); // Update color preview if(self->dt->gui->reset) return; dt_dev_add_history_item(darktable.develop, self, TRUE); }
static gboolean dt_iop_levels_scroll(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_levels_gui_data_t *c = (dt_iop_levels_gui_data_t *)self->gui_data; dt_iop_levels_params_t *p = (dt_iop_levels_params_t *)self->params; const float interval = 0.002; // Distance moved for each scroll event gboolean updated = FALSE; float new_position = 0; if (c->dragging) { return FALSE; } if(event->direction == GDK_SCROLL_UP) { new_position = p->levels[c->handle_move] + interval; updated = TRUE; } else if(event->direction == GDK_SCROLL_DOWN) { new_position = p->levels[c->handle_move] - interval; updated = TRUE; } if (updated) { dt_iop_levels_move_handle(self, c->handle_move, new_position, p->levels, c->drag_start_percentage); dt_dev_add_history_item(darktable.develop, self, TRUE); return TRUE; } return FALSE; }
static void hue_callback(GtkDarktableGradientSlider *slider, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_colorize_params_t *p = (dt_iop_colorize_params_t *)self->params; dt_iop_colorize_gui_data_t *g = (dt_iop_colorize_gui_data_t *)self->gui_data; float color[3]; GtkWidget *preview; GtkDarktableGradientSlider *sslider=NULL; p->hue = dtgtk_gradient_slider_get_value(slider); preview = GTK_WIDGET(g->colorpick1); sslider = g->gslider2; /* convert to rgb */ hsl2rgb(color,p->hue,p->saturation,0.5); /* update preview color */ GdkColor c; c.red=color[0]*65535.0; c.green=color[1]*65535.0; c.blue=color[2]*65535.0; dtgtk_gradient_slider_set_stop(sslider,1.0,c); gtk_widget_modify_fg(preview,GTK_STATE_NORMAL,&c); if (self->dt->gui->reset) return; gtk_widget_draw(GTK_WIDGET(sslider),NULL); if (dtgtk_gradient_slider_is_dragging(slider)==FALSE) dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void position_v_changed (GtkWidget *combo, dt_iop_module_t *self) { dt_iop_borders_gui_data_t *g = (dt_iop_borders_gui_data_t *)self->gui_data; dt_iop_borders_params_t *p = (dt_iop_borders_params_t *)self->params; int which = dt_bauhaus_combobox_get(combo); const char* text = dt_bauhaus_combobox_get_text(combo); if (which < 0) { p->pos_v = 0.5f; // center if(text) { const char *c = text; while(*c != ':' && *c != '/' && c < text + strlen(text)) c++; if(c < text + strlen(text) - 1) { // *c = '\0'; // not needed, atof will stop there. c++; p->pos_v = atof(text) / atof(c); } else { p->pos_v = atof(text); } g_strlcpy(p->pos_v_text, text, sizeof(p->pos_v_text)); p->pos_v = MAX(p->pos_v, 0); p->pos_v = MIN(p->pos_v, 1); } } else if (which < DT_IOP_BORDERS_POSITION_H_COUNT) { g_strlcpy(p->pos_v_text, text, sizeof(p->pos_v_text)); p->pos_v = g->pos_h_ratios[which]; } dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void mode_changed (GtkWidget *combo, dt_iop_module_t *self) { dt_iop_highlights_params_t *p = (dt_iop_highlights_params_t *)self->params; dt_iop_highlights_gui_data_t *g = (dt_iop_highlights_gui_data_t *)self->gui_data; int active = dt_bauhaus_combobox_get(combo); switch(active) { case DT_IOP_HIGHLIGHTS_CLIP: p->mode = DT_IOP_HIGHLIGHTS_CLIP; gtk_widget_set_visible(GTK_WIDGET(g->slider_box), FALSE); break; default: case DT_IOP_HIGHLIGHTS_LCH: p->mode = DT_IOP_HIGHLIGHTS_LCH; gtk_widget_set_visible(GTK_WIDGET(g->slider_box), TRUE); gtk_widget_set_no_show_all(GTK_WIDGET(g->slider_box), FALSE); gtk_widget_show_all(GTK_WIDGET(g->slider_box)); gtk_widget_set_no_show_all(GTK_WIDGET(g->slider_box), TRUE); break; } dt_dev_add_history_item(darktable.develop, self, TRUE); }
static gboolean dt_iop_tonecurve_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_tonecurve_gui_data_t *c = (dt_iop_tonecurve_gui_data_t *)self->gui_data; dt_iop_tonecurve_params_t *p = (dt_iop_tonecurve_params_t *)self->params; int ch = c->channel; int nodes = p->tonecurve_nodes[ch]; dt_iop_tonecurve_node_t *tonecurve = p->tonecurve[ch]; int autoscale_ab = p->tonecurve_autoscale_ab; // if autoscale_ab is on: do not modify a and b curves if (autoscale_ab && ch != ch_L) goto finally; const int inset = DT_GUI_CURVE_EDITOR_INSET; int height = widget->allocation.height - 2*inset, width = widget->allocation.width - 2*inset; c->mouse_x = CLAMP(event->x - inset, 0, width); c->mouse_y = CLAMP(event->y - inset, 0, height); const float mx = c->mouse_x/(float)width; const float my = 1.0f - c->mouse_y/(float)height; if(event->state & GDK_BUTTON1_MASK) { // got a vertex selected: if(c->selected >= 0) { tonecurve[c->selected].x = mx; tonecurve[c->selected].y = my; // delete vertex if order has changed: if(nodes > 2) if((c->selected > 0 && tonecurve[c->selected-1].x >= mx) || (c->selected < nodes-1 && tonecurve[c->selected+1].x <= mx)) { for(int k=c->selected; k<nodes-1; k++) { tonecurve[k].x = tonecurve[k+1].x; tonecurve[k].y = tonecurve[k+1].y; } c->selected = -2; // avoid re-insertion of that point immediately after this p->tonecurve_nodes[ch] --; } dt_dev_add_history_item(darktable.develop, self, TRUE); } else if(nodes < 20 && c->selected >= -1) { // no vertex was close, create a new one! if(tonecurve[0].x > mx) c->selected = 0; else for(int k=1; k<nodes; k++) { if(tonecurve[k].x > mx) { c->selected = k; break; } } if(c->selected == -1) c->selected = nodes; for(int i=nodes; i>c->selected; i--) { tonecurve[i].x = tonecurve[i-1].x; tonecurve[i].y = tonecurve[i-1].y; } // found a new point tonecurve[c->selected].x = mx; tonecurve[c->selected].y = my; p->tonecurve_nodes[ch] ++; dt_dev_add_history_item(darktable.develop, self, TRUE); } } else { // minimum area around the node to select it: float min = .04f; min *= min; // comparing against square int nearest = -1; for(int k=0; k<nodes; k++) { float dist = (my - tonecurve[k].y)*(my - tonecurve[k].y) + (mx - tonecurve[k].x)*(mx - tonecurve[k].x); if(dist < min) { min = dist; nearest = k; } } c->selected = nearest; } finally: gtk_widget_queue_draw(widget); return TRUE; }
static gboolean dt_iop_levels_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_levels_gui_data_t *c = (dt_iop_levels_gui_data_t *)self->gui_data; dt_iop_levels_params_t *p = (dt_iop_levels_params_t *)self->params; const int inset = DT_GUI_CURVE_EDITOR_INSET; int height = widget->allocation.height - 2*inset, width = widget->allocation.width - 2*inset; if(!c->dragging) { c->mouse_x = CLAMP(event->x - inset, 0, width); c->drag_start_percentage = (p->levels[1] - p->levels[0]) / (p->levels[2] - p->levels[0]); } c->mouse_y = CLAMP(event->y - inset, 0, height); if(c->dragging) { if(c->handle_move >= 0 && c->handle_move < 3) { const float mx = (CLAMP(event->x - inset, 0, width)) / (float)width; float min_x = 0; float max_x = 1; // Determining the minimum and maximum bounds for the drag handles switch(c->handle_move) { case 0: max_x = fminf(p->levels[2] - (0.05 / c->drag_start_percentage), 1); max_x = fminf((p->levels[2] * (1 - c->drag_start_percentage) - 0.05) / (1 - c->drag_start_percentage), max_x); break; case 1: min_x = p->levels[0] + 0.05; max_x = p->levels[2] - 0.05; break; case 2: min_x = fmaxf((0.05 / c->drag_start_percentage) + p->levels[0], 0); min_x = fmaxf((p->levels[0] * (1 - c->drag_start_percentage) + 0.05) / (1 - c->drag_start_percentage), min_x); break; } p->levels[c->handle_move] = fminf(max_x, fmaxf(min_x, mx)); if(c->handle_move != 1) p->levels[1] = p->levels[0] + (c->drag_start_percentage * (p->levels[2] - p->levels[0])); } dt_dev_add_history_item(darktable.develop, self, TRUE); } else { c->handle_move = 0; const float mx = CLAMP(event->x - inset, 0, width)/(float)width; float dist = fabsf(p->levels[0] - mx); for(int k=1; k<3; k++) { float d2 = fabsf(p->levels[k] - mx); if(d2 < dist) { c->handle_move = k; dist = d2; } } } gtk_widget_queue_draw(widget); gint x, y; gdk_window_get_pointer(event->window, &x, &y, NULL); return TRUE; }
static gboolean dt_iop_levels_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_levels_gui_data_t *c = (dt_iop_levels_gui_data_t *)self->gui_data; dt_iop_levels_params_t *p = (dt_iop_levels_params_t *)self->params; const int inset = DT_GUI_CURVE_EDITOR_INSET; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); float mean_picked_color = *self->picked_color / 100.0; /* we need to save the last picked color to prevent flickering when * changing from one picker to another, as the picked_color value does not * update as rapidly */ if(self->request_color_pick && mean_picked_color != c->last_picked_color) { float previous_color[3]; previous_color[0] = p->levels[0]; previous_color[1] = p->levels[1]; previous_color[2] = p->levels[2]; c->last_picked_color = mean_picked_color; if (BLACK == c->current_pick) { if (mean_picked_color > p->levels[1]) { p->levels[0] = p->levels[1]-FLT_EPSILON; } else { p->levels[0] = mean_picked_color; } c->pick_xy_positions[0][0] = self->color_picker_point[0]; c->pick_xy_positions[0][1] = self->color_picker_point[1]; } else if (GREY == c->current_pick) { if (mean_picked_color < p->levels[0] || mean_picked_color > p->levels[2]) { p->levels[1] = p->levels[1]; } else { p->levels[1] = mean_picked_color; } c->pick_xy_positions[1][0] = self->color_picker_point[0]; c->pick_xy_positions[1][1] = self->color_picker_point[1]; } else if (WHITE == c->current_pick) { if (mean_picked_color < p->levels[1]) { p->levels[2] = p->levels[1]+FLT_EPSILON; } else { p->levels[2] = mean_picked_color; } c->pick_xy_positions[2][0] = self->color_picker_point[0]; c->pick_xy_positions[2][1] = self->color_picker_point[1]; } if ( previous_color[0] != p->levels[0] || previous_color[1] != p->levels[1] || previous_color[2] != p->levels[2] ) { dt_dev_add_history_item(darktable.develop, self, TRUE); } } // clear bg cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2*inset; height -= 2*inset; cairo_set_line_width(cr, 1.0); cairo_set_source_rgb (cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); cairo_set_source_rgb (cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); // draw grid cairo_set_line_width(cr, .4); cairo_set_source_rgb (cr, .1, .1, .1); dt_draw_vertical_lines(cr, 4, 0, 0, width, height); // Drawing the vertical line indicators cairo_set_line_width(cr, 2.); for(int k = 0; k < 3; k++) { if(k == c->handle_move && c->mouse_x > 0) cairo_set_source_rgb(cr, 1, 1, 1); else cairo_set_source_rgb(cr, .7, .7, .7); cairo_move_to(cr, width*p->levels[k], height); cairo_rel_line_to(cr, 0, -height); cairo_stroke(cr); } // draw x positions cairo_set_line_width(cr, 1.); const float arrw = 7.0f; for(int k=0; k<3; k++) { switch(k) { case 0: cairo_set_source_rgb(cr, 0, 0, 0); break; case 1: cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); break; default: cairo_set_source_rgb(cr, 1, 1, 1); break; } cairo_move_to(cr, width*p->levels[k], height+inset-1); cairo_rel_line_to(cr, -arrw*.5f, 0); cairo_rel_line_to(cr, arrw*.5f, -arrw); cairo_rel_line_to(cr, arrw*.5f, arrw); cairo_close_path(cr); if(c->handle_move == k && c->mouse_x > 0) cairo_fill(cr); else cairo_stroke(cr); } cairo_translate(cr, 0, height); // draw lum histogram in background // only if the module is enabled if (self->enabled) { dt_develop_t *dev = darktable.develop; float *hist, hist_max; hist = dev->histogram_pre_levels; hist_max = dev->histogram_linear?dev->histogram_pre_levels_max:logf(1.0 + dev->histogram_pre_levels_max); if(hist_max > 0) { cairo_save(cr); cairo_scale(cr, width/63.0, -(height-5)/(float)hist_max); cairo_set_source_rgba(cr, .2, .2, .2, 0.5); dt_draw_histogram_8(cr, hist, 3); cairo_restore(cr); } } // Cleaning up cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static gboolean borders_draw(GtkWidget *widget, cairo_t *cr, dt_iop_module_t *self) { if(darktable.gui->reset) return FALSE; if(self->picked_output_color_max[0] < 0) return FALSE; if(self->request_color_pick == DT_REQUEST_COLORPICK_OFF) return FALSE; dt_iop_borders_gui_data_t *g = (dt_iop_borders_gui_data_t *)self->gui_data; dt_iop_borders_params_t *p = (dt_iop_borders_params_t *)self->params; // interrupt if no valid color reading if(self->picked_color_min[0] == INFINITY) return FALSE; if(fabsf(p->color[0] - self->picked_color[0]) < 0.0001f && fabsf(p->color[1] - self->picked_color[1]) < 0.0001f && fabsf(p->color[2] - self->picked_color[2]) < 0.0001f) { // interrupt infinite loops return FALSE; } if(fabsf(p->frame_color[0] - self->picked_color[0]) < 0.0001f && fabsf(p->frame_color[1] - self->picked_color[1]) < 0.0001f && fabsf(p->frame_color[2] - self->picked_color[2]) < 0.0001f) { // interrupt infinite loops return FALSE; } GdkRGBA c = (GdkRGBA){.red = self->picked_color[0], .green = self->picked_color[1], .blue = self->picked_color[2], .alpha = 1.0 }; if(g->active_colorpick == g->frame_colorpick) { p->frame_color[0] = self->picked_color[0]; p->frame_color[1] = self->picked_color[1]; p->frame_color[2] = self->picked_color[2]; gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(g->frame_colorpick), &c); } else { p->color[0] = self->picked_color[0]; p->color[1] = self->picked_color[1]; p->color[2] = self->picked_color[2]; gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(g->colorpick), &c); } dt_dev_add_history_item(darktable.develop, self, TRUE); return FALSE; } static void aspect_changed(GtkWidget *combo, dt_iop_module_t *self) { dt_iop_borders_gui_data_t *g = (dt_iop_borders_gui_data_t *)self->gui_data; dt_iop_borders_params_t *p = (dt_iop_borders_params_t *)self->params; int which = dt_bauhaus_combobox_get(combo); const char *text = dt_bauhaus_combobox_get_text(combo); if(which < 0) { p->aspect = DT_IOP_BORDERS_ASPECT_CONSTANT_VALUE; if(text) { const char *c = text; const char *end = text + strlen(text); while(*c != ':' && *c != '/' && c < end) c++; if(c < end - 1) { // *c = '\0'; // not needed, atof will stop there. c++; p->aspect = atof(text) / atof(c); g_strlcpy(p->aspect_text, text, sizeof(p->aspect_text)); } } } else if(which < DT_IOP_BORDERS_ASPECT_COUNT) { g_strlcpy(p->aspect_text, text, sizeof(p->aspect_text)); p->aspect = g->aspect_ratios[which]; } dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void detail_callback(GtkWidget *w, dt_iop_module_t *self) { dt_iop_bilat_params_t *p = (dt_iop_bilat_params_t *)self->params; p->detail = dt_bauhaus_slider_get(w); dt_dev_add_history_item(darktable.develop, self, TRUE); }
static gboolean lowlight_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_lowlight_gui_data_t *c = (dt_iop_lowlight_gui_data_t *)self->gui_data; dt_iop_lowlight_params_t *p = (dt_iop_lowlight_params_t *)self->params; const int inset = DT_IOP_LOWLIGHT_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; if(!c->dragging) c->mouse_x = CLAMP(event->x - inset, 0, width) / (float)width; c->mouse_y = 1.0 - CLAMP(event->y - inset, 0, height) / (float)height; if(c->dragging) { *p = c->drag_params; if(c->x_move >= 0) { const float mx = CLAMP(event->x - inset, 0, width) / (float)width; if(c->x_move > 0 && c->x_move < DT_IOP_LOWLIGHT_BANDS - 1) { const float minx = p->transition_x[c->x_move - 1] + 0.001f; const float maxx = p->transition_x[c->x_move + 1] - 0.001f; p->transition_x[c->x_move] = fminf(maxx, fmaxf(minx, mx)); } } else { dt_iop_lowlight_get_params(p, c->mouse_x, c->mouse_y + c->mouse_pick, c->mouse_radius); } dt_dev_add_history_item(darktable.develop, self, TRUE); } else if(event->y > height) { c->x_move = 0; float dist = fabs(p->transition_x[0] - c->mouse_x); for(int k = 1; k < DT_IOP_LOWLIGHT_BANDS; k++) { float d2 = fabs(p->transition_x[k] - c->mouse_x); if(d2 < dist) { c->x_move = k; dist = d2; } } } else { c->x_move = -1; } gtk_widget_queue_draw(widget); gint x, y; #if GTK_CHECK_VERSION(3, 20, 0) gdk_window_get_device_position(event->window, gdk_seat_get_pointer(gdk_display_get_default_seat( gdk_window_get_display(event->window))), &x, &y, 0); #else gdk_window_get_device_position(event->window, gdk_device_manager_get_client_pointer( gdk_display_get_device_manager(gdk_window_get_display(event->window))), &x, &y, NULL); #endif return TRUE; }
static gboolean dt_iop_basecurve_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data; dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params; int ch = 0; int nodes = p->basecurve_nodes[ch]; dt_iop_basecurve_node_t *basecurve = p->basecurve[ch]; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); const int inset = DT_GUI_CURVE_EDITOR_INSET; int height = allocation.height - 2 * inset, width = allocation.width - 2 * inset; c->mouse_x = CLAMP(event->x - inset, 0, width); c->mouse_y = CLAMP(event->y - inset, 0, height); const float mx = c->mouse_x / (float)width; const float my = 1.0f - c->mouse_y / (float)height; const float linx = to_lin(mx, c->loglogscale), liny = to_lin(my, c->loglogscale); if(event->state & GDK_BUTTON1_MASK) { // got a vertex selected: if(c->selected >= 0) { basecurve[c->selected].x = linx; basecurve[c->selected].y = liny; // delete vertex if order has changed: if(nodes > 2) if((c->selected > 0 && basecurve[c->selected - 1].x >= linx) || (c->selected < nodes - 1 && basecurve[c->selected + 1].x <= linx)) { for(int k = c->selected; k < nodes - 1; k++) { basecurve[k].x = basecurve[k + 1].x; basecurve[k].y = basecurve[k + 1].y; } c->selected = -2; // avoid re-insertion of that point immediately after this p->basecurve_nodes[ch]--; } dt_dev_add_history_item(darktable.develop, self, TRUE); } else if(nodes < 20 && c->selected >= -1) { // no vertex was close, create a new one! if(basecurve[0].x > linx) c->selected = 0; else for(int k = 1; k < nodes; k++) { if(basecurve[k].x > linx) { c->selected = k; break; } } if(c->selected == -1) c->selected = nodes; for(int i = nodes; i > c->selected; i--) { basecurve[i].x = basecurve[i - 1].x; basecurve[i].y = basecurve[i - 1].y; } // found a new point basecurve[c->selected].x = linx; basecurve[c->selected].y = liny; p->basecurve_nodes[ch]++; dt_dev_add_history_item(darktable.develop, self, TRUE); } } else { // minimum area around the node to select it: float min = .04f; min *= min; // comparing against square int nearest = -1; for(int k = 0; k < nodes; k++) { float dist = (my - to_log(basecurve[k].y, c->loglogscale)) * (my - to_log(basecurve[k].y, c->loglogscale)) + (mx - to_log(basecurve[k].x, c->loglogscale)) * (mx - to_log(basecurve[k].x, c->loglogscale)); if(dist < min) { min = dist; nearest = k; } } c->selected = nearest; } gtk_widget_queue_draw(widget); return TRUE; }