static gboolean _gradient_slider_leave_notify_event(GtkWidget *widget, GdkEventCrossing *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); gtk_widget_set_state(widget,GTK_STATE_NORMAL); gslider->is_entered = FALSE; gtk_widget_draw(widget,NULL); DTGTK_GRADIENT_SLIDER(widget)->prev_x_root=event->x_root; return FALSE; }
static gboolean _blendop_blendif_expose(GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *module) { if(darktable.gui->reset) return FALSE; dt_iop_gui_blend_data_t *data = module->blend_data; float picker_mean[8], picker_min[8], picker_max[8]; float cooked[8]; float *raw_mean, *raw_min, *raw_max; char text[256]; GtkLabel *label; if(widget == GTK_WIDGET(data->lower_slider)) { raw_mean = module->picked_color; raw_min = module->picked_color_min; raw_max = module->picked_color_max; label = data->lower_picker_label; } else { raw_mean = module->picked_output_color; raw_min = module->picked_output_color_min; raw_max = module->picked_output_color_max; label = data->upper_picker_label; } darktable.gui->reset = 1; if(module->request_color_pick) { _blendif_scale(data->csp, raw_mean, picker_mean); _blendif_scale(data->csp, raw_min, picker_min); _blendif_scale(data->csp, raw_max, picker_max); _blendif_cook(data->csp, raw_mean, cooked); if(data->channels[data->tab][0] >= 8) // min and max make no sense for HSL and LCh picker_min[data->tab] = picker_max[data->tab] = picker_mean[data->tab]; snprintf(text, 256, "(%.1f)", cooked[data->tab]); dtgtk_gradient_slider_multivalue_set_picker_meanminmax(DTGTK_GRADIENT_SLIDER(widget), picker_mean[data->tab], picker_min[data->tab], picker_max[data->tab]); gtk_label_set_text(label, text); } else { dtgtk_gradient_slider_multivalue_set_picker(DTGTK_GRADIENT_SLIDER(widget), -1.0f); gtk_label_set_text(label, ""); } gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->colorpicker), (module->request_color_pick < 0 ? 1 : 0)); darktable.gui->reset = 0; return FALSE; }
static gboolean _blendop_blendif_expose(GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *module) { if(darktable.gui->reset) return FALSE; dt_iop_gui_blend_data_t *data = module->blend_data; float picker_mean[4], picker_min[4], picker_max[4]; float cooked[4]; float *raw_mean, *raw_min, *raw_max; char text[256]; GtkLabel *label; if(widget == GTK_WIDGET(data->lower_slider)) { raw_mean = module->picked_color; raw_min = module->picked_color_min; raw_max = module->picked_color_max; label = data->lower_picker_label; } else { raw_mean = module->picked_output_color; raw_min = module->picked_output_color_min; raw_max = module->picked_output_color_max; label = data->upper_picker_label; } darktable.gui->reset = 1; if(module->request_color_pick) { _blendif_scale(data->csp, raw_mean, picker_mean); _blendif_scale(data->csp, raw_min, picker_min); _blendif_scale(data->csp, raw_max, picker_max); _blendif_cook(data->csp, raw_mean, cooked); snprintf(text, 256, "(%.1f)", cooked[data->channel]); dtgtk_gradient_slider_multivalue_set_picker_meanminmax(DTGTK_GRADIENT_SLIDER(widget), picker_mean[data->channel], picker_min[data->channel], picker_max[data->channel]); gtk_label_set_text(label, text); } else { dtgtk_gradient_slider_multivalue_set_picker(DTGTK_GRADIENT_SLIDER(widget), -1.0f); gtk_label_set_text(label, ""); } darktable.gui->reset = 0; return FALSE; }
static gdouble _slider_move(GtkWidget *widget, gint k, gdouble value, gint direction) { GtkDarktableGradientSlider *gslider = DTGTK_GRADIENT_SLIDER(widget); gdouble newvalue = value; gdouble leftnext = (k == 0) ? 0.0f : gslider->position[k-1]; gdouble rightnext = (k == gslider->positions-1) ? 1.0f : gslider->position[k+1]; switch(direction) { case MOVE_LEFT: if(value < leftnext) { newvalue = (k == 0) ? fmax(value, 0.0f) : _slider_move(widget, k-1, value, direction); } break; case MOVE_RIGHT: if(value > rightnext) { newvalue = (k == gslider->positions-1) ? fmin(value, 1.0f) : _slider_move(widget, k+1, value, direction); } break; } gslider->position[k] = newvalue; return newvalue; }
static gboolean _gradient_slider_button_release(GtkWidget *widget, GdkEventButton *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); if( event->button==1 && gslider->selected != -1 && gslider->do_reset==FALSE ) { // First get some dimention info gslider->is_changed=TRUE; gdouble newposition = roundf(_screen_to_scale(widget, event->x)/gslider->increment)*gslider->increment; newposition = CLAMP_RANGE(newposition, 0.0, 1.0); gint direction = gslider->position[gslider->selected] <= newposition ? MOVE_RIGHT : MOVE_LEFT; _slider_move(widget, gslider->selected, newposition, direction); gslider->min = gslider->selected == 0 ? 0.0f : gslider->position[gslider->selected-1]; gslider->max = gslider->selected == gslider->positions-1 ? 1.0f : gslider->position[gslider->selected+1]; gtk_widget_draw(widget,NULL); gslider->prev_x_root = event->x_root; gslider->is_dragging=FALSE; g_signal_emit_by_name(G_OBJECT(widget),"value-changed"); } return TRUE; }
static gboolean expose (GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *self) { // capture gui color picked event. if(darktable.gui->reset) return FALSE; float mean, min, max; if(self->request_color_pick) { mean = fmin(fmax(self->picked_color[0] / 100.0f, 0.0f), 1.0f); min = fmin(fmax(self->picked_color_min[0] / 100.0f, 0.0f), 1.0f); max = fmin(fmax(self->picked_color_max[0] / 100.0f, 0.0f), 1.0f); } else { mean = min = max = -1.0f; } dt_iop_relight_gui_data_t *g = (dt_iop_relight_gui_data_t *)self->gui_data; dtgtk_gradient_slider_set_picker_meanminmax(DTGTK_GRADIENT_SLIDER(g->gslider1), mean, min, max); gtk_widget_queue_draw(GTK_WIDGET(g->gslider1)); return FALSE; }
static inline gint _scale_to_screen(GtkWidget *widget, gdouble scale) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); return (gint)(scale * (allocation.width - 2*gslider->margins) + gslider->margins); }
static inline gdouble _screen_to_scale(GtkWidget *widget, gint screen) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); return ((gdouble)screen - gslider->margins) / ((gdouble)allocation.width - 2*gslider->margins); }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_relight_gui_data_t)); dt_iop_relight_gui_data_t *g = (dt_iop_relight_gui_data_t *)self->gui_data; dt_iop_relight_params_t *p = (dt_iop_relight_params_t *)self->params; self->widget = gtk_vbox_new(FALSE, DT_BAUHAUS_SPACE); g_signal_connect (G_OBJECT (self->widget), "expose-event", G_CALLBACK (expose), self); /* exposure */ g->scale1 = dt_bauhaus_slider_new_with_range(self,-2.0, 2.0,0.05, p->ev, 2); dt_bauhaus_slider_set_format(g->scale1,"%.2fEV"); dt_bauhaus_widget_set_label(g->scale1,_("exposure")); g_object_set(G_OBJECT(g->scale1), "tooltip-text", _("the fill-light in EV"), (char *)NULL); g_signal_connect (G_OBJECT (g->scale1), "value-changed", G_CALLBACK (ev_callback), self); /* width*/ g->scale2 = dt_bauhaus_slider_new_with_range(self,2, 10, 0.5, p->width, 1); dt_bauhaus_slider_set_format(g->scale2,"%.1f"); dt_bauhaus_widget_set_label(g->scale2,_("width")); /* xgettext:no-c-format */ g_object_set(G_OBJECT(g->scale2), "tooltip-text", _("width of fill-light area defined in zones"), (char *)NULL); g_signal_connect (G_OBJECT (g->scale2), "value-changed", G_CALLBACK (width_callback), self); /* lightnessslider */ GtkBox *hbox=GTK_BOX (gtk_hbox_new (FALSE,2)); int lightness=32768; g->gslider1=DTGTK_GRADIENT_SLIDER (dtgtk_gradient_slider_new_with_color ((GdkColor) { 0,0,0,0 },(GdkColor) { 0,lightness,lightness,lightness })); g_object_set(G_OBJECT (g->gslider1), "tooltip-text", _("select the center of fill-light"), (char *)NULL); g_signal_connect (G_OBJECT (g->gslider1), "value-changed", G_CALLBACK (center_callback), self); g->tbutton1 = DTGTK_TOGGLEBUTTON (dtgtk_togglebutton_new (dtgtk_cairo_paint_colorpicker, CPF_STYLE_FLAT)); gtk_widget_set_size_request(GTK_WIDGET(g->tbutton1),22,22); g_signal_connect (G_OBJECT (g->tbutton1), "toggled", G_CALLBACK (picker_callback), self); gtk_box_pack_start (hbox,GTK_WIDGET (g->gslider1),TRUE,TRUE,0); gtk_box_pack_start (hbox,GTK_WIDGET (g->tbutton1),FALSE,FALSE,0); /* add controls to widget ui */ gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET (g->scale1),TRUE,FALSE,0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET (hbox), TRUE,FALSE,0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET (g->scale2),TRUE,FALSE,0); g_object_set(G_OBJECT(g->tbutton1), "tooltip-text", _("toggle tool for picking median lightness in image"), (char *)NULL); }
static gboolean _gradient_slider_postponed_value_change(gpointer data) { if(!GTK_IS_WIDGET(data)) return 0; gdk_threads_enter(); if(DTGTK_GRADIENT_SLIDER(data)->is_changed==TRUE) { g_signal_emit_by_name(G_OBJECT(data),"value-changed"); DTGTK_GRADIENT_SLIDER(data)->is_changed=FALSE; } if(!DTGTK_GRADIENT_SLIDER(data)->is_dragging) DTGTK_GRADIENT_SLIDER(data)->timeout_handle = 0; gdk_threads_leave(); return DTGTK_GRADIENT_SLIDER(data)->is_dragging; // This is called by the gtk mainloop and is threadsafe }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_relight_gui_data_t)); dt_iop_relight_gui_data_t *g = (dt_iop_relight_gui_data_t *)self->gui_data; dt_iop_relight_params_t *p = (dt_iop_relight_params_t *)self->params; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); g_signal_connect(G_OBJECT(self->widget), "draw", G_CALLBACK(draw), self); /* exposure */ g->scale1 = dt_bauhaus_slider_new_with_range(self, -2.0, 2.0, 0.05, p->ev, 2); dt_bauhaus_slider_set_format(g->scale1, "%.2fEV"); dt_bauhaus_widget_set_label(g->scale1, NULL, _("exposure")); g_object_set(G_OBJECT(g->scale1), "tooltip-text", _("the fill-light in EV"), (char *)NULL); g_signal_connect(G_OBJECT(g->scale1), "value-changed", G_CALLBACK(ev_callback), self); /* width*/ g->scale2 = dt_bauhaus_slider_new_with_range(self, 2, 10, 0.5, p->width, 1); dt_bauhaus_slider_set_format(g->scale2, "%.1f"); dt_bauhaus_widget_set_label(g->scale2, NULL, _("width")); /* xgettext:no-c-format */ g_object_set(G_OBJECT(g->scale2), "tooltip-text", _("width of fill-light area defined in zones"), (char *)NULL); g_signal_connect(G_OBJECT(g->scale2), "value-changed", G_CALLBACK(width_callback), self); /* lightnessslider */ GtkBox *hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2)); #define NEUTRAL_GRAY 0.5 static const GdkRGBA _gradient_L[] = { { 0, 0, 0, 1.0 }, { NEUTRAL_GRAY, NEUTRAL_GRAY, NEUTRAL_GRAY, 1.0 } }; g->gslider1 = DTGTK_GRADIENT_SLIDER(dtgtk_gradient_slider_new_with_color(_gradient_L[0], _gradient_L[1])); g_object_set(G_OBJECT(g->gslider1), "tooltip-text", _("select the center of fill-light"), (char *)NULL); g_signal_connect(G_OBJECT(g->gslider1), "value-changed", G_CALLBACK(center_callback), self); g->tbutton1 = DTGTK_TOGGLEBUTTON(dtgtk_togglebutton_new(dtgtk_cairo_paint_colorpicker, CPF_STYLE_FLAT)); gtk_widget_set_size_request(GTK_WIDGET(g->tbutton1), DT_PIXEL_APPLY_DPI(22), DT_PIXEL_APPLY_DPI(22)); g_signal_connect(G_OBJECT(g->tbutton1), "toggled", G_CALLBACK(picker_callback), self); gtk_box_pack_start(hbox, GTK_WIDGET(g->gslider1), TRUE, TRUE, 0); gtk_box_pack_start(hbox, GTK_WIDGET(g->tbutton1), FALSE, FALSE, 0); /* add controls to widget ui */ gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->scale1), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->scale2), TRUE, FALSE, 0); g_object_set(G_OBJECT(g->tbutton1), "tooltip-text", _("toggle tool for picking median lightness in image"), (char *)NULL); }
static gboolean _gradient_slider_scroll_event(GtkWidget *widget, GdkEventScroll *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); if (gslider->selected != -1) { gdouble inc = gslider->increment; gdouble newvalue = gslider->position[gslider->selected] + ((event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT) ? inc : -inc); gslider->position[gslider->selected] = newvalue > gslider->max ? gslider->max : (newvalue < gslider->min ? gslider->min : newvalue); gtk_widget_draw( widget, NULL); g_signal_emit_by_name(G_OBJECT(widget),"value-changed"); } return TRUE; }
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; const float *Lab = self->picked_color; dt_iop_relight_params_t *p = (dt_iop_relight_params_t *)self->params; p->center = Lab[0]; dt_dev_add_history_item(darktable.develop, self, TRUE); darktable.gui->reset = 1; dt_iop_relight_gui_data_t *g = (dt_iop_relight_gui_data_t *)self->gui_data; dtgtk_gradient_slider_set_value(DTGTK_GRADIENT_SLIDER(g->gslider1),p->center); darktable.gui->reset = 0; return FALSE; }
static void _gradient_slider_destroy(GtkObject *object) { GtkDarktableGradientSliderClass *klass; g_return_if_fail(object != NULL); g_return_if_fail(DTGTK_IS_GRADIENT_SLIDER(object)); if(DTGTK_GRADIENT_SLIDER(object)->timeout_handle) g_source_remove(DTGTK_GRADIENT_SLIDER(object)->timeout_handle); DTGTK_GRADIENT_SLIDER(object)->timeout_handle = 0; if(DTGTK_GRADIENT_SLIDER(object)->colors) { g_list_foreach(DTGTK_GRADIENT_SLIDER(object)->colors, (GFunc)g_free, NULL); g_list_free(DTGTK_GRADIENT_SLIDER(object)->colors); DTGTK_GRADIENT_SLIDER(object)->colors = NULL; } klass = gtk_type_class(gtk_widget_get_type()); if (GTK_OBJECT_CLASS(klass)->destroy) { (* GTK_OBJECT_CLASS(klass)->destroy) (object); } }
static gboolean _gradient_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); if( gslider->is_dragging==TRUE && gslider->selected != -1 && gslider->do_reset==FALSE ) { assert(gslider->timeout_handle > 0); gdouble newposition = roundf(_screen_to_scale(widget, event->x)/gslider->increment)*gslider->increment; newposition = CLAMP_RANGE(newposition, 0.0, 1.0); gint direction = gslider->position[gslider->selected] <= newposition ? MOVE_RIGHT : MOVE_LEFT; _slider_move(widget, gslider->selected, newposition, direction); gslider->min = gslider->selected == 0 ? 0.0f : gslider->position[gslider->selected-1]; gslider->max = gslider->selected == gslider->positions-1 ? 1.0f : gslider->position[gslider->selected+1]; gslider->is_changed = TRUE; gtk_widget_draw(widget,NULL); } return TRUE; }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_colorize_gui_data_t)); dt_iop_colorize_gui_data_t *g = (dt_iop_colorize_gui_data_t *)self->gui_data; dt_iop_colorize_params_t *p = (dt_iop_colorize_params_t *)self->params; self->widget = GTK_WIDGET(gtk_vbox_new(FALSE, 0)); g->colorpick1 = DTGTK_BUTTON(dtgtk_button_new(dtgtk_cairo_paint_color,CPF_IGNORE_FG_STATE|CPF_STYLE_FLAT|CPF_DO_NOT_USE_BORDER)); gtk_widget_set_size_request(GTK_WIDGET(g->colorpick1),32,32); GtkWidget *hbox = GTK_WIDGET(gtk_hbox_new(FALSE, 0)); g->vbox1 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); g->vbox2 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox1), FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox2), TRUE, TRUE, 5); gtk_box_pack_end(GTK_BOX(hbox),GTK_WIDGET(g->colorpick1),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 5); g->label1 = dtgtk_reset_label_new (_("hue"), self, &p->hue, sizeof(float)); g->label2 = dtgtk_reset_label_new (_("saturation"), self, &p->saturation, sizeof(float)); gtk_box_pack_start(GTK_BOX(g->vbox1), GTK_WIDGET(g->label1), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(g->vbox1), GTK_WIDGET(g->label2), TRUE, TRUE, 0); int lightness=32768; g->gslider1 = DTGTK_GRADIENT_SLIDER(dtgtk_gradient_slider_new_with_color((GdkColor) { 0,lightness,0,0 },(GdkColor) { 0,lightness,0,0 })); dtgtk_gradient_slider_set_stop(g->gslider1,0.166,(GdkColor) { 0,lightness,lightness,0 }); dtgtk_gradient_slider_set_stop(g->gslider1,0.332,(GdkColor) { 0,0,lightness,0 }); dtgtk_gradient_slider_set_stop(g->gslider1,0.498,(GdkColor) { 0,0,lightness,lightness }); dtgtk_gradient_slider_set_stop(g->gslider1,0.664,(GdkColor) { 0,0,0,lightness }); dtgtk_gradient_slider_set_stop(g->gslider1,0.83,(GdkColor) { 0,lightness,0,lightness }); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->gslider1), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->gslider1), "tooltip-text", _("select the hue tone"), (char *)NULL); g->gslider2=DTGTK_GRADIENT_SLIDER(dtgtk_gradient_slider_new_with_color((GdkColor) { 0,lightness,lightness,lightness },(GdkColor) { 0,lightness,lightness,lightness })); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->gslider2), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->gslider2), "tooltip-text", _("select the saturation shadow tone"), (char *)NULL); // Additional paramters hbox=GTK_WIDGET(gtk_hbox_new(FALSE, 0)); g->vbox2 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox2), TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 5); g->scale1 = DTGTK_SLIDER(dtgtk_slider_new_with_range(DARKTABLE_SLIDER_BAR,0.0, 100.0, 0.1, p->lightness*100.0, 2)); dtgtk_slider_set_format_type(g->scale1,DARKTABLE_SLIDER_FORMAT_PERCENT); dtgtk_slider_set_label(g->scale1,_("lightness")); dtgtk_slider_set_unit(g->scale1,"%"); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->scale1), TRUE, TRUE, 0); g->scale2 = DTGTK_SLIDER(dtgtk_slider_new_with_range(DARKTABLE_SLIDER_BAR,0.0, 100.0, 0.1, p->source_lightness_mix, 2)); dtgtk_slider_set_format_type(g->scale2,DARKTABLE_SLIDER_FORMAT_PERCENT); dtgtk_slider_set_label(g->scale2,_("source mix")); dtgtk_slider_set_unit(g->scale2,"%"); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->scale2), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->scale1), "tooltip-text", _("lightness of color"), (char *)NULL); g_object_set(G_OBJECT(g->scale2), "tooltip-text", _("mix value of source lightness"), (char *)NULL); g_signal_connect (G_OBJECT (g->gslider1), "value-changed", G_CALLBACK (hue_callback), self); g_signal_connect (G_OBJECT (g->gslider2), "value-changed", G_CALLBACK (saturation_callback), self); g_signal_connect (G_OBJECT (g->scale1), "value-changed", G_CALLBACK (lightness_callback), self); g_signal_connect (G_OBJECT (g->scale2), "value-changed", G_CALLBACK (source_lightness_mix_callback), self); g_signal_connect (G_OBJECT (g->colorpick1), "clicked", G_CALLBACK (colorpick_callback), self); }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_splittoning_gui_data_t)); dt_iop_splittoning_gui_data_t *g = (dt_iop_splittoning_gui_data_t *)self->gui_data; dt_iop_splittoning_params_t *p = (dt_iop_splittoning_params_t *)self->params; self->widget = GTK_WIDGET(gtk_vbox_new(FALSE, 0)); // Shadows gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(dtgtk_label_new(_("shadows"),DARKTABLE_LABEL_TAB|DARKTABLE_LABEL_ALIGN_RIGHT)), FALSE, FALSE, 5); g->colorpick1 = DTGTK_BUTTON(dtgtk_button_new(dtgtk_cairo_paint_color,CPF_IGNORE_FG_STATE|CPF_STYLE_FLAT|CPF_DO_NOT_USE_BORDER)); gtk_widget_set_size_request(GTK_WIDGET(g->colorpick1),32,32); GtkWidget *hbox=GTK_WIDGET(gtk_hbox_new(FALSE, 0)); g->vbox1 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); g->vbox2 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox1), FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox2), TRUE, TRUE, 5); gtk_box_pack_end(GTK_BOX(hbox),GTK_WIDGET(g->colorpick1),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 5); g->label1 = dtgtk_reset_label_new (_("hue"), self, &p->shadow_hue, sizeof(float)); g->label2 = dtgtk_reset_label_new (_("saturation"), self, &p->shadow_saturation, sizeof(float)); gtk_box_pack_start(GTK_BOX(g->vbox1), GTK_WIDGET(g->label1), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(g->vbox1), GTK_WIDGET(g->label2), TRUE, TRUE, 0); int lightness=32768; g->gslider1=DTGTK_GRADIENT_SLIDER(dtgtk_gradient_slider_new_with_color((GdkColor) { 0,lightness,0,0 },(GdkColor) { 0,lightness,0,0 })); dtgtk_gradient_slider_set_stop(g->gslider1,0.166,(GdkColor) { 0,lightness,lightness,0 }); dtgtk_gradient_slider_set_stop(g->gslider1,0.332,(GdkColor) { 0,0,lightness,0 }); dtgtk_gradient_slider_set_stop(g->gslider1,0.498,(GdkColor) { 0,0,lightness,lightness }); dtgtk_gradient_slider_set_stop(g->gslider1,0.664,(GdkColor) { 0,0,0,lightness }); dtgtk_gradient_slider_set_stop(g->gslider1,0.83,(GdkColor) { 0,lightness,0,lightness }); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->gslider1), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->gslider1), "tooltip-text", _("select the hue tone for shadows"), (char *)NULL); g->gslider2=DTGTK_GRADIENT_SLIDER(dtgtk_gradient_slider_new_with_color((GdkColor) { 0,lightness,lightness,lightness },(GdkColor) { 0,lightness,lightness,lightness })); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->gslider2), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->gslider2), "tooltip-text", _("select the saturation shadow tone"), (char *)NULL); // Highlights gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(dtgtk_label_new(_("highlights"),DARKTABLE_LABEL_TAB|DARKTABLE_LABEL_ALIGN_RIGHT)), FALSE, FALSE, 5); g->colorpick2 = DTGTK_BUTTON(dtgtk_button_new(dtgtk_cairo_paint_color,CPF_IGNORE_FG_STATE|CPF_STYLE_FLAT|CPF_DO_NOT_USE_BORDER)); gtk_widget_set_size_request(GTK_WIDGET(g->colorpick2),32,32); hbox=GTK_WIDGET(gtk_hbox_new(FALSE, 0)); g->vbox1 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); g->vbox2 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox1), FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox2), TRUE, TRUE, 5); gtk_box_pack_end(GTK_BOX(hbox),GTK_WIDGET(g->colorpick2),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 5); g->label3 = dtgtk_reset_label_new (_("hue"), self, &p->highlight_hue, sizeof(float)); g->label4 = dtgtk_reset_label_new (_("saturation"), self, &p->highlight_saturation, sizeof(float)); gtk_box_pack_start(GTK_BOX(g->vbox1), GTK_WIDGET(g->label3), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(g->vbox1), GTK_WIDGET(g->label4), TRUE, TRUE, 0); g->gslider3=DTGTK_GRADIENT_SLIDER(dtgtk_gradient_slider_new_with_color((GdkColor) { 0,lightness,0,0 },(GdkColor) { 0,lightness,0,0 })); dtgtk_gradient_slider_set_stop(g->gslider3,0.166,(GdkColor) { 0,lightness,lightness,0 }); dtgtk_gradient_slider_set_stop(g->gslider3,0.332,(GdkColor) { 0,0,lightness,0 }); dtgtk_gradient_slider_set_stop(g->gslider3,0.498,(GdkColor) { 0,0,lightness,lightness }); dtgtk_gradient_slider_set_stop(g->gslider3,0.664,(GdkColor) { 0,0,0,lightness }); dtgtk_gradient_slider_set_stop(g->gslider3,0.83,(GdkColor) { 0,lightness,0,lightness }); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->gslider3), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->gslider3), "tooltip-text", _("select the hue tone for highlights"), (char *)NULL); g->gslider4=DTGTK_GRADIENT_SLIDER(dtgtk_gradient_slider_new_with_color((GdkColor) { 0,lightness,lightness,lightness },(GdkColor) { 0,lightness,lightness,lightness })); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->gslider4), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->gslider4), "tooltip-text", _("select the saturation highlights tone"), (char *)NULL); // Additional paramters hbox=GTK_WIDGET(gtk_hbox_new(FALSE, 0)); g->vbox2 = GTK_VBOX(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(g->vbox2), TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 5); g->scale1 = dt_bauhaus_slider_new_with_range(self, 0.0, 100.0, 0.1, p->balance*100.0, 2); dt_bauhaus_slider_set_format(g->scale1, "%.2f"); dt_bauhaus_widget_set_label(g->scale1, _("balance")); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->scale1), TRUE, TRUE, 0); g->scale2 = dt_bauhaus_slider_new_with_range(self, 0.0, 100.0, 1.0, p->compress, 2); dt_bauhaus_slider_set_format(g->scale2, "%.2f%%"); dt_bauhaus_widget_set_label(g->scale2,_("compress")); gtk_box_pack_start(GTK_BOX(g->vbox2), GTK_WIDGET(g->scale2), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->scale1), "tooltip-text", _("the balance of center of splittoning"), (char *)NULL); g_object_set(G_OBJECT(g->scale2), "tooltip-text", _("compress the effect on highlighs/shadows and\npreserve midtones"), (char *)NULL); g_signal_connect (G_OBJECT (g->gslider1), "value-changed", G_CALLBACK (hue_callback), self); g_signal_connect (G_OBJECT (g->gslider3), "value-changed", G_CALLBACK (hue_callback), self); g_signal_connect (G_OBJECT (g->gslider2), "value-changed", G_CALLBACK (saturation_callback), self); g_signal_connect (G_OBJECT (g->gslider4), "value-changed", G_CALLBACK (saturation_callback), self); g_signal_connect (G_OBJECT (g->scale1), "value-changed", G_CALLBACK (balance_callback), self); g_signal_connect (G_OBJECT (g->scale2), "value-changed", G_CALLBACK (compress_callback), self); g_signal_connect (G_OBJECT (g->colorpick1), "clicked", G_CALLBACK (colorpick_callback), self); g_signal_connect (G_OBJECT (g->colorpick2), "clicked", G_CALLBACK (colorpick_callback), self); }
static gboolean _gradient_slider_expose(GtkWidget *widget, GdkEventExpose *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); assert(gslider->position > 0); g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkButton", GTK_TYPE_BUTTON); if(!style) style = gtk_rc_get_style(widget); int state = gtk_widget_get_state(widget); /*int x = widget->allocation.x; int y = widget->allocation.y;*/ int width = widget->allocation.width; int height = widget->allocation.height; int margins = gslider->margins; // Begin cairo drawing cairo_t *cr; cr = gdk_cairo_create(widget->window); // First build the cairo gradient and then fill the gradient float gheight=height/2.0; float gwidth=width-2*margins; GList *current=NULL; cairo_pattern_t *gradient=NULL; if((current=g_list_first(gslider->colors)) != NULL) { gradient=cairo_pattern_create_linear(0,0,gwidth,gheight); do { _gradient_slider_stop_t *stop=(_gradient_slider_stop_t *)current->data; cairo_pattern_add_color_stop_rgb(gradient,stop->position,stop->color.red/65535.0,stop->color.green/65535.0,stop->color.blue/65535.0); } while((current=g_list_next(current))!=NULL); } if(gradient!=NULL) // Do we got a gradient, lets draw it { cairo_set_line_width(cr,0.1); cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); cairo_set_source(cr,gradient); cairo_rectangle(cr,margins,(height-gheight)/2.0,gwidth,gheight); cairo_fill(cr); cairo_stroke(cr); } // Lets draw position arrows cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 1.0 ); // do we have a picker value to draw? gdouble *picker = gslider->picker; if(picker[0] >= 0.0 && picker[0] <= 1.0) { int vx_min=_scale_to_screen(widget, picker[1]); int vx_max=_scale_to_screen(widget, picker[2]); int vx_avg=_scale_to_screen(widget, picker[0]); cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 0.33 ); cairo_rectangle(cr,vx_min,(height-gheight)/2.0,fmax((float)vx_max-vx_min, 0.0f),gheight); cairo_fill(cr); cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 1.0 ); cairo_move_to(cr,vx_avg,(height-gheight)/2.0); cairo_line_to(cr,vx_avg,(height+gheight)/2.0); cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr,1.0); cairo_stroke(cr); } int indirect[GRADIENT_SLIDER_MAX_POSITIONS]; for(int k=0; k<gslider->positions; k++) indirect[k] = gslider->selected == -1 ? k : (gslider->selected + 1 + k) % gslider->positions; for(int k=0; k<gslider->positions; k++) { int l = indirect[k]; int vx=_scale_to_screen(widget, gslider->position[l]); int mk=gslider->marker[l]; int sz=(mk & (1<<3)) ? 13 : 10; // big or small marker? if(l == gslider->selected && (gslider->is_entered == TRUE || gslider->is_dragging == TRUE)) { cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0 * 0.5, 1.0 ); } else { cairo_set_source_rgba(cr, style->fg[state].red/65535.0*0.8, style->fg[state].green/65535.0*0.8, style->fg[state].blue/65535.0*0.8, 1.0 ); } #if 0 if(sz < 10) { // supporting line for small markers cairo_move_to(cr,vx,2); cairo_line_to(cr,vx,height-2); cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr,1.0); cairo_stroke(cr); } #endif cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT); if(mk & 0x04) /* upper arrow */ { if (mk & 0x01) /* filled */ dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN); else dtgtk_cairo_paint_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN); } if(mk & 0x02) /* lower arrow */ { if (mk & 0x01) /* filled */ dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP); else dtgtk_cairo_paint_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP); } } cairo_destroy(cr); return FALSE; }
static gboolean _gradient_slider_button_press(GtkWidget *widget, GdkEventButton *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); if(event->button == 1 && event->type == GDK_2BUTTON_PRESS && gslider->is_resettable) { gslider->is_dragging=FALSE; gslider->do_reset=TRUE; gslider->selected=-1; for(int k=0; k<gslider->positions; k++) gslider->position[k] = gslider->resetvalue[k]; gtk_widget_draw(widget,NULL); g_signal_emit_by_name(G_OBJECT(widget),"value-changed"); } else if((event->button==1 || event->button==3) && event->type == GDK_BUTTON_PRESS) { gint lselected = -1; gdouble newposition = roundf(_screen_to_scale(widget, event->x)/gslider->increment)*gslider->increment; gslider->prev_x_root=event->x_root; assert(gslider->positions > 0); if(gslider->positions == 1) { lselected = 0; } else if (newposition <= gslider->position[0]) { lselected = 0; } else if (newposition >= gslider->position[gslider->positions-1]) { lselected = gslider->positions-1; } else for(int k=0; k<=gslider->positions-2; k++) { if(newposition >= gslider->position[k] && newposition <= gslider->position[k+1]) { lselected = newposition - gslider->position[k] < gslider->position[k+1] - newposition ? k : k+1; break; } } assert(lselected >= 0); assert(lselected <= gslider->positions-1); if(event->button==1) // left mouse button : select and start dragging { gslider->selected = lselected; gslider->is_dragging=TRUE; gslider->do_reset=FALSE; newposition = CLAMP_RANGE(newposition, 0.0, 1.0); gint direction = gslider->position[gslider->selected] <= newposition ? MOVE_RIGHT : MOVE_LEFT; _slider_move(widget, gslider->selected, newposition, direction); gslider->min = gslider->selected == 0 ? 0.0f : gslider->position[gslider->selected-1]; gslider->max = gslider->selected == gslider->positions-1 ? 1.0f : gslider->position[gslider->selected+1]; g_signal_emit_by_name(G_OBJECT(widget),"value-changed"); } else if (gslider->positions > 1) // right mouse button: switch on/off selection (only if we have more than one marker) { gslider->is_dragging=FALSE; gslider->do_reset=FALSE; if(gslider->selected != lselected) { gslider->selected = lselected; gslider->min = gslider->selected == 0 ? 0.0f : gslider->position[gslider->selected-1]; gslider->max = gslider->selected == gslider->positions-1 ? 1.0f : gslider->position[gslider->selected+1]; } else gslider->selected = -1; gtk_widget_draw(widget,NULL); } } return TRUE; }