void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_monochrome_gui_data_t)); dt_iop_monochrome_gui_data_t *g = (dt_iop_monochrome_gui_data_t *)self->gui_data; g->dragging = 0; self->request_color_pick = DT_REQUEST_COLORPICK_OFF; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); dt_gui_add_help_link(self->widget, dt_get_help_url(self->op)); g->area = GTK_DRAWING_AREA(dtgtk_drawing_area_new_with_aspect_ratio(1.0)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0); gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag and scroll mouse wheel to adjust the virtual color filter")); gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_monochrome_draw), self); g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_monochrome_button_press), self); g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(dt_iop_monochrome_button_release), self); g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_monochrome_motion_notify), self); g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_monochrome_leave_notify), self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_monochrome_scrolled), self); GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_BAUHAUS_SPACE); g->highlights = dt_bauhaus_slider_new_with_range(self, 0.0, 1.0, 0.01, 0.0, 2); gtk_widget_set_tooltip_text(g->highlights, _("how much to keep highlights")); dt_bauhaus_widget_set_label(g->highlights, NULL, _("highlights")); gtk_box_pack_start(GTK_BOX(box), g->highlights, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(g->highlights), "value-changed", G_CALLBACK(highlights_callback), self); g->colorpicker = dtgtk_togglebutton_new(dtgtk_cairo_paint_colorpicker, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER, NULL); gtk_widget_set_size_request(GTK_WIDGET(g->colorpicker), DT_PIXEL_APPLY_DPI(14), DT_PIXEL_APPLY_DPI(14)); gtk_box_pack_end(GTK_BOX(box), GTK_WIDGET(g->colorpicker), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(g->colorpicker), "toggled", G_CALLBACK(picker_callback), self); gtk_box_pack_end(GTK_BOX(self->widget), GTK_WIDGET(box), TRUE, TRUE, 0); cmsHPROFILE hsRGB = dt_colorspaces_get_profile(DT_COLORSPACE_SRGB, "", DT_PROFILE_DIRECTION_IN)->profile; cmsHPROFILE hLab = dt_colorspaces_get_profile(DT_COLORSPACE_LAB, "", DT_PROFILE_DIRECTION_ANY)->profile; g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0); // cmsFLAGS_NOTPRECALC); }
/** Creates a gconf widget. */ static _camera_gconf_widget_t *_camera_import_gconf_widget(_camera_import_dialog_t *dlg, gchar *label, gchar *confstring) { _camera_gconf_widget_t *gcw = calloc(1, sizeof(_camera_gconf_widget_t)); GtkWidget *vbox, *hbox; gcw->widget = vbox = GTK_WIDGET(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0)); hbox = GTK_WIDGET(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0)); g_object_set_data(G_OBJECT(vbox), "gconf:string", confstring); gcw->dialog = dlg; gcw->entry = gtk_entry_new(); char *value = dt_conf_get_string(confstring); if(value) { gtk_entry_set_text(GTK_ENTRY(gcw->entry), value); g_free(gcw->value); gcw->value = value; } gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(gcw->entry), TRUE, TRUE, 0); GtkWidget *button = dtgtk_button_new(dtgtk_cairo_paint_store, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); gtk_widget_set_tooltip_text(button, _("store value as default")); gtk_widget_set_size_request(button, DT_PIXEL_APPLY_DPI(13), DT_PIXEL_APPLY_DPI(13)); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(_gcw_store_callback), gcw); button = dtgtk_button_new(dtgtk_cairo_paint_reset, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); gtk_widget_set_tooltip_text(button, _("reset value to default")); gtk_widget_set_size_request(button, DT_PIXEL_APPLY_DPI(13), DT_PIXEL_APPLY_DPI(13)); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(_gcw_reset_callback), gcw); GtkWidget *l = gtk_label_new(label); gtk_widget_set_halign(l, GTK_ALIGN_START); gtk_box_pack_start(GTK_BOX(vbox), l, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(gtk_entry_get_buffer(GTK_ENTRY(gcw->entry))), "inserted-text", G_CALLBACK(entry_it_callback), gcw); g_signal_connect(G_OBJECT(gtk_entry_get_buffer(GTK_ENTRY(gcw->entry))), "deleted-text", G_CALLBACK(entry_dt_callback), gcw); return gcw; }
static gboolean _lib_darktable_draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_darktable_t *d = (dt_lib_darktable_t *)self->data; GtkStyleContext *context = gtk_widget_get_style_context(widget); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height); GtkStateFlags state = gtk_widget_get_state_flags(widget); PangoFontDescription *font_desc = NULL; gtk_style_context_get(context, state, "font", &font_desc, NULL); /* paint icon image */ if(d->image) { cairo_set_source_surface(cr, d->image, 0, (int)DT_PIXEL_APPLY_DPI(7)); cairo_rectangle(cr, 0, 0, d->image_width + (int)DT_PIXEL_APPLY_DPI(8), d->image_height + (int)DT_PIXEL_APPLY_DPI(8)); cairo_fill(cr); } /* create a pango layout and print fancy name/version string */ PangoLayout *layout; layout = gtk_widget_create_pango_layout(widget, NULL); pango_font_description_set_weight(font_desc, PANGO_WEIGHT_BOLD); pango_font_description_set_absolute_size(font_desc, DT_PIXEL_APPLY_DPI(25) * PANGO_SCALE); pango_layout_set_font_description(layout, font_desc); pango_layout_set_text(layout, PACKAGE_NAME, -1); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5); cairo_move_to(cr, d->image_width + DT_PIXEL_APPLY_DPI(2.0), DT_PIXEL_APPLY_DPI(5.0)); pango_cairo_show_layout(cr, layout); /* print version */ pango_font_description_set_absolute_size(font_desc, DT_PIXEL_APPLY_DPI(10) * PANGO_SCALE); pango_layout_set_font_description(layout, font_desc); pango_layout_set_text(layout, darktable_package_version, -1); cairo_move_to(cr, d->image_width + DT_PIXEL_APPLY_DPI(4.0), DT_PIXEL_APPLY_DPI(30.0)); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.3); pango_cairo_show_layout(cr, layout); /* cleanup */ g_object_unref(layout); pango_font_description_free(font_desc); return TRUE; }
void gui_init(dt_lib_module_t *self) { /* initialize ui widgets */ dt_lib_tool_lighttable_t *d = (dt_lib_tool_lighttable_t *)g_malloc0(sizeof(dt_lib_tool_lighttable_t)); self->data = (void *)d; self->widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); d->layout = dt_conf_get_int("plugins/lighttable/layout"); d->previous_layout = d->layout == DT_LIGHTTABLE_LAYOUT_EXPOSE ? DT_LIGHTTABLE_LAYOUT_FILEMANAGER : DT_LIGHTTABLE_LAYOUT_EXPOSE; d->current_zoom = dt_conf_get_int("plugins/lighttable/images_in_row"); /* create layout selection combobox */ d->layout_combo = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(d->layout_combo), _("zoomable light table")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(d->layout_combo), _("file manager")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(d->layout_combo), _("expose")); gtk_combo_box_set_active(GTK_COMBO_BOX(d->layout_combo), d->layout); g_signal_connect(G_OBJECT(d->layout_combo), "changed", G_CALLBACK(_lib_lighttable_layout_changed), (gpointer)self); gtk_box_pack_start(GTK_BOX(self->widget), d->layout_combo, TRUE, TRUE, 0); /* create horizontal zoom slider */ d->zoom = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 1, 21, 1); gtk_widget_set_size_request(GTK_WIDGET(d->zoom), DT_PIXEL_APPLY_DPI(140), -1); gtk_scale_set_draw_value(GTK_SCALE(d->zoom), FALSE); gtk_range_set_increments(GTK_RANGE(d->zoom), 1, 1); gtk_box_pack_start(GTK_BOX(self->widget), d->zoom, TRUE, TRUE, 0); /* manual entry of the zoom level */ d->zoom_entry = gtk_entry_new(); gtk_entry_set_alignment(GTK_ENTRY(d->zoom_entry), 1.0); gtk_entry_set_max_length(GTK_ENTRY(d->zoom_entry), 2); gtk_entry_set_width_chars(GTK_ENTRY(d->zoom_entry), 3); gtk_entry_set_max_width_chars(GTK_ENTRY(d->zoom_entry), 3); dt_gui_key_accel_block_on_focus_connect(d->zoom_entry); gtk_box_pack_start(GTK_BOX(self->widget), d->zoom_entry, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(d->zoom), "value-changed", G_CALLBACK(_lib_lighttable_zoom_slider_changed), (gpointer)self); g_signal_connect(d->zoom_entry, "key-press-event", G_CALLBACK(_lib_lighttable_zoom_entry_changed), self); gtk_range_set_value(GTK_RANGE(d->zoom), d->current_zoom); _lib_lighttable_zoom_slider_changed(GTK_RANGE(d->zoom), self); // the slider defaults to 1 and GTK doesn't // fire a value-changed signal when setting // it to 1 => empty text box gtk_widget_set_no_show_all(d->zoom, TRUE); gtk_widget_set_no_show_all(d->zoom_entry, TRUE); _lib_lighttable_layout_changed(GTK_COMBO_BOX(d->layout_combo), self); darktable.view_manager->proxy.lighttable.module = self; darktable.view_manager->proxy.lighttable.set_zoom = _lib_lighttable_set_zoom; darktable.view_manager->proxy.lighttable.get_zoom = _lib_lighttable_get_zoom; darktable.view_manager->proxy.lighttable.get_layout = _lib_lighttable_get_layout; darktable.view_manager->proxy.lighttable.set_layout = _lib_lighttable_set_layout; }
int mouse_moved(struct dt_iop_module_t *self, double x, double y, double pressure, int which) { dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; dt_dev_zoom_t zoom = dt_control_get_dev_zoom(); int closeup = dt_control_get_dev_closeup(); float zoom_scale = dt_dev_get_zoom_scale(self->dev, zoom, closeup ? 2 : 1, 1); float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; // are we dragging something ? if(g->dragging > 0) { if(g->dragging == 1) { // we are dragging xa,ya g->xa = pzx; g->ya = pzy; } else if(g->dragging == 2) { // we are dragging xb,yb g->xb = pzx; g->yb = pzy; } else if(g->dragging == 3) { // we are dragging the entire line g->xa += pzx - g->oldx; g->xb += pzx - g->oldx; g->ya += pzy - g->oldy; g->yb += pzy - g->oldy; g->oldx = pzx; g->oldy = pzy; } } else { g->selected = 0; const float ext = DT_PIXEL_APPLY_DPI(0.02f) / zoom_scale; // are we near extermity ? if(pzy > g->ya - ext && pzy < g->ya + ext && pzx > g->xa - ext && pzx < g->xa + ext) { g->selected = 1; } else if(pzy > g->yb - ext && pzy < g->yb + ext && pzx > g->xb - ext && pzx < g->xb + ext) { g->selected = 2; } else if(dist_seg(g->xa, g->ya, g->xb, g->yb, pzx, pzy) < ext * ext * 0.5) g->selected = 3; } dt_control_queue_redraw_center(); return 1; }
static inline void gui_init_tab(struct dt_iop_module_t *self, const char *name, GtkWidget **ppcolor, const GdkRGBA *c, GtkWidget **pphue, GtkWidget **ppsaturation) { gtk_box_pack_start(GTK_BOX(self->widget), dt_ui_section_label_new(name), FALSE, FALSE, 5); // color button GtkWidget *color; *ppcolor = color = gtk_color_button_new_with_rgba(c); gtk_widget_set_size_request(GTK_WIDGET(color), DT_PIXEL_APPLY_DPI(32), DT_PIXEL_APPLY_DPI(32)); gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(color), FALSE); gtk_color_button_set_title(GTK_COLOR_BUTTON(color), _("select tone color")); // hue slider GtkWidget *hue; *pphue = hue = (dt_bauhaus_slider_new_with_range_and_feedback(self, 0.0f, 1.0f, 0.01f, 0.0f, 2, 0)); dt_bauhaus_slider_set_stop(hue, 0.0f, 1.0f, 0.0f, 0.0f); dt_bauhaus_widget_set_label(hue, NULL, _("hue")); dt_bauhaus_slider_set_stop(hue, 0.166f, 1.0f, 1.0f, 0.0f); dt_bauhaus_slider_set_stop(hue, 0.322f, 0.0f, 1.0f, 0.0f); dt_bauhaus_slider_set_stop(hue, 0.498f, 0.0f, 1.0f, 1.0f); dt_bauhaus_slider_set_stop(hue, 0.664f, 0.0f, 0.0f, 1.0f); dt_bauhaus_slider_set_stop(hue, 0.830f, 1.0f, 0.0f, 1.0f); dt_bauhaus_slider_set_stop(hue, 1.0f, 1.0f, 0.0f, 0.0f); g_object_set(G_OBJECT(hue), "tooltip-text", _("select the hue tone"), (char *)NULL); // saturation slider GtkWidget *saturation; *ppsaturation = saturation = dt_bauhaus_slider_new_with_range(self, 0.0f, 1.0f, 0.01f, 0.0f, 2); dt_bauhaus_widget_set_label(saturation, NULL, _("saturation")); dt_bauhaus_slider_set_stop(saturation, 0.0f, 0.2f, 0.2f, 0.2f); dt_bauhaus_slider_set_stop(saturation, 1.0f, 1.0f, 1.0f, 1.0f); g_object_set(G_OBJECT(saturation), "tooltip-text", _("select the saturation tone"), (char *)NULL); // pack the widgets GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hue), FALSE, TRUE, 0); gtk_box_pack_end(GTK_BOX(vbox), GTK_WIDGET(saturation), FALSE, TRUE, 0); GtkWidget *hbox = GTK_WIDGET(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0)); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox), TRUE, TRUE, 0); gtk_box_pack_end(GTK_BOX(hbox), GTK_WIDGET(color), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 0); }
void gui_init(dt_lib_module_t *self) { /* initialize ui widgets */ dt_lib_history_t *d = (dt_lib_history_t *)g_malloc0(sizeof(dt_lib_history_t)); self->data = (void *)d; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5)); gtk_widget_set_name(self->widget, "history-ui"); d->history_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); GtkWidget *hhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_PIXEL_APPLY_DPI(5)); GtkWidget *hbutton = dtgtk_button_new(NULL, /*CPF_DO_NOT_USE_BORDER | CPF_STYLE_FLAT*/0); gtk_button_set_label(GTK_BUTTON(hbutton), _("compress history stack")); d->compress_button = hbutton; g_object_set(G_OBJECT(hbutton), "tooltip-text", _("create a minimal history stack which produces the same image"), (char *)NULL); g_signal_connect(G_OBJECT(hbutton), "clicked", G_CALLBACK(_lib_history_compress_clicked_callback), NULL); /* add toolbar button for creating style */ GtkWidget *hbutton2 = dtgtk_button_new(dtgtk_cairo_paint_styles, CPF_DO_NOT_USE_BORDER); gtk_widget_set_size_request (hbutton2, DT_PIXEL_APPLY_DPI(24), -1); g_signal_connect(G_OBJECT(hbutton2), "clicked", G_CALLBACK(_lib_history_create_style_button_clicked_callback), NULL); g_object_set(G_OBJECT(hbutton2), "tooltip-text", _("create a style from the current history stack"), (char *)NULL); d->create_button = hbutton2; /* add buttons to buttonbox */ gtk_box_pack_start(GTK_BOX(hhbox), hbutton, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hhbox), hbutton2, FALSE, FALSE, 0); /* add history list and buttonbox to widget */ gtk_box_pack_start(GTK_BOX(self->widget), d->history_box, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(self->widget), hhbox, FALSE, FALSE, 0); gtk_widget_show_all(self->widget); /* connect to history change signal for updating the history view */ dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_HISTORY_CHANGE, G_CALLBACK(_lib_history_change_callback), self); }
static void _lib_filmstrip_dnd_begin_callback(GtkWidget *widget, GdkDragContext *context, gpointer user_data) { const int ts = DT_PIXEL_APPLY_DPI(64); dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data; int imgid = strip->mouse_over_id; // imgid part of selection -> do nothing // otherwise -> select the current image strip->select = DT_LIB_FILMSTRIP_SELECT_NONE; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT imgid FROM main.selected_images WHERE imgid=?1 LIMIT 1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); if(sqlite3_step(stmt) != SQLITE_ROW) { dt_selection_select_single(darktable.selection, imgid); /* redraw filmstrip */ if(darktable.view_manager->proxy.filmstrip.module) gtk_widget_queue_draw(darktable.view_manager->proxy.filmstrip.module->widget); } sqlite3_finalize(stmt); // if we are dragging a single image -> use the thumbnail of that image // otherwise use the generic d&d icon // TODO: have something pretty in the 2nd case, too. if(dt_collection_get_selected_count(NULL) == 1) { dt_mipmap_buffer_t buf; dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size(darktable.mipmap_cache, ts, ts); dt_mipmap_cache_get(darktable.mipmap_cache, &buf, imgid, mip, DT_MIPMAP_BLOCKING, 'r'); if(buf.buf) { for(size_t i = 3; i < (size_t)4 * buf.width * buf.height; i += 4) buf.buf[i] = UINT8_MAX; int w = ts, h = ts; if(buf.width < buf.height) w = (buf.width * ts) / buf.height; // portrait else h = (buf.height * ts) / buf.width; // landscape GdkPixbuf *source = gdk_pixbuf_new_from_data(buf.buf, GDK_COLORSPACE_RGB, TRUE, 8, buf.width, buf.height, buf.width * 4, NULL, NULL); GdkPixbuf *scaled = gdk_pixbuf_scale_simple(source, w, h, GDK_INTERP_HYPER); gtk_drag_set_icon_pixbuf(context, scaled, 0, h); if(source) g_object_unref(source); if(scaled) g_object_unref(scaled); } dt_mipmap_cache_release(darktable.mipmap_cache, &buf); } }
/* http://nominatim.openstreetmap.org/search/norrköping?format=xml&limit=5 */ void gui_init(dt_lib_module_t *self) { self->data = calloc(1, sizeof(dt_lib_location_t)); dt_lib_location_t *lib = self->data; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5)); /* add search box */ lib->search = GTK_ENTRY(gtk_entry_new()); dt_gui_key_accel_block_on_focus_connect(GTK_WIDGET(lib->search)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(lib->search), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(lib->search), "activate", G_CALLBACK(_lib_location_entry_activated), (gpointer)self); /* add result vbox */ lib->result = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(10)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(lib->result), TRUE, FALSE, DT_PIXEL_APPLY_DPI(2)); }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_zonesystem_gui_data_t)); dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; g->in_preview_buffer = g->out_preview_buffer = NULL; g->is_dragging = FALSE; g->hilite_zone = FALSE; g->preview_width = g->preview_height = 0; g->mouse_over_output_zones = FALSE; dt_pthread_mutex_init(&g->lock, NULL); self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_IOP_MODULE_CONTROL_SPACING); g->preview = dtgtk_drawing_area_new_with_aspect_ratio(1.0); g_signal_connect(G_OBJECT(g->preview), "size-allocate", G_CALLBACK(size_allocate_callback), self); g_signal_connect(G_OBJECT(g->preview), "draw", G_CALLBACK(dt_iop_zonesystem_preview_draw), self); gtk_widget_add_events(GTK_WIDGET(g->preview), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK); /* create the zonesystem bar widget */ g->zones = gtk_drawing_area_new(); gtk_widget_set_tooltip_text(g->zones, _("lightness zones\nuse mouse scrollwheel to change the number of zones\n" "left-click on a border to create a marker\n" "right-click on a marker to delete it")); g_signal_connect(G_OBJECT(g->zones), "draw", G_CALLBACK(dt_iop_zonesystem_bar_draw), self); g_signal_connect(G_OBJECT(g->zones), "motion-notify-event", G_CALLBACK(dt_iop_zonesystem_bar_motion_notify), self); g_signal_connect(G_OBJECT(g->zones), "leave-notify-event", G_CALLBACK(dt_iop_zonesystem_bar_leave_notify), self); g_signal_connect(G_OBJECT(g->zones), "button-press-event", G_CALLBACK(dt_iop_zonesystem_bar_button_press), self); g_signal_connect(G_OBJECT(g->zones), "button-release-event", G_CALLBACK(dt_iop_zonesystem_bar_button_release), self); g_signal_connect(G_OBJECT(g->zones), "scroll-event", G_CALLBACK(dt_iop_zonesystem_bar_scrolled), self); gtk_widget_add_events(GTK_WIDGET(g->zones), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK); gtk_widget_set_size_request(g->zones, -1, DT_PIXEL_APPLY_DPI(40)); gtk_box_pack_start(GTK_BOX(self->widget), g->preview, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(self->widget), g->zones, TRUE, TRUE, 0); /* add signal handler for preview pipe finish to redraw the preview */ dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED, G_CALLBACK(_iop_zonesystem_redraw_preview_callback), self); g->image = NULL; g->image_buffer = NULL; g->image_width = 0; g->image_height = 0; }
static inline int gui_init_tab(struct dt_iop_module_t *self, int line, const char *name, GtkWidget **ppcolor, const GdkRGBA *c, GtkWidget **pphue, GtkWidget **ppsaturation) { GtkGrid *grid = GTK_GRID(self->widget); gtk_grid_attach(grid, dt_ui_section_label_new(name), 0, line++, 2, 1); // color button GtkWidget *color; *ppcolor = color = gtk_color_button_new_with_rgba(c); gtk_widget_set_size_request(GTK_WIDGET(color), DT_PIXEL_APPLY_DPI(32), DT_PIXEL_APPLY_DPI(32)); gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(color), FALSE); gtk_color_button_set_title(GTK_COLOR_BUTTON(color), _("select tone color")); // hue slider GtkWidget *hue; *pphue = hue = (dt_bauhaus_slider_new_with_range_and_feedback(self, 0.0f, 1.0f, 0.01f, 0.0f, 2, 0)); dt_bauhaus_slider_set_stop(hue, 0.0f, 1.0f, 0.0f, 0.0f); dt_bauhaus_widget_set_label(hue, NULL, _("hue")); dt_bauhaus_slider_set_stop(hue, 0.166f, 1.0f, 1.0f, 0.0f); dt_bauhaus_slider_set_stop(hue, 0.322f, 0.0f, 1.0f, 0.0f); dt_bauhaus_slider_set_stop(hue, 0.498f, 0.0f, 1.0f, 1.0f); dt_bauhaus_slider_set_stop(hue, 0.664f, 0.0f, 0.0f, 1.0f); dt_bauhaus_slider_set_stop(hue, 0.830f, 1.0f, 0.0f, 1.0f); dt_bauhaus_slider_set_stop(hue, 1.0f, 1.0f, 0.0f, 0.0f); g_object_set(G_OBJECT(hue), "tooltip-text", _("select the hue tone"), (char *)NULL); // saturation slider GtkWidget *saturation; *ppsaturation = saturation = dt_bauhaus_slider_new_with_range(self, 0.0f, 1.0f, 0.01f, 0.0f, 2); dt_bauhaus_widget_set_label(saturation, NULL, _("saturation")); dt_bauhaus_slider_set_stop(saturation, 0.0f, 0.2f, 0.2f, 0.2f); dt_bauhaus_slider_set_stop(saturation, 1.0f, 1.0f, 1.0f, 1.0f); g_object_set(G_OBJECT(saturation), "tooltip-text", _("select the saturation tone"), (char *)NULL); // pack the widgets gtk_widget_set_hexpand(hue, TRUE); // make sure that the color picker doesn't become HUGE gtk_grid_attach(grid, hue, 0, line, 1, 1); gtk_grid_attach(grid, color, 1, line++, 1, 2); gtk_grid_attach(grid, saturation, 0, line++, 1, 1); return line; }
void gui_init(dt_lib_module_t *self) { /* initialize ui widgets */ dt_lib_duplicate_t *d = (dt_lib_duplicate_t *)g_malloc0(sizeof(dt_lib_duplicate_t)); self->data = (void *)d; d->imgid = 0; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5)); gtk_widget_set_name(self->widget, "duplicate-ui"); GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(sw), DT_PIXEL_APPLY_DPI(300)); d->duplicate_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); GtkWidget *bt = gtk_label_new(_("existing duplicates")); gtk_box_pack_start(GTK_BOX(hb), bt, FALSE, FALSE, 0); bt = dtgtk_button_new(dtgtk_cairo_paint_plusminus, CPF_ACTIVE | CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER, NULL); g_object_set(G_OBJECT(bt), "tooltip-text", _("create a 'virgin' duplicate of the image without any developpement"), (char *)NULL); g_signal_connect(G_OBJECT(bt), "button-press-event", G_CALLBACK(_lib_duplicate_new_clicked_callback), self); gtk_box_pack_end(GTK_BOX(hb), bt, FALSE, FALSE, 0); bt = dtgtk_button_new(dtgtk_cairo_paint_multiinstance, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER, NULL); g_object_set(G_OBJECT(bt), "tooltip-text", _("create a duplicate of the image with same history stack"), (char *)NULL); g_signal_connect(G_OBJECT(bt), "button-press-event", G_CALLBACK(_lib_duplicate_duplicate_clicked_callback), self); gtk_box_pack_end(GTK_BOX(hb), bt, FALSE, FALSE, 0); /* add duplicate list and buttonbox to widget */ gtk_box_pack_start(GTK_BOX(self->widget), hb, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(sw), d->duplicate_box); gtk_box_pack_start(GTK_BOX(self->widget), sw, FALSE, FALSE, 0); gtk_widget_show_all(self->widget); dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_IMAGE_CHANGED, G_CALLBACK(_lib_duplicate_init_callback), self); dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_INITIALIZE, G_CALLBACK(_lib_duplicate_init_callback), self); dt_control_signal_connect(darktable.signals, DT_SIGNAL_COLLECTION_CHANGED, G_CALLBACK(_lib_duplicate_init_callback), self); dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_MIPMAP_UPDATED, G_CALLBACK(_lib_duplicate_mipmap_updated_callback), (gpointer)self); }
void gui_init(dt_lib_module_t *self) { /* initialize ui widgets */ dt_lib_modulelist_t *d = (dt_lib_modulelist_t *)g_malloc0(sizeof(dt_lib_modulelist_t)); self->data = (void *)d; self->widget = gtk_scrolled_window_new(NULL, NULL); //GTK_ADJUSTMENT(gtk_adjustment_new(200, 100, 200, 10, 100, 100)) gtk_widget_set_size_request(self->widget, -1, DT_PIXEL_APPLY_DPI(208)); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); d->tree = GTK_TREE_VIEW(gtk_tree_view_new()); gtk_widget_set_size_request(GTK_WIDGET(d->tree), DT_PIXEL_APPLY_DPI(50), -1); gtk_container_add(GTK_CONTAINER(self->widget), GTK_WIDGET(d->tree)); /* connect to signal for darktable.develop initialization */ dt_control_signal_connect(darktable.signals,DT_SIGNAL_DEVELOP_INITIALIZE,G_CALLBACK(_lib_modulelist_populate_callback),self); g_signal_connect(GTK_WIDGET(d->tree), "style-set", G_CALLBACK(_lib_modulelist_style_set), self); g_signal_connect(GTK_WIDGET(d->tree), "cursor-changed", G_CALLBACK(_lib_modulelist_row_changed_callback), NULL); darktable.view_manager->proxy.more_module.module = self; darktable.view_manager->proxy.more_module.update = _lib_modulelist_gui_update; }
static void _slider_size_request(GtkWidget *widget, GtkRequisition *requisition) { g_return_if_fail(widget != NULL); g_return_if_fail(DTGTK_IS_SLIDER(widget)); g_return_if_fail(requisition != NULL); GTK_WIDGET_CLASS(_slider_parent_class)->size_request(widget, requisition); requisition->width = DT_PIXEL_APPLY_DPI(100); requisition->height = DTGTK_SLIDER_CONTROL_MIN_HEIGHT; }
static void _lib_property_add_to_gui(dt_lib_camera_property_t *prop, dt_lib_camera_t *lib) { GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_PIXEL_APPLY_DPI(5)); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(prop->values), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(prop->osd), FALSE, FALSE, 0); gtk_grid_insert_row(lib->gui.main_grid, lib->gui.prop_end); // make space for the new row gtk_grid_attach(lib->gui.main_grid, GTK_WIDGET(hbox), 0, lib->gui.prop_end, 2, 1); g_signal_connect(G_OBJECT(prop->osd), "clicked", G_CALLBACK(_osd_button_clicked), prop); gtk_widget_show_all(GTK_WIDGET(hbox)); lib->gui.rows++; lib->gui.prop_end++; }
/* clean entries */ gtk_entry_set_text(GTK_ENTRY(lib->gui.plabel), ""); gtk_entry_set_text(GTK_ENTRY(lib->gui.pname), ""); } } } static void _toggle_capture_mode_clicked(GtkWidget *widget, gpointer user_data) { dt_lib_camera_t *lib = (dt_lib_camera_t *)user_data; GtkWidget *w = NULL; if(widget == GTK_WIDGET(lib->gui.tb1)) w = lib->gui.sb1; else if(widget == GTK_WIDGET(lib->gui.tb2)) w = lib->gui.sb2; else if(widget == GTK_WIDGET(lib->gui.tb3)) { gtk_widget_set_sensitive(lib->gui.sb3, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); gtk_widget_set_sensitive(lib->gui.sb4, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); } if(w) gtk_widget_set_sensitive(w, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); } #define BAR_HEIGHT DT_PIXEL_APPLY_DPI(18) /* also change in views/tethering.c */ static void _expose_info_bar(dt_lib_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_lib_camera_t *lib = (dt_lib_camera_t *)self->data; // Draw infobar background at top cairo_set_source_rgb(cr, .0, .0, .0); cairo_rectangle(cr, 0, 0, width, BAR_HEIGHT); cairo_fill(cr); cairo_set_source_rgb(cr, .8, .8, .8); // Draw left aligned value camera model value PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); const int fontsize = DT_PIXEL_APPLY_DPI(11.5); pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE); pango_layout_set_font_description(layout, desc); char model[4096] = { 0 }; sprintf(model + strlen(model), "%s", lib->data.camera_model); pango_layout_set_text(layout, model, -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, DT_PIXEL_APPLY_DPI(5), DT_PIXEL_APPLY_DPI(1) + BAR_HEIGHT - ink.height / 2 - fontsize); pango_cairo_show_layout(cr, layout); // Draw right aligned battery value const char *battery_value = dt_camctl_camera_get_property(darktable.camctl, NULL, "batterylevel"); char battery[4096] = { 0 }; snprintf(battery, sizeof(battery), "%s: %s", _("battery"), battery_value ? battery_value : _("n/a")); pango_layout_set_text(layout, battery, -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, width - ink.width - DT_PIXEL_APPLY_DPI(5), DT_PIXEL_APPLY_DPI(1) + BAR_HEIGHT - ink.height / 2 - fontsize); pango_cairo_show_layout(cr, layout); // Let's cook up the middle part of infobar gchar center[1024] = { 0 }; for(guint i = 0; i < g_list_length(lib->gui.properties); i++) { dt_lib_camera_property_t *prop = (dt_lib_camera_property_t *)g_list_nth_data(lib->gui.properties, i); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prop->osd)) == TRUE) { g_strlcat(center, " ", sizeof(center)); g_strlcat(center, prop->name, sizeof(center)); g_strlcat(center, ": ", sizeof(center)); g_strlcat(center, dt_bauhaus_combobox_get_text(prop->values), sizeof(center)); } } g_strlcat(center, " ", sizeof(center)); // Now lets put it in center view... pango_layout_set_text(layout, center, -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, (width / 2) - (ink.width / 2), DT_PIXEL_APPLY_DPI(1) + BAR_HEIGHT - ink.height / 2 - fontsize); pango_cairo_show_layout(cr, layout); pango_font_description_free(desc); g_object_unref(layout); }
void gui_init(dt_lib_module_t *self) { self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5)); self->data = calloc(1, sizeof(dt_lib_session_t)); // Setup lib data dt_lib_session_t *lib = self->data; // Setup gui self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5)); GtkBox *hbox, *vbox1, *vbox2; // Session settings hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_PIXEL_APPLY_DPI(5))); vbox1 = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5))); vbox2 = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5))); lib->gui.label1 = GTK_LABEL(gtk_label_new(_("jobcode"))); gtk_widget_set_halign(GTK_WIDGET(lib->gui.label1), GTK_ALIGN_START); gtk_box_pack_start(vbox1, GTK_WIDGET(lib->gui.label1), TRUE, TRUE, 0); lib->gui.entry1 = GTK_ENTRY(gtk_entry_new()); gtk_entry_set_width_chars(GTK_ENTRY(lib->gui.entry1), 0); dt_gui_key_accel_block_on_focus_connect(GTK_WIDGET(lib->gui.entry1)); gtk_box_pack_start(vbox2, GTK_WIDGET(lib->gui.entry1), TRUE, TRUE, 0); lib->gui.button1 = GTK_BUTTON(gtk_button_new_with_label(_("create"))); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox1), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox2), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(lib->gui.button1), TRUE, TRUE, 0); g_signal_connect(G_OBJECT(lib->gui.button1), "clicked", G_CALLBACK(create_callback), self); gchar *str = dt_conf_get_string("plugins/session/jobcode"); gtk_entry_set_text(lib->gui.entry1, str); g_free(str); }
void gui_post_expose(dt_lib_module_t *self, cairo_t *cri, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_lib_duplicate_t *d = (dt_lib_duplicate_t *)self->data; if (d->imgid == 0) return; const int32_t tb = DT_PIXEL_APPLY_DPI(dt_conf_get_int("plugins/darkroom/ui/border_size")); int nw = width-2*tb; int nh = height-2*tb; dt_mipmap_buffer_t buf; dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size(darktable.mipmap_cache, nw, nh); dt_mipmap_cache_get(darktable.mipmap_cache, &buf, d->imgid, mip, DT_MIPMAP_BEST_EFFORT, 'r'); int img_wd = buf.width; int img_ht = buf.height; dt_mipmap_cache_release(darktable.mipmap_cache, &buf); // and now we get the values to "fit the screen" int px,py,nimgw,nimgh; if (img_ht*nw > img_wd*nh) { nimgh = nh; nimgw = img_wd*nh/img_ht; py=0; px=(nw-nimgw)/2; } else { nimgw = nw; nimgh = img_ht*nw/img_wd; px=0; py=(nh-nimgh)/2; } // we erase everything cairo_set_source_rgb(cri, .2, .2, .2); cairo_paint(cri); //we draw the cached image dt_view_image_over_t image_over = DT_VIEW_DESERT; dt_view_image_expose(&image_over, d->imgid, cri, nw, nh, 1, px+tb, py+tb, TRUE, TRUE); //and the nice border line cairo_rectangle(cri, tb+px, tb+py, nimgw, nimgh); cairo_set_line_width(cri, 1.0); cairo_set_source_rgb(cri, .3, .3, .3); cairo_stroke(cri); }
void gui_init(dt_iop_module_t *self) { self->gui_data = g_malloc0(sizeof(dt_iop_invert_gui_data_t)); dt_iop_invert_gui_data_t *g = (dt_iop_invert_gui_data_t *)self->gui_data; dt_iop_invert_params_t *p = (dt_iop_invert_params_t *)self->params; self->widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); g->label = DTGTK_RESET_LABEL(dtgtk_reset_label_new("", self, &p->color, 4 * sizeof(float))); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->label), TRUE, TRUE, 0); g->pickerbuttons = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->pickerbuttons), TRUE, TRUE, 0); GdkRGBA color = (GdkRGBA){.red = p->color[0], .green = p->color[1], .blue = p->color[2], .alpha = 1.0 }; g->colorpicker = gtk_color_button_new_with_rgba(&color); gtk_widget_set_size_request(GTK_WIDGET(g->colorpicker), DT_PIXEL_APPLY_DPI(75), DT_PIXEL_APPLY_DPI(24)); gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(g->colorpicker), FALSE); gtk_color_button_set_title(GTK_COLOR_BUTTON(g->colorpicker), _("select color of film material")); g_signal_connect(G_OBJECT(g->colorpicker), "color-set", G_CALLBACK(colorpicker_callback), self); gtk_box_pack_start(GTK_BOX(g->pickerbuttons), GTK_WIDGET(g->colorpicker), TRUE, TRUE, 0); g->picker = dtgtk_togglebutton_new(dtgtk_cairo_paint_colorpicker, CPF_STYLE_FLAT); gtk_widget_set_tooltip_text(g->picker, _("pick color of film material from image")); gtk_widget_set_size_request(g->picker, DT_PIXEL_APPLY_DPI(24), DT_PIXEL_APPLY_DPI(24)); g_signal_connect(G_OBJECT(g->picker), "toggled", G_CALLBACK(request_pick_toggled), self); gtk_box_pack_start(GTK_BOX(g->pickerbuttons), g->picker, TRUE, TRUE, 5); g_signal_connect(G_OBJECT(self->widget), "draw", G_CALLBACK(draw), self); } void gui_cleanup(dt_iop_module_t *self) { g_free(self->gui_data); self->gui_data = NULL; }
void gui_init(dt_lib_module_t *self) { /* initialize ui widgets */ dt_lib_metadata_view_t *d = (dt_lib_metadata_view_t *)g_malloc0(sizeof(dt_lib_metadata_view_t)); self->data = (void *)d; _lib_metatdata_view_init_labels(); self->widget = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(self->widget), DT_PIXEL_APPLY_DPI(5)); // GtkWidget *last = NULL; /* initialize the metadata name/value labels */ for(int k = 0; k < md_size; k++) { GtkWidget *evb = gtk_event_box_new(); gtk_widget_set_name(evb, "brightbg"); GtkLabel *name = GTK_LABEL(gtk_label_new(_md_labels[k])); d->metadata[k] = GTK_LABEL(gtk_label_new("-")); gtk_label_set_selectable(d->metadata[k], TRUE); gtk_container_add(GTK_CONTAINER(evb), GTK_WIDGET(d->metadata[k])); if(k == md_internal_filmroll) { // film roll jump to: g_signal_connect(G_OBJECT(evb), "button-press-event", G_CALLBACK(_filmroll_clicked), NULL); } gtk_widget_set_halign(GTK_WIDGET(name), GTK_ALIGN_START); gtk_widget_set_halign(GTK_WIDGET(d->metadata[k]), GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(self->widget), GTK_WIDGET(name), 0, k, 1, 1); gtk_grid_attach_next_to(GTK_GRID(self->widget), GTK_WIDGET(evb), GTK_WIDGET(name), GTK_POS_RIGHT, 1, 1); } /* lets signup for mouse over image change signals */ dt_control_signal_connect(darktable.signals, DT_SIGNAL_MOUSE_OVER_IMAGE_CHANGE, G_CALLBACK(_mouse_over_image_callback), self); /* lets signup for develop image changed signals */ dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_IMAGE_CHANGED, G_CALLBACK(_mouse_over_image_callback), self); /* signup for develop initialize to update info of current image in darkroom when enter */ dt_control_signal_connect(darktable.signals, DT_SIGNAL_DEVELOP_INITIALIZE, G_CALLBACK(_mouse_over_image_callback), self); }
static gboolean dt_iop_colorcorrection_motion_notify(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_colorcorrection_gui_data_t *g = (dt_iop_colorcorrection_gui_data_t *)self->gui_data; dt_iop_colorcorrection_params_t *p = (dt_iop_colorcorrection_params_t *)self->params; const int inset = DT_COLORCORRECTION_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width - 2 * inset, height = allocation.height - 2 * inset; const float mouse_x = CLAMP(event->x - inset, 0, width); const float mouse_y = CLAMP(height - 1 - event->y + inset, 0, height); const float ma = (2.0 * mouse_x - width) * DT_COLORCORRECTION_MAX / (float)width; const float mb = (2.0 * mouse_y - height) * DT_COLORCORRECTION_MAX / (float)height; if(event->state & GDK_BUTTON1_MASK) { if(g->selected == 1) { p->loa = ma; p->lob = mb; dt_dev_add_history_item(darktable.develop, self, TRUE); } else if(g->selected == 2) { p->hia = ma; p->hib = mb; dt_dev_add_history_item(darktable.develop, self, TRUE); } } else { g->selected = 0; const float thrs = DT_PIXEL_APPLY_DPI(5.0f); const float distlo = (p->loa - ma) * (p->loa - ma) + (p->lob - mb) * (p->lob - mb); const float disthi = (p->hia - ma) * (p->hia - ma) + (p->hib - mb) * (p->hib - mb); if(distlo < thrs * thrs && distlo < disthi) g->selected = 1; else if(disthi < thrs * thrs && disthi <= distlo) g->selected = 2; } gtk_widget_queue_draw(self->widget); return TRUE; }
/** Add a new property of camera to the gui */ dt_lib_camera_property_t *_lib_property_add_new(dt_lib_camera_t *lib, const gchar *label, const gchar *propertyname) { if(dt_camctl_camera_property_exists(darktable.camctl, NULL, propertyname)) { const char *value; if((value = dt_camctl_camera_property_get_first_choice(darktable.camctl, NULL, propertyname)) != NULL) { // We got a value for property lets construct the gui for the property and add values int i = 0; const char *current_value = dt_camctl_camera_get_property(darktable.camctl, NULL, propertyname); dt_lib_camera_property_t *prop = calloc(1, sizeof(dt_lib_camera_property_t)); prop->name = strdup(label); prop->property_name = strdup(propertyname); prop->values = dt_bauhaus_combobox_new(NULL); dt_bauhaus_widget_set_label(prop->values, NULL, label); g_object_ref_sink(prop->values); prop->osd = DTGTK_TOGGLEBUTTON(dtgtk_togglebutton_new(dtgtk_cairo_paint_eye, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER)); g_object_ref_sink(prop->osd); gtk_widget_set_size_request(GTK_WIDGET(prop->osd), DT_PIXEL_APPLY_DPI(14), -1); g_object_set(G_OBJECT(prop->osd), "tooltip-text", _("toggle view property in center view"), (char *)NULL); do { dt_bauhaus_combobox_add(prop->values, g_dgettext("libgphoto2-2", value)); if(!strcmp(current_value, g_dgettext("libgphoto2-2", value))) dt_bauhaus_combobox_set(prop->values, i); i++; } while((value = dt_camctl_camera_property_get_next_choice(darktable.camctl, NULL, propertyname)) != NULL); lib->gui.properties = g_list_append(lib->gui.properties, prop); // Does dead lock!!! g_signal_connect(G_OBJECT(prop->values), "value-changed", G_CALLBACK(property_changed_callback), (gpointer)prop); return prop; } } return NULL; }
void gui_init(dt_lib_module_t *self) { /* initialize ui widgets */ dt_lib_tool_preferences_t *d = (dt_lib_tool_preferences_t *)g_malloc0(sizeof(dt_lib_tool_preferences_t)); self->data = (void *)d; self->widget = gtk_hbox_new(FALSE,2); /* create the grouping button */ d->grouping_button = dtgtk_togglebutton_new(dtgtk_cairo_paint_grouping, CPF_STYLE_FLAT); gtk_widget_set_size_request(d->grouping_button, DT_PIXEL_APPLY_DPI(18), DT_PIXEL_APPLY_DPI(18)); gtk_box_pack_start(GTK_BOX(self->widget), d->grouping_button, FALSE, FALSE, 2); if(darktable.gui->grouping) g_object_set(G_OBJECT(d->grouping_button), "tooltip-text", _("expand grouped images"), (char *)NULL); else g_object_set(G_OBJECT(d->grouping_button), "tooltip-text", _("collapse grouped images"), (char *)NULL); g_signal_connect (G_OBJECT (d->grouping_button), "clicked", G_CALLBACK (_lib_filter_grouping_button_clicked), NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d->grouping_button), darktable.gui->grouping); /* create the "show/hide overlays" button */ d->overlays_button = dtgtk_togglebutton_new(dtgtk_cairo_paint_overlays, CPF_STYLE_FLAT); gtk_widget_set_size_request(d->overlays_button, DT_PIXEL_APPLY_DPI(18), DT_PIXEL_APPLY_DPI(18)); gtk_box_pack_start(GTK_BOX(self->widget), d->overlays_button, FALSE, FALSE, 2); if(darktable.gui->show_overlays) g_object_set(G_OBJECT(d->overlays_button), "tooltip-text", _("hide image overlays"), (char *)NULL); else g_object_set(G_OBJECT(d->overlays_button), "tooltip-text", _("show image overlays"), (char *)NULL); g_signal_connect (G_OBJECT (d->overlays_button), "clicked", G_CALLBACK (_lib_overlays_button_clicked), NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d->overlays_button), darktable.gui->show_overlays); /* create the preference button */ d->preferences_button = dtgtk_button_new(dtgtk_cairo_paint_preferences, CPF_STYLE_FLAT); gtk_widget_set_size_request(d->preferences_button, DT_PIXEL_APPLY_DPI(18), DT_PIXEL_APPLY_DPI(18)); gtk_box_pack_end(GTK_BOX(self->widget), d->preferences_button, FALSE, FALSE, 2); g_object_set(G_OBJECT(d->preferences_button), "tooltip-text", _("show global preferences"), (char *)NULL); g_signal_connect (G_OBJECT (d->preferences_button), "clicked", G_CALLBACK (_lib_preferences_button_clicked), NULL); }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_watermark_gui_data_t)); dt_iop_watermark_gui_data_t *g = (dt_iop_watermark_gui_data_t *)self->gui_data; dt_iop_watermark_params_t *p = (dt_iop_watermark_params_t *)self->params; int line = 0; self->widget = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(self->widget), DT_BAUHAUS_SPACE); gtk_grid_set_column_spacing(GTK_GRID(self->widget), DT_PIXEL_APPLY_DPI(10)); gtk_grid_attach(GTK_GRID(self->widget), dt_ui_section_label_new(_("content")), 0, line++, 3, 1); // Add the marker combobox gchar configdir[PATH_MAX] = { 0 }; gchar datadir[PATH_MAX] = { 0 }; dt_loc_get_datadir(datadir, sizeof(datadir)); dt_loc_get_user_config_dir(configdir, sizeof(configdir)); GtkWidget *label = dtgtk_reset_label_new(_("marker"), self, &p->filename, sizeof(p->filename)); g->watermarks = dt_bauhaus_combobox_new(self); gtk_widget_set_hexpand(GTK_WIDGET(g->watermarks), TRUE); char *tooltip = g_strdup_printf(_("SVG watermarks in %s/watermarks or %s/watermarks"), configdir, datadir); gtk_widget_set_tooltip_text(g->watermarks, tooltip); g_free(tooltip); g->refresh = dtgtk_button_new(dtgtk_cairo_paint_refresh, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); gtk_grid_attach(GTK_GRID(self->widget), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(self->widget), g->watermarks, label, GTK_POS_RIGHT, 1, 1); gtk_grid_attach_next_to(GTK_GRID(self->widget), g->refresh, g->watermarks, GTK_POS_RIGHT, 1, 1); // Watermark color float red = dt_conf_get_float("plugins/darkroom/watermark/color_red"); float green = dt_conf_get_float("plugins/darkroom/watermark/color_green"); float blue = dt_conf_get_float("plugins/darkroom/watermark/color_blue"); GdkRGBA color = (GdkRGBA){.red = red, .green = green, .blue = blue, .alpha = 1.0 }; label = dtgtk_reset_label_new(_("color"), self, &p->color, 3 * sizeof(float)); g->colorpick = gtk_color_button_new_with_rgba(&color); gtk_widget_set_tooltip_text(g->colorpick, _("watermark color, tag:\n$(WATERMARK_COLOR)")); gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(g->colorpick), FALSE); gtk_widget_set_size_request(GTK_WIDGET(g->colorpick), DT_PIXEL_APPLY_DPI(24), DT_PIXEL_APPLY_DPI(24)); gtk_color_button_set_title(GTK_COLOR_BUTTON(g->colorpick), _("select watermark color")); gtk_grid_attach(GTK_GRID(self->widget), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(self->widget), g->colorpick, label, GTK_POS_RIGHT, 2, 1); // Simple text label = gtk_label_new(_("text")); gtk_widget_set_halign(label, GTK_ALIGN_START); g->text = gtk_entry_new(); gtk_entry_set_width_chars(GTK_ENTRY(g->text), 1); gtk_widget_set_tooltip_text(g->text, _("text string, tag:\n$(WATERMARK_TEXT)")); dt_gui_key_accel_block_on_focus_connect(g->text); gtk_grid_attach(GTK_GRID(self->widget), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(self->widget), g->text, label, GTK_POS_RIGHT, 2, 1); gchar *str = dt_conf_get_string("plugins/darkroom/watermark/text"); gtk_entry_set_text(GTK_ENTRY(g->text), str); g_free(str); // Text font label = dtgtk_reset_label_new(_("font"), self, &p->font, sizeof(p->font)); str = dt_conf_get_string("plugins/darkroom/watermark/font"); g->fontsel = gtk_font_button_new_with_font(str==NULL?"DejaVu Sans 10":str); GList *childs = gtk_container_get_children(GTK_CONTAINER(gtk_bin_get_child(GTK_BIN(g->fontsel)))); gtk_label_set_ellipsize(GTK_LABEL(childs->data), PANGO_ELLIPSIZE_MIDDLE); g_list_free(childs); gtk_widget_set_tooltip_text(g->fontsel, _("text font, tags:\n$(WATERMARK_FONT_FAMILY)\n" "$(WATERMARK_FONT_STYLE)\n$(WATERMARK_FONT_WEIGHT)")); gtk_font_button_set_show_size (GTK_FONT_BUTTON(g->fontsel), FALSE); g_free(str); gtk_grid_attach(GTK_GRID(self->widget), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(self->widget), g->fontsel, label, GTK_POS_RIGHT, 2, 1); gtk_grid_attach(GTK_GRID(self->widget), dt_ui_section_label_new(_("properties")), 0, line++, 3, 1); // Add opacity/scale sliders to table g->opacity = dt_bauhaus_slider_new_with_range(self, 0.0, 100.0, 1.0, p->opacity, 0); dt_bauhaus_slider_set_format(g->opacity, "%.f%%"); dt_bauhaus_widget_set_label(g->opacity, NULL, _("opacity")); g->scale = dt_bauhaus_slider_new_with_range(self, 1.0, 100.0, 1.0, p->scale, 0); dt_bauhaus_slider_enable_soft_boundaries(g->scale, 1.0, 500.0); dt_bauhaus_slider_set_format(g->scale, "%.f%%"); dt_bauhaus_widget_set_label(g->scale, NULL, _("scale")); g->rotate = dt_bauhaus_slider_new_with_range(self, -180.0, 180.0, 1.0, p->rotate, 2); dt_bauhaus_slider_set_format(g->rotate, "%.02f°"); dt_bauhaus_widget_set_label(g->rotate, NULL, _("rotation")); gtk_grid_attach(GTK_GRID(self->widget), g->opacity, 0, line++, 3, 1); gtk_grid_attach(GTK_GRID(self->widget), g->scale, 0, line++, 3, 1); gtk_grid_attach(GTK_GRID(self->widget), g->rotate, 0, line++, 3, 1); g->sizeto = dt_bauhaus_combobox_new(self); dt_bauhaus_combobox_add(g->sizeto, C_("size", "image")); dt_bauhaus_combobox_add(g->sizeto, _("larger border")); dt_bauhaus_combobox_add(g->sizeto, _("smaller border")); dt_bauhaus_combobox_set(g->sizeto, p->sizeto); dt_bauhaus_widget_set_label(g->sizeto, NULL, _("scale on")); gtk_widget_set_tooltip_text(g->sizeto, _("size is relative to")); gtk_grid_attach(GTK_GRID(self->widget), g->sizeto, 0, line++, 3, 1); gtk_grid_attach(GTK_GRID(self->widget), dt_ui_section_label_new(_("position")), 0, line++, 3, 1); // Create the 3x3 gtk table toggle button table... label = dtgtk_reset_label_new(_("alignment"), self, &p->alignment, sizeof(p->alignment)); GtkWidget *bat = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(bat), DT_PIXEL_APPLY_DPI(3)); gtk_grid_set_column_spacing(GTK_GRID(bat), DT_PIXEL_APPLY_DPI(3)); for(int i = 0; i < 9; i++) { g->align[i] = dtgtk_togglebutton_new(dtgtk_cairo_paint_alignment, CPF_STYLE_FLAT | (CPF_SPECIAL_FLAG << i)); gtk_widget_set_size_request(GTK_WIDGET(g->align[i]), DT_PIXEL_APPLY_DPI(16), DT_PIXEL_APPLY_DPI(16)); gtk_grid_attach(GTK_GRID(bat), GTK_WIDGET(g->align[i]), i%3, i/3, 1, 1); g_signal_connect(G_OBJECT(g->align[i]), "toggled", G_CALLBACK(alignment_callback), self); } gtk_grid_attach(GTK_GRID(self->widget), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(self->widget), bat, label, GTK_POS_RIGHT, 2, 1); // x/y offset g->x_offset = dt_bauhaus_slider_new_with_range(self, -1.0, 1.0, 0.001, p->xoffset, 3); dt_bauhaus_slider_set_format(g->x_offset, "%.3f"); dt_bauhaus_widget_set_label(g->x_offset, NULL, _("x offset")); g->y_offset = dt_bauhaus_slider_new_with_range(self, -1.0, 1.0, 0.001, p->yoffset, 3); dt_bauhaus_slider_set_format(g->y_offset, "%.3f"); dt_bauhaus_widget_set_label(g->y_offset, NULL, _("y offset")); gtk_grid_attach(GTK_GRID(self->widget), g->x_offset, 0, line++, 3, 1); gtk_grid_attach(GTK_GRID(self->widget), g->y_offset, 0, line++, 3, 1); // Let's add some tooltips and hook up some signals... gtk_widget_set_tooltip_text(g->opacity, _("the opacity of the watermark")); gtk_widget_set_tooltip_text(g->scale, _("the scale of the watermark")); gtk_widget_set_tooltip_text(g->rotate, _("the rotation of the watermark")); g_signal_connect(G_OBJECT(g->opacity), "value-changed", G_CALLBACK(opacity_callback), self); g_signal_connect(G_OBJECT(g->scale), "value-changed", G_CALLBACK(scale_callback), self); g_signal_connect(G_OBJECT(g->rotate), "value-changed", G_CALLBACK(rotate_callback), self); g_signal_connect(G_OBJECT(g->x_offset), "value-changed", G_CALLBACK(xoffset_callback), self); g_signal_connect(G_OBJECT(g->y_offset), "value-changed", G_CALLBACK(yoffset_callback), self); g_signal_connect(G_OBJECT(g->refresh), "clicked", G_CALLBACK(refresh_callback), self); refresh_watermarks(self); g_signal_connect(G_OBJECT(g->watermarks), "value-changed", G_CALLBACK(watermark_callback), self); g_signal_connect(G_OBJECT(g->sizeto), "value-changed", G_CALLBACK(sizeto_callback), self); g_signal_connect(G_OBJECT(g->text), "changed", G_CALLBACK(text_callback), self); g_signal_connect(G_OBJECT(g->colorpick), "color-set", G_CALLBACK(colorpick_color_set), self); g_signal_connect(G_OBJECT(g->fontsel), "font-set", G_CALLBACK(fontsel_callback), self); } void gui_cleanup(struct dt_iop_module_t *self) { free(self->gui_data); self->gui_data = NULL; }
void *dt_control_expose(void *voidptr) { int width, height, pointerx, pointery; if(!darktable.gui->surface) return NULL; width = dt_cairo_image_surface_get_width(darktable.gui->surface); height = dt_cairo_image_surface_get_height(darktable.gui->surface); GtkWidget *widget = dt_ui_center(darktable.gui->ui); GdkDevice *device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(widget))); gdk_window_get_device_position(gtk_widget_get_window(widget), device, &pointerx, &pointery, NULL); // create a gtk-independent surface to draw on cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // TODO: control_expose: only redraw the part not overlapped by temporary control panel show! // float tb = 8; // fmaxf(10, width/100.0); darktable.control->tabborder = tb; darktable.control->width = width; darktable.control->height = height; GdkRGBA color; GtkStyleContext *context = gtk_widget_get_style_context(widget); gboolean color_found = gtk_style_context_lookup_color (context, "bg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_set_line_width(cr, tb); cairo_rectangle(cr, tb / 2., tb / 2., width - tb, height - tb); cairo_stroke(cr); cairo_set_line_width(cr, 1.5); color_found = gtk_style_context_lookup_color (context, "really_dark_bg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_rectangle(cr, tb, tb, width - 2 * tb, height - 2 * tb); cairo_stroke(cr); cairo_save(cr); cairo_translate(cr, tb, tb); cairo_rectangle(cr, 0, 0, width - 2 * tb, height - 2 * tb); cairo_clip(cr); cairo_new_path(cr); // draw view dt_view_manager_expose(darktable.view_manager, cr, width - 2 * tb, height - 2 * tb, pointerx - tb, pointery - tb); cairo_restore(cr); // draw log message, if any dt_pthread_mutex_lock(&darktable.control->log_mutex); if(darktable.control->log_ack != darktable.control->log_pos) { PangoRectangle ink; PangoLayout *layout; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); const float fontsize = DT_PIXEL_APPLY_DPI(14); pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, desc); pango_layout_set_text(layout, darktable.control->log_message[darktable.control->log_ack], -1); pango_layout_get_pixel_extents(layout, &ink, NULL); const float pad = DT_PIXEL_APPLY_DPI(20.0f), xc = width / 2.0; const float yc = height * 0.85 + DT_PIXEL_APPLY_DPI(10), wd = pad + ink.width * .5f; float rad = DT_PIXEL_APPLY_DPI(14); cairo_set_line_width(cr, 1.); cairo_move_to(cr, xc - wd, yc + rad); for(int k = 0; k < 5; k++) { cairo_arc(cr, xc - wd, yc, rad, M_PI / 2.0, 3.0 / 2.0 * M_PI); cairo_line_to(cr, xc + wd, yc - rad); cairo_arc(cr, xc + wd, yc, rad, 3.0 * M_PI / 2.0, M_PI / 2.0); cairo_line_to(cr, xc - wd, yc + rad); if(k == 0) { color_found = gtk_style_context_lookup_color (context, "selected_bg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_fill_preserve(cr); } cairo_set_source_rgba(cr, 0., 0., 0., 1.0 / (1 + k)); cairo_stroke(cr); rad += .5f; } color_found = gtk_style_context_lookup_color (context, "fg_color", &color); if(!color_found) { color.red = 1.0; color.green = 0.0; color.blue = 0.0; color.alpha = 1.0; } gdk_cairo_set_source_rgba(cr, &color); cairo_move_to(cr, xc - wd + .5f * pad, (yc + 1. / 3. * fontsize) - fontsize); pango_cairo_show_layout(cr, layout); pango_font_description_free(desc); g_object_unref(layout); } // draw busy indicator if(darktable.control->log_busy > 0) { PangoRectangle ink; PangoLayout *layout; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); const float fontsize = DT_PIXEL_APPLY_DPI(14); pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, desc); pango_layout_set_text(layout, _("working.."), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); const float xc = width / 2.0, yc = height * 0.85 - DT_PIXEL_APPLY_DPI(30), wd = ink.width * .5f; cairo_move_to(cr, xc - wd, yc + 1. / 3. * fontsize - fontsize); pango_cairo_layout_path(cr, layout); cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_fill_preserve(cr); cairo_set_line_width(cr, 0.7); cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_stroke(cr); pango_font_description_free(desc); g_object_unref(layout); } dt_pthread_mutex_unlock(&darktable.control->log_mutex); cairo_destroy(cr); cairo_t *cr_pixmap = cairo_create(darktable.gui->surface); cairo_set_source_surface(cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return NULL; }
static gboolean _lib_histogram_draw_callback(GtkWidget *widget, cairo_t *crf, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_histogram_t *d = (dt_lib_histogram_t *)self->data; dt_develop_t *dev = darktable.develop; uint32_t *hist = dev->histogram; float hist_max = dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR ? dev->histogram_max : logf(1.0 + dev->histogram_max); const int inset = DT_HIST_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); gtk_render_background(gtk_widget_get_style_context(widget), cr, 0, 0, allocation.width, allocation.height); cairo_translate(cr, 4 * inset, inset); width -= 2 * 4 * inset; height -= 2 * inset; if(d->mode_x == 0) { d->color_w = 0.06 * width; d->button_spacing = 0.01 * width; d->button_h = 0.06 * width; d->button_y = d->button_spacing; d->mode_w = d->color_w; d->mode_x = width - 3 * (d->color_w + d->button_spacing) - (d->mode_w + d->button_spacing); d->red_x = width - 3 * (d->color_w + d->button_spacing); d->green_x = width - 2 * (d->color_w + d->button_spacing); d->blue_x = width - (d->color_w + d->button_spacing); } // TODO: probably this should move to the configure-event callback! That would be future proof if we ever // (again) allow to resize the side panels. const gint stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); // this code assumes that the first expose comes before the first (preview) pipe is processed and that the // size of the widget doesn't change! if(dev->histogram_waveform_width == 0) { dev->histogram_waveform = (uint32_t *)calloc(height * stride / 4, sizeof(uint32_t)); dev->histogram_waveform_stride = stride; dev->histogram_waveform_height = height; dev->histogram_waveform_width = width; // return TRUE; // there are enough expose events following ... } #if 1 // draw shadow around float alpha = 1.0f; cairo_set_line_width(cr, 0.2); for(int k = 0; k < inset; k++) { cairo_rectangle(cr, -k, -k, width + 2 * k, height + 2 * k); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.5f; cairo_fill(cr); } cairo_set_line_width(cr, 1.0); #else 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); #endif cairo_rectangle(cr, 0, 0, width, height); cairo_clip(cr); cairo_set_source_rgb(cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); if(d->highlight == 1) { cairo_set_source_rgb(cr, .5, .5, .5); cairo_rectangle(cr, 0, 0, .2 * width, height); cairo_fill(cr); } else if(d->highlight == 2) { cairo_set_source_rgb(cr, .5, .5, .5); cairo_rectangle(cr, 0.2 * width, 0, width, height); cairo_fill(cr); } // draw grid cairo_set_line_width(cr, .4); cairo_set_source_rgb(cr, .1, .1, .1); if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM) dt_draw_waveform_lines(cr, 0, 0, width, height); else dt_draw_grid(cr, 4, 0, 0, width, height); if(hist_max > 0.0f) { cairo_save(cr); if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM) { // make the color channel selector work: uint8_t *buf = (uint8_t *)malloc(sizeof(uint8_t) * height * stride); uint8_t mask[3] = { d->blue, d->green, d->red }; memcpy(buf, dev->histogram_waveform, sizeof(uint8_t) * height * stride); for(int y = 0; y < height; y++) for(int x = 0; x < width; x++) for(int k = 0; k < 3; k++) { buf[y * stride + x * 4 + k] *= mask[k]; } cairo_surface_t *source = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32, width, height, stride); cairo_set_source_surface(cr, source, 0.0, 0.0); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); cairo_paint(cr); cairo_surface_destroy(source); free(buf); } else { // cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); cairo_translate(cr, 0, height); cairo_scale(cr, width / 63.0, -(height - 10) / hist_max); cairo_set_operator(cr, CAIRO_OPERATOR_ADD); // cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_line_width(cr, 1.); if(d->red) { cairo_set_source_rgba(cr, 1., 0., 0., 0.2); dt_draw_histogram_8(cr, hist, 0, dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR); } if(d->green) { cairo_set_source_rgba(cr, 0., 1., 0., 0.2); dt_draw_histogram_8(cr, hist, 1, dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR); } if(d->blue) { cairo_set_source_rgba(cr, 0., 0., 1., 0.2); dt_draw_histogram_8(cr, hist, 2, dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR); } cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); } cairo_restore(cr); } cairo_set_source_rgb(cr, .25, .25, .25); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); pango_font_description_set_absolute_size(desc, .1 * height * PANGO_SCALE); pango_layout_set_font_description(layout, desc); char exifline[50]; dt_image_print_exif(&dev->image_storage, exifline, 50); pango_layout_set_text(layout, exifline, -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .02 * width, .98 * height - ink.height - ink.y); cairo_save(cr); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0)); cairo_set_source_rgba(cr, 1, 1, 1, 0.3); pango_cairo_layout_path(cr, layout); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, .25, .25, .25); cairo_fill(cr); cairo_restore(cr); // buttons to control the display of the histogram: linear/log, r, g, b if(d->highlight != 0) { _draw_mode_toggle(cr, d->mode_x, d->button_y, d->mode_w, d->button_h, dev->histogram_type); cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4); _draw_color_toggle(cr, d->red_x, d->button_y, d->color_w, d->button_h, d->red); cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.4); _draw_color_toggle(cr, d->green_x, d->button_y, d->color_w, d->button_h, d->green); cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 0.4); _draw_color_toggle(cr, d->blue_x, d->button_y, d->color_w, d->button_h, d->blue); } cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); pango_font_description_free(desc); g_object_unref(layout); return TRUE; }
void gui_init(dt_lib_module_t *self) { unsigned int i; GtkWidget *container = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5)); GtkWidget *output_row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_PIXEL_APPLY_DPI(5)); GtkWidget *output_options = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(5)); GtkWidget *picker_subrow = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_PIXEL_APPLY_DPI(2)); GtkWidget *restrict_button; GtkWidget *samples_label = dt_ui_section_label_new(_("live samples")); GtkWidget *samples_options_row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_PIXEL_APPLY_DPI(2)); // Initializing self data structure dt_lib_colorpicker_t *data = (dt_lib_colorpicker_t *)calloc(1, sizeof(dt_lib_colorpicker_t)); self->data = (void *)data; data->rgb.red = 0.7; data->rgb.green = 0.7; data->rgb.blue = 0.7; data->rgb.alpha = 1.0; // Initializing proxy functions and data darktable.lib->proxy.colorpicker.module = self; darktable.lib->proxy.colorpicker.size = dt_conf_get_int("ui_last/colorpicker_size"); darktable.lib->proxy.colorpicker.display_samples = dt_conf_get_int("ui_last/colorpicker_display_samples"); darktable.lib->proxy.colorpicker.live_samples = NULL; darktable.lib->proxy.colorpicker.picked_color_rgb_mean = (uint8_t *)malloc(sizeof(uint8_t) * 3); darktable.lib->proxy.colorpicker.picked_color_rgb_min = (uint8_t *)malloc(sizeof(uint8_t) * 3); darktable.lib->proxy.colorpicker.picked_color_rgb_max = (uint8_t *)malloc(sizeof(uint8_t) * 3); darktable.lib->proxy.colorpicker.picked_color_lab_mean = (float *)malloc(sizeof(float) * 3); darktable.lib->proxy.colorpicker.picked_color_lab_min = (float *)malloc(sizeof(float) * 3); darktable.lib->proxy.colorpicker.picked_color_lab_max = (float *)malloc(sizeof(float) * 3); for(i = 0; i < 3; i++) darktable.lib->proxy.colorpicker.picked_color_rgb_mean[i] = darktable.lib->proxy.colorpicker.picked_color_rgb_min[i] = darktable.lib->proxy.colorpicker.picked_color_rgb_max[i] = 0; for(i = 0; i < 3; i++) darktable.lib->proxy.colorpicker.picked_color_lab_mean[i] = darktable.lib->proxy.colorpicker.picked_color_lab_min[i] = darktable.lib->proxy.colorpicker.picked_color_lab_max[i] = 0; darktable.lib->proxy.colorpicker.update_panel = _update_picker_output; darktable.lib->proxy.colorpicker.update_samples = _update_samples_output; darktable.lib->proxy.colorpicker.set_sample_area = _set_sample_area; darktable.lib->proxy.colorpicker.set_sample_point = _set_sample_point; // Setting up the GUI self->widget = container; gtk_box_pack_start(GTK_BOX(container), output_row, TRUE, TRUE, 0); // The color patch data->color_patch = gtk_drawing_area_new(); gtk_widget_set_size_request(data->color_patch, DT_PIXEL_APPLY_DPI(100), DT_PIXEL_APPLY_DPI(100)); g_signal_connect(G_OBJECT(data->color_patch), "draw", G_CALLBACK(main_draw_callback), data); gtk_box_pack_start(GTK_BOX(output_row), data->color_patch, FALSE, FALSE, 0); // The picker button, output selectors and label gtk_box_pack_start(GTK_BOX(output_row), output_options, TRUE, TRUE, 0); data->size_selector = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->size_selector), _("point")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->size_selector), _("area")); gtk_combo_box_set_active(GTK_COMBO_BOX(data->size_selector), dt_conf_get_int("ui_last/colorpicker_size")); gtk_widget_set_size_request(data->size_selector, DT_PIXEL_APPLY_DPI(30), -1); gtk_box_pack_start(GTK_BOX(picker_subrow), data->size_selector, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(data->size_selector), "changed", G_CALLBACK(_size_changed), (gpointer)self); data->picker_button = dtgtk_togglebutton_new(dtgtk_cairo_paint_colorpicker, CPF_STYLE_BOX); gtk_widget_set_size_request(data->picker_button, DT_PIXEL_APPLY_DPI(50), -1); gtk_box_pack_start(GTK_BOX(picker_subrow), data->picker_button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(data->picker_button), "toggled", G_CALLBACK(_picker_button_toggled), self); gtk_box_pack_start(GTK_BOX(output_options), picker_subrow, TRUE, TRUE, 0); data->statistic_selector = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->statistic_selector), _("mean")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->statistic_selector), _("min")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->statistic_selector), _("max")); gtk_combo_box_set_active(GTK_COMBO_BOX(data->statistic_selector), dt_conf_get_int("ui_last/colorpicker_mode")); gtk_widget_set_sensitive(data->statistic_selector, dt_conf_get_int("ui_last/colorpicker_size")); gtk_box_pack_start(GTK_BOX(output_options), data->statistic_selector, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(data->statistic_selector), "changed", G_CALLBACK(_statistic_changed), self); data->color_mode_selector = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->color_mode_selector), _("RGB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->color_mode_selector), _("Lab")); gtk_combo_box_set_active(GTK_COMBO_BOX(data->color_mode_selector), dt_conf_get_int("ui_last/colorpicker_model")); gtk_box_pack_start(GTK_BOX(output_options), data->color_mode_selector, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(data->color_mode_selector), "changed", G_CALLBACK(_color_mode_changed), self); data->output_label = gtk_label_new(""); gtk_label_set_justify(GTK_LABEL(data->output_label), GTK_JUSTIFY_CENTER); gtk_widget_set_size_request(data->output_label, DT_PIXEL_APPLY_DPI(80), -1); gtk_box_pack_start(GTK_BOX(output_options), data->output_label, FALSE, FALSE, 0); restrict_button = gtk_check_button_new_with_label(_("restrict histogram to selection")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(restrict_button), dt_conf_get_int("ui_last/colorpicker_restrict_histogram")); darktable.lib->proxy.colorpicker.restrict_histogram = dt_conf_get_int("ui_last/colorpicker_restrict_histogram"); gtk_box_pack_start(GTK_BOX(container), restrict_button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(restrict_button), "toggled", G_CALLBACK(_restrict_histogram_changed), NULL); // Adding the live samples section gtk_box_pack_start(GTK_BOX(container), samples_label, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(container), samples_options_row, TRUE, TRUE, 0); data->samples_statistic_selector = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->samples_statistic_selector), _("mean")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->samples_statistic_selector), _("min")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->samples_statistic_selector), _("max")); gtk_combo_box_set_active(GTK_COMBO_BOX(data->samples_statistic_selector), dt_conf_get_int("ui_last/colorsamples_mode")); gtk_box_pack_start(GTK_BOX(samples_options_row), data->samples_statistic_selector, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(data->samples_statistic_selector), "changed", G_CALLBACK(_samples_statistic_changed), self); data->samples_mode_selector = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->samples_mode_selector), _("RGB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(data->samples_mode_selector), _("Lab")); gtk_combo_box_set_active(GTK_COMBO_BOX(data->samples_mode_selector), dt_conf_get_int("ui_last/colorsamples_model")); gtk_box_pack_start(GTK_BOX(samples_options_row), data->samples_mode_selector, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(data->samples_mode_selector), "changed", G_CALLBACK(_samples_mode_changed), self); data->add_sample_button = gtk_button_new_with_label(_("add")); gtk_widget_set_sensitive(data->add_sample_button, FALSE); gtk_box_pack_start(GTK_BOX(samples_options_row), data->add_sample_button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(data->add_sample_button), "clicked", G_CALLBACK(_add_sample), self); data->samples_container = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_PIXEL_APPLY_DPI(2)); gtk_box_pack_start(GTK_BOX(container), data->samples_container, TRUE, TRUE, 0); data->display_samples_check_box = gtk_check_button_new_with_label(_("display sample areas on image")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->display_samples_check_box), dt_conf_get_int("ui_last/colorpicker_display_samples")); gtk_box_pack_start(GTK_BOX(container), data->display_samples_check_box, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(data->display_samples_check_box), "toggled", G_CALLBACK(_display_samples_changed), NULL); }
static void _add_sample(GtkButton *widget, gpointer self) { dt_lib_colorpicker_t *data = ((dt_lib_module_t *)self)->data; dt_colorpicker_sample_t *sample = (dt_colorpicker_sample_t *)malloc(sizeof(dt_colorpicker_sample_t)); darktable.lib->proxy.colorpicker.live_samples = g_slist_append(darktable.lib->proxy.colorpicker.live_samples, sample); dt_iop_module_t *module = get_colorout_module(); int i; sample->locked = 0; sample->rgb.red = 0.7; sample->rgb.green = 0.7; sample->rgb.blue = 0.7; sample->rgb.alpha = 1.0; // Initializing the UI sample->container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); gtk_box_pack_start(GTK_BOX(data->samples_container), sample->container, TRUE, TRUE, 0); sample->color_patch = gtk_drawing_area_new(); gtk_widget_set_size_request(sample->color_patch, DT_PIXEL_APPLY_DPI(40), -1); gtk_widget_set_events(sample->color_patch, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK); gtk_widget_set_tooltip_text(sample->color_patch, _("hover to highlight sample on canvas, " "click to lock sample")); gtk_box_pack_start(GTK_BOX(sample->container), sample->color_patch, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(sample->color_patch), "enter-notify-event", G_CALLBACK(_live_sample_enter), sample); g_signal_connect(G_OBJECT(sample->color_patch), "leave-notify-event", G_CALLBACK(_live_sample_leave), sample); g_signal_connect(G_OBJECT(sample->color_patch), "button-press-event", G_CALLBACK(_sample_lock_toggle), sample); g_signal_connect(G_OBJECT(sample->color_patch), "draw", G_CALLBACK(sample_draw_callback), sample); sample->output_label = gtk_label_new(""); gtk_box_pack_start(GTK_BOX(sample->container), sample->output_label, TRUE, TRUE, 0); sample->delete_button = gtk_button_new_with_label(_("remove")); gtk_box_pack_start(GTK_BOX(sample->container), sample->delete_button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(sample->delete_button), "clicked", G_CALLBACK(_remove_sample), sample); gtk_widget_show_all(data->samples_container); // Setting the actual data if(dt_conf_get_int("ui_last/colorpicker_size")) { sample->size = DT_COLORPICKER_SIZE_BOX; for(i = 0; i < 4; i++) sample->box[i] = module->color_picker_box[i]; } else { sample->size = DT_COLORPICKER_SIZE_POINT; for(i = 0; i < 2; i++) sample->point[i] = module->color_picker_point[i]; } for(i = 0; i < 3; i++) sample->picked_color_lab_max[i] = darktable.lib->proxy.colorpicker.picked_color_lab_max[i]; for(i = 0; i < 3; i++) sample->picked_color_lab_mean[i] = darktable.lib->proxy.colorpicker.picked_color_lab_mean[i]; for(i = 0; i < 3; i++) sample->picked_color_lab_min[i] = darktable.lib->proxy.colorpicker.picked_color_lab_min[i]; for(i = 0; i < 3; i++) sample->picked_color_rgb_max[i] = darktable.lib->proxy.colorpicker.picked_color_rgb_max[i]; for(i = 0; i < 3; i++) sample->picked_color_rgb_mean[i] = darktable.lib->proxy.colorpicker.picked_color_rgb_mean[i]; for(i = 0; i < 3; i++) sample->picked_color_rgb_min[i] = darktable.lib->proxy.colorpicker.picked_color_rgb_min[i]; // Updating the display _update_samples_output((dt_lib_module_t *)self); }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_borders_gui_data_t)); 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; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); g->size = dt_bauhaus_slider_new_with_range(self, 0.0, 50.0, 0.5, p->size * 100.0, 2); dt_bauhaus_widget_set_label(g->size, NULL, _("border size")); dt_bauhaus_slider_set_format(g->size, "%.2f%%"); g_signal_connect(G_OBJECT(g->size), "value-changed", G_CALLBACK(size_callback), self); gtk_widget_set_tooltip_text(g->size, _("size of the border in percent of the full image")); gtk_box_pack_start(GTK_BOX(self->widget), g->size, TRUE, TRUE, 0); g->aspect = dt_bauhaus_combobox_new(self); dt_bauhaus_combobox_set_editable(g->aspect, 1); dt_bauhaus_widget_set_label(g->aspect, NULL, _("aspect")); gtk_box_pack_start(GTK_BOX(self->widget), g->aspect, TRUE, TRUE, 0); gui_init_aspect(self); g_signal_connect(G_OBJECT(g->aspect), "value-changed", G_CALLBACK(aspect_changed), self); gtk_widget_set_tooltip_text(g->aspect, _("select the aspect ratio or right click and type your own (w:h)")); g->aspect_orient = dt_bauhaus_combobox_new(self); dt_bauhaus_widget_set_label(g->aspect_orient, NULL, _("orientation")); dt_bauhaus_combobox_add(g->aspect_orient, _("auto")); dt_bauhaus_combobox_add(g->aspect_orient, _("portrait")); dt_bauhaus_combobox_add(g->aspect_orient, _("landscape")); gtk_widget_set_tooltip_text(g->aspect_orient, _("aspect ratio orientation of the image with border")); g_signal_connect(G_OBJECT(g->aspect_orient), "value-changed", G_CALLBACK(aspect_orient_changed), self); gtk_box_pack_start(GTK_BOX(self->widget), g->aspect_orient, TRUE, TRUE, 0); g->pos_h = dt_bauhaus_combobox_new(self); dt_bauhaus_combobox_set_editable(g->pos_h, 1); dt_bauhaus_widget_set_label(g->pos_h, NULL, _("horizontal position")); gtk_box_pack_start(GTK_BOX(self->widget), g->pos_h, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(g->pos_h), "value-changed", G_CALLBACK(position_h_changed), self); gtk_widget_set_tooltip_text(g->pos_h, _("select the horizontal position ratio relative to top " "or right click and type your own (y:h)")); g->pos_v = dt_bauhaus_combobox_new(self); dt_bauhaus_combobox_set_editable(g->pos_v, 1); dt_bauhaus_widget_set_label(g->pos_v, NULL, _("vertical position")); gtk_box_pack_start(GTK_BOX(self->widget), g->pos_v, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(g->pos_v), "value-changed", G_CALLBACK(position_v_changed), self); gtk_widget_set_tooltip_text(g->pos_v, _("select the vertical position ratio relative to left " "or right click and type your own (x:w)")); gui_init_positions(self); g->frame_size = dt_bauhaus_slider_new_with_range(self, 0.0, 100.0, 0.5, p->frame_size * 100.0, 2); dt_bauhaus_widget_set_label(g->frame_size, NULL, _("frame line size")); dt_bauhaus_slider_set_format(g->frame_size, "%.2f%%"); g_signal_connect(G_OBJECT(g->frame_size), "value-changed", G_CALLBACK(frame_size_callback), self); gtk_widget_set_tooltip_text(g->frame_size, _("size of the frame line in percent of min border width")); gtk_box_pack_start(GTK_BOX(self->widget), g->frame_size, TRUE, TRUE, 0); g->frame_offset = dt_bauhaus_slider_new_with_range(self, 0.0, 100.0, 0.5, p->frame_offset * 100.0, 2); dt_bauhaus_widget_set_label(g->frame_offset, NULL, _("frame line offset")); dt_bauhaus_slider_set_format(g->frame_offset, "%.2f%%"); g_signal_connect(G_OBJECT(g->frame_offset), "value-changed", G_CALLBACK(frame_offset_callback), self); gtk_widget_set_tooltip_text(g->frame_offset, _("offset of the frame line beginning on picture side")); gtk_box_pack_start(GTK_BOX(self->widget), g->frame_offset, TRUE, TRUE, 0); GdkRGBA color = (GdkRGBA){.red = p->color[0], .green = p->color[1], .blue = p->color[2], .alpha = 1.0 }; GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); g->colorpick = gtk_color_button_new_with_rgba(&color); gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(g->colorpick), FALSE); gtk_widget_set_size_request(GTK_WIDGET(g->colorpick), DT_PIXEL_APPLY_DPI(24), DT_PIXEL_APPLY_DPI(24)); gtk_color_button_set_title(GTK_COLOR_BUTTON(g->colorpick), _("select border color")); GtkWidget *label = dtgtk_reset_label_new(_("border color"), self, &p->color, 3 * sizeof(float)); g_signal_connect(G_OBJECT(g->colorpick), "color-set", G_CALLBACK(colorpick_color_set), self); g->border_picker = GTK_TOGGLE_BUTTON(dtgtk_togglebutton_new(dtgtk_cairo_paint_colorpicker, CPF_STYLE_FLAT)); gtk_widget_set_tooltip_text(GTK_WIDGET(g->border_picker), _("pick border color from image")); gtk_widget_set_size_request(GTK_WIDGET(g->border_picker), DT_PIXEL_APPLY_DPI(24), DT_PIXEL_APPLY_DPI(24)); g_signal_connect(G_OBJECT(g->border_picker), "toggled", G_CALLBACK(request_pick_toggled_border), self); gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(g->colorpick), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(g->border_picker), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(self->widget), box, TRUE, TRUE, 0); box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); g->frame_colorpick = gtk_color_button_new_with_rgba(&color); gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(g->frame_colorpick), FALSE); gtk_color_button_set_title(GTK_COLOR_BUTTON(g->frame_colorpick), _("select frame line color")); gtk_widget_set_size_request(GTK_WIDGET(g->frame_colorpick), DT_PIXEL_APPLY_DPI(24), DT_PIXEL_APPLY_DPI(24)); label = dtgtk_reset_label_new(_("frame line color"), self, &p->color, 3 * sizeof(float)); g_signal_connect(G_OBJECT(g->frame_colorpick), "color-set", G_CALLBACK(frame_colorpick_color_set), self); g->frame_picker = GTK_TOGGLE_BUTTON(dtgtk_togglebutton_new(dtgtk_cairo_paint_colorpicker, CPF_STYLE_FLAT)); gtk_widget_set_tooltip_text(GTK_WIDGET(g->frame_picker), _("pick frame line color from image")); gtk_widget_set_size_request(GTK_WIDGET(g->frame_picker), DT_PIXEL_APPLY_DPI(24), DT_PIXEL_APPLY_DPI(24)); g_signal_connect(G_OBJECT(g->frame_picker), "toggled", G_CALLBACK(request_pick_toggled_frame), self); gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(g->frame_colorpick), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(g->frame_picker), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(self->widget), box, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(self->widget), "draw", G_CALLBACK(borders_draw), self); } void reload_defaults(dt_iop_module_t *self) { dt_iop_borders_params_t tmp = (dt_iop_borders_params_t){ { 1.0f, 1.0f, 1.0f }, DT_IOP_BORDERS_ASPECT_CONSTANT_VALUE, "constant border", 0, 0.1f, 0.5f, "1/2", 0.5f, "1/2", 0.0f, 0.5f, { 0.0f, 0.0f, 0.0f }, TRUE }; memcpy(self->params, &tmp, sizeof(dt_iop_borders_params_t)); memcpy(self->default_params, &tmp, sizeof(dt_iop_borders_params_t)); self->default_enabled = 0; }
static gboolean lowlight_draw(GtkWidget *widget, cairo_t *crf, 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; dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); const int inset = DT_IOP_LOWLIGHT_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); 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, DT_PIXEL_APPLY_DPI(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, DT_PIXEL_APPLY_DPI(.4)); cairo_set_source_rgb(cr, .1, .1, .1); dt_draw_grid(cr, 8, 0, 0, width, height); if(c->mouse_y > 0 || c->dragging) { // draw min/max curves: dt_iop_lowlight_get_params(&p, c->mouse_x, 1., c->mouse_radius); dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_min_xs, c->draw_min_ys); p = *(dt_iop_lowlight_params_t *)self->params; dt_iop_lowlight_get_params(&p, c->mouse_x, .0, c->mouse_radius); dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_max_xs, c->draw_max_ys); } cairo_save(cr); // draw x positions cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); const float arrw = DT_PIXEL_APPLY_DPI(7.0f); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) { cairo_move_to(cr, width * p.transition_x[k], height + inset - DT_PIXEL_APPLY_DPI(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->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } // draw selected cursor cairo_translate(cr, 0, height); // cairo_set_operator(cr, CAIRO_OPERATOR_ADD); // cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.)); cairo_set_source_rgba(cr, .7, .7, .7, 1.0); p = *(dt_iop_lowlight_params_t *)self->params; dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_xs, c->draw_ys); cairo_move_to(cr, 0 * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[0]); for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[k]); cairo_stroke(cr); // draw dots on knots cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) { cairo_arc(cr, width * p.transition_x[k], -height * p.transition_y[k], DT_PIXEL_APPLY_DPI(3.0), 0.0, 2.0 * M_PI); if(c->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } if(c->mouse_y > 0 || c->dragging) { // draw min/max, if selected cairo_set_source_rgba(cr, .7, .7, .7, .6); cairo_move_to(cr, 0, -height * c->draw_min_ys[0]); for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_min_ys[k]); for(int k = DT_IOP_LOWLIGHT_RES - 1; k >= 0; k--) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_max_ys[k]); cairo_close_path(cr); cairo_fill(cr); // draw mouse focus circle cairo_set_source_rgba(cr, .9, .9, .9, .5); const float pos = DT_IOP_LOWLIGHT_RES * c->mouse_x; int k = (int)pos; const float f = k - pos; if(k >= DT_IOP_LOWLIGHT_RES - 1) k = DT_IOP_LOWLIGHT_RES - 2; float ht = -height * (f * c->draw_ys[k] + (1 - f) * c->draw_ys[k + 1]); cairo_arc(cr, c->mouse_x * width, ht, c->mouse_radius * width, 0, 2. * M_PI); cairo_stroke(cr); } cairo_restore(cr); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // draw labels: PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); pango_font_description_set_absolute_size(desc,(.06 * height) * PANGO_SCALE); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, desc); cairo_set_source_rgb(cr, .1, .1, .1); pango_layout_set_text(layout, _("dark"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .02 * width - ink.y, .5 * (height + ink.width)); cairo_save(cr); cairo_rotate(cr, -M_PI * .5f); pango_cairo_show_layout(cr, layout); cairo_restore(cr); pango_layout_set_text(layout, _("bright"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .98 * width - ink.height, .5 * (height + ink.width)); cairo_save(cr); cairo_rotate(cr, -M_PI * .5f); pango_cairo_show_layout(cr, layout); cairo_restore(cr); pango_layout_set_text(layout, _("day vision"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .5 * (width - ink.width), .08 * height - ink.height); pango_cairo_show_layout(cr, layout); pango_layout_set_text(layout, _("night vision"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .5 * (width - ink.width), .97 * height - ink.height); pango_cairo_show_layout(cr, layout); pango_font_description_free(desc); g_object_unref(layout); cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }