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>
* 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
* 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 "color_balance.h"
#include "color_transfer.h"
#include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h"
#include "gimpui.h"
#include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
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_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */
if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog ();
color_balance_dialog = color_balance_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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++)
{
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->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->image_map =
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 dialog */
/**************************/
static ColorBalanceDialog *
color_balance_new_dialog (void)
color_balance_dialog_new (void)
{
ColorBalanceDialog *cbd;
GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights")
};
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL);
vbox = gtk_vbox_new (FALSE, 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label);
/* 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);
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);
/* 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);
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);
/* 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);
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 */
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);
/* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan"));
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_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);
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_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_FUNC (color_balance_cr_adjustment_update),
cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red"));
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_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 (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta"));
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_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);
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_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_FUNC (color_balance_mg_adjustment_update),
cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green"));
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_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 (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow"));
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_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);
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_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_FUNC (color_balance_yb_adjustment_update),
cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue"));
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_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 (end_label);
gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */
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);
gtk_widget_show (table);
/* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
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_FUNC (appl_mode_callbacks[i]),
GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd);
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 (table);
gtk_widget_show (vbox);
gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd)
{
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;
color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
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
color_balance_ok_callback (GtkWidget *widget,
gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
}
static void
color_balance_shadows_callback (GtkWidget *widget,
gpointer data)
color_balance_range_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS;
color_balance_update (cbd, ALL);
}
range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
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);
}

View File

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

View File

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

View File

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

View File

@ -33,29 +33,24 @@
#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_HEIGHT 35
#define DA_WIDTH 40
#define DA_HEIGHT 20
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8
#define LIGHTNESS_TEXT 0x10
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation;
struct _HueSaturation
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */
static int hue_transfer[6][256];
static int lightness_transfer[6][256];
static int saturation_transfer[6][256];
static int default_colors[6][3] =
static gint hue_transfer[6][256];
static gint lightness_transfer[6][256];
static gint saturation_transfer[6][256];
static gint default_colors[6][3] =
{
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
};
/* hue saturation action functions */
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 *,
int);
gint);
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_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_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_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_hue_text_update (GtkWidget *, gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer);
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer);
static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *);
/* hue saturation machinery */
void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{
int value;
int hue;
int i;
gint value;
gint hue;
gint i;
/* Calculate transfers */
for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
}
}
/* hue saturation action functions */
static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
}
Tool *
tools_new_hue_saturation ()
tools_new_hue_saturation (void)
{
Tool * tool;
HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void
hue_saturation_initialize (GDisplay *gdisp)
{
int i;
gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */
if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog ();
hue_saturation_dialog = hue_saturation_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->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);
}
void
hue_saturation_free ()
hue_saturation_free (void)
{
if (hue_saturation_dialog)
{
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL;
}
gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/
static HueSaturationDialog *
hue_saturation_new_dialog ()
hue_saturation_dialog_new (void)
{
HueSaturationDialog *hsd;
GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table;
GtkWidget *label;
GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle;
GtkWidget *radio_button;
GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
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->hue_partition = 0;
hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE;
/* 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,
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2);
main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* 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);
/* The table containing hue partitions */
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);
/* 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]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i)
{
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
{
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);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
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);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
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",
(GtkSignalFunc) hue_saturation_hue_partition_events,
GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd);
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",
(GtkSignalFunc) hue_partition_callbacks[i],
GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd);
gtk_widget_show (radio_button);
}
gtk_widget_show (table);
/* 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);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */
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);
/* Create the hue scale widget */
label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed",
(GtkSignalFunc) hue_saturation_hue_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 74, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */
label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->lightness_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed",
(GtkSignalFunc) hue_saturation_lightness_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */
label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->saturation_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed",
(GtkSignalFunc) hue_saturation_saturation_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) hue_saturation_preview_update,
GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void
hue_saturation_update (HueSaturationDialog *hsd,
int update)
gint update)
{
int i, j, b;
int rgb[3];
unsigned char buf[DA_WIDTH * 3];
char text[12];
gint i, j, b;
gint rgb[3];
guchar buf[DA_WIDTH * 3];
if (update & HUE_SLIDER)
{
hsd->hue_data->value = hsd->hue[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
hsd->hue[hsd->hue_partition]);
}
if (update & LIGHTNESS_SLIDER)
{
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
hsd->lightness[hsd->hue_partition]);
}
if (update & SATURATION_SLIDER)
{
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed");
}
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);
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
hsd->saturation[hsd->hue_partition]);
}
hue_saturation_calculate_transfers (hsd);
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[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
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[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);
for (j = 0; j < DA_WIDTH; j++)
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++)
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)
gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd)
{
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;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE;
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_reset_callback (GtkWidget *widget,
gpointer data)
{
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))
gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void
hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
}
static void
hue_saturation_master_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_partition_callback (GtkWidget *widget,
gpointer data)
{
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);
}
static void
hue_saturation_R_callback (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,
hue_saturation_preview_update (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
hsd->preview = TRUE;
hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
}
static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{
hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | 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);
hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog
{
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;
GtkWidget *shell;
GimpDrawable *drawable;
ImageMap image_map;
GtkWidget *hue_partition_da[6];
double hue[7];
double lightness[7];
double saturation[7];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
int hue_partition;
gint preview;
GimpDrawable *drawable;
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);
void tools_free_hue_saturation (Tool *);
Tool * tools_new_hue_saturation (void);
void tools_free_hue_saturation (Tool *tool);
void hue_saturation_initialize (GDisplay *);
void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *);
void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (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__ */

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software
* 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 "drawable.h"
#include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */
typedef struct _Threshold Threshold;
struct _Threshold
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the threshold tool options */
static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */
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_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer);
static void threshold_high_threshold_text_update (GtkWidget *, gpointer);
static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
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 */
void
threshold_2 (void *user_data,
threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR)
{
/* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */
threshold(srcPR, destPR, user_data);
/* this function just re-orders the arguments so we can use
* pixel_regions_process_paralell
*/
threshold (srcPR, destPR, data);
}
static void
threshold (PixelRegion *srcPR,
PixelRegion *destPR,
void *user_data)
void *data)
{
ThresholdDialog *td;
unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b;
int value;
td = (ThresholdDialog *) user_data;
td = (ThresholdDialog *) data;
h = srcPR->h;
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 */
static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
}
Tool *
tools_new_threshold ()
tools_new_threshold (void)
{
Tool * tool;
Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
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);
private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private;
/* Close the color select dialog */
/* Close the threshold dialog */
if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */
if (!threshold_dialog)
threshold_dialog = threshold_new_dialog ();
threshold_dialog = threshold_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram,
threshold_dialog->low_threshold,
threshold_dialog->high_threshold);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview)
threshold_preview (threshold_dialog);
}
/**********************/
/* Threshold dialog */
/**********************/
static ThresholdDialog *
threshold_new_dialog ()
threshold_dialog_new (void)
{
ThresholdDialog *td;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label;
GtkWidget *frame;
GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1);
td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL);
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Threshold Range: "));
label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
/* low threshold text */
td->low_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127");
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);
/* low threshold spinbutton */
data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->low_threshold_data = GTK_ADJUSTMENT (data);
/* high threshold text */
td->high_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255");
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->high_threshold_text), "changed",
(GtkSignalFunc) threshold_high_threshold_text_update,
spinbutton = gtk_spin_button_new (td->low_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->low_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
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);
/* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL);
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);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range,
(void*)td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
GTK_SIGNAL_FUNC (threshold_histogram_range),
td);
gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame);
gtk_widget_show (hbox);
/* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) threshold_preview_update,
GTK_SIGNAL_FUNC (threshold_preview_update),
td);
gtk_widget_show (label);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (vbox);
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;
}
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
threshold_preview (ThresholdDialog *td)
{
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
threshold_ok_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map)
image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void
threshold_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
}
static void
threshold_preview_update (GtkWidget *w,
threshold_preview_update (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
td->preview = TRUE;
threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
}
static void
threshold_low_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->low_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
threshold_preview (td);
}
}
static void
threshold_high_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->high_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
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"
typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog
{
GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text;
GtkWidget *shell;
GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram;
GimpHistogram *hist;
GimpDrawable *drawable;
ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
GimpDrawable *drawable;
ImageMap image_map;
gint preview;
gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
};
/* by_color select functions */
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *);
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *tool);
void threshold_initialize (GDisplay *);
void threshold_2 (void *, PixelRegion *, PixelRegion *);
void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */

View File

@ -15,60 +15,51 @@
* along with this program; if not, write to the Free Software
* 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 "brightness_contrast.h"
#include "drawable.h"
#include "gimage_mask.h"
#include "gimplut.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "image_map.h"
#include "interface.h"
#include "gimplut.h"
#include "lut_funcs.h"
#include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define BRIGHTNESS_SLIDER 0x1
#define CONTRAST_SLIDER 0x2
#define BRIGHTNESS_TEXT 0x4
#define CONTRAST_TEXT 0x8
#define ALL 0xF
#define BRIGHTNESS 0x1
#define CONTRAST 0x2
#define ALL (BRIGHTNESS | CONTRAST)
/* the brightness-contrast structures */
typedef struct _BrightnessContrast BrightnessContrast;
struct _BrightnessContrast
{
gint x, y; /* coords for last mouse click */
};
typedef struct _BrightnessContrastDialog BrightnessContrastDialog;
struct _BrightnessContrastDialog
{
GtkWidget *shell;
GtkWidget *gimage_name;
GtkWidget *brightness_text;
GtkWidget *contrast_text;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
GtkWidget *shell;
GtkWidget *gimage_name;
GimpDrawable *drawable;
ImageMap image_map;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
double brightness;
double contrast;
GimpDrawable *drawable;
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 BrightnessContrastDialog * brightness_contrast_new_dialog (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 BrightnessContrastDialog * brightness_contrast_dialog_new (void);
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 */
@ -122,7 +114,7 @@ brightness_contrast_control (Tool *tool,
}
Tool *
tools_new_brightness_contrast ()
tools_new_brightness_contrast (void)
{
Tool * tool;
BrightnessContrast * private;
@ -155,7 +147,7 @@ tools_free_brightness_contrast (Tool *tool)
bc = (BrightnessContrast *) tool->private;
/* Close the color select dialog */
/* Close the brightness-contrast dialog */
if (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 */
if (!brightness_contrast_dialog)
brightness_contrast_dialog = brightness_contrast_new_dialog ();
brightness_contrast_dialog = brightness_contrast_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->contrast = 0.0;
brightness_contrast_dialog->contrast = 0.0;
brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->image_map =
@ -190,19 +180,20 @@ brightness_contrast_initialize (GDisplay *gdisp)
brightness_contrast_update (brightness_contrast_dialog, ALL);
}
/********************************/
/* Brightness Contrast dialog */
/********************************/
static BrightnessContrastDialog *
brightness_contrast_new_dialog ()
brightness_contrast_dialog_new (void)
{
BrightnessContrastDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
GtkWidget *label;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *slider;
GtkWidget *toggle;
GtkObject *data;
@ -219,6 +210,8 @@ brightness_contrast_new_dialog ()
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), brightness_contrast_reset_callback,
bcd, NULL, TRUE, FALSE,
_("OK"), brightness_contrast_ok_callback,
bcd, NULL, TRUE, FALSE,
_("Cancel"), brightness_contrast_cancel_callback,
@ -226,94 +219,90 @@ brightness_contrast_new_dialog ()
NULL);
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* The table containing sliders */
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);
/* Create the brightness scale widget */
label = gtk_label_new (_("Brightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_brightness_scale_update,
bcd);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
bcd->brightness_text = gtk_entry_new ();
gtk_widget_set_usize (bcd->brightness_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), bcd->brightness_text, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (bcd->brightness_text), "changed",
(GtkSignalFunc) brightness_contrast_brightness_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (bcd->brightness_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
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);
gtk_widget_show (label);
gtk_widget_show (bcd->brightness_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the contrast scale widget */
label = gtk_label_new (_("Contrast"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_contrast_scale_update,
bcd);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
bcd->contrast_text = gtk_entry_new ();
gtk_widget_set_usize (bcd->contrast_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), bcd->contrast_text, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (bcd->contrast_text), "changed",
(GtkSignalFunc) brightness_contrast_contrast_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (bcd->contrast_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
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);
gtk_widget_show (label);
gtk_widget_show (bcd->contrast_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Horizontal box for preview and preserve luminosity toggle buttons */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) brightness_contrast_preview_update,
GTK_SIGNAL_FUNC (brightness_contrast_preview_update),
bcd);
gtk_widget_show (label);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
@ -328,27 +317,13 @@ static void
brightness_contrast_update (BrightnessContrastDialog *bcd,
gint update)
{
char text[12];
if (update & BRIGHTNESS_SLIDER)
if (update & BRIGHTNESS)
{
bcd->brightness_data->value = bcd->brightness;
gtk_signal_emit_by_name (GTK_OBJECT (bcd->brightness_data), "value_changed");
gtk_adjustment_set_value (bcd->brightness_data, bcd->brightness);
}
if (update & CONTRAST_SLIDER)
if (update & CONTRAST)
{
bcd->contrast_data->value = 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);
gtk_adjustment_set_value (bcd->contrast_data, bcd->contrast);
}
}
@ -371,12 +346,29 @@ brightness_contrast_preview (BrightnessContrastDialog *bcd)
}
static void
brightness_contrast_ok_callback (GtkWidget *widget,
gpointer client_data)
brightness_contrast_reset_callback (GtkWidget *widget,
gpointer data)
{
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))
gtk_widget_hide (bcd->shell);
@ -446,8 +438,8 @@ brightness_contrast_preview_update (GtkWidget *widget,
}
static void
brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
gpointer data)
brightness_contrast_brightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
BrightnessContrastDialog *bcd;
@ -456,7 +448,6 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
if (bcd->brightness != adjustment->value)
{
bcd->brightness = adjustment->value;
brightness_contrast_update (bcd, BRIGHTNESS_TEXT);
if (bcd->preview)
brightness_contrast_preview (bcd);
@ -464,8 +455,8 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
}
static void
brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
gpointer data)
brightness_contrast_contrast_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
BrightnessContrastDialog *bcd;
@ -474,51 +465,6 @@ brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
if (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)
brightness_contrast_preview (bcd);

View File

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

View File

@ -15,32 +15,27 @@
* along with this program; if not, write to the Free Software
* 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 "boundary.h"
#include "by_color_select.h"
#include "colormaps.h"
#include "drawable.h"
#include "draw_core.h"
#include "general.h"
#include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimprc.h"
#include "gimpset.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "selection_options.h"
#include "gimpdnd.h"
#include "tile.h" /* ick. */
#include "libgimp/gimpintl.h"
#include "tile.h" /* ick. */
#define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_ENTER_NOTIFY_MASK
@ -48,40 +43,43 @@
/* the by color selection structures */
typedef struct _ByColorSelect ByColorSelect;
struct _ByColorSelect
{
int x, y; /* Point from which to execute seed fill */
int operation; /* add, subtract, normal color selection */
gint x, y; /* Point from which to execute seed fill */
gint operation; /* add, subtract, normal color selection */
};
typedef struct _ByColorDialog ByColorDialog;
struct _ByColorDialog
{
GtkWidget *shell;
GtkWidget *preview;
GtkWidget *gimage_name;
GtkWidget *shell;
int threshold; /* threshold value for color select */
int operation; /* Add, Subtract, Replace */
GImage *gimage; /* gimage which is currently under examination */
GtkWidget *preview;
GtkWidget *gimage_name;
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 */
static SelectionOptions *by_color_options = NULL;
static SelectionOptions * by_color_options = NULL;
/* the by color selection dialog */
static ByColorDialog * by_color_dialog = NULL;
static ByColorDialog * by_color_dialog = NULL;
/* dnd stuff */
static GtkTargetEntry by_color_select_image_target_table[] =
static GtkTargetEntry by_color_select_targets[] =
{
GIMP_TARGET_COLOR
};
static guint n_by_color_select_image_targets =
(sizeof (by_color_select_image_target_table) /
sizeof (by_color_select_image_target_table[0]));
static void by_color_select_color_drop (GtkWidget*, guchar, guchar, guchar, gpointer);
static guint n_by_color_select_targets = (sizeof (by_color_select_targets) /
sizeof (by_color_select_targets[0]));
static void by_color_select_color_drop (GtkWidget *, guchar, guchar, guchar,
gpointer);
/* 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_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_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *, GdkEventButton *,
ByColorDialog *);
static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_reset_callback (GtkWidget *, gpointer);
static void by_color_select_close_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer);
static void by_color_select_render (ByColorDialog *, GImage *);
static void by_color_select_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *,
GdkEventButton *,
ByColorDialog *);
static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_reset_callback (GtkWidget *, 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 *,
GdkEventButton *);
static int is_pixel_sufficiently_different (unsigned char *, unsigned char *, int, int, int, int);
static Channel * by_color_select_color (GImage *, GimpDrawable *, unsigned char *, int, int, int);
static gint is_pixel_sufficiently_different (guchar *, guchar *,
gint, gint, gint, gint);
static Channel * by_color_select_color (GImage *, GimpDrawable *,
guchar *, gint, gint, gint);
/* by_color selection machinery */
static int
is_pixel_sufficiently_different (unsigned char *col1,
unsigned char *col2,
int antialias,
int threshold,
int bytes,
int has_alpha)
is_pixel_sufficiently_different (guchar *col1,
guchar *col2,
gint antialias,
gint threshold,
gint bytes,
gint has_alpha)
{
int diff;
int max;
@ -145,7 +146,7 @@ is_pixel_sufficiently_different (unsigned char *col1,
if (aa <= 0)
return 0;
else if (aa < 0.5)
return (unsigned char) (aa * 512);
return (guchar) (aa * 512);
else
return 255;
}
@ -159,12 +160,12 @@ is_pixel_sufficiently_different (unsigned char *col1,
}
static Channel *
by_color_select_color (GImage *gimage,
GimpDrawable *drawable,
unsigned char *color,
int antialias,
int threshold,
int sample_merged)
by_color_select_color (GImage *gimage,
GimpDrawable *drawable,
guchar *color,
gint antialias,
gint threshold,
gint sample_merged)
{
/* Scan over the gimage's active layer, finding pixels within the specified
* threshold from the given R, G, & B values. If antialiasing is on,
@ -173,10 +174,10 @@ by_color_select_color (GImage *gimage,
*/
Channel *mask;
PixelRegion imagePR, maskPR;
unsigned char *image_data;
unsigned char *mask_data;
unsigned char *idata, *mdata;
unsigned char rgb[MAX_CHANNELS];
guchar *image_data;
guchar *mask_data;
guchar *idata, *mdata;
guchar rgb[MAX_CHANNELS];
int has_alpha, indexed;
int width, height;
int bytes, color_bytes, alpha;
@ -195,7 +196,8 @@ by_color_select_color (GImage *gimage,
indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE;
width = gimage->width;
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
{
@ -206,16 +208,20 @@ by_color_select_color (GImage *gimage,
width = drawable_width (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) {
/* indexed colors are always RGB or RGBA */
color_bytes = has_alpha ? 4 : 3;
} else {
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
if (indexed)
{
/* indexed colors are always RGB or RGBA */
color_bytes = has_alpha ? 4 : 3;
}
else
{
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
alpha = bytes - 1;
mask = channel_new_mask (gimage, width, height);
@ -223,7 +229,9 @@ by_color_select_color (GImage *gimage,
0, 0, width, height, TRUE);
/* 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;
mask_data = maskPR.data;
@ -242,8 +250,12 @@ by_color_select_color (GImage *gimage,
rgb[color_bytes - 1] = idata[alpha];
/* Find how closely the colors match */
*mdata++ = is_pixel_sufficiently_different (color, rgb, antialias,
threshold, color_bytes, has_alpha);
*mdata++ = is_pixel_sufficiently_different (color,
rgb,
antialias,
threshold,
color_bytes,
has_alpha);
idata += bytes;
}
@ -257,15 +269,15 @@ by_color_select_color (GImage *gimage,
}
void
by_color_select (GImage *gimage,
GimpDrawable *drawable,
unsigned char *color,
int threshold,
int op,
int antialias,
int feather,
double feather_radius,
int sample_merged)
by_color_select (GImage *gimage,
GimpDrawable *drawable,
guchar *color,
gint threshold,
gint op,
gint antialias,
gint feather,
gdouble feather_radius,
gint sample_merged)
{
Channel * new_mask;
int off_x, off_y;
@ -273,7 +285,8 @@ by_color_select (GImage *gimage,
if (!drawable)
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 (op == REPLACE)
@ -300,7 +313,6 @@ by_color_select (GImage *gimage,
channel_delete (new_mask);
}
/* by_color select action functions */
static void
@ -345,8 +357,25 @@ by_color_select_button_press (Tool *tool,
/* Update the by_color_dialog's active gdisp pointer */
if (by_color_dialog->gimage)
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;
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
@ -356,32 +385,35 @@ by_color_select_button_release (Tool *tool,
{
ByColorSelect * by_color_sel;
GDisplay * gdisp;
int x, y;
gint x, y;
GimpDrawable *drawable;
unsigned char *color;
int use_offsets;
guchar *color;
gint use_offsets;
gdisp = (GDisplay *) gdisp_ptr;
by_color_sel = (ByColorSelect *) tool->private;
drawable = gimage_active_drawable (gdisp->gimage);
gdk_pointer_ungrab (bevent->time);
tool->state = INACTIVE;
/* First take care of the case where the user "cancels" the action */
if (! (bevent->state & GDK_BUTTON3_MASK))
{
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 */
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;
}
else
{
if (!(color = gimp_drawable_get_color_at(drawable, x, y)))
if (!(color = gimp_drawable_get_color_at (drawable, x, y)))
return;
}
@ -394,7 +426,7 @@ by_color_select_button_release (Tool *tool,
by_color_options->feather_radius,
by_color_options->sample_merged);
g_free(color);
g_free (color);
/* show selection on all views */
gdisplays_flush ();
@ -412,17 +444,20 @@ by_color_select_cursor_update (Tool *tool,
{
GDisplay *gdisp;
Layer *layer;
int x, y;
gint x, y;
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 == gdisp->gimage->active_layer)
{
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
return;
}
gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW);
}
@ -450,13 +485,13 @@ by_color_select_control (Tool *tool,
}
static void
by_color_select_options_reset ()
by_color_select_options_reset (void)
{
selection_options_reset (by_color_options);
}
Tool *
tools_new_by_color_select ()
tools_new_by_color_select (void)
{
Tool * tool;
ByColorSelect * private;
@ -471,7 +506,7 @@ tools_new_by_color_select ()
/* The "by color" dialog */
if (!by_color_dialog)
by_color_dialog = by_color_select_new_dialog ();
by_color_dialog = by_color_select_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell))
gtk_widget_show (by_color_dialog->shell);
@ -521,7 +556,6 @@ by_color_select_initialize_by_image (GImage *gimage)
void
by_color_select_initialize (GDisplay *gdisp)
{
/* wrap this call so the tool_info->init_func works */
by_color_select_initialize_by_image (gdisp->gimage);
}
@ -530,37 +564,16 @@ by_color_select_initialize (GDisplay *gdisp)
/****************************/
static ByColorDialog *
by_color_select_new_dialog ()
by_color_select_dialog_new (void)
{
ByColorDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *options_box;
GtkWidget *label;
GtkWidget *util_box;
GtkWidget *slider;
GtkWidget *radio_box;
GtkWidget *radio_button;
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->gimage = NULL;
@ -580,101 +593,98 @@ by_color_select_new_dialog ()
NULL);
/* The vbox */
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* 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 main hbox */
hbox = gtk_hbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), hbox);
/* 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);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0);
bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT);
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);
/* 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_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
by_color_select_image_target_table,
n_by_color_select_image_targets,
by_color_select_targets,
n_by_color_select_targets,
GDK_ACTION_COPY);
gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd);
gtk_widget_show (bcd->preview);
gtk_widget_show (frame);
gtk_widget_show (util_box);
/* options box */
options_box = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (options_box), 5);
gtk_box_pack_start (GTK_BOX (hbox), options_box, TRUE, TRUE, 0);
options_box = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), options_box, FALSE, FALSE, 0);
/* Create the active image label */
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
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 (util_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);
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);
/* Create the opacity scale widget */
util_box = gtk_vbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
label = gtk_label_new (_("Fuzziness Threshold"));
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);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) by_color_select_fuzzy_update,
GTK_SIGNAL_FUNC (by_color_select_fuzzy_update),
bcd);
gtk_widget_show (label);
gtk_widget_show (slider);
gtk_widget_show (util_box);
gtk_widget_show (options_box);
gtk_widget_show (hbox);
gtk_widget_show (vbox);
gtk_widget_show (bcd->shell);
return bcd;
@ -686,14 +696,14 @@ by_color_select_render (ByColorDialog *bcd,
{
Channel * mask;
MaskBuf * scaled_buf = NULL;
unsigned char *buf;
guchar *buf;
PixelRegion srcPR, destPR;
unsigned char * src;
int subsample;
int width, height;
int srcwidth;
int i;
int scale;
guchar * src;
gint subsample;
gint width, height;
gint srcwidth;
gint i;
gint scale;
mask = gimage_get_mask (gimage);
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))
{
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
{
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;
}
@ -726,10 +738,10 @@ by_color_select_render (ByColorDialog *bcd,
gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height);
/* clear the image buf */
buf = (unsigned char *) g_malloc (bcd->preview->requisition.width);
memset (buf, 0, bcd->preview->requisition.width);
buf = g_new0 (guchar, bcd->preview->requisition.width);
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);
/* 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);
/* 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
@ -823,25 +836,25 @@ by_color_select_preview_events (GtkWidget *widget,
static void
by_color_select_type_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
if (by_color_dialog)
by_color_dialog->operation = (long) client_data;
by_color_dialog->operation = (long) data;
}
static void
by_color_select_reset_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data;
bcd = (ByColorDialog *) data;
if (!bcd->gimage)
return;
/* 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;
/* reset the mask */
@ -857,16 +870,16 @@ by_color_select_reset_callback (GtkWidget *widget,
static void
by_color_select_close_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data;
bcd = (ByColorDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell);
if (bcd->gimage &&
gimp_set_have (image_context, bcd->gimage))
if (bcd->gimage && gimp_set_have (image_context, bcd->gimage))
{
bcd->gimage->by_color_select = FALSE;
bcd->gimage = NULL;
@ -880,18 +893,19 @@ by_color_select_fuzzy_update (GtkAdjustment *adjustment,
ByColorDialog *bcd;
bcd = (ByColorDialog *) data;
bcd->threshold = (int) adjustment->value;
bcd->threshold = (gint) (adjustment->value + 0.5);
}
static void
by_color_select_preview_button_press (ByColorDialog *bcd,
GdkEventButton *bevent)
{
int x, y;
int replace, operation;
gint x, y;
gint replace, operation;
GimpDrawable *drawable;
Tile *tile;
unsigned char *col;
guchar *col;
if (!bcd->gimage)
return;

View File

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

View File

@ -15,21 +15,13 @@
* along with this program; if not, write to the Free Software
* 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 "color_balance.h"
#include "color_transfer.h"
#include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h"
#include "gimpui.h"
#include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
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_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */
if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog ();
color_balance_dialog = color_balance_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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++)
{
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->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->image_map =
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 dialog */
/**************************/
static ColorBalanceDialog *
color_balance_new_dialog (void)
color_balance_dialog_new (void)
{
ColorBalanceDialog *cbd;
GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights")
};
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL);
vbox = gtk_vbox_new (FALSE, 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label);
/* 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);
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);
/* 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);
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);
/* 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);
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 */
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);
/* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan"));
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_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);
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_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_FUNC (color_balance_cr_adjustment_update),
cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red"));
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_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 (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta"));
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_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);
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_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_FUNC (color_balance_mg_adjustment_update),
cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green"));
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_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 (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow"));
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_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);
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_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_FUNC (color_balance_yb_adjustment_update),
cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue"));
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_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 (end_label);
gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */
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);
gtk_widget_show (table);
/* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
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_FUNC (appl_mode_callbacks[i]),
GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd);
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 (table);
gtk_widget_show (vbox);
gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd)
{
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;
color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
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
color_balance_ok_callback (GtkWidget *widget,
gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
}
static void
color_balance_shadows_callback (GtkWidget *widget,
gpointer data)
color_balance_range_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS;
color_balance_update (cbd, ALL);
}
range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
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);
}

View File

@ -57,8 +57,6 @@ struct _ColorBalanceDialog
TransferMode application_mode;
};
/* color balance functions */
Tool * tools_new_color_balance (void);
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_page_switch (GtkWidget *, GtkNotebookPage *,
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 */
typedef struct _ColorSelectorInfo {
typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */
char *help_page;
GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next;
} ColorSelectorInfo;
typedef struct _ColorSelectorInstance {
typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook;
ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp,
color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
}
static void
color_notebook_help_func (gpointer data)
color_notebook_help_func (gchar *data)
{
ColorNotebookP cnp;
gchar *help_path;

View File

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

View File

@ -23,47 +23,53 @@
#include "lut_funcs.h"
#include "tools.h"
#define SMOOTH 0
#define GFREE 1
#define SMOOTH 0
#define GFREE 1
typedef struct _CurvesDialog CurvesDialog;
struct _CurvesDialog
{
GtkWidget * shell;
GtkWidget * channel_menu;
GtkWidget * xrange;
GtkWidget * yrange;
GtkWidget * graph;
GdkPixmap * pixmap;
GimpDrawable * drawable;
ImageMap image_map;
int color;
int channel;
gint preview;
GtkWidget *shell;
int grab_point;
int last;
int leftmost;
int rightmost;
int curve_type;
int points[5][17][2];
unsigned char curve[5][256];
int col_value[5];
GtkWidget *channel_menu;
GtkWidget *xrange;
GtkWidget *yrange;
GtkWidget *graph;
GdkPixmap *pixmap;
GimpDrawable *drawable;
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;
int cursor_ind_width;
int cursor_ind_ascent;
gint cursor_ind_height;
gint cursor_ind_width;
gint cursor_ind_ascent;
GimpLut *lut;
GimpLut *lut;
};
/* hue-saturation functions */
Tool * tools_new_curves (void);
void tools_free_curves (Tool *);
Tool * tools_new_curves (void);
void tools_free_curves (Tool *tool);
void curves_initialize (GDisplay *);
void curves_free (void);
float curves_lut_func (CurvesDialog *, int, int, float);
void curves_calculate_curve (CurvesDialog *);
void curves_initialize (GDisplay *gdisp);
void curves_free (void);
float curves_lut_func (CurvesDialog *cd,
gint nchannels,
gint channel,
gfloat value);
void curves_calculate_curve (CurvesDialog *cd);
#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_page_switch (GtkWidget *, GtkNotebookPage *,
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 */
typedef struct _ColorSelectorInfo {
typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */
char *help_page;
GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next;
} ColorSelectorInfo;
typedef struct _ColorSelectorInstance {
typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook;
ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp,
color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
}
static void
color_notebook_help_func (gpointer data)
color_notebook_help_func (gchar *data)
{
ColorNotebookP cnp;
gchar *help_path;

View File

@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include "gimpui.h"
#include "libgimp/gimpsizeentry.h"
@ -324,50 +321,73 @@ gimp_option_menu_new (GtkSignalFunc menu_item_callback,
}
GtkWidget *
gimp_radio_group_new (GtkSignalFunc radio_button_callback,
gpointer initial, /* user_data */
gimp_radio_group_new (gboolean in_frame,
gchar *frame_title,
/* specify radio buttons as va_list:
* gchar *label,
* gpointer data,
* gpointer user_data,
* gchar *label,
* GtkSignalFunc callback,
* gpointer data,
* gpointer user_data,
* GtkWidget **widget_ptr,
* gboolean active,
*/
...)
{
GtkWidget *vbox;
GtkWidget *frame;
GtkWidget *button;
GSList *group;
/* radio button variables */
gchar *label;
gpointer data;
gpointer user_data;
gchar *label;
GtkSignalFunc callback;
gpointer data;
gpointer user_data;
GtkWidget **widget_ptr;
gboolean active;
va_list args;
va_list args;
vbox = gtk_vbox_new (FALSE, 1);
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;
/* create the radio buttons */
va_start (args, initial);
va_start (args, frame_title);
label = va_arg (args, gchar*);
while (label)
{
data = va_arg (args, gpointer);
user_data = va_arg (args, gpointer);
callback = va_arg (args, GtkSignalFunc);
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);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (button), "toggled",
(GtkSignalFunc) radio_button_callback,
GTK_SIGNAL_FUNC (callback),
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 */
if (user_data == initial)
if (active)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_widget_show (button);
@ -376,6 +396,9 @@ gimp_radio_group_new (GtkSignalFunc radio_button_callback,
}
va_end (args);
if (in_frame)
return frame;
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_SHADOW_NONE);
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;
}
@ -787,11 +810,12 @@ struct _MessageBox
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 dialog boxes */
#define MESSAGE_BOX_MAXIMUM 7 /* the maximum number of concucrrent
* dialog boxes
*/
static int message_pool = MESSAGE_BOX_MAXIMUM;
static gchar message_box_last[MESSAGE_STRING_BUFFER];
static gint message_pool = MESSAGE_BOX_MAXIMUM;
static gchar *message_box_last = NULL;
GtkWidget *
gimp_message_box (gchar *message,
@ -803,13 +827,13 @@ gimp_message_box (gchar *message,
GtkWidget *vbox;
GtkWidget *label;
static int repeat_count;
static gint repeat_count;
/* arguably, if message_pool <= 0 we could print to stdout */
if (!message || message_pool <= 0)
return NULL;
if (!strcmp (message_box_last, message))
if (message_box_last && !strcmp (message_box_last, message))
{
repeat_count++;
if (repeat_count == 3)
@ -820,8 +844,9 @@ gimp_message_box (gchar *message,
else
{
repeat_count = 0;
if (strlen (message) < MESSAGE_STRING_BUFFER)
strcpy (message_box_last, message);
if (message_box_last)
g_free (message_box_last);
message_box_last = g_strdup (message);
}
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,
gpointer initial, /* user_data */
GtkWidget * gimp_radio_group_new (gboolean in_frame,
gchar *frame_title,
/* specify radio buttons as va_list:
* gchar *label,
* GtkSignalFunc callback,
* gpointer 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_page_switch (GtkWidget *, GtkNotebookPage *,
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 */
typedef struct _ColorSelectorInfo {
typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */
char *help_page;
GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next;
} ColorSelectorInfo;
typedef struct _ColorSelectorInstance {
typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook;
ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp,
color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
}
static void
color_notebook_help_func (gpointer data)
color_notebook_help_func (gchar *data)
{
ColorNotebookP cnp;
gchar *help_path;

View File

@ -99,21 +99,6 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
"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 */
{ { N_("/File/---"), NULL, NULL, 0, "<Separator>" },

View File

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

View File

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

View File

@ -33,29 +33,24 @@
#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_HEIGHT 35
#define DA_WIDTH 40
#define DA_HEIGHT 20
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8
#define LIGHTNESS_TEXT 0x10
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation;
struct _HueSaturation
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */
static int hue_transfer[6][256];
static int lightness_transfer[6][256];
static int saturation_transfer[6][256];
static int default_colors[6][3] =
static gint hue_transfer[6][256];
static gint lightness_transfer[6][256];
static gint saturation_transfer[6][256];
static gint default_colors[6][3] =
{
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
};
/* hue saturation action functions */
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 *,
int);
gint);
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_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_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_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_hue_text_update (GtkWidget *, gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer);
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer);
static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *);
/* hue saturation machinery */
void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{
int value;
int hue;
int i;
gint value;
gint hue;
gint i;
/* Calculate transfers */
for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
}
}
/* hue saturation action functions */
static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
}
Tool *
tools_new_hue_saturation ()
tools_new_hue_saturation (void)
{
Tool * tool;
HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void
hue_saturation_initialize (GDisplay *gdisp)
{
int i;
gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */
if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog ();
hue_saturation_dialog = hue_saturation_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->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);
}
void
hue_saturation_free ()
hue_saturation_free (void)
{
if (hue_saturation_dialog)
{
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL;
}
gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/
static HueSaturationDialog *
hue_saturation_new_dialog ()
hue_saturation_dialog_new (void)
{
HueSaturationDialog *hsd;
GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table;
GtkWidget *label;
GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle;
GtkWidget *radio_button;
GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
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->hue_partition = 0;
hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE;
/* 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,
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2);
main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* 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);
/* The table containing hue partitions */
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);
/* 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]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i)
{
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
{
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);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
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);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
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",
(GtkSignalFunc) hue_saturation_hue_partition_events,
GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd);
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",
(GtkSignalFunc) hue_partition_callbacks[i],
GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd);
gtk_widget_show (radio_button);
}
gtk_widget_show (table);
/* 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);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */
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);
/* Create the hue scale widget */
label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed",
(GtkSignalFunc) hue_saturation_hue_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 74, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */
label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->lightness_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed",
(GtkSignalFunc) hue_saturation_lightness_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */
label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->saturation_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed",
(GtkSignalFunc) hue_saturation_saturation_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) hue_saturation_preview_update,
GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void
hue_saturation_update (HueSaturationDialog *hsd,
int update)
gint update)
{
int i, j, b;
int rgb[3];
unsigned char buf[DA_WIDTH * 3];
char text[12];
gint i, j, b;
gint rgb[3];
guchar buf[DA_WIDTH * 3];
if (update & HUE_SLIDER)
{
hsd->hue_data->value = hsd->hue[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
hsd->hue[hsd->hue_partition]);
}
if (update & LIGHTNESS_SLIDER)
{
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
hsd->lightness[hsd->hue_partition]);
}
if (update & SATURATION_SLIDER)
{
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed");
}
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);
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
hsd->saturation[hsd->hue_partition]);
}
hue_saturation_calculate_transfers (hsd);
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[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
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[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);
for (j = 0; j < DA_WIDTH; j++)
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++)
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)
gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd)
{
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;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE;
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_reset_callback (GtkWidget *widget,
gpointer data)
{
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))
gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void
hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
}
static void
hue_saturation_master_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_partition_callback (GtkWidget *widget,
gpointer data)
{
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);
}
static void
hue_saturation_R_callback (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,
hue_saturation_preview_update (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
hsd->preview = TRUE;
hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
}
static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{
hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | 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);
hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog
{
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;
GtkWidget *shell;
GimpDrawable *drawable;
ImageMap image_map;
GtkWidget *hue_partition_da[6];
double hue[7];
double lightness[7];
double saturation[7];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
int hue_partition;
gint preview;
GimpDrawable *drawable;
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);
void tools_free_hue_saturation (Tool *);
Tool * tools_new_hue_saturation (void);
void tools_free_hue_saturation (Tool *tool);
void hue_saturation_initialize (GDisplay *);
void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *);
void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (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__ */

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -99,21 +99,6 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
"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 */
{ { 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 },
"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 */
{ { N_("/File/---"), NULL, NULL, 0, "<Separator>" },

View File

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

View File

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

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software
* 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 "drawable.h"
#include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */
typedef struct _Threshold Threshold;
struct _Threshold
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the threshold tool options */
static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */
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_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer);
static void threshold_high_threshold_text_update (GtkWidget *, gpointer);
static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
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 */
void
threshold_2 (void *user_data,
threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR)
{
/* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */
threshold(srcPR, destPR, user_data);
/* this function just re-orders the arguments so we can use
* pixel_regions_process_paralell
*/
threshold (srcPR, destPR, data);
}
static void
threshold (PixelRegion *srcPR,
PixelRegion *destPR,
void *user_data)
void *data)
{
ThresholdDialog *td;
unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b;
int value;
td = (ThresholdDialog *) user_data;
td = (ThresholdDialog *) data;
h = srcPR->h;
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 */
static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
}
Tool *
tools_new_threshold ()
tools_new_threshold (void)
{
Tool * tool;
Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
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);
private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private;
/* Close the color select dialog */
/* Close the threshold dialog */
if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */
if (!threshold_dialog)
threshold_dialog = threshold_new_dialog ();
threshold_dialog = threshold_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram,
threshold_dialog->low_threshold,
threshold_dialog->high_threshold);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview)
threshold_preview (threshold_dialog);
}
/**********************/
/* Threshold dialog */
/**********************/
static ThresholdDialog *
threshold_new_dialog ()
threshold_dialog_new (void)
{
ThresholdDialog *td;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label;
GtkWidget *frame;
GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1);
td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL);
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Threshold Range: "));
label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
/* low threshold text */
td->low_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127");
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);
/* low threshold spinbutton */
data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->low_threshold_data = GTK_ADJUSTMENT (data);
/* high threshold text */
td->high_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255");
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->high_threshold_text), "changed",
(GtkSignalFunc) threshold_high_threshold_text_update,
spinbutton = gtk_spin_button_new (td->low_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->low_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
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);
/* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL);
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);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range,
(void*)td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
GTK_SIGNAL_FUNC (threshold_histogram_range),
td);
gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame);
gtk_widget_show (hbox);
/* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) threshold_preview_update,
GTK_SIGNAL_FUNC (threshold_preview_update),
td);
gtk_widget_show (label);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (vbox);
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;
}
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
threshold_preview (ThresholdDialog *td)
{
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
threshold_ok_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map)
image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void
threshold_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
}
static void
threshold_preview_update (GtkWidget *w,
threshold_preview_update (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
td->preview = TRUE;
threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
}
static void
threshold_low_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->low_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
threshold_preview (td);
}
}
static void
threshold_high_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->high_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
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"
typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog
{
GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text;
GtkWidget *shell;
GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram;
GimpHistogram *hist;
GimpDrawable *drawable;
ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
GimpDrawable *drawable;
ImageMap image_map;
gint preview;
gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
};
/* by_color select functions */
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *);
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *tool);
void threshold_initialize (GDisplay *);
void threshold_2 (void *, PixelRegion *, PixelRegion *);
void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */

View File

@ -802,7 +802,17 @@ tools_initialize (ToolType tool_type,
if (tool_info[(gint) tool_type].init_func && !gdisp)
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)
{

View File

@ -15,60 +15,51 @@
* along with this program; if not, write to the Free Software
* 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 "brightness_contrast.h"
#include "drawable.h"
#include "gimage_mask.h"
#include "gimplut.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "image_map.h"
#include "interface.h"
#include "gimplut.h"
#include "lut_funcs.h"
#include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define BRIGHTNESS_SLIDER 0x1
#define CONTRAST_SLIDER 0x2
#define BRIGHTNESS_TEXT 0x4
#define CONTRAST_TEXT 0x8
#define ALL 0xF
#define BRIGHTNESS 0x1
#define CONTRAST 0x2
#define ALL (BRIGHTNESS | CONTRAST)
/* the brightness-contrast structures */
typedef struct _BrightnessContrast BrightnessContrast;
struct _BrightnessContrast
{
gint x, y; /* coords for last mouse click */
};
typedef struct _BrightnessContrastDialog BrightnessContrastDialog;
struct _BrightnessContrastDialog
{
GtkWidget *shell;
GtkWidget *gimage_name;
GtkWidget *brightness_text;
GtkWidget *contrast_text;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
GtkWidget *shell;
GtkWidget *gimage_name;
GimpDrawable *drawable;
ImageMap image_map;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
double brightness;
double contrast;
GimpDrawable *drawable;
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 BrightnessContrastDialog * brightness_contrast_new_dialog (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 BrightnessContrastDialog * brightness_contrast_dialog_new (void);
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 */
@ -122,7 +114,7 @@ brightness_contrast_control (Tool *tool,
}
Tool *
tools_new_brightness_contrast ()
tools_new_brightness_contrast (void)
{
Tool * tool;
BrightnessContrast * private;
@ -155,7 +147,7 @@ tools_free_brightness_contrast (Tool *tool)
bc = (BrightnessContrast *) tool->private;
/* Close the color select dialog */
/* Close the brightness-contrast dialog */
if (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 */
if (!brightness_contrast_dialog)
brightness_contrast_dialog = brightness_contrast_new_dialog ();
brightness_contrast_dialog = brightness_contrast_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->contrast = 0.0;
brightness_contrast_dialog->contrast = 0.0;
brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->image_map =
@ -190,19 +180,20 @@ brightness_contrast_initialize (GDisplay *gdisp)
brightness_contrast_update (brightness_contrast_dialog, ALL);
}
/********************************/
/* Brightness Contrast dialog */
/********************************/
static BrightnessContrastDialog *
brightness_contrast_new_dialog ()
brightness_contrast_dialog_new (void)
{
BrightnessContrastDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
GtkWidget *label;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *slider;
GtkWidget *toggle;
GtkObject *data;
@ -219,6 +210,8 @@ brightness_contrast_new_dialog ()
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), brightness_contrast_reset_callback,
bcd, NULL, TRUE, FALSE,
_("OK"), brightness_contrast_ok_callback,
bcd, NULL, TRUE, FALSE,
_("Cancel"), brightness_contrast_cancel_callback,
@ -226,94 +219,90 @@ brightness_contrast_new_dialog ()
NULL);
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* The table containing sliders */
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);
/* Create the brightness scale widget */
label = gtk_label_new (_("Brightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_brightness_scale_update,
bcd);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
bcd->brightness_text = gtk_entry_new ();
gtk_widget_set_usize (bcd->brightness_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), bcd->brightness_text, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (bcd->brightness_text), "changed",
(GtkSignalFunc) brightness_contrast_brightness_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (bcd->brightness_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
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);
gtk_widget_show (label);
gtk_widget_show (bcd->brightness_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the contrast scale widget */
label = gtk_label_new (_("Contrast"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_contrast_scale_update,
bcd);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
bcd->contrast_text = gtk_entry_new ();
gtk_widget_set_usize (bcd->contrast_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), bcd->contrast_text, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (bcd->contrast_text), "changed",
(GtkSignalFunc) brightness_contrast_contrast_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (bcd->contrast_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
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);
gtk_widget_show (label);
gtk_widget_show (bcd->contrast_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Horizontal box for preview and preserve luminosity toggle buttons */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) brightness_contrast_preview_update,
GTK_SIGNAL_FUNC (brightness_contrast_preview_update),
bcd);
gtk_widget_show (label);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
@ -328,27 +317,13 @@ static void
brightness_contrast_update (BrightnessContrastDialog *bcd,
gint update)
{
char text[12];
if (update & BRIGHTNESS_SLIDER)
if (update & BRIGHTNESS)
{
bcd->brightness_data->value = bcd->brightness;
gtk_signal_emit_by_name (GTK_OBJECT (bcd->brightness_data), "value_changed");
gtk_adjustment_set_value (bcd->brightness_data, bcd->brightness);
}
if (update & CONTRAST_SLIDER)
if (update & CONTRAST)
{
bcd->contrast_data->value = 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);
gtk_adjustment_set_value (bcd->contrast_data, bcd->contrast);
}
}
@ -371,12 +346,29 @@ brightness_contrast_preview (BrightnessContrastDialog *bcd)
}
static void
brightness_contrast_ok_callback (GtkWidget *widget,
gpointer client_data)
brightness_contrast_reset_callback (GtkWidget *widget,
gpointer data)
{
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))
gtk_widget_hide (bcd->shell);
@ -446,8 +438,8 @@ brightness_contrast_preview_update (GtkWidget *widget,
}
static void
brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
gpointer data)
brightness_contrast_brightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
BrightnessContrastDialog *bcd;
@ -456,7 +448,6 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
if (bcd->brightness != adjustment->value)
{
bcd->brightness = adjustment->value;
brightness_contrast_update (bcd, BRIGHTNESS_TEXT);
if (bcd->preview)
brightness_contrast_preview (bcd);
@ -464,8 +455,8 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
}
static void
brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
gpointer data)
brightness_contrast_contrast_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
BrightnessContrastDialog *bcd;
@ -474,51 +465,6 @@ brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
if (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)
brightness_contrast_preview (bcd);

View File

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

View File

@ -15,32 +15,27 @@
* along with this program; if not, write to the Free Software
* 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 "boundary.h"
#include "by_color_select.h"
#include "colormaps.h"
#include "drawable.h"
#include "draw_core.h"
#include "general.h"
#include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimprc.h"
#include "gimpset.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "selection_options.h"
#include "gimpdnd.h"
#include "tile.h" /* ick. */
#include "libgimp/gimpintl.h"
#include "tile.h" /* ick. */
#define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_ENTER_NOTIFY_MASK
@ -48,40 +43,43 @@
/* the by color selection structures */
typedef struct _ByColorSelect ByColorSelect;
struct _ByColorSelect
{
int x, y; /* Point from which to execute seed fill */
int operation; /* add, subtract, normal color selection */
gint x, y; /* Point from which to execute seed fill */
gint operation; /* add, subtract, normal color selection */
};
typedef struct _ByColorDialog ByColorDialog;
struct _ByColorDialog
{
GtkWidget *shell;
GtkWidget *preview;
GtkWidget *gimage_name;
GtkWidget *shell;
int threshold; /* threshold value for color select */
int operation; /* Add, Subtract, Replace */
GImage *gimage; /* gimage which is currently under examination */
GtkWidget *preview;
GtkWidget *gimage_name;
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 */
static SelectionOptions *by_color_options = NULL;
static SelectionOptions * by_color_options = NULL;
/* the by color selection dialog */
static ByColorDialog * by_color_dialog = NULL;
static ByColorDialog * by_color_dialog = NULL;
/* dnd stuff */
static GtkTargetEntry by_color_select_image_target_table[] =
static GtkTargetEntry by_color_select_targets[] =
{
GIMP_TARGET_COLOR
};
static guint n_by_color_select_image_targets =
(sizeof (by_color_select_image_target_table) /
sizeof (by_color_select_image_target_table[0]));
static void by_color_select_color_drop (GtkWidget*, guchar, guchar, guchar, gpointer);
static guint n_by_color_select_targets = (sizeof (by_color_select_targets) /
sizeof (by_color_select_targets[0]));
static void by_color_select_color_drop (GtkWidget *, guchar, guchar, guchar,
gpointer);
/* 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_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_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *, GdkEventButton *,
ByColorDialog *);
static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_reset_callback (GtkWidget *, gpointer);
static void by_color_select_close_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer);
static void by_color_select_render (ByColorDialog *, GImage *);
static void by_color_select_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *,
GdkEventButton *,
ByColorDialog *);
static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_reset_callback (GtkWidget *, 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 *,
GdkEventButton *);
static int is_pixel_sufficiently_different (unsigned char *, unsigned char *, int, int, int, int);
static Channel * by_color_select_color (GImage *, GimpDrawable *, unsigned char *, int, int, int);
static gint is_pixel_sufficiently_different (guchar *, guchar *,
gint, gint, gint, gint);
static Channel * by_color_select_color (GImage *, GimpDrawable *,
guchar *, gint, gint, gint);
/* by_color selection machinery */
static int
is_pixel_sufficiently_different (unsigned char *col1,
unsigned char *col2,
int antialias,
int threshold,
int bytes,
int has_alpha)
is_pixel_sufficiently_different (guchar *col1,
guchar *col2,
gint antialias,
gint threshold,
gint bytes,
gint has_alpha)
{
int diff;
int max;
@ -145,7 +146,7 @@ is_pixel_sufficiently_different (unsigned char *col1,
if (aa <= 0)
return 0;
else if (aa < 0.5)
return (unsigned char) (aa * 512);
return (guchar) (aa * 512);
else
return 255;
}
@ -159,12 +160,12 @@ is_pixel_sufficiently_different (unsigned char *col1,
}
static Channel *
by_color_select_color (GImage *gimage,
GimpDrawable *drawable,
unsigned char *color,
int antialias,
int threshold,
int sample_merged)
by_color_select_color (GImage *gimage,
GimpDrawable *drawable,
guchar *color,
gint antialias,
gint threshold,
gint sample_merged)
{
/* Scan over the gimage's active layer, finding pixels within the specified
* threshold from the given R, G, & B values. If antialiasing is on,
@ -173,10 +174,10 @@ by_color_select_color (GImage *gimage,
*/
Channel *mask;
PixelRegion imagePR, maskPR;
unsigned char *image_data;
unsigned char *mask_data;
unsigned char *idata, *mdata;
unsigned char rgb[MAX_CHANNELS];
guchar *image_data;
guchar *mask_data;
guchar *idata, *mdata;
guchar rgb[MAX_CHANNELS];
int has_alpha, indexed;
int width, height;
int bytes, color_bytes, alpha;
@ -195,7 +196,8 @@ by_color_select_color (GImage *gimage,
indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE;
width = gimage->width;
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
{
@ -206,16 +208,20 @@ by_color_select_color (GImage *gimage,
width = drawable_width (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) {
/* indexed colors are always RGB or RGBA */
color_bytes = has_alpha ? 4 : 3;
} else {
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
if (indexed)
{
/* indexed colors are always RGB or RGBA */
color_bytes = has_alpha ? 4 : 3;
}
else
{
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
alpha = bytes - 1;
mask = channel_new_mask (gimage, width, height);
@ -223,7 +229,9 @@ by_color_select_color (GImage *gimage,
0, 0, width, height, TRUE);
/* 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;
mask_data = maskPR.data;
@ -242,8 +250,12 @@ by_color_select_color (GImage *gimage,
rgb[color_bytes - 1] = idata[alpha];
/* Find how closely the colors match */
*mdata++ = is_pixel_sufficiently_different (color, rgb, antialias,
threshold, color_bytes, has_alpha);
*mdata++ = is_pixel_sufficiently_different (color,
rgb,
antialias,
threshold,
color_bytes,
has_alpha);
idata += bytes;
}
@ -257,15 +269,15 @@ by_color_select_color (GImage *gimage,
}
void
by_color_select (GImage *gimage,
GimpDrawable *drawable,
unsigned char *color,
int threshold,
int op,
int antialias,
int feather,
double feather_radius,
int sample_merged)
by_color_select (GImage *gimage,
GimpDrawable *drawable,
guchar *color,
gint threshold,
gint op,
gint antialias,
gint feather,
gdouble feather_radius,
gint sample_merged)
{
Channel * new_mask;
int off_x, off_y;
@ -273,7 +285,8 @@ by_color_select (GImage *gimage,
if (!drawable)
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 (op == REPLACE)
@ -300,7 +313,6 @@ by_color_select (GImage *gimage,
channel_delete (new_mask);
}
/* by_color select action functions */
static void
@ -345,8 +357,25 @@ by_color_select_button_press (Tool *tool,
/* Update the by_color_dialog's active gdisp pointer */
if (by_color_dialog->gimage)
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;
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
@ -356,32 +385,35 @@ by_color_select_button_release (Tool *tool,
{
ByColorSelect * by_color_sel;
GDisplay * gdisp;
int x, y;
gint x, y;
GimpDrawable *drawable;
unsigned char *color;
int use_offsets;
guchar *color;
gint use_offsets;
gdisp = (GDisplay *) gdisp_ptr;
by_color_sel = (ByColorSelect *) tool->private;
drawable = gimage_active_drawable (gdisp->gimage);
gdk_pointer_ungrab (bevent->time);
tool->state = INACTIVE;
/* First take care of the case where the user "cancels" the action */
if (! (bevent->state & GDK_BUTTON3_MASK))
{
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 */
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;
}
else
{
if (!(color = gimp_drawable_get_color_at(drawable, x, y)))
if (!(color = gimp_drawable_get_color_at (drawable, x, y)))
return;
}
@ -394,7 +426,7 @@ by_color_select_button_release (Tool *tool,
by_color_options->feather_radius,
by_color_options->sample_merged);
g_free(color);
g_free (color);
/* show selection on all views */
gdisplays_flush ();
@ -412,17 +444,20 @@ by_color_select_cursor_update (Tool *tool,
{
GDisplay *gdisp;
Layer *layer;
int x, y;
gint x, y;
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 == gdisp->gimage->active_layer)
{
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
return;
}
gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW);
}
@ -450,13 +485,13 @@ by_color_select_control (Tool *tool,
}
static void
by_color_select_options_reset ()
by_color_select_options_reset (void)
{
selection_options_reset (by_color_options);
}
Tool *
tools_new_by_color_select ()
tools_new_by_color_select (void)
{
Tool * tool;
ByColorSelect * private;
@ -471,7 +506,7 @@ tools_new_by_color_select ()
/* The "by color" dialog */
if (!by_color_dialog)
by_color_dialog = by_color_select_new_dialog ();
by_color_dialog = by_color_select_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell))
gtk_widget_show (by_color_dialog->shell);
@ -521,7 +556,6 @@ by_color_select_initialize_by_image (GImage *gimage)
void
by_color_select_initialize (GDisplay *gdisp)
{
/* wrap this call so the tool_info->init_func works */
by_color_select_initialize_by_image (gdisp->gimage);
}
@ -530,37 +564,16 @@ by_color_select_initialize (GDisplay *gdisp)
/****************************/
static ByColorDialog *
by_color_select_new_dialog ()
by_color_select_dialog_new (void)
{
ByColorDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *options_box;
GtkWidget *label;
GtkWidget *util_box;
GtkWidget *slider;
GtkWidget *radio_box;
GtkWidget *radio_button;
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->gimage = NULL;
@ -580,101 +593,98 @@ by_color_select_new_dialog ()
NULL);
/* The vbox */
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* 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 main hbox */
hbox = gtk_hbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), hbox);
/* 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);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0);
bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT);
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);
/* 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_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
by_color_select_image_target_table,
n_by_color_select_image_targets,
by_color_select_targets,
n_by_color_select_targets,
GDK_ACTION_COPY);
gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd);
gtk_widget_show (bcd->preview);
gtk_widget_show (frame);
gtk_widget_show (util_box);
/* options box */
options_box = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (options_box), 5);
gtk_box_pack_start (GTK_BOX (hbox), options_box, TRUE, TRUE, 0);
options_box = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), options_box, FALSE, FALSE, 0);
/* Create the active image label */
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
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 (util_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);
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);
/* Create the opacity scale widget */
util_box = gtk_vbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
label = gtk_label_new (_("Fuzziness Threshold"));
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);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) by_color_select_fuzzy_update,
GTK_SIGNAL_FUNC (by_color_select_fuzzy_update),
bcd);
gtk_widget_show (label);
gtk_widget_show (slider);
gtk_widget_show (util_box);
gtk_widget_show (options_box);
gtk_widget_show (hbox);
gtk_widget_show (vbox);
gtk_widget_show (bcd->shell);
return bcd;
@ -686,14 +696,14 @@ by_color_select_render (ByColorDialog *bcd,
{
Channel * mask;
MaskBuf * scaled_buf = NULL;
unsigned char *buf;
guchar *buf;
PixelRegion srcPR, destPR;
unsigned char * src;
int subsample;
int width, height;
int srcwidth;
int i;
int scale;
guchar * src;
gint subsample;
gint width, height;
gint srcwidth;
gint i;
gint scale;
mask = gimage_get_mask (gimage);
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))
{
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
{
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;
}
@ -726,10 +738,10 @@ by_color_select_render (ByColorDialog *bcd,
gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height);
/* clear the image buf */
buf = (unsigned char *) g_malloc (bcd->preview->requisition.width);
memset (buf, 0, bcd->preview->requisition.width);
buf = g_new0 (guchar, bcd->preview->requisition.width);
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);
/* 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);
/* 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
@ -823,25 +836,25 @@ by_color_select_preview_events (GtkWidget *widget,
static void
by_color_select_type_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
if (by_color_dialog)
by_color_dialog->operation = (long) client_data;
by_color_dialog->operation = (long) data;
}
static void
by_color_select_reset_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data;
bcd = (ByColorDialog *) data;
if (!bcd->gimage)
return;
/* 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;
/* reset the mask */
@ -857,16 +870,16 @@ by_color_select_reset_callback (GtkWidget *widget,
static void
by_color_select_close_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data;
bcd = (ByColorDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell);
if (bcd->gimage &&
gimp_set_have (image_context, bcd->gimage))
if (bcd->gimage && gimp_set_have (image_context, bcd->gimage))
{
bcd->gimage->by_color_select = FALSE;
bcd->gimage = NULL;
@ -880,18 +893,19 @@ by_color_select_fuzzy_update (GtkAdjustment *adjustment,
ByColorDialog *bcd;
bcd = (ByColorDialog *) data;
bcd->threshold = (int) adjustment->value;
bcd->threshold = (gint) (adjustment->value + 0.5);
}
static void
by_color_select_preview_button_press (ByColorDialog *bcd,
GdkEventButton *bevent)
{
int x, y;
int replace, operation;
gint x, y;
gint replace, operation;
GimpDrawable *drawable;
Tile *tile;
unsigned char *col;
guchar *col;
if (!bcd->gimage)
return;

View File

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

View File

@ -15,21 +15,13 @@
* along with this program; if not, write to the Free Software
* 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 "color_balance.h"
#include "color_transfer.h"
#include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h"
#include "gimpui.h"
#include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
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_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */
if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog ();
color_balance_dialog = color_balance_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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++)
{
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->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->image_map =
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 dialog */
/**************************/
static ColorBalanceDialog *
color_balance_new_dialog (void)
color_balance_dialog_new (void)
{
ColorBalanceDialog *cbd;
GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights")
};
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL);
vbox = gtk_vbox_new (FALSE, 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label);
/* 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);
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);
/* 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);
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);
/* 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);
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 */
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);
/* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan"));
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_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);
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_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_FUNC (color_balance_cr_adjustment_update),
cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red"));
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_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 (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta"));
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_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);
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_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_FUNC (color_balance_mg_adjustment_update),
cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green"));
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_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 (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow"));
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_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);
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_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_FUNC (color_balance_yb_adjustment_update),
cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue"));
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_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 (end_label);
gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */
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);
gtk_widget_show (table);
/* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
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_FUNC (appl_mode_callbacks[i]),
GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd);
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 (table);
gtk_widget_show (vbox);
gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd)
{
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;
color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
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
color_balance_ok_callback (GtkWidget *widget,
gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
}
static void
color_balance_shadows_callback (GtkWidget *widget,
gpointer data)
color_balance_range_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS;
color_balance_update (cbd, ALL);
}
range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
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);
}

View File

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

View File

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

View File

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

View File

@ -15,60 +15,51 @@
* along with this program; if not, write to the Free Software
* 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 "brightness_contrast.h"
#include "drawable.h"
#include "gimage_mask.h"
#include "gimplut.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "image_map.h"
#include "interface.h"
#include "gimplut.h"
#include "lut_funcs.h"
#include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define TEXT_HEIGHT 25
#define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 35
#define BRIGHTNESS_SLIDER 0x1
#define CONTRAST_SLIDER 0x2
#define BRIGHTNESS_TEXT 0x4
#define CONTRAST_TEXT 0x8
#define ALL 0xF
#define BRIGHTNESS 0x1
#define CONTRAST 0x2
#define ALL (BRIGHTNESS | CONTRAST)
/* the brightness-contrast structures */
typedef struct _BrightnessContrast BrightnessContrast;
struct _BrightnessContrast
{
gint x, y; /* coords for last mouse click */
};
typedef struct _BrightnessContrastDialog BrightnessContrastDialog;
struct _BrightnessContrastDialog
{
GtkWidget *shell;
GtkWidget *gimage_name;
GtkWidget *brightness_text;
GtkWidget *contrast_text;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
GtkWidget *shell;
GtkWidget *gimage_name;
GimpDrawable *drawable;
ImageMap image_map;
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
double brightness;
double contrast;
GimpDrawable *drawable;
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 BrightnessContrastDialog * brightness_contrast_new_dialog (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 BrightnessContrastDialog * brightness_contrast_dialog_new (void);
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 */
@ -122,7 +114,7 @@ brightness_contrast_control (Tool *tool,
}
Tool *
tools_new_brightness_contrast ()
tools_new_brightness_contrast (void)
{
Tool * tool;
BrightnessContrast * private;
@ -155,7 +147,7 @@ tools_free_brightness_contrast (Tool *tool)
bc = (BrightnessContrast *) tool->private;
/* Close the color select dialog */
/* Close the brightness-contrast dialog */
if (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 */
if (!brightness_contrast_dialog)
brightness_contrast_dialog = brightness_contrast_new_dialog ();
brightness_contrast_dialog = brightness_contrast_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->contrast = 0.0;
brightness_contrast_dialog->contrast = 0.0;
brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->image_map =
@ -190,19 +180,20 @@ brightness_contrast_initialize (GDisplay *gdisp)
brightness_contrast_update (brightness_contrast_dialog, ALL);
}
/********************************/
/* Brightness Contrast dialog */
/********************************/
static BrightnessContrastDialog *
brightness_contrast_new_dialog ()
brightness_contrast_dialog_new (void)
{
BrightnessContrastDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
GtkWidget *label;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *slider;
GtkWidget *toggle;
GtkObject *data;
@ -219,6 +210,8 @@ brightness_contrast_new_dialog ()
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), brightness_contrast_reset_callback,
bcd, NULL, TRUE, FALSE,
_("OK"), brightness_contrast_ok_callback,
bcd, NULL, TRUE, FALSE,
_("Cancel"), brightness_contrast_cancel_callback,
@ -226,94 +219,90 @@ brightness_contrast_new_dialog ()
NULL);
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* The table containing sliders */
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);
/* Create the brightness scale widget */
label = gtk_label_new (_("Brightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_brightness_scale_update,
bcd);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
bcd->brightness_text = gtk_entry_new ();
gtk_widget_set_usize (bcd->brightness_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), bcd->brightness_text, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (bcd->brightness_text), "changed",
(GtkSignalFunc) brightness_contrast_brightness_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (bcd->brightness_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
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);
gtk_widget_show (label);
gtk_widget_show (bcd->brightness_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the contrast scale widget */
label = gtk_label_new (_("Contrast"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) brightness_contrast_contrast_scale_update,
bcd);
gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
bcd->contrast_text = gtk_entry_new ();
gtk_widget_set_usize (bcd->contrast_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), bcd->contrast_text, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (bcd->contrast_text), "changed",
(GtkSignalFunc) brightness_contrast_contrast_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (bcd->contrast_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
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);
gtk_widget_show (label);
gtk_widget_show (bcd->contrast_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Horizontal box for preview and preserve luminosity toggle buttons */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) brightness_contrast_preview_update,
GTK_SIGNAL_FUNC (brightness_contrast_preview_update),
bcd);
gtk_widget_show (label);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
@ -328,27 +317,13 @@ static void
brightness_contrast_update (BrightnessContrastDialog *bcd,
gint update)
{
char text[12];
if (update & BRIGHTNESS_SLIDER)
if (update & BRIGHTNESS)
{
bcd->brightness_data->value = bcd->brightness;
gtk_signal_emit_by_name (GTK_OBJECT (bcd->brightness_data), "value_changed");
gtk_adjustment_set_value (bcd->brightness_data, bcd->brightness);
}
if (update & CONTRAST_SLIDER)
if (update & CONTRAST)
{
bcd->contrast_data->value = 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);
gtk_adjustment_set_value (bcd->contrast_data, bcd->contrast);
}
}
@ -371,12 +346,29 @@ brightness_contrast_preview (BrightnessContrastDialog *bcd)
}
static void
brightness_contrast_ok_callback (GtkWidget *widget,
gpointer client_data)
brightness_contrast_reset_callback (GtkWidget *widget,
gpointer data)
{
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))
gtk_widget_hide (bcd->shell);
@ -446,8 +438,8 @@ brightness_contrast_preview_update (GtkWidget *widget,
}
static void
brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
gpointer data)
brightness_contrast_brightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
BrightnessContrastDialog *bcd;
@ -456,7 +448,6 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
if (bcd->brightness != adjustment->value)
{
bcd->brightness = adjustment->value;
brightness_contrast_update (bcd, BRIGHTNESS_TEXT);
if (bcd->preview)
brightness_contrast_preview (bcd);
@ -464,8 +455,8 @@ brightness_contrast_brightness_scale_update (GtkAdjustment *adjustment,
}
static void
brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
gpointer data)
brightness_contrast_contrast_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
BrightnessContrastDialog *bcd;
@ -474,51 +465,6 @@ brightness_contrast_contrast_scale_update (GtkAdjustment *adjustment,
if (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)
brightness_contrast_preview (bcd);

View File

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

View File

@ -15,32 +15,27 @@
* along with this program; if not, write to the Free Software
* 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 "boundary.h"
#include "by_color_select.h"
#include "colormaps.h"
#include "drawable.h"
#include "draw_core.h"
#include "general.h"
#include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimprc.h"
#include "gimpset.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "selection_options.h"
#include "gimpdnd.h"
#include "tile.h" /* ick. */
#include "libgimp/gimpintl.h"
#include "tile.h" /* ick. */
#define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
#define PREVIEW_HEIGHT 256
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_ENTER_NOTIFY_MASK
@ -48,40 +43,43 @@
/* the by color selection structures */
typedef struct _ByColorSelect ByColorSelect;
struct _ByColorSelect
{
int x, y; /* Point from which to execute seed fill */
int operation; /* add, subtract, normal color selection */
gint x, y; /* Point from which to execute seed fill */
gint operation; /* add, subtract, normal color selection */
};
typedef struct _ByColorDialog ByColorDialog;
struct _ByColorDialog
{
GtkWidget *shell;
GtkWidget *preview;
GtkWidget *gimage_name;
GtkWidget *shell;
int threshold; /* threshold value for color select */
int operation; /* Add, Subtract, Replace */
GImage *gimage; /* gimage which is currently under examination */
GtkWidget *preview;
GtkWidget *gimage_name;
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 */
static SelectionOptions *by_color_options = NULL;
static SelectionOptions * by_color_options = NULL;
/* the by color selection dialog */
static ByColorDialog * by_color_dialog = NULL;
static ByColorDialog * by_color_dialog = NULL;
/* dnd stuff */
static GtkTargetEntry by_color_select_image_target_table[] =
static GtkTargetEntry by_color_select_targets[] =
{
GIMP_TARGET_COLOR
};
static guint n_by_color_select_image_targets =
(sizeof (by_color_select_image_target_table) /
sizeof (by_color_select_image_target_table[0]));
static void by_color_select_color_drop (GtkWidget*, guchar, guchar, guchar, gpointer);
static guint n_by_color_select_targets = (sizeof (by_color_select_targets) /
sizeof (by_color_select_targets[0]));
static void by_color_select_color_drop (GtkWidget *, guchar, guchar, guchar,
gpointer);
/* 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_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_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *, GdkEventButton *,
ByColorDialog *);
static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_reset_callback (GtkWidget *, gpointer);
static void by_color_select_close_callback (GtkWidget *, gpointer);
static void by_color_select_fuzzy_update (GtkAdjustment *, gpointer);
static void by_color_select_render (ByColorDialog *, GImage *);
static void by_color_select_draw (ByColorDialog *, GImage *);
static gint by_color_select_preview_events (GtkWidget *,
GdkEventButton *,
ByColorDialog *);
static void by_color_select_type_callback (GtkWidget *, gpointer);
static void by_color_select_reset_callback (GtkWidget *, 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 *,
GdkEventButton *);
static int is_pixel_sufficiently_different (unsigned char *, unsigned char *, int, int, int, int);
static Channel * by_color_select_color (GImage *, GimpDrawable *, unsigned char *, int, int, int);
static gint is_pixel_sufficiently_different (guchar *, guchar *,
gint, gint, gint, gint);
static Channel * by_color_select_color (GImage *, GimpDrawable *,
guchar *, gint, gint, gint);
/* by_color selection machinery */
static int
is_pixel_sufficiently_different (unsigned char *col1,
unsigned char *col2,
int antialias,
int threshold,
int bytes,
int has_alpha)
is_pixel_sufficiently_different (guchar *col1,
guchar *col2,
gint antialias,
gint threshold,
gint bytes,
gint has_alpha)
{
int diff;
int max;
@ -145,7 +146,7 @@ is_pixel_sufficiently_different (unsigned char *col1,
if (aa <= 0)
return 0;
else if (aa < 0.5)
return (unsigned char) (aa * 512);
return (guchar) (aa * 512);
else
return 255;
}
@ -159,12 +160,12 @@ is_pixel_sufficiently_different (unsigned char *col1,
}
static Channel *
by_color_select_color (GImage *gimage,
GimpDrawable *drawable,
unsigned char *color,
int antialias,
int threshold,
int sample_merged)
by_color_select_color (GImage *gimage,
GimpDrawable *drawable,
guchar *color,
gint antialias,
gint threshold,
gint sample_merged)
{
/* Scan over the gimage's active layer, finding pixels within the specified
* threshold from the given R, G, & B values. If antialiasing is on,
@ -173,10 +174,10 @@ by_color_select_color (GImage *gimage,
*/
Channel *mask;
PixelRegion imagePR, maskPR;
unsigned char *image_data;
unsigned char *mask_data;
unsigned char *idata, *mdata;
unsigned char rgb[MAX_CHANNELS];
guchar *image_data;
guchar *mask_data;
guchar *idata, *mdata;
guchar rgb[MAX_CHANNELS];
int has_alpha, indexed;
int width, height;
int bytes, color_bytes, alpha;
@ -195,7 +196,8 @@ by_color_select_color (GImage *gimage,
indexed = d_type == INDEXEDA_GIMAGE || d_type == INDEXED_GIMAGE;
width = gimage->width;
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
{
@ -206,16 +208,20 @@ by_color_select_color (GImage *gimage,
width = drawable_width (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) {
/* indexed colors are always RGB or RGBA */
color_bytes = has_alpha ? 4 : 3;
} else {
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
if (indexed)
{
/* indexed colors are always RGB or RGBA */
color_bytes = has_alpha ? 4 : 3;
}
else
{
/* RGB, RGBA, GRAY and GRAYA colors are shaped just like the image */
color_bytes = bytes;
}
alpha = bytes - 1;
mask = channel_new_mask (gimage, width, height);
@ -223,7 +229,9 @@ by_color_select_color (GImage *gimage,
0, 0, width, height, TRUE);
/* 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;
mask_data = maskPR.data;
@ -242,8 +250,12 @@ by_color_select_color (GImage *gimage,
rgb[color_bytes - 1] = idata[alpha];
/* Find how closely the colors match */
*mdata++ = is_pixel_sufficiently_different (color, rgb, antialias,
threshold, color_bytes, has_alpha);
*mdata++ = is_pixel_sufficiently_different (color,
rgb,
antialias,
threshold,
color_bytes,
has_alpha);
idata += bytes;
}
@ -257,15 +269,15 @@ by_color_select_color (GImage *gimage,
}
void
by_color_select (GImage *gimage,
GimpDrawable *drawable,
unsigned char *color,
int threshold,
int op,
int antialias,
int feather,
double feather_radius,
int sample_merged)
by_color_select (GImage *gimage,
GimpDrawable *drawable,
guchar *color,
gint threshold,
gint op,
gint antialias,
gint feather,
gdouble feather_radius,
gint sample_merged)
{
Channel * new_mask;
int off_x, off_y;
@ -273,7 +285,8 @@ by_color_select (GImage *gimage,
if (!drawable)
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 (op == REPLACE)
@ -300,7 +313,6 @@ by_color_select (GImage *gimage,
channel_delete (new_mask);
}
/* by_color select action functions */
static void
@ -345,8 +357,25 @@ by_color_select_button_press (Tool *tool,
/* Update the by_color_dialog's active gdisp pointer */
if (by_color_dialog->gimage)
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;
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
@ -356,32 +385,35 @@ by_color_select_button_release (Tool *tool,
{
ByColorSelect * by_color_sel;
GDisplay * gdisp;
int x, y;
gint x, y;
GimpDrawable *drawable;
unsigned char *color;
int use_offsets;
guchar *color;
gint use_offsets;
gdisp = (GDisplay *) gdisp_ptr;
by_color_sel = (ByColorSelect *) tool->private;
drawable = gimage_active_drawable (gdisp->gimage);
gdk_pointer_ungrab (bevent->time);
tool->state = INACTIVE;
/* First take care of the case where the user "cancels" the action */
if (! (bevent->state & GDK_BUTTON3_MASK))
{
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 */
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;
}
else
{
if (!(color = gimp_drawable_get_color_at(drawable, x, y)))
if (!(color = gimp_drawable_get_color_at (drawable, x, y)))
return;
}
@ -394,7 +426,7 @@ by_color_select_button_release (Tool *tool,
by_color_options->feather_radius,
by_color_options->sample_merged);
g_free(color);
g_free (color);
/* show selection on all views */
gdisplays_flush ();
@ -412,17 +444,20 @@ by_color_select_cursor_update (Tool *tool,
{
GDisplay *gdisp;
Layer *layer;
int x, y;
gint x, y;
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 == gdisp->gimage->active_layer)
{
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
return;
}
gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW);
}
@ -450,13 +485,13 @@ by_color_select_control (Tool *tool,
}
static void
by_color_select_options_reset ()
by_color_select_options_reset (void)
{
selection_options_reset (by_color_options);
}
Tool *
tools_new_by_color_select ()
tools_new_by_color_select (void)
{
Tool * tool;
ByColorSelect * private;
@ -471,7 +506,7 @@ tools_new_by_color_select ()
/* The "by color" dialog */
if (!by_color_dialog)
by_color_dialog = by_color_select_new_dialog ();
by_color_dialog = by_color_select_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (by_color_dialog->shell))
gtk_widget_show (by_color_dialog->shell);
@ -521,7 +556,6 @@ by_color_select_initialize_by_image (GImage *gimage)
void
by_color_select_initialize (GDisplay *gdisp)
{
/* wrap this call so the tool_info->init_func works */
by_color_select_initialize_by_image (gdisp->gimage);
}
@ -530,37 +564,16 @@ by_color_select_initialize (GDisplay *gdisp)
/****************************/
static ByColorDialog *
by_color_select_new_dialog ()
by_color_select_dialog_new (void)
{
ByColorDialog *bcd;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *options_box;
GtkWidget *label;
GtkWidget *util_box;
GtkWidget *slider;
GtkWidget *radio_box;
GtkWidget *radio_button;
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->gimage = NULL;
@ -580,101 +593,98 @@ by_color_select_new_dialog ()
NULL);
/* The vbox */
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
/* 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 main hbox */
hbox = gtk_hbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), hbox);
/* 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);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (util_box), frame, FALSE, FALSE, 0);
bcd->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (bcd->preview), PREVIEW_WIDTH, PREVIEW_HEIGHT);
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);
/* 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_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
by_color_select_image_target_table,
n_by_color_select_image_targets,
by_color_select_targets,
n_by_color_select_targets,
GDK_ACTION_COPY);
gimp_dnd_color_dest_set (bcd->preview, by_color_select_color_drop, bcd);
gtk_widget_show (bcd->preview);
gtk_widget_show (frame);
gtk_widget_show (util_box);
/* options box */
options_box = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (options_box), 5);
gtk_box_pack_start (GTK_BOX (hbox), options_box, TRUE, TRUE, 0);
options_box = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), options_box, FALSE, FALSE, 0);
/* Create the active image label */
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
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 (util_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);
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);
/* Create the opacity scale widget */
util_box = gtk_vbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (options_box), util_box, FALSE, FALSE, 0);
label = gtk_label_new (_("Fuzziness Threshold"));
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);
slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) by_color_select_fuzzy_update,
GTK_SIGNAL_FUNC (by_color_select_fuzzy_update),
bcd);
gtk_widget_show (label);
gtk_widget_show (slider);
gtk_widget_show (util_box);
gtk_widget_show (options_box);
gtk_widget_show (hbox);
gtk_widget_show (vbox);
gtk_widget_show (bcd->shell);
return bcd;
@ -686,14 +696,14 @@ by_color_select_render (ByColorDialog *bcd,
{
Channel * mask;
MaskBuf * scaled_buf = NULL;
unsigned char *buf;
guchar *buf;
PixelRegion srcPR, destPR;
unsigned char * src;
int subsample;
int width, height;
int srcwidth;
int i;
int scale;
guchar * src;
gint subsample;
gint width, height;
gint srcwidth;
gint i;
gint scale;
mask = gimage_get_mask (gimage);
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))
{
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
{
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;
}
@ -726,10 +738,10 @@ by_color_select_render (ByColorDialog *bcd,
gtk_preview_size (GTK_PREVIEW (bcd->preview), width, height);
/* clear the image buf */
buf = (unsigned char *) g_malloc (bcd->preview->requisition.width);
memset (buf, 0, bcd->preview->requisition.width);
buf = g_new0 (guchar, bcd->preview->requisition.width);
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);
/* 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);
/* 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
@ -823,25 +836,25 @@ by_color_select_preview_events (GtkWidget *widget,
static void
by_color_select_type_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
if (by_color_dialog)
by_color_dialog->operation = (long) client_data;
by_color_dialog->operation = (long) data;
}
static void
by_color_select_reset_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data;
bcd = (ByColorDialog *) data;
if (!bcd->gimage)
return;
/* 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;
/* reset the mask */
@ -857,16 +870,16 @@ by_color_select_reset_callback (GtkWidget *widget,
static void
by_color_select_close_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ByColorDialog *bcd;
bcd = (ByColorDialog *) client_data;
bcd = (ByColorDialog *) data;
if (GTK_WIDGET_VISIBLE (bcd->shell))
gtk_widget_hide (bcd->shell);
if (bcd->gimage &&
gimp_set_have (image_context, bcd->gimage))
if (bcd->gimage && gimp_set_have (image_context, bcd->gimage))
{
bcd->gimage->by_color_select = FALSE;
bcd->gimage = NULL;
@ -880,18 +893,19 @@ by_color_select_fuzzy_update (GtkAdjustment *adjustment,
ByColorDialog *bcd;
bcd = (ByColorDialog *) data;
bcd->threshold = (int) adjustment->value;
bcd->threshold = (gint) (adjustment->value + 0.5);
}
static void
by_color_select_preview_button_press (ByColorDialog *bcd,
GdkEventButton *bevent)
{
int x, y;
int replace, operation;
gint x, y;
gint replace, operation;
GimpDrawable *drawable;
Tile *tile;
unsigned char *col;
guchar *col;
if (!bcd->gimage)
return;

View File

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

View File

@ -15,21 +15,13 @@
* along with this program; if not, write to the Free Software
* 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 "color_balance.h"
#include "color_transfer.h"
#include "drawable.h"
#include "general.h"
#include "gimage_mask.h"
#include "gdisplay.h"
#include "gimpui.h"
#include "image_map.h"
#include "interface.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
@ -59,15 +51,14 @@ static ColorBalanceDialog *color_balance_dialog = NULL;
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_preview (ColorBalanceDialog *);
static void color_balance_reset_callback (GtkWidget *, gpointer);
static void color_balance_ok_callback (GtkWidget *, gpointer);
static void color_balance_cancel_callback (GtkWidget *, gpointer);
static void color_balance_shadows_callback (GtkWidget *, gpointer);
static void color_balance_midtones_callback (GtkWidget *, gpointer);
static void color_balance_highlights_callback (GtkWidget *, gpointer);
static void color_balance_range_callback (GtkWidget *, gpointer);
static void color_balance_preserve_update (GtkWidget *, gpointer);
static void color_balance_preview_update (GtkWidget *, gpointer);
static void color_balance_cr_adjustment_update (GtkAdjustment *, gpointer);
@ -216,19 +207,18 @@ color_balance_initialize (GDisplay *gdisp)
/* The color balance dialog */
if (!color_balance_dialog)
color_balance_dialog = color_balance_new_dialog ();
color_balance_dialog = color_balance_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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++)
{
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->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->image_map =
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 dialog */
/**************************/
static ColorBalanceDialog *
color_balance_new_dialog (void)
color_balance_dialog_new (void)
{
ColorBalanceDialog *cbd;
GtkWidget *vbox;
@ -266,13 +255,6 @@ color_balance_new_dialog (void)
N_("Highlights")
};
GtkSignalFunc appl_mode_callbacks[] =
{
color_balance_shadows_callback,
color_balance_midtones_callback,
color_balance_highlights_callback
};
cbd = g_new (ColorBalanceDialog, 1);
cbd->preserve_luminosity = TRUE;
cbd->preview = TRUE;
@ -284,6 +266,8 @@ color_balance_new_dialog (void)
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), color_balance_reset_callback,
cbd, NULL, TRUE, FALSE,
_("OK"), color_balance_ok_callback,
cbd, NULL, TRUE, FALSE,
_("Cancel"), color_balance_cancel_callback,
@ -291,12 +275,12 @@ color_balance_new_dialog (void)
NULL);
vbox = gtk_vbox_new (FALSE, 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cbd->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Color Levels:"));
@ -304,7 +288,7 @@ color_balance_new_dialog (void)
gtk_widget_show (label);
/* 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);
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);
/* 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);
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);
/* 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);
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 */
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);
/* Create the cyan-red scale widget */
start_label = gtk_label_new (_("Cyan"));
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_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);
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_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_FUNC (color_balance_cr_adjustment_update),
cbd);
@ -357,7 +341,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Red"));
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_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 (end_label);
@ -367,16 +351,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Magenta"));
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_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);
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_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_FUNC (color_balance_mg_adjustment_update),
cbd);
@ -384,7 +366,7 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Green"));
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_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 (end_label);
@ -394,16 +376,14 @@ color_balance_new_dialog (void)
start_label = gtk_label_new (_("Yellow"));
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_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);
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_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_FUNC (color_balance_yb_adjustment_update),
cbd);
@ -411,35 +391,13 @@ color_balance_new_dialog (void)
end_label = gtk_label_new (_("Blue"));
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_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 (end_label);
gtk_widget_show (slider);
/* Horizontal box for preview and preserve luminosity toggle buttons */
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);
gtk_widget_show (table);
/* Horizontal box for application mode */
hbox = gtk_hbox_new (TRUE, 4);
@ -451,15 +409,43 @@ color_balance_new_dialog (void)
radio_button =
gtk_radio_button_new_with_label (group, gettext (appl_mode_names[i]));
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_FUNC (appl_mode_callbacks[i]),
GTK_SIGNAL_FUNC (color_balance_range_callback),
cbd);
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 (table);
gtk_widget_show (vbox);
gtk_widget_show (cbd->shell);
@ -544,7 +530,10 @@ static void
color_balance_preview (ColorBalanceDialog *cbd)
{
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;
color_balance_create_lookup_tables (cbd);
@ -552,6 +541,24 @@ color_balance_preview (ColorBalanceDialog *cbd)
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
color_balance_ok_callback (GtkWidget *widget,
gpointer data)
@ -605,38 +612,17 @@ color_balance_cancel_callback (GtkWidget *widget,
}
static void
color_balance_shadows_callback (GtkWidget *widget,
gpointer data)
color_balance_range_callback (GtkWidget *widget,
gpointer data)
{
ColorBalanceDialog *cbd;
TransferMode range;
cbd = (ColorBalanceDialog *) data;
cbd->application_mode = SHADOWS;
color_balance_update (cbd, ALL);
}
range = (TransferMode) gtk_object_get_user_data (GTK_OBJECT (widget));
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);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,29 +33,24 @@
#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_HEIGHT 35
#define DA_WIDTH 40
#define DA_HEIGHT 20
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8
#define LIGHTNESS_TEXT 0x10
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation;
struct _HueSaturation
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */
static int hue_transfer[6][256];
static int lightness_transfer[6][256];
static int saturation_transfer[6][256];
static int default_colors[6][3] =
static gint hue_transfer[6][256];
static gint lightness_transfer[6][256];
static gint saturation_transfer[6][256];
static gint default_colors[6][3] =
{
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
};
/* hue saturation action functions */
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 *,
int);
gint);
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_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_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_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_hue_text_update (GtkWidget *, gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer);
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer);
static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *);
/* hue saturation machinery */
void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{
int value;
int hue;
int i;
gint value;
gint hue;
gint i;
/* Calculate transfers */
for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
}
}
/* hue saturation action functions */
static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
}
Tool *
tools_new_hue_saturation ()
tools_new_hue_saturation (void)
{
Tool * tool;
HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void
hue_saturation_initialize (GDisplay *gdisp)
{
int i;
gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */
if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog ();
hue_saturation_dialog = hue_saturation_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->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);
}
void
hue_saturation_free ()
hue_saturation_free (void)
{
if (hue_saturation_dialog)
{
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL;
}
gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/
static HueSaturationDialog *
hue_saturation_new_dialog ()
hue_saturation_dialog_new (void)
{
HueSaturationDialog *hsd;
GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table;
GtkWidget *label;
GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle;
GtkWidget *radio_button;
GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
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->hue_partition = 0;
hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE;
/* 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,
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2);
main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* 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);
/* The table containing hue partitions */
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);
/* 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]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i)
{
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
{
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);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
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);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
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",
(GtkSignalFunc) hue_saturation_hue_partition_events,
GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd);
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",
(GtkSignalFunc) hue_partition_callbacks[i],
GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd);
gtk_widget_show (radio_button);
}
gtk_widget_show (table);
/* 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);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */
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);
/* Create the hue scale widget */
label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed",
(GtkSignalFunc) hue_saturation_hue_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 74, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */
label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->lightness_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed",
(GtkSignalFunc) hue_saturation_lightness_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */
label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->saturation_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed",
(GtkSignalFunc) hue_saturation_saturation_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) hue_saturation_preview_update,
GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void
hue_saturation_update (HueSaturationDialog *hsd,
int update)
gint update)
{
int i, j, b;
int rgb[3];
unsigned char buf[DA_WIDTH * 3];
char text[12];
gint i, j, b;
gint rgb[3];
guchar buf[DA_WIDTH * 3];
if (update & HUE_SLIDER)
{
hsd->hue_data->value = hsd->hue[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
hsd->hue[hsd->hue_partition]);
}
if (update & LIGHTNESS_SLIDER)
{
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
hsd->lightness[hsd->hue_partition]);
}
if (update & SATURATION_SLIDER)
{
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed");
}
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);
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
hsd->saturation[hsd->hue_partition]);
}
hue_saturation_calculate_transfers (hsd);
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[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
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[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);
for (j = 0; j < DA_WIDTH; j++)
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++)
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)
gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd)
{
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;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE;
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_reset_callback (GtkWidget *widget,
gpointer data)
{
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))
gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void
hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
}
static void
hue_saturation_master_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_partition_callback (GtkWidget *widget,
gpointer data)
{
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);
}
static void
hue_saturation_R_callback (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,
hue_saturation_preview_update (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
hsd->preview = TRUE;
hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
}
static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{
hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | 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);
hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog
{
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;
GtkWidget *shell;
GimpDrawable *drawable;
ImageMap image_map;
GtkWidget *hue_partition_da[6];
double hue[7];
double lightness[7];
double saturation[7];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
int hue_partition;
gint preview;
GimpDrawable *drawable;
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);
void tools_free_hue_saturation (Tool *);
Tool * tools_new_hue_saturation (void);
void tools_free_hue_saturation (Tool *tool);
void hue_saturation_initialize (GDisplay *);
void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *);
void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (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__ */

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software
* 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 "drawable.h"
#include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */
typedef struct _Threshold Threshold;
struct _Threshold
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the threshold tool options */
static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */
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_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer);
static void threshold_high_threshold_text_update (GtkWidget *, gpointer);
static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
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 */
void
threshold_2 (void *user_data,
threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR)
{
/* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */
threshold(srcPR, destPR, user_data);
/* this function just re-orders the arguments so we can use
* pixel_regions_process_paralell
*/
threshold (srcPR, destPR, data);
}
static void
threshold (PixelRegion *srcPR,
PixelRegion *destPR,
void *user_data)
void *data)
{
ThresholdDialog *td;
unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b;
int value;
td = (ThresholdDialog *) user_data;
td = (ThresholdDialog *) data;
h = srcPR->h;
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 */
static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
}
Tool *
tools_new_threshold ()
tools_new_threshold (void)
{
Tool * tool;
Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
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);
private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private;
/* Close the color select dialog */
/* Close the threshold dialog */
if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */
if (!threshold_dialog)
threshold_dialog = threshold_new_dialog ();
threshold_dialog = threshold_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram,
threshold_dialog->low_threshold,
threshold_dialog->high_threshold);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview)
threshold_preview (threshold_dialog);
}
/**********************/
/* Threshold dialog */
/**********************/
static ThresholdDialog *
threshold_new_dialog ()
threshold_dialog_new (void)
{
ThresholdDialog *td;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label;
GtkWidget *frame;
GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1);
td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL);
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Threshold Range: "));
label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
/* low threshold text */
td->low_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127");
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);
/* low threshold spinbutton */
data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->low_threshold_data = GTK_ADJUSTMENT (data);
/* high threshold text */
td->high_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255");
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->high_threshold_text), "changed",
(GtkSignalFunc) threshold_high_threshold_text_update,
spinbutton = gtk_spin_button_new (td->low_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->low_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
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);
/* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL);
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);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range,
(void*)td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
GTK_SIGNAL_FUNC (threshold_histogram_range),
td);
gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame);
gtk_widget_show (hbox);
/* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) threshold_preview_update,
GTK_SIGNAL_FUNC (threshold_preview_update),
td);
gtk_widget_show (label);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (vbox);
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;
}
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
threshold_preview (ThresholdDialog *td)
{
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
threshold_ok_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map)
image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void
threshold_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
}
static void
threshold_preview_update (GtkWidget *w,
threshold_preview_update (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
td->preview = TRUE;
threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
}
static void
threshold_low_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->low_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
threshold_preview (td);
}
}
static void
threshold_high_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->high_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
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"
typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog
{
GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text;
GtkWidget *shell;
GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram;
GimpHistogram *hist;
GimpDrawable *drawable;
ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
GimpDrawable *drawable;
ImageMap image_map;
gint preview;
gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
};
/* by_color select functions */
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *);
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *tool);
void threshold_initialize (GDisplay *);
void threshold_2 (void *, PixelRegion *, PixelRegion *);
void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */

View File

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

View File

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

View File

@ -33,29 +33,24 @@
#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_HEIGHT 35
#define DA_WIDTH 40
#define DA_HEIGHT 20
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define HUE_TEXT 0x8
#define LIGHTNESS_TEXT 0x10
#define SATURATION_TEXT 0x20
#define DRAW 0x40
#define ALL 0xFF
#define HUE_PARTITION 0x0
#define HUE_SLIDER 0x1
#define LIGHTNESS_SLIDER 0x2
#define SATURATION_SLIDER 0x4
#define DRAW 0x40
#define ALL 0xFF
/* the hue-saturation structures */
typedef struct _HueSaturation HueSaturation;
struct _HueSaturation
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the hue-saturation tool options */
@ -65,56 +60,49 @@ static ToolOptions *hue_saturation_options = NULL;
static HueSaturationDialog *hue_saturation_dialog = NULL;
/* Local variables */
static int hue_transfer[6][256];
static int lightness_transfer[6][256];
static int saturation_transfer[6][256];
static int default_colors[6][3] =
static gint hue_transfer[6][256];
static gint lightness_transfer[6][256];
static gint saturation_transfer[6][256];
static gint default_colors[6][3] =
{
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
{ 255, 0, 0 },
{ 255, 255, 0 },
{ 0, 255, 0 },
{ 0, 255, 255 },
{ 0, 0, 255 },
{ 255, 0, 255 }
};
/* hue saturation action functions */
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 *,
int);
gint);
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_cancel_callback (GtkWidget *, gpointer);
static void hue_saturation_master_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_partition_callback (GtkWidget *, gpointer);
static void hue_saturation_preview_update (GtkWidget *, gpointer);
static void hue_saturation_hue_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_lightness_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_saturation_scale_update (GtkAdjustment *, gpointer);
static void hue_saturation_hue_text_update (GtkWidget *, gpointer);
static void hue_saturation_lightness_text_update (GtkWidget *, gpointer);
static void hue_saturation_saturation_text_update (GtkWidget *, gpointer);
static void hue_saturation_hue_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_lightness_adjustment_update (GtkAdjustment *,
gpointer);
static void hue_saturation_saturation_adjustment_update (GtkAdjustment *,
gpointer);
static gint hue_saturation_hue_partition_events (GtkWidget *, GdkEvent *,
HueSaturationDialog *);
/* hue saturation machinery */
void
hue_saturation_calculate_transfers (HueSaturationDialog *hsd)
{
int value;
int hue;
int i;
gint value;
gint hue;
gint i;
/* Calculate transfers */
for (hue = 0; hue < 6; hue++)
@ -221,7 +209,6 @@ hue_saturation (PixelRegion *srcPR,
}
}
/* hue saturation action functions */
static void
@ -248,7 +235,7 @@ hue_saturation_control (Tool *tool,
}
Tool *
tools_new_hue_saturation ()
tools_new_hue_saturation (void)
{
Tool * tool;
HueSaturation * private;
@ -290,7 +277,7 @@ tools_free_hue_saturation (Tool *tool)
void
hue_saturation_initialize (GDisplay *gdisp)
{
int i;
gint i;
if (! drawable_color (gimage_active_drawable (gdisp->gimage)))
{
@ -300,7 +287,7 @@ hue_saturation_initialize (GDisplay *gdisp)
/* The "hue-saturation" dialog */
if (!hue_saturation_dialog)
hue_saturation_dialog = hue_saturation_new_dialog ();
hue_saturation_dialog = hue_saturation_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->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);
}
void
hue_saturation_free ()
hue_saturation_free (void)
{
if (hue_saturation_dialog)
{
@ -327,6 +316,7 @@ hue_saturation_free ()
active_tool->preserve = TRUE;
image_map_abort (hue_saturation_dialog->image_map);
active_tool->preserve = FALSE;
hue_saturation_dialog->image_map = NULL;
}
gtk_widget_destroy (hue_saturation_dialog->shell);
@ -338,7 +328,7 @@ hue_saturation_free ()
/***************************/
static HueSaturationDialog *
hue_saturation_new_dialog ()
hue_saturation_dialog_new (void)
{
HueSaturationDialog *hsd;
GtkWidget *main_vbox;
@ -348,6 +338,8 @@ hue_saturation_new_dialog ()
GtkWidget *table;
GtkWidget *label;
GtkWidget *slider;
GtkWidget *abox;
GtkWidget *spinbutton;
GtkWidget *toggle;
GtkWidget *radio_button;
GtkWidget *frame;
@ -366,27 +358,18 @@ hue_saturation_new_dialog ()
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->hue_partition = 0;
hsd->hue_partition = ALL_HUES;
hsd->preview = TRUE;
/* 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,
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), hue_saturation_reset_callback,
hsd, NULL, FALSE, FALSE,
_("OK"), hue_saturation_ok_callback,
hsd, NULL, TRUE, FALSE,
_("Cancel"), hue_saturation_cancel_callback,
@ -394,16 +377,18 @@ hue_saturation_new_dialog ()
NULL);
main_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2);
main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (hsd->shell)->vbox), main_vbox);
/* 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);
/* The table containing hue partitions */
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);
/* 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]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_object_set_data (GTK_OBJECT (radio_button), "hue_partition",
(gpointer) i);
if (!i)
{
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
{
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);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
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);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]), DA_WIDTH, DA_HEIGHT);
gtk_widget_set_events (hsd->hue_partition_da[i - 1], HUE_PARTITION_MASK);
gtk_preview_size (GTK_PREVIEW (hsd->hue_partition_da[i - 1]),
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",
(GtkSignalFunc) hue_saturation_hue_partition_events,
GTK_SIGNAL_FUNC (hue_saturation_hue_partition_events),
hsd);
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",
(GtkSignalFunc) hue_partition_callbacks[i],
GTK_SIGNAL_FUNC (hue_saturation_partition_callback),
hsd);
gtk_widget_show (radio_button);
}
gtk_widget_show (table);
/* 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);
label = gtk_label_new (_("Hue / Lightness / Saturation Adjustments"));
@ -456,126 +447,130 @@ hue_saturation_new_dialog ()
/* The table containing sliders */
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);
/* Create the hue scale widget */
label = gtk_label_new (_("Hue"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_hue_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->hue_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->hue_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->hue_text, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->hue_text), "changed",
(GtkSignalFunc) hue_saturation_hue_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->hue_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 74, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->hue_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the lightness scale widget */
label = gtk_label_new (_("Lightness"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_lightness_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->lightness_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->lightness_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->lightness_text, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2, 2);
gtk_signal_connect (GTK_OBJECT (hsd->lightness_text), "changed",
(GtkSignalFunc) hue_saturation_lightness_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->lightness_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->lightness_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
/* Create the saturation scale widget */
label = gtk_label_new (_("Saturation"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
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);
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_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
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_signal_connect (GTK_OBJECT (data), "value_changed",
(GtkSignalFunc) hue_saturation_saturation_scale_update,
hsd);
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
hsd->saturation_text = gtk_entry_new ();
gtk_widget_set_usize (hsd->saturation_text, TEXT_WIDTH, TEXT_HEIGHT);
gtk_table_attach (GTK_TABLE (table), hsd->saturation_text, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 3, 2);
gtk_signal_connect (GTK_OBJECT (hsd->saturation_text), "changed",
(GtkSignalFunc) hue_saturation_saturation_text_update,
abox = gtk_vbox_new (FALSE, 0);
spinbutton = gtk_spin_button_new (hsd->saturation_data, 1.0, 0);
gtk_widget_set_usize (spinbutton, 75, -1);
gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 2, 3,
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);
gtk_widget_show (label);
gtk_widget_show (hsd->saturation_text);
gtk_widget_show (slider);
gtk_widget_show (spinbutton);
gtk_widget_show (abox);
gtk_widget_show (table);
/* Horizontal box for preview and colorize toggle buttons */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
/* Horizontal box for preview toggle button */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) hue_saturation_preview_update,
GTK_SIGNAL_FUNC (hue_saturation_preview_update),
hsd);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (main_hbox);
gtk_widget_show (main_vbox);
@ -586,66 +581,51 @@ hue_saturation_new_dialog ()
static void
hue_saturation_update (HueSaturationDialog *hsd,
int update)
gint update)
{
int i, j, b;
int rgb[3];
unsigned char buf[DA_WIDTH * 3];
char text[12];
gint i, j, b;
gint rgb[3];
guchar buf[DA_WIDTH * 3];
if (update & HUE_SLIDER)
{
hsd->hue_data->value = hsd->hue[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->hue_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->hue_data),
hsd->hue[hsd->hue_partition]);
}
if (update & LIGHTNESS_SLIDER)
{
hsd->lightness_data->value = hsd->lightness[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->lightness_data), "value_changed");
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->lightness_data),
hsd->lightness[hsd->hue_partition]);
}
if (update & SATURATION_SLIDER)
{
hsd->saturation_data->value = hsd->saturation[hsd->hue_partition];
gtk_signal_emit_by_name (GTK_OBJECT (hsd->saturation_data), "value_changed");
}
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);
gtk_adjustment_set_value (GTK_ADJUSTMENT (hsd->saturation_data),
hsd->saturation[hsd->hue_partition]);
}
hue_saturation_calculate_transfers (hsd);
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[BLUE_PIX] = default_colors[i][BLUE_PIX];
rgb[BLUE_PIX] = default_colors[i][BLUE_PIX];
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[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);
for (j = 0; j < DA_WIDTH; j++)
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++)
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)
gtk_widget_draw (hsd->hue_partition_da[i], NULL);
@ -656,19 +636,41 @@ static void
hue_saturation_preview (HueSaturationDialog *hsd)
{
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;
image_map_apply (hsd->image_map, hue_saturation, (void *) hsd);
active_tool->preserve = FALSE;
}
static void
hue_saturation_ok_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_reset_callback (GtkWidget *widget,
gpointer data)
{
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))
gtk_widget_hide (hsd->shell);
@ -691,11 +693,12 @@ hue_saturation_ok_callback (GtkWidget *widget,
static void
hue_saturation_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) client_data;
hsd = (HueSaturationDialog *) data;
if (GTK_WIDGET_VISIBLE (hsd->shell))
gtk_widget_hide (hsd->shell);
@ -714,91 +717,30 @@ hue_saturation_cancel_callback (GtkWidget *widget,
}
static void
hue_saturation_master_callback (GtkWidget *widget,
gpointer client_data)
hue_saturation_partition_callback (GtkWidget *widget,
gpointer data)
{
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);
}
static void
hue_saturation_R_callback (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,
hue_saturation_preview_update (GtkWidget *widget,
gpointer data)
{
HueSaturationDialog *hsd;
hsd = (HueSaturationDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
hsd->preview = TRUE;
hue_saturation_preview (hsd);
@ -808,8 +750,8 @@ hue_saturation_preview_update (GtkWidget *w,
}
static void
hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_hue_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -818,7 +760,7 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -826,8 +768,8 @@ hue_saturation_hue_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_lightness_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -836,7 +778,7 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
if (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)
hue_saturation_preview (hsd);
@ -844,8 +786,8 @@ hue_saturation_lightness_scale_update (GtkAdjustment *adjustment,
}
static void
hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
gpointer data)
hue_saturation_saturation_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
HueSaturationDialog *hsd;
@ -854,73 +796,7 @@ hue_saturation_saturation_scale_update (GtkAdjustment *adjustment,
if (hsd->saturation[hsd->hue_partition] != adjustment->value)
{
hsd->saturation[hsd->hue_partition] = adjustment->value;
hue_saturation_update (hsd, SATURATION_TEXT | 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);
hue_saturation_update (hsd, DRAW);
if (hsd->preview)
hue_saturation_preview (hsd);

View File

@ -35,37 +35,37 @@ typedef enum
} HueRange;
typedef struct _HueSaturationDialog HueSaturationDialog;
struct _HueSaturationDialog
{
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;
GtkWidget *shell;
GimpDrawable *drawable;
ImageMap image_map;
GtkWidget *hue_partition_da[6];
double hue[7];
double lightness[7];
double saturation[7];
GtkAdjustment *hue_data;
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
int hue_partition;
gint preview;
GimpDrawable *drawable;
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);
void tools_free_hue_saturation (Tool *);
Tool * tools_new_hue_saturation (void);
void tools_free_hue_saturation (Tool *tool);
void hue_saturation_initialize (GDisplay *);
void hue_saturation_free (void);
void hue_saturation (PixelRegion *, PixelRegion *, void *);
void hue_saturation_initialize (GDisplay *gdisp);
void hue_saturation_free (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__ */

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software
* 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 "drawable.h"
#include "general.h"
@ -28,58 +25,66 @@
#include "libgimp/gimpintl.h"
#define TEXT_WIDTH 45
#define HISTOGRAM_WIDTH 256
#define HISTOGRAM_HEIGHT 150
#define LOW 0x1
#define HIGH 0x2
#define HISTORGAM 0x4
#define ALL (LOW | HIGH | HISTOGRAM)
/* the threshold structures */
typedef struct _Threshold Threshold;
struct _Threshold
{
int x, y; /* coords for last mouse click */
gint x, y; /* coords for last mouse click */
};
/* the threshold tool options */
static ToolOptions *threshold_options = NULL;
/* the threshold tool dialog */
static ThresholdDialog *threshold_dialog = NULL;
/* threshold action functions */
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_reset_callback (GtkWidget *, gpointer);
static void threshold_ok_callback (GtkWidget *, gpointer);
static void threshold_cancel_callback (GtkWidget *, gpointer);
static void threshold_preview_update (GtkWidget *, gpointer);
static void threshold_low_threshold_text_update (GtkWidget *, gpointer);
static void threshold_high_threshold_text_update (GtkWidget *, gpointer);
static void threshold_low_threshold_adjustment_update (GtkAdjustment *,
gpointer);
static void threshold_high_threshold_adjustment_update (GtkAdjustment *,
gpointer);
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 */
void
threshold_2 (void *user_data,
threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR)
{
/* this function just re-orders the arguments so we can use
pixel_regions_process_paralell */
threshold(srcPR, destPR, user_data);
/* this function just re-orders the arguments so we can use
* pixel_regions_process_paralell
*/
threshold (srcPR, destPR, data);
}
static void
threshold (PixelRegion *srcPR,
PixelRegion *destPR,
void *user_data)
void *data)
{
ThresholdDialog *td;
unsigned char *src, *s;
@ -88,7 +93,7 @@ threshold (PixelRegion *srcPR,
int w, h, b;
int value;
td = (ThresholdDialog *) user_data;
td = (ThresholdDialog *) data;
h = srcPR->h;
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 */
static void
@ -176,7 +159,7 @@ threshold_control (Tool *tool,
}
Tool *
tools_new_threshold ()
tools_new_threshold (void)
{
Tool * tool;
Threshold * private;
@ -188,13 +171,6 @@ tools_new_threshold ()
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);
private = g_new (Threshold, 1);
@ -215,7 +191,7 @@ tools_free_threshold (Tool *tool)
thresh = (Threshold *) tool->private;
/* Close the color select dialog */
/* Close the threshold dialog */
if (threshold_dialog)
threshold_cancel_callback (NULL, (gpointer) threshold_dialog);
@ -233,11 +209,14 @@ threshold_initialize (GDisplay *gdisp)
/* The threshold dialog */
if (!threshold_dialog)
threshold_dialog = threshold_new_dialog ();
threshold_dialog = threshold_dialog_new ();
else
if (!GTK_WIDGET_VISIBLE (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->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map =
@ -245,31 +224,35 @@ threshold_initialize (GDisplay *gdisp)
gimp_histogram_calculate_drawable (threshold_dialog->hist,
threshold_dialog->drawable);
gtk_signal_handler_block_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
histogram_widget_update (threshold_dialog->histogram,
threshold_dialog->hist);
histogram_widget_range (threshold_dialog->histogram,
threshold_dialog->low_threshold,
threshold_dialog->high_threshold);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (threshold_dialog->histogram),
threshold_dialog);
threshold_update (threshold_dialog, ALL);
if (threshold_dialog->preview)
threshold_preview (threshold_dialog);
}
/**********************/
/* Threshold dialog */
/**********************/
static ThresholdDialog *
threshold_new_dialog ()
threshold_dialog_new (void)
{
ThresholdDialog *td;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *spinbutton;
GtkWidget *label;
GtkWidget *frame;
GtkWidget *toggle;
GtkObject *data;
td = g_new (ThresholdDialog, 1);
td->preview = TRUE;
@ -284,6 +267,8 @@ threshold_new_dialog ()
GTK_WIN_POS_NONE,
FALSE, TRUE, FALSE,
_("Reset"), threshold_reset_callback,
td, NULL, TRUE, FALSE,
_("OK"), threshold_ok_callback,
td, NULL, TRUE, FALSE,
_("Cancel"), threshold_cancel_callback,
@ -291,42 +276,51 @@ threshold_new_dialog ()
NULL);
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (td->shell)->vbox), vbox);
/* 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);
label = gtk_label_new (_("Threshold Range: "));
label = gtk_label_new (_("Threshold Range:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
/* low threshold text */
td->low_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->low_threshold_text), "127");
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);
/* low threshold spinbutton */
data = gtk_adjustment_new (td->low_threshold, 0.0, 255.0, 1.0, 10.0, 0.0);
td->low_threshold_data = GTK_ADJUSTMENT (data);
/* high threshold text */
td->high_threshold_text = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (td->high_threshold_text), "255");
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->high_threshold_text), "changed",
(GtkSignalFunc) threshold_high_threshold_text_update,
spinbutton = gtk_spin_button_new (td->low_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->low_threshold_data), "value_changed",
GTK_SIGNAL_FUNC (threshold_low_threshold_adjustment_update),
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);
/* The threshold histogram */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
hbox = gtk_hbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL);
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);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (td->histogram));
gtk_signal_connect (GTK_OBJECT (td->histogram), "rangechanged",
(GtkSignalFunc) threshold_histogram_range,
(void*)td);
gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET(td->histogram));
GTK_SIGNAL_FUNC (threshold_histogram_range),
td);
gtk_widget_show (GTK_WIDGET(td->histogram));
gtk_widget_show (frame);
gtk_widget_show (hbox);
/* Horizontal box for preview */
hbox = gtk_hbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_end (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), 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",
(GtkSignalFunc) threshold_preview_update,
GTK_SIGNAL_FUNC (threshold_preview_update),
td);
gtk_widget_show (label);
gtk_widget_show (toggle);
gtk_widget_show (hbox);
gtk_widget_show (vbox);
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;
}
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
threshold_preview (ThresholdDialog *td)
{
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
threshold_ok_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -391,6 +427,7 @@ threshold_ok_callback (GtkWidget *widget,
if (!td->preview)
image_map_apply (td->image_map, threshold, (void *) td);
if (td->image_map)
image_map_commit (td->image_map);
@ -404,11 +441,12 @@ threshold_ok_callback (GtkWidget *widget,
static void
threshold_cancel_callback (GtkWidget *widget,
gpointer client_data)
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) client_data;
td = (ThresholdDialog *) data;
if (GTK_WIDGET_VISIBLE (td->shell))
gtk_widget_hide (td->shell);
@ -427,14 +465,14 @@ threshold_cancel_callback (GtkWidget *widget,
}
static void
threshold_preview_update (GtkWidget *w,
threshold_preview_update (GtkWidget *widget,
gpointer data)
{
ThresholdDialog *td;
td = (ThresholdDialog *) data;
if (GTK_TOGGLE_BUTTON (w)->active)
if (GTK_TOGGLE_BUTTON (widget)->active)
{
td->preview = TRUE;
threshold_preview (td);
@ -444,47 +482,58 @@ threshold_preview_update (GtkWidget *w,
}
static void
threshold_low_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_low_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->low_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
threshold_preview (td);
}
}
static void
threshold_high_threshold_text_update (GtkWidget *w,
gpointer data)
threshold_high_threshold_adjustment_update (GtkAdjustment *adjustment,
gpointer data)
{
ThresholdDialog *td;
char *str;
int value;
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;
histogram_widget_range (td->histogram,
td->low_threshold,
td->high_threshold);
td->high_threshold = adjustment->value;
threshold_update (td, HISTOGRAM);
if (td->preview)
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"
typedef struct _ThresholdDialog ThresholdDialog;
struct _ThresholdDialog
{
GtkWidget *shell;
GtkWidget *low_threshold_text;
GtkWidget *high_threshold_text;
GtkWidget *shell;
GtkAdjustment *low_threshold_data;
GtkAdjustment *high_threshold_data;
HistogramWidget *histogram;
GimpHistogram *hist;
GimpDrawable *drawable;
ImageMap image_map;
int color;
int low_threshold;
int high_threshold;
GimpDrawable *drawable;
ImageMap image_map;
gint preview;
gint color;
gint low_threshold;
gint high_threshold;
gboolean preview;
};
/* by_color select functions */
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *);
Tool * tools_new_threshold (void);
void tools_free_threshold (Tool *tool);
void threshold_initialize (GDisplay *);
void threshold_2 (void *, PixelRegion *, PixelRegion *);
void threshold_initialize (GDisplay *gdisp);
void threshold_2 (void *data,
PixelRegion *srcPR,
PixelRegion *destPR);
#endif /* __THRESHOLD_H__ */

View File

@ -802,7 +802,17 @@ tools_initialize (ToolType tool_type,
if (tool_info[(gint) tool_type].init_func && !gdisp)
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)
{

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_page_switch (GtkWidget *, GtkNotebookPage *,
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 */
typedef struct _ColorSelectorInfo {
typedef struct _ColorSelectorInfo
{
char *name; /* label used in notebook tab */
char *help_page;
GimpColorSelectorMethods m;
@ -53,7 +54,8 @@ typedef struct _ColorSelectorInfo {
struct _ColorSelectorInfo *next;
} ColorSelectorInfo;
typedef struct _ColorSelectorInstance {
typedef struct _ColorSelectorInstance
{
_ColorNotebook *color_notebook;
ColorSelectorInfo *info;
GtkWidget *frame; /* main widget */
@ -103,7 +105,7 @@ color_notebook_new (int r,
cnp->shell =
gimp_dialog_new (_("Color Selection"), "color_selection",
color_notebook_help_func, cnp,
color_notebook_help_func, (gchar *) cnp,
GTK_WIN_POS_NONE,
FALSE, FALSE, FALSE,
@ -339,7 +341,7 @@ color_notebook_page_switch (GtkWidget *widget,
}
static void
color_notebook_help_func (gpointer data)
color_notebook_help_func (gchar *data)
{
ColorNotebookP cnp;
gchar *help_path;

View File

@ -99,21 +99,6 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { N_("/File/Preferences..."), NULL, file_pref_cmd_callback, 0 },
"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 */
{ { N_("/File/---"), NULL, NULL, 0, "<Separator>" },

View File

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