app/brightness_contrast.[ch] app/by_color_select.[ch]

1999-11-22  Michael Natterer  <mitschel@cs.tu-berlin.de>

	* app/brightness_contrast.[ch]
	* app/by_color_select.[ch]
	* app/color_balance.[ch]
	* app/curves.[ch]
	* app/histogram_tool.[ch]
	* app/hue_saturation.[ch]
	* app/levels.[ch]
	* app/posterize.[ch]
	* app/threshold.[ch]: spinbuttons and cleaned up ui for all
	dialog-tools. Added a "Reset" button to all dialogs.

	* app/color_notebook.c: fixed a compiler warning.

	* app/gimpui.[ch]: made gimp_radio_group_new() more general.

	* app/menus.c: removed the <Toolbox>/File/Help submenu.

	* app/tools.c: restored the old behaviour of "tools_initialize()"
	(force the emission of the "tool_changed" signal)
This commit is contained in:
Michael Natterer 1999-11-22 11:14:29 +00:00 committed by Michael Natterer
parent 22f77c5ab7
commit 3711f5587e
77 changed files with 5892 additions and 5837 deletions

View File

@ -1,3 +1,25 @@
1999-11-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/brightness_contrast.[ch]
* app/by_color_select.[ch]
* app/color_balance.[ch]
* app/curves.[ch]
* app/histogram_tool.[ch]
* app/hue_saturation.[ch]
* app/levels.[ch]
* app/posterize.[ch]
* app/threshold.[ch]: spinbuttons and cleaned up ui for all
dialog-tools. Added a "Reset" button to all dialogs.
* app/color_notebook.c: fixed a compiler warning.
* app/gimpui.[ch]: made gimp_radio_group_new() more general.
* app/menus.c: removed the <Toolbox>/File/Help submenu.
* app/tools.c: restored the old behaviour of "tools_initialize()"
(force the emission of the "tool_changed" signal)
Sun Nov 21 22:13:59 CET 1999 Marc Lehmann <pcg@goof.com> Sun Nov 21 22:13:59 CET 1999 Marc Lehmann <pcg@goof.com>
* app/plug_in.c: image_type=="*" enables all (known) * app/plug_in.c: image_type=="*" enables all (known)

View File

@ -15,21 +15,13 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "color_balance.h" #include "color_balance.h"
#include "color_transfer.h" #include "color_transfer.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimpui.h" #include "gimpui.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
static void color_balance_control (Tool *, ToolAction, gpointer); static void color_balance_control (Tool *, ToolAction, gpointer);
static ColorBalanceDialog * color_balance_new_dialog (void); static ColorBalanceDialog * color_balance_dialog_new (void);
static void color_balance_update (ColorBalanceDialog *, int); static void color_balance_update (ColorBalanceDialog *, int);
static void color_balance_preview (ColorBalanceDialog *); static void color_balance_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer); static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer); static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer); static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer); static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer); static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer); static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */ /* The color balance dialog */
if (!color_balance_dialog) if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog (); color_balance_dialog = color_balance_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell)) if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell))
gtk_widget_show (color_balance_dialog->shell); gtk_widget_show (color_balance_dialog->shell);
/* Initialize dialog fields */
color_balance_dialog->image_map = NULL;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
color_balance_dialog->cyan_red[i] = 0.0; color_balance_dialog->cyan_red[i] = 0.0;
color_balance_dialog->magenta_green[i] = 0.0; color_balance_dialog->magenta_green[i] = 0.0;
color_balance_dialog->yellow_blue[i] = 0.0; color_balance_dialog->yellow_blue[i] = 0.0;
} }
color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage); color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = color_balance_dialog->image_map =
image_map_create (gdisp, color_balance_dialog->drawable); image_map_create (gdisp, color_balance_dialog->drawable);
@ -236,13 +226,12 @@ color_balance_initialize (GDisplay *gdisp)
color_balance_update (color_balance_dialog, ALL); color_balance_update (color_balance_dialog, ALL);
} }
/**************************/ /**************************/
/* Color Balance dialog */ /* Color Balance dialog */
/**************************/ /**************************/
static ColorBalanceDialog * static ColorBalanceDialog *
color_balance_new_dialog (void) color_balance_dialog_new (void)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
GtkWidget *vbox; GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights") N_("Highlights")
}; };
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1); cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE; cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE; cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback, _("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE, cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback, _("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Color Levels:")); label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label); gtk_widget_show (label);
/* cyan-red spinbutton */ /* cyan-red spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->cyan_red_data = GTK_ADJUSTMENT (data); cbd->cyan_red_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0);
@ -313,7 +297,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* magenta-green spinbutton */ /* magenta-green spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->magenta_green_data = GTK_ADJUSTMENT (data); cbd->magenta_green_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0);
@ -322,7 +306,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* yellow-blue spinbutton */ /* yellow-blue spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->yellow_blue_data = GTK_ADJUSTMENT (data); cbd->yellow_blue_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0);
@ -334,22 +318,22 @@ color_balance_new_dialog (void)
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the cyan-red scale widget */ /* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan")); start_label = gtk_label_new (_("Cyan"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->cyan_red_data); slider = gtk_hscale_new (cbd->cyan_red_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update), GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update),
cbd); cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red")); end_label = gtk_label_new (_("Red"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta")); start_label = gtk_label_new (_("Magenta"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->magenta_green_data); slider = gtk_hscale_new (cbd->magenta_green_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update), GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update),
cbd); cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green")); end_label = gtk_label_new (_("Green"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow")); start_label = gtk_label_new (_("Yellow"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->yellow_blue_data); slider = gtk_hscale_new (cbd->yellow_blue_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 2, 3);
gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update), GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update),
cbd); cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue")); end_label = gtk_label_new (_("Blue"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
gtk_widget_show (slider); gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */ gtk_widget_show (table);
hbox = gtk_hbox_new (TRUE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button = radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i])); gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_box_pack_start (GTK_BOX (hbox), radio_button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), radio_button, TRUE, FALSE, 0);
gtk_object_set_user_data (GTK_OBJECT (radio_button), (gpointer) i);
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
GTK_SIGNAL_FUNC (appl_mode_callbacks[i]), GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd); cbd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (hbox);
/* Horizontal box for preview and preserve luminosity toggle buttons */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (cbd->shell); gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd) color_balance_preview (ColorBalanceDialog *cbd)
{ {
if (!cbd->image_map) if (!cbd->image_map)
g_message ("color_balance_preview(): No image map"); {
g_message ("color_balance_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
color_balance_create_lookup_tables (cbd); color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void
color_balance_reset_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->cyan_red[cbd->application_mode] = 0.0;
cbd->magenta_green[cbd->application_mode] = 0.0;
cbd->yellow_blue[cbd->application_mode] = 0.0;
color_balance_update (cbd, ALL);
if (cbd->preview)
color_balance_preview (cbd);
}
static void static void
color_balance_ok_callback (GtkWidget *widget, color_balance_ok_callback (GtkWidget *widget,
gpointer data) gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
} }
static void static void
color_balance_shadows_callback (GtkWidget *widget, color_balance_range_callback (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data; cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS; range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
color_balance_update (cbd, ALL); cbd->application_mode = range;
}
static void
color_balance_midtones_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = MIDTONES;
color_balance_update (cbd, ALL);
}
static void
color_balance_highlights_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = HIGHLIGHTS;
color_balance_update (cbd, ALL); color_balance_update (cbd, ALL);
} }

View File

@ -57,8 +57,6 @@ struct _ColorBalanceDialog
TransferMode application_mode; TransferMode application_mode;
}; };
/* color balance functions */
Tool * tools_new_color_balance (void); Tool * tools_new_color_balance (void);
void tools_free_color_balance (Tool *tool); void tools_free_color_balance (Tool *tool);

View File

@ -15,43 +15,36 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "buildmenu.h" #include "buildmenu.h"
#include "colormaps.h" #include "colormaps.h"
#include "cursorutil.h" #include "cursorutil.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimphistogram.h" #include "gimphistogram.h"
#include "gimpui.h" #include "gimpui.h"
#include "interface.h"
#include "curves.h" #include "curves.h"
#include "gimplut.h" #include "gimplut.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
#define GRAPH 0x1 #define GRAPH 0x1
#define XRANGE_TOP 0x2 #define XRANGE_TOP 0x2
#define XRANGE_BOTTOM 0x4 #define XRANGE_BOTTOM 0x4
#define YRANGE 0x8 #define YRANGE 0x8
#define DRAW 0x10 #define DRAW 0x10
#define ALL 0xFF #define ALL 0xFF
/* NB: take care when changing these values: make sure the curve[] array in /* NB: take care when changing these values: make sure the curve[] array in
* curves.h is large enough. * curves.h is large enough.
*/ */
#define GRAPH_WIDTH 256 #define GRAPH_WIDTH 256
#define GRAPH_HEIGHT 256 #define GRAPH_HEIGHT 256
#define XRANGE_WIDTH 256 #define XRANGE_WIDTH 256
#define XRANGE_HEIGHT 16 #define XRANGE_HEIGHT 16
#define YRANGE_WIDTH 16 #define YRANGE_WIDTH 16
#define YRANGE_HEIGHT 256 #define YRANGE_HEIGHT 256
#define RADIUS 3 #define RADIUS 3
#define MIN_DISTANCE 8 #define MIN_DISTANCE 8
@ -69,13 +62,13 @@
/* the curves structures */ /* the curves structures */
typedef struct _Curves Curves; typedef struct _Curves Curves;
struct _Curves struct _Curves
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef double CRMatrix[4][4]; typedef gdouble CRMatrix[4][4];
/* the curves tool options */ /* the curves tool options */
static ToolOptions * curves_options = NULL; static ToolOptions * curves_options = NULL;
@ -99,18 +92,21 @@ static void curves_button_release (Tool *, GdkEventButton *, gpointer);
static void curves_motion (Tool *, GdkEventMotion *, gpointer); static void curves_motion (Tool *, GdkEventMotion *, gpointer);
static void curves_control (Tool *, ToolAction, gpointer); static void curves_control (Tool *, ToolAction, gpointer);
static CurvesDialog * curves_new_dialog (void); static CurvesDialog * curves_dialog_new (void);
static void curves_update (CurvesDialog *, int); static void curves_update (CurvesDialog *, int);
static void curves_plot_curve (CurvesDialog *, int, int, int, int); static void curves_plot_curve (CurvesDialog *, int, int, int, int);
static void curves_preview (CurvesDialog *); static void curves_preview (CurvesDialog *);
static void curves_value_callback (GtkWidget *, gpointer); static void curves_value_callback (GtkWidget *, gpointer);
static void curves_red_callback (GtkWidget *, gpointer); static void curves_red_callback (GtkWidget *, gpointer);
static void curves_green_callback (GtkWidget *, gpointer); static void curves_green_callback (GtkWidget *, gpointer);
static void curves_blue_callback (GtkWidget *, gpointer); static void curves_blue_callback (GtkWidget *, gpointer);
static void curves_alpha_callback (GtkWidget *, gpointer); static void curves_alpha_callback (GtkWidget *, gpointer);
static void curves_smooth_callback (GtkWidget *, gpointer); static void curves_smooth_callback (GtkWidget *, gpointer);
static void curves_free_callback (GtkWidget *, gpointer); static void curves_free_callback (GtkWidget *, gpointer);
static void curves_reset_callback (GtkWidget *, gpointer); static void curves_reset_callback (GtkWidget *, gpointer);
static void curves_ok_callback (GtkWidget *, gpointer); static void curves_ok_callback (GtkWidget *, gpointer);
static void curves_cancel_callback (GtkWidget *, gpointer); static void curves_cancel_callback (GtkWidget *, gpointer);
@ -120,12 +116,13 @@ static gint curves_yrange_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *); static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix); static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix);
/* curves machinery */ /* curves machinery */
float float
curves_lut_func (CurvesDialog *cd, curves_lut_func (CurvesDialog *cd,
int nchannels, int channel, float value) gint nchannels,
gint channel,
gfloat value)
{ {
float f; float f;
int index; int index;
@ -188,9 +185,9 @@ curves_colour_update (Tool *tool,
if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y))) if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y)))
return; return;
sample_type = gimp_drawable_type(drawable); sample_type = gimp_drawable_type (drawable);
is_indexed = gimp_drawable_is_indexed (drawable); is_indexed = gimp_drawable_is_indexed (drawable);
has_alpha = TYPE_HAS_ALPHA(sample_type); has_alpha = TYPE_HAS_ALPHA (sample_type);
curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX]; curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX];
curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX]; curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX];
@ -207,11 +204,14 @@ curves_colour_update (Tool *tool,
maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]); maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]);
curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]); curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]);
g_free(color); g_free (color);
} }
static void static void
curves_add_point(GimpDrawable * drawable,gint x, gint y,gint cchan) curves_add_point (GimpDrawable *drawable,
gint x,
gint y,
gint cchan)
{ {
/* Add point onto the curve */ /* Add point onto the curve */
int closest_point = 0; int closest_point = 0;
@ -301,21 +301,21 @@ curves_button_release (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
if(bevent->state & GDK_SHIFT_MASK) if(bevent->state & GDK_SHIFT_MASK)
{ {
curves_add_point(drawable,x,y,curves_dialog->channel); curves_add_point (drawable, x, y, curves_dialog->channel);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
else if(bevent->state & GDK_CONTROL_MASK) else if(bevent->state & GDK_CONTROL_MASK)
{ {
curves_add_point(drawable,x,y,HISTOGRAM_VALUE); curves_add_point (drawable, x, y, HISTOGRAM_VALUE);
curves_add_point(drawable,x,y,HISTOGRAM_RED); curves_add_point (drawable, x, y, HISTOGRAM_RED);
curves_add_point(drawable,x,y,HISTOGRAM_GREEN); curves_add_point (drawable, x, y, HISTOGRAM_GREEN);
curves_add_point(drawable,x,y,HISTOGRAM_BLUE); curves_add_point (drawable, x, y, HISTOGRAM_BLUE);
curves_add_point(drawable,x,y,HISTOGRAM_ALPHA); curves_add_point (drawable, x, y, HISTOGRAM_ALPHA);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
@ -338,7 +338,7 @@ curves_motion (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
} }
@ -366,7 +366,7 @@ curves_control (Tool *tool,
} }
Tool * Tool *
tools_new_curves () tools_new_curves (void)
{ {
Tool * tool; Tool * tool;
Curves * private; Curves * private;
@ -397,15 +397,15 @@ tools_new_curves ()
void void
tools_free_curves (Tool *tool) tools_free_curves (Tool *tool)
{ {
Curves * _curves; Curves * private;
_curves = (Curves *) tool->private; private = (Curves *) tool->private;
/* Close the color select dialog */ /* Close the color select dialog */
if (curves_dialog) if (curves_dialog)
curves_cancel_callback (NULL, (gpointer) curves_dialog); curves_cancel_callback (NULL, (gpointer) curves_dialog);
g_free (_curves); g_free (private);
} }
static MenuItem channel_items[] = static MenuItem channel_items[] =
@ -421,7 +421,7 @@ static MenuItem channel_items[] =
void void
curves_initialize (GDisplay *gdisp) curves_initialize (GDisplay *gdisp)
{ {
int i, j; gint i, j;
if (drawable_indexed (gimage_active_drawable (gdisp->gimage))) if (drawable_indexed (gimage_active_drawable (gdisp->gimage)))
{ {
@ -431,7 +431,10 @@ curves_initialize (GDisplay *gdisp)
/* The curves dialog */ /* The curves dialog */
if (!curves_dialog) if (!curves_dialog)
curves_dialog = curves_new_dialog (); curves_dialog = curves_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (curves_dialog->shell))
gtk_widget_show (curves_dialog->shell);
/* Initialize the values */ /* Initialize the values */
curves_dialog->channel = HISTOGRAM_VALUE; curves_dialog->channel = HISTOGRAM_VALUE;
@ -454,22 +457,22 @@ curves_initialize (GDisplay *gdisp)
} }
curves_dialog->drawable = gimage_active_drawable (gdisp->gimage); curves_dialog->drawable = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color ( (curves_dialog->drawable)); curves_dialog->color = drawable_color (curves_dialog->drawable);
curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable); curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable);
/* check for alpha channel */ /* check for alpha channel */
if (drawable_has_alpha ( (curves_dialog->drawable))) if (drawable_has_alpha (curves_dialog->drawable))
gtk_widget_set_sensitive( channel_items[4].widget, TRUE); gtk_widget_set_sensitive (channel_items[4].widget, TRUE);
else else
gtk_widget_set_sensitive( channel_items[4].widget, FALSE); gtk_widget_set_sensitive (channel_items[4].widget, FALSE);
/* hide or show the channel menu based on image type */ /* hide or show the channel menu based on image type */
if (curves_dialog->color) if (curves_dialog->color)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, TRUE); gtk_widget_set_sensitive (channel_items[i].widget, TRUE);
else else
for (i = 1; i < 4; i++) for (i = 1; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, FALSE); gtk_widget_set_sensitive (channel_items[i].widget, FALSE);
/* set the current selection */ /* set the current selection */
gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0); gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0);
@ -481,7 +484,7 @@ curves_initialize (GDisplay *gdisp)
} }
void void
curves_free () curves_free (void)
{ {
if (curves_dialog) if (curves_dialog)
{ {
@ -506,7 +509,7 @@ curves_free ()
/*******************/ /*******************/
static CurvesDialog * static CurvesDialog *
curves_new_dialog () curves_dialog_new (void)
{ {
CurvesDialog *cd; CurvesDialog *cd;
GtkWidget *vbox; GtkWidget *vbox;
@ -528,19 +531,20 @@ curves_new_dialog ()
}; };
cd = g_new (CurvesDialog, 1); cd = g_new (CurvesDialog, 1);
cd->cursor_ind_height = cd->cursor_ind_width = -1; cd->cursor_ind_height = -1;
cd->preview = TRUE; cd->cursor_ind_width = -1;
cd->curve_type = SMOOTH; cd->preview = TRUE;
cd->pixmap = NULL; cd->curve_type = SMOOTH;
cd->channel = HISTOGRAM_VALUE; cd->pixmap = NULL;
cd->channel = HISTOGRAM_VALUE;
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
for (j = 0; j < 256; j++) for (j = 0; j < 256; j++)
cd->curve[i][j] = j; cd->curve[i][j] = j;
for(i = 0; i < (sizeof(cd->col_value)/sizeof(cd->col_value[0])); i++) for (i = 0; i < (sizeof (cd->col_value) / sizeof (cd->col_value[0])); i++)
cd->col_value[i] = 0; cd->col_value[i] = 0;
cd->lut = gimp_lut_new(); cd->lut = gimp_lut_new ();
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
channel_items [i].user_data = (gpointer) cd; channel_items [i].user_data = (gpointer) cd;
@ -562,15 +566,15 @@ curves_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox);
/* The option menu for selecting channels */ /* The option menu for selecting channels */
channel_hbox = gtk_hbox_new (FALSE, 2); channel_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Modify Curves for Channel: ")); label = gtk_label_new (_("Modify Curves for Channel:"));
gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0);
menu = build_menu (channel_items, NULL); menu = build_menu (channel_items, NULL);
@ -584,7 +588,8 @@ curves_new_dialog ()
/* The table for the yrange and the graph */ /* The table for the yrange and the graph */
table = gtk_table_new (2, 2, FALSE); table = gtk_table_new (2, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 2);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* The range drawing area */ /* The range drawing area */
@ -596,10 +601,12 @@ curves_new_dialog ()
cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT);
gtk_widget_set_events (cd->yrange, RANGE_MASK); gtk_widget_set_events (cd->yrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
(GtkSignalFunc) curves_yrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->yrange); gtk_container_add (GTK_CONTAINER (frame), cd->yrange);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
GTK_SIGNAL_FUNC (curves_yrange_events),
cd);
gtk_widget_show (cd->yrange); gtk_widget_show (cd->yrange);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -607,18 +614,20 @@ curves_new_dialog ()
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, 0, 0);
cd->graph = gtk_drawing_area_new (); cd->graph = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph), gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph),
GRAPH_WIDTH + RADIUS * 2, GRAPH_WIDTH + RADIUS * 2,
GRAPH_HEIGHT + RADIUS * 2); GRAPH_HEIGHT + RADIUS * 2);
gtk_widget_set_events (cd->graph, GRAPH_MASK); gtk_widget_set_events (cd->graph, GRAPH_MASK);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
(GtkSignalFunc) curves_graph_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->graph); gtk_container_add (GTK_CONTAINER (frame), cd->graph);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
GTK_SIGNAL_FUNC (curves_graph_events),
cd);
gtk_widget_show (cd->graph); gtk_widget_show (cd->graph);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -631,20 +640,22 @@ curves_new_dialog ()
cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT);
gtk_widget_set_events (cd->xrange, RANGE_MASK); gtk_widget_set_events (cd->xrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
(GtkSignalFunc) curves_xrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->xrange); gtk_container_add (GTK_CONTAINER (frame), cd->xrange);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
GTK_SIGNAL_FUNC (curves_xrange_events),
cd);
gtk_widget_show (cd->xrange); gtk_widget_show (cd->xrange);
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (table); gtk_widget_show (table);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The option menu for selecting the drawing method */ /* The option menu for selecting the drawing method */
label = gtk_label_new (_("Curve Type: ")); label = gtk_label_new (_("Curve Type:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
menu = build_menu (curve_type_items, NULL); menu = build_menu (curve_type_items, NULL);
@ -659,12 +670,12 @@ curves_new_dialog ()
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) curves_preview_update, GTK_SIGNAL_FUNC (curves_preview_update),
cd); cd);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
@ -674,32 +685,32 @@ curves_new_dialog ()
} }
static void static void
curve_print_loc(CurvesDialog *cd, curve_print_loc (CurvesDialog *cd,
gint xpos, gint xpos,
gint ypos) gint ypos)
{ {
char buf[32]; char buf[32];
gint width; gint width;
gint ascent; gint ascent;
gint descent; gint descent;
if(cd->cursor_ind_width < 0) if (cd->cursor_ind_width < 0)
{ {
/* Calc max extents */ /* Calc max extents */
gdk_string_extents(cd->graph->style->font, gdk_string_extents (cd->graph->style->font,
"x:888 y:888", "x:888 y:888",
NULL, NULL,
NULL, NULL,
&width, &width,
&ascent, &ascent,
&descent); &descent);
cd->cursor_ind_width = width; cd->cursor_ind_width = width;
cd->cursor_ind_height = ascent + descent; cd->cursor_ind_height = ascent + descent;
cd->cursor_ind_ascent = ascent; cd->cursor_ind_ascent = ascent;
} }
if(xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255) if (xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255)
{ {
g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos); g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos);
@ -730,53 +741,54 @@ curves_update (CurvesDialog *cd,
int update) int update)
{ {
GdkRectangle area; GdkRectangle area;
int i, j; gint i, j;
char buf[32]; gchar buf[32];
gint offset; gint offset;
if (update & XRANGE_TOP) if (update & XRANGE_TOP)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
for (i = 0; i < XRANGE_HEIGHT / 2; i++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH ; j++) for (j = 0; j < XRANGE_WIDTH ; j++)
{ {
buf[j*3+0] = cd->curve[cd->channel][j]; buf[j*3+0] = cd->curve[cd->channel][j];
buf[j*3+1] = cd->curve[cd->channel][j]; buf[j*3+1] = cd->curve[cd->channel][j];
buf[j*3+2] = cd->curve[cd->channel][j]; buf[j*3+2] = cd->curve[cd->channel][j];
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH); buf, 0, i, XRANGE_WIDTH);
} }
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
{
for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH; j++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
buf[j*3+0] = cd->curve[HISTOGRAM_RED][j]; for (j = 0; j < XRANGE_WIDTH; j++)
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j]; {
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j]; buf[j*3+0] = cd->curve[HISTOGRAM_RED][j];
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j];
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j];
}
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH);
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), break;
buf, 0, i, XRANGE_WIDTH);
} }
break;
}
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} /* end switch */ }
if (update & DRAW) if (update & DRAW)
{ {
@ -789,7 +801,7 @@ curves_update (CurvesDialog *cd,
} }
if (update & XRANGE_BOTTOM) if (update & XRANGE_BOTTOM)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
for (i = 0; i < XRANGE_WIDTH; i++) for (i = 0; i < XRANGE_WIDTH; i++)
{ {
@ -812,35 +824,36 @@ curves_update (CurvesDialog *cd,
} }
if (update & YRANGE) if (update & YRANGE)
{ {
unsigned char buf[YRANGE_WIDTH * 3]; guchar buf[YRANGE_WIDTH * 3];
unsigned char pix[3]; guchar pix[3];
for (i = 0; i < YRANGE_HEIGHT; i++) for (i = 0; i < YRANGE_HEIGHT; i++)
{ {
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
pix[0] = pix[1] = pix[2] = (255 - i); pix[0] = pix[1] = pix[2] = (255 - i);
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
pix[0] = pix[1] = pix[2] = 0; pix[0] = pix[1] = pix[2] = 0;
pix[cd->channel - 1] = (255 - i); pix[cd->channel - 1] = (255 - i);
break; break;
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} }
for (j = 0; j < YRANGE_WIDTH * 3; j++) for (j = 0; j < YRANGE_WIDTH * 3; j++)
buf[j] = pix[j%3]; buf[j] = pix[j%3];
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange), buf, 0, i, YRANGE_WIDTH);
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange),
buf, 0, i, YRANGE_WIDTH);
} }
if (update & DRAW) if (update & DRAW)
@ -852,7 +865,8 @@ curves_update (CurvesDialog *cd,
/* Clear the pixmap */ /* Clear the pixmap */
gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL], gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL],
TRUE, 0, 0, GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2); TRUE, 0, 0,
GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2);
/* Draw the grid lines */ /* Draw the grid lines */
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
@ -885,20 +899,20 @@ curves_update (CurvesDialog *cd,
} }
/* draw the colour line */ /* draw the colour line */
gdk_draw_line(cd->pixmap, cd->graph->style->black_gc, gdk_draw_line (cd->pixmap, cd->graph->style->black_gc,
cd->col_value[cd->channel]+RADIUS,RADIUS, cd->col_value[cd->channel]+RADIUS,RADIUS,
cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS); cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS);
/* and xpos indicator */ /* and xpos indicator */
g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]); g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]);
if((cd->col_value[cd->channel]+RADIUS) < 127) if ((cd->col_value[cd->channel]+RADIUS) < 127)
{ {
offset = RADIUS + 4; offset = RADIUS + 4;
} }
else else
{ {
offset = -gdk_string_width(cd->graph->style->font,buf) - 2; offset = - gdk_string_width (cd->graph->style->font,buf) - 2;
} }
gdk_draw_string (cd->pixmap, gdk_draw_string (cd->pixmap,
@ -916,10 +930,10 @@ curves_update (CurvesDialog *cd,
static void static void
curves_plot_curve (CurvesDialog *cd, curves_plot_curve (CurvesDialog *cd,
int p1, gint p1,
int p2, gint p2,
int p3, gint p3,
int p4) gint p4)
{ {
CRMatrix geometry; CRMatrix geometry;
CRMatrix tmp1, tmp2; CRMatrix tmp1, tmp2;
@ -1045,8 +1059,8 @@ curves_calculate_curve (CurvesDialog *cd)
} }
break; break;
} }
gimp_lut_setup(cd->lut, (GimpLutFunc) curves_lut_func, gimp_lut_setup (cd->lut, (GimpLutFunc) curves_lut_func,
(void *) cd, gimp_drawable_bytes(cd->drawable)); (void *) cd, gimp_drawable_bytes (cd->drawable));
} }
@ -1054,23 +1068,24 @@ static void
curves_preview (CurvesDialog *cd) curves_preview (CurvesDialog *cd)
{ {
if (!cd->image_map) if (!cd->image_map)
g_message ("curves_preview(): No image map"); {
g_message ("curves_preview(): No image map");
active_tool->preserve = TRUE; /* Going to dirty the display... */ return;
}
active_tool->preserve = TRUE;
image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2,
(void *) cd->lut); (void *) cd->lut);
active_tool->preserve = FALSE;
active_tool->preserve = FALSE; /* All done */
} }
static void static void
curves_value_callback (GtkWidget *w, curves_value_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_VALUE) if (cd->channel != HISTOGRAM_VALUE)
{ {
@ -1080,12 +1095,12 @@ curves_value_callback (GtkWidget *w,
} }
static void static void
curves_red_callback (GtkWidget *w, curves_red_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_RED) if (cd->channel != HISTOGRAM_RED)
{ {
@ -1095,12 +1110,12 @@ curves_red_callback (GtkWidget *w,
} }
static void static void
curves_green_callback (GtkWidget *w, curves_green_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_GREEN) if (cd->channel != HISTOGRAM_GREEN)
{ {
@ -1110,12 +1125,12 @@ curves_green_callback (GtkWidget *w,
} }
static void static void
curves_blue_callback (GtkWidget *w, curves_blue_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_BLUE) if (cd->channel != HISTOGRAM_BLUE)
{ {
@ -1125,12 +1140,12 @@ curves_blue_callback (GtkWidget *w,
} }
static void static void
curves_alpha_callback (GtkWidget *w, curves_alpha_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_ALPHA) if (cd->channel != HISTOGRAM_ALPHA)
{ {
@ -1140,14 +1155,14 @@ curves_alpha_callback (GtkWidget *w,
} }
static void static void
curves_smooth_callback (GtkWidget *w, curves_smooth_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
gint32 index; gint32 index;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != SMOOTH) if (cd->curve_type != SMOOTH)
{ {
@ -1170,12 +1185,12 @@ curves_smooth_callback (GtkWidget *w,
} }
static void static void
curves_free_callback (GtkWidget *w, curves_free_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != GFREE) if (cd->curve_type != GFREE)
{ {
@ -1190,12 +1205,12 @@ curves_free_callback (GtkWidget *w,
static void static void
curves_reset_callback (GtkWidget *widget, curves_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
/* Initialize the values */ /* Initialize the values */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -1214,17 +1229,18 @@ curves_reset_callback (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
} }
static void static void
curves_ok_callback (GtkWidget *widget, curves_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1248,11 +1264,12 @@ curves_ok_callback (GtkWidget *widget,
static void static void
curves_cancel_callback (GtkWidget *widget, curves_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1373,7 +1390,7 @@ curves_graph_events (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
gtk_grab_add(widget); gtk_grab_add (widget);
break; break;
@ -1384,7 +1401,7 @@ curves_graph_events (GtkWidget *widget,
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
gtk_grab_remove(widget); gtk_grab_remove (widget);
break; break;
@ -1527,7 +1544,7 @@ curves_CR_compose (CRMatrix a,
CRMatrix b, CRMatrix b,
CRMatrix ab) CRMatrix ab)
{ {
int i, j; gint i, j;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {

View File

@ -23,47 +23,53 @@
#include "lut_funcs.h" #include "lut_funcs.h"
#include "tools.h" #include "tools.h"
#define SMOOTH 0 #define SMOOTH 0
#define GFREE 1 #define GFREE 1
typedef struct _CurvesDialog CurvesDialog; typedef struct _CurvesDialog CurvesDialog;
struct _CurvesDialog struct _CurvesDialog
{ {
GtkWidget * shell; GtkWidget *shell;
GtkWidget * channel_menu;
GtkWidget * xrange;
GtkWidget * yrange;
GtkWidget * graph;
GdkPixmap * pixmap;
GimpDrawable * drawable;
ImageMap image_map;
int color;
int channel;
gint preview;
int grab_point; GtkWidget *channel_menu;
int last; GtkWidget *xrange;
int leftmost; GtkWidget *yrange;
int rightmost; GtkWidget *graph;
int curve_type; GdkPixmap *pixmap;
int points[5][17][2];
unsigned char curve[5][256]; GimpDrawable *drawable;
int col_value[5]; ImageMap image_map;
gint color;
gint channel;
gboolean preview;
gint grab_point;
gint last;
gint leftmost;
gint rightmost;
gint curve_type;
gint points[5][17][2];
guchar curve[5][256];
gint col_value[5];
int cursor_ind_height; gint cursor_ind_height;
int cursor_ind_width; gint cursor_ind_width;
int cursor_ind_ascent; gint cursor_ind_ascent;
GimpLut *lut; GimpLut *lut;
}; };
/* hue-saturation functions */ Tool * tools_new_curves (void);
Tool * tools_new_curves (void); void tools_free_curves (Tool *tool);
void tools_free_curves (Tool *);
void curves_initialize (GDisplay *); void curves_initialize (GDisplay *gdisp);
void curves_free (void); void curves_free (void);
float curves_lut_func (CurvesDialog *, int, int, float); float curves_lut_func (CurvesDialog *cd,
void curves_calculate_curve (CurvesDialog *); gint nchannels,
gint channel,
gfloat value);
void curves_calculate_curve (CurvesDialog *cd);
#endif /* __CURVES_H__ */ #endif /* __CURVES_H__ */

View File

@ -33,29 +33,24 @@
#define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK #define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200 #define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define DA_WIDTH 40 #define DA_WIDTH 40
#define DA_HEIGHT 20 #define DA_HEIGHT 20
#define HUE_PARTITION 0x0 #define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1 #define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2 #define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4 #define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8 #define DRAW 0x40
#define LIGHTNESS_TEXT 0x10 #define ALL 0xFF
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */ /* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation; typedef struct _HueSaturation HueSaturation;
struct _HueSaturation struct _HueSaturation
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the hue-saturation tool options */ /* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL; static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */ /* Local variables */
static int hue_transfer[6][256]; static gint hue_transfer[6][256];
static int lightness_transfer[6][256]; static gint lightness_transfer[6][256];
static int saturation_transfer[6][256]; static gint saturation_transfer[6][256];
static int default_colors[6][3] = static gint default_colors[6][3] =
{ {
{ 255, 0, 0 }, { 255, 0, 0 },
{ 255, 255, 0 }, { 255, 255, 0 },
{ 0, 255, 0 }, { 0, 255, 0 },
{ 0, 255, 255 }, { 0, 255, 255 },
{ 0, 0, 255 }, { 0, 0, 255 },
{ 255, 0, 255 } { 255, 0, 255 }
}; };
/* hue saturation action functions */ /* hue saturation action functions */
static void hue_saturation_control (Tool *, ToolAction, gpointer); static void hue_saturation_control (Tool *, ToolAction, gpointer);
static HueSaturationDialog * hue_saturation_new_dialog (void); static HueSaturationDialog * hue_saturation_dialog_new (void);
static void hue_saturation_update (HueSaturationDialog *, static void hue_saturation_update (HueSaturationDialog *,
int); gint);
static void hue_saturation_preview (HueSaturationDialog *); static void hue_saturation_preview (HueSaturationDialog *);
static void hue_saturation_reset_callback (GtkWidget *, gpointer);
static void hue_saturation_ok_callback (GtkWidget *, gpointer); static void hue_saturation_ok_callback (GtkWidget *, gpointer);
static void hue_saturation_cancel_callback (GtkWidget *, gpointer); static void hue_saturation_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_callback (GtkWidget *, gpointer); static void hue_saturation_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_R_callback (GtkWidget *, gpointer);
static void hue_saturation_Y_callback (GtkWidget *, gpointer);
static void hue_saturation_G_callback (GtkWidget *, gpointer);
static void hue_saturation_C_callback (GtkWidget *, gpointer);
static void hue_saturation_B_callback (GtkWidget *, gpointer);
static void hue_saturation_M_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer); static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer); gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
static void hue_saturation_hue_text_update (GtkWidget *, gpointer); gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer); static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer); gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *, static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *); HueSaturationDialog *);
/* hue saturation machinery */ /* hue saturation machinery */
void void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd) hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{ {
int value; gint value;
int hue; gint hue;
int i; gint i;
/* Calculate transfers */ /* Calculate transfers */
for (hue = 0; hue < 6; hue++) for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
} }
} }
/* hue saturation action functions */ /* hue saturation action functions */
static void static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
} }
Tool * Tool *
tools_new_hue_saturation () tools_new_hue_saturation (void)
{ {
Tool * tool; Tool * tool;
HueSaturation * private; HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void void
hue_saturation_initialize (GDisplay *gdisp) hue_saturation_initialize (GDisplay *gdisp)
{ {
int i; gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage))) if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{ {
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */ /* The "hue-saturation" dialog */
if (!hue_saturation_dialog) if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog (); hue_saturation_dialog = hue_saturation_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell)) if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell))
gtk_widget_show (hue_saturation_dialog->shell); gtk_widget_show (hue_saturation_dialog->shell);
@ -313,12 +300,14 @@ hue_saturation_initialize (GDisplay *gdisp)
} }
hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage); hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage);
hue_saturation_dialog->image_map = image_map_create (gdisp, hue_saturation_dialog->drawable); hue_saturation_dialog->image_map =
image_map_create (gdisp, hue_saturation_dialog->drawable);
hue_saturation_update (hue_saturation_dialog, ALL); hue_saturation_update (hue_saturation_dialog, ALL);
} }
void void
hue_saturation_free () hue_saturation_free (void)
{ {
if (hue_saturation_dialog) if (hue_saturation_dialog)
{ {
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map); image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL; hue_saturation_dialog->image_map = NULL;
} }
gtk_widget_destroy (hue_saturation_dialog->shell); gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/ /***************************/
static HueSaturationDialog * static HueSaturationDialog *
hue_saturation_new_dialog () hue_saturation_dialog_new (void)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
GtkWidget *main_vbox; GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle; GtkWidget *toggle;
GtkWidget *radio_button; GtkWidget *radio_button;
GtkWidget *frame; GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
N_("M") N_("M")
}; };
GtkSignalFunc hue_partition_callbacks[] =
{
hue_saturation_master_callback,
hue_saturation_R_callback,
hue_saturation_Y_callback,
hue_saturation_G_callback,
hue_saturation_C_callback,
hue_saturation_B_callback,
hue_saturation_M_callback
};
hsd = g_new (HueSaturationDialog, 1); hsd = g_new (HueSaturationDialog, 1);
hsd->hue_partition = 0; hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE; hsd->preview = TRUE;
/* The shell and main vbox */ /* The shell and main vbox */
hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_satiration", hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_saturation",
tools_help_func, NULL, tools_help_func, NULL,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback, _("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE, hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback, _("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL); NULL);
main_vbox = gtk_vbox_new (FALSE, 2); main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* The main hbox containing hue partitions and sliders */ /* The main hbox containing hue partitions and sliders */
main_hbox = gtk_hbox_new (FALSE, 2); main_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0);
/* The table containing hue partitions */ /* The table containing hue partitions */
table = gtk_table_new (7, 2, FALSE); table = gtk_table_new (7, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0);
/* the radio buttons for hue partitions */ /* the radio buttons for hue partitions */
@ -411,26 +396,30 @@ hue_saturation_new_dialog ()
{ {
radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]); radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i) if (!i)
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
} }
else else
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR); hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT); gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK); DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1],
HUE_PARTITION_MASK);
gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event", gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event",
(GtkSignalFunc) hue_saturation_hue_partition_events, GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd); hsd);
gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]); gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]);
@ -439,14 +428,16 @@ hue_saturation_new_dialog ()
} }
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) hue_partition_callbacks[i], GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd); hsd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (table); gtk_widget_show (table);
/* The vbox for the table and preview toggle */ /* The vbox for the table and preview toggle */
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments")); label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the hue scale widget */ /* Create the hue scale widget */
label = gtk_label_new (_("Hue")); label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0);
hsd->hue_data = GTK_ADJUSTMENT (data); hsd->hue_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->hue_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
hsd->hue_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1, gtk_widget_set_usize (spinbutton, 74, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
(GtkSignalFunc) hue_saturation_hue_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_hue_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */ /* Create the lightness scale widget */
label = gtk_label_new (_("Lightness")); label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->lightness_data = GTK_ADJUSTMENT (data); hsd->lightness_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->lightness_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
hsd->lightness_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
(GtkSignalFunc) hue_saturation_lightness_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_lightness_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */ /* Create the saturation scale widget */
label = gtk_label_new (_("Saturation")); label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->saturation_data = GTK_ADJUSTMENT (data); hsd->saturation_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->saturation_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
hsd->saturation_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
(GtkSignalFunc) hue_saturation_saturation_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_saturation_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */ /* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) hue_saturation_preview_update, GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd); hsd);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (main_hbox); gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox); gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void static void
hue_saturation_update (HueSaturationDialog *hsd, hue_saturation_update (HueSaturationDialog *hsd,
int update) gint update)
{ {
int i, j, b; gint i, j, b;
int rgb[3]; gint rgb[3];
unsigned char buf[DA_WIDTH * 3]; guchar buf[DA_WIDTH * 3];
char text[12];
if (update & HUE_SLIDER) if (update & HUE_SLIDER)
{ {
hsd->hue_data->value = hsd->hue[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed"); hsd->hue[hsd->hue_partition]);
} }
if (update & LIGHTNESS_SLIDER) if (update & LIGHTNESS_SLIDER)
{ {
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed"); hsd->lightness[hsd->hue_partition]);
} }
if (update & SATURATION_SLIDER) if (update & SATURATION_SLIDER)
{ {
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed"); hsd->saturation[hsd->hue_partition]);
}
if (update & HUE_TEXT)
{
sprintf (text, "%0.0f", hsd->hue[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->hue_text), text);
}
if (update & LIGHTNESS_TEXT)
{
sprintf (text, "%0.0f", hsd->lightness[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->lightness_text), text);
}
if (update & SATURATION_TEXT)
{
sprintf (text, "%0.0f", hsd->saturation[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->saturation_text), text);
} }
hue_saturation_calculate_transfers (hsd); hue_saturation_calculate_transfers (hsd);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
rgb[RED_PIX] = default_colors[i][RED_PIX]; rgb[RED_PIX] = default_colors[i][RED_PIX];
rgb[GREEN_PIX] = default_colors[i][GREEN_PIX]; rgb[GREEN_PIX] = default_colors[i][GREEN_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX]; rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb_to_hls (rgb, rgb + 1, rgb + 2); rgb_to_hls (rgb, rgb + 1, rgb + 2);
rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]]; rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]];
rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]]; rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]];
rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]]; rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]];
hls_to_rgb (rgb, rgb + 1, rgb + 2); hls_to_rgb (rgb, rgb + 1, rgb + 2);
for (j = 0; j < DA_WIDTH; j++) for (j = 0; j < DA_WIDTH; j++)
for (b = 0; b < 3; b++) for (b = 0; b < 3; b++)
buf[j * 3 + b] = (unsigned char) rgb[b]; buf[j * 3 + b] = (guchar) rgb[b];
for (j = 0; j < DA_HEIGHT; j++) for (j = 0; j < DA_HEIGHT; j++)
gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]), buf, 0, j, DA_WIDTH); gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]),
buf, 0, j, DA_WIDTH);
if (update & DRAW) if (update & DRAW)
gtk_widget_draw (hsd->hue_partition_da[i], NULL); gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd) hue_saturation_preview (HueSaturationDialog *hsd)
{ {
if (!hsd->image_map) if (!hsd->image_map)
g_warning ("hue_saturation_preview(): No image map"); {
g_warning ("hue_saturation_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd); image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void static void
hue_saturation_ok_callback (GtkWidget *widget, hue_saturation_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
hsd->hue[hsd->hue_partition] = 0.0;
hsd->lightness[hsd->hue_partition] = 0.0;
hsd->saturation[hsd->hue_partition] = 0.0;
hue_saturation_update (hsd, ALL);
if (hsd->preview)
hue_saturation_preview (hsd);
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void static void
hue_saturation_cancel_callback (GtkWidget *widget, hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
} }
static void static void
hue_saturation_master_callback (GtkWidget *widget, hue_saturation_partition_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
HueRange partition;
hsd = (HueSaturationDialog *) data;
partition = (HueRange) gtk_object_get_data (GTK_OBJECT (widget),
"hue_partition");
hsd->hue_partition = partition;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 0;
hue_saturation_update (hsd, ALL); hue_saturation_update (hsd, ALL);
} }
static void static void
hue_saturation_R_callback (GtkWidget *widget, hue_saturation_preview_update (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 1;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_Y_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 2;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_G_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 3;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_C_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 4;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_B_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 5;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_M_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 6;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_preview_update (GtkWidget *w,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data; hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
hsd->preview = TRUE; hsd->preview = TRUE;
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
} }
static void static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment, hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (hsd->hue[hsd->hue_partition] != adjustment->value) if (hsd->hue[hsd->hue_partition] != adjustment->value)
{ {
hsd->hue[hsd->hue_partition] = adjustment->value; hsd->hue[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, HUE_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment, hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (hsd->lightness[hsd->hue_partition] != adjustment->value) if (hsd->lightness[hsd->hue_partition] != adjustment->value)
{ {
hsd->lightness[hsd->hue_partition] = adjustment->value; hsd->lightness[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, LIGHTNESS_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment, hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value) if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{ {
hsd->saturation[hsd->hue_partition] = adjustment->value; hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_hue_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -180, 180);
if ((int) hsd->hue[hsd->hue_partition] != value)
{
hsd->hue[hsd->hue_partition] = value;
hue_saturation_update (hsd, HUE_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_lightness_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->lightness[hsd->hue_partition] != value)
{
hsd->lightness[hsd->hue_partition] = value;
hue_saturation_update (hsd, LIGHTNESS_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_saturation_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->saturation[hsd->hue_partition] != value)
{
hsd->saturation[hsd->hue_partition] = value;
hue_saturation_update (hsd, SATURATION_SLIDER | DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange; } HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog; typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog struct _HueSaturationDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *gimage_name;
GtkWidget *hue_text;
GtkWidget *lightness_text;
GtkWidget *saturation_text;
GtkWidget *hue_partition_da[6];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
GimpDrawable *drawable; GtkWidget *hue_partition_da[6];
ImageMap image_map;
double hue[7]; GtkAdjustment *hue_data;
double lightness[7]; GtkAdjustment *lightness_data;
double saturation[7]; GtkAdjustment *saturation_data;
int hue_partition; GimpDrawable *drawable;
gint preview; ImageMap image_map;
gdouble hue[7];
gdouble lightness[7];
gdouble saturation[7];
HueRange hue_partition;
gboolean preview;
}; };
/* hue-saturation functions */ Tool * tools_new_hue_saturation (void);
Tool * tools_new_hue_saturation (void); void tools_free_hue_saturation (Tool *tool);
void tools_free_hue_saturation (Tool *);
void hue_saturation_initialize (GDisplay *); void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (void); void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *); void hue_saturation (PixelRegion *srcPR,
PixelRegion *destPR,
void *data);
void hue_saturation_calculate_transfers (HueSaturationDialog *hsd); void hue_saturation_calculate_transfers (HueSaturationDialog *hsd);
#endif /* __HUE_SATURATION_H__ */ #endif /* __HUE_SATURATION_H__ */

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "drawable.h" #include "drawable.h"
#include "general.h" #include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256 #define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150 #define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */ /* the threshold structures */
typedef struct _Threshold Threshold; typedef struct _Threshold Threshold;
struct _Threshold struct _Threshold
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the threshold tool options */ /* the threshold tool options */
static ToolOptions *threshold_options = NULL; static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */ /* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL; static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */ /* threshold action functions */
static void threshold_control (Tool *, ToolAction, gpointer); static void threshold_control (Tool *, ToolAction, gpointer);
static ThresholdDialog * threshold_new_dialog (void); static ThresholdDialog * threshold_dialog_new (void);
static void threshold_update (ThresholdDialog *,
gint);
static void threshold_preview (ThresholdDialog *); static void threshold_preview (ThresholdDialog *);
static void threshold_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer); static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer); static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer); static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer); static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
static void threshold_high_threshold_text_update (GtkWidget *, gpointer); gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold (PixelRegion *, PixelRegion *, void *); static void threshold (PixelRegion *, PixelRegion *, void *);
static void threshold_histogram_range (HistogramWidget *, int, int, void *); static void threshold_histogram_range (HistogramWidget *, gint, gint,
gpointer);
/* threshold machinery */ /* threshold machinery */
void void
threshold_2 (void *user_data, threshold_2 (void *data,
PixelRegion *srcPR, PixelRegion *srcPR,
PixelRegion *destPR) PixelRegion *destPR)
{ {
/* this function just re-orders the arguments so we can use /* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */ * pixel_regions_process_paralell
threshold(srcPR, destPR, user_data); */
threshold (srcPR, destPR, data);
} }
static void static void
threshold (PixelRegion *srcPR, threshold (PixelRegion *srcPR,
PixelRegion *destPR, PixelRegion *destPR,
void *user_data) void *data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
unsigned char *src, *s; unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b; int w, h, b;
int value; int value;
td = (ThresholdDialog *) user_data; td = (ThresholdDialog *) data;
h = srcPR->h; h = srcPR->h;
src = srcPR->data; src = srcPR->data;
@ -128,28 +133,6 @@ threshold (PixelRegion *srcPR,
} }
} }
static void
threshold_histogram_range (HistogramWidget *w,
int start,
int end,
void *user_data)
{
ThresholdDialog *td;
char text[12];
td = (ThresholdDialog *) user_data;
td->low_threshold = start;
td->high_threshold = end;
sprintf (text, "%d", start);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), text);
sprintf (text, "%d", end);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), text);
if (td->preview)
threshold_preview (td);
}
/* threshold action functions */ /* threshold action functions */
static void static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
} }
Tool * Tool *
tools_new_threshold () tools_new_threshold (void)
{ {
Tool * tool; Tool * tool;
Threshold * private; Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
tools_register (THRESHOLD, threshold_options); tools_register (THRESHOLD, threshold_options);
} }
/* The threshold dialog */
if (! threshold_dialog)
threshold_dialog = threshold_new_dialog ();
else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell);
tool = tools_new_tool (THRESHOLD); tool = tools_new_tool (THRESHOLD);
private = g_new (Threshold, 1); private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private; thresh = (Threshold *) tool->private;
/* Close the color select dialog */ /* Close the threshold dialog */
if (threshold_dialog) if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog); threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */ /* The threshold dialog */
if (!threshold_dialog) if (!threshold_dialog)
threshold_dialog = threshold_new_dialog (); threshold_dialog = threshold_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell)) if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell); gtk_widget_show (threshold_dialog->shell);
threshold_dialog->low_threshold = 127;
threshold_dialog->high_threshold = 255;
threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage); threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage);
threshold_dialog->color = drawable_color (threshold_dialog->drawable); threshold_dialog->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map = threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist, gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable); threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram, histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist); threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram, gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog->low_threshold, threshold_dialog);
threshold_dialog->high_threshold);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview) if (threshold_dialog->preview)
threshold_preview (threshold_dialog); threshold_preview (threshold_dialog);
} }
/**********************/ /**********************/
/* Threshold dialog */ /* Threshold dialog */
/**********************/ /**********************/
static ThresholdDialog * static ThresholdDialog *
threshold_new_dialog () threshold_dialog_new (void)
{ {
ThresholdDialog *td; ThresholdDialog *td;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label; GtkWidget *label;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1); td = g_new (ThresholdDialog, 1);
td->preview = TRUE; td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback, _("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE, td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback, _("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* Horizontal box for threshold text widget */ /* Horizontal box for threshold text widget */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Threshold Range: ")); label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label); gtk_widget_show (label);
/* low threshold text */ /* low threshold spinbutton */
td->low_threshold_text = gtk_entry_new (); data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127"); td->low_threshold_data = GTK_ADJUSTMENT (data);
gtk_widget_set_usize (td->low_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->low_threshold_text, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->low_threshold_text), "changed",
(GtkSignalFunc) threshold_low_threshold_text_update,
td);
gtk_widget_show (td->low_threshold_text);
/* high threshold text */ spinbutton = gtk_spin_button_new (td->low_threshold_data, 1.0, 0);
td->high_threshold_text = gtk_entry_new (); gtk_widget_set_usize (spinbutton, 75, -1);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255"); gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_set_usize (td->high_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->high_threshold_text, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (td->low_threshold_data), "value_changed",
gtk_signal_connect (GTK_OBJECT (td->high_threshold_text), "changed", GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
(GtkSignalFunc) threshold_high_threshold_text_update,
td); td);
gtk_widget_show (td->high_threshold_text);
gtk_widget_show (spinbutton);
/* high threshold spinbutton */
data = gtk_adjustment_new (td->high_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->high_threshold_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (td->high_threshold_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->high_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_high_threshold_adjustment_update),
td);
gtk_widget_show (spinbutton);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* The threshold histogram */ /* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
@ -334,55 +328,97 @@ threshold_new_dialog ()
td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT); td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged", gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range, GTK_SIGNAL_FUNC (threshold_histogram_range),
(void*)td); td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
gtk_widget_show (GTK_WIDGET(td->histogram)); gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) threshold_preview_update, GTK_SIGNAL_FUNC (threshold_preview_update),
td); td);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (td->shell); gtk_widget_show (td->shell);
/* This code is so far removed from the histogram creation because the
function histogram_range requires a non-NULL drawable, and that
doesn't happen until after the top-level dialog is shown. */
histogram_widget_range (td->histogram, td->low_threshold, td->high_threshold);
return td; return td;
} }
static void
threshold_update (ThresholdDialog *td,
gint update)
{
if (update & LOW)
{
gtk_adjustment_set_value (td->low_threshold_data, td->low_threshold);
}
if (update & HIGH)
{
gtk_adjustment_set_value (td->high_threshold_data, td->high_threshold);
}
if (update & HISTOGRAM)
{
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
}
}
static void static void
threshold_preview (ThresholdDialog *td) threshold_preview (ThresholdDialog *td)
{ {
if (!td->image_map) if (!td->image_map)
g_warning ("threshold_preview(): No image map"); {
image_map_apply (td->image_map, threshold, (void *) td); g_warning ("threshold_preview(): No image map");
return;
}
active_tool->preserve = TRUE;
image_map_apply (td->image_map, threshold, td);
active_tool->preserve = FALSE;
}
static void
threshold_reset_callback (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = 127.0;
td->high_threshold = 255.0;
threshold_update (td, ALL);
if (td->preview)
threshold_preview (td);
} }
static void static void
threshold_ok_callback (GtkWidget *widget, threshold_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview) if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td); image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map) if (td->image_map)
image_map_commit (td->image_map); image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void static void
threshold_cancel_callback (GtkWidget *widget, threshold_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
} }
static void static void
threshold_preview_update (GtkWidget *w, threshold_preview_update (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
td->preview = TRUE; td->preview = TRUE;
threshold_preview (td); threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
} }
static void static void
threshold_low_threshold_text_update (GtkWidget *w, threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), 0, td->high_threshold);
if (value != td->low_threshold) if (td->low_threshold != adjustment->value)
{ {
td->low_threshold = value; td->low_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void static void
threshold_high_threshold_text_update (GtkWidget *w, threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), td->low_threshold, 255);
if (value != td->high_threshold) if (td->high_threshold != adjustment->value)
{ {
td->high_threshold = value; td->high_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void
threshold_histogram_range (HistogramWidget *widget,
gint start,
gint end,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = start;
td->high_threshold = end;
threshold_update (td, LOW | HIGH);
if (td->preview)
threshold_preview (td);
}

View File

@ -25,28 +25,33 @@
#include "tools.h" #include "tools.h"
typedef struct _ThresholdDialog ThresholdDialog; typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog struct _ThresholdDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text; GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram; HistogramWidget *histogram;
GimpHistogram *hist; GimpHistogram *hist;
GimpDrawable *drawable; GimpDrawable *drawable;
ImageMap image_map; ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
gint preview; gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
}; };
/* by_color select functions */ Tool * tools_new_threshold (void);
Tool * tools_new_threshold (void); void tools_free_threshold (Tool *tool);
void tools_free_threshold (Tool *);
void threshold_initialize (GDisplay *); void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *, PixelRegion *, PixelRegion *); void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */ #endif /* __THRESHOLD_H__ */

View File

@ -15,60 +15,51 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "brightness_contrast.h" #include "brightness_contrast.h"
#include "drawable.h" #include "drawable.h"
#include "gimage_mask.h" #include "gimplut.h"
#include "gimpui.h" #include "gimpui.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "gimplut.h"
#include "lut_funcs.h" #include "lut_funcs.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200 #define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define BRIGHTNESS_SLIDER 0x1 #define BRIGHTNESS 0x1
#define CONTRAST_SLIDER 0x2 #define CONTRAST 0x2
#define BRIGHTNESS_TEXT 0x4 #define ALL (BRIGHTNESS | CONTRAST)
#define CONTRAST_TEXT 0x8
#define ALL 0xF
/* the brightness-contrast structures */ /* the brightness-contrast structures */
typedef struct _BrightnessContrast BrightnessContrast; typedef struct _BrightnessContrast BrightnessContrast;
struct _BrightnessContrast struct _BrightnessContrast
{ {
gint x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef struct _BrightnessContrastDialog BrightnessContrastDialog; typedef struct _BrightnessContrastDialog BrightnessContrastDialog;
struct _BrightnessContrastDialog struct _BrightnessContrastDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *gimage_name; GtkWidget *gimage_name;
GtkWidget *brightness_text;
GtkWidget *contrast_text;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
GimpDrawable *drawable; GtkAdjustment *brightness_data;
ImageMap image_map; GtkAdjustment *contrast_data;
double brightness; GimpDrawable *drawable;
double contrast; ImageMap image_map;
gint preview; gdouble brightness;
gdouble contrast;
GimpLut *lut; gboolean preview;
GimpLut *lut;
}; };
@ -83,18 +74,19 @@ static BrightnessContrastDialog *brightness_contrast_dialog = NULL;
static void brightness_contrast_control (Tool *, ToolAction, gpointer); static void brightness_contrast_control (Tool *, ToolAction, gpointer);
static BrightnessContrastDialog * brightness_contrast_new_dialog (void); static BrightnessContrastDialog * brightness_contrast_dialog_new (void);
static void brightness_contrast_update (BrightnessContrastDialog *, int);
static void brightness_contrast_preview (BrightnessContrastDialog *);
static void brightness_contrast_ok_callback (GtkWidget *, gpointer);
static void brightness_contrast_cancel_callback (GtkWidget *, gpointer);
static void brightness_contrast_preview_update (GtkWidget *, gpointer);
static void brightness_contrast_brightness_scale_update (GtkAdjustment *, gpointer);
static void brightness_contrast_contrast_scale_update (GtkAdjustment *, gpointer);
static void brightness_contrast_brightness_text_update (GtkWidget *, gpointer);
static void brightness_contrast_contrast_text_update (GtkWidget *, gpointer);
static void brightness_contrast_update (BrightnessContrastDialog *,
gint);
static void brightness_contrast_preview (BrightnessContrastDialog *);
static void brightness_contrast_reset_callback (GtkWidget *, gpointer);
static void brightness_contrast_ok_callback (GtkWidget *, gpointer);
static void brightness_contrast_cancel_callback (GtkWidget *, gpointer);
static void brightness_contrast_preview_update (GtkWidget *, gpointer);
static void brightness_contrast_brightness_adjustment_update (GtkAdjustment *,
gpointer);
static void brightness_contrast_contrast_adjustment_update (GtkAdjustment *,
gpointer);
/* brightness-contrast select action functions */ /* brightness-contrast select action functions */
@ -122,7 +114,7 @@ brightness_contrast_control (Tool *tool,
} }
Tool * Tool *
tools_new_brightness_contrast () tools_new_brightness_contrast (void)
{ {
Tool * tool; Tool * tool;
BrightnessContrast * private; BrightnessContrast * private;
@ -155,7 +147,7 @@ tools_free_brightness_contrast (Tool *tool)
bc = (BrightnessContrast *) tool->private; bc = (BrightnessContrast *) tool->private;
/* Close the color select dialog */ /* Close the brightness-contrast dialog */
if (brightness_contrast_dialog) if (brightness_contrast_dialog)
brightness_contrast_cancel_callback (NULL, (gpointer) brightness_contrast_dialog); brightness_contrast_cancel_callback (NULL, (gpointer) brightness_contrast_dialog);
@ -173,15 +165,13 @@ brightness_contrast_initialize (GDisplay *gdisp)
/* The brightness-contrast dialog */ /* The brightness-contrast dialog */
if (!brightness_contrast_dialog) if (!brightness_contrast_dialog)
brightness_contrast_dialog = brightness_contrast_new_dialog (); brightness_contrast_dialog = brightness_contrast_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (brightness_contrast_dialog->shell)) if (!GTK_WIDGET_VISIBLE (brightness_contrast_dialog->shell))
gtk_widget_show (brightness_contrast_dialog->shell); gtk_widget_show (brightness_contrast_dialog->shell);
/* Initialize dialog fields */
brightness_contrast_dialog->image_map = NULL;
brightness_contrast_dialog->brightness = 0.0; brightness_contrast_dialog->brightness = 0.0;
brightness_contrast_dialog->contrast = 0.0; brightness_contrast_dialog->contrast = 0.0;
brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage); brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->image_map = brightness_contrast_dialog->image_map =
@ -190,19 +180,20 @@ brightness_contrast_initialize (GDisplay *gdisp)
brightness_contrast_update (brightness_contrast_dialog, ALL); brightness_contrast_update (brightness_contrast_dialog, ALL);
} }
/********************************/ /********************************/
/* Brightness Contrast dialog */ /* Brightness Contrast dialog */
/********************************/ /********************************/
static BrightnessContrastDialog * static BrightnessContrastDialog *
brightness_contrast_new_dialog () brightness_contrast_dialog_new (void)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data; GtkObject *data;
@ -219,6 +210,8 @@ brightness_contrast_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), brightness_contrast_reset_callback,
bcd, NULL, TRUE, FALSE,
_("OK"), brightness_contrast_ok_callback, _("OK"), brightness_contrast_ok_callback,
bcd, NULL, TRUE, FALSE, bcd, NULL, TRUE, FALSE,
_("Cancel"), brightness_contrast_cancel_callback, _("Cancel"), brightness_contrast_cancel_callback,
@ -226,94 +219,90 @@ brightness_contrast_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (2, 3, FALSE); table = gtk_table_new (2, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the brightness scale widget */ /* Create the brightness scale widget */
label = gtk_label_new (_("Brightness")); label = gtk_label_new (_("Brightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -127, 127.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -127, 127.0, 1.0, 10.0, 0.0);
bcd->brightness_data = GTK_ADJUSTMENT (data); bcd->brightness_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1, gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_brightness_scale_update,
bcd);
bcd->brightness_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (bcd->brightness_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (bcd->brightness_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), bcd->brightness_text, 2, 3, 0, 1, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (bcd->brightness_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
(GtkSignalFunc) brightness_contrast_brightness_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
GTK_SIGNAL_FUNC (brightness_contrast_brightness_adjustment_update),
bcd); bcd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (bcd->brightness_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the contrast scale widget */ /* Create the contrast scale widget */
label = gtk_label_new (_("Contrast")); label = gtk_label_new (_("Contrast"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -127.0, 127.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -127.0, 127.0, 1.0, 10.0, 0.0);
bcd->contrast_data = GTK_ADJUSTMENT (data); bcd->contrast_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2, gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_contrast_scale_update,
bcd);
bcd->contrast_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (bcd->contrast_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (bcd->contrast_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), bcd->contrast_text, 2, 3, 1, 2, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (bcd->contrast_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
(GtkSignalFunc) brightness_contrast_contrast_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
GTK_SIGNAL_FUNC (brightness_contrast_contrast_adjustment_update),
bcd); bcd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (bcd->contrast_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Horizontal box for preview toggle button */
/* Horizontal box for preview and preserve luminosity toggle buttons */ hbox = gtk_hbox_new (FALSE, 4);
hbox = gtk_hbox_new (TRUE, 2); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), bcd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), bcd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) brightness_contrast_preview_update, GTK_SIGNAL_FUNC (brightness_contrast_preview_update),
bcd); bcd);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
@ -328,27 +317,13 @@ static void
brightness_contrast_update (BrightnessContrastDialog *bcd, brightness_contrast_update (BrightnessContrastDialog *bcd,
gint update) gint update)
{ {
char text[12]; if (update & BRIGHTNESS)
if (update & BRIGHTNESS_SLIDER)
{ {
bcd->brightness_data->value = bcd->brightness; gtk_adjustment_set_value (bcd->brightness_data, bcd->brightness);
gtk_signal_emit_by_name (GTK_OBJECT (bcd->brightness_data), "value_changed");
} }
if (update & CONTRAST_SLIDER) if (update & CONTRAST)
{ {
bcd->contrast_data->value = bcd->contrast; gtk_adjustment_set_value (bcd->contrast_data, bcd->contrast);
gtk_signal_emit_by_name (GTK_OBJECT (bcd->contrast_data), "value_changed");
}
if (update & BRIGHTNESS_TEXT)
{
g_snprintf (text, sizeof (text), "%0.0f", bcd->brightness);
gtk_entry_set_text (GTK_ENTRY (bcd->brightness_text), text);
}
if (update & CONTRAST_TEXT)
{
g_snprintf (text, sizeof (text), "%0.0f", bcd->contrast);
gtk_entry_set_text (GTK_ENTRY (bcd->contrast_text), text);
} }
} }
@ -371,12 +346,29 @@ brightness_contrast_preview (BrightnessContrastDialog *bcd)
} }
static void static void
brightness_contrast_ok_callback (GtkWidget *widget, brightness_contrast_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
bcd = (BrightnessContrastDialog *) client_data; bcd = (BrightnessContrastDialog *) data;
bcd->brightness = 0.0;
bcd->contrast = 0.0;
brightness_contrast_update (bcd, ALL);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
static void
brightness_contrast_ok_callback (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
bcd = (BrightnessContrastDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell)) if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell); gtk_widget_hide (bcd->shell);
@ -446,8 +438,8 @@ brightness_contrast_preview_update (GtkWidget *widget,
} }
static void static void
brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment, brightness_contrast_brightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
@ -456,7 +448,6 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
if (bcd->brightness != adjustment->value) if (bcd->brightness != adjustment->value)
{ {
bcd->brightness = adjustment->value; bcd->brightness = adjustment->value;
brightness_contrast_update (bcd, BRIGHTNESS_TEXT);
if (bcd->preview) if (bcd->preview)
brightness_contrast_preview (bcd); brightness_contrast_preview (bcd);
@ -464,8 +455,8 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
} }
static void static void
brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment, brightness_contrast_contrast_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
@ -474,51 +465,6 @@ brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
if (bcd->contrast != adjustment->value) if (bcd->contrast != adjustment->value)
{ {
bcd->contrast = adjustment->value; bcd->contrast = adjustment->value;
brightness_contrast_update (bcd, CONTRAST_TEXT);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
}
static void
brightness_contrast_brightness_text_update (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
gchar *str;
gint value;
str = gtk_entry_get_text (GTK_ENTRY (widget));
bcd = (BrightnessContrastDialog *) data;
value = BOUNDS (((int) atof (str)), -127, 127);
if ((int) bcd->brightness != value)
{
bcd->brightness = value;
brightness_contrast_update (bcd, BRIGHTNESS_SLIDER);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
}
static void
brightness_contrast_contrast_text_update (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
gchar *str;
gint value;
str = gtk_entry_get_text (GTK_ENTRY (widget));
bcd = (BrightnessContrastDialog *) data;
value = BOUNDS (((int) atof (str)), -127, 127);
if ((int) bcd->contrast != value)
{
bcd->contrast = value;
brightness_contrast_update (bcd, CONTRAST_SLIDER);
if (bcd->preview) if (bcd->preview)
brightness_contrast_preview (bcd); brightness_contrast_preview (bcd);

View File

@ -20,10 +20,9 @@
#include "tools.h" #include "tools.h"
/* by_color select functions */ Tool * tools_new_brightness_contrast (void);
Tool * tools_new_brightness_contrast (void); void tools_free_brightness_contrast (Tool *tool);
void tools_free_brightness_contrast (Tool *);
void brightness_contrast_initialize (GDisplay *); void brightness_contrast_initialize (GDisplay *gdisp);
#endif /* __BRIGHTNESS_CONTRAST_H__ */ #endif /* __BRIGHTNESS_CONTRAST_H__ */

View File

@ -15,32 +15,27 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "boundary.h" #include "boundary.h"
#include "by_color_select.h" #include "by_color_select.h"
#include "colormaps.h" #include "colormaps.h"
#include "drawable.h" #include "drawable.h"
#include "draw_core.h" #include "draw_core.h"
#include "general.h"
#include "gimage_mask.h" #include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimprc.h" #include "gimprc.h"
#include "gimpset.h" #include "gimpset.h"
#include "gimpui.h" #include "gimpui.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "selection_options.h" #include "selection_options.h"
#include "gimpdnd.h" #include "tile.h" /* ick. */
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "tile.h" /* ick. */ #define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define DEFAULT_FUZZINESS 15 #define PREVIEW_HEIGHT 256
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \ #define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \ GDK_BUTTON_PRESS_MASK | \
GDK_ENTER_NOTIFY_MASK GDK_ENTER_NOTIFY_MASK
@ -48,40 +43,43 @@
/* the by color selection structures */ /* the by color selection structures */
typedef struct _ByColorSelect ByColorSelect; typedef struct _ByColorSelect ByColorSelect;
struct _ByColorSelect struct _ByColorSelect
{ {
int x, y; /* Point from which to execute seed fill */ gint x, y; /* Point from which to execute seed fill */
int operation; /* add, subtract, normal color selection */ gint operation; /* add, subtract, normal color selection */
}; };
typedef struct _ByColorDialog ByColorDialog; typedef struct _ByColorDialog ByColorDialog;
struct _ByColorDialog struct _ByColorDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *preview;
GtkWidget *gimage_name;
int threshold; /* threshold value for color select */ GtkWidget *preview;
int operation; /* Add, Subtract, Replace */ GtkWidget *gimage_name;
GImage *gimage; /* gimage which is currently under examination */
gint threshold; /* threshold value for color select */
gint operation; /* Add, Subtract, Replace */
GImage *gimage; /* gimage which is currently under examination */
}; };
/* the by color selection tool options */ /* the by color selection tool options */
static SelectionOptions *by_color_options = NULL; static SelectionOptions * by_color_options = NULL;
/* the by color selection dialog */ /* the by color selection dialog */
static ByColorDialog * by_color_dialog = NULL; static ByColorDialog * by_color_dialog = NULL;
/* dnd stuff */ /* dnd stuff */
static GtkTargetEntry by_color_select_image_target_table[] = static GtkTargetEntry by_color_select_targets[] =
{ {
GIMP_TARGET_COLOR GIMP_TARGET_COLOR
}; };
static guint n_by_color_select_image_targets = static guint n_by_color_select_targets = (sizeof (by_color_select_targets) /
(sizeof (by_color_select_image_target_table) / sizeof (by_color_select_targets[0]));
sizeof (by_color_select_image_target_table[0]));
static void by_color_select_color_drop (GtkWidget*, guchar, guchar, guchar, gpointer); static void by_color_select_color_drop (GtkWidget *, guchar, guchar, guchar,
gpointer);
/* by_color select action functions */ /* by_color select action functions */
@ -90,32 +88,35 @@ static void by_color_select_button_release (Tool *, GdkEventButton *, gpointer);
static void by_color_select_cursor_update (Tool *, GdkEventMotion *, gpointer); static void by_color_select_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void by_color_select_control (Tool *, ToolAction, gpointer); static void by_color_select_control (Tool *, ToolAction, gpointer);
static ByColorDialog * by_color_select_new_dialog (void); static ByColorDialog * by_color_select_dialog_new (void);
static void by_color_select_render (ByColorDialog *, GImage *); static void by_color_select_render (ByColorDialog *, GImage *);
static void by_color_select_draw (ByColorDialog *, GImage *); static void by_color_select_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *, GdkEventButton *, static gint by_color_select_preview_events (GtkWidget *,
ByColorDialog *); GdkEventButton *,
static void by_color_select_type_callback (GtkWidget *, gpointer); ByColorDialog *);
static void by_color_select_reset_callback (GtkWidget *, gpointer); static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_close_callback (GtkWidget *, gpointer); static void by_color_select_reset_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer); static void by_color_select_close_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer);
static void by_color_select_preview_button_press (ByColorDialog *, static void by_color_select_preview_button_press (ByColorDialog *,
GdkEventButton *); GdkEventButton *);
static int is_pixel_sufficiently_different (unsigned char *, unsigned char *, int, int, int, int); static gint is_pixel_sufficiently_different (guchar *, guchar *,
static Channel * by_color_select_color (GImage *, GimpDrawable *, unsigned char *, int, int, int); gint, gint, gint, gint);
static Channel * by_color_select_color (GImage *, GimpDrawable *,
guchar *, gint, gint, gint);
/* by_color selection machinery */ /* by_color selection machinery */
static int static int
is_pixel_sufficiently_different (unsigned char *col1, is_pixel_sufficiently_different (guchar *col1,
unsigned char *col2, guchar *col2,
int antialias, gint antialias,
int threshold, gint threshold,
int bytes, gint bytes,
int has_alpha) gint has_alpha)
{ {
int diff; int diff;
int max; int max;
@ -145,7 +146,7 @@ is_pixel_sufficiently_different (unsigned char *col1,
if (aa <= 0) if (aa <= 0)
return 0; return 0;
else if (aa < 0.5) else if (aa < 0.5)
return (unsigned char) (aa * 512); return (guchar) (aa * 512);
else else
return 255; return 255;
} }
@ -159,12 +160,12 @@ is_pixel_sufficiently_different (unsigned char *col1,
} }
static Channel * static Channel *
by_color_select_color (GImage *gimage, by_color_select_color (GImage *gimage,
GimpDrawable *drawable, GimpDrawable *drawable,
unsigned char *color, guchar *color,
int antialias, gint antialias,
int threshold, gint threshold,
int sample_merged) gint sample_merged)
{ {
/* Scan over the gimage's active layer, finding pixels within the specified /* Scan over the gimage's active layer, finding pixels within the specified
* threshold from the given R, G, & B values. If antialiasing is on, * threshold from the given R, G, & B values. If antialiasing is on,
@ -173,10 +174,10 @@ by_color_select_color (GImage *gimage,
*/ */
Channel *mask; Channel *mask;
PixelRegion imagePR, maskPR; PixelRegion imagePR, maskPR;
unsigned char *image_data; guchar *image_data;
unsigned char *mask_data; guchar *mask_data;
unsigned char *idata, *mdata; guchar *idata, *mdata;
unsigned char rgb[MAX_CHANNELS]; guchar rgb[MAX_CHANNELS];
int has_alpha, indexed; int has_alpha, indexed;
int width, height; int width, height;
int bytes, color_bytes, alpha; int bytes, color_bytes, alpha;
@ -195,7 +196,8 @@ by_color_select_color (GImage *gimage,
indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE; indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE;
width = gimage->width; width = gimage->width;
height = gimage->height; height = gimage->height;
pixel_region_init (&imagePR, gimage_composite (gimage), 0, 0, width, height, FALSE); pixel_region_init (&imagePR, gimage_composite (gimage),
0, 0, width, height, FALSE);
} }
else else
{ {
@ -206,16 +208,20 @@ by_color_select_color (GImage *gimage,
width = drawable_width (drawable); width = drawable_width (drawable);
height = drawable_height (drawable); height = drawable_height (drawable);
pixel_region_init (&imagePR, drawable_data (drawable), 0, 0, width, height, FALSE); pixel_region_init (&imagePR, drawable_data (drawable),
0, 0, width, height, FALSE);
} }
if (indexed) { if (indexed)
/* indexed colors are always RGB or RGBA */ {
color_bytes = has_alpha ? 4 : 3; /* indexed colors are always RGB or RGBA */
} else { color_bytes = has_alpha ? 4 : 3;
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */ }
color_bytes = bytes; else
} {
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
alpha = bytes - 1; alpha = bytes - 1;
mask = channel_new_mask (gimage, width, height); mask = channel_new_mask (gimage, width, height);
@ -223,7 +229,9 @@ by_color_select_color (GImage *gimage,
0, 0, width, height, TRUE); 0, 0, width, height, TRUE);
/* iterate over the entire image */ /* iterate over the entire image */
for (pr = pixel_regions_register (2, &imagePR, &maskPR); pr != NULL; pr = pixel_regions_process (pr)) for (pr = pixel_regions_register (2, &imagePR, &maskPR);
pr != NULL;
pr = pixel_regions_process (pr))
{ {
image_data = imagePR.data; image_data = imagePR.data;
mask_data = maskPR.data; mask_data = maskPR.data;
@ -242,8 +250,12 @@ by_color_select_color (GImage *gimage,
rgb[color_bytes - 1] = idata[alpha]; rgb[color_bytes - 1] = idata[alpha];
/* Find how closely the colors match */ /* Find how closely the colors match */
*mdata++ = is_pixel_sufficiently_different (color, rgb, antialias, *mdata++ = is_pixel_sufficiently_different (color,
threshold, color_bytes, has_alpha); rgb,
antialias,
threshold,
color_bytes,
has_alpha);
idata += bytes; idata += bytes;
} }
@ -257,15 +269,15 @@ by_color_select_color (GImage *gimage,
} }
void void
by_color_select (GImage *gimage, by_color_select (GImage *gimage,
GimpDrawable *drawable, GimpDrawable *drawable,
unsigned char *color, guchar *color,
int threshold, gint threshold,
int op, gint op,
int antialias, gint antialias,
int feather, gint feather,
double feather_radius, gdouble feather_radius,
int sample_merged) gint sample_merged)
{ {
Channel * new_mask; Channel * new_mask;
int off_x, off_y; int off_x, off_y;
@ -273,7 +285,8 @@ by_color_select (GImage *gimage,
if (!drawable) if (!drawable)
return; return;
new_mask = by_color_select_color (gimage, drawable, color, antialias, threshold, sample_merged); new_mask = by_color_select_color (gimage, drawable, color,
antialias, threshold, sample_merged);
/* if applicable, replace the current selection */ /* if applicable, replace the current selection */
if (op == REPLACE) if (op == REPLACE)
@ -300,7 +313,6 @@ by_color_select (GImage *gimage,
channel_delete (new_mask); channel_delete (new_mask);
} }
/* by_color select action functions */ /* by_color select action functions */
static void static void
@ -345,8 +357,25 @@ by_color_select_button_press (Tool *tool,
/* Update the by_color_dialog's active gdisp pointer */ /* Update the by_color_dialog's active gdisp pointer */
if (by_color_dialog->gimage) if (by_color_dialog->gimage)
by_color_dialog->gimage->by_color_select = FALSE; by_color_dialog->gimage->by_color_select = FALSE;
if (by_color_dialog->gimage != gdisp->gimage)
{
gdk_draw_rectangle
(by_color_dialog->preview->window,
by_color_dialog->preview->style->bg_gc[GTK_STATE_NORMAL],
TRUE,
0, 0,
by_color_dialog->preview->allocation.width,
by_color_dialog->preview->allocation.width);
}
by_color_dialog->gimage = gdisp->gimage; by_color_dialog->gimage = gdisp->gimage;
gdisp->gimage->by_color_select = TRUE; gdisp->gimage->by_color_select = TRUE;
gdk_pointer_grab (gdisp->canvas->window, FALSE,
GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, bevent->time);
} }
static void static void
@ -356,32 +385,35 @@ by_color_select_button_release (Tool *tool,
{ {
ByColorSelect * by_color_sel; ByColorSelect * by_color_sel;
GDisplay * gdisp; GDisplay * gdisp;
int x, y; gint x, y;
GimpDrawable *drawable; GimpDrawable *drawable;
unsigned char *color; guchar *color;
int use_offsets; gint use_offsets;
gdisp = (GDisplay *) gdisp_ptr; gdisp = (GDisplay *) gdisp_ptr;
by_color_sel = (ByColorSelect *) tool->private; by_color_sel = (ByColorSelect *) tool->private;
drawable = gimage_active_drawable (gdisp->gimage); drawable = gimage_active_drawable (gdisp->gimage);
gdk_pointer_ungrab (bevent->time);
tool->state = INACTIVE; tool->state = INACTIVE;
/* First take care of the case where the user "cancels" the action */ /* First take care of the case where the user "cancels" the action */
if (! (bevent->state & GDK_BUTTON3_MASK)) if (! (bevent->state & GDK_BUTTON3_MASK))
{ {
use_offsets = (by_color_options->sample_merged) ? FALSE : TRUE; use_offsets = (by_color_options->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, by_color_sel->x, by_color_sel->y, &x, &y, FALSE, use_offsets); gdisplay_untransform_coords (gdisp, by_color_sel->x, by_color_sel->y,
&x, &y, FALSE, use_offsets);
/* Get the start color */ /* Get the start color */
if (by_color_options->sample_merged) if (by_color_options->sample_merged)
{ {
if (!(color = gimp_image_get_color_at(gdisp->gimage, x, y))) if (!(color = gimp_image_get_color_at (gdisp->gimage, x, y)))
return; return;
} }
else else
{ {
if (!(color = gimp_drawable_get_color_at(drawable, x, y))) if (!(color = gimp_drawable_get_color_at (drawable, x, y)))
return; return;
} }
@ -394,7 +426,7 @@ by_color_select_button_release (Tool *tool,
by_color_options->feather_radius, by_color_options->feather_radius,
by_color_options->sample_merged); by_color_options->sample_merged);
g_free(color); g_free (color);
/* show selection on all views */ /* show selection on all views */
gdisplays_flush (); gdisplays_flush ();
@ -412,17 +444,20 @@ by_color_select_cursor_update (Tool *tool,
{ {
GDisplay *gdisp; GDisplay *gdisp;
Layer *layer; Layer *layer;
int x, y; gint x, y;
gdisp = (GDisplay *) gdisp_ptr; gdisp = (GDisplay *) gdisp_ptr;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&x, &y, FALSE, FALSE);
if ((layer = gimage_pick_correlate_layer (gdisp->gimage, x, y))) if ((layer = gimage_pick_correlate_layer (gdisp->gimage, x, y)))
if (layer == gdisp->gimage->active_layer) if (layer == gdisp->gimage->active_layer)
{ {
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS); gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
return; return;
} }
gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW); gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW);
} }
@ -450,13 +485,13 @@ by_color_select_control (Tool *tool,
} }
static void static void
by_color_select_options_reset () by_color_select_options_reset (void)
{ {
selection_options_reset (by_color_options); selection_options_reset (by_color_options);
} }
Tool * Tool *
tools_new_by_color_select () tools_new_by_color_select (void)
{ {
Tool * tool; Tool * tool;
ByColorSelect * private; ByColorSelect * private;
@ -471,7 +506,7 @@ tools_new_by_color_select ()
/* The "by color" dialog */ /* The "by color" dialog */
if (!by_color_dialog) if (!by_color_dialog)
by_color_dialog = by_color_select_new_dialog (); by_color_dialog = by_color_select_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell)) if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell))
gtk_widget_show (by_color_dialog->shell); gtk_widget_show (by_color_dialog->shell);
@ -521,7 +556,6 @@ by_color_select_initialize_by_image (GImage *gimage)
void void
by_color_select_initialize (GDisplay *gdisp) by_color_select_initialize (GDisplay *gdisp)
{ {
/* wrap this call so the tool_info->init_func works */
by_color_select_initialize_by_image (gdisp->gimage); by_color_select_initialize_by_image (gdisp->gimage);
} }
@ -530,37 +564,16 @@ by_color_select_initialize (GDisplay *gdisp)
/****************************/ /****************************/
static ByColorDialog * static ByColorDialog *
by_color_select_new_dialog () by_color_select_dialog_new (void)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *options_box; GtkWidget *options_box;
GtkWidget *label; GtkWidget *label;
GtkWidget *util_box; GtkWidget *util_box;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *radio_box;
GtkWidget *radio_button;
GtkObject *data; GtkObject *data;
GSList *group = NULL;
gint i;
gchar *button_names[] =
{
N_("Replace"),
N_("Add"),
N_("Subtract"),
N_("Intersect")
};
gint button_values[] =
{
REPLACE,
ADD,
SUB,
INTERSECT
};
bcd = g_new (ByColorDialog, 1); bcd = g_new (ByColorDialog, 1);
bcd->gimage = NULL; bcd->gimage = NULL;
@ -580,101 +593,98 @@ by_color_select_new_dialog ()
NULL); NULL);
/* The vbox */ /* The main hbox */
vbox = gtk_vbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), hbox);
/* The horizontal box containing preview & options box */
hbox = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview */ /* The preview */
util_box = gtk_vbox_new (FALSE, 2); util_box = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), util_box, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0);
bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE); bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT); gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT);
gtk_widget_set_events (bcd->preview, PREVIEW_EVENT_MASK); gtk_widget_set_events (bcd->preview, PREVIEW_EVENT_MASK);
gtk_signal_connect (GTK_OBJECT (bcd->preview), "button_press_event",
(GtkSignalFunc) by_color_select_preview_events,
bcd);
gtk_container_add (GTK_CONTAINER (frame), bcd->preview); gtk_container_add (GTK_CONTAINER (frame), bcd->preview);
/* dnd colors to the image window */ gtk_signal_connect (GTK_OBJECT (bcd->preview), "button_press_event",
GTK_SIGNAL_FUNC (by_color_select_preview_events),
bcd);
/* dnd colors to the image window */
gtk_drag_dest_set (bcd->preview, gtk_drag_dest_set (bcd->preview,
GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP, GTK_DEST_DEFAULT_DROP,
by_color_select_image_target_table, by_color_select_targets,
n_by_color_select_image_targets, n_by_color_select_targets,
GDK_ACTION_COPY); GDK_ACTION_COPY);
gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd); gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd);
gtk_widget_show (bcd->preview); gtk_widget_show (bcd->preview);
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (util_box); gtk_widget_show (util_box);
/* options box */ /* options box */
options_box = gtk_vbox_new (FALSE, 2); options_box = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (options_box), 5); gtk_box_pack_start (GTK_BOX (hbox), options_box, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), options_box, TRUE, TRUE, 0);
/* Create the active image label */ /* Create the active image label */
util_box = gtk_hbox_new (FALSE, 2); util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
bcd->gimage_name = gtk_label_new (_("Inactive")); bcd->gimage_name = gtk_label_new (_("Inactive"));
gtk_box_pack_start (GTK_BOX (util_box), bcd->gimage_name, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), bcd->gimage_name, FALSE, FALSE, 0);
gtk_widget_show (bcd->gimage_name); gtk_widget_show (bcd->gimage_name);
gtk_widget_show (util_box); gtk_widget_show (util_box);
/* Create the selection mode radio box */ /* Create the selection mode radio box */
frame = gtk_frame_new (_("Selection Mode")); frame =
gimp_radio_group_new (TRUE, _("Selection Mode"),
_("Replace"), by_color_select_type_callback,
(gpointer) REPLACE, NULL, NULL, TRUE,
_("Add"), by_color_select_type_callback,
(gpointer) ADD, NULL, NULL, FALSE,
_("Subtract"), by_color_select_type_callback,
(gpointer) SUB, NULL, NULL, FALSE,
_("Intersect"), by_color_select_type_callback,
(gpointer) INTERSECT, NULL, NULL, FALSE,
NULL);
gtk_box_pack_start (GTK_BOX (options_box), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), frame, FALSE, FALSE, 0);
radio_box = gtk_vbox_new (FALSE, 2);
gtk_container_add (GTK_CONTAINER (frame), radio_box);
/* the radio buttons */
for (i = 0; i < (sizeof(button_names) / sizeof(button_names[0])); i++)
{
radio_button = gtk_radio_button_new_with_label (group,
gettext(button_names[i]));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_box_pack_start (GTK_BOX (radio_box), radio_button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) by_color_select_type_callback,
(gpointer) ((long) button_values[i]));
gtk_widget_show (radio_button);
}
gtk_widget_show (radio_box);
gtk_widget_show (frame); gtk_widget_show (frame);
/* Create the opacity scale widget */ /* Create the opacity scale widget */
util_box = gtk_vbox_new (FALSE, 2); util_box = gtk_vbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
label = gtk_label_new (_("Fuzziness Threshold")); label = gtk_label_new (_("Fuzziness Threshold"));
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
gtk_widget_show (label);
gtk_widget_show (util_box);
data = gtk_adjustment_new (bcd->threshold, 0.0, 255.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (bcd->threshold, 0.0, 255.0, 1.0, 1.0, 0.0);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (data), "value_changed", gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) by_color_select_fuzzy_update, GTK_SIGNAL_FUNC (by_color_select_fuzzy_update),
bcd); bcd);
gtk_widget_show (label);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (util_box);
gtk_widget_show (options_box); gtk_widget_show (options_box);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (vbox);
gtk_widget_show (bcd->shell); gtk_widget_show (bcd->shell);
return bcd; return bcd;
@ -686,14 +696,14 @@ by_color_select_render (ByColorDialog *bcd,
{ {
Channel * mask; Channel * mask;
MaskBuf * scaled_buf = NULL; MaskBuf * scaled_buf = NULL;
unsigned char *buf; guchar *buf;
PixelRegion srcPR, destPR; PixelRegion srcPR, destPR;
unsigned char * src; guchar * src;
int subsample; gint subsample;
int width, height; gint width, height;
int srcwidth; gint srcwidth;
int i; gint i;
int scale; gint scale;
mask = gimage_get_mask (gimage); mask = gimage_get_mask (gimage);
if ((drawable_width (GIMP_DRAWABLE(mask)) > PREVIEW_WIDTH) || if ((drawable_width (GIMP_DRAWABLE(mask)) > PREVIEW_WIDTH) ||
@ -703,11 +713,13 @@ by_color_select_render (ByColorDialog *bcd,
((float) drawable_height (GIMP_DRAWABLE (mask)) / (float) PREVIEW_HEIGHT)) ((float) drawable_height (GIMP_DRAWABLE (mask)) / (float) PREVIEW_HEIGHT))
{ {
width = PREVIEW_WIDTH; width = PREVIEW_WIDTH;
height = (drawable_height (GIMP_DRAWABLE (mask)) * PREVIEW_WIDTH) / drawable_width (GIMP_DRAWABLE (mask)); height = ((drawable_height (GIMP_DRAWABLE (mask)) * PREVIEW_WIDTH) /
drawable_width (GIMP_DRAWABLE (mask)));
} }
else else
{ {
width = (drawable_width (GIMP_DRAWABLE (mask)) * PREVIEW_HEIGHT) / drawable_height (GIMP_DRAWABLE (mask)); width = ((drawable_width (GIMP_DRAWABLE (mask)) * PREVIEW_HEIGHT) /
drawable_height (GIMP_DRAWABLE (mask)));
height = PREVIEW_HEIGHT; height = PREVIEW_HEIGHT;
} }
@ -726,10 +738,10 @@ by_color_select_render (ByColorDialog *bcd,
gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height); gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height);
/* clear the image buf */ /* clear the image buf */
buf = (unsigned char *) g_malloc (bcd->preview->requisition.width); buf = g_new0 (guchar, bcd->preview->requisition.width);
memset (buf, 0, bcd->preview->requisition.width);
for (i = 0; i < bcd->preview->requisition.height; i++) for (i = 0; i < bcd->preview->requisition.height; i++)
gtk_preview_draw_row (GTK_PREVIEW (bcd->preview), buf, 0, i, bcd->preview->requisition.width); gtk_preview_draw_row (GTK_PREVIEW (bcd->preview), buf,
0, i, bcd->preview->requisition.width);
g_free (buf); g_free (buf);
/* if the mask is empty, no need to scale and update again */ /* if the mask is empty, no need to scale and update again */
@ -800,7 +812,8 @@ by_color_select_draw (ByColorDialog *bcd,
gtk_widget_draw (bcd->preview, NULL); gtk_widget_draw (bcd->preview, NULL);
/* Update the gimage label to reflect the displayed gimage name */ /* Update the gimage label to reflect the displayed gimage name */
gtk_label_set_text (GTK_LABEL (bcd->gimage_name), g_basename (gimage_filename (gimage))); gtk_label_set_text (GTK_LABEL (bcd->gimage_name),
g_basename (gimage_filename (gimage)));
} }
static gint static gint
@ -823,25 +836,25 @@ by_color_select_preview_events (GtkWidget *widget,
static void static void
by_color_select_type_callback (GtkWidget *widget, by_color_select_type_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
if (by_color_dialog) if (by_color_dialog)
by_color_dialog->operation = (long) client_data; by_color_dialog->operation = (long) data;
} }
static void static void
by_color_select_reset_callback (GtkWidget *widget, by_color_select_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data; bcd = (ByColorDialog *) data;
if (!bcd->gimage) if (!bcd->gimage)
return; return;
/* check if the image associated to the mask still exists */ /* check if the image associated to the mask still exists */
if (!drawable_gimage (GIMP_DRAWABLE(gimage_get_mask (bcd->gimage)))) if (!drawable_gimage (GIMP_DRAWABLE (gimage_get_mask (bcd->gimage))))
return; return;
/* reset the mask */ /* reset the mask */
@ -857,16 +870,16 @@ by_color_select_reset_callback (GtkWidget *widget,
static void static void
by_color_select_close_callback (GtkWidget *widget, by_color_select_close_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data; bcd = (ByColorDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell)) if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell); gtk_widget_hide (bcd->shell);
if (bcd->gimage && if (bcd->gimage && gimp_set_have (image_context, bcd->gimage))
gimp_set_have (image_context, bcd->gimage))
{ {
bcd->gimage->by_color_select = FALSE; bcd->gimage->by_color_select = FALSE;
bcd->gimage = NULL; bcd->gimage = NULL;
@ -880,18 +893,19 @@ by_color_select_fuzzy_update (GtkAdjustment *adjustment,
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) data; bcd = (ByColorDialog *) data;
bcd->threshold = (int) adjustment->value;
bcd->threshold = (gint) (adjustment->value + 0.5);
} }
static void static void
by_color_select_preview_button_press (ByColorDialog *bcd, by_color_select_preview_button_press (ByColorDialog *bcd,
GdkEventButton *bevent) GdkEventButton *bevent)
{ {
int x, y; gint x, y;
int replace, operation; gint replace, operation;
GimpDrawable *drawable; GimpDrawable *drawable;
Tile *tile; Tile *tile;
unsigned char *col; guchar *col;
if (!bcd->gimage) if (!bcd->gimage)
return; return;

View File

@ -22,14 +22,20 @@
#include "gdisplayF.h" #include "gdisplayF.h"
#include "gimage.h" #include "gimage.h"
/* by_color select functions */ Tool * tools_new_by_color_select (void);
void by_color_select (GimpImage *, GimpDrawable *, guchar *, int, void tools_free_by_color_select (Tool *tool);
int, int, int, double, int);
Tool * tools_new_by_color_select (void); void by_color_select_initialize (GDisplay *gdisp);
void tools_free_by_color_select (Tool *); void by_color_select_initialize_by_image (GImage *gimage);
void by_color_select_initialize (GDisplay *); void by_color_select (GimpImage *gimage,
void by_color_select_initialize_by_image (GImage *); GimpDrawable *drawable,
guchar *color,
gint threshold,
gint op,
gint antialias,
gint feather,
gdouble feather_radius,
gint sample_merged);
#endif /* __BY_COLOR_SELECT_H__ */ #endif /* __BY_COLOR_SELECT_H__ */

View File

@ -15,21 +15,13 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "color_balance.h" #include "color_balance.h"
#include "color_transfer.h" #include "color_transfer.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimpui.h" #include "gimpui.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
static void color_balance_control (Tool *, ToolAction, gpointer); static void color_balance_control (Tool *, ToolAction, gpointer);
static ColorBalanceDialog * color_balance_new_dialog (void); static ColorBalanceDialog * color_balance_dialog_new (void);
static void color_balance_update (ColorBalanceDialog *, int); static void color_balance_update (ColorBalanceDialog *, int);
static void color_balance_preview (ColorBalanceDialog *); static void color_balance_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer); static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer); static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer); static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer); static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer); static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer); static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */ /* The color balance dialog */
if (!color_balance_dialog) if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog (); color_balance_dialog = color_balance_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell)) if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell))
gtk_widget_show (color_balance_dialog->shell); gtk_widget_show (color_balance_dialog->shell);
/* Initialize dialog fields */
color_balance_dialog->image_map = NULL;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
color_balance_dialog->cyan_red[i] = 0.0; color_balance_dialog->cyan_red[i] = 0.0;
color_balance_dialog->magenta_green[i] = 0.0; color_balance_dialog->magenta_green[i] = 0.0;
color_balance_dialog->yellow_blue[i] = 0.0; color_balance_dialog->yellow_blue[i] = 0.0;
} }
color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage); color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = color_balance_dialog->image_map =
image_map_create (gdisp, color_balance_dialog->drawable); image_map_create (gdisp, color_balance_dialog->drawable);
@ -236,13 +226,12 @@ color_balance_initialize (GDisplay *gdisp)
color_balance_update (color_balance_dialog, ALL); color_balance_update (color_balance_dialog, ALL);
} }
/**************************/ /**************************/
/* Color Balance dialog */ /* Color Balance dialog */
/**************************/ /**************************/
static ColorBalanceDialog * static ColorBalanceDialog *
color_balance_new_dialog (void) color_balance_dialog_new (void)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
GtkWidget *vbox; GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights") N_("Highlights")
}; };
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1); cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE; cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE; cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback, _("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE, cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback, _("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Color Levels:")); label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label); gtk_widget_show (label);
/* cyan-red spinbutton */ /* cyan-red spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->cyan_red_data = GTK_ADJUSTMENT (data); cbd->cyan_red_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0);
@ -313,7 +297,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* magenta-green spinbutton */ /* magenta-green spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->magenta_green_data = GTK_ADJUSTMENT (data); cbd->magenta_green_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0);
@ -322,7 +306,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* yellow-blue spinbutton */ /* yellow-blue spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->yellow_blue_data = GTK_ADJUSTMENT (data); cbd->yellow_blue_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0);
@ -334,22 +318,22 @@ color_balance_new_dialog (void)
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the cyan-red scale widget */ /* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan")); start_label = gtk_label_new (_("Cyan"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->cyan_red_data); slider = gtk_hscale_new (cbd->cyan_red_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update), GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update),
cbd); cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red")); end_label = gtk_label_new (_("Red"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta")); start_label = gtk_label_new (_("Magenta"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->magenta_green_data); slider = gtk_hscale_new (cbd->magenta_green_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update), GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update),
cbd); cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green")); end_label = gtk_label_new (_("Green"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow")); start_label = gtk_label_new (_("Yellow"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->yellow_blue_data); slider = gtk_hscale_new (cbd->yellow_blue_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 2, 3);
gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update), GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update),
cbd); cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue")); end_label = gtk_label_new (_("Blue"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
gtk_widget_show (slider); gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */ gtk_widget_show (table);
hbox = gtk_hbox_new (TRUE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button = radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i])); gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_box_pack_start (GTK_BOX (hbox), radio_button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), radio_button, TRUE, FALSE, 0);
gtk_object_set_user_data (GTK_OBJECT (radio_button), (gpointer) i);
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
GTK_SIGNAL_FUNC (appl_mode_callbacks[i]), GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd); cbd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (hbox);
/* Horizontal box for preview and preserve luminosity toggle buttons */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (cbd->shell); gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd) color_balance_preview (ColorBalanceDialog *cbd)
{ {
if (!cbd->image_map) if (!cbd->image_map)
g_message ("color_balance_preview(): No image map"); {
g_message ("color_balance_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
color_balance_create_lookup_tables (cbd); color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void
color_balance_reset_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->cyan_red[cbd->application_mode] = 0.0;
cbd->magenta_green[cbd->application_mode] = 0.0;
cbd->yellow_blue[cbd->application_mode] = 0.0;
color_balance_update (cbd, ALL);
if (cbd->preview)
color_balance_preview (cbd);
}
static void static void
color_balance_ok_callback (GtkWidget *widget, color_balance_ok_callback (GtkWidget *widget,
gpointer data) gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
} }
static void static void
color_balance_shadows_callback (GtkWidget *widget, color_balance_range_callback (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data; cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS; range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
color_balance_update (cbd, ALL); cbd->application_mode = range;
}
static void
color_balance_midtones_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = MIDTONES;
color_balance_update (cbd, ALL);
}
static void
color_balance_highlights_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = HIGHLIGHTS;
color_balance_update (cbd, ALL); color_balance_update (cbd, ALL);
} }

View File

@ -57,8 +57,6 @@ struct _ColorBalanceDialog
TransferMode application_mode; TransferMode application_mode;
}; };
/* color balance functions */
Tool * tools_new_color_balance (void); Tool * tools_new_color_balance (void);
void tools_free_color_balance (Tool *tool); void tools_free_color_balance (Tool *tool);

View File

@ -39,10 +39,11 @@ static void color_notebook_cancel_callback (GtkWidget *, gpointer);
static void color_notebook_update_callback (void *, int, int, int); static void color_notebook_update_callback (void *, int, int, int);
static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *, static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *,
guint); guint);
static void color_notebook_help_func (gpointer data); static void color_notebook_help_func (gchar *data);
/* information we keep on each registered colour selector */ /* information we keep on each registered colour selector */
typedef struct _ColorSelectorInfo { typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */ char *name; /* label used in notebook tab */
char *help_page; char *help_page;
GimpColorSelectorMethods m; GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next; struct _ColorSelectorInfo *next;
} ColorSelectorInfo; } ColorSelectorInfo;
typedef struct _ColorSelectorInstance { typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook; _ColorNotebook *color_notebook;
ColorSelectorInfo *info; ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */ GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell = cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection", gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp, color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
} }
static void static void
color_notebook_help_func (gpointer data) color_notebook_help_func (gchar *data)
{ {
ColorNotebookP cnp; ColorNotebookP cnp;
gchar *help_path; gchar *help_path;

View File

@ -15,43 +15,36 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "buildmenu.h" #include "buildmenu.h"
#include "colormaps.h" #include "colormaps.h"
#include "cursorutil.h" #include "cursorutil.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimphistogram.h" #include "gimphistogram.h"
#include "gimpui.h" #include "gimpui.h"
#include "interface.h"
#include "curves.h" #include "curves.h"
#include "gimplut.h" #include "gimplut.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
#define GRAPH 0x1 #define GRAPH 0x1
#define XRANGE_TOP 0x2 #define XRANGE_TOP 0x2
#define XRANGE_BOTTOM 0x4 #define XRANGE_BOTTOM 0x4
#define YRANGE 0x8 #define YRANGE 0x8
#define DRAW 0x10 #define DRAW 0x10
#define ALL 0xFF #define ALL 0xFF
/* NB: take care when changing these values: make sure the curve[] array in /* NB: take care when changing these values: make sure the curve[] array in
* curves.h is large enough. * curves.h is large enough.
*/ */
#define GRAPH_WIDTH 256 #define GRAPH_WIDTH 256
#define GRAPH_HEIGHT 256 #define GRAPH_HEIGHT 256
#define XRANGE_WIDTH 256 #define XRANGE_WIDTH 256
#define XRANGE_HEIGHT 16 #define XRANGE_HEIGHT 16
#define YRANGE_WIDTH 16 #define YRANGE_WIDTH 16
#define YRANGE_HEIGHT 256 #define YRANGE_HEIGHT 256
#define RADIUS 3 #define RADIUS 3
#define MIN_DISTANCE 8 #define MIN_DISTANCE 8
@ -69,13 +62,13 @@
/* the curves structures */ /* the curves structures */
typedef struct _Curves Curves; typedef struct _Curves Curves;
struct _Curves struct _Curves
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef double CRMatrix[4][4]; typedef gdouble CRMatrix[4][4];
/* the curves tool options */ /* the curves tool options */
static ToolOptions * curves_options = NULL; static ToolOptions * curves_options = NULL;
@ -99,18 +92,21 @@ static void curves_button_release (Tool *, GdkEventButton *, gpointer);
static void curves_motion (Tool *, GdkEventMotion *, gpointer); static void curves_motion (Tool *, GdkEventMotion *, gpointer);
static void curves_control (Tool *, ToolAction, gpointer); static void curves_control (Tool *, ToolAction, gpointer);
static CurvesDialog * curves_new_dialog (void); static CurvesDialog * curves_dialog_new (void);
static void curves_update (CurvesDialog *, int); static void curves_update (CurvesDialog *, int);
static void curves_plot_curve (CurvesDialog *, int, int, int, int); static void curves_plot_curve (CurvesDialog *, int, int, int, int);
static void curves_preview (CurvesDialog *); static void curves_preview (CurvesDialog *);
static void curves_value_callback (GtkWidget *, gpointer); static void curves_value_callback (GtkWidget *, gpointer);
static void curves_red_callback (GtkWidget *, gpointer); static void curves_red_callback (GtkWidget *, gpointer);
static void curves_green_callback (GtkWidget *, gpointer); static void curves_green_callback (GtkWidget *, gpointer);
static void curves_blue_callback (GtkWidget *, gpointer); static void curves_blue_callback (GtkWidget *, gpointer);
static void curves_alpha_callback (GtkWidget *, gpointer); static void curves_alpha_callback (GtkWidget *, gpointer);
static void curves_smooth_callback (GtkWidget *, gpointer); static void curves_smooth_callback (GtkWidget *, gpointer);
static void curves_free_callback (GtkWidget *, gpointer); static void curves_free_callback (GtkWidget *, gpointer);
static void curves_reset_callback (GtkWidget *, gpointer); static void curves_reset_callback (GtkWidget *, gpointer);
static void curves_ok_callback (GtkWidget *, gpointer); static void curves_ok_callback (GtkWidget *, gpointer);
static void curves_cancel_callback (GtkWidget *, gpointer); static void curves_cancel_callback (GtkWidget *, gpointer);
@ -120,12 +116,13 @@ static gint curves_yrange_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *); static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix); static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix);
/* curves machinery */ /* curves machinery */
float float
curves_lut_func (CurvesDialog *cd, curves_lut_func (CurvesDialog *cd,
int nchannels, int channel, float value) gint nchannels,
gint channel,
gfloat value)
{ {
float f; float f;
int index; int index;
@ -188,9 +185,9 @@ curves_colour_update (Tool *tool,
if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y))) if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y)))
return; return;
sample_type = gimp_drawable_type(drawable); sample_type = gimp_drawable_type (drawable);
is_indexed = gimp_drawable_is_indexed (drawable); is_indexed = gimp_drawable_is_indexed (drawable);
has_alpha = TYPE_HAS_ALPHA(sample_type); has_alpha = TYPE_HAS_ALPHA (sample_type);
curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX]; curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX];
curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX]; curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX];
@ -207,11 +204,14 @@ curves_colour_update (Tool *tool,
maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]); maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]);
curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]); curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]);
g_free(color); g_free (color);
} }
static void static void
curves_add_point(GimpDrawable * drawable,gint x, gint y,gint cchan) curves_add_point (GimpDrawable *drawable,
gint x,
gint y,
gint cchan)
{ {
/* Add point onto the curve */ /* Add point onto the curve */
int closest_point = 0; int closest_point = 0;
@ -301,21 +301,21 @@ curves_button_release (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
if(bevent->state & GDK_SHIFT_MASK) if(bevent->state & GDK_SHIFT_MASK)
{ {
curves_add_point(drawable,x,y,curves_dialog->channel); curves_add_point (drawable, x, y, curves_dialog->channel);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
else if(bevent->state & GDK_CONTROL_MASK) else if(bevent->state & GDK_CONTROL_MASK)
{ {
curves_add_point(drawable,x,y,HISTOGRAM_VALUE); curves_add_point (drawable, x, y, HISTOGRAM_VALUE);
curves_add_point(drawable,x,y,HISTOGRAM_RED); curves_add_point (drawable, x, y, HISTOGRAM_RED);
curves_add_point(drawable,x,y,HISTOGRAM_GREEN); curves_add_point (drawable, x, y, HISTOGRAM_GREEN);
curves_add_point(drawable,x,y,HISTOGRAM_BLUE); curves_add_point (drawable, x, y, HISTOGRAM_BLUE);
curves_add_point(drawable,x,y,HISTOGRAM_ALPHA); curves_add_point (drawable, x, y, HISTOGRAM_ALPHA);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
@ -338,7 +338,7 @@ curves_motion (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
} }
@ -366,7 +366,7 @@ curves_control (Tool *tool,
} }
Tool * Tool *
tools_new_curves () tools_new_curves (void)
{ {
Tool * tool; Tool * tool;
Curves * private; Curves * private;
@ -397,15 +397,15 @@ tools_new_curves ()
void void
tools_free_curves (Tool *tool) tools_free_curves (Tool *tool)
{ {
Curves * _curves; Curves * private;
_curves = (Curves *) tool->private; private = (Curves *) tool->private;
/* Close the color select dialog */ /* Close the color select dialog */
if (curves_dialog) if (curves_dialog)
curves_cancel_callback (NULL, (gpointer) curves_dialog); curves_cancel_callback (NULL, (gpointer) curves_dialog);
g_free (_curves); g_free (private);
} }
static MenuItem channel_items[] = static MenuItem channel_items[] =
@ -421,7 +421,7 @@ static MenuItem channel_items[] =
void void
curves_initialize (GDisplay *gdisp) curves_initialize (GDisplay *gdisp)
{ {
int i, j; gint i, j;
if (drawable_indexed (gimage_active_drawable (gdisp->gimage))) if (drawable_indexed (gimage_active_drawable (gdisp->gimage)))
{ {
@ -431,7 +431,10 @@ curves_initialize (GDisplay *gdisp)
/* The curves dialog */ /* The curves dialog */
if (!curves_dialog) if (!curves_dialog)
curves_dialog = curves_new_dialog (); curves_dialog = curves_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (curves_dialog->shell))
gtk_widget_show (curves_dialog->shell);
/* Initialize the values */ /* Initialize the values */
curves_dialog->channel = HISTOGRAM_VALUE; curves_dialog->channel = HISTOGRAM_VALUE;
@ -454,22 +457,22 @@ curves_initialize (GDisplay *gdisp)
} }
curves_dialog->drawable = gimage_active_drawable (gdisp->gimage); curves_dialog->drawable = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color ( (curves_dialog->drawable)); curves_dialog->color = drawable_color (curves_dialog->drawable);
curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable); curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable);
/* check for alpha channel */ /* check for alpha channel */
if (drawable_has_alpha ( (curves_dialog->drawable))) if (drawable_has_alpha (curves_dialog->drawable))
gtk_widget_set_sensitive( channel_items[4].widget, TRUE); gtk_widget_set_sensitive (channel_items[4].widget, TRUE);
else else
gtk_widget_set_sensitive( channel_items[4].widget, FALSE); gtk_widget_set_sensitive (channel_items[4].widget, FALSE);
/* hide or show the channel menu based on image type */ /* hide or show the channel menu based on image type */
if (curves_dialog->color) if (curves_dialog->color)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, TRUE); gtk_widget_set_sensitive (channel_items[i].widget, TRUE);
else else
for (i = 1; i < 4; i++) for (i = 1; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, FALSE); gtk_widget_set_sensitive (channel_items[i].widget, FALSE);
/* set the current selection */ /* set the current selection */
gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0); gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0);
@ -481,7 +484,7 @@ curves_initialize (GDisplay *gdisp)
} }
void void
curves_free () curves_free (void)
{ {
if (curves_dialog) if (curves_dialog)
{ {
@ -506,7 +509,7 @@ curves_free ()
/*******************/ /*******************/
static CurvesDialog * static CurvesDialog *
curves_new_dialog () curves_dialog_new (void)
{ {
CurvesDialog *cd; CurvesDialog *cd;
GtkWidget *vbox; GtkWidget *vbox;
@ -528,19 +531,20 @@ curves_new_dialog ()
}; };
cd = g_new (CurvesDialog, 1); cd = g_new (CurvesDialog, 1);
cd->cursor_ind_height = cd->cursor_ind_width = -1; cd->cursor_ind_height = -1;
cd->preview = TRUE; cd->cursor_ind_width = -1;
cd->curve_type = SMOOTH; cd->preview = TRUE;
cd->pixmap = NULL; cd->curve_type = SMOOTH;
cd->channel = HISTOGRAM_VALUE; cd->pixmap = NULL;
cd->channel = HISTOGRAM_VALUE;
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
for (j = 0; j < 256; j++) for (j = 0; j < 256; j++)
cd->curve[i][j] = j; cd->curve[i][j] = j;
for(i = 0; i < (sizeof(cd->col_value)/sizeof(cd->col_value[0])); i++) for (i = 0; i < (sizeof (cd->col_value) / sizeof (cd->col_value[0])); i++)
cd->col_value[i] = 0; cd->col_value[i] = 0;
cd->lut = gimp_lut_new(); cd->lut = gimp_lut_new ();
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
channel_items [i].user_data = (gpointer) cd; channel_items [i].user_data = (gpointer) cd;
@ -562,15 +566,15 @@ curves_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox);
/* The option menu for selecting channels */ /* The option menu for selecting channels */
channel_hbox = gtk_hbox_new (FALSE, 2); channel_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Modify Curves for Channel: ")); label = gtk_label_new (_("Modify Curves for Channel:"));
gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0);
menu = build_menu (channel_items, NULL); menu = build_menu (channel_items, NULL);
@ -584,7 +588,8 @@ curves_new_dialog ()
/* The table for the yrange and the graph */ /* The table for the yrange and the graph */
table = gtk_table_new (2, 2, FALSE); table = gtk_table_new (2, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 2);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* The range drawing area */ /* The range drawing area */
@ -596,10 +601,12 @@ curves_new_dialog ()
cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT);
gtk_widget_set_events (cd->yrange, RANGE_MASK); gtk_widget_set_events (cd->yrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
(GtkSignalFunc) curves_yrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->yrange); gtk_container_add (GTK_CONTAINER (frame), cd->yrange);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
GTK_SIGNAL_FUNC (curves_yrange_events),
cd);
gtk_widget_show (cd->yrange); gtk_widget_show (cd->yrange);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -607,18 +614,20 @@ curves_new_dialog ()
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, 0, 0);
cd->graph = gtk_drawing_area_new (); cd->graph = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph), gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph),
GRAPH_WIDTH + RADIUS * 2, GRAPH_WIDTH + RADIUS * 2,
GRAPH_HEIGHT + RADIUS * 2); GRAPH_HEIGHT + RADIUS * 2);
gtk_widget_set_events (cd->graph, GRAPH_MASK); gtk_widget_set_events (cd->graph, GRAPH_MASK);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
(GtkSignalFunc) curves_graph_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->graph); gtk_container_add (GTK_CONTAINER (frame), cd->graph);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
GTK_SIGNAL_FUNC (curves_graph_events),
cd);
gtk_widget_show (cd->graph); gtk_widget_show (cd->graph);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -631,20 +640,22 @@ curves_new_dialog ()
cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT);
gtk_widget_set_events (cd->xrange, RANGE_MASK); gtk_widget_set_events (cd->xrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
(GtkSignalFunc) curves_xrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->xrange); gtk_container_add (GTK_CONTAINER (frame), cd->xrange);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
GTK_SIGNAL_FUNC (curves_xrange_events),
cd);
gtk_widget_show (cd->xrange); gtk_widget_show (cd->xrange);
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (table); gtk_widget_show (table);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The option menu for selecting the drawing method */ /* The option menu for selecting the drawing method */
label = gtk_label_new (_("Curve Type: ")); label = gtk_label_new (_("Curve Type:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
menu = build_menu (curve_type_items, NULL); menu = build_menu (curve_type_items, NULL);
@ -659,12 +670,12 @@ curves_new_dialog ()
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) curves_preview_update, GTK_SIGNAL_FUNC (curves_preview_update),
cd); cd);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
@ -674,32 +685,32 @@ curves_new_dialog ()
} }
static void static void
curve_print_loc(CurvesDialog *cd, curve_print_loc (CurvesDialog *cd,
gint xpos, gint xpos,
gint ypos) gint ypos)
{ {
char buf[32]; char buf[32];
gint width; gint width;
gint ascent; gint ascent;
gint descent; gint descent;
if(cd->cursor_ind_width < 0) if (cd->cursor_ind_width < 0)
{ {
/* Calc max extents */ /* Calc max extents */
gdk_string_extents(cd->graph->style->font, gdk_string_extents (cd->graph->style->font,
"x:888 y:888", "x:888 y:888",
NULL, NULL,
NULL, NULL,
&width, &width,
&ascent, &ascent,
&descent); &descent);
cd->cursor_ind_width = width; cd->cursor_ind_width = width;
cd->cursor_ind_height = ascent + descent; cd->cursor_ind_height = ascent + descent;
cd->cursor_ind_ascent = ascent; cd->cursor_ind_ascent = ascent;
} }
if(xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255) if (xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255)
{ {
g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos); g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos);
@ -730,53 +741,54 @@ curves_update (CurvesDialog *cd,
int update) int update)
{ {
GdkRectangle area; GdkRectangle area;
int i, j; gint i, j;
char buf[32]; gchar buf[32];
gint offset; gint offset;
if (update & XRANGE_TOP) if (update & XRANGE_TOP)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
for (i = 0; i < XRANGE_HEIGHT / 2; i++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH ; j++) for (j = 0; j < XRANGE_WIDTH ; j++)
{ {
buf[j*3+0] = cd->curve[cd->channel][j]; buf[j*3+0] = cd->curve[cd->channel][j];
buf[j*3+1] = cd->curve[cd->channel][j]; buf[j*3+1] = cd->curve[cd->channel][j];
buf[j*3+2] = cd->curve[cd->channel][j]; buf[j*3+2] = cd->curve[cd->channel][j];
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH); buf, 0, i, XRANGE_WIDTH);
} }
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
{
for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH; j++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
buf[j*3+0] = cd->curve[HISTOGRAM_RED][j]; for (j = 0; j < XRANGE_WIDTH; j++)
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j]; {
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j]; buf[j*3+0] = cd->curve[HISTOGRAM_RED][j];
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j];
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j];
}
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH);
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), break;
buf, 0, i, XRANGE_WIDTH);
} }
break;
}
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} /* end switch */ }
if (update & DRAW) if (update & DRAW)
{ {
@ -789,7 +801,7 @@ curves_update (CurvesDialog *cd,
} }
if (update & XRANGE_BOTTOM) if (update & XRANGE_BOTTOM)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
for (i = 0; i < XRANGE_WIDTH; i++) for (i = 0; i < XRANGE_WIDTH; i++)
{ {
@ -812,35 +824,36 @@ curves_update (CurvesDialog *cd,
} }
if (update & YRANGE) if (update & YRANGE)
{ {
unsigned char buf[YRANGE_WIDTH * 3]; guchar buf[YRANGE_WIDTH * 3];
unsigned char pix[3]; guchar pix[3];
for (i = 0; i < YRANGE_HEIGHT; i++) for (i = 0; i < YRANGE_HEIGHT; i++)
{ {
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
pix[0] = pix[1] = pix[2] = (255 - i); pix[0] = pix[1] = pix[2] = (255 - i);
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
pix[0] = pix[1] = pix[2] = 0; pix[0] = pix[1] = pix[2] = 0;
pix[cd->channel - 1] = (255 - i); pix[cd->channel - 1] = (255 - i);
break; break;
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} }
for (j = 0; j < YRANGE_WIDTH * 3; j++) for (j = 0; j < YRANGE_WIDTH * 3; j++)
buf[j] = pix[j%3]; buf[j] = pix[j%3];
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange), buf, 0, i, YRANGE_WIDTH);
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange),
buf, 0, i, YRANGE_WIDTH);
} }
if (update & DRAW) if (update & DRAW)
@ -852,7 +865,8 @@ curves_update (CurvesDialog *cd,
/* Clear the pixmap */ /* Clear the pixmap */
gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL], gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL],
TRUE, 0, 0, GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2); TRUE, 0, 0,
GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2);
/* Draw the grid lines */ /* Draw the grid lines */
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
@ -885,20 +899,20 @@ curves_update (CurvesDialog *cd,
} }
/* draw the colour line */ /* draw the colour line */
gdk_draw_line(cd->pixmap, cd->graph->style->black_gc, gdk_draw_line (cd->pixmap, cd->graph->style->black_gc,
cd->col_value[cd->channel]+RADIUS,RADIUS, cd->col_value[cd->channel]+RADIUS,RADIUS,
cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS); cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS);
/* and xpos indicator */ /* and xpos indicator */
g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]); g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]);
if((cd->col_value[cd->channel]+RADIUS) < 127) if ((cd->col_value[cd->channel]+RADIUS) < 127)
{ {
offset = RADIUS + 4; offset = RADIUS + 4;
} }
else else
{ {
offset = -gdk_string_width(cd->graph->style->font,buf) - 2; offset = - gdk_string_width (cd->graph->style->font,buf) - 2;
} }
gdk_draw_string (cd->pixmap, gdk_draw_string (cd->pixmap,
@ -916,10 +930,10 @@ curves_update (CurvesDialog *cd,
static void static void
curves_plot_curve (CurvesDialog *cd, curves_plot_curve (CurvesDialog *cd,
int p1, gint p1,
int p2, gint p2,
int p3, gint p3,
int p4) gint p4)
{ {
CRMatrix geometry; CRMatrix geometry;
CRMatrix tmp1, tmp2; CRMatrix tmp1, tmp2;
@ -1045,8 +1059,8 @@ curves_calculate_curve (CurvesDialog *cd)
} }
break; break;
} }
gimp_lut_setup(cd->lut, (GimpLutFunc) curves_lut_func, gimp_lut_setup (cd->lut, (GimpLutFunc) curves_lut_func,
(void *) cd, gimp_drawable_bytes(cd->drawable)); (void *) cd, gimp_drawable_bytes (cd->drawable));
} }
@ -1054,23 +1068,24 @@ static void
curves_preview (CurvesDialog *cd) curves_preview (CurvesDialog *cd)
{ {
if (!cd->image_map) if (!cd->image_map)
g_message ("curves_preview(): No image map"); {
g_message ("curves_preview(): No image map");
active_tool->preserve = TRUE; /* Going to dirty the display... */ return;
}
active_tool->preserve = TRUE;
image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2,
(void *) cd->lut); (void *) cd->lut);
active_tool->preserve = FALSE;
active_tool->preserve = FALSE; /* All done */
} }
static void static void
curves_value_callback (GtkWidget *w, curves_value_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_VALUE) if (cd->channel != HISTOGRAM_VALUE)
{ {
@ -1080,12 +1095,12 @@ curves_value_callback (GtkWidget *w,
} }
static void static void
curves_red_callback (GtkWidget *w, curves_red_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_RED) if (cd->channel != HISTOGRAM_RED)
{ {
@ -1095,12 +1110,12 @@ curves_red_callback (GtkWidget *w,
} }
static void static void
curves_green_callback (GtkWidget *w, curves_green_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_GREEN) if (cd->channel != HISTOGRAM_GREEN)
{ {
@ -1110,12 +1125,12 @@ curves_green_callback (GtkWidget *w,
} }
static void static void
curves_blue_callback (GtkWidget *w, curves_blue_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_BLUE) if (cd->channel != HISTOGRAM_BLUE)
{ {
@ -1125,12 +1140,12 @@ curves_blue_callback (GtkWidget *w,
} }
static void static void
curves_alpha_callback (GtkWidget *w, curves_alpha_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_ALPHA) if (cd->channel != HISTOGRAM_ALPHA)
{ {
@ -1140,14 +1155,14 @@ curves_alpha_callback (GtkWidget *w,
} }
static void static void
curves_smooth_callback (GtkWidget *w, curves_smooth_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
gint32 index; gint32 index;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != SMOOTH) if (cd->curve_type != SMOOTH)
{ {
@ -1170,12 +1185,12 @@ curves_smooth_callback (GtkWidget *w,
} }
static void static void
curves_free_callback (GtkWidget *w, curves_free_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != GFREE) if (cd->curve_type != GFREE)
{ {
@ -1190,12 +1205,12 @@ curves_free_callback (GtkWidget *w,
static void static void
curves_reset_callback (GtkWidget *widget, curves_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
/* Initialize the values */ /* Initialize the values */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -1214,17 +1229,18 @@ curves_reset_callback (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
} }
static void static void
curves_ok_callback (GtkWidget *widget, curves_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1248,11 +1264,12 @@ curves_ok_callback (GtkWidget *widget,
static void static void
curves_cancel_callback (GtkWidget *widget, curves_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1373,7 +1390,7 @@ curves_graph_events (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
gtk_grab_add(widget); gtk_grab_add (widget);
break; break;
@ -1384,7 +1401,7 @@ curves_graph_events (GtkWidget *widget,
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
gtk_grab_remove(widget); gtk_grab_remove (widget);
break; break;
@ -1527,7 +1544,7 @@ curves_CR_compose (CRMatrix a,
CRMatrix b, CRMatrix b,
CRMatrix ab) CRMatrix ab)
{ {
int i, j; gint i, j;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {

View File

@ -23,47 +23,53 @@
#include "lut_funcs.h" #include "lut_funcs.h"
#include "tools.h" #include "tools.h"
#define SMOOTH 0 #define SMOOTH 0
#define GFREE 1 #define GFREE 1
typedef struct _CurvesDialog CurvesDialog; typedef struct _CurvesDialog CurvesDialog;
struct _CurvesDialog struct _CurvesDialog
{ {
GtkWidget * shell; GtkWidget *shell;
GtkWidget * channel_menu;
GtkWidget * xrange;
GtkWidget * yrange;
GtkWidget * graph;
GdkPixmap * pixmap;
GimpDrawable * drawable;
ImageMap image_map;
int color;
int channel;
gint preview;
int grab_point; GtkWidget *channel_menu;
int last; GtkWidget *xrange;
int leftmost; GtkWidget *yrange;
int rightmost; GtkWidget *graph;
int curve_type; GdkPixmap *pixmap;
int points[5][17][2];
unsigned char curve[5][256]; GimpDrawable *drawable;
int col_value[5]; ImageMap image_map;
gint color;
gint channel;
gboolean preview;
gint grab_point;
gint last;
gint leftmost;
gint rightmost;
gint curve_type;
gint points[5][17][2];
guchar curve[5][256];
gint col_value[5];
int cursor_ind_height; gint cursor_ind_height;
int cursor_ind_width; gint cursor_ind_width;
int cursor_ind_ascent; gint cursor_ind_ascent;
GimpLut *lut; GimpLut *lut;
}; };
/* hue-saturation functions */ Tool * tools_new_curves (void);
Tool * tools_new_curves (void); void tools_free_curves (Tool *tool);
void tools_free_curves (Tool *);
void curves_initialize (GDisplay *); void curves_initialize (GDisplay *gdisp);
void curves_free (void); void curves_free (void);
float curves_lut_func (CurvesDialog *, int, int, float); float curves_lut_func (CurvesDialog *cd,
void curves_calculate_curve (CurvesDialog *); gint nchannels,
gint channel,
gfloat value);
void curves_calculate_curve (CurvesDialog *cd);
#endif /* __CURVES_H__ */ #endif /* __CURVES_H__ */

View File

@ -39,10 +39,11 @@ static void color_notebook_cancel_callback (GtkWidget *, gpointer);
static void color_notebook_update_callback (void *, int, int, int); static void color_notebook_update_callback (void *, int, int, int);
static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *, static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *,
guint); guint);
static void color_notebook_help_func (gpointer data); static void color_notebook_help_func (gchar *data);
/* information we keep on each registered colour selector */ /* information we keep on each registered colour selector */
typedef struct _ColorSelectorInfo { typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */ char *name; /* label used in notebook tab */
char *help_page; char *help_page;
GimpColorSelectorMethods m; GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next; struct _ColorSelectorInfo *next;
} ColorSelectorInfo; } ColorSelectorInfo;
typedef struct _ColorSelectorInstance { typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook; _ColorNotebook *color_notebook;
ColorSelectorInfo *info; ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */ GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell = cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection", gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp, color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
} }
static void static void
color_notebook_help_func (gpointer data) color_notebook_help_func (gchar *data)
{ {
ColorNotebookP cnp; ColorNotebookP cnp;
gchar *help_path; gchar *help_path;

View File

@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <string.h>
#include "gimpui.h" #include "gimpui.h"
#include "libgimp/gimpsizeentry.h" #include "libgimp/gimpsizeentry.h"
@ -324,50 +321,73 @@ gimp_option_menu_new (GtkSignalFunc menu_item_callback,
} }
GtkWidget * GtkWidget *
gimp_radio_group_new (GtkSignalFunc radio_button_callback, gimp_radio_group_new (gboolean in_frame,
gpointer initial, /* user_data */ gchar *frame_title,
/* specify radio buttons as va_list: /* specify radio buttons as va_list:
* gchar *label, * gchar *label,
* gpointer data, * GtkSignalFunc callback,
* gpointer user_data, * gpointer data,
* gpointer user_data,
* GtkWidget **widget_ptr,
* gboolean active,
*/ */
...) ...)
{ {
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *frame;
GtkWidget *button; GtkWidget *button;
GSList *group; GSList *group;
/* radio button variables */ /* radio button variables */
gchar *label; gchar *label;
gpointer data; GtkSignalFunc callback;
gpointer user_data; gpointer data;
gpointer user_data;
GtkWidget **widget_ptr;
gboolean active;
va_list args; va_list args;
vbox = gtk_vbox_new (FALSE, 1); vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
if (in_frame)
{
frame = gtk_frame_new (frame_title);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
}
group = NULL; group = NULL;
/* create the radio buttons */ /* create the radio buttons */
va_start (args, initial); va_start (args, frame_title);
label = va_arg (args, gchar*); label = va_arg (args, gchar*);
while (label) while (label)
{ {
data = va_arg (args, gpointer); callback = va_arg (args, GtkSignalFunc);
user_data = va_arg (args, gpointer); data = va_arg (args, gpointer);
user_data = va_arg (args, gpointer);
widget_ptr = va_arg (args, gpointer);
active = va_arg (args, gboolean);
button = gtk_radio_button_new_with_label (group, label); button = gtk_radio_button_new_with_label (group, label);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (button), "toggled", gtk_signal_connect (GTK_OBJECT (button), "toggled",
(GtkSignalFunc) radio_button_callback, GTK_SIGNAL_FUNC (callback),
data); data);
gtk_object_set_user_data (GTK_OBJECT (button), user_data);
if (user_data)
gtk_object_set_user_data (GTK_OBJECT (button), user_data);
if (widget_ptr)
*widget_ptr = button;
/* press the initially active radio button */ /* press the initially active radio button */
if (user_data == initial) if (active)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_widget_show (button); gtk_widget_show (button);
@ -376,6 +396,9 @@ gimp_radio_group_new (GtkSignalFunc radio_button_callback,
} }
va_end (args); va_end (args);
if (in_frame)
return frame;
return vbox; return vbox;
} }
@ -400,7 +423,7 @@ gimp_spin_button_new (GtkObject **adjustment, /* return value */
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton), gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
GTK_SHADOW_NONE); GTK_SHADOW_NONE);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
gtk_widget_set_usize (spinbutton, 75, 0); gtk_widget_set_usize (spinbutton, 75, -1);
return spinbutton; return spinbutton;
} }
@ -787,11 +810,12 @@ struct _MessageBox
static void gimp_message_box_close_callback (GtkWidget *, gpointer); static void gimp_message_box_close_callback (GtkWidget *, gpointer);
#define MESSAGE_STRING_BUFFER 80 /* some buffer size, not critical */ #define MESSAGE_BOX_MAXIMUM 7 /* the maximum number of concucrrent
#define MESSAGE_BOX_MAXIMUM 7 /* the maximum number of concucrrent dialog boxes */ * dialog boxes
*/
static int message_pool = MESSAGE_BOX_MAXIMUM; static gint message_pool = MESSAGE_BOX_MAXIMUM;
static gchar message_box_last[MESSAGE_STRING_BUFFER]; static gchar *message_box_last = NULL;
GtkWidget * GtkWidget *
gimp_message_box (gchar *message, gimp_message_box (gchar *message,
@ -803,13 +827,13 @@ gimp_message_box (gchar *message,
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *label; GtkWidget *label;
static int repeat_count; static gint repeat_count;
/* arguably, if message_pool <= 0 we could print to stdout */ /* arguably, if message_pool <= 0 we could print to stdout */
if (!message || message_pool <= 0) if (!message || message_pool <= 0)
return NULL; return NULL;
if (!strcmp (message_box_last, message)) if (message_box_last && !strcmp (message_box_last, message))
{ {
repeat_count++; repeat_count++;
if (repeat_count == 3) if (repeat_count == 3)
@ -820,8 +844,9 @@ gimp_message_box (gchar *message,
else else
{ {
repeat_count = 0; repeat_count = 0;
if (strlen (message) < MESSAGE_STRING_BUFFER) if (message_box_last)
strcpy (message_box_last, message); g_free (message_box_last);
message_box_last = g_strdup (message);
} }
if (message_pool == 1) if (message_pool == 1)

View File

@ -93,13 +93,16 @@ GtkWidget * gimp_option_menu_new (GtkSignalFunc menu_item_callback,
...); ...);
GtkWidget * gimp_radio_group_new (GtkSignalFunc radio_button_callback, GtkWidget * gimp_radio_group_new (gboolean in_frame,
gpointer initial, /* user_data */ gchar *frame_title,
/* specify radio buttons as va_list: /* specify radio buttons as va_list:
* gchar *label, * gchar *label,
* GtkSignalFunc callback,
* gpointer data, * gpointer data,
* gpointer user_data, * gpointer user_data,
* GtkWidget **widget_ptr,
* gboolean active,
*/ */
...); ...);

View File

@ -39,10 +39,11 @@ static void color_notebook_cancel_callback (GtkWidget *, gpointer);
static void color_notebook_update_callback (void *, int, int, int); static void color_notebook_update_callback (void *, int, int, int);
static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *, static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *,
guint); guint);
static void color_notebook_help_func (gpointer data); static void color_notebook_help_func (gchar *data);
/* information we keep on each registered colour selector */ /* information we keep on each registered colour selector */
typedef struct _ColorSelectorInfo { typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */ char *name; /* label used in notebook tab */
char *help_page; char *help_page;
GimpColorSelectorMethods m; GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next; struct _ColorSelectorInfo *next;
} ColorSelectorInfo; } ColorSelectorInfo;
typedef struct _ColorSelectorInstance { typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook; _ColorNotebook *color_notebook;
ColorSelectorInfo *info; ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */ GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell = cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection", gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp, color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
} }
static void static void
color_notebook_help_func (gpointer data) color_notebook_help_func (gchar *data)
{ {
ColorNotebookP cnp; ColorNotebookP cnp;
gchar *help_path; gchar *help_path;

View File

@ -99,21 +99,6 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 }, { { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
"file/dialogs/preferences/preferences.html", NULL }, "file/dialogs/preferences/preferences.html", NULL },
/* <Toolbox>/File/Help */
{ { N_("/File/Help/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
NULL, NULL },
{ { N_("/File/Help/Help..."), "F1", help_help_cmd_callback, 0 },
"file/dialogs/help.html", NULL },
{ { N_("/File/Help/Context Help..."), "<shift>F1", help_context_help_cmd_callback, 0 },
"file/dialogs/context_help.html", NULL },
{ { N_("/File/Help/Tip of the day..."), NULL, help_tips_cmd_callback, 0 },
"file/dialogs/tip_of_the_day.html", NULL },
{ { N_("/File/Help/About..."), NULL, help_about_cmd_callback, 0 },
"file/dialogs/about.html", NULL },
{ { N_("/File/Help/Dump Items (Debug)"), NULL, help_debug_cmd_callback, 0 },
NULL, NULL },
/* <Toolbox>/File/Dialogs */ /* <Toolbox>/File/Dialogs */
{ { N_("/File/---"), NULL, NULL, 0, "<Separator>" }, { { N_("/File/---"), NULL, NULL, 0, "<Separator>" },

View File

@ -17,7 +17,6 @@
*/ */
#include "config.h" #include "config.h"
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "buildmenu.h" #include "buildmenu.h"
#include "drawable.h" #include "drawable.h"
@ -25,9 +24,9 @@
#include "gimpui.h" #include "gimpui.h"
#include "histogram_tool.h" #include "histogram_tool.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
#define TEXT_WIDTH 45 #define TEXT_WIDTH 45
#define GRADIENT_HEIGHT 15 #define GRADIENT_HEIGHT 15
@ -35,23 +34,22 @@
/* the histogram structures */ /* the histogram structures */
typedef struct _HistogramTool HistogramTool; typedef struct _HistogramTool HistogramTool;
struct _HistogramTool struct _HistogramTool
{ {
gint x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the histogram tool options */ /* the histogram tool options */
static ToolOptions * histogram_tool_options = NULL; static ToolOptions * histogram_tool_options = NULL;
/* the histogram tool dialog */ /* the histogram tool dialog */
static HistogramToolDialog * histogram_tool_dialog = NULL; static HistogramToolDialog * histogram_tool_dialog = NULL;
/* histogram_tool action functions */ /* histogram_tool action functions */
static void histogram_tool_control (Tool *, ToolAction, gpointer); static void histogram_tool_control (Tool *, ToolAction, gpointer);
static HistogramToolDialog * histogram_tool_new_dialog (void); static HistogramToolDialog * histogram_tool_dialog_new (void);
static void histogram_tool_close_callback (GtkWidget *, gpointer); static void histogram_tool_close_callback (GtkWidget *, gpointer);
static void histogram_tool_value_callback (GtkWidget *, gpointer); static void histogram_tool_value_callback (GtkWidget *, gpointer);
@ -62,20 +60,19 @@ static void histogram_tool_gradient_draw (GtkWidget *, gint);
static void histogram_tool_dialog_update (HistogramToolDialog *, gint, gint); static void histogram_tool_dialog_update (HistogramToolDialog *, gint, gint);
/* histogram_tool machinery */ /* histogram_tool machinery */
void void
histogram_tool_histogram_range (HistogramWidget *widget, histogram_tool_histogram_range (HistogramWidget *widget,
gint start, gint start,
gint end, gint end,
void *user_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
gdouble pixels; gdouble pixels;
gdouble count; gdouble count;
htd = (HistogramToolDialog *) user_data; htd = (HistogramToolDialog *) data;
if (htd == NULL || htd->hist == NULL || if (htd == NULL || htd->hist == NULL ||
gimp_histogram_nchannels(htd->hist) <= 0) gimp_histogram_nchannels(htd->hist) <= 0)
@ -161,7 +158,7 @@ histogram_tool_control (Tool *tool,
} }
Tool * Tool *
tools_new_histogram_tool () tools_new_histogram_tool (void)
{ {
Tool * tool; Tool * tool;
HistogramTool * private; HistogramTool * private;
@ -213,7 +210,7 @@ histogram_tool_initialize (GDisplay *gdisp)
/* The histogram_tool dialog */ /* The histogram_tool dialog */
if (!histogram_tool_dialog) if (!histogram_tool_dialog)
histogram_tool_dialog = histogram_tool_new_dialog (); histogram_tool_dialog = histogram_tool_dialog_new ();
else if (!GTK_WIDGET_VISIBLE (histogram_tool_dialog->shell)) else if (!GTK_WIDGET_VISIBLE (histogram_tool_dialog->shell))
gtk_widget_show (histogram_tool_dialog->shell); gtk_widget_show (histogram_tool_dialog->shell);
@ -238,17 +235,17 @@ histogram_tool_initialize (GDisplay *gdisp)
histogram_widget_range (histogram_tool_dialog->histogram, 0, 255); histogram_widget_range (histogram_tool_dialog->histogram, 0, 255);
} }
/***************************/ /***************************/
/* Histogram Tool dialog */ /* Histogram Tool dialog */
/***************************/ /***************************/
static HistogramToolDialog * static HistogramToolDialog *
histogram_tool_new_dialog () histogram_tool_dialog_new (void)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
GtkWidget *main_vbox;
GtkWidget *hbox;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
@ -296,17 +293,19 @@ histogram_tool_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (htd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (htd->shell)->vbox), main_vbox);
/* The vbox for the menu and histogram */ hbox = gtk_hbox_new (TRUE, 0);
vbox2 = gtk_vbox_new (FALSE, 2); gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
/* The option menu for selecting channels */ /* The option menu for selecting channels */
htd->channel_menu = gtk_hbox_new (FALSE, 6); htd->channel_menu = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox2), htd->channel_menu, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), htd->channel_menu, FALSE, FALSE, 0);
label = gtk_label_new (_("Information on Channel:")); label = gtk_label_new (_("Information on Channel:"));
gtk_box_pack_start (GTK_BOX (htd->channel_menu), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (htd->channel_menu), label, FALSE, FALSE, 0);
@ -323,32 +322,33 @@ histogram_tool_new_dialog ()
/* The histogram tool histogram */ /* The histogram tool histogram */
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
htd->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT); htd->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(htd->histogram));
gtk_signal_connect (GTK_OBJECT (htd->histogram), "rangechanged", gtk_signal_connect (GTK_OBJECT (htd->histogram), "rangechanged",
(GtkSignalFunc) histogram_tool_histogram_range, GTK_SIGNAL_FUNC (histogram_tool_histogram_range),
(void*)htd); htd);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(htd->histogram)); gtk_widget_show (GTK_WIDGET (htd->histogram));
gtk_widget_show (GTK_WIDGET(htd->histogram));
gtk_widget_show (frame); gtk_widget_show (frame);
/* The gradient below the histogram */ /* The gradient below the histogram */
htd->gradient = gtk_preview_new (GTK_PREVIEW_COLOR); htd->gradient = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (htd->gradient), gtk_preview_size (GTK_PREVIEW (htd->gradient),
HISTOGRAM_WIDTH, GRADIENT_HEIGHT); HISTOGRAM_WIDTH, GRADIENT_HEIGHT);
gtk_box_pack_start (GTK_BOX (vbox2), htd->gradient, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), htd->gradient, FALSE, FALSE, 0);
gtk_widget_show (htd->gradient); gtk_widget_show (htd->gradient);
histogram_tool_gradient_draw (htd->gradient, HISTOGRAM_VALUE); histogram_tool_gradient_draw (htd->gradient, HISTOGRAM_VALUE);
gtk_widget_show (vbox2); gtk_widget_show (vbox);
gtk_widget_show (hbox);
/* The table containing histogram information */ /* The table containing histogram information */
table = gtk_table_new (4, 4, TRUE); table = gtk_table_new (4, 4, TRUE);
gtk_table_set_col_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 6);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
/* the labels for histogram information */ /* the labels for histogram information */
for (i = 0; i < 7; i++) for (i = 0; i < 7; i++)
@ -371,7 +371,8 @@ histogram_tool_new_dialog ()
} }
gtk_widget_show (table); gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (main_vbox);
gtk_widget_show (htd->shell); gtk_widget_show (htd->shell);
return htd; return htd;
@ -379,23 +380,26 @@ histogram_tool_new_dialog ()
static void static void
histogram_tool_close_callback (GtkWidget *widget, histogram_tool_close_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (GTK_WIDGET_VISIBLE (htd->shell)) if (GTK_WIDGET_VISIBLE (htd->shell))
gtk_widget_hide (htd->shell); gtk_widget_hide (htd->shell);
active_tool->gdisp_ptr = NULL;
active_tool->drawable = NULL;
} }
static void static void
histogram_tool_value_callback (GtkWidget *widget, histogram_tool_value_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_VALUE) if (htd->channel != HISTOGRAM_VALUE)
{ {
@ -407,11 +411,11 @@ histogram_tool_value_callback (GtkWidget *widget,
static void static void
histogram_tool_red_callback (GtkWidget *widget, histogram_tool_red_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_RED) if (htd->channel != HISTOGRAM_RED)
{ {
@ -423,11 +427,11 @@ histogram_tool_red_callback (GtkWidget *widget,
static void static void
histogram_tool_green_callback (GtkWidget *widget, histogram_tool_green_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_GREEN) if (htd->channel != HISTOGRAM_GREEN)
{ {
@ -439,11 +443,11 @@ histogram_tool_green_callback (GtkWidget *widget,
static void static void
histogram_tool_blue_callback (GtkWidget *widget, histogram_tool_blue_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_BLUE) if (htd->channel != HISTOGRAM_BLUE)
{ {

View File

@ -26,34 +26,39 @@
#define HISTOGRAM_HEIGHT 150 #define HISTOGRAM_HEIGHT 150
typedef struct _HistogramToolDialog HistogramToolDialog; typedef struct _HistogramToolDialog HistogramToolDialog;
struct _HistogramToolDialog struct _HistogramToolDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *info_labels[7]; GtkWidget *info_labels[7];
GtkWidget *channel_menu; GtkWidget *channel_menu;
HistogramWidget *histogram; HistogramWidget *histogram;
GimpHistogram *hist; GimpHistogram *hist;
GtkWidget *gradient; GtkWidget *gradient;
gdouble mean; gdouble mean;
gdouble std_dev; gdouble std_dev;
gdouble median; gdouble median;
gdouble pixels; gdouble pixels;
gdouble count; gdouble count;
gdouble percentile; gdouble percentile;
GimpDrawable *drawable; GimpDrawable *drawable;
ImageMap image_map; ImageMap image_map;
gint channel; gint channel;
gint color; gint color;
}; };
/* histogram_tool functions */ /* histogram_tool functions */
Tool * tools_new_histogram_tool (void); Tool * tools_new_histogram_tool (void);
void tools_free_histogram_tool (Tool *); void tools_free_histogram_tool (Tool *tool);
void histogram_tool_initialize (GDisplay *); void histogram_tool_initialize (GDisplay *gdisp);
void histogram_tool_free (void); void histogram_tool_free (void);
void histogram_tool_histogram_range (HistogramWidget *, gint, gint, void *); void histogram_tool_histogram_range (HistogramWidget *hw,
gint start,
gint end,
gpointer data);
#endif /* __HISTOGRAM_TOOL_H__ */ #endif /* __HISTOGRAM_TOOL_H__ */

View File

@ -33,29 +33,24 @@
#define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK #define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200 #define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define DA_WIDTH 40 #define DA_WIDTH 40
#define DA_HEIGHT 20 #define DA_HEIGHT 20
#define HUE_PARTITION 0x0 #define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1 #define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2 #define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4 #define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8 #define DRAW 0x40
#define LIGHTNESS_TEXT 0x10 #define ALL 0xFF
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */ /* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation; typedef struct _HueSaturation HueSaturation;
struct _HueSaturation struct _HueSaturation
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the hue-saturation tool options */ /* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL; static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */ /* Local variables */
static int hue_transfer[6][256]; static gint hue_transfer[6][256];
static int lightness_transfer[6][256]; static gint lightness_transfer[6][256];
static int saturation_transfer[6][256]; static gint saturation_transfer[6][256];
static int default_colors[6][3] = static gint default_colors[6][3] =
{ {
{ 255, 0, 0 }, { 255, 0, 0 },
{ 255, 255, 0 }, { 255, 255, 0 },
{ 0, 255, 0 }, { 0, 255, 0 },
{ 0, 255, 255 }, { 0, 255, 255 },
{ 0, 0, 255 }, { 0, 0, 255 },
{ 255, 0, 255 } { 255, 0, 255 }
}; };
/* hue saturation action functions */ /* hue saturation action functions */
static void hue_saturation_control (Tool *, ToolAction, gpointer); static void hue_saturation_control (Tool *, ToolAction, gpointer);
static HueSaturationDialog * hue_saturation_new_dialog (void); static HueSaturationDialog * hue_saturation_dialog_new (void);
static void hue_saturation_update (HueSaturationDialog *, static void hue_saturation_update (HueSaturationDialog *,
int); gint);
static void hue_saturation_preview (HueSaturationDialog *); static void hue_saturation_preview (HueSaturationDialog *);
static void hue_saturation_reset_callback (GtkWidget *, gpointer);
static void hue_saturation_ok_callback (GtkWidget *, gpointer); static void hue_saturation_ok_callback (GtkWidget *, gpointer);
static void hue_saturation_cancel_callback (GtkWidget *, gpointer); static void hue_saturation_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_callback (GtkWidget *, gpointer); static void hue_saturation_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_R_callback (GtkWidget *, gpointer);
static void hue_saturation_Y_callback (GtkWidget *, gpointer);
static void hue_saturation_G_callback (GtkWidget *, gpointer);
static void hue_saturation_C_callback (GtkWidget *, gpointer);
static void hue_saturation_B_callback (GtkWidget *, gpointer);
static void hue_saturation_M_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer); static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer); gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
static void hue_saturation_hue_text_update (GtkWidget *, gpointer); gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer); static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer); gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *, static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *); HueSaturationDialog *);
/* hue saturation machinery */ /* hue saturation machinery */
void void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd) hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{ {
int value; gint value;
int hue; gint hue;
int i; gint i;
/* Calculate transfers */ /* Calculate transfers */
for (hue = 0; hue < 6; hue++) for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
} }
} }
/* hue saturation action functions */ /* hue saturation action functions */
static void static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
} }
Tool * Tool *
tools_new_hue_saturation () tools_new_hue_saturation (void)
{ {
Tool * tool; Tool * tool;
HueSaturation * private; HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void void
hue_saturation_initialize (GDisplay *gdisp) hue_saturation_initialize (GDisplay *gdisp)
{ {
int i; gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage))) if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{ {
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */ /* The "hue-saturation" dialog */
if (!hue_saturation_dialog) if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog (); hue_saturation_dialog = hue_saturation_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell)) if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell))
gtk_widget_show (hue_saturation_dialog->shell); gtk_widget_show (hue_saturation_dialog->shell);
@ -313,12 +300,14 @@ hue_saturation_initialize (GDisplay *gdisp)
} }
hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage); hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage);
hue_saturation_dialog->image_map = image_map_create (gdisp, hue_saturation_dialog->drawable); hue_saturation_dialog->image_map =
image_map_create (gdisp, hue_saturation_dialog->drawable);
hue_saturation_update (hue_saturation_dialog, ALL); hue_saturation_update (hue_saturation_dialog, ALL);
} }
void void
hue_saturation_free () hue_saturation_free (void)
{ {
if (hue_saturation_dialog) if (hue_saturation_dialog)
{ {
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map); image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL; hue_saturation_dialog->image_map = NULL;
} }
gtk_widget_destroy (hue_saturation_dialog->shell); gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/ /***************************/
static HueSaturationDialog * static HueSaturationDialog *
hue_saturation_new_dialog () hue_saturation_dialog_new (void)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
GtkWidget *main_vbox; GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle; GtkWidget *toggle;
GtkWidget *radio_button; GtkWidget *radio_button;
GtkWidget *frame; GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
N_("M") N_("M")
}; };
GtkSignalFunc hue_partition_callbacks[] =
{
hue_saturation_master_callback,
hue_saturation_R_callback,
hue_saturation_Y_callback,
hue_saturation_G_callback,
hue_saturation_C_callback,
hue_saturation_B_callback,
hue_saturation_M_callback
};
hsd = g_new (HueSaturationDialog, 1); hsd = g_new (HueSaturationDialog, 1);
hsd->hue_partition = 0; hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE; hsd->preview = TRUE;
/* The shell and main vbox */ /* The shell and main vbox */
hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_satiration", hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_saturation",
tools_help_func, NULL, tools_help_func, NULL,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback, _("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE, hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback, _("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL); NULL);
main_vbox = gtk_vbox_new (FALSE, 2); main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* The main hbox containing hue partitions and sliders */ /* The main hbox containing hue partitions and sliders */
main_hbox = gtk_hbox_new (FALSE, 2); main_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0);
/* The table containing hue partitions */ /* The table containing hue partitions */
table = gtk_table_new (7, 2, FALSE); table = gtk_table_new (7, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0);
/* the radio buttons for hue partitions */ /* the radio buttons for hue partitions */
@ -411,26 +396,30 @@ hue_saturation_new_dialog ()
{ {
radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]); radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i) if (!i)
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
} }
else else
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR); hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT); gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK); DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1],
HUE_PARTITION_MASK);
gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event", gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event",
(GtkSignalFunc) hue_saturation_hue_partition_events, GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd); hsd);
gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]); gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]);
@ -439,14 +428,16 @@ hue_saturation_new_dialog ()
} }
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) hue_partition_callbacks[i], GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd); hsd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (table); gtk_widget_show (table);
/* The vbox for the table and preview toggle */ /* The vbox for the table and preview toggle */
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments")); label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the hue scale widget */ /* Create the hue scale widget */
label = gtk_label_new (_("Hue")); label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0);
hsd->hue_data = GTK_ADJUSTMENT (data); hsd->hue_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->hue_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
hsd->hue_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1, gtk_widget_set_usize (spinbutton, 74, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
(GtkSignalFunc) hue_saturation_hue_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_hue_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */ /* Create the lightness scale widget */
label = gtk_label_new (_("Lightness")); label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->lightness_data = GTK_ADJUSTMENT (data); hsd->lightness_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->lightness_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
hsd->lightness_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
(GtkSignalFunc) hue_saturation_lightness_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_lightness_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */ /* Create the saturation scale widget */
label = gtk_label_new (_("Saturation")); label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->saturation_data = GTK_ADJUSTMENT (data); hsd->saturation_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->saturation_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
hsd->saturation_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
(GtkSignalFunc) hue_saturation_saturation_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_saturation_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */ /* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) hue_saturation_preview_update, GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd); hsd);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (main_hbox); gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox); gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void static void
hue_saturation_update (HueSaturationDialog *hsd, hue_saturation_update (HueSaturationDialog *hsd,
int update) gint update)
{ {
int i, j, b; gint i, j, b;
int rgb[3]; gint rgb[3];
unsigned char buf[DA_WIDTH * 3]; guchar buf[DA_WIDTH * 3];
char text[12];
if (update & HUE_SLIDER) if (update & HUE_SLIDER)
{ {
hsd->hue_data->value = hsd->hue[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed"); hsd->hue[hsd->hue_partition]);
} }
if (update & LIGHTNESS_SLIDER) if (update & LIGHTNESS_SLIDER)
{ {
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed"); hsd->lightness[hsd->hue_partition]);
} }
if (update & SATURATION_SLIDER) if (update & SATURATION_SLIDER)
{ {
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed"); hsd->saturation[hsd->hue_partition]);
}
if (update & HUE_TEXT)
{
sprintf (text, "%0.0f", hsd->hue[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->hue_text), text);
}
if (update & LIGHTNESS_TEXT)
{
sprintf (text, "%0.0f", hsd->lightness[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->lightness_text), text);
}
if (update & SATURATION_TEXT)
{
sprintf (text, "%0.0f", hsd->saturation[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->saturation_text), text);
} }
hue_saturation_calculate_transfers (hsd); hue_saturation_calculate_transfers (hsd);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
rgb[RED_PIX] = default_colors[i][RED_PIX]; rgb[RED_PIX] = default_colors[i][RED_PIX];
rgb[GREEN_PIX] = default_colors[i][GREEN_PIX]; rgb[GREEN_PIX] = default_colors[i][GREEN_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX]; rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb_to_hls (rgb, rgb + 1, rgb + 2); rgb_to_hls (rgb, rgb + 1, rgb + 2);
rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]]; rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]];
rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]]; rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]];
rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]]; rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]];
hls_to_rgb (rgb, rgb + 1, rgb + 2); hls_to_rgb (rgb, rgb + 1, rgb + 2);
for (j = 0; j < DA_WIDTH; j++) for (j = 0; j < DA_WIDTH; j++)
for (b = 0; b < 3; b++) for (b = 0; b < 3; b++)
buf[j * 3 + b] = (unsigned char) rgb[b]; buf[j * 3 + b] = (guchar) rgb[b];
for (j = 0; j < DA_HEIGHT; j++) for (j = 0; j < DA_HEIGHT; j++)
gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]), buf, 0, j, DA_WIDTH); gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]),
buf, 0, j, DA_WIDTH);
if (update & DRAW) if (update & DRAW)
gtk_widget_draw (hsd->hue_partition_da[i], NULL); gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd) hue_saturation_preview (HueSaturationDialog *hsd)
{ {
if (!hsd->image_map) if (!hsd->image_map)
g_warning ("hue_saturation_preview(): No image map"); {
g_warning ("hue_saturation_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd); image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void static void
hue_saturation_ok_callback (GtkWidget *widget, hue_saturation_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
hsd->hue[hsd->hue_partition] = 0.0;
hsd->lightness[hsd->hue_partition] = 0.0;
hsd->saturation[hsd->hue_partition] = 0.0;
hue_saturation_update (hsd, ALL);
if (hsd->preview)
hue_saturation_preview (hsd);
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void static void
hue_saturation_cancel_callback (GtkWidget *widget, hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
} }
static void static void
hue_saturation_master_callback (GtkWidget *widget, hue_saturation_partition_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
HueRange partition;
hsd = (HueSaturationDialog *) data;
partition = (HueRange) gtk_object_get_data (GTK_OBJECT (widget),
"hue_partition");
hsd->hue_partition = partition;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 0;
hue_saturation_update (hsd, ALL); hue_saturation_update (hsd, ALL);
} }
static void static void
hue_saturation_R_callback (GtkWidget *widget, hue_saturation_preview_update (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 1;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_Y_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 2;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_G_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 3;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_C_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 4;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_B_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 5;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_M_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 6;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_preview_update (GtkWidget *w,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data; hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
hsd->preview = TRUE; hsd->preview = TRUE;
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
} }
static void static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment, hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (hsd->hue[hsd->hue_partition] != adjustment->value) if (hsd->hue[hsd->hue_partition] != adjustment->value)
{ {
hsd->hue[hsd->hue_partition] = adjustment->value; hsd->hue[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, HUE_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment, hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (hsd->lightness[hsd->hue_partition] != adjustment->value) if (hsd->lightness[hsd->hue_partition] != adjustment->value)
{ {
hsd->lightness[hsd->hue_partition] = adjustment->value; hsd->lightness[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, LIGHTNESS_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment, hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value) if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{ {
hsd->saturation[hsd->hue_partition] = adjustment->value; hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_hue_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -180, 180);
if ((int) hsd->hue[hsd->hue_partition] != value)
{
hsd->hue[hsd->hue_partition] = value;
hue_saturation_update (hsd, HUE_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_lightness_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->lightness[hsd->hue_partition] != value)
{
hsd->lightness[hsd->hue_partition] = value;
hue_saturation_update (hsd, LIGHTNESS_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_saturation_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->saturation[hsd->hue_partition] != value)
{
hsd->saturation[hsd->hue_partition] = value;
hue_saturation_update (hsd, SATURATION_SLIDER | DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange; } HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog; typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog struct _HueSaturationDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *gimage_name;
GtkWidget *hue_text;
GtkWidget *lightness_text;
GtkWidget *saturation_text;
GtkWidget *hue_partition_da[6];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
GimpDrawable *drawable; GtkWidget *hue_partition_da[6];
ImageMap image_map;
double hue[7]; GtkAdjustment *hue_data;
double lightness[7]; GtkAdjustment *lightness_data;
double saturation[7]; GtkAdjustment *saturation_data;
int hue_partition; GimpDrawable *drawable;
gint preview; ImageMap image_map;
gdouble hue[7];
gdouble lightness[7];
gdouble saturation[7];
HueRange hue_partition;
gboolean preview;
}; };
/* hue-saturation functions */ Tool * tools_new_hue_saturation (void);
Tool * tools_new_hue_saturation (void); void tools_free_hue_saturation (Tool *tool);
void tools_free_hue_saturation (Tool *);
void hue_saturation_initialize (GDisplay *); void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (void); void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *); void hue_saturation (PixelRegion *srcPR,
PixelRegion *destPR,
void *data);
void hue_saturation_calculate_transfers (HueSaturationDialog *hsd); void hue_saturation_calculate_transfers (HueSaturationDialog *hsd);
#endif /* __HUE_SATURATION_H__ */ #endif /* __HUE_SATURATION_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -20,11 +20,10 @@
#include "tools.h" #include "tools.h"
/* hue-saturation functions */ Tool * tools_new_levels (void);
Tool * tools_new_levels (void); void tools_free_levels (Tool *tool);
void tools_free_levels (Tool *);
void levels_initialize (GDisplay *); void levels_initialize (GDisplay *gdisp);
void levels_free (void); void levels_free (void);
#endif /* __LEVELS_H__ */ #endif /* __LEVELS_H__ */

View File

@ -99,21 +99,6 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 }, { { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
"file/dialogs/preferences/preferences.html", NULL }, "file/dialogs/preferences/preferences.html", NULL },
/* <Toolbox>/File/Help */
{ { N_("/File/Help/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
NULL, NULL },
{ { N_("/File/Help/Help..."), "F1", help_help_cmd_callback, 0 },
"file/dialogs/help.html", NULL },
{ { N_("/File/Help/Context Help..."), "<shift>F1", help_context_help_cmd_callback, 0 },
"file/dialogs/context_help.html", NULL },
{ { N_("/File/Help/Tip of the day..."), NULL, help_tips_cmd_callback, 0 },
"file/dialogs/tip_of_the_day.html", NULL },
{ { N_("/File/Help/About..."), NULL, help_about_cmd_callback, 0 },
"file/dialogs/about.html", NULL },
{ { N_("/File/Help/Dump Items (Debug)"), NULL, help_debug_cmd_callback, 0 },
NULL, NULL },
/* <Toolbox>/File/Dialogs */ /* <Toolbox>/File/Dialogs */
{ { N_("/File/---"), NULL, NULL, 0, "<Separator>" }, { { N_("/File/---"), NULL, NULL, 0, "<Separator>" },

View File

@ -99,21 +99,6 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 }, { { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
"file/dialogs/preferences/preferences.html", NULL }, "file/dialogs/preferences/preferences.html", NULL },
/* <Toolbox>/File/Help */
{ { N_("/File/Help/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
NULL, NULL },
{ { N_("/File/Help/Help..."), "F1", help_help_cmd_callback, 0 },
"file/dialogs/help.html", NULL },
{ { N_("/File/Help/Context Help..."), "<shift>F1", help_context_help_cmd_callback, 0 },
"file/dialogs/context_help.html", NULL },
{ { N_("/File/Help/Tip of the day..."), NULL, help_tips_cmd_callback, 0 },
"file/dialogs/tip_of_the_day.html", NULL },
{ { N_("/File/Help/About..."), NULL, help_about_cmd_callback, 0 },
"file/dialogs/about.html", NULL },
{ { N_("/File/Help/Dump Items (Debug)"), NULL, help_debug_cmd_callback, 0 },
NULL, NULL },
/* <Toolbox>/File/Dialogs */ /* <Toolbox>/File/Dialogs */
{ { N_("/File/---"), NULL, NULL, 0, "<Separator>" }, { { N_("/File/---"), NULL, NULL, 0, "<Separator>" },

View File

@ -15,12 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "drawable.h" #include "drawable.h"
#include "gdisplay.h" #include "gdisplay.h"
@ -33,32 +27,33 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 55
/* the posterize structures */ /* the posterize structures */
typedef struct _Posterize Posterize; typedef struct _Posterize Posterize;
struct _Posterize struct _Posterize
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef struct _PosterizeDialog PosterizeDialog; typedef struct _PosterizeDialog PosterizeDialog;
struct _PosterizeDialog struct _PosterizeDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *levels_text;
GimpDrawable *drawable; GtkAdjustment *levels_data;
ImageMap image_map;
int levels;
gint preview; GimpDrawable *drawable;
ImageMap image_map;
GimpLut *lut; gint levels;
gboolean preview;
GimpLut *lut;
}; };
/* the posterize tool options */ /* the posterize tool options */
static ToolOptions *posterize_options = NULL; static ToolOptions *posterize_options = NULL;
@ -69,14 +64,14 @@ static PosterizeDialog *posterize_dialog = NULL;
/* posterize action functions */ /* posterize action functions */
static void posterize_control (Tool *, ToolAction, gpointer); static void posterize_control (Tool *, ToolAction, gpointer);
static PosterizeDialog * posterize_new_dialog (void); static PosterizeDialog * posterize_dialog_new (void);
static void posterize_preview (PosterizeDialog *);
static void posterize_ok_callback (GtkWidget *, gpointer);
static void posterize_cancel_callback (GtkWidget *, gpointer);
static void posterize_preview_update (GtkWidget *, gpointer);
static void posterize_levels_text_update (GtkWidget *, gpointer);
static void posterize_preview (PosterizeDialog *);
static void posterize_reset_callback (GtkWidget *, gpointer);
static void posterize_ok_callback (GtkWidget *, gpointer);
static void posterize_cancel_callback (GtkWidget *, gpointer);
static void posterize_preview_update (GtkWidget *, gpointer);
static void posterize_levels_adjustment_update (GtkAdjustment *, gpointer);
/* posterize select action functions */ /* posterize select action functions */
@ -104,7 +99,7 @@ posterize_control (Tool *tool,
} }
Tool * Tool *
tools_new_posterize () tools_new_posterize (void)
{ {
Tool * tool; Tool * tool;
Posterize * private; Posterize * private;
@ -116,13 +111,6 @@ tools_new_posterize ()
tools_register (POSTERIZE, posterize_options); tools_register (POSTERIZE, posterize_options);
} }
/* The posterize dialog */
if (!posterize_dialog)
posterize_dialog = posterize_new_dialog ();
else
if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell))
gtk_widget_show (posterize_dialog->shell);
tool = tools_new_tool (POSTERIZE); tool = tools_new_tool (POSTERIZE);
private = g_new (Posterize, 1); private = g_new (Posterize, 1);
@ -161,32 +149,37 @@ posterize_initialize (GDisplay *gdisp)
/* The posterize dialog */ /* The posterize dialog */
if (!posterize_dialog) if (!posterize_dialog)
posterize_dialog = posterize_new_dialog (); posterize_dialog = posterize_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell)) if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell))
gtk_widget_show (posterize_dialog->shell); gtk_widget_show (posterize_dialog->shell);
posterize_dialog->levels = 3;
posterize_dialog->drawable = gimage_active_drawable (gdisp->gimage); posterize_dialog->drawable = gimage_active_drawable (gdisp->gimage);
posterize_dialog->image_map = posterize_dialog->image_map =
image_map_create (gdisp, posterize_dialog->drawable); image_map_create (gdisp, posterize_dialog->drawable);
gtk_adjustment_set_value (GTK_ADJUSTMENT (posterize_dialog->levels_data), 3);
if (posterize_dialog->preview) if (posterize_dialog->preview)
posterize_preview (posterize_dialog); posterize_preview (posterize_dialog);
} }
/**********************/ /**********************/
/* Posterize dialog */ /* Posterize dialog */
/**********************/ /**********************/
static PosterizeDialog * static PosterizeDialog *
posterize_new_dialog () posterize_dialog_new (void)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *label; GtkWidget *label;
GtkWidget *spinbutton;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data;
pd = g_new (PosterizeDialog, 1); pd = g_new (PosterizeDialog, 1);
pd->preview = TRUE; pd->preview = TRUE;
@ -200,6 +193,8 @@ posterize_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), posterize_reset_callback,
pd, NULL, TRUE, FALSE,
_("OK"), posterize_ok_callback, _("OK"), posterize_ok_callback,
pd, NULL, TRUE, FALSE, pd, NULL, TRUE, FALSE,
_("Cancel"), posterize_cancel_callback, _("Cancel"), posterize_cancel_callback,
@ -208,39 +203,43 @@ posterize_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pd->shell)->vbox), vbox);
/* Horizontal box for levels text widget */ /* Horizontal box for levels text widget */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Posterize Levels: ")); label = gtk_label_new (_("Posterize Levels:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
gtk_widget_show (label); gtk_widget_show (label);
/* levels text */ /* levels spinbutton */
pd->levels_text = gtk_entry_new (); data = gtk_adjustment_new (3, 2, 256, 1.0, 10.0, 0.0);
gtk_entry_set_text (GTK_ENTRY (pd->levels_text), "3"); pd->levels_data = GTK_ADJUSTMENT (data);
gtk_widget_set_usize (pd->levels_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), pd->levels_text, TRUE, FALSE, 0); spinbutton = gtk_spin_button_new (pd->levels_data, 1.0, 0);
gtk_signal_connect (GTK_OBJECT (pd->levels_text), "changed", gtk_widget_set_usize (spinbutton, 75, -1);
(GtkSignalFunc) posterize_levels_text_update, gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (pd->levels_data), "value_changed",
GTK_SIGNAL_FUNC (posterize_levels_adjustment_update),
pd); pd);
gtk_widget_show (pd->levels_text);
gtk_widget_show (spinbutton);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), pd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), pd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) posterize_preview_update, GTK_SIGNAL_FUNC (posterize_preview_update),
pd); pd);
gtk_widget_show (label); gtk_widget_show (label);
@ -257,21 +256,36 @@ static void
posterize_preview (PosterizeDialog *pd) posterize_preview (PosterizeDialog *pd)
{ {
if (!pd->image_map) if (!pd->image_map)
g_warning ("posterize_preview(): No image map"); {
g_warning ("posterize_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
posterize_lut_setup(pd->lut, pd->levels, gimp_drawable_bytes(pd->drawable)); posterize_lut_setup (pd->lut, pd->levels, gimp_drawable_bytes(pd->drawable));
image_map_apply (pd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (pd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
(void *) pd->lut); (void *) pd->lut);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void static void
posterize_ok_callback (GtkWidget *widget, posterize_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) client_data; pd = (PosterizeDialog *) data;
gtk_adjustment_set_value (GTK_ADJUSTMENT (pd->levels_data), 3);
}
static void
posterize_ok_callback (GtkWidget *widget,
gpointer data)
{
PosterizeDialog *pd;
pd = (PosterizeDialog *) data;
if (GTK_WIDGET_VISIBLE (pd->shell)) if (GTK_WIDGET_VISIBLE (pd->shell))
gtk_widget_hide (pd->shell); gtk_widget_hide (pd->shell);
@ -279,12 +293,13 @@ posterize_ok_callback (GtkWidget *widget,
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
if (!pd->preview) if (!pd->preview)
{ {
posterize_lut_setup(pd->lut, pd->levels, posterize_lut_setup( pd->lut, pd->levels,
gimp_drawable_bytes(pd->drawable)); gimp_drawable_bytes (pd->drawable));
image_map_apply (pd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (pd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
(void *) pd->lut); (void *) pd->lut);
} }
if (pd->image_map) if (pd->image_map)
image_map_commit (pd->image_map); image_map_commit (pd->image_map);
@ -298,11 +313,12 @@ posterize_ok_callback (GtkWidget *widget,
static void static void
posterize_cancel_callback (GtkWidget *widget, posterize_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) client_data; pd = (PosterizeDialog *) data;
if (GTK_WIDGET_VISIBLE (pd->shell)) if (GTK_WIDGET_VISIBLE (pd->shell))
gtk_widget_hide (pd->shell); gtk_widget_hide (pd->shell);
@ -321,14 +337,14 @@ posterize_cancel_callback (GtkWidget *widget,
} }
static void static void
posterize_preview_update (GtkWidget *w, posterize_preview_update (GtkWidget *widget,
gpointer data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) data; pd = (PosterizeDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
pd->preview = TRUE; pd->preview = TRUE;
posterize_preview (pd); posterize_preview (pd);
@ -338,20 +354,17 @@ posterize_preview_update (GtkWidget *w,
} }
static void static void
posterize_levels_text_update (GtkWidget *w, posterize_levels_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
char *str;
int value;
pd = (PosterizeDialog *) data; pd = (PosterizeDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), 2, 256);
if (value != pd->levels) if (pd->levels != adjustment->value)
{ {
pd->levels = value; pd->levels = adjustment->value;
if (pd->preview) if (pd->preview)
posterize_preview (pd); posterize_preview (pd);
} }

View File

@ -20,10 +20,9 @@
#include "tools.h" #include "tools.h"
/* by_color select functions */ Tool * tools_new_posterize (void);
Tool * tools_new_posterize (void); void tools_free_posterize (Tool *tool);
void tools_free_posterize (Tool *);
void posterize_initialize (GDisplay *); void posterize_initialize (GDisplay *gdisp);
#endif /* __POSTERIZE_H__ */ #endif /* __POSTERIZE_H__ */

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "drawable.h" #include "drawable.h"
#include "general.h" #include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256 #define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150 #define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */ /* the threshold structures */
typedef struct _Threshold Threshold; typedef struct _Threshold Threshold;
struct _Threshold struct _Threshold
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the threshold tool options */ /* the threshold tool options */
static ToolOptions *threshold_options = NULL; static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */ /* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL; static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */ /* threshold action functions */
static void threshold_control (Tool *, ToolAction, gpointer); static void threshold_control (Tool *, ToolAction, gpointer);
static ThresholdDialog * threshold_new_dialog (void); static ThresholdDialog * threshold_dialog_new (void);
static void threshold_update (ThresholdDialog *,
gint);
static void threshold_preview (ThresholdDialog *); static void threshold_preview (ThresholdDialog *);
static void threshold_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer); static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer); static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer); static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer); static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
static void threshold_high_threshold_text_update (GtkWidget *, gpointer); gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold (PixelRegion *, PixelRegion *, void *); static void threshold (PixelRegion *, PixelRegion *, void *);
static void threshold_histogram_range (HistogramWidget *, int, int, void *); static void threshold_histogram_range (HistogramWidget *, gint, gint,
gpointer);
/* threshold machinery */ /* threshold machinery */
void void
threshold_2 (void *user_data, threshold_2 (void *data,
PixelRegion *srcPR, PixelRegion *srcPR,
PixelRegion *destPR) PixelRegion *destPR)
{ {
/* this function just re-orders the arguments so we can use /* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */ * pixel_regions_process_paralell
threshold(srcPR, destPR, user_data); */
threshold (srcPR, destPR, data);
} }
static void static void
threshold (PixelRegion *srcPR, threshold (PixelRegion *srcPR,
PixelRegion *destPR, PixelRegion *destPR,
void *user_data) void *data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
unsigned char *src, *s; unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b; int w, h, b;
int value; int value;
td = (ThresholdDialog *) user_data; td = (ThresholdDialog *) data;
h = srcPR->h; h = srcPR->h;
src = srcPR->data; src = srcPR->data;
@ -128,28 +133,6 @@ threshold (PixelRegion *srcPR,
} }
} }
static void
threshold_histogram_range (HistogramWidget *w,
int start,
int end,
void *user_data)
{
ThresholdDialog *td;
char text[12];
td = (ThresholdDialog *) user_data;
td->low_threshold = start;
td->high_threshold = end;
sprintf (text, "%d", start);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), text);
sprintf (text, "%d", end);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), text);
if (td->preview)
threshold_preview (td);
}
/* threshold action functions */ /* threshold action functions */
static void static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
} }
Tool * Tool *
tools_new_threshold () tools_new_threshold (void)
{ {
Tool * tool; Tool * tool;
Threshold * private; Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
tools_register (THRESHOLD, threshold_options); tools_register (THRESHOLD, threshold_options);
} }
/* The threshold dialog */
if (! threshold_dialog)
threshold_dialog = threshold_new_dialog ();
else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell);
tool = tools_new_tool (THRESHOLD); tool = tools_new_tool (THRESHOLD);
private = g_new (Threshold, 1); private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private; thresh = (Threshold *) tool->private;
/* Close the color select dialog */ /* Close the threshold dialog */
if (threshold_dialog) if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog); threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */ /* The threshold dialog */
if (!threshold_dialog) if (!threshold_dialog)
threshold_dialog = threshold_new_dialog (); threshold_dialog = threshold_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell)) if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell); gtk_widget_show (threshold_dialog->shell);
threshold_dialog->low_threshold = 127;
threshold_dialog->high_threshold = 255;
threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage); threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage);
threshold_dialog->color = drawable_color (threshold_dialog->drawable); threshold_dialog->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map = threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist, gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable); threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram, histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist); threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram, gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog->low_threshold, threshold_dialog);
threshold_dialog->high_threshold);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview) if (threshold_dialog->preview)
threshold_preview (threshold_dialog); threshold_preview (threshold_dialog);
} }
/**********************/ /**********************/
/* Threshold dialog */ /* Threshold dialog */
/**********************/ /**********************/
static ThresholdDialog * static ThresholdDialog *
threshold_new_dialog () threshold_dialog_new (void)
{ {
ThresholdDialog *td; ThresholdDialog *td;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label; GtkWidget *label;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1); td = g_new (ThresholdDialog, 1);
td->preview = TRUE; td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback, _("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE, td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback, _("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* Horizontal box for threshold text widget */ /* Horizontal box for threshold text widget */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Threshold Range: ")); label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label); gtk_widget_show (label);
/* low threshold text */ /* low threshold spinbutton */
td->low_threshold_text = gtk_entry_new (); data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127"); td->low_threshold_data = GTK_ADJUSTMENT (data);
gtk_widget_set_usize (td->low_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->low_threshold_text, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->low_threshold_text), "changed",
(GtkSignalFunc) threshold_low_threshold_text_update,
td);
gtk_widget_show (td->low_threshold_text);
/* high threshold text */ spinbutton = gtk_spin_button_new (td->low_threshold_data, 1.0, 0);
td->high_threshold_text = gtk_entry_new (); gtk_widget_set_usize (spinbutton, 75, -1);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255"); gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_set_usize (td->high_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->high_threshold_text, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (td->low_threshold_data), "value_changed",
gtk_signal_connect (GTK_OBJECT (td->high_threshold_text), "changed", GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
(GtkSignalFunc) threshold_high_threshold_text_update,
td); td);
gtk_widget_show (td->high_threshold_text);
gtk_widget_show (spinbutton);
/* high threshold spinbutton */
data = gtk_adjustment_new (td->high_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->high_threshold_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (td->high_threshold_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->high_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_high_threshold_adjustment_update),
td);
gtk_widget_show (spinbutton);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* The threshold histogram */ /* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
@ -334,55 +328,97 @@ threshold_new_dialog ()
td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT); td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged", gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range, GTK_SIGNAL_FUNC (threshold_histogram_range),
(void*)td); td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
gtk_widget_show (GTK_WIDGET(td->histogram)); gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) threshold_preview_update, GTK_SIGNAL_FUNC (threshold_preview_update),
td); td);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (td->shell); gtk_widget_show (td->shell);
/* This code is so far removed from the histogram creation because the
function histogram_range requires a non-NULL drawable, and that
doesn't happen until after the top-level dialog is shown. */
histogram_widget_range (td->histogram, td->low_threshold, td->high_threshold);
return td; return td;
} }
static void
threshold_update (ThresholdDialog *td,
gint update)
{
if (update & LOW)
{
gtk_adjustment_set_value (td->low_threshold_data, td->low_threshold);
}
if (update & HIGH)
{
gtk_adjustment_set_value (td->high_threshold_data, td->high_threshold);
}
if (update & HISTOGRAM)
{
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
}
}
static void static void
threshold_preview (ThresholdDialog *td) threshold_preview (ThresholdDialog *td)
{ {
if (!td->image_map) if (!td->image_map)
g_warning ("threshold_preview(): No image map"); {
image_map_apply (td->image_map, threshold, (void *) td); g_warning ("threshold_preview(): No image map");
return;
}
active_tool->preserve = TRUE;
image_map_apply (td->image_map, threshold, td);
active_tool->preserve = FALSE;
}
static void
threshold_reset_callback (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = 127.0;
td->high_threshold = 255.0;
threshold_update (td, ALL);
if (td->preview)
threshold_preview (td);
} }
static void static void
threshold_ok_callback (GtkWidget *widget, threshold_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview) if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td); image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map) if (td->image_map)
image_map_commit (td->image_map); image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void static void
threshold_cancel_callback (GtkWidget *widget, threshold_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
} }
static void static void
threshold_preview_update (GtkWidget *w, threshold_preview_update (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
td->preview = TRUE; td->preview = TRUE;
threshold_preview (td); threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
} }
static void static void
threshold_low_threshold_text_update (GtkWidget *w, threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), 0, td->high_threshold);
if (value != td->low_threshold) if (td->low_threshold != adjustment->value)
{ {
td->low_threshold = value; td->low_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void static void
threshold_high_threshold_text_update (GtkWidget *w, threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), td->low_threshold, 255);
if (value != td->high_threshold) if (td->high_threshold != adjustment->value)
{ {
td->high_threshold = value; td->high_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void
threshold_histogram_range (HistogramWidget *widget,
gint start,
gint end,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = start;
td->high_threshold = end;
threshold_update (td, LOW | HIGH);
if (td->preview)
threshold_preview (td);
}

View File

@ -25,28 +25,33 @@
#include "tools.h" #include "tools.h"
typedef struct _ThresholdDialog ThresholdDialog; typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog struct _ThresholdDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text; GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram; HistogramWidget *histogram;
GimpHistogram *hist; GimpHistogram *hist;
GimpDrawable *drawable; GimpDrawable *drawable;
ImageMap image_map; ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
gint preview; gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
}; };
/* by_color select functions */ Tool * tools_new_threshold (void);
Tool * tools_new_threshold (void); void tools_free_threshold (Tool *tool);
void tools_free_threshold (Tool *);
void threshold_initialize (GDisplay *); void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *, PixelRegion *, PixelRegion *); void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */ #endif /* __THRESHOLD_H__ */

View File

@ -802,7 +802,17 @@ tools_initialize (ToolType tool_type,
if (tool_info[(gint) tool_type].init_func && !gdisp) if (tool_info[(gint) tool_type].init_func && !gdisp)
tool_type = RECT_SELECT; tool_type = RECT_SELECT;
gimp_context_set_tool (gimp_context_get_user (), tool_type); /* Force the emission of the "tool_changed" signal
*/
if (active_tool->type == tool_type)
{
gtk_signal_emit_by_name (GTK_OBJECT (gimp_context_get_user ()),
"tool_changed", tool_type);
}
else
{
gimp_context_set_tool (gimp_context_get_user (), tool_type);
}
if (tool_info[(gint) tool_type].init_func) if (tool_info[(gint) tool_type].init_func)
{ {

View File

@ -15,60 +15,51 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "brightness_contrast.h" #include "brightness_contrast.h"
#include "drawable.h" #include "drawable.h"
#include "gimage_mask.h" #include "gimplut.h"
#include "gimpui.h" #include "gimpui.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "gimplut.h"
#include "lut_funcs.h" #include "lut_funcs.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200 #define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define BRIGHTNESS_SLIDER 0x1 #define BRIGHTNESS 0x1
#define CONTRAST_SLIDER 0x2 #define CONTRAST 0x2
#define BRIGHTNESS_TEXT 0x4 #define ALL (BRIGHTNESS | CONTRAST)
#define CONTRAST_TEXT 0x8
#define ALL 0xF
/* the brightness-contrast structures */ /* the brightness-contrast structures */
typedef struct _BrightnessContrast BrightnessContrast; typedef struct _BrightnessContrast BrightnessContrast;
struct _BrightnessContrast struct _BrightnessContrast
{ {
gint x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef struct _BrightnessContrastDialog BrightnessContrastDialog; typedef struct _BrightnessContrastDialog BrightnessContrastDialog;
struct _BrightnessContrastDialog struct _BrightnessContrastDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *gimage_name; GtkWidget *gimage_name;
GtkWidget *brightness_text;
GtkWidget *contrast_text;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
GimpDrawable *drawable; GtkAdjustment *brightness_data;
ImageMap image_map; GtkAdjustment *contrast_data;
double brightness; GimpDrawable *drawable;
double contrast; ImageMap image_map;
gint preview; gdouble brightness;
gdouble contrast;
GimpLut *lut; gboolean preview;
GimpLut *lut;
}; };
@ -83,18 +74,19 @@ static BrightnessContrastDialog *brightness_contrast_dialog = NULL;
static void brightness_contrast_control (Tool *, ToolAction, gpointer); static void brightness_contrast_control (Tool *, ToolAction, gpointer);
static BrightnessContrastDialog * brightness_contrast_new_dialog (void); static BrightnessContrastDialog * brightness_contrast_dialog_new (void);
static void brightness_contrast_update (BrightnessContrastDialog *, int);
static void brightness_contrast_preview (BrightnessContrastDialog *);
static void brightness_contrast_ok_callback (GtkWidget *, gpointer);
static void brightness_contrast_cancel_callback (GtkWidget *, gpointer);
static void brightness_contrast_preview_update (GtkWidget *, gpointer);
static void brightness_contrast_brightness_scale_update (GtkAdjustment *, gpointer);
static void brightness_contrast_contrast_scale_update (GtkAdjustment *, gpointer);
static void brightness_contrast_brightness_text_update (GtkWidget *, gpointer);
static void brightness_contrast_contrast_text_update (GtkWidget *, gpointer);
static void brightness_contrast_update (BrightnessContrastDialog *,
gint);
static void brightness_contrast_preview (BrightnessContrastDialog *);
static void brightness_contrast_reset_callback (GtkWidget *, gpointer);
static void brightness_contrast_ok_callback (GtkWidget *, gpointer);
static void brightness_contrast_cancel_callback (GtkWidget *, gpointer);
static void brightness_contrast_preview_update (GtkWidget *, gpointer);
static void brightness_contrast_brightness_adjustment_update (GtkAdjustment *,
gpointer);
static void brightness_contrast_contrast_adjustment_update (GtkAdjustment *,
gpointer);
/* brightness-contrast select action functions */ /* brightness-contrast select action functions */
@ -122,7 +114,7 @@ brightness_contrast_control (Tool *tool,
} }
Tool * Tool *
tools_new_brightness_contrast () tools_new_brightness_contrast (void)
{ {
Tool * tool; Tool * tool;
BrightnessContrast * private; BrightnessContrast * private;
@ -155,7 +147,7 @@ tools_free_brightness_contrast (Tool *tool)
bc = (BrightnessContrast *) tool->private; bc = (BrightnessContrast *) tool->private;
/* Close the color select dialog */ /* Close the brightness-contrast dialog */
if (brightness_contrast_dialog) if (brightness_contrast_dialog)
brightness_contrast_cancel_callback (NULL, (gpointer) brightness_contrast_dialog); brightness_contrast_cancel_callback (NULL, (gpointer) brightness_contrast_dialog);
@ -173,15 +165,13 @@ brightness_contrast_initialize (GDisplay *gdisp)
/* The brightness-contrast dialog */ /* The brightness-contrast dialog */
if (!brightness_contrast_dialog) if (!brightness_contrast_dialog)
brightness_contrast_dialog = brightness_contrast_new_dialog (); brightness_contrast_dialog = brightness_contrast_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (brightness_contrast_dialog->shell)) if (!GTK_WIDGET_VISIBLE (brightness_contrast_dialog->shell))
gtk_widget_show (brightness_contrast_dialog->shell); gtk_widget_show (brightness_contrast_dialog->shell);
/* Initialize dialog fields */
brightness_contrast_dialog->image_map = NULL;
brightness_contrast_dialog->brightness = 0.0; brightness_contrast_dialog->brightness = 0.0;
brightness_contrast_dialog->contrast = 0.0; brightness_contrast_dialog->contrast = 0.0;
brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage); brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->image_map = brightness_contrast_dialog->image_map =
@ -190,19 +180,20 @@ brightness_contrast_initialize (GDisplay *gdisp)
brightness_contrast_update (brightness_contrast_dialog, ALL); brightness_contrast_update (brightness_contrast_dialog, ALL);
} }
/********************************/ /********************************/
/* Brightness Contrast dialog */ /* Brightness Contrast dialog */
/********************************/ /********************************/
static BrightnessContrastDialog * static BrightnessContrastDialog *
brightness_contrast_new_dialog () brightness_contrast_dialog_new (void)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data; GtkObject *data;
@ -219,6 +210,8 @@ brightness_contrast_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), brightness_contrast_reset_callback,
bcd, NULL, TRUE, FALSE,
_("OK"), brightness_contrast_ok_callback, _("OK"), brightness_contrast_ok_callback,
bcd, NULL, TRUE, FALSE, bcd, NULL, TRUE, FALSE,
_("Cancel"), brightness_contrast_cancel_callback, _("Cancel"), brightness_contrast_cancel_callback,
@ -226,94 +219,90 @@ brightness_contrast_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (2, 3, FALSE); table = gtk_table_new (2, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the brightness scale widget */ /* Create the brightness scale widget */
label = gtk_label_new (_("Brightness")); label = gtk_label_new (_("Brightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -127, 127.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -127, 127.0, 1.0, 10.0, 0.0);
bcd->brightness_data = GTK_ADJUSTMENT (data); bcd->brightness_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1, gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_brightness_scale_update,
bcd);
bcd->brightness_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (bcd->brightness_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (bcd->brightness_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), bcd->brightness_text, 2, 3, 0, 1, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (bcd->brightness_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
(GtkSignalFunc) brightness_contrast_brightness_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
GTK_SIGNAL_FUNC (brightness_contrast_brightness_adjustment_update),
bcd); bcd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (bcd->brightness_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the contrast scale widget */ /* Create the contrast scale widget */
label = gtk_label_new (_("Contrast")); label = gtk_label_new (_("Contrast"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -127.0, 127.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -127.0, 127.0, 1.0, 10.0, 0.0);
bcd->contrast_data = GTK_ADJUSTMENT (data); bcd->contrast_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2, gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_contrast_scale_update,
bcd);
bcd->contrast_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (bcd->contrast_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (bcd->contrast_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), bcd->contrast_text, 2, 3, 1, 2, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (bcd->contrast_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
(GtkSignalFunc) brightness_contrast_contrast_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
GTK_SIGNAL_FUNC (brightness_contrast_contrast_adjustment_update),
bcd); bcd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (bcd->contrast_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Horizontal box for preview toggle button */
/* Horizontal box for preview and preserve luminosity toggle buttons */ hbox = gtk_hbox_new (FALSE, 4);
hbox = gtk_hbox_new (TRUE, 2); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), bcd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), bcd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) brightness_contrast_preview_update, GTK_SIGNAL_FUNC (brightness_contrast_preview_update),
bcd); bcd);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
@ -328,27 +317,13 @@ static void
brightness_contrast_update (BrightnessContrastDialog *bcd, brightness_contrast_update (BrightnessContrastDialog *bcd,
gint update) gint update)
{ {
char text[12]; if (update & BRIGHTNESS)
if (update & BRIGHTNESS_SLIDER)
{ {
bcd->brightness_data->value = bcd->brightness; gtk_adjustment_set_value (bcd->brightness_data, bcd->brightness);
gtk_signal_emit_by_name (GTK_OBJECT (bcd->brightness_data), "value_changed");
} }
if (update & CONTRAST_SLIDER) if (update & CONTRAST)
{ {
bcd->contrast_data->value = bcd->contrast; gtk_adjustment_set_value (bcd->contrast_data, bcd->contrast);
gtk_signal_emit_by_name (GTK_OBJECT (bcd->contrast_data), "value_changed");
}
if (update & BRIGHTNESS_TEXT)
{
g_snprintf (text, sizeof (text), "%0.0f", bcd->brightness);
gtk_entry_set_text (GTK_ENTRY (bcd->brightness_text), text);
}
if (update & CONTRAST_TEXT)
{
g_snprintf (text, sizeof (text), "%0.0f", bcd->contrast);
gtk_entry_set_text (GTK_ENTRY (bcd->contrast_text), text);
} }
} }
@ -371,12 +346,29 @@ brightness_contrast_preview (BrightnessContrastDialog *bcd)
} }
static void static void
brightness_contrast_ok_callback (GtkWidget *widget, brightness_contrast_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
bcd = (BrightnessContrastDialog *) client_data; bcd = (BrightnessContrastDialog *) data;
bcd->brightness = 0.0;
bcd->contrast = 0.0;
brightness_contrast_update (bcd, ALL);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
static void
brightness_contrast_ok_callback (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
bcd = (BrightnessContrastDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell)) if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell); gtk_widget_hide (bcd->shell);
@ -446,8 +438,8 @@ brightness_contrast_preview_update (GtkWidget *widget,
} }
static void static void
brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment, brightness_contrast_brightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
@ -456,7 +448,6 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
if (bcd->brightness != adjustment->value) if (bcd->brightness != adjustment->value)
{ {
bcd->brightness = adjustment->value; bcd->brightness = adjustment->value;
brightness_contrast_update (bcd, BRIGHTNESS_TEXT);
if (bcd->preview) if (bcd->preview)
brightness_contrast_preview (bcd); brightness_contrast_preview (bcd);
@ -464,8 +455,8 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
} }
static void static void
brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment, brightness_contrast_contrast_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
@ -474,51 +465,6 @@ brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
if (bcd->contrast != adjustment->value) if (bcd->contrast != adjustment->value)
{ {
bcd->contrast = adjustment->value; bcd->contrast = adjustment->value;
brightness_contrast_update (bcd, CONTRAST_TEXT);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
}
static void
brightness_contrast_brightness_text_update (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
gchar *str;
gint value;
str = gtk_entry_get_text (GTK_ENTRY (widget));
bcd = (BrightnessContrastDialog *) data;
value = BOUNDS (((int) atof (str)), -127, 127);
if ((int) bcd->brightness != value)
{
bcd->brightness = value;
brightness_contrast_update (bcd, BRIGHTNESS_SLIDER);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
}
static void
brightness_contrast_contrast_text_update (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
gchar *str;
gint value;
str = gtk_entry_get_text (GTK_ENTRY (widget));
bcd = (BrightnessContrastDialog *) data;
value = BOUNDS (((int) atof (str)), -127, 127);
if ((int) bcd->contrast != value)
{
bcd->contrast = value;
brightness_contrast_update (bcd, CONTRAST_SLIDER);
if (bcd->preview) if (bcd->preview)
brightness_contrast_preview (bcd); brightness_contrast_preview (bcd);

View File

@ -20,10 +20,9 @@
#include "tools.h" #include "tools.h"
/* by_color select functions */ Tool * tools_new_brightness_contrast (void);
Tool * tools_new_brightness_contrast (void); void tools_free_brightness_contrast (Tool *tool);
void tools_free_brightness_contrast (Tool *);
void brightness_contrast_initialize (GDisplay *); void brightness_contrast_initialize (GDisplay *gdisp);
#endif /* __BRIGHTNESS_CONTRAST_H__ */ #endif /* __BRIGHTNESS_CONTRAST_H__ */

View File

@ -15,32 +15,27 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "boundary.h" #include "boundary.h"
#include "by_color_select.h" #include "by_color_select.h"
#include "colormaps.h" #include "colormaps.h"
#include "drawable.h" #include "drawable.h"
#include "draw_core.h" #include "draw_core.h"
#include "general.h"
#include "gimage_mask.h" #include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimprc.h" #include "gimprc.h"
#include "gimpset.h" #include "gimpset.h"
#include "gimpui.h" #include "gimpui.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "selection_options.h" #include "selection_options.h"
#include "gimpdnd.h" #include "tile.h" /* ick. */
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "tile.h" /* ick. */ #define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define DEFAULT_FUZZINESS 15 #define PREVIEW_HEIGHT 256
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \ #define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \ GDK_BUTTON_PRESS_MASK | \
GDK_ENTER_NOTIFY_MASK GDK_ENTER_NOTIFY_MASK
@ -48,40 +43,43 @@
/* the by color selection structures */ /* the by color selection structures */
typedef struct _ByColorSelect ByColorSelect; typedef struct _ByColorSelect ByColorSelect;
struct _ByColorSelect struct _ByColorSelect
{ {
int x, y; /* Point from which to execute seed fill */ gint x, y; /* Point from which to execute seed fill */
int operation; /* add, subtract, normal color selection */ gint operation; /* add, subtract, normal color selection */
}; };
typedef struct _ByColorDialog ByColorDialog; typedef struct _ByColorDialog ByColorDialog;
struct _ByColorDialog struct _ByColorDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *preview;
GtkWidget *gimage_name;
int threshold; /* threshold value for color select */ GtkWidget *preview;
int operation; /* Add, Subtract, Replace */ GtkWidget *gimage_name;
GImage *gimage; /* gimage which is currently under examination */
gint threshold; /* threshold value for color select */
gint operation; /* Add, Subtract, Replace */
GImage *gimage; /* gimage which is currently under examination */
}; };
/* the by color selection tool options */ /* the by color selection tool options */
static SelectionOptions *by_color_options = NULL; static SelectionOptions * by_color_options = NULL;
/* the by color selection dialog */ /* the by color selection dialog */
static ByColorDialog * by_color_dialog = NULL; static ByColorDialog * by_color_dialog = NULL;
/* dnd stuff */ /* dnd stuff */
static GtkTargetEntry by_color_select_image_target_table[] = static GtkTargetEntry by_color_select_targets[] =
{ {
GIMP_TARGET_COLOR GIMP_TARGET_COLOR
}; };
static guint n_by_color_select_image_targets = static guint n_by_color_select_targets = (sizeof (by_color_select_targets) /
(sizeof (by_color_select_image_target_table) / sizeof (by_color_select_targets[0]));
sizeof (by_color_select_image_target_table[0]));
static void by_color_select_color_drop (GtkWidget*, guchar, guchar, guchar, gpointer); static void by_color_select_color_drop (GtkWidget *, guchar, guchar, guchar,
gpointer);
/* by_color select action functions */ /* by_color select action functions */
@ -90,32 +88,35 @@ static void by_color_select_button_release (Tool *, GdkEventButton *, gpointer);
static void by_color_select_cursor_update (Tool *, GdkEventMotion *, gpointer); static void by_color_select_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void by_color_select_control (Tool *, ToolAction, gpointer); static void by_color_select_control (Tool *, ToolAction, gpointer);
static ByColorDialog * by_color_select_new_dialog (void); static ByColorDialog * by_color_select_dialog_new (void);
static void by_color_select_render (ByColorDialog *, GImage *); static void by_color_select_render (ByColorDialog *, GImage *);
static void by_color_select_draw (ByColorDialog *, GImage *); static void by_color_select_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *, GdkEventButton *, static gint by_color_select_preview_events (GtkWidget *,
ByColorDialog *); GdkEventButton *,
static void by_color_select_type_callback (GtkWidget *, gpointer); ByColorDialog *);
static void by_color_select_reset_callback (GtkWidget *, gpointer); static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_close_callback (GtkWidget *, gpointer); static void by_color_select_reset_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer); static void by_color_select_close_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer);
static void by_color_select_preview_button_press (ByColorDialog *, static void by_color_select_preview_button_press (ByColorDialog *,
GdkEventButton *); GdkEventButton *);
static int is_pixel_sufficiently_different (unsigned char *, unsigned char *, int, int, int, int); static gint is_pixel_sufficiently_different (guchar *, guchar *,
static Channel * by_color_select_color (GImage *, GimpDrawable *, unsigned char *, int, int, int); gint, gint, gint, gint);
static Channel * by_color_select_color (GImage *, GimpDrawable *,
guchar *, gint, gint, gint);
/* by_color selection machinery */ /* by_color selection machinery */
static int static int
is_pixel_sufficiently_different (unsigned char *col1, is_pixel_sufficiently_different (guchar *col1,
unsigned char *col2, guchar *col2,
int antialias, gint antialias,
int threshold, gint threshold,
int bytes, gint bytes,
int has_alpha) gint has_alpha)
{ {
int diff; int diff;
int max; int max;
@ -145,7 +146,7 @@ is_pixel_sufficiently_different (unsigned char *col1,
if (aa <= 0) if (aa <= 0)
return 0; return 0;
else if (aa < 0.5) else if (aa < 0.5)
return (unsigned char) (aa * 512); return (guchar) (aa * 512);
else else
return 255; return 255;
} }
@ -159,12 +160,12 @@ is_pixel_sufficiently_different (unsigned char *col1,
} }
static Channel * static Channel *
by_color_select_color (GImage *gimage, by_color_select_color (GImage *gimage,
GimpDrawable *drawable, GimpDrawable *drawable,
unsigned char *color, guchar *color,
int antialias, gint antialias,
int threshold, gint threshold,
int sample_merged) gint sample_merged)
{ {
/* Scan over the gimage's active layer, finding pixels within the specified /* Scan over the gimage's active layer, finding pixels within the specified
* threshold from the given R, G, & B values. If antialiasing is on, * threshold from the given R, G, & B values. If antialiasing is on,
@ -173,10 +174,10 @@ by_color_select_color (GImage *gimage,
*/ */
Channel *mask; Channel *mask;
PixelRegion imagePR, maskPR; PixelRegion imagePR, maskPR;
unsigned char *image_data; guchar *image_data;
unsigned char *mask_data; guchar *mask_data;
unsigned char *idata, *mdata; guchar *idata, *mdata;
unsigned char rgb[MAX_CHANNELS]; guchar rgb[MAX_CHANNELS];
int has_alpha, indexed; int has_alpha, indexed;
int width, height; int width, height;
int bytes, color_bytes, alpha; int bytes, color_bytes, alpha;
@ -195,7 +196,8 @@ by_color_select_color (GImage *gimage,
indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE; indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE;
width = gimage->width; width = gimage->width;
height = gimage->height; height = gimage->height;
pixel_region_init (&imagePR, gimage_composite (gimage), 0, 0, width, height, FALSE); pixel_region_init (&imagePR, gimage_composite (gimage),
0, 0, width, height, FALSE);
} }
else else
{ {
@ -206,16 +208,20 @@ by_color_select_color (GImage *gimage,
width = drawable_width (drawable); width = drawable_width (drawable);
height = drawable_height (drawable); height = drawable_height (drawable);
pixel_region_init (&imagePR, drawable_data (drawable), 0, 0, width, height, FALSE); pixel_region_init (&imagePR, drawable_data (drawable),
0, 0, width, height, FALSE);
} }
if (indexed) { if (indexed)
/* indexed colors are always RGB or RGBA */ {
color_bytes = has_alpha ? 4 : 3; /* indexed colors are always RGB or RGBA */
} else { color_bytes = has_alpha ? 4 : 3;
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */ }
color_bytes = bytes; else
} {
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
alpha = bytes - 1; alpha = bytes - 1;
mask = channel_new_mask (gimage, width, height); mask = channel_new_mask (gimage, width, height);
@ -223,7 +229,9 @@ by_color_select_color (GImage *gimage,
0, 0, width, height, TRUE); 0, 0, width, height, TRUE);
/* iterate over the entire image */ /* iterate over the entire image */
for (pr = pixel_regions_register (2, &imagePR, &maskPR); pr != NULL; pr = pixel_regions_process (pr)) for (pr = pixel_regions_register (2, &imagePR, &maskPR);
pr != NULL;
pr = pixel_regions_process (pr))
{ {
image_data = imagePR.data; image_data = imagePR.data;
mask_data = maskPR.data; mask_data = maskPR.data;
@ -242,8 +250,12 @@ by_color_select_color (GImage *gimage,
rgb[color_bytes - 1] = idata[alpha]; rgb[color_bytes - 1] = idata[alpha];
/* Find how closely the colors match */ /* Find how closely the colors match */
*mdata++ = is_pixel_sufficiently_different (color, rgb, antialias, *mdata++ = is_pixel_sufficiently_different (color,
threshold, color_bytes, has_alpha); rgb,
antialias,
threshold,
color_bytes,
has_alpha);
idata += bytes; idata += bytes;
} }
@ -257,15 +269,15 @@ by_color_select_color (GImage *gimage,
} }
void void
by_color_select (GImage *gimage, by_color_select (GImage *gimage,
GimpDrawable *drawable, GimpDrawable *drawable,
unsigned char *color, guchar *color,
int threshold, gint threshold,
int op, gint op,
int antialias, gint antialias,
int feather, gint feather,
double feather_radius, gdouble feather_radius,
int sample_merged) gint sample_merged)
{ {
Channel * new_mask; Channel * new_mask;
int off_x, off_y; int off_x, off_y;
@ -273,7 +285,8 @@ by_color_select (GImage *gimage,
if (!drawable) if (!drawable)
return; return;
new_mask = by_color_select_color (gimage, drawable, color, antialias, threshold, sample_merged); new_mask = by_color_select_color (gimage, drawable, color,
antialias, threshold, sample_merged);
/* if applicable, replace the current selection */ /* if applicable, replace the current selection */
if (op == REPLACE) if (op == REPLACE)
@ -300,7 +313,6 @@ by_color_select (GImage *gimage,
channel_delete (new_mask); channel_delete (new_mask);
} }
/* by_color select action functions */ /* by_color select action functions */
static void static void
@ -345,8 +357,25 @@ by_color_select_button_press (Tool *tool,
/* Update the by_color_dialog's active gdisp pointer */ /* Update the by_color_dialog's active gdisp pointer */
if (by_color_dialog->gimage) if (by_color_dialog->gimage)
by_color_dialog->gimage->by_color_select = FALSE; by_color_dialog->gimage->by_color_select = FALSE;
if (by_color_dialog->gimage != gdisp->gimage)
{
gdk_draw_rectangle
(by_color_dialog->preview->window,
by_color_dialog->preview->style->bg_gc[GTK_STATE_NORMAL],
TRUE,
0, 0,
by_color_dialog->preview->allocation.width,
by_color_dialog->preview->allocation.width);
}
by_color_dialog->gimage = gdisp->gimage; by_color_dialog->gimage = gdisp->gimage;
gdisp->gimage->by_color_select = TRUE; gdisp->gimage->by_color_select = TRUE;
gdk_pointer_grab (gdisp->canvas->window, FALSE,
GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, bevent->time);
} }
static void static void
@ -356,32 +385,35 @@ by_color_select_button_release (Tool *tool,
{ {
ByColorSelect * by_color_sel; ByColorSelect * by_color_sel;
GDisplay * gdisp; GDisplay * gdisp;
int x, y; gint x, y;
GimpDrawable *drawable; GimpDrawable *drawable;
unsigned char *color; guchar *color;
int use_offsets; gint use_offsets;
gdisp = (GDisplay *) gdisp_ptr; gdisp = (GDisplay *) gdisp_ptr;
by_color_sel = (ByColorSelect *) tool->private; by_color_sel = (ByColorSelect *) tool->private;
drawable = gimage_active_drawable (gdisp->gimage); drawable = gimage_active_drawable (gdisp->gimage);
gdk_pointer_ungrab (bevent->time);
tool->state = INACTIVE; tool->state = INACTIVE;
/* First take care of the case where the user "cancels" the action */ /* First take care of the case where the user "cancels" the action */
if (! (bevent->state & GDK_BUTTON3_MASK)) if (! (bevent->state & GDK_BUTTON3_MASK))
{ {
use_offsets = (by_color_options->sample_merged) ? FALSE : TRUE; use_offsets = (by_color_options->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, by_color_sel->x, by_color_sel->y, &x, &y, FALSE, use_offsets); gdisplay_untransform_coords (gdisp, by_color_sel->x, by_color_sel->y,
&x, &y, FALSE, use_offsets);
/* Get the start color */ /* Get the start color */
if (by_color_options->sample_merged) if (by_color_options->sample_merged)
{ {
if (!(color = gimp_image_get_color_at(gdisp->gimage, x, y))) if (!(color = gimp_image_get_color_at (gdisp->gimage, x, y)))
return; return;
} }
else else
{ {
if (!(color = gimp_drawable_get_color_at(drawable, x, y))) if (!(color = gimp_drawable_get_color_at (drawable, x, y)))
return; return;
} }
@ -394,7 +426,7 @@ by_color_select_button_release (Tool *tool,
by_color_options->feather_radius, by_color_options->feather_radius,
by_color_options->sample_merged); by_color_options->sample_merged);
g_free(color); g_free (color);
/* show selection on all views */ /* show selection on all views */
gdisplays_flush (); gdisplays_flush ();
@ -412,17 +444,20 @@ by_color_select_cursor_update (Tool *tool,
{ {
GDisplay *gdisp; GDisplay *gdisp;
Layer *layer; Layer *layer;
int x, y; gint x, y;
gdisp = (GDisplay *) gdisp_ptr; gdisp = (GDisplay *) gdisp_ptr;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&x, &y, FALSE, FALSE);
if ((layer = gimage_pick_correlate_layer (gdisp->gimage, x, y))) if ((layer = gimage_pick_correlate_layer (gdisp->gimage, x, y)))
if (layer == gdisp->gimage->active_layer) if (layer == gdisp->gimage->active_layer)
{ {
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS); gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
return; return;
} }
gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW); gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW);
} }
@ -450,13 +485,13 @@ by_color_select_control (Tool *tool,
} }
static void static void
by_color_select_options_reset () by_color_select_options_reset (void)
{ {
selection_options_reset (by_color_options); selection_options_reset (by_color_options);
} }
Tool * Tool *
tools_new_by_color_select () tools_new_by_color_select (void)
{ {
Tool * tool; Tool * tool;
ByColorSelect * private; ByColorSelect * private;
@ -471,7 +506,7 @@ tools_new_by_color_select ()
/* The "by color" dialog */ /* The "by color" dialog */
if (!by_color_dialog) if (!by_color_dialog)
by_color_dialog = by_color_select_new_dialog (); by_color_dialog = by_color_select_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell)) if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell))
gtk_widget_show (by_color_dialog->shell); gtk_widget_show (by_color_dialog->shell);
@ -521,7 +556,6 @@ by_color_select_initialize_by_image (GImage *gimage)
void void
by_color_select_initialize (GDisplay *gdisp) by_color_select_initialize (GDisplay *gdisp)
{ {
/* wrap this call so the tool_info->init_func works */
by_color_select_initialize_by_image (gdisp->gimage); by_color_select_initialize_by_image (gdisp->gimage);
} }
@ -530,37 +564,16 @@ by_color_select_initialize (GDisplay *gdisp)
/****************************/ /****************************/
static ByColorDialog * static ByColorDialog *
by_color_select_new_dialog () by_color_select_dialog_new (void)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *options_box; GtkWidget *options_box;
GtkWidget *label; GtkWidget *label;
GtkWidget *util_box; GtkWidget *util_box;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *radio_box;
GtkWidget *radio_button;
GtkObject *data; GtkObject *data;
GSList *group = NULL;
gint i;
gchar *button_names[] =
{
N_("Replace"),
N_("Add"),
N_("Subtract"),
N_("Intersect")
};
gint button_values[] =
{
REPLACE,
ADD,
SUB,
INTERSECT
};
bcd = g_new (ByColorDialog, 1); bcd = g_new (ByColorDialog, 1);
bcd->gimage = NULL; bcd->gimage = NULL;
@ -580,101 +593,98 @@ by_color_select_new_dialog ()
NULL); NULL);
/* The vbox */ /* The main hbox */
vbox = gtk_vbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), hbox);
/* The horizontal box containing preview & options box */
hbox = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview */ /* The preview */
util_box = gtk_vbox_new (FALSE, 2); util_box = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), util_box, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0);
bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE); bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT); gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT);
gtk_widget_set_events (bcd->preview, PREVIEW_EVENT_MASK); gtk_widget_set_events (bcd->preview, PREVIEW_EVENT_MASK);
gtk_signal_connect (GTK_OBJECT (bcd->preview), "button_press_event",
(GtkSignalFunc) by_color_select_preview_events,
bcd);
gtk_container_add (GTK_CONTAINER (frame), bcd->preview); gtk_container_add (GTK_CONTAINER (frame), bcd->preview);
/* dnd colors to the image window */ gtk_signal_connect (GTK_OBJECT (bcd->preview), "button_press_event",
GTK_SIGNAL_FUNC (by_color_select_preview_events),
bcd);
/* dnd colors to the image window */
gtk_drag_dest_set (bcd->preview, gtk_drag_dest_set (bcd->preview,
GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP, GTK_DEST_DEFAULT_DROP,
by_color_select_image_target_table, by_color_select_targets,
n_by_color_select_image_targets, n_by_color_select_targets,
GDK_ACTION_COPY); GDK_ACTION_COPY);
gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd); gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd);
gtk_widget_show (bcd->preview); gtk_widget_show (bcd->preview);
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (util_box); gtk_widget_show (util_box);
/* options box */ /* options box */
options_box = gtk_vbox_new (FALSE, 2); options_box = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (options_box), 5); gtk_box_pack_start (GTK_BOX (hbox), options_box, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), options_box, TRUE, TRUE, 0);
/* Create the active image label */ /* Create the active image label */
util_box = gtk_hbox_new (FALSE, 2); util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
bcd->gimage_name = gtk_label_new (_("Inactive")); bcd->gimage_name = gtk_label_new (_("Inactive"));
gtk_box_pack_start (GTK_BOX (util_box), bcd->gimage_name, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), bcd->gimage_name, FALSE, FALSE, 0);
gtk_widget_show (bcd->gimage_name); gtk_widget_show (bcd->gimage_name);
gtk_widget_show (util_box); gtk_widget_show (util_box);
/* Create the selection mode radio box */ /* Create the selection mode radio box */
frame = gtk_frame_new (_("Selection Mode")); frame =
gimp_radio_group_new (TRUE, _("Selection Mode"),
_("Replace"), by_color_select_type_callback,
(gpointer) REPLACE, NULL, NULL, TRUE,
_("Add"), by_color_select_type_callback,
(gpointer) ADD, NULL, NULL, FALSE,
_("Subtract"), by_color_select_type_callback,
(gpointer) SUB, NULL, NULL, FALSE,
_("Intersect"), by_color_select_type_callback,
(gpointer) INTERSECT, NULL, NULL, FALSE,
NULL);
gtk_box_pack_start (GTK_BOX (options_box), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), frame, FALSE, FALSE, 0);
radio_box = gtk_vbox_new (FALSE, 2);
gtk_container_add (GTK_CONTAINER (frame), radio_box);
/* the radio buttons */
for (i = 0; i < (sizeof(button_names) / sizeof(button_names[0])); i++)
{
radio_button = gtk_radio_button_new_with_label (group,
gettext(button_names[i]));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_box_pack_start (GTK_BOX (radio_box), radio_button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) by_color_select_type_callback,
(gpointer) ((long) button_values[i]));
gtk_widget_show (radio_button);
}
gtk_widget_show (radio_box);
gtk_widget_show (frame); gtk_widget_show (frame);
/* Create the opacity scale widget */ /* Create the opacity scale widget */
util_box = gtk_vbox_new (FALSE, 2); util_box = gtk_vbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
label = gtk_label_new (_("Fuzziness Threshold")); label = gtk_label_new (_("Fuzziness Threshold"));
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
gtk_widget_show (label);
gtk_widget_show (util_box);
data = gtk_adjustment_new (bcd->threshold, 0.0, 255.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (bcd->threshold, 0.0, 255.0, 1.0, 1.0, 0.0);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (data), "value_changed", gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) by_color_select_fuzzy_update, GTK_SIGNAL_FUNC (by_color_select_fuzzy_update),
bcd); bcd);
gtk_widget_show (label);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (util_box);
gtk_widget_show (options_box); gtk_widget_show (options_box);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (vbox);
gtk_widget_show (bcd->shell); gtk_widget_show (bcd->shell);
return bcd; return bcd;
@ -686,14 +696,14 @@ by_color_select_render (ByColorDialog *bcd,
{ {
Channel * mask; Channel * mask;
MaskBuf * scaled_buf = NULL; MaskBuf * scaled_buf = NULL;
unsigned char *buf; guchar *buf;
PixelRegion srcPR, destPR; PixelRegion srcPR, destPR;
unsigned char * src; guchar * src;
int subsample; gint subsample;
int width, height; gint width, height;
int srcwidth; gint srcwidth;
int i; gint i;
int scale; gint scale;
mask = gimage_get_mask (gimage); mask = gimage_get_mask (gimage);
if ((drawable_width (GIMP_DRAWABLE(mask)) > PREVIEW_WIDTH) || if ((drawable_width (GIMP_DRAWABLE(mask)) > PREVIEW_WIDTH) ||
@ -703,11 +713,13 @@ by_color_select_render (ByColorDialog *bcd,
((float) drawable_height (GIMP_DRAWABLE (mask)) / (float) PREVIEW_HEIGHT)) ((float) drawable_height (GIMP_DRAWABLE (mask)) / (float) PREVIEW_HEIGHT))
{ {
width = PREVIEW_WIDTH; width = PREVIEW_WIDTH;
height = (drawable_height (GIMP_DRAWABLE (mask)) * PREVIEW_WIDTH) / drawable_width (GIMP_DRAWABLE (mask)); height = ((drawable_height (GIMP_DRAWABLE (mask)) * PREVIEW_WIDTH) /
drawable_width (GIMP_DRAWABLE (mask)));
} }
else else
{ {
width = (drawable_width (GIMP_DRAWABLE (mask)) * PREVIEW_HEIGHT) / drawable_height (GIMP_DRAWABLE (mask)); width = ((drawable_width (GIMP_DRAWABLE (mask)) * PREVIEW_HEIGHT) /
drawable_height (GIMP_DRAWABLE (mask)));
height = PREVIEW_HEIGHT; height = PREVIEW_HEIGHT;
} }
@ -726,10 +738,10 @@ by_color_select_render (ByColorDialog *bcd,
gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height); gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height);
/* clear the image buf */ /* clear the image buf */
buf = (unsigned char *) g_malloc (bcd->preview->requisition.width); buf = g_new0 (guchar, bcd->preview->requisition.width);
memset (buf, 0, bcd->preview->requisition.width);
for (i = 0; i < bcd->preview->requisition.height; i++) for (i = 0; i < bcd->preview->requisition.height; i++)
gtk_preview_draw_row (GTK_PREVIEW (bcd->preview), buf, 0, i, bcd->preview->requisition.width); gtk_preview_draw_row (GTK_PREVIEW (bcd->preview), buf,
0, i, bcd->preview->requisition.width);
g_free (buf); g_free (buf);
/* if the mask is empty, no need to scale and update again */ /* if the mask is empty, no need to scale and update again */
@ -800,7 +812,8 @@ by_color_select_draw (ByColorDialog *bcd,
gtk_widget_draw (bcd->preview, NULL); gtk_widget_draw (bcd->preview, NULL);
/* Update the gimage label to reflect the displayed gimage name */ /* Update the gimage label to reflect the displayed gimage name */
gtk_label_set_text (GTK_LABEL (bcd->gimage_name), g_basename (gimage_filename (gimage))); gtk_label_set_text (GTK_LABEL (bcd->gimage_name),
g_basename (gimage_filename (gimage)));
} }
static gint static gint
@ -823,25 +836,25 @@ by_color_select_preview_events (GtkWidget *widget,
static void static void
by_color_select_type_callback (GtkWidget *widget, by_color_select_type_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
if (by_color_dialog) if (by_color_dialog)
by_color_dialog->operation = (long) client_data; by_color_dialog->operation = (long) data;
} }
static void static void
by_color_select_reset_callback (GtkWidget *widget, by_color_select_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data; bcd = (ByColorDialog *) data;
if (!bcd->gimage) if (!bcd->gimage)
return; return;
/* check if the image associated to the mask still exists */ /* check if the image associated to the mask still exists */
if (!drawable_gimage (GIMP_DRAWABLE(gimage_get_mask (bcd->gimage)))) if (!drawable_gimage (GIMP_DRAWABLE (gimage_get_mask (bcd->gimage))))
return; return;
/* reset the mask */ /* reset the mask */
@ -857,16 +870,16 @@ by_color_select_reset_callback (GtkWidget *widget,
static void static void
by_color_select_close_callback (GtkWidget *widget, by_color_select_close_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data; bcd = (ByColorDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell)) if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell); gtk_widget_hide (bcd->shell);
if (bcd->gimage && if (bcd->gimage && gimp_set_have (image_context, bcd->gimage))
gimp_set_have (image_context, bcd->gimage))
{ {
bcd->gimage->by_color_select = FALSE; bcd->gimage->by_color_select = FALSE;
bcd->gimage = NULL; bcd->gimage = NULL;
@ -880,18 +893,19 @@ by_color_select_fuzzy_update (GtkAdjustment *adjustment,
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) data; bcd = (ByColorDialog *) data;
bcd->threshold = (int) adjustment->value;
bcd->threshold = (gint) (adjustment->value + 0.5);
} }
static void static void
by_color_select_preview_button_press (ByColorDialog *bcd, by_color_select_preview_button_press (ByColorDialog *bcd,
GdkEventButton *bevent) GdkEventButton *bevent)
{ {
int x, y; gint x, y;
int replace, operation; gint replace, operation;
GimpDrawable *drawable; GimpDrawable *drawable;
Tile *tile; Tile *tile;
unsigned char *col; guchar *col;
if (!bcd->gimage) if (!bcd->gimage)
return; return;

View File

@ -22,14 +22,20 @@
#include "gdisplayF.h" #include "gdisplayF.h"
#include "gimage.h" #include "gimage.h"
/* by_color select functions */ Tool * tools_new_by_color_select (void);
void by_color_select (GimpImage *, GimpDrawable *, guchar *, int, void tools_free_by_color_select (Tool *tool);
int, int, int, double, int);
Tool * tools_new_by_color_select (void); void by_color_select_initialize (GDisplay *gdisp);
void tools_free_by_color_select (Tool *); void by_color_select_initialize_by_image (GImage *gimage);
void by_color_select_initialize (GDisplay *); void by_color_select (GimpImage *gimage,
void by_color_select_initialize_by_image (GImage *); GimpDrawable *drawable,
guchar *color,
gint threshold,
gint op,
gint antialias,
gint feather,
gdouble feather_radius,
gint sample_merged);
#endif /* __BY_COLOR_SELECT_H__ */ #endif /* __BY_COLOR_SELECT_H__ */

View File

@ -15,21 +15,13 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "color_balance.h" #include "color_balance.h"
#include "color_transfer.h" #include "color_transfer.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimpui.h" #include "gimpui.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
static void color_balance_control (Tool *, ToolAction, gpointer); static void color_balance_control (Tool *, ToolAction, gpointer);
static ColorBalanceDialog * color_balance_new_dialog (void); static ColorBalanceDialog * color_balance_dialog_new (void);
static void color_balance_update (ColorBalanceDialog *, int); static void color_balance_update (ColorBalanceDialog *, int);
static void color_balance_preview (ColorBalanceDialog *); static void color_balance_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer); static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer); static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer); static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer); static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer); static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer); static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */ /* The color balance dialog */
if (!color_balance_dialog) if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog (); color_balance_dialog = color_balance_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell)) if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell))
gtk_widget_show (color_balance_dialog->shell); gtk_widget_show (color_balance_dialog->shell);
/* Initialize dialog fields */
color_balance_dialog->image_map = NULL;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
color_balance_dialog->cyan_red[i] = 0.0; color_balance_dialog->cyan_red[i] = 0.0;
color_balance_dialog->magenta_green[i] = 0.0; color_balance_dialog->magenta_green[i] = 0.0;
color_balance_dialog->yellow_blue[i] = 0.0; color_balance_dialog->yellow_blue[i] = 0.0;
} }
color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage); color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = color_balance_dialog->image_map =
image_map_create (gdisp, color_balance_dialog->drawable); image_map_create (gdisp, color_balance_dialog->drawable);
@ -236,13 +226,12 @@ color_balance_initialize (GDisplay *gdisp)
color_balance_update (color_balance_dialog, ALL); color_balance_update (color_balance_dialog, ALL);
} }
/**************************/ /**************************/
/* Color Balance dialog */ /* Color Balance dialog */
/**************************/ /**************************/
static ColorBalanceDialog * static ColorBalanceDialog *
color_balance_new_dialog (void) color_balance_dialog_new (void)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
GtkWidget *vbox; GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights") N_("Highlights")
}; };
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1); cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE; cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE; cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback, _("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE, cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback, _("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Color Levels:")); label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label); gtk_widget_show (label);
/* cyan-red spinbutton */ /* cyan-red spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->cyan_red_data = GTK_ADJUSTMENT (data); cbd->cyan_red_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0);
@ -313,7 +297,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* magenta-green spinbutton */ /* magenta-green spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->magenta_green_data = GTK_ADJUSTMENT (data); cbd->magenta_green_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0);
@ -322,7 +306,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* yellow-blue spinbutton */ /* yellow-blue spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->yellow_blue_data = GTK_ADJUSTMENT (data); cbd->yellow_blue_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0);
@ -334,22 +318,22 @@ color_balance_new_dialog (void)
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the cyan-red scale widget */ /* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan")); start_label = gtk_label_new (_("Cyan"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->cyan_red_data); slider = gtk_hscale_new (cbd->cyan_red_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update), GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update),
cbd); cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red")); end_label = gtk_label_new (_("Red"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta")); start_label = gtk_label_new (_("Magenta"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->magenta_green_data); slider = gtk_hscale_new (cbd->magenta_green_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update), GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update),
cbd); cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green")); end_label = gtk_label_new (_("Green"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow")); start_label = gtk_label_new (_("Yellow"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->yellow_blue_data); slider = gtk_hscale_new (cbd->yellow_blue_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 2, 3);
gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update), GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update),
cbd); cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue")); end_label = gtk_label_new (_("Blue"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
gtk_widget_show (slider); gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */ gtk_widget_show (table);
hbox = gtk_hbox_new (TRUE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button = radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i])); gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_box_pack_start (GTK_BOX (hbox), radio_button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), radio_button, TRUE, FALSE, 0);
gtk_object_set_user_data (GTK_OBJECT (radio_button), (gpointer) i);
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
GTK_SIGNAL_FUNC (appl_mode_callbacks[i]), GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd); cbd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (hbox);
/* Horizontal box for preview and preserve luminosity toggle buttons */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (cbd->shell); gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd) color_balance_preview (ColorBalanceDialog *cbd)
{ {
if (!cbd->image_map) if (!cbd->image_map)
g_message ("color_balance_preview(): No image map"); {
g_message ("color_balance_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
color_balance_create_lookup_tables (cbd); color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void
color_balance_reset_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->cyan_red[cbd->application_mode] = 0.0;
cbd->magenta_green[cbd->application_mode] = 0.0;
cbd->yellow_blue[cbd->application_mode] = 0.0;
color_balance_update (cbd, ALL);
if (cbd->preview)
color_balance_preview (cbd);
}
static void static void
color_balance_ok_callback (GtkWidget *widget, color_balance_ok_callback (GtkWidget *widget,
gpointer data) gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
} }
static void static void
color_balance_shadows_callback (GtkWidget *widget, color_balance_range_callback (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data; cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS; range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
color_balance_update (cbd, ALL); cbd->application_mode = range;
}
static void
color_balance_midtones_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = MIDTONES;
color_balance_update (cbd, ALL);
}
static void
color_balance_highlights_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = HIGHLIGHTS;
color_balance_update (cbd, ALL); color_balance_update (cbd, ALL);
} }

View File

@ -57,8 +57,6 @@ struct _ColorBalanceDialog
TransferMode application_mode; TransferMode application_mode;
}; };
/* color balance functions */
Tool * tools_new_color_balance (void); Tool * tools_new_color_balance (void);
void tools_free_color_balance (Tool *tool); void tools_free_color_balance (Tool *tool);

View File

@ -15,43 +15,36 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "buildmenu.h" #include "buildmenu.h"
#include "colormaps.h" #include "colormaps.h"
#include "cursorutil.h" #include "cursorutil.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimphistogram.h" #include "gimphistogram.h"
#include "gimpui.h" #include "gimpui.h"
#include "interface.h"
#include "curves.h" #include "curves.h"
#include "gimplut.h" #include "gimplut.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
#define GRAPH 0x1 #define GRAPH 0x1
#define XRANGE_TOP 0x2 #define XRANGE_TOP 0x2
#define XRANGE_BOTTOM 0x4 #define XRANGE_BOTTOM 0x4
#define YRANGE 0x8 #define YRANGE 0x8
#define DRAW 0x10 #define DRAW 0x10
#define ALL 0xFF #define ALL 0xFF
/* NB: take care when changing these values: make sure the curve[] array in /* NB: take care when changing these values: make sure the curve[] array in
* curves.h is large enough. * curves.h is large enough.
*/ */
#define GRAPH_WIDTH 256 #define GRAPH_WIDTH 256
#define GRAPH_HEIGHT 256 #define GRAPH_HEIGHT 256
#define XRANGE_WIDTH 256 #define XRANGE_WIDTH 256
#define XRANGE_HEIGHT 16 #define XRANGE_HEIGHT 16
#define YRANGE_WIDTH 16 #define YRANGE_WIDTH 16
#define YRANGE_HEIGHT 256 #define YRANGE_HEIGHT 256
#define RADIUS 3 #define RADIUS 3
#define MIN_DISTANCE 8 #define MIN_DISTANCE 8
@ -69,13 +62,13 @@
/* the curves structures */ /* the curves structures */
typedef struct _Curves Curves; typedef struct _Curves Curves;
struct _Curves struct _Curves
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef double CRMatrix[4][4]; typedef gdouble CRMatrix[4][4];
/* the curves tool options */ /* the curves tool options */
static ToolOptions * curves_options = NULL; static ToolOptions * curves_options = NULL;
@ -99,18 +92,21 @@ static void curves_button_release (Tool *, GdkEventButton *, gpointer);
static void curves_motion (Tool *, GdkEventMotion *, gpointer); static void curves_motion (Tool *, GdkEventMotion *, gpointer);
static void curves_control (Tool *, ToolAction, gpointer); static void curves_control (Tool *, ToolAction, gpointer);
static CurvesDialog * curves_new_dialog (void); static CurvesDialog * curves_dialog_new (void);
static void curves_update (CurvesDialog *, int); static void curves_update (CurvesDialog *, int);
static void curves_plot_curve (CurvesDialog *, int, int, int, int); static void curves_plot_curve (CurvesDialog *, int, int, int, int);
static void curves_preview (CurvesDialog *); static void curves_preview (CurvesDialog *);
static void curves_value_callback (GtkWidget *, gpointer); static void curves_value_callback (GtkWidget *, gpointer);
static void curves_red_callback (GtkWidget *, gpointer); static void curves_red_callback (GtkWidget *, gpointer);
static void curves_green_callback (GtkWidget *, gpointer); static void curves_green_callback (GtkWidget *, gpointer);
static void curves_blue_callback (GtkWidget *, gpointer); static void curves_blue_callback (GtkWidget *, gpointer);
static void curves_alpha_callback (GtkWidget *, gpointer); static void curves_alpha_callback (GtkWidget *, gpointer);
static void curves_smooth_callback (GtkWidget *, gpointer); static void curves_smooth_callback (GtkWidget *, gpointer);
static void curves_free_callback (GtkWidget *, gpointer); static void curves_free_callback (GtkWidget *, gpointer);
static void curves_reset_callback (GtkWidget *, gpointer); static void curves_reset_callback (GtkWidget *, gpointer);
static void curves_ok_callback (GtkWidget *, gpointer); static void curves_ok_callback (GtkWidget *, gpointer);
static void curves_cancel_callback (GtkWidget *, gpointer); static void curves_cancel_callback (GtkWidget *, gpointer);
@ -120,12 +116,13 @@ static gint curves_yrange_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *); static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix); static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix);
/* curves machinery */ /* curves machinery */
float float
curves_lut_func (CurvesDialog *cd, curves_lut_func (CurvesDialog *cd,
int nchannels, int channel, float value) gint nchannels,
gint channel,
gfloat value)
{ {
float f; float f;
int index; int index;
@ -188,9 +185,9 @@ curves_colour_update (Tool *tool,
if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y))) if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y)))
return; return;
sample_type = gimp_drawable_type(drawable); sample_type = gimp_drawable_type (drawable);
is_indexed = gimp_drawable_is_indexed (drawable); is_indexed = gimp_drawable_is_indexed (drawable);
has_alpha = TYPE_HAS_ALPHA(sample_type); has_alpha = TYPE_HAS_ALPHA (sample_type);
curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX]; curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX];
curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX]; curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX];
@ -207,11 +204,14 @@ curves_colour_update (Tool *tool,
maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]); maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]);
curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]); curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]);
g_free(color); g_free (color);
} }
static void static void
curves_add_point(GimpDrawable * drawable,gint x, gint y,gint cchan) curves_add_point (GimpDrawable *drawable,
gint x,
gint y,
gint cchan)
{ {
/* Add point onto the curve */ /* Add point onto the curve */
int closest_point = 0; int closest_point = 0;
@ -301,21 +301,21 @@ curves_button_release (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
if(bevent->state & GDK_SHIFT_MASK) if(bevent->state & GDK_SHIFT_MASK)
{ {
curves_add_point(drawable,x,y,curves_dialog->channel); curves_add_point (drawable, x, y, curves_dialog->channel);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
else if(bevent->state & GDK_CONTROL_MASK) else if(bevent->state & GDK_CONTROL_MASK)
{ {
curves_add_point(drawable,x,y,HISTOGRAM_VALUE); curves_add_point (drawable, x, y, HISTOGRAM_VALUE);
curves_add_point(drawable,x,y,HISTOGRAM_RED); curves_add_point (drawable, x, y, HISTOGRAM_RED);
curves_add_point(drawable,x,y,HISTOGRAM_GREEN); curves_add_point (drawable, x, y, HISTOGRAM_GREEN);
curves_add_point(drawable,x,y,HISTOGRAM_BLUE); curves_add_point (drawable, x, y, HISTOGRAM_BLUE);
curves_add_point(drawable,x,y,HISTOGRAM_ALPHA); curves_add_point (drawable, x, y, HISTOGRAM_ALPHA);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
@ -338,7 +338,7 @@ curves_motion (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
} }
@ -366,7 +366,7 @@ curves_control (Tool *tool,
} }
Tool * Tool *
tools_new_curves () tools_new_curves (void)
{ {
Tool * tool; Tool * tool;
Curves * private; Curves * private;
@ -397,15 +397,15 @@ tools_new_curves ()
void void
tools_free_curves (Tool *tool) tools_free_curves (Tool *tool)
{ {
Curves * _curves; Curves * private;
_curves = (Curves *) tool->private; private = (Curves *) tool->private;
/* Close the color select dialog */ /* Close the color select dialog */
if (curves_dialog) if (curves_dialog)
curves_cancel_callback (NULL, (gpointer) curves_dialog); curves_cancel_callback (NULL, (gpointer) curves_dialog);
g_free (_curves); g_free (private);
} }
static MenuItem channel_items[] = static MenuItem channel_items[] =
@ -421,7 +421,7 @@ static MenuItem channel_items[] =
void void
curves_initialize (GDisplay *gdisp) curves_initialize (GDisplay *gdisp)
{ {
int i, j; gint i, j;
if (drawable_indexed (gimage_active_drawable (gdisp->gimage))) if (drawable_indexed (gimage_active_drawable (gdisp->gimage)))
{ {
@ -431,7 +431,10 @@ curves_initialize (GDisplay *gdisp)
/* The curves dialog */ /* The curves dialog */
if (!curves_dialog) if (!curves_dialog)
curves_dialog = curves_new_dialog (); curves_dialog = curves_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (curves_dialog->shell))
gtk_widget_show (curves_dialog->shell);
/* Initialize the values */ /* Initialize the values */
curves_dialog->channel = HISTOGRAM_VALUE; curves_dialog->channel = HISTOGRAM_VALUE;
@ -454,22 +457,22 @@ curves_initialize (GDisplay *gdisp)
} }
curves_dialog->drawable = gimage_active_drawable (gdisp->gimage); curves_dialog->drawable = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color ( (curves_dialog->drawable)); curves_dialog->color = drawable_color (curves_dialog->drawable);
curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable); curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable);
/* check for alpha channel */ /* check for alpha channel */
if (drawable_has_alpha ( (curves_dialog->drawable))) if (drawable_has_alpha (curves_dialog->drawable))
gtk_widget_set_sensitive( channel_items[4].widget, TRUE); gtk_widget_set_sensitive (channel_items[4].widget, TRUE);
else else
gtk_widget_set_sensitive( channel_items[4].widget, FALSE); gtk_widget_set_sensitive (channel_items[4].widget, FALSE);
/* hide or show the channel menu based on image type */ /* hide or show the channel menu based on image type */
if (curves_dialog->color) if (curves_dialog->color)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, TRUE); gtk_widget_set_sensitive (channel_items[i].widget, TRUE);
else else
for (i = 1; i < 4; i++) for (i = 1; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, FALSE); gtk_widget_set_sensitive (channel_items[i].widget, FALSE);
/* set the current selection */ /* set the current selection */
gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0); gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0);
@ -481,7 +484,7 @@ curves_initialize (GDisplay *gdisp)
} }
void void
curves_free () curves_free (void)
{ {
if (curves_dialog) if (curves_dialog)
{ {
@ -506,7 +509,7 @@ curves_free ()
/*******************/ /*******************/
static CurvesDialog * static CurvesDialog *
curves_new_dialog () curves_dialog_new (void)
{ {
CurvesDialog *cd; CurvesDialog *cd;
GtkWidget *vbox; GtkWidget *vbox;
@ -528,19 +531,20 @@ curves_new_dialog ()
}; };
cd = g_new (CurvesDialog, 1); cd = g_new (CurvesDialog, 1);
cd->cursor_ind_height = cd->cursor_ind_width = -1; cd->cursor_ind_height = -1;
cd->preview = TRUE; cd->cursor_ind_width = -1;
cd->curve_type = SMOOTH; cd->preview = TRUE;
cd->pixmap = NULL; cd->curve_type = SMOOTH;
cd->channel = HISTOGRAM_VALUE; cd->pixmap = NULL;
cd->channel = HISTOGRAM_VALUE;
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
for (j = 0; j < 256; j++) for (j = 0; j < 256; j++)
cd->curve[i][j] = j; cd->curve[i][j] = j;
for(i = 0; i < (sizeof(cd->col_value)/sizeof(cd->col_value[0])); i++) for (i = 0; i < (sizeof (cd->col_value) / sizeof (cd->col_value[0])); i++)
cd->col_value[i] = 0; cd->col_value[i] = 0;
cd->lut = gimp_lut_new(); cd->lut = gimp_lut_new ();
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
channel_items [i].user_data = (gpointer) cd; channel_items [i].user_data = (gpointer) cd;
@ -562,15 +566,15 @@ curves_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox);
/* The option menu for selecting channels */ /* The option menu for selecting channels */
channel_hbox = gtk_hbox_new (FALSE, 2); channel_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Modify Curves for Channel: ")); label = gtk_label_new (_("Modify Curves for Channel:"));
gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0);
menu = build_menu (channel_items, NULL); menu = build_menu (channel_items, NULL);
@ -584,7 +588,8 @@ curves_new_dialog ()
/* The table for the yrange and the graph */ /* The table for the yrange and the graph */
table = gtk_table_new (2, 2, FALSE); table = gtk_table_new (2, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 2);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* The range drawing area */ /* The range drawing area */
@ -596,10 +601,12 @@ curves_new_dialog ()
cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT);
gtk_widget_set_events (cd->yrange, RANGE_MASK); gtk_widget_set_events (cd->yrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
(GtkSignalFunc) curves_yrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->yrange); gtk_container_add (GTK_CONTAINER (frame), cd->yrange);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
GTK_SIGNAL_FUNC (curves_yrange_events),
cd);
gtk_widget_show (cd->yrange); gtk_widget_show (cd->yrange);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -607,18 +614,20 @@ curves_new_dialog ()
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, 0, 0);
cd->graph = gtk_drawing_area_new (); cd->graph = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph), gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph),
GRAPH_WIDTH + RADIUS * 2, GRAPH_WIDTH + RADIUS * 2,
GRAPH_HEIGHT + RADIUS * 2); GRAPH_HEIGHT + RADIUS * 2);
gtk_widget_set_events (cd->graph, GRAPH_MASK); gtk_widget_set_events (cd->graph, GRAPH_MASK);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
(GtkSignalFunc) curves_graph_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->graph); gtk_container_add (GTK_CONTAINER (frame), cd->graph);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
GTK_SIGNAL_FUNC (curves_graph_events),
cd);
gtk_widget_show (cd->graph); gtk_widget_show (cd->graph);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -631,20 +640,22 @@ curves_new_dialog ()
cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT);
gtk_widget_set_events (cd->xrange, RANGE_MASK); gtk_widget_set_events (cd->xrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
(GtkSignalFunc) curves_xrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->xrange); gtk_container_add (GTK_CONTAINER (frame), cd->xrange);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
GTK_SIGNAL_FUNC (curves_xrange_events),
cd);
gtk_widget_show (cd->xrange); gtk_widget_show (cd->xrange);
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (table); gtk_widget_show (table);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The option menu for selecting the drawing method */ /* The option menu for selecting the drawing method */
label = gtk_label_new (_("Curve Type: ")); label = gtk_label_new (_("Curve Type:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
menu = build_menu (curve_type_items, NULL); menu = build_menu (curve_type_items, NULL);
@ -659,12 +670,12 @@ curves_new_dialog ()
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) curves_preview_update, GTK_SIGNAL_FUNC (curves_preview_update),
cd); cd);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
@ -674,32 +685,32 @@ curves_new_dialog ()
} }
static void static void
curve_print_loc(CurvesDialog *cd, curve_print_loc (CurvesDialog *cd,
gint xpos, gint xpos,
gint ypos) gint ypos)
{ {
char buf[32]; char buf[32];
gint width; gint width;
gint ascent; gint ascent;
gint descent; gint descent;
if(cd->cursor_ind_width < 0) if (cd->cursor_ind_width < 0)
{ {
/* Calc max extents */ /* Calc max extents */
gdk_string_extents(cd->graph->style->font, gdk_string_extents (cd->graph->style->font,
"x:888 y:888", "x:888 y:888",
NULL, NULL,
NULL, NULL,
&width, &width,
&ascent, &ascent,
&descent); &descent);
cd->cursor_ind_width = width; cd->cursor_ind_width = width;
cd->cursor_ind_height = ascent + descent; cd->cursor_ind_height = ascent + descent;
cd->cursor_ind_ascent = ascent; cd->cursor_ind_ascent = ascent;
} }
if(xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255) if (xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255)
{ {
g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos); g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos);
@ -730,53 +741,54 @@ curves_update (CurvesDialog *cd,
int update) int update)
{ {
GdkRectangle area; GdkRectangle area;
int i, j; gint i, j;
char buf[32]; gchar buf[32];
gint offset; gint offset;
if (update & XRANGE_TOP) if (update & XRANGE_TOP)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
for (i = 0; i < XRANGE_HEIGHT / 2; i++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH ; j++) for (j = 0; j < XRANGE_WIDTH ; j++)
{ {
buf[j*3+0] = cd->curve[cd->channel][j]; buf[j*3+0] = cd->curve[cd->channel][j];
buf[j*3+1] = cd->curve[cd->channel][j]; buf[j*3+1] = cd->curve[cd->channel][j];
buf[j*3+2] = cd->curve[cd->channel][j]; buf[j*3+2] = cd->curve[cd->channel][j];
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH); buf, 0, i, XRANGE_WIDTH);
} }
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
{
for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH; j++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
buf[j*3+0] = cd->curve[HISTOGRAM_RED][j]; for (j = 0; j < XRANGE_WIDTH; j++)
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j]; {
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j]; buf[j*3+0] = cd->curve[HISTOGRAM_RED][j];
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j];
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j];
}
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH);
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), break;
buf, 0, i, XRANGE_WIDTH);
} }
break;
}
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} /* end switch */ }
if (update & DRAW) if (update & DRAW)
{ {
@ -789,7 +801,7 @@ curves_update (CurvesDialog *cd,
} }
if (update & XRANGE_BOTTOM) if (update & XRANGE_BOTTOM)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
for (i = 0; i < XRANGE_WIDTH; i++) for (i = 0; i < XRANGE_WIDTH; i++)
{ {
@ -812,35 +824,36 @@ curves_update (CurvesDialog *cd,
} }
if (update & YRANGE) if (update & YRANGE)
{ {
unsigned char buf[YRANGE_WIDTH * 3]; guchar buf[YRANGE_WIDTH * 3];
unsigned char pix[3]; guchar pix[3];
for (i = 0; i < YRANGE_HEIGHT; i++) for (i = 0; i < YRANGE_HEIGHT; i++)
{ {
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
pix[0] = pix[1] = pix[2] = (255 - i); pix[0] = pix[1] = pix[2] = (255 - i);
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
pix[0] = pix[1] = pix[2] = 0; pix[0] = pix[1] = pix[2] = 0;
pix[cd->channel - 1] = (255 - i); pix[cd->channel - 1] = (255 - i);
break; break;
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} }
for (j = 0; j < YRANGE_WIDTH * 3; j++) for (j = 0; j < YRANGE_WIDTH * 3; j++)
buf[j] = pix[j%3]; buf[j] = pix[j%3];
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange), buf, 0, i, YRANGE_WIDTH);
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange),
buf, 0, i, YRANGE_WIDTH);
} }
if (update & DRAW) if (update & DRAW)
@ -852,7 +865,8 @@ curves_update (CurvesDialog *cd,
/* Clear the pixmap */ /* Clear the pixmap */
gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL], gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL],
TRUE, 0, 0, GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2); TRUE, 0, 0,
GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2);
/* Draw the grid lines */ /* Draw the grid lines */
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
@ -885,20 +899,20 @@ curves_update (CurvesDialog *cd,
} }
/* draw the colour line */ /* draw the colour line */
gdk_draw_line(cd->pixmap, cd->graph->style->black_gc, gdk_draw_line (cd->pixmap, cd->graph->style->black_gc,
cd->col_value[cd->channel]+RADIUS,RADIUS, cd->col_value[cd->channel]+RADIUS,RADIUS,
cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS); cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS);
/* and xpos indicator */ /* and xpos indicator */
g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]); g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]);
if((cd->col_value[cd->channel]+RADIUS) < 127) if ((cd->col_value[cd->channel]+RADIUS) < 127)
{ {
offset = RADIUS + 4; offset = RADIUS + 4;
} }
else else
{ {
offset = -gdk_string_width(cd->graph->style->font,buf) - 2; offset = - gdk_string_width (cd->graph->style->font,buf) - 2;
} }
gdk_draw_string (cd->pixmap, gdk_draw_string (cd->pixmap,
@ -916,10 +930,10 @@ curves_update (CurvesDialog *cd,
static void static void
curves_plot_curve (CurvesDialog *cd, curves_plot_curve (CurvesDialog *cd,
int p1, gint p1,
int p2, gint p2,
int p3, gint p3,
int p4) gint p4)
{ {
CRMatrix geometry; CRMatrix geometry;
CRMatrix tmp1, tmp2; CRMatrix tmp1, tmp2;
@ -1045,8 +1059,8 @@ curves_calculate_curve (CurvesDialog *cd)
} }
break; break;
} }
gimp_lut_setup(cd->lut, (GimpLutFunc) curves_lut_func, gimp_lut_setup (cd->lut, (GimpLutFunc) curves_lut_func,
(void *) cd, gimp_drawable_bytes(cd->drawable)); (void *) cd, gimp_drawable_bytes (cd->drawable));
} }
@ -1054,23 +1068,24 @@ static void
curves_preview (CurvesDialog *cd) curves_preview (CurvesDialog *cd)
{ {
if (!cd->image_map) if (!cd->image_map)
g_message ("curves_preview(): No image map"); {
g_message ("curves_preview(): No image map");
active_tool->preserve = TRUE; /* Going to dirty the display... */ return;
}
active_tool->preserve = TRUE;
image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2,
(void *) cd->lut); (void *) cd->lut);
active_tool->preserve = FALSE;
active_tool->preserve = FALSE; /* All done */
} }
static void static void
curves_value_callback (GtkWidget *w, curves_value_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_VALUE) if (cd->channel != HISTOGRAM_VALUE)
{ {
@ -1080,12 +1095,12 @@ curves_value_callback (GtkWidget *w,
} }
static void static void
curves_red_callback (GtkWidget *w, curves_red_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_RED) if (cd->channel != HISTOGRAM_RED)
{ {
@ -1095,12 +1110,12 @@ curves_red_callback (GtkWidget *w,
} }
static void static void
curves_green_callback (GtkWidget *w, curves_green_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_GREEN) if (cd->channel != HISTOGRAM_GREEN)
{ {
@ -1110,12 +1125,12 @@ curves_green_callback (GtkWidget *w,
} }
static void static void
curves_blue_callback (GtkWidget *w, curves_blue_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_BLUE) if (cd->channel != HISTOGRAM_BLUE)
{ {
@ -1125,12 +1140,12 @@ curves_blue_callback (GtkWidget *w,
} }
static void static void
curves_alpha_callback (GtkWidget *w, curves_alpha_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_ALPHA) if (cd->channel != HISTOGRAM_ALPHA)
{ {
@ -1140,14 +1155,14 @@ curves_alpha_callback (GtkWidget *w,
} }
static void static void
curves_smooth_callback (GtkWidget *w, curves_smooth_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
gint32 index; gint32 index;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != SMOOTH) if (cd->curve_type != SMOOTH)
{ {
@ -1170,12 +1185,12 @@ curves_smooth_callback (GtkWidget *w,
} }
static void static void
curves_free_callback (GtkWidget *w, curves_free_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != GFREE) if (cd->curve_type != GFREE)
{ {
@ -1190,12 +1205,12 @@ curves_free_callback (GtkWidget *w,
static void static void
curves_reset_callback (GtkWidget *widget, curves_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
/* Initialize the values */ /* Initialize the values */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -1214,17 +1229,18 @@ curves_reset_callback (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
} }
static void static void
curves_ok_callback (GtkWidget *widget, curves_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1248,11 +1264,12 @@ curves_ok_callback (GtkWidget *widget,
static void static void
curves_cancel_callback (GtkWidget *widget, curves_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1373,7 +1390,7 @@ curves_graph_events (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
gtk_grab_add(widget); gtk_grab_add (widget);
break; break;
@ -1384,7 +1401,7 @@ curves_graph_events (GtkWidget *widget,
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
gtk_grab_remove(widget); gtk_grab_remove (widget);
break; break;
@ -1527,7 +1544,7 @@ curves_CR_compose (CRMatrix a,
CRMatrix b, CRMatrix b,
CRMatrix ab) CRMatrix ab)
{ {
int i, j; gint i, j;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {

View File

@ -23,47 +23,53 @@
#include "lut_funcs.h" #include "lut_funcs.h"
#include "tools.h" #include "tools.h"
#define SMOOTH 0 #define SMOOTH 0
#define GFREE 1 #define GFREE 1
typedef struct _CurvesDialog CurvesDialog; typedef struct _CurvesDialog CurvesDialog;
struct _CurvesDialog struct _CurvesDialog
{ {
GtkWidget * shell; GtkWidget *shell;
GtkWidget * channel_menu;
GtkWidget * xrange;
GtkWidget * yrange;
GtkWidget * graph;
GdkPixmap * pixmap;
GimpDrawable * drawable;
ImageMap image_map;
int color;
int channel;
gint preview;
int grab_point; GtkWidget *channel_menu;
int last; GtkWidget *xrange;
int leftmost; GtkWidget *yrange;
int rightmost; GtkWidget *graph;
int curve_type; GdkPixmap *pixmap;
int points[5][17][2];
unsigned char curve[5][256]; GimpDrawable *drawable;
int col_value[5]; ImageMap image_map;
gint color;
gint channel;
gboolean preview;
gint grab_point;
gint last;
gint leftmost;
gint rightmost;
gint curve_type;
gint points[5][17][2];
guchar curve[5][256];
gint col_value[5];
int cursor_ind_height; gint cursor_ind_height;
int cursor_ind_width; gint cursor_ind_width;
int cursor_ind_ascent; gint cursor_ind_ascent;
GimpLut *lut; GimpLut *lut;
}; };
/* hue-saturation functions */ Tool * tools_new_curves (void);
Tool * tools_new_curves (void); void tools_free_curves (Tool *tool);
void tools_free_curves (Tool *);
void curves_initialize (GDisplay *); void curves_initialize (GDisplay *gdisp);
void curves_free (void); void curves_free (void);
float curves_lut_func (CurvesDialog *, int, int, float); float curves_lut_func (CurvesDialog *cd,
void curves_calculate_curve (CurvesDialog *); gint nchannels,
gint channel,
gfloat value);
void curves_calculate_curve (CurvesDialog *cd);
#endif /* __CURVES_H__ */ #endif /* __CURVES_H__ */

View File

@ -15,60 +15,51 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "brightness_contrast.h" #include "brightness_contrast.h"
#include "drawable.h" #include "drawable.h"
#include "gimage_mask.h" #include "gimplut.h"
#include "gimpui.h" #include "gimpui.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "gimplut.h"
#include "lut_funcs.h" #include "lut_funcs.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200 #define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define BRIGHTNESS_SLIDER 0x1 #define BRIGHTNESS 0x1
#define CONTRAST_SLIDER 0x2 #define CONTRAST 0x2
#define BRIGHTNESS_TEXT 0x4 #define ALL (BRIGHTNESS | CONTRAST)
#define CONTRAST_TEXT 0x8
#define ALL 0xF
/* the brightness-contrast structures */ /* the brightness-contrast structures */
typedef struct _BrightnessContrast BrightnessContrast; typedef struct _BrightnessContrast BrightnessContrast;
struct _BrightnessContrast struct _BrightnessContrast
{ {
gint x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef struct _BrightnessContrastDialog BrightnessContrastDialog; typedef struct _BrightnessContrastDialog BrightnessContrastDialog;
struct _BrightnessContrastDialog struct _BrightnessContrastDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *gimage_name; GtkWidget *gimage_name;
GtkWidget *brightness_text;
GtkWidget *contrast_text;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
GimpDrawable *drawable; GtkAdjustment *brightness_data;
ImageMap image_map; GtkAdjustment *contrast_data;
double brightness; GimpDrawable *drawable;
double contrast; ImageMap image_map;
gint preview; gdouble brightness;
gdouble contrast;
GimpLut *lut; gboolean preview;
GimpLut *lut;
}; };
@ -83,18 +74,19 @@ static BrightnessContrastDialog *brightness_contrast_dialog = NULL;
static void brightness_contrast_control (Tool *, ToolAction, gpointer); static void brightness_contrast_control (Tool *, ToolAction, gpointer);
static BrightnessContrastDialog * brightness_contrast_new_dialog (void); static BrightnessContrastDialog * brightness_contrast_dialog_new (void);
static void brightness_contrast_update (BrightnessContrastDialog *, int);
static void brightness_contrast_preview (BrightnessContrastDialog *);
static void brightness_contrast_ok_callback (GtkWidget *, gpointer);
static void brightness_contrast_cancel_callback (GtkWidget *, gpointer);
static void brightness_contrast_preview_update (GtkWidget *, gpointer);
static void brightness_contrast_brightness_scale_update (GtkAdjustment *, gpointer);
static void brightness_contrast_contrast_scale_update (GtkAdjustment *, gpointer);
static void brightness_contrast_brightness_text_update (GtkWidget *, gpointer);
static void brightness_contrast_contrast_text_update (GtkWidget *, gpointer);
static void brightness_contrast_update (BrightnessContrastDialog *,
gint);
static void brightness_contrast_preview (BrightnessContrastDialog *);
static void brightness_contrast_reset_callback (GtkWidget *, gpointer);
static void brightness_contrast_ok_callback (GtkWidget *, gpointer);
static void brightness_contrast_cancel_callback (GtkWidget *, gpointer);
static void brightness_contrast_preview_update (GtkWidget *, gpointer);
static void brightness_contrast_brightness_adjustment_update (GtkAdjustment *,
gpointer);
static void brightness_contrast_contrast_adjustment_update (GtkAdjustment *,
gpointer);
/* brightness-contrast select action functions */ /* brightness-contrast select action functions */
@ -122,7 +114,7 @@ brightness_contrast_control (Tool *tool,
} }
Tool * Tool *
tools_new_brightness_contrast () tools_new_brightness_contrast (void)
{ {
Tool * tool; Tool * tool;
BrightnessContrast * private; BrightnessContrast * private;
@ -155,7 +147,7 @@ tools_free_brightness_contrast (Tool *tool)
bc = (BrightnessContrast *) tool->private; bc = (BrightnessContrast *) tool->private;
/* Close the color select dialog */ /* Close the brightness-contrast dialog */
if (brightness_contrast_dialog) if (brightness_contrast_dialog)
brightness_contrast_cancel_callback (NULL, (gpointer) brightness_contrast_dialog); brightness_contrast_cancel_callback (NULL, (gpointer) brightness_contrast_dialog);
@ -173,15 +165,13 @@ brightness_contrast_initialize (GDisplay *gdisp)
/* The brightness-contrast dialog */ /* The brightness-contrast dialog */
if (!brightness_contrast_dialog) if (!brightness_contrast_dialog)
brightness_contrast_dialog = brightness_contrast_new_dialog (); brightness_contrast_dialog = brightness_contrast_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (brightness_contrast_dialog->shell)) if (!GTK_WIDGET_VISIBLE (brightness_contrast_dialog->shell))
gtk_widget_show (brightness_contrast_dialog->shell); gtk_widget_show (brightness_contrast_dialog->shell);
/* Initialize dialog fields */
brightness_contrast_dialog->image_map = NULL;
brightness_contrast_dialog->brightness = 0.0; brightness_contrast_dialog->brightness = 0.0;
brightness_contrast_dialog->contrast = 0.0; brightness_contrast_dialog->contrast = 0.0;
brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage); brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->image_map = brightness_contrast_dialog->image_map =
@ -190,19 +180,20 @@ brightness_contrast_initialize (GDisplay *gdisp)
brightness_contrast_update (brightness_contrast_dialog, ALL); brightness_contrast_update (brightness_contrast_dialog, ALL);
} }
/********************************/ /********************************/
/* Brightness Contrast dialog */ /* Brightness Contrast dialog */
/********************************/ /********************************/
static BrightnessContrastDialog * static BrightnessContrastDialog *
brightness_contrast_new_dialog () brightness_contrast_dialog_new (void)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data; GtkObject *data;
@ -219,6 +210,8 @@ brightness_contrast_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), brightness_contrast_reset_callback,
bcd, NULL, TRUE, FALSE,
_("OK"), brightness_contrast_ok_callback, _("OK"), brightness_contrast_ok_callback,
bcd, NULL, TRUE, FALSE, bcd, NULL, TRUE, FALSE,
_("Cancel"), brightness_contrast_cancel_callback, _("Cancel"), brightness_contrast_cancel_callback,
@ -226,94 +219,90 @@ brightness_contrast_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (2, 3, FALSE); table = gtk_table_new (2, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the brightness scale widget */ /* Create the brightness scale widget */
label = gtk_label_new (_("Brightness")); label = gtk_label_new (_("Brightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -127, 127.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -127, 127.0, 1.0, 10.0, 0.0);
bcd->brightness_data = GTK_ADJUSTMENT (data); bcd->brightness_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1, gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_brightness_scale_update,
bcd);
bcd->brightness_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (bcd->brightness_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (bcd->brightness_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), bcd->brightness_text, 2, 3, 0, 1, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (bcd->brightness_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
(GtkSignalFunc) brightness_contrast_brightness_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
GTK_SIGNAL_FUNC (brightness_contrast_brightness_adjustment_update),
bcd); bcd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (bcd->brightness_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the contrast scale widget */ /* Create the contrast scale widget */
label = gtk_label_new (_("Contrast")); label = gtk_label_new (_("Contrast"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -127.0, 127.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -127.0, 127.0, 1.0, 10.0, 0.0);
bcd->contrast_data = GTK_ADJUSTMENT (data); bcd->contrast_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2, gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_contrast_scale_update,
bcd);
bcd->contrast_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (bcd->contrast_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (bcd->contrast_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), bcd->contrast_text, 2, 3, 1, 2, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (bcd->contrast_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
(GtkSignalFunc) brightness_contrast_contrast_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
GTK_SIGNAL_FUNC (brightness_contrast_contrast_adjustment_update),
bcd); bcd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (bcd->contrast_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Horizontal box for preview toggle button */
/* Horizontal box for preview and preserve luminosity toggle buttons */ hbox = gtk_hbox_new (FALSE, 4);
hbox = gtk_hbox_new (TRUE, 2); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), bcd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), bcd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) brightness_contrast_preview_update, GTK_SIGNAL_FUNC (brightness_contrast_preview_update),
bcd); bcd);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
@ -328,27 +317,13 @@ static void
brightness_contrast_update (BrightnessContrastDialog *bcd, brightness_contrast_update (BrightnessContrastDialog *bcd,
gint update) gint update)
{ {
char text[12]; if (update & BRIGHTNESS)
if (update & BRIGHTNESS_SLIDER)
{ {
bcd->brightness_data->value = bcd->brightness; gtk_adjustment_set_value (bcd->brightness_data, bcd->brightness);
gtk_signal_emit_by_name (GTK_OBJECT (bcd->brightness_data), "value_changed");
} }
if (update & CONTRAST_SLIDER) if (update & CONTRAST)
{ {
bcd->contrast_data->value = bcd->contrast; gtk_adjustment_set_value (bcd->contrast_data, bcd->contrast);
gtk_signal_emit_by_name (GTK_OBJECT (bcd->contrast_data), "value_changed");
}
if (update & BRIGHTNESS_TEXT)
{
g_snprintf (text, sizeof (text), "%0.0f", bcd->brightness);
gtk_entry_set_text (GTK_ENTRY (bcd->brightness_text), text);
}
if (update & CONTRAST_TEXT)
{
g_snprintf (text, sizeof (text), "%0.0f", bcd->contrast);
gtk_entry_set_text (GTK_ENTRY (bcd->contrast_text), text);
} }
} }
@ -371,12 +346,29 @@ brightness_contrast_preview (BrightnessContrastDialog *bcd)
} }
static void static void
brightness_contrast_ok_callback (GtkWidget *widget, brightness_contrast_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
bcd = (BrightnessContrastDialog *) client_data; bcd = (BrightnessContrastDialog *) data;
bcd->brightness = 0.0;
bcd->contrast = 0.0;
brightness_contrast_update (bcd, ALL);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
static void
brightness_contrast_ok_callback (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
bcd = (BrightnessContrastDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell)) if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell); gtk_widget_hide (bcd->shell);
@ -446,8 +438,8 @@ brightness_contrast_preview_update (GtkWidget *widget,
} }
static void static void
brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment, brightness_contrast_brightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
@ -456,7 +448,6 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
if (bcd->brightness != adjustment->value) if (bcd->brightness != adjustment->value)
{ {
bcd->brightness = adjustment->value; bcd->brightness = adjustment->value;
brightness_contrast_update (bcd, BRIGHTNESS_TEXT);
if (bcd->preview) if (bcd->preview)
brightness_contrast_preview (bcd); brightness_contrast_preview (bcd);
@ -464,8 +455,8 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
} }
static void static void
brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment, brightness_contrast_contrast_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
BrightnessContrastDialog *bcd; BrightnessContrastDialog *bcd;
@ -474,51 +465,6 @@ brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
if (bcd->contrast != adjustment->value) if (bcd->contrast != adjustment->value)
{ {
bcd->contrast = adjustment->value; bcd->contrast = adjustment->value;
brightness_contrast_update (bcd, CONTRAST_TEXT);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
}
static void
brightness_contrast_brightness_text_update (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
gchar *str;
gint value;
str = gtk_entry_get_text (GTK_ENTRY (widget));
bcd = (BrightnessContrastDialog *) data;
value = BOUNDS (((int) atof (str)), -127, 127);
if ((int) bcd->brightness != value)
{
bcd->brightness = value;
brightness_contrast_update (bcd, BRIGHTNESS_SLIDER);
if (bcd->preview)
brightness_contrast_preview (bcd);
}
}
static void
brightness_contrast_contrast_text_update (GtkWidget *widget,
gpointer data)
{
BrightnessContrastDialog *bcd;
gchar *str;
gint value;
str = gtk_entry_get_text (GTK_ENTRY (widget));
bcd = (BrightnessContrastDialog *) data;
value = BOUNDS (((int) atof (str)), -127, 127);
if ((int) bcd->contrast != value)
{
bcd->contrast = value;
brightness_contrast_update (bcd, CONTRAST_SLIDER);
if (bcd->preview) if (bcd->preview)
brightness_contrast_preview (bcd); brightness_contrast_preview (bcd);

View File

@ -20,10 +20,9 @@
#include "tools.h" #include "tools.h"
/* by_color select functions */ Tool * tools_new_brightness_contrast (void);
Tool * tools_new_brightness_contrast (void); void tools_free_brightness_contrast (Tool *tool);
void tools_free_brightness_contrast (Tool *);
void brightness_contrast_initialize (GDisplay *); void brightness_contrast_initialize (GDisplay *gdisp);
#endif /* __BRIGHTNESS_CONTRAST_H__ */ #endif /* __BRIGHTNESS_CONTRAST_H__ */

View File

@ -15,32 +15,27 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "boundary.h" #include "boundary.h"
#include "by_color_select.h" #include "by_color_select.h"
#include "colormaps.h" #include "colormaps.h"
#include "drawable.h" #include "drawable.h"
#include "draw_core.h" #include "draw_core.h"
#include "general.h"
#include "gimage_mask.h" #include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimprc.h" #include "gimprc.h"
#include "gimpset.h" #include "gimpset.h"
#include "gimpui.h" #include "gimpui.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "selection_options.h" #include "selection_options.h"
#include "gimpdnd.h" #include "tile.h" /* ick. */
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "tile.h" /* ick. */ #define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define DEFAULT_FUZZINESS 15 #define PREVIEW_HEIGHT 256
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \ #define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \ GDK_BUTTON_PRESS_MASK | \
GDK_ENTER_NOTIFY_MASK GDK_ENTER_NOTIFY_MASK
@ -48,40 +43,43 @@
/* the by color selection structures */ /* the by color selection structures */
typedef struct _ByColorSelect ByColorSelect; typedef struct _ByColorSelect ByColorSelect;
struct _ByColorSelect struct _ByColorSelect
{ {
int x, y; /* Point from which to execute seed fill */ gint x, y; /* Point from which to execute seed fill */
int operation; /* add, subtract, normal color selection */ gint operation; /* add, subtract, normal color selection */
}; };
typedef struct _ByColorDialog ByColorDialog; typedef struct _ByColorDialog ByColorDialog;
struct _ByColorDialog struct _ByColorDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *preview;
GtkWidget *gimage_name;
int threshold; /* threshold value for color select */ GtkWidget *preview;
int operation; /* Add, Subtract, Replace */ GtkWidget *gimage_name;
GImage *gimage; /* gimage which is currently under examination */
gint threshold; /* threshold value for color select */
gint operation; /* Add, Subtract, Replace */
GImage *gimage; /* gimage which is currently under examination */
}; };
/* the by color selection tool options */ /* the by color selection tool options */
static SelectionOptions *by_color_options = NULL; static SelectionOptions * by_color_options = NULL;
/* the by color selection dialog */ /* the by color selection dialog */
static ByColorDialog * by_color_dialog = NULL; static ByColorDialog * by_color_dialog = NULL;
/* dnd stuff */ /* dnd stuff */
static GtkTargetEntry by_color_select_image_target_table[] = static GtkTargetEntry by_color_select_targets[] =
{ {
GIMP_TARGET_COLOR GIMP_TARGET_COLOR
}; };
static guint n_by_color_select_image_targets = static guint n_by_color_select_targets = (sizeof (by_color_select_targets) /
(sizeof (by_color_select_image_target_table) / sizeof (by_color_select_targets[0]));
sizeof (by_color_select_image_target_table[0]));
static void by_color_select_color_drop (GtkWidget*, guchar, guchar, guchar, gpointer); static void by_color_select_color_drop (GtkWidget *, guchar, guchar, guchar,
gpointer);
/* by_color select action functions */ /* by_color select action functions */
@ -90,32 +88,35 @@ static void by_color_select_button_release (Tool *, GdkEventButton *, gpointer);
static void by_color_select_cursor_update (Tool *, GdkEventMotion *, gpointer); static void by_color_select_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void by_color_select_control (Tool *, ToolAction, gpointer); static void by_color_select_control (Tool *, ToolAction, gpointer);
static ByColorDialog * by_color_select_new_dialog (void); static ByColorDialog * by_color_select_dialog_new (void);
static void by_color_select_render (ByColorDialog *, GImage *); static void by_color_select_render (ByColorDialog *, GImage *);
static void by_color_select_draw (ByColorDialog *, GImage *); static void by_color_select_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *, GdkEventButton *, static gint by_color_select_preview_events (GtkWidget *,
ByColorDialog *); GdkEventButton *,
static void by_color_select_type_callback (GtkWidget *, gpointer); ByColorDialog *);
static void by_color_select_reset_callback (GtkWidget *, gpointer); static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_close_callback (GtkWidget *, gpointer); static void by_color_select_reset_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer); static void by_color_select_close_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer);
static void by_color_select_preview_button_press (ByColorDialog *, static void by_color_select_preview_button_press (ByColorDialog *,
GdkEventButton *); GdkEventButton *);
static int is_pixel_sufficiently_different (unsigned char *, unsigned char *, int, int, int, int); static gint is_pixel_sufficiently_different (guchar *, guchar *,
static Channel * by_color_select_color (GImage *, GimpDrawable *, unsigned char *, int, int, int); gint, gint, gint, gint);
static Channel * by_color_select_color (GImage *, GimpDrawable *,
guchar *, gint, gint, gint);
/* by_color selection machinery */ /* by_color selection machinery */
static int static int
is_pixel_sufficiently_different (unsigned char *col1, is_pixel_sufficiently_different (guchar *col1,
unsigned char *col2, guchar *col2,
int antialias, gint antialias,
int threshold, gint threshold,
int bytes, gint bytes,
int has_alpha) gint has_alpha)
{ {
int diff; int diff;
int max; int max;
@ -145,7 +146,7 @@ is_pixel_sufficiently_different (unsigned char *col1,
if (aa <= 0) if (aa <= 0)
return 0; return 0;
else if (aa < 0.5) else if (aa < 0.5)
return (unsigned char) (aa * 512); return (guchar) (aa * 512);
else else
return 255; return 255;
} }
@ -159,12 +160,12 @@ is_pixel_sufficiently_different (unsigned char *col1,
} }
static Channel * static Channel *
by_color_select_color (GImage *gimage, by_color_select_color (GImage *gimage,
GimpDrawable *drawable, GimpDrawable *drawable,
unsigned char *color, guchar *color,
int antialias, gint antialias,
int threshold, gint threshold,
int sample_merged) gint sample_merged)
{ {
/* Scan over the gimage's active layer, finding pixels within the specified /* Scan over the gimage's active layer, finding pixels within the specified
* threshold from the given R, G, & B values. If antialiasing is on, * threshold from the given R, G, & B values. If antialiasing is on,
@ -173,10 +174,10 @@ by_color_select_color (GImage *gimage,
*/ */
Channel *mask; Channel *mask;
PixelRegion imagePR, maskPR; PixelRegion imagePR, maskPR;
unsigned char *image_data; guchar *image_data;
unsigned char *mask_data; guchar *mask_data;
unsigned char *idata, *mdata; guchar *idata, *mdata;
unsigned char rgb[MAX_CHANNELS]; guchar rgb[MAX_CHANNELS];
int has_alpha, indexed; int has_alpha, indexed;
int width, height; int width, height;
int bytes, color_bytes, alpha; int bytes, color_bytes, alpha;
@ -195,7 +196,8 @@ by_color_select_color (GImage *gimage,
indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE; indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE;
width = gimage->width; width = gimage->width;
height = gimage->height; height = gimage->height;
pixel_region_init (&imagePR, gimage_composite (gimage), 0, 0, width, height, FALSE); pixel_region_init (&imagePR, gimage_composite (gimage),
0, 0, width, height, FALSE);
} }
else else
{ {
@ -206,16 +208,20 @@ by_color_select_color (GImage *gimage,
width = drawable_width (drawable); width = drawable_width (drawable);
height = drawable_height (drawable); height = drawable_height (drawable);
pixel_region_init (&imagePR, drawable_data (drawable), 0, 0, width, height, FALSE); pixel_region_init (&imagePR, drawable_data (drawable),
0, 0, width, height, FALSE);
} }
if (indexed) { if (indexed)
/* indexed colors are always RGB or RGBA */ {
color_bytes = has_alpha ? 4 : 3; /* indexed colors are always RGB or RGBA */
} else { color_bytes = has_alpha ? 4 : 3;
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */ }
color_bytes = bytes; else
} {
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
alpha = bytes - 1; alpha = bytes - 1;
mask = channel_new_mask (gimage, width, height); mask = channel_new_mask (gimage, width, height);
@ -223,7 +229,9 @@ by_color_select_color (GImage *gimage,
0, 0, width, height, TRUE); 0, 0, width, height, TRUE);
/* iterate over the entire image */ /* iterate over the entire image */
for (pr = pixel_regions_register (2, &imagePR, &maskPR); pr != NULL; pr = pixel_regions_process (pr)) for (pr = pixel_regions_register (2, &imagePR, &maskPR);
pr != NULL;
pr = pixel_regions_process (pr))
{ {
image_data = imagePR.data; image_data = imagePR.data;
mask_data = maskPR.data; mask_data = maskPR.data;
@ -242,8 +250,12 @@ by_color_select_color (GImage *gimage,
rgb[color_bytes - 1] = idata[alpha]; rgb[color_bytes - 1] = idata[alpha];
/* Find how closely the colors match */ /* Find how closely the colors match */
*mdata++ = is_pixel_sufficiently_different (color, rgb, antialias, *mdata++ = is_pixel_sufficiently_different (color,
threshold, color_bytes, has_alpha); rgb,
antialias,
threshold,
color_bytes,
has_alpha);
idata += bytes; idata += bytes;
} }
@ -257,15 +269,15 @@ by_color_select_color (GImage *gimage,
} }
void void
by_color_select (GImage *gimage, by_color_select (GImage *gimage,
GimpDrawable *drawable, GimpDrawable *drawable,
unsigned char *color, guchar *color,
int threshold, gint threshold,
int op, gint op,
int antialias, gint antialias,
int feather, gint feather,
double feather_radius, gdouble feather_radius,
int sample_merged) gint sample_merged)
{ {
Channel * new_mask; Channel * new_mask;
int off_x, off_y; int off_x, off_y;
@ -273,7 +285,8 @@ by_color_select (GImage *gimage,
if (!drawable) if (!drawable)
return; return;
new_mask = by_color_select_color (gimage, drawable, color, antialias, threshold, sample_merged); new_mask = by_color_select_color (gimage, drawable, color,
antialias, threshold, sample_merged);
/* if applicable, replace the current selection */ /* if applicable, replace the current selection */
if (op == REPLACE) if (op == REPLACE)
@ -300,7 +313,6 @@ by_color_select (GImage *gimage,
channel_delete (new_mask); channel_delete (new_mask);
} }
/* by_color select action functions */ /* by_color select action functions */
static void static void
@ -345,8 +357,25 @@ by_color_select_button_press (Tool *tool,
/* Update the by_color_dialog's active gdisp pointer */ /* Update the by_color_dialog's active gdisp pointer */
if (by_color_dialog->gimage) if (by_color_dialog->gimage)
by_color_dialog->gimage->by_color_select = FALSE; by_color_dialog->gimage->by_color_select = FALSE;
if (by_color_dialog->gimage != gdisp->gimage)
{
gdk_draw_rectangle
(by_color_dialog->preview->window,
by_color_dialog->preview->style->bg_gc[GTK_STATE_NORMAL],
TRUE,
0, 0,
by_color_dialog->preview->allocation.width,
by_color_dialog->preview->allocation.width);
}
by_color_dialog->gimage = gdisp->gimage; by_color_dialog->gimage = gdisp->gimage;
gdisp->gimage->by_color_select = TRUE; gdisp->gimage->by_color_select = TRUE;
gdk_pointer_grab (gdisp->canvas->window, FALSE,
GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, bevent->time);
} }
static void static void
@ -356,32 +385,35 @@ by_color_select_button_release (Tool *tool,
{ {
ByColorSelect * by_color_sel; ByColorSelect * by_color_sel;
GDisplay * gdisp; GDisplay * gdisp;
int x, y; gint x, y;
GimpDrawable *drawable; GimpDrawable *drawable;
unsigned char *color; guchar *color;
int use_offsets; gint use_offsets;
gdisp = (GDisplay *) gdisp_ptr; gdisp = (GDisplay *) gdisp_ptr;
by_color_sel = (ByColorSelect *) tool->private; by_color_sel = (ByColorSelect *) tool->private;
drawable = gimage_active_drawable (gdisp->gimage); drawable = gimage_active_drawable (gdisp->gimage);
gdk_pointer_ungrab (bevent->time);
tool->state = INACTIVE; tool->state = INACTIVE;
/* First take care of the case where the user "cancels" the action */ /* First take care of the case where the user "cancels" the action */
if (! (bevent->state & GDK_BUTTON3_MASK)) if (! (bevent->state & GDK_BUTTON3_MASK))
{ {
use_offsets = (by_color_options->sample_merged) ? FALSE : TRUE; use_offsets = (by_color_options->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, by_color_sel->x, by_color_sel->y, &x, &y, FALSE, use_offsets); gdisplay_untransform_coords (gdisp, by_color_sel->x, by_color_sel->y,
&x, &y, FALSE, use_offsets);
/* Get the start color */ /* Get the start color */
if (by_color_options->sample_merged) if (by_color_options->sample_merged)
{ {
if (!(color = gimp_image_get_color_at(gdisp->gimage, x, y))) if (!(color = gimp_image_get_color_at (gdisp->gimage, x, y)))
return; return;
} }
else else
{ {
if (!(color = gimp_drawable_get_color_at(drawable, x, y))) if (!(color = gimp_drawable_get_color_at (drawable, x, y)))
return; return;
} }
@ -394,7 +426,7 @@ by_color_select_button_release (Tool *tool,
by_color_options->feather_radius, by_color_options->feather_radius,
by_color_options->sample_merged); by_color_options->sample_merged);
g_free(color); g_free (color);
/* show selection on all views */ /* show selection on all views */
gdisplays_flush (); gdisplays_flush ();
@ -412,17 +444,20 @@ by_color_select_cursor_update (Tool *tool,
{ {
GDisplay *gdisp; GDisplay *gdisp;
Layer *layer; Layer *layer;
int x, y; gint x, y;
gdisp = (GDisplay *) gdisp_ptr; gdisp = (GDisplay *) gdisp_ptr;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&x, &y, FALSE, FALSE);
if ((layer = gimage_pick_correlate_layer (gdisp->gimage, x, y))) if ((layer = gimage_pick_correlate_layer (gdisp->gimage, x, y)))
if (layer == gdisp->gimage->active_layer) if (layer == gdisp->gimage->active_layer)
{ {
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS); gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
return; return;
} }
gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW); gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW);
} }
@ -450,13 +485,13 @@ by_color_select_control (Tool *tool,
} }
static void static void
by_color_select_options_reset () by_color_select_options_reset (void)
{ {
selection_options_reset (by_color_options); selection_options_reset (by_color_options);
} }
Tool * Tool *
tools_new_by_color_select () tools_new_by_color_select (void)
{ {
Tool * tool; Tool * tool;
ByColorSelect * private; ByColorSelect * private;
@ -471,7 +506,7 @@ tools_new_by_color_select ()
/* The "by color" dialog */ /* The "by color" dialog */
if (!by_color_dialog) if (!by_color_dialog)
by_color_dialog = by_color_select_new_dialog (); by_color_dialog = by_color_select_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell)) if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell))
gtk_widget_show (by_color_dialog->shell); gtk_widget_show (by_color_dialog->shell);
@ -521,7 +556,6 @@ by_color_select_initialize_by_image (GImage *gimage)
void void
by_color_select_initialize (GDisplay *gdisp) by_color_select_initialize (GDisplay *gdisp)
{ {
/* wrap this call so the tool_info->init_func works */
by_color_select_initialize_by_image (gdisp->gimage); by_color_select_initialize_by_image (gdisp->gimage);
} }
@ -530,37 +564,16 @@ by_color_select_initialize (GDisplay *gdisp)
/****************************/ /****************************/
static ByColorDialog * static ByColorDialog *
by_color_select_new_dialog () by_color_select_dialog_new (void)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *options_box; GtkWidget *options_box;
GtkWidget *label; GtkWidget *label;
GtkWidget *util_box; GtkWidget *util_box;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *radio_box;
GtkWidget *radio_button;
GtkObject *data; GtkObject *data;
GSList *group = NULL;
gint i;
gchar *button_names[] =
{
N_("Replace"),
N_("Add"),
N_("Subtract"),
N_("Intersect")
};
gint button_values[] =
{
REPLACE,
ADD,
SUB,
INTERSECT
};
bcd = g_new (ByColorDialog, 1); bcd = g_new (ByColorDialog, 1);
bcd->gimage = NULL; bcd->gimage = NULL;
@ -580,101 +593,98 @@ by_color_select_new_dialog ()
NULL); NULL);
/* The vbox */ /* The main hbox */
vbox = gtk_vbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), hbox);
/* The horizontal box containing preview & options box */
hbox = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview */ /* The preview */
util_box = gtk_vbox_new (FALSE, 2); util_box = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), util_box, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0);
bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE); bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT); gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT);
gtk_widget_set_events (bcd->preview, PREVIEW_EVENT_MASK); gtk_widget_set_events (bcd->preview, PREVIEW_EVENT_MASK);
gtk_signal_connect (GTK_OBJECT (bcd->preview), "button_press_event",
(GtkSignalFunc) by_color_select_preview_events,
bcd);
gtk_container_add (GTK_CONTAINER (frame), bcd->preview); gtk_container_add (GTK_CONTAINER (frame), bcd->preview);
/* dnd colors to the image window */ gtk_signal_connect (GTK_OBJECT (bcd->preview), "button_press_event",
GTK_SIGNAL_FUNC (by_color_select_preview_events),
bcd);
/* dnd colors to the image window */
gtk_drag_dest_set (bcd->preview, gtk_drag_dest_set (bcd->preview,
GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP, GTK_DEST_DEFAULT_DROP,
by_color_select_image_target_table, by_color_select_targets,
n_by_color_select_image_targets, n_by_color_select_targets,
GDK_ACTION_COPY); GDK_ACTION_COPY);
gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd); gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd);
gtk_widget_show (bcd->preview); gtk_widget_show (bcd->preview);
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (util_box); gtk_widget_show (util_box);
/* options box */ /* options box */
options_box = gtk_vbox_new (FALSE, 2); options_box = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (options_box), 5); gtk_box_pack_start (GTK_BOX (hbox), options_box, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), options_box, TRUE, TRUE, 0);
/* Create the active image label */ /* Create the active image label */
util_box = gtk_hbox_new (FALSE, 2); util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
bcd->gimage_name = gtk_label_new (_("Inactive")); bcd->gimage_name = gtk_label_new (_("Inactive"));
gtk_box_pack_start (GTK_BOX (util_box), bcd->gimage_name, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), bcd->gimage_name, FALSE, FALSE, 0);
gtk_widget_show (bcd->gimage_name); gtk_widget_show (bcd->gimage_name);
gtk_widget_show (util_box); gtk_widget_show (util_box);
/* Create the selection mode radio box */ /* Create the selection mode radio box */
frame = gtk_frame_new (_("Selection Mode")); frame =
gimp_radio_group_new (TRUE, _("Selection Mode"),
_("Replace"), by_color_select_type_callback,
(gpointer) REPLACE, NULL, NULL, TRUE,
_("Add"), by_color_select_type_callback,
(gpointer) ADD, NULL, NULL, FALSE,
_("Subtract"), by_color_select_type_callback,
(gpointer) SUB, NULL, NULL, FALSE,
_("Intersect"), by_color_select_type_callback,
(gpointer) INTERSECT, NULL, NULL, FALSE,
NULL);
gtk_box_pack_start (GTK_BOX (options_box), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), frame, FALSE, FALSE, 0);
radio_box = gtk_vbox_new (FALSE, 2);
gtk_container_add (GTK_CONTAINER (frame), radio_box);
/* the radio buttons */
for (i = 0; i < (sizeof(button_names) / sizeof(button_names[0])); i++)
{
radio_button = gtk_radio_button_new_with_label (group,
gettext(button_names[i]));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_box_pack_start (GTK_BOX (radio_box), radio_button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) by_color_select_type_callback,
(gpointer) ((long) button_values[i]));
gtk_widget_show (radio_button);
}
gtk_widget_show (radio_box);
gtk_widget_show (frame); gtk_widget_show (frame);
/* Create the opacity scale widget */ /* Create the opacity scale widget */
util_box = gtk_vbox_new (FALSE, 2); util_box = gtk_vbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
label = gtk_label_new (_("Fuzziness Threshold")); label = gtk_label_new (_("Fuzziness Threshold"));
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
gtk_widget_show (label);
gtk_widget_show (util_box);
data = gtk_adjustment_new (bcd->threshold, 0.0, 255.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (bcd->threshold, 0.0, 255.0, 1.0, 1.0, 0.0);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data)); slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (data), "value_changed", gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) by_color_select_fuzzy_update, GTK_SIGNAL_FUNC (by_color_select_fuzzy_update),
bcd); bcd);
gtk_widget_show (label);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (util_box);
gtk_widget_show (options_box); gtk_widget_show (options_box);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (vbox);
gtk_widget_show (bcd->shell); gtk_widget_show (bcd->shell);
return bcd; return bcd;
@ -686,14 +696,14 @@ by_color_select_render (ByColorDialog *bcd,
{ {
Channel * mask; Channel * mask;
MaskBuf * scaled_buf = NULL; MaskBuf * scaled_buf = NULL;
unsigned char *buf; guchar *buf;
PixelRegion srcPR, destPR; PixelRegion srcPR, destPR;
unsigned char * src; guchar * src;
int subsample; gint subsample;
int width, height; gint width, height;
int srcwidth; gint srcwidth;
int i; gint i;
int scale; gint scale;
mask = gimage_get_mask (gimage); mask = gimage_get_mask (gimage);
if ((drawable_width (GIMP_DRAWABLE(mask)) > PREVIEW_WIDTH) || if ((drawable_width (GIMP_DRAWABLE(mask)) > PREVIEW_WIDTH) ||
@ -703,11 +713,13 @@ by_color_select_render (ByColorDialog *bcd,
((float) drawable_height (GIMP_DRAWABLE (mask)) / (float) PREVIEW_HEIGHT)) ((float) drawable_height (GIMP_DRAWABLE (mask)) / (float) PREVIEW_HEIGHT))
{ {
width = PREVIEW_WIDTH; width = PREVIEW_WIDTH;
height = (drawable_height (GIMP_DRAWABLE (mask)) * PREVIEW_WIDTH) / drawable_width (GIMP_DRAWABLE (mask)); height = ((drawable_height (GIMP_DRAWABLE (mask)) * PREVIEW_WIDTH) /
drawable_width (GIMP_DRAWABLE (mask)));
} }
else else
{ {
width = (drawable_width (GIMP_DRAWABLE (mask)) * PREVIEW_HEIGHT) / drawable_height (GIMP_DRAWABLE (mask)); width = ((drawable_width (GIMP_DRAWABLE (mask)) * PREVIEW_HEIGHT) /
drawable_height (GIMP_DRAWABLE (mask)));
height = PREVIEW_HEIGHT; height = PREVIEW_HEIGHT;
} }
@ -726,10 +738,10 @@ by_color_select_render (ByColorDialog *bcd,
gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height); gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height);
/* clear the image buf */ /* clear the image buf */
buf = (unsigned char *) g_malloc (bcd->preview->requisition.width); buf = g_new0 (guchar, bcd->preview->requisition.width);
memset (buf, 0, bcd->preview->requisition.width);
for (i = 0; i < bcd->preview->requisition.height; i++) for (i = 0; i < bcd->preview->requisition.height; i++)
gtk_preview_draw_row (GTK_PREVIEW (bcd->preview), buf, 0, i, bcd->preview->requisition.width); gtk_preview_draw_row (GTK_PREVIEW (bcd->preview), buf,
0, i, bcd->preview->requisition.width);
g_free (buf); g_free (buf);
/* if the mask is empty, no need to scale and update again */ /* if the mask is empty, no need to scale and update again */
@ -800,7 +812,8 @@ by_color_select_draw (ByColorDialog *bcd,
gtk_widget_draw (bcd->preview, NULL); gtk_widget_draw (bcd->preview, NULL);
/* Update the gimage label to reflect the displayed gimage name */ /* Update the gimage label to reflect the displayed gimage name */
gtk_label_set_text (GTK_LABEL (bcd->gimage_name), g_basename (gimage_filename (gimage))); gtk_label_set_text (GTK_LABEL (bcd->gimage_name),
g_basename (gimage_filename (gimage)));
} }
static gint static gint
@ -823,25 +836,25 @@ by_color_select_preview_events (GtkWidget *widget,
static void static void
by_color_select_type_callback (GtkWidget *widget, by_color_select_type_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
if (by_color_dialog) if (by_color_dialog)
by_color_dialog->operation = (long) client_data; by_color_dialog->operation = (long) data;
} }
static void static void
by_color_select_reset_callback (GtkWidget *widget, by_color_select_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data; bcd = (ByColorDialog *) data;
if (!bcd->gimage) if (!bcd->gimage)
return; return;
/* check if the image associated to the mask still exists */ /* check if the image associated to the mask still exists */
if (!drawable_gimage (GIMP_DRAWABLE(gimage_get_mask (bcd->gimage)))) if (!drawable_gimage (GIMP_DRAWABLE (gimage_get_mask (bcd->gimage))))
return; return;
/* reset the mask */ /* reset the mask */
@ -857,16 +870,16 @@ by_color_select_reset_callback (GtkWidget *widget,
static void static void
by_color_select_close_callback (GtkWidget *widget, by_color_select_close_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data; bcd = (ByColorDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell)) if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell); gtk_widget_hide (bcd->shell);
if (bcd->gimage && if (bcd->gimage && gimp_set_have (image_context, bcd->gimage))
gimp_set_have (image_context, bcd->gimage))
{ {
bcd->gimage->by_color_select = FALSE; bcd->gimage->by_color_select = FALSE;
bcd->gimage = NULL; bcd->gimage = NULL;
@ -880,18 +893,19 @@ by_color_select_fuzzy_update (GtkAdjustment *adjustment,
ByColorDialog *bcd; ByColorDialog *bcd;
bcd = (ByColorDialog *) data; bcd = (ByColorDialog *) data;
bcd->threshold = (int) adjustment->value;
bcd->threshold = (gint) (adjustment->value + 0.5);
} }
static void static void
by_color_select_preview_button_press (ByColorDialog *bcd, by_color_select_preview_button_press (ByColorDialog *bcd,
GdkEventButton *bevent) GdkEventButton *bevent)
{ {
int x, y; gint x, y;
int replace, operation; gint replace, operation;
GimpDrawable *drawable; GimpDrawable *drawable;
Tile *tile; Tile *tile;
unsigned char *col; guchar *col;
if (!bcd->gimage) if (!bcd->gimage)
return; return;

View File

@ -22,14 +22,20 @@
#include "gdisplayF.h" #include "gdisplayF.h"
#include "gimage.h" #include "gimage.h"
/* by_color select functions */ Tool * tools_new_by_color_select (void);
void by_color_select (GimpImage *, GimpDrawable *, guchar *, int, void tools_free_by_color_select (Tool *tool);
int, int, int, double, int);
Tool * tools_new_by_color_select (void); void by_color_select_initialize (GDisplay *gdisp);
void tools_free_by_color_select (Tool *); void by_color_select_initialize_by_image (GImage *gimage);
void by_color_select_initialize (GDisplay *); void by_color_select (GimpImage *gimage,
void by_color_select_initialize_by_image (GImage *); GimpDrawable *drawable,
guchar *color,
gint threshold,
gint op,
gint antialias,
gint feather,
gdouble feather_radius,
gint sample_merged);
#endif /* __BY_COLOR_SELECT_H__ */ #endif /* __BY_COLOR_SELECT_H__ */

View File

@ -15,21 +15,13 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "color_balance.h" #include "color_balance.h"
#include "color_transfer.h" #include "color_transfer.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimpui.h" #include "gimpui.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
static void color_balance_control (Tool *, ToolAction, gpointer); static void color_balance_control (Tool *, ToolAction, gpointer);
static ColorBalanceDialog * color_balance_new_dialog (void); static ColorBalanceDialog * color_balance_dialog_new (void);
static void color_balance_update (ColorBalanceDialog *, int); static void color_balance_update (ColorBalanceDialog *, int);
static void color_balance_preview (ColorBalanceDialog *); static void color_balance_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer); static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer); static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer); static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer); static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer); static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer); static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */ /* The color balance dialog */
if (!color_balance_dialog) if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog (); color_balance_dialog = color_balance_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell)) if (!GTK_WIDGET_VISIBLE (color_balance_dialog->shell))
gtk_widget_show (color_balance_dialog->shell); gtk_widget_show (color_balance_dialog->shell);
/* Initialize dialog fields */
color_balance_dialog->image_map = NULL;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
color_balance_dialog->cyan_red[i] = 0.0; color_balance_dialog->cyan_red[i] = 0.0;
color_balance_dialog->magenta_green[i] = 0.0; color_balance_dialog->magenta_green[i] = 0.0;
color_balance_dialog->yellow_blue[i] = 0.0; color_balance_dialog->yellow_blue[i] = 0.0;
} }
color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage); color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = color_balance_dialog->image_map =
image_map_create (gdisp, color_balance_dialog->drawable); image_map_create (gdisp, color_balance_dialog->drawable);
@ -236,13 +226,12 @@ color_balance_initialize (GDisplay *gdisp)
color_balance_update (color_balance_dialog, ALL); color_balance_update (color_balance_dialog, ALL);
} }
/**************************/ /**************************/
/* Color Balance dialog */ /* Color Balance dialog */
/**************************/ /**************************/
static ColorBalanceDialog * static ColorBalanceDialog *
color_balance_new_dialog (void) color_balance_dialog_new (void)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
GtkWidget *vbox; GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights") N_("Highlights")
}; };
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1); cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE; cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE; cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback, _("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE, cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback, _("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Color Levels:")); label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label); gtk_widget_show (label);
/* cyan-red spinbutton */ /* cyan-red spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->cyan_red_data = GTK_ADJUSTMENT (data); cbd->cyan_red_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->cyan_red_data, 1.0, 0);
@ -313,7 +297,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* magenta-green spinbutton */ /* magenta-green spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->magenta_green_data = GTK_ADJUSTMENT (data); cbd->magenta_green_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->magenta_green_data, 1.0, 0);
@ -322,7 +306,7 @@ color_balance_new_dialog (void)
gtk_widget_show (spinbutton); gtk_widget_show (spinbutton);
/* yellow-blue spinbutton */ /* yellow-blue spinbutton */
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 10.0, 0.0);
cbd->yellow_blue_data = GTK_ADJUSTMENT (data); cbd->yellow_blue_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0); spinbutton = gtk_spin_button_new (cbd->yellow_blue_data, 1.0, 0);
@ -334,22 +318,22 @@ color_balance_new_dialog (void)
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the cyan-red scale widget */ /* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan")); start_label = gtk_label_new (_("Cyan"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->cyan_red_data); slider = gtk_hscale_new (cbd->cyan_red_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->cyan_red_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update), GTK_SIGNAL_FUNC (color_balance_cr_adjustment_update),
cbd); cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red")); end_label = gtk_label_new (_("Red"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta")); start_label = gtk_label_new (_("Magenta"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->magenta_green_data); slider = gtk_hscale_new (cbd->magenta_green_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->magenta_green_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update), GTK_SIGNAL_FUNC (color_balance_mg_adjustment_update),
cbd); cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green")); end_label = gtk_label_new (_("Green"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow")); start_label = gtk_label_new (_("Yellow"));
gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (start_label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), start_label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
slider = gtk_hscale_new (cbd->yellow_blue_data); slider = gtk_hscale_new (cbd->yellow_blue_data);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
2, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 2, 3);
gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed", gtk_signal_connect (GTK_OBJECT (cbd->yellow_blue_data), "value_changed",
GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update), GTK_SIGNAL_FUNC (color_balance_yb_adjustment_update),
cbd); cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue")); end_label = gtk_label_new (_("Blue"));
gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0); gtk_misc_set_alignment (GTK_MISC (end_label), 0.0, 1.0);
gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3, gtk_table_attach (GTK_TABLE (table), end_label, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (start_label); gtk_widget_show (start_label);
gtk_widget_show (end_label); gtk_widget_show (end_label);
gtk_widget_show (slider); gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */ gtk_widget_show (table);
hbox = gtk_hbox_new (TRUE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
/* Horizontal box for application mode */ /* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4); hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button = radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i])); gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_box_pack_start (GTK_BOX (hbox), radio_button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), radio_button, TRUE, FALSE, 0);
gtk_object_set_user_data (GTK_OBJECT (radio_button), (gpointer) i);
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
GTK_SIGNAL_FUNC (appl_mode_callbacks[i]), GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd); cbd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (hbox);
/* Horizontal box for preview and preserve luminosity toggle buttons */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preserve luminosity toggle */
toggle = gtk_check_button_new_with_label (_("Preserve Luminosity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
cbd->preserve_luminosity);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preserve_update),
cbd);
gtk_widget_show (toggle);
/* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cbd->preview);
gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (color_balance_preview_update),
cbd);
gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (cbd->shell); gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd) color_balance_preview (ColorBalanceDialog *cbd)
{ {
if (!cbd->image_map) if (!cbd->image_map)
g_message ("color_balance_preview(): No image map"); {
g_message ("color_balance_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
color_balance_create_lookup_tables (cbd); color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void
color_balance_reset_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->cyan_red[cbd->application_mode] = 0.0;
cbd->magenta_green[cbd->application_mode] = 0.0;
cbd->yellow_blue[cbd->application_mode] = 0.0;
color_balance_update (cbd, ALL);
if (cbd->preview)
color_balance_preview (cbd);
}
static void static void
color_balance_ok_callback (GtkWidget *widget, color_balance_ok_callback (GtkWidget *widget,
gpointer data) gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
} }
static void static void
color_balance_shadows_callback (GtkWidget *widget, color_balance_range_callback (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ColorBalanceDialog *cbd; ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data; cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS; range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
color_balance_update (cbd, ALL); cbd->application_mode = range;
}
static void
color_balance_midtones_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = MIDTONES;
color_balance_update (cbd, ALL);
}
static void
color_balance_highlights_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = HIGHLIGHTS;
color_balance_update (cbd, ALL); color_balance_update (cbd, ALL);
} }

View File

@ -57,8 +57,6 @@ struct _ColorBalanceDialog
TransferMode application_mode; TransferMode application_mode;
}; };
/* color balance functions */
Tool * tools_new_color_balance (void); Tool * tools_new_color_balance (void);
void tools_free_color_balance (Tool *tool); void tools_free_color_balance (Tool *tool);

View File

@ -15,43 +15,36 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "appenv.h" #include "appenv.h"
#include "buildmenu.h" #include "buildmenu.h"
#include "colormaps.h" #include "colormaps.h"
#include "cursorutil.h" #include "cursorutil.h"
#include "drawable.h" #include "drawable.h"
#include "general.h"
#include "gdisplay.h" #include "gdisplay.h"
#include "gimphistogram.h" #include "gimphistogram.h"
#include "gimpui.h" #include "gimpui.h"
#include "interface.h"
#include "curves.h" #include "curves.h"
#include "gimplut.h" #include "gimplut.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h" #include "libgimp/gimpmath.h"
#define GRAPH 0x1 #define GRAPH 0x1
#define XRANGE_TOP 0x2 #define XRANGE_TOP 0x2
#define XRANGE_BOTTOM 0x4 #define XRANGE_BOTTOM 0x4
#define YRANGE 0x8 #define YRANGE 0x8
#define DRAW 0x10 #define DRAW 0x10
#define ALL 0xFF #define ALL 0xFF
/* NB: take care when changing these values: make sure the curve[] array in /* NB: take care when changing these values: make sure the curve[] array in
* curves.h is large enough. * curves.h is large enough.
*/ */
#define GRAPH_WIDTH 256 #define GRAPH_WIDTH 256
#define GRAPH_HEIGHT 256 #define GRAPH_HEIGHT 256
#define XRANGE_WIDTH 256 #define XRANGE_WIDTH 256
#define XRANGE_HEIGHT 16 #define XRANGE_HEIGHT 16
#define YRANGE_WIDTH 16 #define YRANGE_WIDTH 16
#define YRANGE_HEIGHT 256 #define YRANGE_HEIGHT 256
#define RADIUS 3 #define RADIUS 3
#define MIN_DISTANCE 8 #define MIN_DISTANCE 8
@ -69,13 +62,13 @@
/* the curves structures */ /* the curves structures */
typedef struct _Curves Curves; typedef struct _Curves Curves;
struct _Curves struct _Curves
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef double CRMatrix[4][4]; typedef gdouble CRMatrix[4][4];
/* the curves tool options */ /* the curves tool options */
static ToolOptions * curves_options = NULL; static ToolOptions * curves_options = NULL;
@ -99,18 +92,21 @@ static void curves_button_release (Tool *, GdkEventButton *, gpointer);
static void curves_motion (Tool *, GdkEventMotion *, gpointer); static void curves_motion (Tool *, GdkEventMotion *, gpointer);
static void curves_control (Tool *, ToolAction, gpointer); static void curves_control (Tool *, ToolAction, gpointer);
static CurvesDialog * curves_new_dialog (void); static CurvesDialog * curves_dialog_new (void);
static void curves_update (CurvesDialog *, int); static void curves_update (CurvesDialog *, int);
static void curves_plot_curve (CurvesDialog *, int, int, int, int); static void curves_plot_curve (CurvesDialog *, int, int, int, int);
static void curves_preview (CurvesDialog *); static void curves_preview (CurvesDialog *);
static void curves_value_callback (GtkWidget *, gpointer); static void curves_value_callback (GtkWidget *, gpointer);
static void curves_red_callback (GtkWidget *, gpointer); static void curves_red_callback (GtkWidget *, gpointer);
static void curves_green_callback (GtkWidget *, gpointer); static void curves_green_callback (GtkWidget *, gpointer);
static void curves_blue_callback (GtkWidget *, gpointer); static void curves_blue_callback (GtkWidget *, gpointer);
static void curves_alpha_callback (GtkWidget *, gpointer); static void curves_alpha_callback (GtkWidget *, gpointer);
static void curves_smooth_callback (GtkWidget *, gpointer); static void curves_smooth_callback (GtkWidget *, gpointer);
static void curves_free_callback (GtkWidget *, gpointer); static void curves_free_callback (GtkWidget *, gpointer);
static void curves_reset_callback (GtkWidget *, gpointer); static void curves_reset_callback (GtkWidget *, gpointer);
static void curves_ok_callback (GtkWidget *, gpointer); static void curves_ok_callback (GtkWidget *, gpointer);
static void curves_cancel_callback (GtkWidget *, gpointer); static void curves_cancel_callback (GtkWidget *, gpointer);
@ -120,12 +116,13 @@ static gint curves_yrange_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *); static gint curves_graph_events (GtkWidget *, GdkEvent *, CurvesDialog *);
static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix); static void curves_CR_compose (CRMatrix, CRMatrix, CRMatrix);
/* curves machinery */ /* curves machinery */
float float
curves_lut_func (CurvesDialog *cd, curves_lut_func (CurvesDialog *cd,
int nchannels, int channel, float value) gint nchannels,
gint channel,
gfloat value)
{ {
float f; float f;
int index; int index;
@ -188,9 +185,9 @@ curves_colour_update (Tool *tool,
if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y))) if (!(color = image_map_get_color_at(curves_dialog->image_map, x, y)))
return; return;
sample_type = gimp_drawable_type(drawable); sample_type = gimp_drawable_type (drawable);
is_indexed = gimp_drawable_is_indexed (drawable); is_indexed = gimp_drawable_is_indexed (drawable);
has_alpha = TYPE_HAS_ALPHA(sample_type); has_alpha = TYPE_HAS_ALPHA (sample_type);
curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX]; curves_dialog->col_value[HISTOGRAM_RED] = color[RED_PIX];
curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX]; curves_dialog->col_value[HISTOGRAM_GREEN] = color[GREEN_PIX];
@ -207,11 +204,14 @@ curves_colour_update (Tool *tool,
maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]); maxval = MAXIMUM(color[RED_PIX],color[GREEN_PIX]);
curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]); curves_dialog->col_value[HISTOGRAM_VALUE] = MAXIMUM(maxval,color[BLUE_PIX]);
g_free(color); g_free (color);
} }
static void static void
curves_add_point(GimpDrawable * drawable,gint x, gint y,gint cchan) curves_add_point (GimpDrawable *drawable,
gint x,
gint y,
gint cchan)
{ {
/* Add point onto the curve */ /* Add point onto the curve */
int closest_point = 0; int closest_point = 0;
@ -301,21 +301,21 @@ curves_button_release (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
if(bevent->state & GDK_SHIFT_MASK) if(bevent->state & GDK_SHIFT_MASK)
{ {
curves_add_point(drawable,x,y,curves_dialog->channel); curves_add_point (drawable, x, y, curves_dialog->channel);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
else if(bevent->state & GDK_CONTROL_MASK) else if(bevent->state & GDK_CONTROL_MASK)
{ {
curves_add_point(drawable,x,y,HISTOGRAM_VALUE); curves_add_point (drawable, x, y, HISTOGRAM_VALUE);
curves_add_point(drawable,x,y,HISTOGRAM_RED); curves_add_point (drawable, x, y, HISTOGRAM_RED);
curves_add_point(drawable,x,y,HISTOGRAM_GREEN); curves_add_point (drawable, x, y, HISTOGRAM_GREEN);
curves_add_point(drawable,x,y,HISTOGRAM_BLUE); curves_add_point (drawable, x, y, HISTOGRAM_BLUE);
curves_add_point(drawable,x,y,HISTOGRAM_ALPHA); curves_add_point (drawable, x, y, HISTOGRAM_ALPHA);
curves_calculate_curve(curves_dialog); curves_calculate_curve (curves_dialog);
} }
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
@ -338,7 +338,7 @@ curves_motion (Tool *tool,
return; return;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE); gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE);
curves_colour_update(tool,gdisp,drawable,x,y); curves_colour_update (tool, gdisp, drawable, x, y);
curves_update (curves_dialog, GRAPH | DRAW); curves_update (curves_dialog, GRAPH | DRAW);
} }
@ -366,7 +366,7 @@ curves_control (Tool *tool,
} }
Tool * Tool *
tools_new_curves () tools_new_curves (void)
{ {
Tool * tool; Tool * tool;
Curves * private; Curves * private;
@ -397,15 +397,15 @@ tools_new_curves ()
void void
tools_free_curves (Tool *tool) tools_free_curves (Tool *tool)
{ {
Curves * _curves; Curves * private;
_curves = (Curves *) tool->private; private = (Curves *) tool->private;
/* Close the color select dialog */ /* Close the color select dialog */
if (curves_dialog) if (curves_dialog)
curves_cancel_callback (NULL, (gpointer) curves_dialog); curves_cancel_callback (NULL, (gpointer) curves_dialog);
g_free (_curves); g_free (private);
} }
static MenuItem channel_items[] = static MenuItem channel_items[] =
@ -421,7 +421,7 @@ static MenuItem channel_items[] =
void void
curves_initialize (GDisplay *gdisp) curves_initialize (GDisplay *gdisp)
{ {
int i, j; gint i, j;
if (drawable_indexed (gimage_active_drawable (gdisp->gimage))) if (drawable_indexed (gimage_active_drawable (gdisp->gimage)))
{ {
@ -431,7 +431,10 @@ curves_initialize (GDisplay *gdisp)
/* The curves dialog */ /* The curves dialog */
if (!curves_dialog) if (!curves_dialog)
curves_dialog = curves_new_dialog (); curves_dialog = curves_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (curves_dialog->shell))
gtk_widget_show (curves_dialog->shell);
/* Initialize the values */ /* Initialize the values */
curves_dialog->channel = HISTOGRAM_VALUE; curves_dialog->channel = HISTOGRAM_VALUE;
@ -454,22 +457,22 @@ curves_initialize (GDisplay *gdisp)
} }
curves_dialog->drawable = gimage_active_drawable (gdisp->gimage); curves_dialog->drawable = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color ( (curves_dialog->drawable)); curves_dialog->color = drawable_color (curves_dialog->drawable);
curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable); curves_dialog->image_map = image_map_create (gdisp, curves_dialog->drawable);
/* check for alpha channel */ /* check for alpha channel */
if (drawable_has_alpha ( (curves_dialog->drawable))) if (drawable_has_alpha (curves_dialog->drawable))
gtk_widget_set_sensitive( channel_items[4].widget, TRUE); gtk_widget_set_sensitive (channel_items[4].widget, TRUE);
else else
gtk_widget_set_sensitive( channel_items[4].widget, FALSE); gtk_widget_set_sensitive (channel_items[4].widget, FALSE);
/* hide or show the channel menu based on image type */ /* hide or show the channel menu based on image type */
if (curves_dialog->color) if (curves_dialog->color)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, TRUE); gtk_widget_set_sensitive (channel_items[i].widget, TRUE);
else else
for (i = 1; i < 4; i++) for (i = 1; i < 4; i++)
gtk_widget_set_sensitive( channel_items[i].widget, FALSE); gtk_widget_set_sensitive (channel_items[i].widget, FALSE);
/* set the current selection */ /* set the current selection */
gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0); gtk_option_menu_set_history (GTK_OPTION_MENU (curves_dialog->channel_menu), 0);
@ -481,7 +484,7 @@ curves_initialize (GDisplay *gdisp)
} }
void void
curves_free () curves_free (void)
{ {
if (curves_dialog) if (curves_dialog)
{ {
@ -506,7 +509,7 @@ curves_free ()
/*******************/ /*******************/
static CurvesDialog * static CurvesDialog *
curves_new_dialog () curves_dialog_new (void)
{ {
CurvesDialog *cd; CurvesDialog *cd;
GtkWidget *vbox; GtkWidget *vbox;
@ -528,19 +531,20 @@ curves_new_dialog ()
}; };
cd = g_new (CurvesDialog, 1); cd = g_new (CurvesDialog, 1);
cd->cursor_ind_height = cd->cursor_ind_width = -1; cd->cursor_ind_height = -1;
cd->preview = TRUE; cd->cursor_ind_width = -1;
cd->curve_type = SMOOTH; cd->preview = TRUE;
cd->pixmap = NULL; cd->curve_type = SMOOTH;
cd->channel = HISTOGRAM_VALUE; cd->pixmap = NULL;
cd->channel = HISTOGRAM_VALUE;
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
for (j = 0; j < 256; j++) for (j = 0; j < 256; j++)
cd->curve[i][j] = j; cd->curve[i][j] = j;
for(i = 0; i < (sizeof(cd->col_value)/sizeof(cd->col_value[0])); i++) for (i = 0; i < (sizeof (cd->col_value) / sizeof (cd->col_value[0])); i++)
cd->col_value[i] = 0; cd->col_value[i] = 0;
cd->lut = gimp_lut_new(); cd->lut = gimp_lut_new ();
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
channel_items [i].user_data = (gpointer) cd; channel_items [i].user_data = (gpointer) cd;
@ -562,15 +566,15 @@ curves_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cd->shell)->vbox), vbox);
/* The option menu for selecting channels */ /* The option menu for selecting channels */
channel_hbox = gtk_hbox_new (FALSE, 2); channel_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), channel_hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Modify Curves for Channel: ")); label = gtk_label_new (_("Modify Curves for Channel:"));
gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (channel_hbox), label, FALSE, FALSE, 0);
menu = build_menu (channel_items, NULL); menu = build_menu (channel_items, NULL);
@ -584,7 +588,8 @@ curves_new_dialog ()
/* The table for the yrange and the graph */ /* The table for the yrange and the graph */
table = gtk_table_new (2, 2, FALSE); table = gtk_table_new (2, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 2);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* The range drawing area */ /* The range drawing area */
@ -596,10 +601,12 @@ curves_new_dialog ()
cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->yrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->yrange), YRANGE_WIDTH, YRANGE_HEIGHT);
gtk_widget_set_events (cd->yrange, RANGE_MASK); gtk_widget_set_events (cd->yrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
(GtkSignalFunc) curves_yrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->yrange); gtk_container_add (GTK_CONTAINER (frame), cd->yrange);
gtk_signal_connect (GTK_OBJECT (cd->yrange), "event",
GTK_SIGNAL_FUNC (curves_yrange_events),
cd);
gtk_widget_show (cd->yrange); gtk_widget_show (cd->yrange);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -607,18 +614,20 @@ curves_new_dialog ()
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, 0, 0);
cd->graph = gtk_drawing_area_new (); cd->graph = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph), gtk_drawing_area_size (GTK_DRAWING_AREA (cd->graph),
GRAPH_WIDTH + RADIUS * 2, GRAPH_WIDTH + RADIUS * 2,
GRAPH_HEIGHT + RADIUS * 2); GRAPH_HEIGHT + RADIUS * 2);
gtk_widget_set_events (cd->graph, GRAPH_MASK); gtk_widget_set_events (cd->graph, GRAPH_MASK);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
(GtkSignalFunc) curves_graph_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->graph); gtk_container_add (GTK_CONTAINER (frame), cd->graph);
gtk_signal_connect (GTK_OBJECT (cd->graph), "event",
GTK_SIGNAL_FUNC (curves_graph_events),
cd);
gtk_widget_show (cd->graph); gtk_widget_show (cd->graph);
gtk_widget_show (frame); gtk_widget_show (frame);
@ -631,20 +640,22 @@ curves_new_dialog ()
cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR); cd->xrange = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT); gtk_preview_size (GTK_PREVIEW (cd->xrange), XRANGE_WIDTH, XRANGE_HEIGHT);
gtk_widget_set_events (cd->xrange, RANGE_MASK); gtk_widget_set_events (cd->xrange, RANGE_MASK);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
(GtkSignalFunc) curves_xrange_events,
cd);
gtk_container_add (GTK_CONTAINER (frame), cd->xrange); gtk_container_add (GTK_CONTAINER (frame), cd->xrange);
gtk_signal_connect (GTK_OBJECT (cd->xrange), "event",
GTK_SIGNAL_FUNC (curves_xrange_events),
cd);
gtk_widget_show (cd->xrange); gtk_widget_show (cd->xrange);
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (table); gtk_widget_show (table);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The option menu for selecting the drawing method */ /* The option menu for selecting the drawing method */
label = gtk_label_new (_("Curve Type: ")); label = gtk_label_new (_("Curve Type:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
menu = build_menu (curve_type_items, NULL); menu = build_menu (curve_type_items, NULL);
@ -659,12 +670,12 @@ curves_new_dialog ()
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), cd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) curves_preview_update, GTK_SIGNAL_FUNC (curves_preview_update),
cd); cd);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
@ -674,32 +685,32 @@ curves_new_dialog ()
} }
static void static void
curve_print_loc(CurvesDialog *cd, curve_print_loc (CurvesDialog *cd,
gint xpos, gint xpos,
gint ypos) gint ypos)
{ {
char buf[32]; char buf[32];
gint width; gint width;
gint ascent; gint ascent;
gint descent; gint descent;
if(cd->cursor_ind_width < 0) if (cd->cursor_ind_width < 0)
{ {
/* Calc max extents */ /* Calc max extents */
gdk_string_extents(cd->graph->style->font, gdk_string_extents (cd->graph->style->font,
"x:888 y:888", "x:888 y:888",
NULL, NULL,
NULL, NULL,
&width, &width,
&ascent, &ascent,
&descent); &descent);
cd->cursor_ind_width = width; cd->cursor_ind_width = width;
cd->cursor_ind_height = ascent + descent; cd->cursor_ind_height = ascent + descent;
cd->cursor_ind_ascent = ascent; cd->cursor_ind_ascent = ascent;
} }
if(xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255) if (xpos >= 0 && xpos <= 255 && ypos >=0 && ypos <= 255)
{ {
g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos); g_snprintf (buf, sizeof (buf), "x:%d y:%d",xpos,ypos);
@ -730,53 +741,54 @@ curves_update (CurvesDialog *cd,
int update) int update)
{ {
GdkRectangle area; GdkRectangle area;
int i, j; gint i, j;
char buf[32]; gchar buf[32];
gint offset; gint offset;
if (update & XRANGE_TOP) if (update & XRANGE_TOP)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
for (i = 0; i < XRANGE_HEIGHT / 2; i++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH ; j++) for (j = 0; j < XRANGE_WIDTH ; j++)
{ {
buf[j*3+0] = cd->curve[cd->channel][j]; buf[j*3+0] = cd->curve[cd->channel][j];
buf[j*3+1] = cd->curve[cd->channel][j]; buf[j*3+1] = cd->curve[cd->channel][j];
buf[j*3+2] = cd->curve[cd->channel][j]; buf[j*3+2] = cd->curve[cd->channel][j];
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH); buf, 0, i, XRANGE_WIDTH);
} }
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
{
for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
for (j = 0; j < XRANGE_WIDTH; j++) for (i = 0; i < XRANGE_HEIGHT / 2; i++)
{ {
buf[j*3+0] = cd->curve[HISTOGRAM_RED][j]; for (j = 0; j < XRANGE_WIDTH; j++)
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j]; {
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j]; buf[j*3+0] = cd->curve[HISTOGRAM_RED][j];
buf[j*3+1] = cd->curve[HISTOGRAM_GREEN][j];
buf[j*3+2] = cd->curve[HISTOGRAM_BLUE][j];
}
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange),
buf, 0, i, XRANGE_WIDTH);
} }
gtk_preview_draw_row (GTK_PREVIEW (cd->xrange), break;
buf, 0, i, XRANGE_WIDTH);
} }
break;
}
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} /* end switch */ }
if (update & DRAW) if (update & DRAW)
{ {
@ -789,7 +801,7 @@ curves_update (CurvesDialog *cd,
} }
if (update & XRANGE_BOTTOM) if (update & XRANGE_BOTTOM)
{ {
unsigned char buf[XRANGE_WIDTH * 3]; guchar buf[XRANGE_WIDTH * 3];
for (i = 0; i < XRANGE_WIDTH; i++) for (i = 0; i < XRANGE_WIDTH; i++)
{ {
@ -812,35 +824,36 @@ curves_update (CurvesDialog *cd,
} }
if (update & YRANGE) if (update & YRANGE)
{ {
unsigned char buf[YRANGE_WIDTH * 3]; guchar buf[YRANGE_WIDTH * 3];
unsigned char pix[3]; guchar pix[3];
for (i = 0; i < YRANGE_HEIGHT; i++) for (i = 0; i < YRANGE_HEIGHT; i++)
{ {
switch (cd->channel) { switch (cd->channel)
case HISTOGRAM_VALUE: {
case HISTOGRAM_ALPHA: case HISTOGRAM_VALUE:
case HISTOGRAM_ALPHA:
pix[0] = pix[1] = pix[2] = (255 - i); pix[0] = pix[1] = pix[2] = (255 - i);
break; break;
case HISTOGRAM_RED: case HISTOGRAM_RED:
case HISTOGRAM_GREEN: case HISTOGRAM_GREEN:
case HISTOGRAM_BLUE: case HISTOGRAM_BLUE:
pix[0] = pix[1] = pix[2] = 0; pix[0] = pix[1] = pix[2] = 0;
pix[cd->channel - 1] = (255 - i); pix[cd->channel - 1] = (255 - i);
break; break;
default: default:
g_warning ("unknown channel type %d, can't happen!?!?", g_warning ("unknown channel type %d, can't happen!?!?",
cd->channel); cd->channel);
break; break;
} }
for (j = 0; j < YRANGE_WIDTH * 3; j++) for (j = 0; j < YRANGE_WIDTH * 3; j++)
buf[j] = pix[j%3]; buf[j] = pix[j%3];
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange), buf, 0, i, YRANGE_WIDTH);
gtk_preview_draw_row (GTK_PREVIEW (cd->yrange),
buf, 0, i, YRANGE_WIDTH);
} }
if (update & DRAW) if (update & DRAW)
@ -852,7 +865,8 @@ curves_update (CurvesDialog *cd,
/* Clear the pixmap */ /* Clear the pixmap */
gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL], gdk_draw_rectangle (cd->pixmap, cd->graph->style->bg_gc[GTK_STATE_NORMAL],
TRUE, 0, 0, GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2); TRUE, 0, 0,
GRAPH_WIDTH + RADIUS * 2, GRAPH_HEIGHT + RADIUS * 2);
/* Draw the grid lines */ /* Draw the grid lines */
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
@ -885,20 +899,20 @@ curves_update (CurvesDialog *cd,
} }
/* draw the colour line */ /* draw the colour line */
gdk_draw_line(cd->pixmap, cd->graph->style->black_gc, gdk_draw_line (cd->pixmap, cd->graph->style->black_gc,
cd->col_value[cd->channel]+RADIUS,RADIUS, cd->col_value[cd->channel]+RADIUS,RADIUS,
cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS); cd->col_value[cd->channel]+RADIUS,GRAPH_HEIGHT + RADIUS);
/* and xpos indicator */ /* and xpos indicator */
g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]); g_snprintf (buf, sizeof (buf), "x:%d",cd->col_value[cd->channel]);
if((cd->col_value[cd->channel]+RADIUS) < 127) if ((cd->col_value[cd->channel]+RADIUS) < 127)
{ {
offset = RADIUS + 4; offset = RADIUS + 4;
} }
else else
{ {
offset = -gdk_string_width(cd->graph->style->font,buf) - 2; offset = - gdk_string_width (cd->graph->style->font,buf) - 2;
} }
gdk_draw_string (cd->pixmap, gdk_draw_string (cd->pixmap,
@ -916,10 +930,10 @@ curves_update (CurvesDialog *cd,
static void static void
curves_plot_curve (CurvesDialog *cd, curves_plot_curve (CurvesDialog *cd,
int p1, gint p1,
int p2, gint p2,
int p3, gint p3,
int p4) gint p4)
{ {
CRMatrix geometry; CRMatrix geometry;
CRMatrix tmp1, tmp2; CRMatrix tmp1, tmp2;
@ -1045,8 +1059,8 @@ curves_calculate_curve (CurvesDialog *cd)
} }
break; break;
} }
gimp_lut_setup(cd->lut, (GimpLutFunc) curves_lut_func, gimp_lut_setup (cd->lut, (GimpLutFunc) curves_lut_func,
(void *) cd, gimp_drawable_bytes(cd->drawable)); (void *) cd, gimp_drawable_bytes (cd->drawable));
} }
@ -1054,23 +1068,24 @@ static void
curves_preview (CurvesDialog *cd) curves_preview (CurvesDialog *cd)
{ {
if (!cd->image_map) if (!cd->image_map)
g_message ("curves_preview(): No image map"); {
g_message ("curves_preview(): No image map");
active_tool->preserve = TRUE; /* Going to dirty the display... */ return;
}
active_tool->preserve = TRUE;
image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (cd->image_map, (ImageMapApplyFunc)gimp_lut_process_2,
(void *) cd->lut); (void *) cd->lut);
active_tool->preserve = FALSE;
active_tool->preserve = FALSE; /* All done */
} }
static void static void
curves_value_callback (GtkWidget *w, curves_value_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_VALUE) if (cd->channel != HISTOGRAM_VALUE)
{ {
@ -1080,12 +1095,12 @@ curves_value_callback (GtkWidget *w,
} }
static void static void
curves_red_callback (GtkWidget *w, curves_red_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_RED) if (cd->channel != HISTOGRAM_RED)
{ {
@ -1095,12 +1110,12 @@ curves_red_callback (GtkWidget *w,
} }
static void static void
curves_green_callback (GtkWidget *w, curves_green_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_GREEN) if (cd->channel != HISTOGRAM_GREEN)
{ {
@ -1110,12 +1125,12 @@ curves_green_callback (GtkWidget *w,
} }
static void static void
curves_blue_callback (GtkWidget *w, curves_blue_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_BLUE) if (cd->channel != HISTOGRAM_BLUE)
{ {
@ -1125,12 +1140,12 @@ curves_blue_callback (GtkWidget *w,
} }
static void static void
curves_alpha_callback (GtkWidget *w, curves_alpha_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->channel != HISTOGRAM_ALPHA) if (cd->channel != HISTOGRAM_ALPHA)
{ {
@ -1140,14 +1155,14 @@ curves_alpha_callback (GtkWidget *w,
} }
static void static void
curves_smooth_callback (GtkWidget *w, curves_smooth_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
gint32 index; gint32 index;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != SMOOTH) if (cd->curve_type != SMOOTH)
{ {
@ -1170,12 +1185,12 @@ curves_smooth_callback (GtkWidget *w,
} }
static void static void
curves_free_callback (GtkWidget *w, curves_free_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (cd->curve_type != GFREE) if (cd->curve_type != GFREE)
{ {
@ -1190,12 +1205,12 @@ curves_free_callback (GtkWidget *w,
static void static void
curves_reset_callback (GtkWidget *widget, curves_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
int i; int i;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
/* Initialize the values */ /* Initialize the values */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -1214,17 +1229,18 @@ curves_reset_callback (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
} }
static void static void
curves_ok_callback (GtkWidget *widget, curves_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1248,11 +1264,12 @@ curves_ok_callback (GtkWidget *widget,
static void static void
curves_cancel_callback (GtkWidget *widget, curves_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
CurvesDialog *cd; CurvesDialog *cd;
cd = (CurvesDialog *) client_data; cd = (CurvesDialog *) data;
if (GTK_WIDGET_VISIBLE (cd->shell)) if (GTK_WIDGET_VISIBLE (cd->shell))
gtk_widget_hide (cd->shell); gtk_widget_hide (cd->shell);
@ -1373,7 +1390,7 @@ curves_graph_events (GtkWidget *widget,
curves_calculate_curve (cd); curves_calculate_curve (cd);
curves_update (cd, GRAPH | XRANGE_TOP | DRAW); curves_update (cd, GRAPH | XRANGE_TOP | DRAW);
gtk_grab_add(widget); gtk_grab_add (widget);
break; break;
@ -1384,7 +1401,7 @@ curves_graph_events (GtkWidget *widget,
if (cd->preview) if (cd->preview)
curves_preview (cd); curves_preview (cd);
gtk_grab_remove(widget); gtk_grab_remove (widget);
break; break;
@ -1527,7 +1544,7 @@ curves_CR_compose (CRMatrix a,
CRMatrix b, CRMatrix b,
CRMatrix ab) CRMatrix ab)
{ {
int i, j; gint i, j;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {

View File

@ -23,47 +23,53 @@
#include "lut_funcs.h" #include "lut_funcs.h"
#include "tools.h" #include "tools.h"
#define SMOOTH 0 #define SMOOTH 0
#define GFREE 1 #define GFREE 1
typedef struct _CurvesDialog CurvesDialog; typedef struct _CurvesDialog CurvesDialog;
struct _CurvesDialog struct _CurvesDialog
{ {
GtkWidget * shell; GtkWidget *shell;
GtkWidget * channel_menu;
GtkWidget * xrange;
GtkWidget * yrange;
GtkWidget * graph;
GdkPixmap * pixmap;
GimpDrawable * drawable;
ImageMap image_map;
int color;
int channel;
gint preview;
int grab_point; GtkWidget *channel_menu;
int last; GtkWidget *xrange;
int leftmost; GtkWidget *yrange;
int rightmost; GtkWidget *graph;
int curve_type; GdkPixmap *pixmap;
int points[5][17][2];
unsigned char curve[5][256]; GimpDrawable *drawable;
int col_value[5]; ImageMap image_map;
gint color;
gint channel;
gboolean preview;
gint grab_point;
gint last;
gint leftmost;
gint rightmost;
gint curve_type;
gint points[5][17][2];
guchar curve[5][256];
gint col_value[5];
int cursor_ind_height; gint cursor_ind_height;
int cursor_ind_width; gint cursor_ind_width;
int cursor_ind_ascent; gint cursor_ind_ascent;
GimpLut *lut; GimpLut *lut;
}; };
/* hue-saturation functions */ Tool * tools_new_curves (void);
Tool * tools_new_curves (void); void tools_free_curves (Tool *tool);
void tools_free_curves (Tool *);
void curves_initialize (GDisplay *); void curves_initialize (GDisplay *gdisp);
void curves_free (void); void curves_free (void);
float curves_lut_func (CurvesDialog *, int, int, float); float curves_lut_func (CurvesDialog *cd,
void curves_calculate_curve (CurvesDialog *); gint nchannels,
gint channel,
gfloat value);
void curves_calculate_curve (CurvesDialog *cd);
#endif /* __CURVES_H__ */ #endif /* __CURVES_H__ */

View File

@ -17,7 +17,6 @@
*/ */
#include "config.h" #include "config.h"
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "buildmenu.h" #include "buildmenu.h"
#include "drawable.h" #include "drawable.h"
@ -25,9 +24,9 @@
#include "gimpui.h" #include "gimpui.h"
#include "histogram_tool.h" #include "histogram_tool.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
#define TEXT_WIDTH 45 #define TEXT_WIDTH 45
#define GRADIENT_HEIGHT 15 #define GRADIENT_HEIGHT 15
@ -35,23 +34,22 @@
/* the histogram structures */ /* the histogram structures */
typedef struct _HistogramTool HistogramTool; typedef struct _HistogramTool HistogramTool;
struct _HistogramTool struct _HistogramTool
{ {
gint x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the histogram tool options */ /* the histogram tool options */
static ToolOptions * histogram_tool_options = NULL; static ToolOptions * histogram_tool_options = NULL;
/* the histogram tool dialog */ /* the histogram tool dialog */
static HistogramToolDialog * histogram_tool_dialog = NULL; static HistogramToolDialog * histogram_tool_dialog = NULL;
/* histogram_tool action functions */ /* histogram_tool action functions */
static void histogram_tool_control (Tool *, ToolAction, gpointer); static void histogram_tool_control (Tool *, ToolAction, gpointer);
static HistogramToolDialog * histogram_tool_new_dialog (void); static HistogramToolDialog * histogram_tool_dialog_new (void);
static void histogram_tool_close_callback (GtkWidget *, gpointer); static void histogram_tool_close_callback (GtkWidget *, gpointer);
static void histogram_tool_value_callback (GtkWidget *, gpointer); static void histogram_tool_value_callback (GtkWidget *, gpointer);
@ -62,20 +60,19 @@ static void histogram_tool_gradient_draw (GtkWidget *, gint);
static void histogram_tool_dialog_update (HistogramToolDialog *, gint, gint); static void histogram_tool_dialog_update (HistogramToolDialog *, gint, gint);
/* histogram_tool machinery */ /* histogram_tool machinery */
void void
histogram_tool_histogram_range (HistogramWidget *widget, histogram_tool_histogram_range (HistogramWidget *widget,
gint start, gint start,
gint end, gint end,
void *user_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
gdouble pixels; gdouble pixels;
gdouble count; gdouble count;
htd = (HistogramToolDialog *) user_data; htd = (HistogramToolDialog *) data;
if (htd == NULL || htd->hist == NULL || if (htd == NULL || htd->hist == NULL ||
gimp_histogram_nchannels(htd->hist) <= 0) gimp_histogram_nchannels(htd->hist) <= 0)
@ -161,7 +158,7 @@ histogram_tool_control (Tool *tool,
} }
Tool * Tool *
tools_new_histogram_tool () tools_new_histogram_tool (void)
{ {
Tool * tool; Tool * tool;
HistogramTool * private; HistogramTool * private;
@ -213,7 +210,7 @@ histogram_tool_initialize (GDisplay *gdisp)
/* The histogram_tool dialog */ /* The histogram_tool dialog */
if (!histogram_tool_dialog) if (!histogram_tool_dialog)
histogram_tool_dialog = histogram_tool_new_dialog (); histogram_tool_dialog = histogram_tool_dialog_new ();
else if (!GTK_WIDGET_VISIBLE (histogram_tool_dialog->shell)) else if (!GTK_WIDGET_VISIBLE (histogram_tool_dialog->shell))
gtk_widget_show (histogram_tool_dialog->shell); gtk_widget_show (histogram_tool_dialog->shell);
@ -238,17 +235,17 @@ histogram_tool_initialize (GDisplay *gdisp)
histogram_widget_range (histogram_tool_dialog->histogram, 0, 255); histogram_widget_range (histogram_tool_dialog->histogram, 0, 255);
} }
/***************************/ /***************************/
/* Histogram Tool dialog */ /* Histogram Tool dialog */
/***************************/ /***************************/
static HistogramToolDialog * static HistogramToolDialog *
histogram_tool_new_dialog () histogram_tool_dialog_new (void)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
GtkWidget *main_vbox;
GtkWidget *hbox;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
@ -296,17 +293,19 @@ histogram_tool_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (htd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (htd->shell)->vbox), main_vbox);
/* The vbox for the menu and histogram */ hbox = gtk_hbox_new (TRUE, 0);
vbox2 = gtk_vbox_new (FALSE, 2); gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
/* The option menu for selecting channels */ /* The option menu for selecting channels */
htd->channel_menu = gtk_hbox_new (FALSE, 6); htd->channel_menu = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox2), htd->channel_menu, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), htd->channel_menu, FALSE, FALSE, 0);
label = gtk_label_new (_("Information on Channel:")); label = gtk_label_new (_("Information on Channel:"));
gtk_box_pack_start (GTK_BOX (htd->channel_menu), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (htd->channel_menu), label, FALSE, FALSE, 0);
@ -323,32 +322,33 @@ histogram_tool_new_dialog ()
/* The histogram tool histogram */ /* The histogram tool histogram */
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
htd->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT); htd->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(htd->histogram));
gtk_signal_connect (GTK_OBJECT (htd->histogram), "rangechanged", gtk_signal_connect (GTK_OBJECT (htd->histogram), "rangechanged",
(GtkSignalFunc) histogram_tool_histogram_range, GTK_SIGNAL_FUNC (histogram_tool_histogram_range),
(void*)htd); htd);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(htd->histogram)); gtk_widget_show (GTK_WIDGET (htd->histogram));
gtk_widget_show (GTK_WIDGET(htd->histogram));
gtk_widget_show (frame); gtk_widget_show (frame);
/* The gradient below the histogram */ /* The gradient below the histogram */
htd->gradient = gtk_preview_new (GTK_PREVIEW_COLOR); htd->gradient = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (htd->gradient), gtk_preview_size (GTK_PREVIEW (htd->gradient),
HISTOGRAM_WIDTH, GRADIENT_HEIGHT); HISTOGRAM_WIDTH, GRADIENT_HEIGHT);
gtk_box_pack_start (GTK_BOX (vbox2), htd->gradient, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), htd->gradient, FALSE, FALSE, 0);
gtk_widget_show (htd->gradient); gtk_widget_show (htd->gradient);
histogram_tool_gradient_draw (htd->gradient, HISTOGRAM_VALUE); histogram_tool_gradient_draw (htd->gradient, HISTOGRAM_VALUE);
gtk_widget_show (vbox2); gtk_widget_show (vbox);
gtk_widget_show (hbox);
/* The table containing histogram information */ /* The table containing histogram information */
table = gtk_table_new (4, 4, TRUE); table = gtk_table_new (4, 4, TRUE);
gtk_table_set_col_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 6);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
/* the labels for histogram information */ /* the labels for histogram information */
for (i = 0; i < 7; i++) for (i = 0; i < 7; i++)
@ -371,7 +371,8 @@ histogram_tool_new_dialog ()
} }
gtk_widget_show (table); gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (main_vbox);
gtk_widget_show (htd->shell); gtk_widget_show (htd->shell);
return htd; return htd;
@ -379,23 +380,26 @@ histogram_tool_new_dialog ()
static void static void
histogram_tool_close_callback (GtkWidget *widget, histogram_tool_close_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (GTK_WIDGET_VISIBLE (htd->shell)) if (GTK_WIDGET_VISIBLE (htd->shell))
gtk_widget_hide (htd->shell); gtk_widget_hide (htd->shell);
active_tool->gdisp_ptr = NULL;
active_tool->drawable = NULL;
} }
static void static void
histogram_tool_value_callback (GtkWidget *widget, histogram_tool_value_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_VALUE) if (htd->channel != HISTOGRAM_VALUE)
{ {
@ -407,11 +411,11 @@ histogram_tool_value_callback (GtkWidget *widget,
static void static void
histogram_tool_red_callback (GtkWidget *widget, histogram_tool_red_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_RED) if (htd->channel != HISTOGRAM_RED)
{ {
@ -423,11 +427,11 @@ histogram_tool_red_callback (GtkWidget *widget,
static void static void
histogram_tool_green_callback (GtkWidget *widget, histogram_tool_green_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_GREEN) if (htd->channel != HISTOGRAM_GREEN)
{ {
@ -439,11 +443,11 @@ histogram_tool_green_callback (GtkWidget *widget,
static void static void
histogram_tool_blue_callback (GtkWidget *widget, histogram_tool_blue_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_BLUE) if (htd->channel != HISTOGRAM_BLUE)
{ {

View File

@ -26,34 +26,39 @@
#define HISTOGRAM_HEIGHT 150 #define HISTOGRAM_HEIGHT 150
typedef struct _HistogramToolDialog HistogramToolDialog; typedef struct _HistogramToolDialog HistogramToolDialog;
struct _HistogramToolDialog struct _HistogramToolDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *info_labels[7]; GtkWidget *info_labels[7];
GtkWidget *channel_menu; GtkWidget *channel_menu;
HistogramWidget *histogram; HistogramWidget *histogram;
GimpHistogram *hist; GimpHistogram *hist;
GtkWidget *gradient; GtkWidget *gradient;
gdouble mean; gdouble mean;
gdouble std_dev; gdouble std_dev;
gdouble median; gdouble median;
gdouble pixels; gdouble pixels;
gdouble count; gdouble count;
gdouble percentile; gdouble percentile;
GimpDrawable *drawable; GimpDrawable *drawable;
ImageMap image_map; ImageMap image_map;
gint channel; gint channel;
gint color; gint color;
}; };
/* histogram_tool functions */ /* histogram_tool functions */
Tool * tools_new_histogram_tool (void); Tool * tools_new_histogram_tool (void);
void tools_free_histogram_tool (Tool *); void tools_free_histogram_tool (Tool *tool);
void histogram_tool_initialize (GDisplay *); void histogram_tool_initialize (GDisplay *gdisp);
void histogram_tool_free (void); void histogram_tool_free (void);
void histogram_tool_histogram_range (HistogramWidget *, gint, gint, void *); void histogram_tool_histogram_range (HistogramWidget *hw,
gint start,
gint end,
gpointer data);
#endif /* __HISTOGRAM_TOOL_H__ */ #endif /* __HISTOGRAM_TOOL_H__ */

View File

@ -33,29 +33,24 @@
#define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK #define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200 #define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define DA_WIDTH 40 #define DA_WIDTH 40
#define DA_HEIGHT 20 #define DA_HEIGHT 20
#define HUE_PARTITION 0x0 #define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1 #define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2 #define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4 #define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8 #define DRAW 0x40
#define LIGHTNESS_TEXT 0x10 #define ALL 0xFF
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */ /* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation; typedef struct _HueSaturation HueSaturation;
struct _HueSaturation struct _HueSaturation
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the hue-saturation tool options */ /* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL; static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */ /* Local variables */
static int hue_transfer[6][256]; static gint hue_transfer[6][256];
static int lightness_transfer[6][256]; static gint lightness_transfer[6][256];
static int saturation_transfer[6][256]; static gint saturation_transfer[6][256];
static int default_colors[6][3] = static gint default_colors[6][3] =
{ {
{ 255, 0, 0 }, { 255, 0, 0 },
{ 255, 255, 0 }, { 255, 255, 0 },
{ 0, 255, 0 }, { 0, 255, 0 },
{ 0, 255, 255 }, { 0, 255, 255 },
{ 0, 0, 255 }, { 0, 0, 255 },
{ 255, 0, 255 } { 255, 0, 255 }
}; };
/* hue saturation action functions */ /* hue saturation action functions */
static void hue_saturation_control (Tool *, ToolAction, gpointer); static void hue_saturation_control (Tool *, ToolAction, gpointer);
static HueSaturationDialog * hue_saturation_new_dialog (void); static HueSaturationDialog * hue_saturation_dialog_new (void);
static void hue_saturation_update (HueSaturationDialog *, static void hue_saturation_update (HueSaturationDialog *,
int); gint);
static void hue_saturation_preview (HueSaturationDialog *); static void hue_saturation_preview (HueSaturationDialog *);
static void hue_saturation_reset_callback (GtkWidget *, gpointer);
static void hue_saturation_ok_callback (GtkWidget *, gpointer); static void hue_saturation_ok_callback (GtkWidget *, gpointer);
static void hue_saturation_cancel_callback (GtkWidget *, gpointer); static void hue_saturation_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_callback (GtkWidget *, gpointer); static void hue_saturation_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_R_callback (GtkWidget *, gpointer);
static void hue_saturation_Y_callback (GtkWidget *, gpointer);
static void hue_saturation_G_callback (GtkWidget *, gpointer);
static void hue_saturation_C_callback (GtkWidget *, gpointer);
static void hue_saturation_B_callback (GtkWidget *, gpointer);
static void hue_saturation_M_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer); static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer); gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
static void hue_saturation_hue_text_update (GtkWidget *, gpointer); gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer); static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer); gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *, static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *); HueSaturationDialog *);
/* hue saturation machinery */ /* hue saturation machinery */
void void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd) hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{ {
int value; gint value;
int hue; gint hue;
int i; gint i;
/* Calculate transfers */ /* Calculate transfers */
for (hue = 0; hue < 6; hue++) for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
} }
} }
/* hue saturation action functions */ /* hue saturation action functions */
static void static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
} }
Tool * Tool *
tools_new_hue_saturation () tools_new_hue_saturation (void)
{ {
Tool * tool; Tool * tool;
HueSaturation * private; HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void void
hue_saturation_initialize (GDisplay *gdisp) hue_saturation_initialize (GDisplay *gdisp)
{ {
int i; gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage))) if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{ {
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */ /* The "hue-saturation" dialog */
if (!hue_saturation_dialog) if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog (); hue_saturation_dialog = hue_saturation_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell)) if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell))
gtk_widget_show (hue_saturation_dialog->shell); gtk_widget_show (hue_saturation_dialog->shell);
@ -313,12 +300,14 @@ hue_saturation_initialize (GDisplay *gdisp)
} }
hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage); hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage);
hue_saturation_dialog->image_map = image_map_create (gdisp, hue_saturation_dialog->drawable); hue_saturation_dialog->image_map =
image_map_create (gdisp, hue_saturation_dialog->drawable);
hue_saturation_update (hue_saturation_dialog, ALL); hue_saturation_update (hue_saturation_dialog, ALL);
} }
void void
hue_saturation_free () hue_saturation_free (void)
{ {
if (hue_saturation_dialog) if (hue_saturation_dialog)
{ {
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map); image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL; hue_saturation_dialog->image_map = NULL;
} }
gtk_widget_destroy (hue_saturation_dialog->shell); gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/ /***************************/
static HueSaturationDialog * static HueSaturationDialog *
hue_saturation_new_dialog () hue_saturation_dialog_new (void)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
GtkWidget *main_vbox; GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle; GtkWidget *toggle;
GtkWidget *radio_button; GtkWidget *radio_button;
GtkWidget *frame; GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
N_("M") N_("M")
}; };
GtkSignalFunc hue_partition_callbacks[] =
{
hue_saturation_master_callback,
hue_saturation_R_callback,
hue_saturation_Y_callback,
hue_saturation_G_callback,
hue_saturation_C_callback,
hue_saturation_B_callback,
hue_saturation_M_callback
};
hsd = g_new (HueSaturationDialog, 1); hsd = g_new (HueSaturationDialog, 1);
hsd->hue_partition = 0; hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE; hsd->preview = TRUE;
/* The shell and main vbox */ /* The shell and main vbox */
hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_satiration", hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_saturation",
tools_help_func, NULL, tools_help_func, NULL,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback, _("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE, hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback, _("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL); NULL);
main_vbox = gtk_vbox_new (FALSE, 2); main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* The main hbox containing hue partitions and sliders */ /* The main hbox containing hue partitions and sliders */
main_hbox = gtk_hbox_new (FALSE, 2); main_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0);
/* The table containing hue partitions */ /* The table containing hue partitions */
table = gtk_table_new (7, 2, FALSE); table = gtk_table_new (7, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0);
/* the radio buttons for hue partitions */ /* the radio buttons for hue partitions */
@ -411,26 +396,30 @@ hue_saturation_new_dialog ()
{ {
radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]); radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i) if (!i)
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
} }
else else
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR); hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT); gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK); DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1],
HUE_PARTITION_MASK);
gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event", gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event",
(GtkSignalFunc) hue_saturation_hue_partition_events, GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd); hsd);
gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]); gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]);
@ -439,14 +428,16 @@ hue_saturation_new_dialog ()
} }
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) hue_partition_callbacks[i], GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd); hsd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (table); gtk_widget_show (table);
/* The vbox for the table and preview toggle */ /* The vbox for the table and preview toggle */
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments")); label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the hue scale widget */ /* Create the hue scale widget */
label = gtk_label_new (_("Hue")); label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0);
hsd->hue_data = GTK_ADJUSTMENT (data); hsd->hue_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->hue_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
hsd->hue_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1, gtk_widget_set_usize (spinbutton, 74, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
(GtkSignalFunc) hue_saturation_hue_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_hue_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */ /* Create the lightness scale widget */
label = gtk_label_new (_("Lightness")); label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->lightness_data = GTK_ADJUSTMENT (data); hsd->lightness_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->lightness_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
hsd->lightness_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
(GtkSignalFunc) hue_saturation_lightness_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_lightness_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */ /* Create the saturation scale widget */
label = gtk_label_new (_("Saturation")); label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->saturation_data = GTK_ADJUSTMENT (data); hsd->saturation_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->saturation_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
hsd->saturation_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
(GtkSignalFunc) hue_saturation_saturation_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_saturation_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */ /* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) hue_saturation_preview_update, GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd); hsd);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (main_hbox); gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox); gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void static void
hue_saturation_update (HueSaturationDialog *hsd, hue_saturation_update (HueSaturationDialog *hsd,
int update) gint update)
{ {
int i, j, b; gint i, j, b;
int rgb[3]; gint rgb[3];
unsigned char buf[DA_WIDTH * 3]; guchar buf[DA_WIDTH * 3];
char text[12];
if (update & HUE_SLIDER) if (update & HUE_SLIDER)
{ {
hsd->hue_data->value = hsd->hue[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed"); hsd->hue[hsd->hue_partition]);
} }
if (update & LIGHTNESS_SLIDER) if (update & LIGHTNESS_SLIDER)
{ {
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed"); hsd->lightness[hsd->hue_partition]);
} }
if (update & SATURATION_SLIDER) if (update & SATURATION_SLIDER)
{ {
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed"); hsd->saturation[hsd->hue_partition]);
}
if (update & HUE_TEXT)
{
sprintf (text, "%0.0f", hsd->hue[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->hue_text), text);
}
if (update & LIGHTNESS_TEXT)
{
sprintf (text, "%0.0f", hsd->lightness[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->lightness_text), text);
}
if (update & SATURATION_TEXT)
{
sprintf (text, "%0.0f", hsd->saturation[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->saturation_text), text);
} }
hue_saturation_calculate_transfers (hsd); hue_saturation_calculate_transfers (hsd);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
rgb[RED_PIX] = default_colors[i][RED_PIX]; rgb[RED_PIX] = default_colors[i][RED_PIX];
rgb[GREEN_PIX] = default_colors[i][GREEN_PIX]; rgb[GREEN_PIX] = default_colors[i][GREEN_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX]; rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb_to_hls (rgb, rgb + 1, rgb + 2); rgb_to_hls (rgb, rgb + 1, rgb + 2);
rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]]; rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]];
rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]]; rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]];
rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]]; rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]];
hls_to_rgb (rgb, rgb + 1, rgb + 2); hls_to_rgb (rgb, rgb + 1, rgb + 2);
for (j = 0; j < DA_WIDTH; j++) for (j = 0; j < DA_WIDTH; j++)
for (b = 0; b < 3; b++) for (b = 0; b < 3; b++)
buf[j * 3 + b] = (unsigned char) rgb[b]; buf[j * 3 + b] = (guchar) rgb[b];
for (j = 0; j < DA_HEIGHT; j++) for (j = 0; j < DA_HEIGHT; j++)
gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]), buf, 0, j, DA_WIDTH); gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]),
buf, 0, j, DA_WIDTH);
if (update & DRAW) if (update & DRAW)
gtk_widget_draw (hsd->hue_partition_da[i], NULL); gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd) hue_saturation_preview (HueSaturationDialog *hsd)
{ {
if (!hsd->image_map) if (!hsd->image_map)
g_warning ("hue_saturation_preview(): No image map"); {
g_warning ("hue_saturation_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd); image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void static void
hue_saturation_ok_callback (GtkWidget *widget, hue_saturation_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
hsd->hue[hsd->hue_partition] = 0.0;
hsd->lightness[hsd->hue_partition] = 0.0;
hsd->saturation[hsd->hue_partition] = 0.0;
hue_saturation_update (hsd, ALL);
if (hsd->preview)
hue_saturation_preview (hsd);
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void static void
hue_saturation_cancel_callback (GtkWidget *widget, hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
} }
static void static void
hue_saturation_master_callback (GtkWidget *widget, hue_saturation_partition_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
HueRange partition;
hsd = (HueSaturationDialog *) data;
partition = (HueRange) gtk_object_get_data (GTK_OBJECT (widget),
"hue_partition");
hsd->hue_partition = partition;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 0;
hue_saturation_update (hsd, ALL); hue_saturation_update (hsd, ALL);
} }
static void static void
hue_saturation_R_callback (GtkWidget *widget, hue_saturation_preview_update (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 1;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_Y_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 2;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_G_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 3;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_C_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 4;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_B_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 5;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_M_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 6;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_preview_update (GtkWidget *w,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data; hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
hsd->preview = TRUE; hsd->preview = TRUE;
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
} }
static void static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment, hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (hsd->hue[hsd->hue_partition] != adjustment->value) if (hsd->hue[hsd->hue_partition] != adjustment->value)
{ {
hsd->hue[hsd->hue_partition] = adjustment->value; hsd->hue[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, HUE_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment, hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (hsd->lightness[hsd->hue_partition] != adjustment->value) if (hsd->lightness[hsd->hue_partition] != adjustment->value)
{ {
hsd->lightness[hsd->hue_partition] = adjustment->value; hsd->lightness[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, LIGHTNESS_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment, hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value) if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{ {
hsd->saturation[hsd->hue_partition] = adjustment->value; hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_hue_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -180, 180);
if ((int) hsd->hue[hsd->hue_partition] != value)
{
hsd->hue[hsd->hue_partition] = value;
hue_saturation_update (hsd, HUE_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_lightness_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->lightness[hsd->hue_partition] != value)
{
hsd->lightness[hsd->hue_partition] = value;
hue_saturation_update (hsd, LIGHTNESS_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_saturation_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->saturation[hsd->hue_partition] != value)
{
hsd->saturation[hsd->hue_partition] = value;
hue_saturation_update (hsd, SATURATION_SLIDER | DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange; } HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog; typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog struct _HueSaturationDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *gimage_name;
GtkWidget *hue_text;
GtkWidget *lightness_text;
GtkWidget *saturation_text;
GtkWidget *hue_partition_da[6];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
GimpDrawable *drawable; GtkWidget *hue_partition_da[6];
ImageMap image_map;
double hue[7]; GtkAdjustment *hue_data;
double lightness[7]; GtkAdjustment *lightness_data;
double saturation[7]; GtkAdjustment *saturation_data;
int hue_partition; GimpDrawable *drawable;
gint preview; ImageMap image_map;
gdouble hue[7];
gdouble lightness[7];
gdouble saturation[7];
HueRange hue_partition;
gboolean preview;
}; };
/* hue-saturation functions */ Tool * tools_new_hue_saturation (void);
Tool * tools_new_hue_saturation (void); void tools_free_hue_saturation (Tool *tool);
void tools_free_hue_saturation (Tool *);
void hue_saturation_initialize (GDisplay *); void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (void); void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *); void hue_saturation (PixelRegion *srcPR,
PixelRegion *destPR,
void *data);
void hue_saturation_calculate_transfers (HueSaturationDialog *hsd); void hue_saturation_calculate_transfers (HueSaturationDialog *hsd);
#endif /* __HUE_SATURATION_H__ */ #endif /* __HUE_SATURATION_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -20,11 +20,10 @@
#include "tools.h" #include "tools.h"
/* hue-saturation functions */ Tool * tools_new_levels (void);
Tool * tools_new_levels (void); void tools_free_levels (Tool *tool);
void tools_free_levels (Tool *);
void levels_initialize (GDisplay *); void levels_initialize (GDisplay *gdisp);
void levels_free (void); void levels_free (void);
#endif /* __LEVELS_H__ */ #endif /* __LEVELS_H__ */

View File

@ -15,12 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "drawable.h" #include "drawable.h"
#include "gdisplay.h" #include "gdisplay.h"
@ -33,32 +27,33 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 55
/* the posterize structures */ /* the posterize structures */
typedef struct _Posterize Posterize; typedef struct _Posterize Posterize;
struct _Posterize struct _Posterize
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef struct _PosterizeDialog PosterizeDialog; typedef struct _PosterizeDialog PosterizeDialog;
struct _PosterizeDialog struct _PosterizeDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *levels_text;
GimpDrawable *drawable; GtkAdjustment *levels_data;
ImageMap image_map;
int levels;
gint preview; GimpDrawable *drawable;
ImageMap image_map;
GimpLut *lut; gint levels;
gboolean preview;
GimpLut *lut;
}; };
/* the posterize tool options */ /* the posterize tool options */
static ToolOptions *posterize_options = NULL; static ToolOptions *posterize_options = NULL;
@ -69,14 +64,14 @@ static PosterizeDialog *posterize_dialog = NULL;
/* posterize action functions */ /* posterize action functions */
static void posterize_control (Tool *, ToolAction, gpointer); static void posterize_control (Tool *, ToolAction, gpointer);
static PosterizeDialog * posterize_new_dialog (void); static PosterizeDialog * posterize_dialog_new (void);
static void posterize_preview (PosterizeDialog *);
static void posterize_ok_callback (GtkWidget *, gpointer);
static void posterize_cancel_callback (GtkWidget *, gpointer);
static void posterize_preview_update (GtkWidget *, gpointer);
static void posterize_levels_text_update (GtkWidget *, gpointer);
static void posterize_preview (PosterizeDialog *);
static void posterize_reset_callback (GtkWidget *, gpointer);
static void posterize_ok_callback (GtkWidget *, gpointer);
static void posterize_cancel_callback (GtkWidget *, gpointer);
static void posterize_preview_update (GtkWidget *, gpointer);
static void posterize_levels_adjustment_update (GtkAdjustment *, gpointer);
/* posterize select action functions */ /* posterize select action functions */
@ -104,7 +99,7 @@ posterize_control (Tool *tool,
} }
Tool * Tool *
tools_new_posterize () tools_new_posterize (void)
{ {
Tool * tool; Tool * tool;
Posterize * private; Posterize * private;
@ -116,13 +111,6 @@ tools_new_posterize ()
tools_register (POSTERIZE, posterize_options); tools_register (POSTERIZE, posterize_options);
} }
/* The posterize dialog */
if (!posterize_dialog)
posterize_dialog = posterize_new_dialog ();
else
if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell))
gtk_widget_show (posterize_dialog->shell);
tool = tools_new_tool (POSTERIZE); tool = tools_new_tool (POSTERIZE);
private = g_new (Posterize, 1); private = g_new (Posterize, 1);
@ -161,32 +149,37 @@ posterize_initialize (GDisplay *gdisp)
/* The posterize dialog */ /* The posterize dialog */
if (!posterize_dialog) if (!posterize_dialog)
posterize_dialog = posterize_new_dialog (); posterize_dialog = posterize_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell)) if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell))
gtk_widget_show (posterize_dialog->shell); gtk_widget_show (posterize_dialog->shell);
posterize_dialog->levels = 3;
posterize_dialog->drawable = gimage_active_drawable (gdisp->gimage); posterize_dialog->drawable = gimage_active_drawable (gdisp->gimage);
posterize_dialog->image_map = posterize_dialog->image_map =
image_map_create (gdisp, posterize_dialog->drawable); image_map_create (gdisp, posterize_dialog->drawable);
gtk_adjustment_set_value (GTK_ADJUSTMENT (posterize_dialog->levels_data), 3);
if (posterize_dialog->preview) if (posterize_dialog->preview)
posterize_preview (posterize_dialog); posterize_preview (posterize_dialog);
} }
/**********************/ /**********************/
/* Posterize dialog */ /* Posterize dialog */
/**********************/ /**********************/
static PosterizeDialog * static PosterizeDialog *
posterize_new_dialog () posterize_dialog_new (void)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *label; GtkWidget *label;
GtkWidget *spinbutton;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data;
pd = g_new (PosterizeDialog, 1); pd = g_new (PosterizeDialog, 1);
pd->preview = TRUE; pd->preview = TRUE;
@ -200,6 +193,8 @@ posterize_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), posterize_reset_callback,
pd, NULL, TRUE, FALSE,
_("OK"), posterize_ok_callback, _("OK"), posterize_ok_callback,
pd, NULL, TRUE, FALSE, pd, NULL, TRUE, FALSE,
_("Cancel"), posterize_cancel_callback, _("Cancel"), posterize_cancel_callback,
@ -208,39 +203,43 @@ posterize_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pd->shell)->vbox), vbox);
/* Horizontal box for levels text widget */ /* Horizontal box for levels text widget */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Posterize Levels: ")); label = gtk_label_new (_("Posterize Levels:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
gtk_widget_show (label); gtk_widget_show (label);
/* levels text */ /* levels spinbutton */
pd->levels_text = gtk_entry_new (); data = gtk_adjustment_new (3, 2, 256, 1.0, 10.0, 0.0);
gtk_entry_set_text (GTK_ENTRY (pd->levels_text), "3"); pd->levels_data = GTK_ADJUSTMENT (data);
gtk_widget_set_usize (pd->levels_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), pd->levels_text, TRUE, FALSE, 0); spinbutton = gtk_spin_button_new (pd->levels_data, 1.0, 0);
gtk_signal_connect (GTK_OBJECT (pd->levels_text), "changed", gtk_widget_set_usize (spinbutton, 75, -1);
(GtkSignalFunc) posterize_levels_text_update, gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (pd->levels_data), "value_changed",
GTK_SIGNAL_FUNC (posterize_levels_adjustment_update),
pd); pd);
gtk_widget_show (pd->levels_text);
gtk_widget_show (spinbutton);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), pd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), pd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) posterize_preview_update, GTK_SIGNAL_FUNC (posterize_preview_update),
pd); pd);
gtk_widget_show (label); gtk_widget_show (label);
@ -257,21 +256,36 @@ static void
posterize_preview (PosterizeDialog *pd) posterize_preview (PosterizeDialog *pd)
{ {
if (!pd->image_map) if (!pd->image_map)
g_warning ("posterize_preview(): No image map"); {
g_warning ("posterize_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
posterize_lut_setup(pd->lut, pd->levels, gimp_drawable_bytes(pd->drawable)); posterize_lut_setup (pd->lut, pd->levels, gimp_drawable_bytes(pd->drawable));
image_map_apply (pd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (pd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
(void *) pd->lut); (void *) pd->lut);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void static void
posterize_ok_callback (GtkWidget *widget, posterize_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) client_data; pd = (PosterizeDialog *) data;
gtk_adjustment_set_value (GTK_ADJUSTMENT (pd->levels_data), 3);
}
static void
posterize_ok_callback (GtkWidget *widget,
gpointer data)
{
PosterizeDialog *pd;
pd = (PosterizeDialog *) data;
if (GTK_WIDGET_VISIBLE (pd->shell)) if (GTK_WIDGET_VISIBLE (pd->shell))
gtk_widget_hide (pd->shell); gtk_widget_hide (pd->shell);
@ -279,12 +293,13 @@ posterize_ok_callback (GtkWidget *widget,
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
if (!pd->preview) if (!pd->preview)
{ {
posterize_lut_setup(pd->lut, pd->levels, posterize_lut_setup( pd->lut, pd->levels,
gimp_drawable_bytes(pd->drawable)); gimp_drawable_bytes (pd->drawable));
image_map_apply (pd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (pd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
(void *) pd->lut); (void *) pd->lut);
} }
if (pd->image_map) if (pd->image_map)
image_map_commit (pd->image_map); image_map_commit (pd->image_map);
@ -298,11 +313,12 @@ posterize_ok_callback (GtkWidget *widget,
static void static void
posterize_cancel_callback (GtkWidget *widget, posterize_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) client_data; pd = (PosterizeDialog *) data;
if (GTK_WIDGET_VISIBLE (pd->shell)) if (GTK_WIDGET_VISIBLE (pd->shell))
gtk_widget_hide (pd->shell); gtk_widget_hide (pd->shell);
@ -321,14 +337,14 @@ posterize_cancel_callback (GtkWidget *widget,
} }
static void static void
posterize_preview_update (GtkWidget *w, posterize_preview_update (GtkWidget *widget,
gpointer data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) data; pd = (PosterizeDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
pd->preview = TRUE; pd->preview = TRUE;
posterize_preview (pd); posterize_preview (pd);
@ -338,20 +354,17 @@ posterize_preview_update (GtkWidget *w,
} }
static void static void
posterize_levels_text_update (GtkWidget *w, posterize_levels_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
char *str;
int value;
pd = (PosterizeDialog *) data; pd = (PosterizeDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), 2, 256);
if (value != pd->levels) if (pd->levels != adjustment->value)
{ {
pd->levels = value; pd->levels = adjustment->value;
if (pd->preview) if (pd->preview)
posterize_preview (pd); posterize_preview (pd);
} }

View File

@ -20,10 +20,9 @@
#include "tools.h" #include "tools.h"
/* by_color select functions */ Tool * tools_new_posterize (void);
Tool * tools_new_posterize (void); void tools_free_posterize (Tool *tool);
void tools_free_posterize (Tool *);
void posterize_initialize (GDisplay *); void posterize_initialize (GDisplay *gdisp);
#endif /* __POSTERIZE_H__ */ #endif /* __POSTERIZE_H__ */

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "drawable.h" #include "drawable.h"
#include "general.h" #include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256 #define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150 #define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */ /* the threshold structures */
typedef struct _Threshold Threshold; typedef struct _Threshold Threshold;
struct _Threshold struct _Threshold
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the threshold tool options */ /* the threshold tool options */
static ToolOptions *threshold_options = NULL; static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */ /* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL; static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */ /* threshold action functions */
static void threshold_control (Tool *, ToolAction, gpointer); static void threshold_control (Tool *, ToolAction, gpointer);
static ThresholdDialog * threshold_new_dialog (void); static ThresholdDialog * threshold_dialog_new (void);
static void threshold_update (ThresholdDialog *,
gint);
static void threshold_preview (ThresholdDialog *); static void threshold_preview (ThresholdDialog *);
static void threshold_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer); static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer); static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer); static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer); static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
static void threshold_high_threshold_text_update (GtkWidget *, gpointer); gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold (PixelRegion *, PixelRegion *, void *); static void threshold (PixelRegion *, PixelRegion *, void *);
static void threshold_histogram_range (HistogramWidget *, int, int, void *); static void threshold_histogram_range (HistogramWidget *, gint, gint,
gpointer);
/* threshold machinery */ /* threshold machinery */
void void
threshold_2 (void *user_data, threshold_2 (void *data,
PixelRegion *srcPR, PixelRegion *srcPR,
PixelRegion *destPR) PixelRegion *destPR)
{ {
/* this function just re-orders the arguments so we can use /* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */ * pixel_regions_process_paralell
threshold(srcPR, destPR, user_data); */
threshold (srcPR, destPR, data);
} }
static void static void
threshold (PixelRegion *srcPR, threshold (PixelRegion *srcPR,
PixelRegion *destPR, PixelRegion *destPR,
void *user_data) void *data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
unsigned char *src, *s; unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b; int w, h, b;
int value; int value;
td = (ThresholdDialog *) user_data; td = (ThresholdDialog *) data;
h = srcPR->h; h = srcPR->h;
src = srcPR->data; src = srcPR->data;
@ -128,28 +133,6 @@ threshold (PixelRegion *srcPR,
} }
} }
static void
threshold_histogram_range (HistogramWidget *w,
int start,
int end,
void *user_data)
{
ThresholdDialog *td;
char text[12];
td = (ThresholdDialog *) user_data;
td->low_threshold = start;
td->high_threshold = end;
sprintf (text, "%d", start);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), text);
sprintf (text, "%d", end);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), text);
if (td->preview)
threshold_preview (td);
}
/* threshold action functions */ /* threshold action functions */
static void static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
} }
Tool * Tool *
tools_new_threshold () tools_new_threshold (void)
{ {
Tool * tool; Tool * tool;
Threshold * private; Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
tools_register (THRESHOLD, threshold_options); tools_register (THRESHOLD, threshold_options);
} }
/* The threshold dialog */
if (! threshold_dialog)
threshold_dialog = threshold_new_dialog ();
else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell);
tool = tools_new_tool (THRESHOLD); tool = tools_new_tool (THRESHOLD);
private = g_new (Threshold, 1); private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private; thresh = (Threshold *) tool->private;
/* Close the color select dialog */ /* Close the threshold dialog */
if (threshold_dialog) if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog); threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */ /* The threshold dialog */
if (!threshold_dialog) if (!threshold_dialog)
threshold_dialog = threshold_new_dialog (); threshold_dialog = threshold_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell)) if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell); gtk_widget_show (threshold_dialog->shell);
threshold_dialog->low_threshold = 127;
threshold_dialog->high_threshold = 255;
threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage); threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage);
threshold_dialog->color = drawable_color (threshold_dialog->drawable); threshold_dialog->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map = threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist, gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable); threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram, histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist); threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram, gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog->low_threshold, threshold_dialog);
threshold_dialog->high_threshold);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview) if (threshold_dialog->preview)
threshold_preview (threshold_dialog); threshold_preview (threshold_dialog);
} }
/**********************/ /**********************/
/* Threshold dialog */ /* Threshold dialog */
/**********************/ /**********************/
static ThresholdDialog * static ThresholdDialog *
threshold_new_dialog () threshold_dialog_new (void)
{ {
ThresholdDialog *td; ThresholdDialog *td;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label; GtkWidget *label;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1); td = g_new (ThresholdDialog, 1);
td->preview = TRUE; td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback, _("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE, td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback, _("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* Horizontal box for threshold text widget */ /* Horizontal box for threshold text widget */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Threshold Range: ")); label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label); gtk_widget_show (label);
/* low threshold text */ /* low threshold spinbutton */
td->low_threshold_text = gtk_entry_new (); data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127"); td->low_threshold_data = GTK_ADJUSTMENT (data);
gtk_widget_set_usize (td->low_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->low_threshold_text, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->low_threshold_text), "changed",
(GtkSignalFunc) threshold_low_threshold_text_update,
td);
gtk_widget_show (td->low_threshold_text);
/* high threshold text */ spinbutton = gtk_spin_button_new (td->low_threshold_data, 1.0, 0);
td->high_threshold_text = gtk_entry_new (); gtk_widget_set_usize (spinbutton, 75, -1);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255"); gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_set_usize (td->high_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->high_threshold_text, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (td->low_threshold_data), "value_changed",
gtk_signal_connect (GTK_OBJECT (td->high_threshold_text), "changed", GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
(GtkSignalFunc) threshold_high_threshold_text_update,
td); td);
gtk_widget_show (td->high_threshold_text);
gtk_widget_show (spinbutton);
/* high threshold spinbutton */
data = gtk_adjustment_new (td->high_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->high_threshold_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (td->high_threshold_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->high_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_high_threshold_adjustment_update),
td);
gtk_widget_show (spinbutton);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* The threshold histogram */ /* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
@ -334,55 +328,97 @@ threshold_new_dialog ()
td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT); td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged", gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range, GTK_SIGNAL_FUNC (threshold_histogram_range),
(void*)td); td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
gtk_widget_show (GTK_WIDGET(td->histogram)); gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) threshold_preview_update, GTK_SIGNAL_FUNC (threshold_preview_update),
td); td);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (td->shell); gtk_widget_show (td->shell);
/* This code is so far removed from the histogram creation because the
function histogram_range requires a non-NULL drawable, and that
doesn't happen until after the top-level dialog is shown. */
histogram_widget_range (td->histogram, td->low_threshold, td->high_threshold);
return td; return td;
} }
static void
threshold_update (ThresholdDialog *td,
gint update)
{
if (update & LOW)
{
gtk_adjustment_set_value (td->low_threshold_data, td->low_threshold);
}
if (update & HIGH)
{
gtk_adjustment_set_value (td->high_threshold_data, td->high_threshold);
}
if (update & HISTOGRAM)
{
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
}
}
static void static void
threshold_preview (ThresholdDialog *td) threshold_preview (ThresholdDialog *td)
{ {
if (!td->image_map) if (!td->image_map)
g_warning ("threshold_preview(): No image map"); {
image_map_apply (td->image_map, threshold, (void *) td); g_warning ("threshold_preview(): No image map");
return;
}
active_tool->preserve = TRUE;
image_map_apply (td->image_map, threshold, td);
active_tool->preserve = FALSE;
}
static void
threshold_reset_callback (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = 127.0;
td->high_threshold = 255.0;
threshold_update (td, ALL);
if (td->preview)
threshold_preview (td);
} }
static void static void
threshold_ok_callback (GtkWidget *widget, threshold_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview) if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td); image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map) if (td->image_map)
image_map_commit (td->image_map); image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void static void
threshold_cancel_callback (GtkWidget *widget, threshold_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
} }
static void static void
threshold_preview_update (GtkWidget *w, threshold_preview_update (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
td->preview = TRUE; td->preview = TRUE;
threshold_preview (td); threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
} }
static void static void
threshold_low_threshold_text_update (GtkWidget *w, threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), 0, td->high_threshold);
if (value != td->low_threshold) if (td->low_threshold != adjustment->value)
{ {
td->low_threshold = value; td->low_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void static void
threshold_high_threshold_text_update (GtkWidget *w, threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), td->low_threshold, 255);
if (value != td->high_threshold) if (td->high_threshold != adjustment->value)
{ {
td->high_threshold = value; td->high_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void
threshold_histogram_range (HistogramWidget *widget,
gint start,
gint end,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = start;
td->high_threshold = end;
threshold_update (td, LOW | HIGH);
if (td->preview)
threshold_preview (td);
}

View File

@ -25,28 +25,33 @@
#include "tools.h" #include "tools.h"
typedef struct _ThresholdDialog ThresholdDialog; typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog struct _ThresholdDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text; GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram; HistogramWidget *histogram;
GimpHistogram *hist; GimpHistogram *hist;
GimpDrawable *drawable; GimpDrawable *drawable;
ImageMap image_map; ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
gint preview; gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
}; };
/* by_color select functions */ Tool * tools_new_threshold (void);
Tool * tools_new_threshold (void); void tools_free_threshold (Tool *tool);
void tools_free_threshold (Tool *);
void threshold_initialize (GDisplay *); void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *, PixelRegion *, PixelRegion *); void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */ #endif /* __THRESHOLD_H__ */

View File

@ -17,7 +17,6 @@
*/ */
#include "config.h" #include "config.h"
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "buildmenu.h" #include "buildmenu.h"
#include "drawable.h" #include "drawable.h"
@ -25,9 +24,9 @@
#include "gimpui.h" #include "gimpui.h"
#include "histogram_tool.h" #include "histogram_tool.h"
#include "image_map.h" #include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
#define TEXT_WIDTH 45 #define TEXT_WIDTH 45
#define GRADIENT_HEIGHT 15 #define GRADIENT_HEIGHT 15
@ -35,23 +34,22 @@
/* the histogram structures */ /* the histogram structures */
typedef struct _HistogramTool HistogramTool; typedef struct _HistogramTool HistogramTool;
struct _HistogramTool struct _HistogramTool
{ {
gint x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the histogram tool options */ /* the histogram tool options */
static ToolOptions * histogram_tool_options = NULL; static ToolOptions * histogram_tool_options = NULL;
/* the histogram tool dialog */ /* the histogram tool dialog */
static HistogramToolDialog * histogram_tool_dialog = NULL; static HistogramToolDialog * histogram_tool_dialog = NULL;
/* histogram_tool action functions */ /* histogram_tool action functions */
static void histogram_tool_control (Tool *, ToolAction, gpointer); static void histogram_tool_control (Tool *, ToolAction, gpointer);
static HistogramToolDialog * histogram_tool_new_dialog (void); static HistogramToolDialog * histogram_tool_dialog_new (void);
static void histogram_tool_close_callback (GtkWidget *, gpointer); static void histogram_tool_close_callback (GtkWidget *, gpointer);
static void histogram_tool_value_callback (GtkWidget *, gpointer); static void histogram_tool_value_callback (GtkWidget *, gpointer);
@ -62,20 +60,19 @@ static void histogram_tool_gradient_draw (GtkWidget *, gint);
static void histogram_tool_dialog_update (HistogramToolDialog *, gint, gint); static void histogram_tool_dialog_update (HistogramToolDialog *, gint, gint);
/* histogram_tool machinery */ /* histogram_tool machinery */
void void
histogram_tool_histogram_range (HistogramWidget *widget, histogram_tool_histogram_range (HistogramWidget *widget,
gint start, gint start,
gint end, gint end,
void *user_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
gdouble pixels; gdouble pixels;
gdouble count; gdouble count;
htd = (HistogramToolDialog *) user_data; htd = (HistogramToolDialog *) data;
if (htd == NULL || htd->hist == NULL || if (htd == NULL || htd->hist == NULL ||
gimp_histogram_nchannels(htd->hist) <= 0) gimp_histogram_nchannels(htd->hist) <= 0)
@ -161,7 +158,7 @@ histogram_tool_control (Tool *tool,
} }
Tool * Tool *
tools_new_histogram_tool () tools_new_histogram_tool (void)
{ {
Tool * tool; Tool * tool;
HistogramTool * private; HistogramTool * private;
@ -213,7 +210,7 @@ histogram_tool_initialize (GDisplay *gdisp)
/* The histogram_tool dialog */ /* The histogram_tool dialog */
if (!histogram_tool_dialog) if (!histogram_tool_dialog)
histogram_tool_dialog = histogram_tool_new_dialog (); histogram_tool_dialog = histogram_tool_dialog_new ();
else if (!GTK_WIDGET_VISIBLE (histogram_tool_dialog->shell)) else if (!GTK_WIDGET_VISIBLE (histogram_tool_dialog->shell))
gtk_widget_show (histogram_tool_dialog->shell); gtk_widget_show (histogram_tool_dialog->shell);
@ -238,17 +235,17 @@ histogram_tool_initialize (GDisplay *gdisp)
histogram_widget_range (histogram_tool_dialog->histogram, 0, 255); histogram_widget_range (histogram_tool_dialog->histogram, 0, 255);
} }
/***************************/ /***************************/
/* Histogram Tool dialog */ /* Histogram Tool dialog */
/***************************/ /***************************/
static HistogramToolDialog * static HistogramToolDialog *
histogram_tool_new_dialog () histogram_tool_dialog_new (void)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
GtkWidget *main_vbox;
GtkWidget *hbox;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
@ -296,17 +293,19 @@ histogram_tool_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (htd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (htd->shell)->vbox), main_vbox);
/* The vbox for the menu and histogram */ hbox = gtk_hbox_new (TRUE, 0);
vbox2 = gtk_vbox_new (FALSE, 2); gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
/* The option menu for selecting channels */ /* The option menu for selecting channels */
htd->channel_menu = gtk_hbox_new (FALSE, 6); htd->channel_menu = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox2), htd->channel_menu, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), htd->channel_menu, FALSE, FALSE, 0);
label = gtk_label_new (_("Information on Channel:")); label = gtk_label_new (_("Information on Channel:"));
gtk_box_pack_start (GTK_BOX (htd->channel_menu), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (htd->channel_menu), label, FALSE, FALSE, 0);
@ -323,32 +322,33 @@ histogram_tool_new_dialog ()
/* The histogram tool histogram */ /* The histogram tool histogram */
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
htd->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT); htd->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(htd->histogram));
gtk_signal_connect (GTK_OBJECT (htd->histogram), "rangechanged", gtk_signal_connect (GTK_OBJECT (htd->histogram), "rangechanged",
(GtkSignalFunc) histogram_tool_histogram_range, GTK_SIGNAL_FUNC (histogram_tool_histogram_range),
(void*)htd); htd);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(htd->histogram)); gtk_widget_show (GTK_WIDGET (htd->histogram));
gtk_widget_show (GTK_WIDGET(htd->histogram));
gtk_widget_show (frame); gtk_widget_show (frame);
/* The gradient below the histogram */ /* The gradient below the histogram */
htd->gradient = gtk_preview_new (GTK_PREVIEW_COLOR); htd->gradient = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (htd->gradient), gtk_preview_size (GTK_PREVIEW (htd->gradient),
HISTOGRAM_WIDTH, GRADIENT_HEIGHT); HISTOGRAM_WIDTH, GRADIENT_HEIGHT);
gtk_box_pack_start (GTK_BOX (vbox2), htd->gradient, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), htd->gradient, FALSE, FALSE, 0);
gtk_widget_show (htd->gradient); gtk_widget_show (htd->gradient);
histogram_tool_gradient_draw (htd->gradient, HISTOGRAM_VALUE); histogram_tool_gradient_draw (htd->gradient, HISTOGRAM_VALUE);
gtk_widget_show (vbox2); gtk_widget_show (vbox);
gtk_widget_show (hbox);
/* The table containing histogram information */ /* The table containing histogram information */
table = gtk_table_new (4, 4, TRUE); table = gtk_table_new (4, 4, TRUE);
gtk_table_set_col_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 6);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
/* the labels for histogram information */ /* the labels for histogram information */
for (i = 0; i < 7; i++) for (i = 0; i < 7; i++)
@ -371,7 +371,8 @@ histogram_tool_new_dialog ()
} }
gtk_widget_show (table); gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (main_vbox);
gtk_widget_show (htd->shell); gtk_widget_show (htd->shell);
return htd; return htd;
@ -379,23 +380,26 @@ histogram_tool_new_dialog ()
static void static void
histogram_tool_close_callback (GtkWidget *widget, histogram_tool_close_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (GTK_WIDGET_VISIBLE (htd->shell)) if (GTK_WIDGET_VISIBLE (htd->shell))
gtk_widget_hide (htd->shell); gtk_widget_hide (htd->shell);
active_tool->gdisp_ptr = NULL;
active_tool->drawable = NULL;
} }
static void static void
histogram_tool_value_callback (GtkWidget *widget, histogram_tool_value_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_VALUE) if (htd->channel != HISTOGRAM_VALUE)
{ {
@ -407,11 +411,11 @@ histogram_tool_value_callback (GtkWidget *widget,
static void static void
histogram_tool_red_callback (GtkWidget *widget, histogram_tool_red_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_RED) if (htd->channel != HISTOGRAM_RED)
{ {
@ -423,11 +427,11 @@ histogram_tool_red_callback (GtkWidget *widget,
static void static void
histogram_tool_green_callback (GtkWidget *widget, histogram_tool_green_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_GREEN) if (htd->channel != HISTOGRAM_GREEN)
{ {
@ -439,11 +443,11 @@ histogram_tool_green_callback (GtkWidget *widget,
static void static void
histogram_tool_blue_callback (GtkWidget *widget, histogram_tool_blue_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HistogramToolDialog *htd; HistogramToolDialog *htd;
htd = (HistogramToolDialog *) client_data; htd = (HistogramToolDialog *) data;
if (htd->channel != HISTOGRAM_BLUE) if (htd->channel != HISTOGRAM_BLUE)
{ {

View File

@ -26,34 +26,39 @@
#define HISTOGRAM_HEIGHT 150 #define HISTOGRAM_HEIGHT 150
typedef struct _HistogramToolDialog HistogramToolDialog; typedef struct _HistogramToolDialog HistogramToolDialog;
struct _HistogramToolDialog struct _HistogramToolDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *info_labels[7]; GtkWidget *info_labels[7];
GtkWidget *channel_menu; GtkWidget *channel_menu;
HistogramWidget *histogram; HistogramWidget *histogram;
GimpHistogram *hist; GimpHistogram *hist;
GtkWidget *gradient; GtkWidget *gradient;
gdouble mean; gdouble mean;
gdouble std_dev; gdouble std_dev;
gdouble median; gdouble median;
gdouble pixels; gdouble pixels;
gdouble count; gdouble count;
gdouble percentile; gdouble percentile;
GimpDrawable *drawable; GimpDrawable *drawable;
ImageMap image_map; ImageMap image_map;
gint channel; gint channel;
gint color; gint color;
}; };
/* histogram_tool functions */ /* histogram_tool functions */
Tool * tools_new_histogram_tool (void); Tool * tools_new_histogram_tool (void);
void tools_free_histogram_tool (Tool *); void tools_free_histogram_tool (Tool *tool);
void histogram_tool_initialize (GDisplay *); void histogram_tool_initialize (GDisplay *gdisp);
void histogram_tool_free (void); void histogram_tool_free (void);
void histogram_tool_histogram_range (HistogramWidget *, gint, gint, void *); void histogram_tool_histogram_range (HistogramWidget *hw,
gint start,
gint end,
gpointer data);
#endif /* __HISTOGRAM_TOOL_H__ */ #endif /* __HISTOGRAM_TOOL_H__ */

View File

@ -33,29 +33,24 @@
#define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK #define HUE_PARTITION_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200 #define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define DA_WIDTH 40 #define DA_WIDTH 40
#define DA_HEIGHT 20 #define DA_HEIGHT 20
#define HUE_PARTITION 0x0 #define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1 #define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2 #define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4 #define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8 #define DRAW 0x40
#define LIGHTNESS_TEXT 0x10 #define ALL 0xFF
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */ /* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation; typedef struct _HueSaturation HueSaturation;
struct _HueSaturation struct _HueSaturation
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the hue-saturation tool options */ /* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL; static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */ /* Local variables */
static int hue_transfer[6][256]; static gint hue_transfer[6][256];
static int lightness_transfer[6][256]; static gint lightness_transfer[6][256];
static int saturation_transfer[6][256]; static gint saturation_transfer[6][256];
static int default_colors[6][3] = static gint default_colors[6][3] =
{ {
{ 255, 0, 0 }, { 255, 0, 0 },
{ 255, 255, 0 }, { 255, 255, 0 },
{ 0, 255, 0 }, { 0, 255, 0 },
{ 0, 255, 255 }, { 0, 255, 255 },
{ 0, 0, 255 }, { 0, 0, 255 },
{ 255, 0, 255 } { 255, 0, 255 }
}; };
/* hue saturation action functions */ /* hue saturation action functions */
static void hue_saturation_control (Tool *, ToolAction, gpointer); static void hue_saturation_control (Tool *, ToolAction, gpointer);
static HueSaturationDialog * hue_saturation_new_dialog (void); static HueSaturationDialog * hue_saturation_dialog_new (void);
static void hue_saturation_update (HueSaturationDialog *, static void hue_saturation_update (HueSaturationDialog *,
int); gint);
static void hue_saturation_preview (HueSaturationDialog *); static void hue_saturation_preview (HueSaturationDialog *);
static void hue_saturation_reset_callback (GtkWidget *, gpointer);
static void hue_saturation_ok_callback (GtkWidget *, gpointer); static void hue_saturation_ok_callback (GtkWidget *, gpointer);
static void hue_saturation_cancel_callback (GtkWidget *, gpointer); static void hue_saturation_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_callback (GtkWidget *, gpointer); static void hue_saturation_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_R_callback (GtkWidget *, gpointer);
static void hue_saturation_Y_callback (GtkWidget *, gpointer);
static void hue_saturation_G_callback (GtkWidget *, gpointer);
static void hue_saturation_C_callback (GtkWidget *, gpointer);
static void hue_saturation_B_callback (GtkWidget *, gpointer);
static void hue_saturation_M_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer); static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer); gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer); static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
static void hue_saturation_hue_text_update (GtkWidget *, gpointer); gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer); static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer); gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *, static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *); HueSaturationDialog *);
/* hue saturation machinery */ /* hue saturation machinery */
void void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd) hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{ {
int value; gint value;
int hue; gint hue;
int i; gint i;
/* Calculate transfers */ /* Calculate transfers */
for (hue = 0; hue < 6; hue++) for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
} }
} }
/* hue saturation action functions */ /* hue saturation action functions */
static void static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
} }
Tool * Tool *
tools_new_hue_saturation () tools_new_hue_saturation (void)
{ {
Tool * tool; Tool * tool;
HueSaturation * private; HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void void
hue_saturation_initialize (GDisplay *gdisp) hue_saturation_initialize (GDisplay *gdisp)
{ {
int i; gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage))) if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{ {
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */ /* The "hue-saturation" dialog */
if (!hue_saturation_dialog) if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog (); hue_saturation_dialog = hue_saturation_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell)) if (!GTK_WIDGET_VISIBLE (hue_saturation_dialog->shell))
gtk_widget_show (hue_saturation_dialog->shell); gtk_widget_show (hue_saturation_dialog->shell);
@ -313,12 +300,14 @@ hue_saturation_initialize (GDisplay *gdisp)
} }
hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage); hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage);
hue_saturation_dialog->image_map = image_map_create (gdisp, hue_saturation_dialog->drawable); hue_saturation_dialog->image_map =
image_map_create (gdisp, hue_saturation_dialog->drawable);
hue_saturation_update (hue_saturation_dialog, ALL); hue_saturation_update (hue_saturation_dialog, ALL);
} }
void void
hue_saturation_free () hue_saturation_free (void)
{ {
if (hue_saturation_dialog) if (hue_saturation_dialog)
{ {
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map); image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL; hue_saturation_dialog->image_map = NULL;
} }
gtk_widget_destroy (hue_saturation_dialog->shell); gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/ /***************************/
static HueSaturationDialog * static HueSaturationDialog *
hue_saturation_new_dialog () hue_saturation_dialog_new (void)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
GtkWidget *main_vbox; GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table; GtkWidget *table;
GtkWidget *label; GtkWidget *label;
GtkWidget *slider; GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle; GtkWidget *toggle;
GtkWidget *radio_button; GtkWidget *radio_button;
GtkWidget *frame; GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
N_("M") N_("M")
}; };
GtkSignalFunc hue_partition_callbacks[] =
{
hue_saturation_master_callback,
hue_saturation_R_callback,
hue_saturation_Y_callback,
hue_saturation_G_callback,
hue_saturation_C_callback,
hue_saturation_B_callback,
hue_saturation_M_callback
};
hsd = g_new (HueSaturationDialog, 1); hsd = g_new (HueSaturationDialog, 1);
hsd->hue_partition = 0; hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE; hsd->preview = TRUE;
/* The shell and main vbox */ /* The shell and main vbox */
hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_satiration", hsd->shell = gimp_dialog_new (_("Hue-Saturation"), "hue_saturation",
tools_help_func, NULL, tools_help_func, NULL,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback, _("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE, hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback, _("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL); NULL);
main_vbox = gtk_vbox_new (FALSE, 2); main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* The main hbox containing hue partitions and sliders */ /* The main hbox containing hue partitions and sliders */
main_hbox = gtk_hbox_new (FALSE, 2); main_hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0);
/* The table containing hue partitions */ /* The table containing hue partitions */
table = gtk_table_new (7, 2, FALSE); table = gtk_table_new (7, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), table, FALSE, FALSE, 0);
/* the radio buttons for hue partitions */ /* the radio buttons for hue partitions */
@ -411,26 +396,30 @@ hue_saturation_new_dialog ()
{ {
radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]); radio_button = gtk_radio_button_new_with_label (group, hue_partition_names[i]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i) if (!i)
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 2, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
} }
else else
{ {
gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1, gtk_table_attach (GTK_TABLE (table), radio_button, 0, 1, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1, gtk_table_attach (GTK_TABLE (table), frame, 1, 2, i, i + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR); hsd->hue_partition_da[i - 1] = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT); gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK); DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1],
HUE_PARTITION_MASK);
gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event", gtk_signal_connect (GTK_OBJECT (hsd->hue_partition_da[i - 1]), "event",
(GtkSignalFunc) hue_saturation_hue_partition_events, GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd); hsd);
gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]); gtk_container_add (GTK_CONTAINER (frame), hsd->hue_partition_da[i - 1]);
@ -439,14 +428,16 @@ hue_saturation_new_dialog ()
} }
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) hue_partition_callbacks[i], GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd); hsd);
gtk_widget_show (radio_button); gtk_widget_show (radio_button);
} }
gtk_widget_show (table); gtk_widget_show (table);
/* The vbox for the table and preview toggle */ /* The vbox for the table and preview toggle */
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments")); label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */ /* The table containing sliders */
table = gtk_table_new (3, 3, FALSE); table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* Create the hue scale widget */ /* Create the hue scale widget */
label = gtk_label_new (_("Hue")); label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -180, 180.0, 1.0, 1.0, 0.0);
hsd->hue_data = GTK_ADJUSTMENT (data); hsd->hue_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->hue_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
hsd->hue_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1, gtk_widget_set_usize (spinbutton, 74, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
(GtkSignalFunc) hue_saturation_hue_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->hue_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_hue_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */ /* Create the lightness scale widget */
label = gtk_label_new (_("Lightness")); label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->lightness_data = GTK_ADJUSTMENT (data); hsd->lightness_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->lightness_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
hsd->lightness_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
(GtkSignalFunc) hue_saturation_lightness_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_lightness_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */ /* Create the saturation scale widget */
label = gtk_label_new (_("Saturation")); label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0); data = gtk_adjustment_new (0, -100.0, 100.0, 1.0, 1.0, 0.0);
hsd->saturation_data = GTK_ADJUSTMENT (data); hsd->saturation_data = GTK_ADJUSTMENT (data);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_widget_set_usize (slider, SLIDER_WIDTH, SLIDER_HEIGHT); slider = gtk_hscale_new (hsd->saturation_data);
gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
gtk_scale_set_digits (GTK_SCALE (slider), 0); gtk_scale_set_digits (GTK_SCALE (slider), 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3, gtk_table_attach (GTK_TABLE (table), slider, 1, 2, 2, 3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
2, 2);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
hsd->saturation_text = gtk_entry_new (); abox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT); spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3, gtk_widget_set_usize (spinbutton, 75, -1);
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2); gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed", gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
(GtkSignalFunc) hue_saturation_saturation_text_update, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_data), "value_changed",
GTK_SIGNAL_FUNC (hue_saturation_saturation_adjustment_update),
hsd); hsd);
gtk_widget_show (label); gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider); gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */ /* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), hsd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) hue_saturation_preview_update, GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd); hsd);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (main_hbox); gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox); gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void static void
hue_saturation_update (HueSaturationDialog *hsd, hue_saturation_update (HueSaturationDialog *hsd,
int update) gint update)
{ {
int i, j, b; gint i, j, b;
int rgb[3]; gint rgb[3];
unsigned char buf[DA_WIDTH * 3]; guchar buf[DA_WIDTH * 3];
char text[12];
if (update & HUE_SLIDER) if (update & HUE_SLIDER)
{ {
hsd->hue_data->value = hsd->hue[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed"); hsd->hue[hsd->hue_partition]);
} }
if (update & LIGHTNESS_SLIDER) if (update & LIGHTNESS_SLIDER)
{ {
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed"); hsd->lightness[hsd->hue_partition]);
} }
if (update & SATURATION_SLIDER) if (update & SATURATION_SLIDER)
{ {
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition]; gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed"); hsd->saturation[hsd->hue_partition]);
}
if (update & HUE_TEXT)
{
sprintf (text, "%0.0f", hsd->hue[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->hue_text), text);
}
if (update & LIGHTNESS_TEXT)
{
sprintf (text, "%0.0f", hsd->lightness[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->lightness_text), text);
}
if (update & SATURATION_TEXT)
{
sprintf (text, "%0.0f", hsd->saturation[hsd->hue_partition]);
gtk_entry_set_text (GTK_ENTRY (hsd->saturation_text), text);
} }
hue_saturation_calculate_transfers (hsd); hue_saturation_calculate_transfers (hsd);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
rgb[RED_PIX] = default_colors[i][RED_PIX]; rgb[RED_PIX] = default_colors[i][RED_PIX];
rgb[GREEN_PIX] = default_colors[i][GREEN_PIX]; rgb[GREEN_PIX] = default_colors[i][GREEN_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX]; rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb_to_hls (rgb, rgb + 1, rgb + 2); rgb_to_hls (rgb, rgb + 1, rgb + 2);
rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]]; rgb[RED_PIX] = hue_transfer[i][rgb[RED_PIX]];
rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]]; rgb[GREEN_PIX] = lightness_transfer[i][rgb[GREEN_PIX]];
rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]]; rgb[BLUE_PIX] = saturation_transfer[i][rgb[BLUE_PIX]];
hls_to_rgb (rgb, rgb + 1, rgb + 2); hls_to_rgb (rgb, rgb + 1, rgb + 2);
for (j = 0; j < DA_WIDTH; j++) for (j = 0; j < DA_WIDTH; j++)
for (b = 0; b < 3; b++) for (b = 0; b < 3; b++)
buf[j * 3 + b] = (unsigned char) rgb[b]; buf[j * 3 + b] = (guchar) rgb[b];
for (j = 0; j < DA_HEIGHT; j++) for (j = 0; j < DA_HEIGHT; j++)
gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]), buf, 0, j, DA_WIDTH); gtk_preview_draw_row (GTK_PREVIEW (hsd->hue_partition_da[i]),
buf, 0, j, DA_WIDTH);
if (update & DRAW) if (update & DRAW)
gtk_widget_draw (hsd->hue_partition_da[i], NULL); gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd) hue_saturation_preview (HueSaturationDialog *hsd)
{ {
if (!hsd->image_map) if (!hsd->image_map)
g_warning ("hue_saturation_preview(): No image map"); {
g_warning ("hue_saturation_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd); image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void static void
hue_saturation_ok_callback (GtkWidget *widget, hue_saturation_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
hsd->hue[hsd->hue_partition] = 0.0;
hsd->lightness[hsd->hue_partition] = 0.0;
hsd->saturation[hsd->hue_partition] = 0.0;
hue_saturation_update (hsd, ALL);
if (hsd->preview)
hue_saturation_preview (hsd);
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void static void
hue_saturation_cancel_callback (GtkWidget *widget, hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data; hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell)) if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell); gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
} }
static void static void
hue_saturation_master_callback (GtkWidget *widget, hue_saturation_partition_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
HueRange partition;
hsd = (HueSaturationDialog *) data;
partition = (HueRange) gtk_object_get_data (GTK_OBJECT (widget),
"hue_partition");
hsd->hue_partition = partition;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 0;
hue_saturation_update (hsd, ALL); hue_saturation_update (hsd, ALL);
} }
static void static void
hue_saturation_R_callback (GtkWidget *widget, hue_saturation_preview_update (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 1;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_Y_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 2;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_G_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 3;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_C_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 4;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_B_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 5;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_M_callback (GtkWidget *widget,
gpointer client_data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd->hue_partition = 6;
hue_saturation_update (hsd, ALL);
}
static void
hue_saturation_preview_update (GtkWidget *w,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data; hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
hsd->preview = TRUE; hsd->preview = TRUE;
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
} }
static void static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment, hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (hsd->hue[hsd->hue_partition] != adjustment->value) if (hsd->hue[hsd->hue_partition] != adjustment->value)
{ {
hsd->hue[hsd->hue_partition] = adjustment->value; hsd->hue[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, HUE_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment, hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (hsd->lightness[hsd->hue_partition] != adjustment->value) if (hsd->lightness[hsd->hue_partition] != adjustment->value)
{ {
hsd->lightness[hsd->hue_partition] = adjustment->value; hsd->lightness[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, LIGHTNESS_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
} }
static void static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment, hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
HueSaturationDialog *hsd; HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value) if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{ {
hsd->saturation[hsd->hue_partition] = adjustment->value; hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | DRAW); hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_hue_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -180, 180);
if ((int) hsd->hue[hsd->hue_partition] != value)
{
hsd->hue[hsd->hue_partition] = value;
hue_saturation_update (hsd, HUE_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_lightness_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->lightness[hsd->hue_partition] != value)
{
hsd->lightness[hsd->hue_partition] = value;
hue_saturation_update (hsd, LIGHTNESS_SLIDER | DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);
}
}
static void
hue_saturation_saturation_text_update (GtkWidget *w,
gpointer data)
{
HueSaturationDialog *hsd;
char *str;
int value;
str = gtk_entry_get_text (GTK_ENTRY (w));
hsd = (HueSaturationDialog *) data;
value = BOUNDS (((int) atof (str)), -100, 100);
if ((int) hsd->saturation[hsd->hue_partition] != value)
{
hsd->saturation[hsd->hue_partition] = value;
hue_saturation_update (hsd, SATURATION_SLIDER | DRAW);
if (hsd->preview) if (hsd->preview)
hue_saturation_preview (hsd); hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange; } HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog; typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog struct _HueSaturationDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *gimage_name;
GtkWidget *hue_text;
GtkWidget *lightness_text;
GtkWidget *saturation_text;
GtkWidget *hue_partition_da[6];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
GimpDrawable *drawable; GtkWidget *hue_partition_da[6];
ImageMap image_map;
double hue[7]; GtkAdjustment *hue_data;
double lightness[7]; GtkAdjustment *lightness_data;
double saturation[7]; GtkAdjustment *saturation_data;
int hue_partition; GimpDrawable *drawable;
gint preview; ImageMap image_map;
gdouble hue[7];
gdouble lightness[7];
gdouble saturation[7];
HueRange hue_partition;
gboolean preview;
}; };
/* hue-saturation functions */ Tool * tools_new_hue_saturation (void);
Tool * tools_new_hue_saturation (void); void tools_free_hue_saturation (Tool *tool);
void tools_free_hue_saturation (Tool *);
void hue_saturation_initialize (GDisplay *); void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (void); void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *); void hue_saturation (PixelRegion *srcPR,
PixelRegion *destPR,
void *data);
void hue_saturation_calculate_transfers (HueSaturationDialog *hsd); void hue_saturation_calculate_transfers (HueSaturationDialog *hsd);
#endif /* __HUE_SATURATION_H__ */ #endif /* __HUE_SATURATION_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -20,11 +20,10 @@
#include "tools.h" #include "tools.h"
/* hue-saturation functions */ Tool * tools_new_levels (void);
Tool * tools_new_levels (void); void tools_free_levels (Tool *tool);
void tools_free_levels (Tool *);
void levels_initialize (GDisplay *); void levels_initialize (GDisplay *gdisp);
void levels_free (void); void levels_free (void);
#endif /* __LEVELS_H__ */ #endif /* __LEVELS_H__ */

View File

@ -15,12 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "drawable.h" #include "drawable.h"
#include "gdisplay.h" #include "gdisplay.h"
@ -33,32 +27,33 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 55
/* the posterize structures */ /* the posterize structures */
typedef struct _Posterize Posterize; typedef struct _Posterize Posterize;
struct _Posterize struct _Posterize
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
typedef struct _PosterizeDialog PosterizeDialog; typedef struct _PosterizeDialog PosterizeDialog;
struct _PosterizeDialog struct _PosterizeDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *levels_text;
GimpDrawable *drawable; GtkAdjustment *levels_data;
ImageMap image_map;
int levels;
gint preview; GimpDrawable *drawable;
ImageMap image_map;
GimpLut *lut; gint levels;
gboolean preview;
GimpLut *lut;
}; };
/* the posterize tool options */ /* the posterize tool options */
static ToolOptions *posterize_options = NULL; static ToolOptions *posterize_options = NULL;
@ -69,14 +64,14 @@ static PosterizeDialog *posterize_dialog = NULL;
/* posterize action functions */ /* posterize action functions */
static void posterize_control (Tool *, ToolAction, gpointer); static void posterize_control (Tool *, ToolAction, gpointer);
static PosterizeDialog * posterize_new_dialog (void); static PosterizeDialog * posterize_dialog_new (void);
static void posterize_preview (PosterizeDialog *);
static void posterize_ok_callback (GtkWidget *, gpointer);
static void posterize_cancel_callback (GtkWidget *, gpointer);
static void posterize_preview_update (GtkWidget *, gpointer);
static void posterize_levels_text_update (GtkWidget *, gpointer);
static void posterize_preview (PosterizeDialog *);
static void posterize_reset_callback (GtkWidget *, gpointer);
static void posterize_ok_callback (GtkWidget *, gpointer);
static void posterize_cancel_callback (GtkWidget *, gpointer);
static void posterize_preview_update (GtkWidget *, gpointer);
static void posterize_levels_adjustment_update (GtkAdjustment *, gpointer);
/* posterize select action functions */ /* posterize select action functions */
@ -104,7 +99,7 @@ posterize_control (Tool *tool,
} }
Tool * Tool *
tools_new_posterize () tools_new_posterize (void)
{ {
Tool * tool; Tool * tool;
Posterize * private; Posterize * private;
@ -116,13 +111,6 @@ tools_new_posterize ()
tools_register (POSTERIZE, posterize_options); tools_register (POSTERIZE, posterize_options);
} }
/* The posterize dialog */
if (!posterize_dialog)
posterize_dialog = posterize_new_dialog ();
else
if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell))
gtk_widget_show (posterize_dialog->shell);
tool = tools_new_tool (POSTERIZE); tool = tools_new_tool (POSTERIZE);
private = g_new (Posterize, 1); private = g_new (Posterize, 1);
@ -161,32 +149,37 @@ posterize_initialize (GDisplay *gdisp)
/* The posterize dialog */ /* The posterize dialog */
if (!posterize_dialog) if (!posterize_dialog)
posterize_dialog = posterize_new_dialog (); posterize_dialog = posterize_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell)) if (!GTK_WIDGET_VISIBLE (posterize_dialog->shell))
gtk_widget_show (posterize_dialog->shell); gtk_widget_show (posterize_dialog->shell);
posterize_dialog->levels = 3;
posterize_dialog->drawable = gimage_active_drawable (gdisp->gimage); posterize_dialog->drawable = gimage_active_drawable (gdisp->gimage);
posterize_dialog->image_map = posterize_dialog->image_map =
image_map_create (gdisp, posterize_dialog->drawable); image_map_create (gdisp, posterize_dialog->drawable);
gtk_adjustment_set_value (GTK_ADJUSTMENT (posterize_dialog->levels_data), 3);
if (posterize_dialog->preview) if (posterize_dialog->preview)
posterize_preview (posterize_dialog); posterize_preview (posterize_dialog);
} }
/**********************/ /**********************/
/* Posterize dialog */ /* Posterize dialog */
/**********************/ /**********************/
static PosterizeDialog * static PosterizeDialog *
posterize_new_dialog () posterize_dialog_new (void)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *label; GtkWidget *label;
GtkWidget *spinbutton;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data;
pd = g_new (PosterizeDialog, 1); pd = g_new (PosterizeDialog, 1);
pd->preview = TRUE; pd->preview = TRUE;
@ -200,6 +193,8 @@ posterize_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), posterize_reset_callback,
pd, NULL, TRUE, FALSE,
_("OK"), posterize_ok_callback, _("OK"), posterize_ok_callback,
pd, NULL, TRUE, FALSE, pd, NULL, TRUE, FALSE,
_("Cancel"), posterize_cancel_callback, _("Cancel"), posterize_cancel_callback,
@ -208,39 +203,43 @@ posterize_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pd->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pd->shell)->vbox), vbox);
/* Horizontal box for levels text widget */ /* Horizontal box for levels text widget */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Posterize Levels: ")); label = gtk_label_new (_("Posterize Levels:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
gtk_widget_show (label); gtk_widget_show (label);
/* levels text */ /* levels spinbutton */
pd->levels_text = gtk_entry_new (); data = gtk_adjustment_new (3, 2, 256, 1.0, 10.0, 0.0);
gtk_entry_set_text (GTK_ENTRY (pd->levels_text), "3"); pd->levels_data = GTK_ADJUSTMENT (data);
gtk_widget_set_usize (pd->levels_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), pd->levels_text, TRUE, FALSE, 0); spinbutton = gtk_spin_button_new (pd->levels_data, 1.0, 0);
gtk_signal_connect (GTK_OBJECT (pd->levels_text), "changed", gtk_widget_set_usize (spinbutton, 75, -1);
(GtkSignalFunc) posterize_levels_text_update, gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (pd->levels_data), "value_changed",
GTK_SIGNAL_FUNC (posterize_levels_adjustment_update),
pd); pd);
gtk_widget_show (pd->levels_text);
gtk_widget_show (spinbutton);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), pd->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), pd->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) posterize_preview_update, GTK_SIGNAL_FUNC (posterize_preview_update),
pd); pd);
gtk_widget_show (label); gtk_widget_show (label);
@ -257,21 +256,36 @@ static void
posterize_preview (PosterizeDialog *pd) posterize_preview (PosterizeDialog *pd)
{ {
if (!pd->image_map) if (!pd->image_map)
g_warning ("posterize_preview(): No image map"); {
g_warning ("posterize_preview(): No image map");
return;
}
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
posterize_lut_setup(pd->lut, pd->levels, gimp_drawable_bytes(pd->drawable)); posterize_lut_setup (pd->lut, pd->levels, gimp_drawable_bytes(pd->drawable));
image_map_apply (pd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (pd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
(void *) pd->lut); (void *) pd->lut);
active_tool->preserve = FALSE; active_tool->preserve = FALSE;
} }
static void static void
posterize_ok_callback (GtkWidget *widget, posterize_reset_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) client_data; pd = (PosterizeDialog *) data;
gtk_adjustment_set_value (GTK_ADJUSTMENT (pd->levels_data), 3);
}
static void
posterize_ok_callback (GtkWidget *widget,
gpointer data)
{
PosterizeDialog *pd;
pd = (PosterizeDialog *) data;
if (GTK_WIDGET_VISIBLE (pd->shell)) if (GTK_WIDGET_VISIBLE (pd->shell))
gtk_widget_hide (pd->shell); gtk_widget_hide (pd->shell);
@ -279,12 +293,13 @@ posterize_ok_callback (GtkWidget *widget,
active_tool->preserve = TRUE; active_tool->preserve = TRUE;
if (!pd->preview) if (!pd->preview)
{ {
posterize_lut_setup(pd->lut, pd->levels, posterize_lut_setup( pd->lut, pd->levels,
gimp_drawable_bytes(pd->drawable)); gimp_drawable_bytes (pd->drawable));
image_map_apply (pd->image_map, (ImageMapApplyFunc)gimp_lut_process_2, image_map_apply (pd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
(void *) pd->lut); (void *) pd->lut);
} }
if (pd->image_map) if (pd->image_map)
image_map_commit (pd->image_map); image_map_commit (pd->image_map);
@ -298,11 +313,12 @@ posterize_ok_callback (GtkWidget *widget,
static void static void
posterize_cancel_callback (GtkWidget *widget, posterize_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) client_data; pd = (PosterizeDialog *) data;
if (GTK_WIDGET_VISIBLE (pd->shell)) if (GTK_WIDGET_VISIBLE (pd->shell))
gtk_widget_hide (pd->shell); gtk_widget_hide (pd->shell);
@ -321,14 +337,14 @@ posterize_cancel_callback (GtkWidget *widget,
} }
static void static void
posterize_preview_update (GtkWidget *w, posterize_preview_update (GtkWidget *widget,
gpointer data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
pd = (PosterizeDialog *) data; pd = (PosterizeDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
pd->preview = TRUE; pd->preview = TRUE;
posterize_preview (pd); posterize_preview (pd);
@ -338,20 +354,17 @@ posterize_preview_update (GtkWidget *w,
} }
static void static void
posterize_levels_text_update (GtkWidget *w, posterize_levels_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
PosterizeDialog *pd; PosterizeDialog *pd;
char *str;
int value;
pd = (PosterizeDialog *) data; pd = (PosterizeDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), 2, 256);
if (value != pd->levels) if (pd->levels != adjustment->value)
{ {
pd->levels = value; pd->levels = adjustment->value;
if (pd->preview) if (pd->preview)
posterize_preview (pd); posterize_preview (pd);
} }

View File

@ -20,10 +20,9 @@
#include "tools.h" #include "tools.h"
/* by_color select functions */ Tool * tools_new_posterize (void);
Tool * tools_new_posterize (void); void tools_free_posterize (Tool *tool);
void tools_free_posterize (Tool *);
void posterize_initialize (GDisplay *); void posterize_initialize (GDisplay *gdisp);
#endif /* __POSTERIZE_H__ */ #endif /* __POSTERIZE_H__ */

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "appenv.h" #include "appenv.h"
#include "drawable.h" #include "drawable.h"
#include "general.h" #include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256 #define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150 #define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */ /* the threshold structures */
typedef struct _Threshold Threshold; typedef struct _Threshold Threshold;
struct _Threshold struct _Threshold
{ {
int x, y; /* coords for last mouse click */ gint x, y; /* coords for last mouse click */
}; };
/* the threshold tool options */ /* the threshold tool options */
static ToolOptions *threshold_options = NULL; static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */ /* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL; static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */ /* threshold action functions */
static void threshold_control (Tool *, ToolAction, gpointer); static void threshold_control (Tool *, ToolAction, gpointer);
static ThresholdDialog * threshold_new_dialog (void); static ThresholdDialog * threshold_dialog_new (void);
static void threshold_update (ThresholdDialog *,
gint);
static void threshold_preview (ThresholdDialog *); static void threshold_preview (ThresholdDialog *);
static void threshold_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer); static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer); static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer); static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer); static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
static void threshold_high_threshold_text_update (GtkWidget *, gpointer); gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold (PixelRegion *, PixelRegion *, void *); static void threshold (PixelRegion *, PixelRegion *, void *);
static void threshold_histogram_range (HistogramWidget *, int, int, void *); static void threshold_histogram_range (HistogramWidget *, gint, gint,
gpointer);
/* threshold machinery */ /* threshold machinery */
void void
threshold_2 (void *user_data, threshold_2 (void *data,
PixelRegion *srcPR, PixelRegion *srcPR,
PixelRegion *destPR) PixelRegion *destPR)
{ {
/* this function just re-orders the arguments so we can use /* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */ * pixel_regions_process_paralell
threshold(srcPR, destPR, user_data); */
threshold (srcPR, destPR, data);
} }
static void static void
threshold (PixelRegion *srcPR, threshold (PixelRegion *srcPR,
PixelRegion *destPR, PixelRegion *destPR,
void *user_data) void *data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
unsigned char *src, *s; unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b; int w, h, b;
int value; int value;
td = (ThresholdDialog *) user_data; td = (ThresholdDialog *) data;
h = srcPR->h; h = srcPR->h;
src = srcPR->data; src = srcPR->data;
@ -128,28 +133,6 @@ threshold (PixelRegion *srcPR,
} }
} }
static void
threshold_histogram_range (HistogramWidget *w,
int start,
int end,
void *user_data)
{
ThresholdDialog *td;
char text[12];
td = (ThresholdDialog *) user_data;
td->low_threshold = start;
td->high_threshold = end;
sprintf (text, "%d", start);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), text);
sprintf (text, "%d", end);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), text);
if (td->preview)
threshold_preview (td);
}
/* threshold action functions */ /* threshold action functions */
static void static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
} }
Tool * Tool *
tools_new_threshold () tools_new_threshold (void)
{ {
Tool * tool; Tool * tool;
Threshold * private; Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
tools_register (THRESHOLD, threshold_options); tools_register (THRESHOLD, threshold_options);
} }
/* The threshold dialog */
if (! threshold_dialog)
threshold_dialog = threshold_new_dialog ();
else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell);
tool = tools_new_tool (THRESHOLD); tool = tools_new_tool (THRESHOLD);
private = g_new (Threshold, 1); private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private; thresh = (Threshold *) tool->private;
/* Close the color select dialog */ /* Close the threshold dialog */
if (threshold_dialog) if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog); threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */ /* The threshold dialog */
if (!threshold_dialog) if (!threshold_dialog)
threshold_dialog = threshold_new_dialog (); threshold_dialog = threshold_dialog_new ();
else else
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell)) if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell); gtk_widget_show (threshold_dialog->shell);
threshold_dialog->low_threshold = 127;
threshold_dialog->high_threshold = 255;
threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage); threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage);
threshold_dialog->color = drawable_color (threshold_dialog->drawable); threshold_dialog->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map = threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist, gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable); threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram, histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist); threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram, gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog->low_threshold, threshold_dialog);
threshold_dialog->high_threshold);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview) if (threshold_dialog->preview)
threshold_preview (threshold_dialog); threshold_preview (threshold_dialog);
} }
/**********************/ /**********************/
/* Threshold dialog */ /* Threshold dialog */
/**********************/ /**********************/
static ThresholdDialog * static ThresholdDialog *
threshold_new_dialog () threshold_dialog_new (void)
{ {
ThresholdDialog *td; ThresholdDialog *td;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label; GtkWidget *label;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *toggle; GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1); td = g_new (ThresholdDialog, 1);
td->preview = TRUE; td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback, _("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE, td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback, _("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL); NULL);
vbox = gtk_vbox_new (FALSE, 2); vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* Horizontal box for threshold text widget */ /* Horizontal box for threshold text widget */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Threshold Range: ")); label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label); gtk_widget_show (label);
/* low threshold text */ /* low threshold spinbutton */
td->low_threshold_text = gtk_entry_new (); data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127"); td->low_threshold_data = GTK_ADJUSTMENT (data);
gtk_widget_set_usize (td->low_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->low_threshold_text, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->low_threshold_text), "changed",
(GtkSignalFunc) threshold_low_threshold_text_update,
td);
gtk_widget_show (td->low_threshold_text);
/* high threshold text */ spinbutton = gtk_spin_button_new (td->low_threshold_data, 1.0, 0);
td->high_threshold_text = gtk_entry_new (); gtk_widget_set_usize (spinbutton, 75, -1);
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255"); gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_widget_set_usize (td->high_threshold_text, TEXT_WIDTH, 25);
gtk_box_pack_start (GTK_BOX (hbox), td->high_threshold_text, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (td->low_threshold_data), "value_changed",
gtk_signal_connect (GTK_OBJECT (td->high_threshold_text), "changed", GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
(GtkSignalFunc) threshold_high_threshold_text_update,
td); td);
gtk_widget_show (td->high_threshold_text);
gtk_widget_show (spinbutton);
/* high threshold spinbutton */
data = gtk_adjustment_new (td->high_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->high_threshold_data = GTK_ADJUSTMENT (data);
spinbutton = gtk_spin_button_new (td->high_threshold_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (td->high_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_high_threshold_adjustment_update),
td);
gtk_widget_show (spinbutton);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* The threshold histogram */ /* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
@ -334,55 +328,97 @@ threshold_new_dialog ()
td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT); td->histogram = histogram_widget_new (HISTOGRAM_WIDTH, HISTOGRAM_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged", gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range, GTK_SIGNAL_FUNC (threshold_histogram_range),
(void*)td); td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
gtk_widget_show (GTK_WIDGET(td->histogram)); gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame); gtk_widget_show (frame);
gtk_widget_show (hbox); gtk_widget_show (hbox);
/* Horizontal box for preview */ /* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2); hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* The preview toggle */ /* The preview toggle */
toggle = gtk_check_button_new_with_label (_("Preview")); toggle = gtk_check_button_new_with_label (_("Preview"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), td->preview);
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled", gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) threshold_preview_update, GTK_SIGNAL_FUNC (threshold_preview_update),
td); td);
gtk_widget_show (label);
gtk_widget_show (toggle); gtk_widget_show (toggle);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtk_widget_show (vbox); gtk_widget_show (vbox);
gtk_widget_show (td->shell); gtk_widget_show (td->shell);
/* This code is so far removed from the histogram creation because the
function histogram_range requires a non-NULL drawable, and that
doesn't happen until after the top-level dialog is shown. */
histogram_widget_range (td->histogram, td->low_threshold, td->high_threshold);
return td; return td;
} }
static void
threshold_update (ThresholdDialog *td,
gint update)
{
if (update & LOW)
{
gtk_adjustment_set_value (td->low_threshold_data, td->low_threshold);
}
if (update & HIGH)
{
gtk_adjustment_set_value (td->high_threshold_data, td->high_threshold);
}
if (update & HISTOGRAM)
{
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
}
}
static void static void
threshold_preview (ThresholdDialog *td) threshold_preview (ThresholdDialog *td)
{ {
if (!td->image_map) if (!td->image_map)
g_warning ("threshold_preview(): No image map"); {
image_map_apply (td->image_map, threshold, (void *) td); g_warning ("threshold_preview(): No image map");
return;
}
active_tool->preserve = TRUE;
image_map_apply (td->image_map, threshold, td);
active_tool->preserve = FALSE;
}
static void
threshold_reset_callback (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = 127.0;
td->high_threshold = 255.0;
threshold_update (td, ALL);
if (td->preview)
threshold_preview (td);
} }
static void static void
threshold_ok_callback (GtkWidget *widget, threshold_ok_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview) if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td); image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map) if (td->image_map)
image_map_commit (td->image_map); image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void static void
threshold_cancel_callback (GtkWidget *widget, threshold_cancel_callback (GtkWidget *widget,
gpointer client_data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) client_data; td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell)) if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell); gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
} }
static void static void
threshold_preview_update (GtkWidget *w, threshold_preview_update (GtkWidget *widget,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active) if (GTK_TOGGLE_BUTTON (widget)->active)
{ {
td->preview = TRUE; td->preview = TRUE;
threshold_preview (td); threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
} }
static void static void
threshold_low_threshold_text_update (GtkWidget *w, threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), 0, td->high_threshold);
if (value != td->low_threshold) if (td->low_threshold != adjustment->value)
{ {
td->low_threshold = value; td->low_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void static void
threshold_high_threshold_text_update (GtkWidget *w, threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data) gpointer data)
{ {
ThresholdDialog *td; ThresholdDialog *td;
char *str;
int value;
td = (ThresholdDialog *) data; td = (ThresholdDialog *) data;
str = gtk_entry_get_text (GTK_ENTRY (w));
value = BOUNDS (((int) atof (str)), td->low_threshold, 255);
if (value != td->high_threshold) if (td->high_threshold != adjustment->value)
{ {
td->high_threshold = value; td->high_threshold = adjustment->value;
histogram_widget_range (td->histogram,
td->low_threshold, threshold_update (td, HISTOGRAM);
td->high_threshold);
if (td->preview) if (td->preview)
threshold_preview (td); threshold_preview (td);
} }
} }
static void
threshold_histogram_range (HistogramWidget *widget,
gint start,
gint end,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
td->low_threshold = start;
td->high_threshold = end;
threshold_update (td, LOW | HIGH);
if (td->preview)
threshold_preview (td);
}

View File

@ -25,28 +25,33 @@
#include "tools.h" #include "tools.h"
typedef struct _ThresholdDialog ThresholdDialog; typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog struct _ThresholdDialog
{ {
GtkWidget *shell; GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text; GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram; HistogramWidget *histogram;
GimpHistogram *hist; GimpHistogram *hist;
GimpDrawable *drawable; GimpDrawable *drawable;
ImageMap image_map; ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
gint preview; gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
}; };
/* by_color select functions */ Tool * tools_new_threshold (void);
Tool * tools_new_threshold (void); void tools_free_threshold (Tool *tool);
void tools_free_threshold (Tool *);
void threshold_initialize (GDisplay *); void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *, PixelRegion *, PixelRegion *); void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */ #endif /* __THRESHOLD_H__ */

View File

@ -802,7 +802,17 @@ tools_initialize (ToolType tool_type,
if (tool_info[(gint) tool_type].init_func && !gdisp) if (tool_info[(gint) tool_type].init_func && !gdisp)
tool_type = RECT_SELECT; tool_type = RECT_SELECT;
gimp_context_set_tool (gimp_context_get_user (), tool_type); /* Force the emission of the "tool_changed" signal
*/
if (active_tool->type == tool_type)
{
gtk_signal_emit_by_name (GTK_OBJECT (gimp_context_get_user ()),
"tool_changed", tool_type);
}
else
{
gimp_context_set_tool (gimp_context_get_user (), tool_type);
}
if (tool_info[(gint) tool_type].init_func) if (tool_info[(gint) tool_type].init_func)
{ {

View File

@ -39,10 +39,11 @@ static void color_notebook_cancel_callback (GtkWidget *, gpointer);
static void color_notebook_update_callback (void *, int, int, int); static void color_notebook_update_callback (void *, int, int, int);
static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *, static void color_notebook_page_switch (GtkWidget *, GtkNotebookPage *,
guint); guint);
static void color_notebook_help_func (gpointer data); static void color_notebook_help_func (gchar *data);
/* information we keep on each registered colour selector */ /* information we keep on each registered colour selector */
typedef struct _ColorSelectorInfo { typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */ char *name; /* label used in notebook tab */
char *help_page; char *help_page;
GimpColorSelectorMethods m; GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next; struct _ColorSelectorInfo *next;
} ColorSelectorInfo; } ColorSelectorInfo;
typedef struct _ColorSelectorInstance { typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook; _ColorNotebook *color_notebook;
ColorSelectorInfo *info; ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */ GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell = cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection", gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp, color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE, GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
} }
static void static void
color_notebook_help_func (gpointer data) color_notebook_help_func (gchar *data)
{ {
ColorNotebookP cnp; ColorNotebookP cnp;
gchar *help_path; gchar *help_path;

View File

@ -99,21 +99,6 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 }, { { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
"file/dialogs/preferences/preferences.html", NULL }, "file/dialogs/preferences/preferences.html", NULL },
/* <Toolbox>/File/Help */
{ { N_("/File/Help/tearoff1"), NULL, NULL, 0, "<Tearoff>" },
NULL, NULL },
{ { N_("/File/Help/Help..."), "F1", help_help_cmd_callback, 0 },
"file/dialogs/help.html", NULL },
{ { N_("/File/Help/Context Help..."), "<shift>F1", help_context_help_cmd_callback, 0 },
"file/dialogs/context_help.html", NULL },
{ { N_("/File/Help/Tip of the day..."), NULL, help_tips_cmd_callback, 0 },
"file/dialogs/tip_of_the_day.html", NULL },
{ { N_("/File/Help/About..."), NULL, help_about_cmd_callback, 0 },
"file/dialogs/about.html", NULL },
{ { N_("/File/Help/Dump Items (Debug)"), NULL, help_debug_cmd_callback, 0 },
NULL, NULL },
/* <Toolbox>/File/Dialogs */ /* <Toolbox>/File/Dialogs */
{ { N_("/File/---"), NULL, NULL, 0, "<Separator>" }, { { N_("/File/---"), NULL, NULL, 0, "<Separator>" },

View File

@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <string.h>
#include "gimpui.h" #include "gimpui.h"
#include "libgimp/gimpsizeentry.h" #include "libgimp/gimpsizeentry.h"
@ -324,50 +321,73 @@ gimp_option_menu_new (GtkSignalFunc menu_item_callback,
} }
GtkWidget * GtkWidget *
gimp_radio_group_new (GtkSignalFunc radio_button_callback, gimp_radio_group_new (gboolean in_frame,
gpointer initial, /* user_data */ gchar *frame_title,
/* specify radio buttons as va_list: /* specify radio buttons as va_list:
* gchar *label, * gchar *label,
* gpointer data, * GtkSignalFunc callback,
* gpointer user_data, * gpointer data,
* gpointer user_data,
* GtkWidget **widget_ptr,
* gboolean active,
*/ */
...) ...)
{ {
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *frame;
GtkWidget *button; GtkWidget *button;
GSList *group; GSList *group;
/* radio button variables */ /* radio button variables */
gchar *label; gchar *label;
gpointer data; GtkSignalFunc callback;
gpointer user_data; gpointer data;
gpointer user_data;
GtkWidget **widget_ptr;
gboolean active;
va_list args; va_list args;
vbox = gtk_vbox_new (FALSE, 1); vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
if (in_frame)
{
frame = gtk_frame_new (frame_title);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
}
group = NULL; group = NULL;
/* create the radio buttons */ /* create the radio buttons */
va_start (args, initial); va_start (args, frame_title);
label = va_arg (args, gchar*); label = va_arg (args, gchar*);
while (label) while (label)
{ {
data = va_arg (args, gpointer); callback = va_arg (args, GtkSignalFunc);
user_data = va_arg (args, gpointer); data = va_arg (args, gpointer);
user_data = va_arg (args, gpointer);
widget_ptr = va_arg (args, gpointer);
active = va_arg (args, gboolean);
button = gtk_radio_button_new_with_label (group, label); button = gtk_radio_button_new_with_label (group, label);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (button), "toggled", gtk_signal_connect (GTK_OBJECT (button), "toggled",
(GtkSignalFunc) radio_button_callback, GTK_SIGNAL_FUNC (callback),
data); data);
gtk_object_set_user_data (GTK_OBJECT (button), user_data);
if (user_data)
gtk_object_set_user_data (GTK_OBJECT (button), user_data);
if (widget_ptr)
*widget_ptr = button;
/* press the initially active radio button */ /* press the initially active radio button */
if (user_data == initial) if (active)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_widget_show (button); gtk_widget_show (button);
@ -376,6 +396,9 @@ gimp_radio_group_new (GtkSignalFunc radio_button_callback,
} }
va_end (args); va_end (args);
if (in_frame)
return frame;
return vbox; return vbox;
} }
@ -400,7 +423,7 @@ gimp_spin_button_new (GtkObject **adjustment, /* return value */
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton), gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
GTK_SHADOW_NONE); GTK_SHADOW_NONE);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
gtk_widget_set_usize (spinbutton, 75, 0); gtk_widget_set_usize (spinbutton, 75, -1);
return spinbutton; return spinbutton;
} }
@ -787,11 +810,12 @@ struct _MessageBox
static void gimp_message_box_close_callback (GtkWidget *, gpointer); static void gimp_message_box_close_callback (GtkWidget *, gpointer);
#define MESSAGE_STRING_BUFFER 80 /* some buffer size, not critical */ #define MESSAGE_BOX_MAXIMUM 7 /* the maximum number of concucrrent
#define MESSAGE_BOX_MAXIMUM 7 /* the maximum number of concucrrent dialog boxes */ * dialog boxes
*/
static int message_pool = MESSAGE_BOX_MAXIMUM; static gint message_pool = MESSAGE_BOX_MAXIMUM;
static gchar message_box_last[MESSAGE_STRING_BUFFER]; static gchar *message_box_last = NULL;
GtkWidget * GtkWidget *
gimp_message_box (gchar *message, gimp_message_box (gchar *message,
@ -803,13 +827,13 @@ gimp_message_box (gchar *message,
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *label; GtkWidget *label;
static int repeat_count; static gint repeat_count;
/* arguably, if message_pool <= 0 we could print to stdout */ /* arguably, if message_pool <= 0 we could print to stdout */
if (!message || message_pool <= 0) if (!message || message_pool <= 0)
return NULL; return NULL;
if (!strcmp (message_box_last, message)) if (message_box_last && !strcmp (message_box_last, message))
{ {
repeat_count++; repeat_count++;
if (repeat_count == 3) if (repeat_count == 3)
@ -820,8 +844,9 @@ gimp_message_box (gchar *message,
else else
{ {
repeat_count = 0; repeat_count = 0;
if (strlen (message) < MESSAGE_STRING_BUFFER) if (message_box_last)
strcpy (message_box_last, message); g_free (message_box_last);
message_box_last = g_strdup (message);
} }
if (message_pool == 1) if (message_pool == 1)

View File

@ -93,13 +93,16 @@ GtkWidget * gimp_option_menu_new (GtkSignalFunc menu_item_callback,
...); ...);
GtkWidget * gimp_radio_group_new (GtkSignalFunc radio_button_callback, GtkWidget * gimp_radio_group_new (gboolean in_frame,
gpointer initial, /* user_data */ gchar *frame_title,
/* specify radio buttons as va_list: /* specify radio buttons as va_list:
* gchar *label, * gchar *label,
* GtkSignalFunc callback,
* gpointer data, * gpointer data,
* gpointer user_data, * gpointer user_data,
* GtkWidget **widget_ptr,
* gboolean active,
*/ */
...); ...);