コード例 #1
0
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);
}
コード例 #2
0
/** 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;
}
コード例 #3
0
ファイル: darktable.c プロジェクト: kael-shipman/darktable
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;
}
コード例 #4
0
ファイル: lighttable.c プロジェクト: TurboGit/darktable
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;
}
コード例 #5
0
ファイル: graduatednd.c プロジェクト: dtorop/darktable
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;
}
コード例 #6
0
ファイル: splittoning.c プロジェクト: boucman/darktable
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);
}
コード例 #7
0
ファイル: history.c プロジェクト: boucman/darktable
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);
}
コード例 #8
0
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);
  }
}
コード例 #9
0
ファイル: location.c プロジェクト: CChiappa/darktable
/*
  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));
}
コード例 #10
0
ファイル: zonesystem.c プロジェクト: rgo/darktable
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;
}
コード例 #11
0
ファイル: splittoning.c プロジェクト: dirkbr/darktable
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;
}
コード例 #12
0
ファイル: duplicate.c プロジェクト: VolkerChristian/darktable
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);
}
コード例 #13
0
ファイル: modulelist.c プロジェクト: Coshibu/darktable
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;
}
コード例 #14
0
ファイル: slider.c プロジェクト: CaptainSifff/darktable
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;
}
コード例 #15
0
ファイル: camera.c プロジェクト: dirkbr/darktable
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++;
}
コード例 #16
0
ファイル: camera.c プロジェクト: mueller-physics/darktable
      /* 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);
}
コード例 #17
0
ファイル: session.c プロジェクト: CarVac/darktable
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);
}
コード例 #18
0
ファイル: duplicate.c プロジェクト: VolkerChristian/darktable
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);
}
コード例 #19
0
ファイル: invert.c プロジェクト: dtorop/darktable
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;
}
コード例 #20
0
ファイル: metadata_view.c プロジェクト: CarVac/darktable
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);
}
コード例 #21
0
ファイル: colorcorrection.c プロジェクト: Nitrosito/darktable
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;
}
コード例 #22
0
ファイル: camera.c プロジェクト: dirkbr/darktable
/** 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;
}
コード例 #23
0
ファイル: global_toolbox.c プロジェクト: PolarFox/darktable
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);
}
コード例 #24
0
ファイル: watermark.c プロジェクト: edgomez/darktable
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;
}
コード例 #25
0
ファイル: control.c プロジェクト: AdamMajer/darktable
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;
}
コード例 #26
0
ファイル: histogram.c プロジェクト: avsmal/darktable
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;
}
コード例 #27
0
ファイル: colorpicker.c プロジェクト: dirkbr/darktable
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);
}
コード例 #28
0
ファイル: colorpicker.c プロジェクト: dirkbr/darktable
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);
}
コード例 #29
0
ファイル: borders.c プロジェクト: CarVac/darktable
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;
}
コード例 #30
0
ファイル: lowlight.c プロジェクト: CChiappa/darktable
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;
}