Esempio n. 1
0
static void
gimp_curves_tool_color_picked (GimpColorTool      *color_tool,
                               GimpColorPickState  pick_state,
                               GimpImageType       sample_type,
                               GimpRGB            *color,
                               gint                color_index)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (color_tool);
  GimpDrawable   *drawable;

  drawable = GIMP_IMAGE_MAP_TOOL (tool)->drawable;

  tool->picked_color[GIMP_HISTOGRAM_RED]   = color->r;
  tool->picked_color[GIMP_HISTOGRAM_GREEN] = color->g;
  tool->picked_color[GIMP_HISTOGRAM_BLUE]  = color->b;

  if (gimp_drawable_has_alpha (drawable))
    tool->picked_color[GIMP_HISTOGRAM_ALPHA] = color->a;

  tool->picked_color[GIMP_HISTOGRAM_VALUE] = MAX (MAX (color->r, color->g),
                                                  color->b);

  gimp_curve_view_set_xpos (GIMP_CURVE_VIEW (tool->graph),
                            tool->picked_color[tool->config->channel]);
}
Esempio n. 2
0
static GeglNode *
gimp_curves_tool_get_operation (GimpImageMapTool  *image_map_tool,
                                GObject          **config)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (image_map_tool);
  GeglNode       *node;

  node = g_object_new (GEGL_TYPE_NODE,
                       "operation", "gimp-curves",
                       NULL);

  tool->config = g_object_new (GIMP_TYPE_CURVES_CONFIG, NULL);

  *config = G_OBJECT (tool->config);

  g_signal_connect_object (tool->config, "notify",
                           G_CALLBACK (gimp_curves_tool_config_notify),
                           tool, 0);

  gegl_node_set (node,
                 "config", tool->config,
                 NULL);

  return node;
}
Esempio n. 3
0
static void
gimp_curves_tool_reset (GimpImageMapTool *image_map_tool)
{
  GimpCurvesTool       *tool = GIMP_CURVES_TOOL (image_map_tool);
  GimpCurvesConfig     *default_config;
  GimpHistogramChannel  channel;

  default_config = GIMP_CURVES_CONFIG (image_map_tool->default_config);

  for (channel = GIMP_HISTOGRAM_VALUE;
       channel <= GIMP_HISTOGRAM_ALPHA;
       channel++)
    {
      if (default_config)
        {
          GimpCurveType curve_type = tool->config->curve[channel]->curve_type;

          g_object_freeze_notify (G_OBJECT (tool->config->curve[channel]));

          gimp_config_copy (GIMP_CONFIG (default_config->curve[channel]),
                            GIMP_CONFIG (tool->config->curve[channel]),
                            0);

          g_object_set (tool->config->curve[channel],
                        "curve-type", curve_type,
                        NULL);

          g_object_thaw_notify (G_OBJECT (tool->config->curve[channel]));
        }
      else
        {
          gimp_curve_reset (tool->config->curve[channel], FALSE);
        }
    }
}
Esempio n. 4
0
static gboolean
gimp_curves_tool_settings_import (GimpImageMapTool  *image_map_tool,
                                  GInputStream      *input,
                                  GError           **error)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (image_map_tool);
  gchar           header[64];
  gsize           bytes_read;

  if (! g_input_stream_read_all (input, header, sizeof (header),
                                 &bytes_read, NULL, error) ||
      bytes_read != sizeof (header))
    {
      g_prefix_error (error, _("Could not read header: "));
      return FALSE;
    }

  g_seekable_seek (G_SEEKABLE (input), 0, G_SEEK_SET, NULL, NULL);

  if (g_str_has_prefix (header, "# GIMP Curves File\n"))
    return gimp_curves_config_load_cruft (tool->config, input, error);

  return GIMP_IMAGE_MAP_TOOL_CLASS (parent_class)->settings_import (image_map_tool,
                                                                    input,
                                                                    error);
}
Esempio n. 5
0
static void
gimp_curves_tool_color_picked (GimpColorTool      *color_tool,
                               GimpColorPickState  pick_state,
                               gdouble             x,
                               gdouble             y,
                               const Babl         *sample_format,
                               gpointer            pixel,
                               const GimpRGB      *color)
{
  GimpCurvesTool   *tool    = GIMP_CURVES_TOOL (color_tool);
  GimpImageMapTool *im_tool = GIMP_IMAGE_MAP_TOOL (color_tool);
  GimpCurvesConfig *config  = GIMP_CURVES_CONFIG (im_tool->config);
  GimpDrawable     *drawable;

  drawable = GIMP_IMAGE_MAP_TOOL (tool)->drawable;

  tool->picked_color[GIMP_HISTOGRAM_RED]   = color->r;
  tool->picked_color[GIMP_HISTOGRAM_GREEN] = color->g;
  tool->picked_color[GIMP_HISTOGRAM_BLUE]  = color->b;

  if (gimp_drawable_has_alpha (drawable))
    tool->picked_color[GIMP_HISTOGRAM_ALPHA] = color->a;
  else
    tool->picked_color[GIMP_HISTOGRAM_ALPHA] = -1;

  tool->picked_color[GIMP_HISTOGRAM_VALUE] = MAX (MAX (color->r, color->g),
                                                  color->b);

  gimp_curve_view_set_xpos (GIMP_CURVE_VIEW (tool->graph),
                            tool->picked_color[config->channel]);
}
Esempio n. 6
0
static gboolean
gimp_curves_tool_settings_export (GimpImageMapTool  *image_map_tool,
                                  const gchar       *filename,
                                  GError           **error)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (image_map_tool);

  if (tool->export_old_format)
    {
      FILE     *file;
      gboolean  success;

      file = g_fopen (filename, "wt");

      if (! file)
        {
          g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                       _("Could not open '%s' for writing: %s"),
                       gimp_filename_to_utf8 (filename),
                       g_strerror (errno));
          return FALSE;
        }

      success = gimp_curves_config_save_cruft (tool->config, file, error);

      fclose (file);

      return success;
    }

  return GIMP_IMAGE_MAP_TOOL_CLASS (parent_class)->settings_export (image_map_tool,
                                                                    filename,
                                                                    error);
}
Esempio n. 7
0
static void
gimp_curves_tool_finalize (GObject *object)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (object);

  gimp_lut_free (tool->lut);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
Esempio n. 8
0
static gboolean
gimp_curves_tool_key_press (GimpTool    *tool,
                            GdkEventKey *kevent,
                            GimpDisplay *display)
{
  GimpCurvesTool *c_tool = GIMP_CURVES_TOOL (tool);

  return gtk_widget_event (c_tool->graph, (GdkEvent *) kevent);
}
Esempio n. 9
0
static void
gimp_curves_tool_button_release (GimpTool              *tool,
                                 const GimpCoords      *coords,
                                 guint32                time,
                                 GdkModifierType        state,
                                 GimpButtonReleaseType  release_type,
                                 GimpDisplay           *display)
{
  GimpCurvesTool   *c_tool  = GIMP_CURVES_TOOL (tool);
  GimpImageMapTool *im_tool = GIMP_IMAGE_MAP_TOOL (tool);
  GimpCurvesConfig *config  = GIMP_CURVES_CONFIG (im_tool->config);

  if (state & gimp_get_extend_selection_mask ())
    {
      GimpCurve *curve = config->curve[config->channel];
      gdouble    value = c_tool->picked_color[config->channel];
      gint       closest;

      closest = gimp_curve_get_closest_point (curve, value);

      gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph),
                                    closest);

      gimp_curve_set_point (curve, closest,
                            value, gimp_curve_map_value (curve, value));
    }
  else if (state & gimp_get_toggle_behavior_mask ())
    {
      GimpHistogramChannel channel;

      for (channel = GIMP_HISTOGRAM_VALUE;
           channel <= GIMP_HISTOGRAM_ALPHA;
           channel++)
        {
          GimpCurve *curve = config->curve[channel];
          gdouble    value = c_tool->picked_color[channel];
          gint       closest;

          if (value != -1)
            {
              closest = gimp_curve_get_closest_point (curve, value);

              gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph),
                                            closest);

              gimp_curve_set_point (curve, closest,
                                    value, gimp_curve_map_value (curve, value));
            }
        }
    }

  /*  chain up to halt the tool */
  GIMP_TOOL_CLASS (parent_class)->button_release (tool, coords, time, state,
                                                  release_type, display);
}
Esempio n. 10
0
static gboolean
gimp_curves_tool_settings_export (GimpImageMapTool  *image_map_tool,
                                  GOutputStream     *output,
                                  GError           **error)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (image_map_tool);

  if (tool->export_old_format)
    return gimp_curves_config_save_cruft (tool->config, output, error);

  return GIMP_IMAGE_MAP_TOOL_CLASS (parent_class)->settings_export (image_map_tool,
                                                                    output,
                                                                    error);
}
Esempio n. 11
0
static void
gimp_curves_tool_button_release (GimpTool              *tool,
                                 GimpCoords            *coords,
                                 guint32                time,
                                 GdkModifierType        state,
                                 GimpButtonReleaseType  release_type,
                                 GimpDisplay           *display)
{
  GimpCurvesTool   *c_tool = GIMP_CURVES_TOOL (tool);
  GimpCurvesConfig *config = c_tool->config;

  if (state & GDK_SHIFT_MASK)
    {
      GimpCurve *curve = config->curve[config->channel];
      gdouble    value = c_tool->picked_color[config->channel];
      gint       closest;

      closest = gimp_curve_get_closest_point (curve, value);

      gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph),
                                    closest);

      gimp_curve_set_point (curve, closest,
                            value, gimp_curve_map_value (curve, value));
    }
  else if (state & GDK_CONTROL_MASK)
    {
      gint i;

      for (i = 0; i < 5; i++)
        {
          GimpCurve *curve = config->curve[i];
          gdouble    value = c_tool->picked_color[i];
          gint       closest;

          closest = gimp_curve_get_closest_point (curve, value);

          gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph),
                                        closest);

          gimp_curve_set_point (curve, closest,
                                value, gimp_curve_map_value (curve, value));
        }
    }

  /*  chain up to halt the tool */
  GIMP_TOOL_CLASS (parent_class)->button_release (tool, coords, time, state,
                                                  release_type, display);
}
Esempio n. 12
0
static gboolean
gimp_curves_tool_settings_import (GimpImageMapTool  *image_map_tool,
                                  const gchar       *filename,
                                  GError           **error)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (image_map_tool);
  FILE           *file;
  gchar           header[64];

  file = g_fopen (filename, "rt");

  if (! file)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename),
                   g_strerror (errno));
      return FALSE;
    }

  if (! fgets (header, sizeof (header), file))
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not read header from '%s': %s"),
                   gimp_filename_to_utf8 (filename),
                   g_strerror (errno));
      fclose (file);
      return FALSE;
    }

  if (g_str_has_prefix (header, "# GIMP Curves File\n"))
    {
      gboolean success;

      rewind (file);

      success = gimp_curves_config_load_cruft (tool->config, file, error);

      fclose (file);

      return success;
    }

  fclose (file);

  return GIMP_IMAGE_MAP_TOOL_CLASS (parent_class)->settings_import (image_map_tool,
                                                                    filename,
                                                                    error);
}
Esempio n. 13
0
static void
gimp_curves_tool_map (GimpImageMapTool *image_map_tool)
{
  GimpCurvesTool *tool     = GIMP_CURVES_TOOL (image_map_tool);
  GimpDrawable   *drawable = image_map_tool->drawable;
  Curves          curves;

  gimp_curves_config_to_cruft (tool->config, &curves,
                               gimp_drawable_is_rgb (drawable));

  gimp_lut_setup (tool->lut,
                  (GimpLutFunc) curves_lut_func,
                  &curves,
                  gimp_drawable_bytes (drawable));
}
Esempio n. 14
0
static gboolean
gimp_curves_tool_key_press (GimpTool    *tool,
                            GdkEventKey *kevent,
                            GimpDisplay *display)
{
  GimpCurvesTool *c_tool = GIMP_CURVES_TOOL (tool);

  if (tool->display && c_tool->graph)
    {
      if (gtk_widget_event (c_tool->graph, (GdkEvent *) kevent))
        return TRUE;
    }

  return GIMP_TOOL_CLASS (parent_class)->key_press (tool, kevent, display);
}
Esempio n. 15
0
static GeglNode *
gimp_curves_tool_get_operation (GimpImageMapTool  *image_map_tool,
                                GObject          **config,
                                gchar            **undo_desc)
{
  GimpCurvesTool *tool = GIMP_CURVES_TOOL (image_map_tool);

  tool->config = g_object_new (GIMP_TYPE_CURVES_CONFIG, NULL);

  g_signal_connect_object (tool->config, "notify",
                           G_CALLBACK (gimp_curves_tool_config_notify),
                           tool, 0);

  *config = G_OBJECT (tool->config);

  return gegl_node_new_child (NULL,
                              "operation", "gimp:curves",
                              "config",    tool->config,
                              NULL);
}
Esempio n. 16
0
static gboolean
gimp_curves_tool_initialize (GimpTool     *tool,
                             GimpDisplay  *display,
                             GError      **error)
{
  GimpCurvesTool *c_tool   = GIMP_CURVES_TOOL (tool);
  GimpImage      *image    = gimp_display_get_image (display);
  GimpDrawable   *drawable = gimp_image_get_active_drawable (image);
  GimpHistogram  *histogram;

  if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error))
    {
      return FALSE;
    }

  /*  always pick colors  */
  gimp_color_tool_enable (GIMP_COLOR_TOOL (tool),
                          GIMP_COLOR_TOOL_GET_OPTIONS (tool));

  gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (c_tool->channel_menu),
                                      curves_menu_sensitivity, drawable, NULL);

  histogram = gimp_histogram_new (TRUE);
  gimp_drawable_calculate_histogram (drawable, histogram);
  gimp_histogram_view_set_background (GIMP_HISTOGRAM_VIEW (c_tool->graph),
                                      histogram);
  g_object_unref (histogram);

  if (gimp_drawable_get_precision (drawable) == GIMP_PRECISION_U8)
    {
      gimp_curve_view_set_range_x (GIMP_CURVE_VIEW (c_tool->graph), 0, 255);
      gimp_curve_view_set_range_y (GIMP_CURVE_VIEW (c_tool->graph), 0, 255);
    }
  else
    {
      gimp_curve_view_set_range_x (GIMP_CURVE_VIEW (c_tool->graph), 0.0, 1.0);
      gimp_curve_view_set_range_y (GIMP_CURVE_VIEW (c_tool->graph), 0.0, 1.0);
    }

  return TRUE;
}
Esempio n. 17
0
static gboolean
gimp_curves_tool_initialize (GimpTool     *tool,
                             GimpDisplay  *display,
                             GError      **error)
{
  GimpCurvesTool *c_tool   = GIMP_CURVES_TOOL (tool);
  GimpDrawable   *drawable = gimp_image_get_active_drawable (display->image);
  GimpHistogram  *histogram;

  if (! drawable)
    return FALSE;

  if (gimp_drawable_is_indexed (drawable))
    {
      g_set_error (error, 0, 0,
                   _("Curves does not operate on indexed layers."));
      return FALSE;
    }

  gimp_config_reset (GIMP_CONFIG (c_tool->config));

  GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error);

  /*  always pick colors  */
  gimp_color_tool_enable (GIMP_COLOR_TOOL (tool),
                          GIMP_COLOR_TOOL_GET_OPTIONS (tool));

  gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (c_tool->channel_menu),
                                      curves_menu_sensitivity, drawable, NULL);

  histogram = gimp_histogram_new ();
  gimp_drawable_calculate_histogram (drawable, histogram);
  gimp_histogram_view_set_background (GIMP_HISTOGRAM_VIEW (c_tool->graph),
                                      histogram);
  gimp_histogram_unref (histogram);

  return TRUE;
}
Esempio n. 18
0
static void
gimp_curves_tool_dialog (GimpImageMapTool *image_map_tool)
{
  GimpCurvesTool   *tool         = GIMP_CURVES_TOOL (image_map_tool);
  GimpToolOptions  *tool_options = GIMP_TOOL_GET_OPTIONS (image_map_tool);
  GimpCurvesConfig *config       = tool->config;
  GtkListStore     *store;
  GtkSizeGroup     *label_group;
  GtkWidget        *main_vbox;
  GtkWidget        *vbox;
  GtkWidget        *hbox;
  GtkWidget        *hbox2;
  GtkWidget        *label;
  GtkWidget        *frame;
  GtkWidget        *table;
  GtkWidget        *button;
  GtkWidget        *bar;
  GtkWidget        *combo;

  g_signal_connect (image_map_tool->settings_box, "file-dialog-setup",
                    G_CALLBACK (gimp_curves_tool_export_setup),
                    image_map_tool);

  main_vbox   = gimp_image_map_tool_dialog_get_vbox (image_map_tool);
  label_group = gimp_image_map_tool_dialog_get_label_group (image_map_tool);

  /*  The combo box for selecting channels  */
  hbox = gtk_hbox_new (FALSE, 6);
  gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
  gtk_widget_show (hbox);

  label = gtk_label_new_with_mnemonic (_("Cha_nnel:"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  gtk_size_group_add_widget (label_group, label);

  store = gimp_enum_store_new_with_range (GIMP_TYPE_HISTOGRAM_CHANNEL,
                                          GIMP_HISTOGRAM_VALUE,
                                          GIMP_HISTOGRAM_ALPHA);
  tool->channel_menu =
    gimp_enum_combo_box_new_with_model (GIMP_ENUM_STORE (store));
  g_object_unref (store);

  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (tool->channel_menu),
                                 config->channel);
  gimp_enum_combo_box_set_stock_prefix (GIMP_ENUM_COMBO_BOX (tool->channel_menu),
                                        "gimp-channel");
  gtk_box_pack_start (GTK_BOX (hbox), tool->channel_menu, FALSE, FALSE, 0);
  gtk_widget_show (tool->channel_menu);

  g_signal_connect (tool->channel_menu, "changed",
                    G_CALLBACK (curves_channel_callback),
                    tool);

  gtk_label_set_mnemonic_widget (GTK_LABEL (label), tool->channel_menu);

  button = gtk_button_new_with_mnemonic (_("R_eset Channel"));
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
  gtk_widget_show (button);

  g_signal_connect (button, "clicked",
                    G_CALLBACK (curves_channel_reset_callback),
                    tool);

  /*  The histogram scale radio buttons  */
  hbox2 = gimp_prop_enum_stock_box_new (G_OBJECT (tool_options),
                                        "histogram-scale", "gimp-histogram",
                                        0, 0);
  gtk_box_pack_end (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
  gtk_widget_show (hbox2);

  /*  The table for the color bars and the graph  */
  table = gtk_table_new (2, 2, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 2);
  gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  gtk_box_pack_start (GTK_BOX (main_vbox), table, TRUE, TRUE, 0);

  /*  The left color bar  */
  vbox = gtk_vbox_new (FALSE, 0);
  gtk_table_attach (GTK_TABLE (table), vbox, 0, 1, 0, 1,
                    GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (vbox);

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, RADIUS);
  gtk_widget_show (frame);

  tool->yrange = gimp_color_bar_new (GTK_ORIENTATION_VERTICAL);
  gtk_widget_set_size_request (tool->yrange, BAR_SIZE, -1);
  gtk_container_add (GTK_CONTAINER (frame), tool->yrange);
  gtk_widget_show (tool->yrange);

  /*  The curves graph  */
  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1,
                    GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (frame);

  tool->graph = gimp_curve_view_new ();
  gtk_widget_set_size_request (tool->graph,
                               GRAPH_SIZE + RADIUS * 2,
                               GRAPH_SIZE + RADIUS * 2);
  g_object_set (tool->graph,
                "border-width", RADIUS,
                "subdivisions", 1,
                NULL);
  gimp_curve_view_set_curve (GIMP_CURVE_VIEW (tool->graph),
                             config->curve[config->channel]);
  gtk_container_add (GTK_CONTAINER (frame), tool->graph);
  gtk_widget_show (tool->graph);

  gimp_histogram_options_connect_view (GIMP_HISTOGRAM_OPTIONS (tool_options),
                                       GIMP_HISTOGRAM_VIEW (tool->graph));

  /*  The bottom color bar  */
  hbox2 = gtk_hbox_new (FALSE, 0);
  gtk_table_attach (GTK_TABLE (table), hbox2, 1, 2, 1, 2,
                    GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (hbox2);

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX (hbox2), frame, TRUE, TRUE, RADIUS);
  gtk_widget_show (frame);

  vbox = gtk_vbox_new (TRUE, 0);
  gtk_container_add (GTK_CONTAINER (frame), vbox);
  gtk_widget_show (vbox);

  tool->xrange = gimp_color_bar_new (GTK_ORIENTATION_HORIZONTAL);
  gtk_widget_set_size_request (tool->xrange, -1, BAR_SIZE / 2);
  gtk_box_pack_start (GTK_BOX (vbox), tool->xrange, TRUE, TRUE, 0);
  gtk_widget_show (tool->xrange);

  bar = gimp_color_bar_new (GTK_ORIENTATION_HORIZONTAL);
  gtk_box_pack_start (GTK_BOX (vbox), bar, TRUE, TRUE, 0);
  gtk_widget_show (bar);

  gtk_widget_show (table);

  hbox = gtk_hbox_new (FALSE, 6);
  gtk_box_pack_end (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
  gtk_widget_show (hbox);

  label = gtk_label_new_with_mnemonic (_("Curve _type:"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  tool->curve_type = combo = gimp_enum_combo_box_new (GIMP_TYPE_CURVE_TYPE);
  gimp_enum_combo_box_set_stock_prefix (GIMP_ENUM_COMBO_BOX (combo),
                                        "gimp-curve");
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), 0,
                              G_CALLBACK (curves_curve_type_callback),
                              tool);
  gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
  gtk_widget_show (combo);

  gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
}