Exemple #1
0
void dt_iop_gui_init_blending(GtkWidget *iopw, dt_iop_module_t *module)
{
  /* create and add blend mode if module supports it */
  if (module->flags()&IOP_FLAGS_SUPPORTS_BLENDING)
  {
    module->blend_data = g_malloc(sizeof(dt_iop_gui_blend_data_t));
    memset(module->blend_data, 0, sizeof(dt_iop_gui_blend_data_t));
    dt_iop_gui_blend_data_t *bd = (dt_iop_gui_blend_data_t*)module->blend_data;

    dt_iop_gui_blendop_modes_t modes[23]; /* number must fit exactly!!! */
    modes[0].mode  = DEVELOP_BLEND_DISABLED;
    modes[0].name  = _("off");
    modes[1].mode  = DEVELOP_BLEND_NORMAL;
    modes[1].name  = _("normal");
    modes[2].mode  = DEVELOP_BLEND_INVERSE;
    modes[2].name  = _("inverse");
    modes[3].mode  = DEVELOP_BLEND_LIGHTEN;
    modes[3].name  = _("lighten");
    modes[4].mode  = DEVELOP_BLEND_DARKEN;
    modes[4].name  = _("darken");
    modes[5].mode  = DEVELOP_BLEND_MULTIPLY;
    modes[5].name  = _("multiply");
    modes[6].mode  = DEVELOP_BLEND_AVERAGE;
    modes[6].name  = _("average");
    modes[7].mode  = DEVELOP_BLEND_ADD;
    modes[7].name  = _("addition");
    modes[8].mode  = DEVELOP_BLEND_SUBSTRACT;
    modes[8].name  = _("subtract");
    modes[9].mode  = DEVELOP_BLEND_DIFFERENCE;
    modes[9].name  = _("difference");
    modes[10].mode = DEVELOP_BLEND_SCREEN;
    modes[10].name = _("screen");
    modes[11].mode = DEVELOP_BLEND_OVERLAY;
    modes[11].name = _("overlay");
    modes[12].mode = DEVELOP_BLEND_SOFTLIGHT;
    modes[12].name = _("softlight");
    modes[13].mode = DEVELOP_BLEND_HARDLIGHT;
    modes[13].name = _("hardlight");
    modes[14].mode = DEVELOP_BLEND_VIVIDLIGHT;
    modes[14].name = _("vividlight");
    modes[15].mode = DEVELOP_BLEND_LINEARLIGHT;
    modes[15].name = _("linearlight");
    modes[16].mode = DEVELOP_BLEND_PINLIGHT;
    modes[16].name = _("pinlight");
    modes[17].mode = DEVELOP_BLEND_LIGHTNESS;
    modes[17].name = _("lightness");
    modes[18].mode = DEVELOP_BLEND_CHROMA;
    modes[18].name = _("chroma");
    modes[19].mode = DEVELOP_BLEND_HUE;
    modes[19].name = _("hue");
    modes[20].mode = DEVELOP_BLEND_COLOR;
    modes[20].name = _("color");
    modes[21].mode = DEVELOP_BLEND_COLORADJUST;
    modes[21].name = _("coloradjustment");
    modes[22].mode = DEVELOP_BLEND_UNBOUNDED;
    modes[22].name = _("unbounded");


    bd->number_modes = sizeof(modes) / sizeof(dt_iop_gui_blendop_modes_t);
    memcpy(bd->modes, modes, bd->number_modes * sizeof(dt_iop_gui_blendop_modes_t));
    bd->iopw = iopw;
    bd->module = module;
    bd->csp = dt_iop_module_colorspace(module);
    bd->blendif_support = (bd->csp == iop_cs_Lab || bd->csp == iop_cs_rgb);
    bd->blendif_box = NULL;

    bd->blend_modes_combo = dt_bauhaus_combobox_new(module);
    dt_bauhaus_widget_set_label(bd->blend_modes_combo, _("blend mode"));
    bd->opacity_slider = dt_bauhaus_slider_new_with_range(module, 0.0, 100.0, 1, 100.0, 0);
    dt_bauhaus_widget_set_label(bd->opacity_slider, _("opacity"));
    dt_bauhaus_slider_set_format(bd->opacity_slider, "%.0f%%");
    module->fusion_slider = bd->opacity_slider;


    for(int k = 0; k < bd->number_modes; k++)
      dt_bauhaus_combobox_add(bd->blend_modes_combo, bd->modes[k].name);

    dt_bauhaus_combobox_set(bd->blend_modes_combo, 0);

    gtk_object_set(GTK_OBJECT(bd->opacity_slider), "tooltip-text", _("set the opacity of the blending"), (char *)NULL);
    gtk_object_set(GTK_OBJECT(bd->blend_modes_combo), "tooltip-text", _("choose blending mode"), (char *)NULL);

    g_signal_connect (G_OBJECT (bd->opacity_slider), "value-changed",
                      G_CALLBACK (_blendop_opacity_callback), bd);
    g_signal_connect (G_OBJECT (bd->blend_modes_combo), "value-changed",
                      G_CALLBACK (_blendop_mode_callback), bd);

    gtk_box_pack_start(GTK_BOX(iopw), bd->blend_modes_combo, TRUE, TRUE,0);
    gtk_box_pack_start(GTK_BOX(iopw), bd->opacity_slider, TRUE, TRUE,0);

    if(bd->blendif_support)
    {
      dt_iop_gui_init_blendif(GTK_VBOX(iopw), module);
    }
    bd->blend_inited = 1;
    gtk_widget_queue_draw(GTK_WIDGET(iopw));
    dt_iop_gui_update_blending(module);
  }
}
Exemple #2
0
void dt_dev_reload_history_items(dt_develop_t *dev)
{
  dt_dev_pop_history_items(dev, 0);
  // remove unused history items:
  GList *history = g_list_nth(dev->history, dev->history_end);
  while(history)
  {
    GList *next = g_list_next(history);
    dt_dev_history_item_t *hist = (dt_dev_history_item_t *)(history->data);
    free(hist->params);
    free(hist->blend_params);
    free(history->data);
    dev->history = g_list_delete_link(dev->history, history);
    history = next;
  }
  dt_dev_read_history(dev);

  //we have to add new module instances first
  GList *modules = dev->iop;
  while(modules)
  {
    dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
    if (module->multi_priority > 0)
    {
      if (!dt_iop_is_hidden(module) && !module->expander)
      {
        module->gui_init(module);
        dt_iop_reload_defaults(module);
        //we search the base iop corresponding
        GList *mods = g_list_first(dev->iop);
        dt_iop_module_t *base = NULL;
        int pos_module = 0;
        int pos_base = 0;
        int pos = 0;
        while (mods)
        {
          dt_iop_module_t *mod = (dt_iop_module_t *)(mods->data);
          if (mod->multi_priority == 0 && mod->instance == module->instance)
          {
            base = mod;
            pos_base = pos;
          }
          else if (mod == module) pos_module = pos;
          mods = g_list_next(mods);
          pos++;
        }
        if (!base) continue;

        /* add module to right panel */
        GtkWidget *expander = dt_iop_gui_get_expander(module);
        dt_ui_container_add_widget(darktable.gui->ui,
                                   DT_UI_CONTAINER_PANEL_RIGHT_CENTER, expander);
        GValue gv = { 0, { { 0 } } };
        g_value_init(&gv,G_TYPE_INT);
        gtk_container_child_get_property(GTK_CONTAINER(dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER)),base->expander,"position",&gv);
        gtk_box_reorder_child (dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER),expander,g_value_get_int(&gv)+pos_base-pos_module);
        dt_iop_gui_set_expanded(module, TRUE);
        dt_iop_gui_update_blending(module);

        //the pipe need to be reconstruct
        dev->pipe->changed |= DT_DEV_PIPE_REMOVE;
        dev->preview_pipe->changed |= DT_DEV_PIPE_REMOVE;
      }
    }
    modules = g_list_next(modules);
  }

  dt_dev_pop_history_items(dev, dev->history_end);
}
Exemple #3
0
static void
dt_dev_change_image(dt_develop_t *dev, const uint32_t imgid)
{
  // stop crazy users from sleeping on key-repeat spacebar:
  if(dev->image_loading) return;

  // get last active plugin, make sure focus out is called:
  gchar *active_plugin = dt_conf_get_string("plugins/darkroom/active");
  dt_iop_request_focus(NULL);
  // store last active group
  dt_conf_set_int("plugins/darkroom/groups", dt_dev_modulegroups_get(dev));

  // store last active plugin:
  if(darktable.develop->gui_module)
    dt_conf_set_string("plugins/darkroom/active", darktable.develop->gui_module->op);
  else
    dt_conf_set_string("plugins/darkroom/active", "");
  g_assert(dev->gui_attached);

  // commit image ops to db
  dt_dev_write_history(dev);

  // be sure light table will update the thumbnail
  // TODO: only if image changed!
  // if()
  {
    dt_mipmap_cache_remove(darktable.mipmap_cache, dev->image_storage.id);
    dt_image_synch_xmp(dev->image_storage.id);
  }

  select_this_image(imgid);

  while(dev->history)
  {
    // clear history of old image
    free(((dt_dev_history_item_t *)dev->history->data)->params);
    free( (dt_dev_history_item_t *)dev->history->data);
    dev->history = g_list_delete_link(dev->history, dev->history);
  }

  // get new image:
  dt_dev_reload_image(dev, imgid);

  // make sure no signals propagate here:
  darktable.gui->reset = 1;

  GList *modules = g_list_last(dev->iop);
  int nb_iop = g_list_length(dev->iop);
  dt_dev_pixelpipe_cleanup_nodes(dev->pipe);
  dt_dev_pixelpipe_cleanup_nodes(dev->preview_pipe);
  for (int i=nb_iop-1; i>0; i--)
  {
    dt_iop_module_t *module = (dt_iop_module_t *)(g_list_nth_data(dev->iop,i));
    if (module->multi_priority == 0) //if the module is the "base" instance, we keep it
    {
      dt_iop_reload_defaults(module);
      dt_iop_gui_update(module);
    }
    else  //else we delete it and remove it from the panel
    {
      if (!dt_iop_is_hidden(module))
      {
        gtk_container_remove (GTK_CONTAINER(dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER)),module->expander);
        dt_iop_gui_cleanup_module(module);
      }

      //we remove the module from the list
      dev->iop = g_list_remove_link(dev->iop,g_list_nth(dev->iop,i));

      //we cleanup the module
      dt_accel_disconnect_list(module->accel_closures);
      dt_accel_cleanup_locals_iop(module);
      module->accel_closures = NULL;
      dt_iop_cleanup_module(module);
      free(module);
    }
  }
  dt_dev_pixelpipe_create_nodes(dev->pipe, dev);
  dt_dev_pixelpipe_create_nodes(dev->preview_pipe, dev);
  dt_dev_read_history(dev);

  //we have to init all module instances other than "base" instance
  modules = dev->iop;
  while(modules)
  {
    dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
    if(module->multi_priority > 0)
    {
      if (!dt_iop_is_hidden(module))
      {
        module->gui_init(module);
        dt_iop_reload_defaults(module);
        //we search the base iop corresponding
        GList *mods = g_list_first(dev->iop);
        dt_iop_module_t *base = NULL;
        int pos_module = 0;
        int pos_base = 0;
        int pos = 0;
        while (mods)
        {
          dt_iop_module_t *mod = (dt_iop_module_t *)(mods->data);
          if (mod->multi_priority == 0 && mod->instance == module->instance)
          {
            base = mod;
            pos_base = pos;
          }
          else if (mod == module) pos_module = pos;
          mods = g_list_next(mods);
          pos++;
        }
        if (!base) continue;

        /* add module to right panel */
        GtkWidget *expander = dt_iop_gui_get_expander(module);
        dt_ui_container_add_widget(darktable.gui->ui,
                                   DT_UI_CONTAINER_PANEL_RIGHT_CENTER, expander);
        GValue gv = { 0, { { 0 } } };
        g_value_init(&gv,G_TYPE_INT);
        gtk_container_child_get_property(GTK_CONTAINER(dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER)),base->expander,"position",&gv);
        gtk_box_reorder_child (dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER),expander,g_value_get_int(&gv)+pos_base-pos_module);
        dt_iop_gui_set_expanded(module, TRUE);
        dt_iop_gui_update_blending(module);
      }

      /* setup key accelerators */
      module->accel_closures = NULL;
      if(module->connect_key_accels)
        module->connect_key_accels(module);
      dt_iop_connect_common_accels(module);

      //we update show params for multi-instances for each other instances
      dt_dev_modules_update_multishow(module->dev);
    }
    modules = g_list_next(modules);
  }

  dt_dev_pop_history_items(dev, dev->history_end);

  if(active_plugin)
  {
    modules = dev->iop;
    while(modules)
    {
      dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
      if(!strcmp(module->op, active_plugin))
        dt_iop_request_focus(module);
      modules = g_list_next(modules);
    }
    g_free(active_plugin);
  }

  /* last set the group to update visibility of iop modules for new pipe */
  dt_dev_modulegroups_set(dev,dt_conf_get_int("plugins/darkroom/groups"));

  // make signals work again, but only after focus event,
  // to avoid crop/rotate for example to add another history item.
  darktable.gui->reset = 0;

  // Signal develop initialize
  dt_control_signal_raise(darktable.signals, DT_SIGNAL_DEVELOP_IMAGE_CHANGED);

  // prefetch next few from first selected image on.
  dt_view_filmstrip_prefetch();
}