home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / tool_options.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  30.0 KB  |  943 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <glib.h>
  22.  
  23. #include "apptypes.h"
  24.  
  25. #include "brush_select.h"
  26. #include "gimprc.h"
  27. #include "gimpui.h"
  28. #include "paint_funcs.h"
  29. #include "paint_options.h"
  30. #include "selection_options.h"
  31. #include "gtkhwrapbox.h"
  32.  
  33. #include "libgimp/gimpunitmenu.h"
  34.  
  35. #include "libgimp/gimpintl.h"
  36.  
  37.  
  38. /*  declared extern in paint_options.h  */
  39. PaintPressureOptions non_gui_pressure_options = 
  40. {
  41.   NULL,
  42.   FALSE, FALSE, NULL,
  43.   FALSE, FALSE, NULL,
  44.   FALSE, FALSE, NULL,
  45.   FALSE, FALSE, NULL,
  46.   FALSE, FALSE, NULL
  47. };
  48.  
  49.  
  50. /*  a list of all PaintOptions  */
  51. static GSList  *paint_options_list = NULL;
  52.  
  53. static PaintPressureOptions * paint_pressure_options_new   (ToolType);
  54. static void                   paint_pressure_options_reset (PaintPressureOptions *);
  55.  
  56.  
  57. /*  ui helper functions  ******************************************************/
  58.  
  59. static void
  60. tool_options_opacity_adjustment_update (GtkAdjustment *adjustment,
  61.                     gpointer       data)
  62. {
  63.   gtk_signal_handler_block_by_data (GTK_OBJECT (data), adjustment);
  64.   gimp_context_set_opacity (GIMP_CONTEXT (data),
  65.                 adjustment->value / 100);
  66.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (data), adjustment);
  67. }
  68.  
  69. static void
  70. tool_options_opacity_changed (GimpContext *context,
  71.                   gdouble      opacity,
  72.                   gpointer     data)
  73. {
  74.   gtk_signal_handler_block_by_data (GTK_OBJECT (data), context);
  75.   gtk_adjustment_set_value (GTK_ADJUSTMENT (data), opacity * 100);
  76.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (data), context);
  77. }
  78.  
  79. static void
  80. tool_options_paint_mode_update (GtkWidget *widget,
  81.                 gpointer   data)
  82. {
  83.   LayerModeEffects  paint_mode;
  84.   PaintOptions     *options;
  85.  
  86.   paint_mode = (LayerModeEffects) gtk_object_get_user_data (GTK_OBJECT (widget));
  87.   options    = (PaintOptions *) data;
  88.  
  89.   gtk_signal_handler_block_by_data (GTK_OBJECT (options->context),
  90.                     options->paint_mode_w);
  91.   gimp_context_set_paint_mode (GIMP_CONTEXT (options->context), paint_mode);
  92.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (options->context),
  93.                       options->paint_mode_w);
  94. }
  95.  
  96. static void
  97. tool_options_paint_mode_changed (GimpContext      *context,
  98.                  LayerModeEffects  paint_mode,
  99.                  gpointer          data)
  100. {
  101.   gimp_option_menu_set_history (GTK_OPTION_MENU (data), (gpointer) paint_mode);
  102. }
  103.  
  104. /*  tool options functions  ***************************************************/
  105.  
  106. void
  107. tool_options_init (ToolOptions          *options,
  108.            gchar                *title,
  109.            ToolOptionsResetFunc  reset_func)
  110. {
  111.   options->main_vbox  = gtk_vbox_new (FALSE, 2);
  112.   options->title      = title;
  113.   options->reset_func = reset_func;
  114. }
  115.  
  116. ToolOptions *
  117. tool_options_new (gchar *title)
  118. {
  119.   ToolOptions *options;
  120.  
  121.   GtkWidget *label;
  122.  
  123.   options = g_new (ToolOptions, 1);
  124.   tool_options_init (options, title, NULL);
  125.  
  126.   label = gtk_label_new (_("This tool has no options."));
  127.   gtk_box_pack_start (GTK_BOX (options->main_vbox), label, FALSE, FALSE, 6);
  128.   gtk_widget_show (label);
  129.  
  130.   return options;
  131. }
  132.  
  133. /*  selection tool options functions  *****************************************/
  134.  
  135. void
  136. selection_options_init (SelectionOptions     *options,
  137.             ToolType              tool_type,
  138.             ToolOptionsResetFunc  reset_func)
  139. {
  140.   GtkWidget *vbox;
  141.   GtkWidget *abox;
  142.   GtkWidget *table;
  143.   GtkWidget *label;
  144.   GtkWidget *scale;
  145.   GtkWidget *separator;
  146.  
  147.   /*  initialize the tool options structure  */
  148.   tool_options_init ((ToolOptions *) options,
  149.              ((tool_type == RECT_SELECT) ?
  150.               _("Rectangular Selection") :
  151.               ((tool_type == ELLIPSE_SELECT) ?
  152.                _("Elliptical Selection") :
  153.                ((tool_type == FREE_SELECT) ?
  154.             _("Free-Hand Selection") :
  155.             ((tool_type == FUZZY_SELECT) ?
  156.              _("Fuzzy Selection") :
  157.              ((tool_type == BEZIER_SELECT) ?
  158.               _("Bezier Selection") :
  159.               ((tool_type == ISCISSORS) ?
  160.                _("Intelligent Scissors") :
  161.                ((tool_type == BY_COLOR_SELECT) ?
  162.                 _("By-Color Selection") :
  163.                 "ERROR: Unknown Select Tool Type"))))))),
  164.              reset_func);
  165.  
  166.   /*  the main vbox  */
  167.   vbox = options->tool_options.main_vbox;
  168.  
  169.   /*  initialize the selection options structure  */
  170.   options->feather        = options->feather_d        = FALSE;
  171.   options->feather_radius = options->feather_radius_d = 10.0;
  172.   options->antialias      = options->antialias_d      = TRUE;
  173.   options->sample_merged  = options->sample_merged_d  = FALSE;
  174.   options->threshold                                  = default_threshold;
  175.   options->fixed_size     = options->fixed_size_d     = FALSE;
  176.   options->fixed_height   = options->fixed_height_d   = 1;
  177.   options->fixed_width    = options->fixed_width_d    = 1;
  178.   options->fixed_unit     = options->fixed_unit_d     = GIMP_UNIT_PIXEL;
  179.  
  180.   options->feather_w        = NULL;
  181.   options->feather_radius_w = NULL;
  182.   options->antialias_w      = NULL;
  183.   options->sample_merged_w  = NULL;
  184.   options->threshold_w      = NULL;
  185.   options->fixed_size_w     = NULL;
  186.   options->fixed_height_w   = NULL;
  187.   options->fixed_width_w    = NULL;
  188.   options->fixed_unit_w     = NULL;
  189.  
  190.   /*  the feather toggle button  */
  191.   table = gtk_table_new (2, 2, FALSE);
  192.   gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  193.   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  194.  
  195.   options->feather_w = gtk_check_button_new_with_label (_("Feather"));
  196.   gtk_table_attach (GTK_TABLE (table), options->feather_w, 0, 1, 0, 1,
  197.             GTK_SHRINK | GTK_FILL, GTK_SHRINK, 0, 0);
  198.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->feather_w),
  199.                 options->feather_d);
  200.   gtk_signal_connect (GTK_OBJECT (options->feather_w), "toggled",
  201.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  202.               &options->feather);
  203.   gtk_widget_show (options->feather_w);
  204.  
  205.   /*  the feather radius scale  */
  206.   label = gtk_label_new (_("Radius:"));
  207.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
  208.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
  209.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  210.   gtk_widget_show (label);
  211.  
  212.   abox = gtk_alignment_new (0.5, 1.0, 1.0, 0.0);
  213.   gtk_table_attach (GTK_TABLE (table), abox, 1, 2, 0, 2,
  214.             GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  215.   gtk_widget_show (abox);
  216.  
  217.   options->feather_radius_w =
  218.     gtk_adjustment_new (options->feather_radius_d, 0.0, 100.0, 1.0, 1.0, 1.0);
  219.   scale = gtk_hscale_new (GTK_ADJUSTMENT (options->feather_radius_w));
  220.   gtk_container_add (GTK_CONTAINER (abox), scale);
  221.   gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
  222.   gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
  223.   gtk_signal_connect (GTK_OBJECT (options->feather_radius_w), "value_changed",
  224.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  225.               &options->feather_radius);
  226.   gtk_widget_show (scale);
  227.  
  228.   /*  grey out label & scale if feather is off  */
  229.   gtk_widget_set_sensitive (scale, options->feather_d);
  230.   gtk_widget_set_sensitive (label, options->feather_d);
  231.   gtk_object_set_data (GTK_OBJECT (options->feather_w), "set_sensitive", scale);
  232.   gtk_object_set_data (GTK_OBJECT (scale), "set_sensitive", label);
  233.  
  234.   gtk_widget_show (table);
  235.  
  236.   /*  the antialias toggle button  */
  237.   if (tool_type != RECT_SELECT)
  238.     {
  239.       options->antialias_w = gtk_check_button_new_with_label (_("Antialiasing"));
  240.       gtk_box_pack_start (GTK_BOX (vbox), options->antialias_w, FALSE, FALSE, 0);
  241.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->antialias_w),
  242.                     options->antialias_d);
  243.       gtk_signal_connect (GTK_OBJECT (options->antialias_w), "toggled",
  244.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  245.               &options->antialias);
  246.       gtk_widget_show (options->antialias_w);
  247.     }
  248.  
  249.   /*  a separator between the common and tool-specific selection options  */
  250.   switch (tool_type)
  251.     {
  252.     case FREE_SELECT:
  253.     case BEZIER_SELECT:
  254.     case ISCISSORS:
  255.       break;
  256.     case RECT_SELECT:
  257.     case ELLIPSE_SELECT:
  258.     case FUZZY_SELECT:
  259.     case BY_COLOR_SELECT:
  260.       separator = gtk_hseparator_new ();
  261.       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
  262.       gtk_widget_show (separator);
  263.       break;
  264.     default:
  265.       break;
  266.     }
  267.  
  268.   /*  selection tools which operate on contiguous regions  */
  269.   if (tool_type == FUZZY_SELECT)
  270.     {
  271.       GtkWidget *hbox;
  272.  
  273.       /*  the sample merged toggle  */
  274.       options->sample_merged_w =
  275.     gtk_check_button_new_with_label (_("Sample Merged"));
  276.       gtk_box_pack_start (GTK_BOX (vbox), options->sample_merged_w,
  277.               FALSE, FALSE, 0);
  278.       gtk_signal_connect (GTK_OBJECT (options->sample_merged_w), "toggled",
  279.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  280.               &options->sample_merged);
  281.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->sample_merged_w),
  282.                     options->sample_merged_d);
  283.       gtk_widget_show (options->sample_merged_w);
  284.  
  285.       /*  the threshold scale  */
  286.       hbox = gtk_hbox_new (FALSE, 1);
  287.       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  288.       gtk_widget_show (hbox);
  289.   
  290.       label = gtk_label_new (_("Threshold:"));
  291.       gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
  292.       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 1);
  293.       gtk_widget_show (label);
  294.  
  295.       options->threshold_w = 
  296.     gtk_adjustment_new (default_threshold, 0.0, 255.0, 1.0, 1.0, 0.0);
  297.       scale = gtk_hscale_new (GTK_ADJUSTMENT (options->threshold_w));
  298.       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
  299.       gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
  300.       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
  301.       gtk_signal_connect (GTK_OBJECT (options->threshold_w), "value_changed",
  302.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  303.               &options->threshold);
  304.       gtk_widget_show (scale);
  305.     }
  306.  
  307.   /*  widgets for fixed size select  */
  308.   if (tool_type == RECT_SELECT || tool_type == ELLIPSE_SELECT)
  309.     {
  310.       GtkWidget *alignment;
  311.       GtkWidget *table;
  312.       GtkWidget *width_spinbutton;
  313.       GtkWidget *height_spinbutton;
  314.  
  315.       options->fixed_size_w =
  316.     gtk_check_button_new_with_label (_("Fixed Size / Aspect Ratio"));
  317.       gtk_box_pack_start (GTK_BOX (vbox), options->fixed_size_w,
  318.               FALSE, FALSE, 0);
  319.       gtk_signal_connect (GTK_OBJECT (options->fixed_size_w), "toggled",
  320.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  321.               &options->fixed_size);
  322.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->fixed_size_w),
  323.                     options->fixed_size_d);
  324.       gtk_widget_show (options->fixed_size_w);
  325.  
  326.       alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  327.       gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
  328.       gtk_widget_show (alignment);
  329.  
  330.       table = gtk_table_new (3, 2, FALSE);
  331.       gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  332.       gtk_table_set_row_spacings (GTK_TABLE (table), 1);
  333.       gtk_container_add (GTK_CONTAINER (alignment), table);
  334.  
  335.       /*  grey out the table if fixed size is off  */
  336.       gtk_widget_set_sensitive (table, options->fixed_size_d);
  337.       gtk_object_set_data (GTK_OBJECT (options->fixed_size_w), "set_sensitive",
  338.                table);
  339.  
  340.       options->fixed_width_w =
  341.     gtk_adjustment_new (options->fixed_width_d, 1e-5, 32767.0,
  342.                 1.0, 50.0, 0.0);
  343.       width_spinbutton =
  344.     gtk_spin_button_new (GTK_ADJUSTMENT (options->fixed_width_w), 1.0, 0.0);
  345.       gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON(width_spinbutton),
  346.                        GTK_SHADOW_NONE);
  347.       gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (width_spinbutton), TRUE);
  348.       gtk_widget_set_usize (width_spinbutton, 75, 0);
  349.       gtk_signal_connect (GTK_OBJECT (options->fixed_width_w), "value_changed",
  350.                           GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  351.                           &options->fixed_width);
  352.       gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  353.                  _("Width:"), 1.0, 0.5,
  354.                  width_spinbutton, 1, FALSE);
  355.  
  356.       options->fixed_height_w =
  357.     gtk_adjustment_new (options->fixed_height_d, 1e-5, 32767.0,
  358.                 1.0, 50.0, 0.0);
  359.       height_spinbutton =
  360.     gtk_spin_button_new (GTK_ADJUSTMENT (options->fixed_height_w), 1.0, 0.0);
  361.       gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON(height_spinbutton),
  362.                        GTK_SHADOW_NONE);
  363.       gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(height_spinbutton), TRUE);
  364.       gtk_widget_set_usize (height_spinbutton, 75, 0);
  365.       gtk_signal_connect (GTK_OBJECT (options->fixed_height_w), "value_changed",
  366.                           GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  367.                           &options->fixed_height);
  368.       gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  369.                  _("Height:"), 1.0, 0.5,
  370.                  height_spinbutton, 1, FALSE);
  371.  
  372.       options->fixed_unit_w =
  373.     gimp_unit_menu_new ("%a", options->fixed_unit_d, TRUE, TRUE, TRUE);
  374.       gtk_signal_connect (GTK_OBJECT (options->fixed_unit_w), "unit_changed",
  375.                           GTK_SIGNAL_FUNC (gimp_unit_menu_update),
  376.                           &options->fixed_unit);
  377.       gtk_object_set_data (GTK_OBJECT (options->fixed_unit_w), "set_digits",
  378.                width_spinbutton);
  379.       gtk_object_set_data (GTK_OBJECT (width_spinbutton), "set_digits",
  380.                height_spinbutton);
  381.       gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
  382.                  _("Unit:"), 1.0, 0.5,
  383.                  options->fixed_unit_w, 1, FALSE);
  384.  
  385.       gtk_widget_show (table);
  386.     }
  387. }
  388.  
  389. SelectionOptions *
  390. selection_options_new (ToolType              tool_type,
  391.                ToolOptionsResetFunc  reset_func)
  392. {
  393.   SelectionOptions *options;
  394.  
  395.   options = g_new (SelectionOptions, 1);
  396.   selection_options_init (options, tool_type, reset_func);
  397.  
  398.   return options;
  399. }
  400.  
  401. void
  402. selection_options_reset (SelectionOptions *options)
  403. {
  404.   if (options->feather_w)
  405.     {
  406.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->feather_w),
  407.                     options->feather_d);
  408.       gtk_adjustment_set_value (GTK_ADJUSTMENT (options->feather_radius_w),
  409.                 options->feather_radius_d);
  410.     }
  411.  
  412.   if (options->antialias_w)
  413.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->antialias_w),
  414.                   options->antialias_d);
  415.  
  416.   if (options->sample_merged_w)
  417.     {
  418.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->sample_merged_w),
  419.                     options->sample_merged_d);
  420.       gtk_adjustment_set_value (GTK_ADJUSTMENT (options->threshold_w),
  421.                 default_threshold);
  422.     }
  423.  
  424.   if (options->fixed_size_w)
  425.     {
  426.       GtkWidget *spinbutton;
  427.       gint       digits;
  428.  
  429.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(options->fixed_size_w),
  430.                     options->fixed_size_d);
  431.       gtk_adjustment_set_value (GTK_ADJUSTMENT (options->fixed_width_w),
  432.                 options->fixed_width_d);
  433.       gtk_adjustment_set_value (GTK_ADJUSTMENT (options->fixed_height_w),
  434.                 options->fixed_height_d);
  435.  
  436.       options->fixed_unit = options->fixed_unit_d;
  437.       gimp_unit_menu_set_unit (GIMP_UNIT_MENU (options->fixed_unit_w),
  438.                    options->fixed_unit_d);
  439.  
  440.       digits =
  441.     ((options->fixed_unit_d == GIMP_UNIT_PIXEL) ? 0 :
  442.      ((options->fixed_unit_d == GIMP_UNIT_PERCENT) ? 2 :
  443.       (MIN (6, MAX (3, gimp_unit_get_digits (options->fixed_unit_d))))));
  444.  
  445.       spinbutton =
  446.     gtk_object_get_data (GTK_OBJECT (options->fixed_unit_w), "set_digits");
  447.       while (spinbutton)
  448.     {
  449.       gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinbutton), digits);
  450.       spinbutton =
  451.         gtk_object_get_data (GTK_OBJECT (spinbutton), "set_digits");
  452.     }
  453.     }
  454. }
  455.  
  456.  
  457. /*  paint tool options functions  *********************************************/
  458.  
  459. void
  460. paint_options_init (PaintOptions         *options,
  461.             ToolType              tool_type,
  462.             ToolOptionsResetFunc  reset_func)
  463. {
  464.   GtkWidget *vbox;
  465.   GtkWidget *table;
  466.   GtkWidget *scale;
  467.   GtkWidget *separator;
  468.  
  469.   GimpContext *tool_context = tool_info[tool_type].tool_context;
  470.  
  471.   /*  initialize the tool options structure  */
  472.   tool_options_init ((ToolOptions *) options,
  473.              ((tool_type == BUCKET_FILL) ?
  474.               _("Bucket Fill") :
  475.               ((tool_type == BLEND) ?
  476.                _("Blend Tool") :
  477.                ((tool_type == PENCIL) ?
  478.             _("Pencil") :
  479.             ((tool_type == PAINTBRUSH) ?
  480.              _("Paintbrush") :
  481.              ((tool_type == ERASER) ?
  482.               _("Eraser") :
  483.               ((tool_type == AIRBRUSH) ?
  484.                _("Airbrush") :
  485.                ((tool_type == CLONE) ?
  486.                 _("Clone Tool") :
  487.                 ((tool_type == CONVOLVE) ?
  488.                  _("Convolver") :
  489.                  ((tool_type == INK) ?
  490.                   _("Ink Tool") :
  491.                   ((tool_type == DODGEBURN) ?
  492.                    _("Dodge or Burn") :
  493.                    ((tool_type == SMUDGE) ?
  494.                 _("Smudge Tool") :
  495. /*                  ((tool_type == XINPUT_AIRBRUSH) ? */
  496. /*                   _("Xinput Airbrush") : */
  497.                  "ERROR: Unknown Paint Tool Type"))))))))))),
  498.              reset_func);
  499.  
  500.   /*  initialize the paint options structure  */
  501.   options->global           = NULL;
  502.   options->opacity_w        = NULL;
  503.   options->paint_mode_w     = NULL;
  504.   options->context          = tool_context;
  505.   options->incremental_w    = NULL;
  506.   options->incremental = options->incremental_d = FALSE;
  507.   options->pressure_options = NULL;
  508.  
  509.   /*  the main vbox  */
  510.   vbox = gtk_vbox_new (FALSE, 2);
  511.   gtk_box_pack_start (GTK_BOX (options->tool_options.main_vbox), vbox,
  512.               FALSE, FALSE, 0);
  513.   options->paint_vbox = vbox;
  514.  
  515.   /*  the main table  */
  516.   table = gtk_table_new (2, 2, FALSE);
  517.   gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  518.   gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
  519.  
  520.   /*  the opacity scale  */
  521.   options->opacity_w =
  522.     gtk_adjustment_new (gimp_context_get_opacity (tool_context) * 100,
  523.             0.0, 100.0, 1.0, 1.0, 0.0);
  524.   scale = gtk_hscale_new (GTK_ADJUSTMENT (options->opacity_w));
  525.   gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
  526.   gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
  527.   gtk_signal_connect (GTK_OBJECT (options->opacity_w), "value_changed",
  528.               GTK_SIGNAL_FUNC (tool_options_opacity_adjustment_update),
  529.               tool_context);
  530.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  531.                  _("Opacity:"), 1.0, 1.0,
  532.                  scale, 1, FALSE);
  533.  
  534.   gtk_signal_connect (GTK_OBJECT (tool_context), "opacity_changed",
  535.               GTK_SIGNAL_FUNC (tool_options_opacity_changed),
  536.               options->opacity_w);
  537.  
  538.   /*  the paint mode menu  */
  539.   switch (tool_type)
  540.     {
  541.     case BUCKET_FILL:
  542.     case BLEND:
  543.     case PENCIL:
  544.     case PAINTBRUSH:
  545.     case AIRBRUSH:
  546.     case CLONE:
  547.     case INK:
  548. /*      case XINPUT_AIRBRUSH: */
  549.       gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
  550.  
  551.       options->paint_mode_w =
  552.     paint_mode_menu_new (tool_options_paint_mode_update, options,
  553.                  gimp_context_get_paint_mode (tool_context));
  554.       gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  555.                  _("Mode:"), 1.0, 0.5,
  556.                  options->paint_mode_w, 1, TRUE);
  557.  
  558.       gtk_signal_connect (GTK_OBJECT (tool_context), "paint_mode_changed",
  559.               GTK_SIGNAL_FUNC (tool_options_paint_mode_changed),
  560.               options->paint_mode_w);
  561.       break;
  562.     case CONVOLVE:
  563.     case ERASER:
  564.     case DODGEBURN:
  565.     case SMUDGE:
  566.       break;
  567.     default:
  568.       break;
  569.     }
  570.  
  571.   /*  show the main table  */
  572.   gtk_widget_show (table);
  573.  
  574.   /*  a separator after the common paint options which can be global  */
  575.   switch (tool_type)
  576.     {
  577.     case BUCKET_FILL:
  578.     case BLEND:
  579.     case INK:
  580.       /* case XINPUT_AIRBRUSH: */
  581.       separator = gtk_hseparator_new ();
  582.       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
  583.       gtk_widget_show (separator);
  584.       break;
  585.     case PENCIL:
  586.     case PAINTBRUSH:
  587.     case ERASER:
  588.     case AIRBRUSH:
  589.     case CLONE:
  590.     case CONVOLVE:
  591.     case DODGEBURN:
  592.     case SMUDGE:
  593.       break;
  594.     default:
  595.       break;
  596.     }
  597.  
  598.   if (! global_paint_options)
  599.     gtk_widget_show (vbox);
  600.  
  601.   /*  the "incremental" toggle  */
  602.   switch (tool_type)
  603.     {
  604.     case AIRBRUSH:
  605.     case ERASER:
  606.     case PAINTBRUSH:
  607.     case PENCIL:
  608.       options->incremental_w =
  609.     gtk_check_button_new_with_label (_("Incremental"));
  610.       gtk_box_pack_start (GTK_BOX (options->tool_options.main_vbox),
  611.               options->incremental_w, FALSE, FALSE, 0);
  612.       gtk_signal_connect (GTK_OBJECT (options->incremental_w), "toggled",
  613.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  614.               &options->incremental);
  615.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->incremental_w),
  616.                     options->incremental_d);
  617.       gtk_widget_show (options->incremental_w);
  618.  
  619.     case BUCKET_FILL:
  620.     case BLEND:
  621.     case CLONE:
  622.     case CONVOLVE:
  623.     case DODGEBURN:
  624.     case SMUDGE:
  625.       break;
  626.     default:
  627.       break;
  628.     }
  629.  
  630.   options->pressure_options = paint_pressure_options_new (tool_type);
  631.  
  632.   if (options->pressure_options->frame)
  633.     {
  634.       gtk_box_pack_start (GTK_BOX (options->tool_options.main_vbox),
  635.               options->pressure_options->frame, FALSE, FALSE, 0);
  636.       gtk_widget_show (options->pressure_options->frame);
  637.     }
  638.  
  639.   /*  register this Paintoptions structure  */
  640.   paint_options_list = g_slist_prepend (paint_options_list, options);
  641. }
  642.  
  643. PaintOptions *
  644. paint_options_new (ToolType              tool_type,
  645.            ToolOptionsResetFunc  reset_func)
  646. {
  647.   PaintOptions *options;
  648.  
  649.   options = g_new (PaintOptions, 1);
  650.   paint_options_init (options, tool_type, reset_func);
  651.  
  652.   if (global_paint_options && options->global)
  653.     gtk_widget_show (options->global);
  654.  
  655.   return options;
  656. }
  657.  
  658. void
  659. paint_options_reset (PaintOptions *options)
  660. {
  661.   GimpContext *default_context;
  662.  
  663.   default_context = gimp_context_get_default ();
  664.  
  665.   if (options->opacity_w)
  666.     {
  667.       gimp_context_set_opacity (GIMP_CONTEXT (options->context),
  668.                 gimp_context_get_opacity (default_context));
  669.     }
  670.   if (options->paint_mode_w)
  671.     {
  672.       gimp_context_set_paint_mode (GIMP_CONTEXT (options->context),
  673.                    gimp_context_get_paint_mode (default_context));
  674.     }
  675.   if (options->incremental_w)
  676.     {
  677.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->incremental_w),
  678.                     options->incremental_d);
  679.     }
  680.  
  681.   paint_pressure_options_reset (options->pressure_options);
  682. }
  683.  
  684. static PaintPressureOptions *
  685. paint_pressure_options_new (ToolType tool_type)
  686. {
  687.   PaintPressureOptions *pressure = NULL;
  688.   GtkWidget *frame = NULL;
  689.   GtkWidget *wbox = NULL;
  690.  
  691.   pressure = g_new (PaintPressureOptions, 1);
  692.  
  693.   pressure->opacity  = pressure->opacity_d  = TRUE;
  694.   pressure->pressure = pressure->pressure_d = TRUE;
  695.   pressure->rate     = pressure->rate_d     = FALSE;
  696.   pressure->size     = pressure->size_d     = FALSE;
  697.   pressure->color    = pressure->color_d    = FALSE;
  698.  
  699.   pressure->opacity_w  = NULL;
  700.   pressure->pressure_w = NULL;
  701.   pressure->rate_w     = NULL;
  702.   pressure->size_w     = NULL;
  703.   pressure->color_w    = NULL;
  704.  
  705.   switch (tool_type)
  706.     {
  707.     case AIRBRUSH:
  708.     case CLONE:
  709.     case CONVOLVE:
  710.     case DODGEBURN:
  711.     case ERASER:
  712.     case PAINTBRUSH:
  713.     case PENCIL:
  714.     case SMUDGE:
  715.       frame = gtk_frame_new (_("Pressure Sensitivity"));
  716.       wbox = gtk_hwrap_box_new (FALSE);
  717.       gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (wbox), 6);
  718.       gtk_container_add (GTK_CONTAINER (frame), wbox);
  719.       gtk_widget_show (wbox);
  720.       break;
  721.     default:
  722.       break;
  723.     }
  724.  
  725.   /*  the opacity toggle  */
  726.   switch (tool_type)
  727.     {
  728.     case CLONE:
  729.     case DODGEBURN:
  730.     case ERASER:
  731.     case PAINTBRUSH:
  732.     case PENCIL:
  733.       pressure->opacity_w =
  734.     gtk_check_button_new_with_label (_("Opacity"));
  735.       gtk_container_add (GTK_CONTAINER (wbox), pressure->opacity_w);
  736.       gtk_signal_connect (GTK_OBJECT (pressure->opacity_w), "toggled",
  737.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  738.               &pressure->opacity);
  739.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->opacity_w),
  740.                     pressure->opacity_d);
  741.       gtk_widget_show (pressure->opacity_w);
  742.       break;
  743.     default:
  744.       break;
  745.     }
  746.  
  747.  /*  the pressure toggle  */
  748.   switch (tool_type)
  749.     {
  750.     case AIRBRUSH:
  751.     case CLONE:
  752.     case CONVOLVE:
  753.     case DODGEBURN:
  754.     case ERASER:
  755.     case PAINTBRUSH:
  756.     case SMUDGE:
  757.       pressure->pressure_w = gtk_check_button_new_with_label (_("Hardness"));
  758.       gtk_container_add (GTK_CONTAINER (wbox), pressure->pressure_w);
  759.       gtk_signal_connect (GTK_OBJECT (pressure->pressure_w), "toggled",
  760.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  761.               &pressure->pressure);
  762.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->pressure_w),
  763.                     pressure->pressure_d);
  764.       gtk_widget_show (pressure->pressure_w);
  765.       break;
  766.     default:
  767.       break;
  768.     }
  769.  
  770.   /*  the rate toggle */
  771.   switch (tool_type)
  772.     {
  773.     case AIRBRUSH:
  774.     case CONVOLVE:
  775.     case SMUDGE:
  776.       pressure->rate_w =
  777.     gtk_check_button_new_with_label (_("Rate"));
  778.       gtk_container_add (GTK_CONTAINER (wbox), pressure->rate_w);
  779.       gtk_signal_connect (GTK_OBJECT (pressure->rate_w), "toggled",
  780.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  781.               &pressure->rate);
  782.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->rate_w),
  783.                     pressure->rate_d);
  784.       gtk_widget_show (pressure->rate_w);
  785.       break;
  786.     default:
  787.       break;
  788.     }
  789.  
  790.   /*  the size toggle  */
  791.   switch (tool_type)
  792.     {
  793.     case AIRBRUSH:
  794.     case CLONE:
  795.     case CONVOLVE:
  796.     case DODGEBURN:
  797.     case ERASER:
  798.     case PAINTBRUSH:
  799.     case PENCIL:
  800.       pressure->size_w =
  801.     gtk_check_button_new_with_label (_("Size"));
  802.       gtk_container_add (GTK_CONTAINER (wbox), pressure->size_w);
  803.       gtk_signal_connect (GTK_OBJECT (pressure->size_w), "toggled",
  804.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  805.               &pressure->size);
  806.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->size_w),
  807.                     pressure->size_d);
  808.       gtk_widget_show (pressure->size_w);
  809.       break;
  810.     default:
  811.       break;
  812.     }
  813.  
  814.   /*  the color toggle  */
  815.   switch (tool_type)
  816.     {
  817.     case AIRBRUSH:
  818.     case PAINTBRUSH:
  819.     case PENCIL:
  820.       pressure->color_w =
  821.     gtk_check_button_new_with_label (_("Color"));
  822.       gtk_container_add (GTK_CONTAINER (wbox), pressure->color_w);
  823.       gtk_signal_connect (GTK_OBJECT (pressure->color_w), "toggled",
  824.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  825.               &pressure->color);
  826.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->color_w),
  827.                     pressure->color_d);
  828.       gtk_widget_show (pressure->color_w);
  829.       break;
  830.     default:
  831.       break;
  832.     }
  833.  
  834.   pressure->frame = frame;
  835.  
  836.   return pressure;
  837. }
  838.  
  839. static void
  840. paint_pressure_options_reset (PaintPressureOptions *pressure)
  841. {
  842.   if (pressure->opacity_w)
  843.     {
  844.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->opacity_w),
  845.                     pressure->opacity_d);
  846.     }
  847.   if (pressure->pressure_w)
  848.     {
  849.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->pressure_w),
  850.                     pressure->pressure_d);
  851.     }
  852.   if (pressure->rate_w)
  853.     {
  854.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->rate_w),
  855.                     pressure->rate_d);
  856.     }
  857.   if (pressure->size_w)
  858.     {
  859.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->size_w),
  860.                     pressure->size_d);
  861.     }
  862.   if (pressure->color_w)
  863.     {
  864.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pressure->color_w),
  865.                     pressure->color_d);
  866.     }
  867. }
  868.  
  869.  
  870. /*  global paint options functions  *******************************************/
  871.  
  872. void
  873. paint_options_set_global (gboolean global)
  874. {
  875.   PaintOptions *options;
  876.   GSList *list;
  877.  
  878.   global = global ? TRUE : FALSE;
  879.  
  880.   if (global_paint_options == global)
  881.     return;
  882.  
  883.   global_paint_options = global;
  884.  
  885.   for (list = paint_options_list; list; list = list->next)
  886.     {
  887.       options = (PaintOptions *) list->data;
  888.  
  889.       if (global)
  890.     {
  891.       if (options->paint_vbox && GTK_WIDGET_VISIBLE (options->paint_vbox))
  892.         gtk_widget_hide (options->paint_vbox);
  893.       if (options->global && ! GTK_WIDGET_VISIBLE (options->global))
  894.         gtk_widget_show (options->global);
  895.     }
  896.       else
  897.     {
  898.       if (options->paint_vbox && ! GTK_WIDGET_VISIBLE (options->paint_vbox))
  899.         gtk_widget_show (options->paint_vbox);
  900.       if (options->global && GTK_WIDGET_VISIBLE (options->global))
  901.         gtk_widget_hide (options->global);
  902.     }
  903.     }
  904.  
  905.   /*  NULL means the main brush selection  */
  906.   brush_select_show_paint_options (NULL, global);
  907. }
  908.  
  909.  
  910. /*  create a paint mode menu  *************************************************/
  911.  
  912. GtkWidget *
  913. paint_mode_menu_new (GtkSignalFunc    callback,
  914.              gpointer         data,
  915.              LayerModeEffects initial)
  916. {
  917.   GtkWidget *menu;
  918.  
  919.   menu = gimp_option_menu_new2
  920.     (FALSE, callback, data, (gpointer) initial,
  921.  
  922.      _("Normal"),          (gpointer) NORMAL_MODE, NULL,
  923.      _("Dissolve"),        (gpointer) DISSOLVE_MODE, NULL,
  924.      _("Behind"),          (gpointer) BEHIND_MODE, NULL,
  925.      _("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL,
  926.      _("Divide (Dodge)"),  (gpointer) DIVIDE_MODE, NULL,
  927.      _("Screen"),          (gpointer) SCREEN_MODE, NULL,
  928.      _("Overlay"),         (gpointer) OVERLAY_MODE, NULL,
  929.      _("Difference"),      (gpointer) DIFFERENCE_MODE, NULL,
  930.      _("Addition"),        (gpointer) ADDITION_MODE, NULL,
  931.      _("Subtract"),        (gpointer) SUBTRACT_MODE, NULL,
  932.      _("Darken Only"),     (gpointer) DARKEN_ONLY_MODE, NULL,
  933.      _("Lighten Only"),    (gpointer) LIGHTEN_ONLY_MODE, NULL,
  934.      _("Hue"),             (gpointer) HUE_MODE, NULL,
  935.      _("Saturation"),      (gpointer) SATURATION_MODE, NULL,
  936.      _("Color"),           (gpointer) COLOR_MODE, NULL,
  937.      _("Value"),           (gpointer) VALUE_MODE, NULL,
  938.  
  939.      NULL);
  940.  
  941.   return menu;
  942. }
  943.