added a new enum to specify how to display histograms.

2003-01-25  Sven Neumann  <sven@gimp.org>

	* app/widgets/widgets-enums.h: added a new enum to specify how to
	display histograms.

	* app/widgets/widgets-enums.c: regenerated.

	* app/widgets/gimphistogramview.[ch]: added a scale property and
	made channel a property. Added support for linear histograms based
	on a patch from Akkana (see bug #72951).

	* app/widgets/gimphistogrambox.c: redraw the gradient when the
	histogram view notifies it that the displayed channel has changed.

	* app/tools/gimphistogramtool.c: added a menu to configure the
	histogram scale.
This commit is contained in:
Sven Neumann 2003-01-25 18:58:45 +00:00 committed by Sven Neumann
parent 90e72e5f62
commit 04d29efd74
7 changed files with 260 additions and 83 deletions

View File

@ -1,3 +1,20 @@
2003-01-25 Sven Neumann <sven@gimp.org>
* app/widgets/widgets-enums.h: added a new enum to specify how to
display histograms.
* app/widgets/widgets-enums.c: regenerated.
* app/widgets/gimphistogramview.[ch]: added a scale property and
made channel a property. Added support for linear histograms based
on a patch from Akkana (see bug #72951).
* app/widgets/gimphistogrambox.c: redraw the gradient when the
histogram view notifies it that the displayed channel has changed.
* app/tools/gimphistogramtool.c: added a menu to configure the
histogram scale.
2003-01-24 Michael Natterer <mitch@gimp.org>
* app/core/gimpdocumentlist.[ch]

View File

@ -38,6 +38,7 @@
#include "widgets/gimpenummenu.h"
#include "widgets/gimphistogrambox.h"
#include "widgets/gimphistogramview.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpviewabledialog.h"
#include "display/gimpdisplay.h"
@ -54,24 +55,22 @@ typedef struct _HistogramToolDialog HistogramToolDialog;
struct _HistogramToolDialog
{
GtkWidget *shell;
GtkWidget *shell;
GtkWidget *info_labels[6];
GtkWidget *channel_menu;
GimpHistogramBox *histogram_box;
GimpHistogram *hist;
GtkWidget *gradient;
GtkWidget *info_labels[6];
GtkWidget *channel_menu;
GimpHistogramBox *histogram_box;
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;
GimpHistogramChannel channel;
gboolean color;
GimpDrawable *drawable;
};
@ -93,8 +92,6 @@ static void histogram_tool_close_callback (GtkWidget *widget,
static gboolean histogram_set_sensitive_callback
(gpointer item_data,
HistogramToolDialog *htd);
static void histogram_tool_channel_callback (GtkWidget *widget,
gpointer data);
static void histogram_tool_dialog_update (HistogramToolDialog *htd,
gint start,
gint end);
@ -199,13 +196,10 @@ gimp_histogram_tool_initialize (GimpTool *tool,
gtk_widget_show (histogram_dialog->shell);
histogram_dialog->drawable = drawable;
histogram_dialog->color = gimp_drawable_is_rgb (drawable);
gimp_option_menu_set_sensitive (GTK_OPTION_MENU (histogram_dialog->channel_menu),
(GimpOptionMenuSensitivityCallback) histogram_set_sensitive_callback,
histogram_dialog);
gimp_option_menu_set_history (GTK_OPTION_MENU (histogram_dialog->channel_menu),
GINT_TO_POINTER (histogram_dialog->channel));
/* calculate the histogram */
pixel_region_init (&PR, gimp_drawable_data (drawable),
@ -255,9 +249,10 @@ histogram_tool_histogram_range (GimpHistogramView *widget,
gint end,
gpointer data)
{
HistogramToolDialog *htd;
gdouble pixels;
gdouble count;
HistogramToolDialog *htd;
GimpHistogramChannel channel;
gdouble pixels;
gdouble count;
htd = (HistogramToolDialog *) data;
@ -265,12 +260,14 @@ histogram_tool_histogram_range (GimpHistogramView *widget,
gimp_histogram_nchannels (htd->hist) <= 0)
return;
channel = gimp_histogram_view_get_channel (htd->histogram_box->histogram);
pixels = gimp_histogram_get_count (htd->hist, 0, 255);
count = gimp_histogram_get_count (htd->hist, start, end);
htd->mean = gimp_histogram_get_mean (htd->hist, htd->channel, start, end);
htd->std_dev = gimp_histogram_get_std_dev (htd->hist, htd->channel, start, end);
htd->median = gimp_histogram_get_median (htd->hist, htd->channel, start, end);
htd->mean = gimp_histogram_get_mean (htd->hist, channel, start, end);
htd->std_dev = gimp_histogram_get_std_dev (htd->hist, channel, start, end);
htd->median = gimp_histogram_get_median (htd->hist, channel, start, end);
htd->pixels = pixels;
htd->count = count;
htd->percentile = count / pixels;
@ -323,6 +320,7 @@ histogram_tool_dialog_new (GimpToolInfo *tool_info)
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *label;
GtkWidget *menu;
gint i;
gint x, y;
@ -337,7 +335,6 @@ histogram_tool_dialog_new (GimpToolInfo *tool_info)
};
htd = g_new0 (HistogramToolDialog, 1);
htd->channel = GIMP_HISTOGRAM_VALUE;
htd->hist = gimp_histogram_new (GIMP_BASE_CONFIG (tool_info->gimp->config));
/* The shell and main vbox */
@ -359,6 +356,10 @@ histogram_tool_dialog_new (GimpToolInfo *tool_info)
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (htd->shell)->vbox), vbox);
gtk_widget_show (vbox);
/* Create the histogram view first */
htd->histogram_box =
GIMP_HISTOGRAM_BOX (gimp_histogram_box_new (_("Intensity Range:")));
/* The option menu for selecting channels */
hbox = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@ -368,16 +369,13 @@ histogram_tool_dialog_new (GimpToolInfo *tool_info)
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
htd->channel_menu =
gimp_enum_option_menu_new (GIMP_TYPE_HISTOGRAM_CHANNEL,
G_CALLBACK (histogram_tool_channel_callback),
htd);
htd->channel_menu =
gimp_prop_enum_option_menu_new (G_OBJECT (htd->histogram_box->histogram),
"channel", 0, 0);
gtk_box_pack_start (GTK_BOX (hbox), htd->channel_menu, FALSE, FALSE, 0);
gtk_widget_show (htd->channel_menu);
/* The histogram tool histogram */
htd->histogram_box =
GIMP_HISTOGRAM_BOX (gimp_histogram_box_new (_("Intensity Range:")));
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (htd->histogram_box),
TRUE, TRUE, 0);
gtk_widget_show (GTK_WIDGET (htd->histogram_box));
@ -386,6 +384,21 @@ histogram_tool_dialog_new (GimpToolInfo *tool_info)
G_CALLBACK (histogram_tool_histogram_range),
htd);
/* The option menu for selecting the histogram scale */
hbox = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new (_("Histogram Scale:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
menu =
gimp_prop_enum_option_menu_new (G_OBJECT (htd->histogram_box->histogram),
"scale", 0, 0);
gtk_box_pack_start (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
gtk_widget_show (menu);
/* The table containing histogram information */
table = gtk_table_new (3, 4, TRUE);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
@ -432,19 +445,6 @@ histogram_tool_close_callback (GtkWidget *widget,
active_tool->drawable = NULL;
}
static void
histogram_tool_channel_callback (GtkWidget *widget,
gpointer data)
{
HistogramToolDialog *htd;
htd = (HistogramToolDialog *) data;
gimp_menu_item_update (widget, &htd->channel);
gimp_histogram_box_set_channel (htd->histogram_box, htd->channel);
}
static gboolean
histogram_set_sensitive_callback (gpointer item_data,
HistogramToolDialog *htd)
@ -458,7 +458,7 @@ histogram_set_sensitive_callback (gpointer item_data,
case GIMP_HISTOGRAM_RED:
case GIMP_HISTOGRAM_GREEN:
case GIMP_HISTOGRAM_BLUE:
return htd->color;
return gimp_drawable_is_rgb (htd->drawable);
case GIMP_HISTOGRAM_ALPHA:
return gimp_drawable_has_alpha (htd->drawable);
}

View File

@ -182,6 +182,10 @@ gimp_histogram_box_init (GimpHistogramBox *box)
g_signal_connect (box->gradient, "expose_event",
G_CALLBACK (gimp_histogram_box_gradient_expose),
box);
g_signal_connect_swapped (view, "notify::channel",
G_CALLBACK (gtk_widget_queue_draw),
box->gradient);
}
static void
@ -332,6 +336,5 @@ gimp_histogram_box_set_channel (GimpHistogramBox *box,
return;
gimp_histogram_view_set_channel (box->histogram, channel);
gtk_widget_queue_draw (box->gradient);
}

View File

@ -39,12 +39,26 @@ enum
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_CHANNEL,
PROP_SCALE
};
static void gimp_histogram_view_class_init (GimpHistogramViewClass *klass);
static void gimp_histogram_view_init (GimpHistogramView *view);
static void gimp_histogram_view_finalize (GObject *object);
static gboolean gimp_histogram_view_expose (GtkWidget *widget,
GdkEventExpose *event);
static void gimp_histogram_view_finalize (GObject *object);
static void gimp_histogram_view_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_histogram_view_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gboolean gimp_histogram_view_expose (GtkWidget *widget,
GdkEventExpose *event);
static guint histogram_view_signals[LAST_SIGNAL] = { 0 };
@ -102,17 +116,33 @@ gimp_histogram_view_class_init (GimpHistogramViewClass *klass)
G_TYPE_INT,
G_TYPE_INT);
object_class->get_property = gimp_histogram_view_get_property;
object_class->set_property = gimp_histogram_view_set_property;
object_class->finalize = gimp_histogram_view_finalize;
widget_class->expose_event = gimp_histogram_view_expose;
klass->range_changed = NULL;
g_object_class_install_property (object_class, PROP_CHANNEL,
g_param_spec_enum ("channel", NULL, NULL,
GIMP_TYPE_HISTOGRAM_CHANNEL,
GIMP_HISTOGRAM_VALUE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_SCALE,
g_param_spec_enum ("scale", NULL, NULL,
GIMP_TYPE_HISTOGRAM_SCALE,
GIMP_HISTOGRAM_SCALE_LOGARITHMIC,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
}
static void
gimp_histogram_view_init (GimpHistogramView *view)
{
view->histogram = NULL;
view->channel = GIMP_HISTOGRAM_VALUE;
view->start = 0;
view->end = 255;
}
@ -129,12 +159,56 @@ gimp_histogram_view_finalize (GObject *object)
}
}
static void
gimp_histogram_view_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpHistogramView *view = GIMP_HISTOGRAM_VIEW (object);
switch (property_id)
{
case PROP_CHANNEL:
gimp_histogram_view_set_channel (view, g_value_get_enum (value));
break;
case PROP_SCALE:
gimp_histogram_view_set_scale (view, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_histogram_view_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpHistogramView *view = GIMP_HISTOGRAM_VIEW (object);
switch (property_id)
{
case PROP_CHANNEL:
g_value_set_enum (value, view->channel);
break;
case PROP_SCALE:
g_value_set_enum (value, view->scale);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gboolean
gimp_histogram_view_expose (GtkWidget *widget,
GdkEventExpose *event)
{
GimpHistogramView *view;
gint x, y;
gint x;
gint width, height;
gdouble max;
@ -149,10 +223,18 @@ gimp_histogram_view_expose (GtkWidget *widget,
/* find the maximum value */
max = gimp_histogram_get_maximum (view->histogram, view->channel);
if (max > 0.0)
max = log (max);
else
max = 1.0;
switch (view->scale)
{
case GIMP_HISTOGRAM_SCALE_LINEAR:
break;
case GIMP_HISTOGRAM_SCALE_LOGARITHMIC:
if (max > 0.0)
max = log (max);
else
max = 1.0;
break;
}
/* Draw the axis */
gdk_draw_line (widget->window, widget->style->black_gc,
@ -161,13 +243,28 @@ gimp_histogram_view_expose (GtkWidget *widget,
/* Draw the spikes */
for (x = 0; x < width; x++)
{
gdouble v = gimp_histogram_get_value (view->histogram, view->channel,
gint y;
gdouble v = gimp_histogram_get_value (view->histogram,
view->channel,
(x * 256) / width);
if (v > 0.0)
y = (gint) ((height * log (v)) / max);
else
y = 0;
if (v <= 0.0)
continue;
switch (view->scale)
{
case GIMP_HISTOGRAM_SCALE_LINEAR:
y = (gint) ((height * v) / max);
break;
case GIMP_HISTOGRAM_SCALE_LOGARITHMIC:
y = (gint) ((height * log (v)) / max);
break;
default:
y = 0;
break;
}
gdk_draw_line (widget->window,
widget->style->black_gc,
@ -180,6 +277,9 @@ gimp_histogram_view_expose (GtkWidget *widget,
gint x1 = (width * MIN (view->start, view->end)) / 256;
gint x2 = (width * MAX (view->start, view->end)) / 255;
if (x2 == x1)
x2++;
if (!view->range_gc)
{
view->range_gc = gdk_gc_new (widget->window);
@ -319,19 +419,43 @@ gimp_histogram_view_set_range (GimpHistogramView *view,
}
void
gimp_histogram_view_set_channel (GimpHistogramView *view,
gint channel)
gimp_histogram_view_set_channel (GimpHistogramView *view,
GimpHistogramChannel channel)
{
g_return_if_fail (GIMP_IS_HISTOGRAM_VIEW (view));
view->channel = channel;
g_object_notify (G_OBJECT (view), "channel");
gtk_widget_queue_draw (GTK_WIDGET (view));
/* FIXME: shouldn't emit range_checked here */
g_signal_emit (view, histogram_view_signals[RANGE_CHANGED], 0,
view->start, view->end);
}
GimpHistogramChannel
gimp_histogram_view_get_channel (GimpHistogramView *view)
{
g_return_val_if_fail (GIMP_IS_HISTOGRAM_VIEW (view), 0);
return view->channel;
}
void
gimp_histogram_view_set_scale (GimpHistogramView *view,
GimpHistogramScale scale)
{
g_return_if_fail (GIMP_IS_HISTOGRAM_VIEW (view));
view->scale = scale;
g_object_notify (G_OBJECT (view), "scale");
gtk_widget_queue_draw (GTK_WIDGET (view));
}
GimpHistogram *
gimp_histogram_view_get_histogram (GimpHistogramView *view)
{

View File

@ -39,14 +39,15 @@ typedef struct _GimpHistogramViewClass GimpHistogramViewClass;
struct _GimpHistogramView
{
GtkDrawingArea parent_instance;
GtkDrawingArea parent_instance;
GdkGC *range_gc;
GimpHistogram *histogram;
GimpHistogramChannel channel;
gint start;
gint end;
GimpHistogram *histogram;
GimpHistogramChannel channel;
GimpHistogramScale scale;
gint start;
gint end;
GdkGC *range_gc;
};
struct _GimpHistogramViewClass
@ -61,17 +62,20 @@ struct _GimpHistogramViewClass
GType gimp_histogram_view_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_histogram_view_new (gint width,
gint height,
gboolean range);
void gimp_histogram_view_set_histogram (GimpHistogramView *view,
GimpHistogram *histogram);
GimpHistogram * gimp_histogram_view_get_histogram (GimpHistogramView *view);
void gimp_histogram_view_set_range (GimpHistogramView *view,
gint start,
gint end);
void gimp_histogram_view_set_channel (GimpHistogramView *view,
gint channel);
GtkWidget * gimp_histogram_view_new (gint width,
gint height,
gboolean range);
void gimp_histogram_view_set_histogram (GimpHistogramView *view,
GimpHistogram *histogram);
GimpHistogram * gimp_histogram_view_get_histogram (GimpHistogramView *view);
void gimp_histogram_view_set_channel (GimpHistogramView *view,
GimpHistogramChannel channel);
GimpHistogramChannel gimp_histogram_view_get_channel (GimpHistogramView *view);
void gimp_histogram_view_set_scale (GimpHistogramView *view,
GimpHistogramScale scale);
void gimp_histogram_view_set_range (GimpHistogramView *view,
gint start,
gint end);
#endif /* __GIMP_HISTOGRAM_VIEW_H__ */

View File

@ -46,5 +46,24 @@ gimp_zoom_type_get_type (void)
}
static const GEnumValue gimp_histogram_scale_enum_values[] =
{
{ GIMP_HISTOGRAM_SCALE_LINEAR, N_("Linear"), "linear" },
{ GIMP_HISTOGRAM_SCALE_LOGARITHMIC, N_("Logarithmic"), "logarithmic" },
{ 0, NULL, NULL }
};
GType
gimp_histogram_scale_get_type (void)
{
static GType enum_type = 0;
if (!enum_type)
enum_type = g_enum_register_static ("GimpHistogramScale", gimp_histogram_scale_enum_values);
return enum_type;
}
/* Generated data ends here */

View File

@ -48,6 +48,17 @@ typedef enum
} GimpZoomType;
#define GIMP_TYPE_HISTOGRAM_SCALE (gimp_histogram_scale_get_type ())
GType gimp_histogram_scale_get_type (void) G_GNUC_CONST;
typedef enum
{
GIMP_HISTOGRAM_SCALE_LINEAR, /*< desc="Linear" >*/
GIMP_HISTOGRAM_SCALE_LOGARITHMIC /*< desc="Logarithmic" >*/
} GimpHistogramScale;
/*
* non-registered enums; register them if needed
*/
@ -142,5 +153,4 @@ typedef enum /*< skip, proxy-skip >*/
GIMP_DEVICE_VALUE_GRADIENT = 1 << 8
} GimpDeviceValues;
#endif /* __WIDGETS_ENUMS_H__ */