add read-only property "frozen" and new API

2007-11-15  Michael Natterer  <mitch@gimp.org>

	* app/core/gimpviewable.[ch]: add read-only property "frozen" and
	new API gimp_viewable_preview_is_fozen(). Emit property notifications.

	* app/widgets/gimphistogramview.[ch]: add API to show a second
	histogram in the background. Remove member "light_histogram" from
	the GimpHistogramViewClass struct.

	* app/widgets/gimpcurveview.c: don't set "light_histogram".

	* app/tools/gimpcurvestool.c: set the background histogram instead.

	* app/widgets/gimphistogrameditor.[ch]: connect to "notify::frozen"
	of the drawable and show its histogram at the freezing point in
	the background. This way the original histogram is visible while
	we are doing color corrections.


svn path=/trunk/; revision=24158
This commit is contained in:
Michael Natterer 2007-11-15 10:26:25 +00:00 committed by Michael Natterer
parent 43b503df95
commit 2ff7c79caf
8 changed files with 257 additions and 69 deletions

View File

@ -1,3 +1,21 @@
2007-11-15 Michael Natterer <mitch@gimp.org>
* app/core/gimpviewable.[ch]: add read-only property "frozen" and
new API gimp_viewable_preview_is_fozen(). Emit property notifications.
* app/widgets/gimphistogramview.[ch]: add API to show a second
histogram in the background. Remove member "light_histogram" from
the GimpHistogramViewClass struct.
* app/widgets/gimpcurveview.c: don't set "light_histogram".
* app/tools/gimpcurvestool.c: set the background histogram instead.
* app/widgets/gimphistogrameditor.[ch]: connect to "notify::frozen"
of the drawable and show its histogram at thje freezing point in
the background. This way the original histogram is visible while
we are doing color corrections.
2007-11-14 Michael Natterer <mitch@gimp.org>
* app/display/gimpcanvas.c

View File

@ -43,7 +43,8 @@
enum
{
PROP_0,
PROP_STOCK_ID
PROP_STOCK_ID,
PROP_FROZEN
};
enum
@ -158,6 +159,12 @@ gimp_viewable_class_init (GimpViewableClass *klass)
GIMP_CONFIG_INSTALL_PROP_STRING (object_class, PROP_STOCK_ID, "stock-id",
NULL, NULL,
GIMP_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_FROZEN,
g_param_spec_boolean ("frozen",
NULL, NULL,
FALSE,
GIMP_PARAM_READABLE));
}
static void
@ -193,12 +200,16 @@ gimp_viewable_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
GimpViewable *viewable = GIMP_VIEWABLE (object);
switch (property_id)
{
case PROP_STOCK_ID:
gimp_viewable_set_stock_id (GIMP_VIEWABLE (object),
g_value_get_string (value));
gimp_viewable_set_stock_id (viewable, g_value_get_string (value));
break;
case PROP_FROZEN:
/* read-only, fall through */
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -211,12 +222,17 @@ gimp_viewable_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
GimpViewable *viewable = GIMP_VIEWABLE (object);
switch (property_id)
{
case PROP_STOCK_ID:
g_value_set_string (value,
gimp_viewable_get_stock_id (GIMP_VIEWABLE (object)));
g_value_set_string (value, gimp_viewable_get_stock_id (viewable));
break;
case PROP_FROZEN:
g_value_set_boolean (value, gimp_viewable_preview_is_frozen (viewable));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -1051,6 +1067,9 @@ gimp_viewable_preview_freeze (GimpViewable *viewable)
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
viewable->freeze_count++;
if (viewable->freeze_count == 1)
g_object_notify (G_OBJECT (viewable), "frozen");
}
void
@ -1062,5 +1081,16 @@ gimp_viewable_preview_thaw (GimpViewable *viewable)
viewable->freeze_count--;
if (viewable->freeze_count == 0)
gimp_viewable_invalidate_preview (viewable);
{
gimp_viewable_invalidate_preview (viewable);
g_object_notify (G_OBJECT (viewable), "frozen");
}
}
gboolean
gimp_viewable_preview_is_frozen (GimpViewable *viewable)
{
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE);
return viewable->freeze_count != 0;
}

View File

@ -172,6 +172,7 @@ void gimp_viewable_set_stock_id (GimpViewable *viewable,
void gimp_viewable_preview_freeze (GimpViewable *viewable);
void gimp_viewable_preview_thaw (GimpViewable *viewable);
gboolean gimp_viewable_preview_is_frozen (GimpViewable *viewable);
#endif /* __GIMP_VIEWABLE_H__ */

View File

@ -77,9 +77,8 @@ G_DEFINE_TYPE (GimpCurveView, gimp_curve_view,
static void
gimp_curve_view_class_init (GimpCurveViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GimpHistogramViewClass *hist_class = GIMP_HISTOGRAM_VIEW_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = gimp_curve_view_finalize;
object_class->dispose = gimp_curve_view_dispose;
@ -94,8 +93,6 @@ gimp_curve_view_class_init (GimpCurveViewClass *klass)
widget_class->leave_notify_event = gimp_curve_view_leave_notify;
widget_class->key_press_event = gimp_curve_view_key_press;
hist_class->light_histogram = TRUE;
g_object_class_install_property (object_class, PROP_GRID_ROWS,
g_param_spec_int ("grid-rows", NULL, NULL,
0, 100, 8,

View File

@ -53,6 +53,8 @@ static void gimp_histogram_editor_set_image (GimpImageEditor *editor
GimpImage *image);
static void gimp_histogram_editor_layer_changed (GimpImage *image,
GimpHistogramEditor *editor);
static void gimp_histogram_editor_frozen_update (GimpHistogramEditor *editor,
const GParamSpec *pspec);
static void gimp_histogram_editor_update (GimpHistogramEditor *editor);
static gboolean gimp_histogram_editor_idle_update (GimpHistogramEditor *editor);
@ -103,11 +105,12 @@ gimp_histogram_editor_init (GimpHistogramEditor *editor)
N_("Percentile:")
};
editor->drawable = NULL;
editor->histogram = NULL;
editor->valid = FALSE;
editor->idle_id = 0;
editor->box = gimp_histogram_box_new ();
editor->drawable = NULL;
editor->histogram = NULL;
editor->bg_histogram = NULL;
editor->valid = FALSE;
editor->idle_id = 0;
editor->box = gimp_histogram_box_new ();
gimp_editor_set_show_name (GIMP_EDITOR (editor), TRUE);
@ -259,9 +262,17 @@ gimp_histogram_editor_set_image (GimpImageEditor *image_editor,
{
gimp_histogram_free (editor->histogram);
editor->histogram = NULL;
gimp_histogram_view_set_histogram (view, NULL);
}
gimp_histogram_view_set_histogram (view, NULL);
if (editor->bg_histogram)
{
gimp_histogram_free (editor->bg_histogram);
editor->bg_histogram = NULL;
gimp_histogram_view_set_background (view, NULL);
}
}
GIMP_IMAGE_EDITOR_CLASS (parent_class)->set_image (image_editor, image);
@ -298,6 +309,16 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
{
if (editor->drawable)
{
if (editor->bg_histogram)
{
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
gimp_histogram_free (editor->bg_histogram);
editor->bg_histogram = NULL;
gimp_histogram_view_set_background (view, NULL);
}
g_signal_handlers_disconnect_by_func (editor->drawable,
gimp_histogram_editor_name_update,
editor);
@ -307,6 +328,9 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
g_signal_handlers_disconnect_by_func (editor->drawable,
gimp_histogram_editor_update,
editor);
g_signal_handlers_disconnect_by_func (editor->drawable,
gimp_histogram_editor_frozen_update,
editor);
editor->drawable = NULL;
}
@ -317,6 +341,9 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
if (editor->drawable)
{
g_signal_connect_object (editor->drawable, "notify::frozen",
G_CALLBACK (gimp_histogram_editor_frozen_update),
editor, G_CONNECT_SWAPPED);
g_signal_connect_object (editor->drawable, "update",
G_CALLBACK (gimp_histogram_editor_update),
editor, G_CONNECT_SWAPPED);
@ -339,6 +366,33 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
gimp_histogram_editor_name_update (editor);
}
static void
gimp_histogram_editor_frozen_update (GimpHistogramEditor *editor,
const GParamSpec *pspec)
{
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
if (gimp_viewable_preview_is_frozen (GIMP_VIEWABLE (editor->drawable)))
{
if (! editor->bg_histogram)
{
editor->bg_histogram = gimp_histogram_new ();
gimp_drawable_calculate_histogram (editor->drawable,
editor->bg_histogram);
gimp_histogram_view_set_background (view, editor->bg_histogram);
}
}
else if (editor->bg_histogram)
{
gimp_histogram_free (editor->bg_histogram);
editor->bg_histogram = NULL;
gimp_histogram_view_set_background (view, NULL);
}
}
static void
gimp_histogram_editor_update (GimpHistogramEditor *editor)
{

View File

@ -39,6 +39,7 @@ struct _GimpHistogramEditor
GimpDrawable *drawable;
GimpHistogram *histogram;
GimpHistogram *bg_histogram;
guint idle_id;
gboolean valid;

View File

@ -73,10 +73,12 @@ static gboolean gimp_histogram_view_motion_notify (GtkWidget *widget,
static void gimp_histogram_view_draw_spike (GimpHistogramView *view,
GimpHistogramChannel channel,
GdkGC *gc,
GdkGC *bg_gc,
gint x,
gint i,
gint j,
gdouble max,
gdouble bg_max,
gint height,
gint border);
@ -150,9 +152,10 @@ gimp_histogram_view_class_init (GimpHistogramViewClass *klass)
static void
gimp_histogram_view_init (GimpHistogramView *view)
{
view->histogram = NULL;
view->start = 0;
view->end = 255;
view->histogram = NULL;
view->bg_histogram = NULL;
view->start = 0;
view->end = 255;
}
static void
@ -227,9 +230,10 @@ gimp_histogram_view_size_request (GtkWidget *widget,
static gdouble
gimp_histogram_view_get_maximum (GimpHistogramView *view,
GimpHistogram *histogram,
GimpHistogramChannel channel)
{
gdouble max = gimp_histogram_get_maximum (view->histogram, channel);
gdouble max = gimp_histogram_get_maximum (histogram, channel);
switch (view->scale)
{
@ -256,13 +260,16 @@ gimp_histogram_view_expose (GtkWidget *widget,
gint x1, x2;
gint border;
gint width, height;
gdouble max;
gdouble max = 0.0;
gdouble bg_max = 0.0;
gint xstop;
GdkGC *gc_in;
GdkGC *gc_out;
GdkGC *bg_gc_in;
GdkGC *bg_gc_out;
GdkGC *rgb_gc[3] = { NULL, NULL, NULL };
if (! view->histogram)
if (! view->histogram && ! view->bg_histogram)
return FALSE;
border = view->border_width;
@ -284,18 +291,19 @@ gimp_histogram_view_expose (GtkWidget *widget,
border, border,
width - 1, height - 1);
max = gimp_histogram_view_get_maximum (view, view->channel);
if (view->histogram)
max = gimp_histogram_view_get_maximum (view, view->histogram,
view->channel);
if (GIMP_HISTOGRAM_VIEW_GET_CLASS (view)->light_histogram)
{
gc_in = widget->style->mid_gc[GTK_STATE_SELECTED];
gc_out = widget->style->mid_gc[GTK_STATE_NORMAL];
}
else
{
gc_in = widget->style->text_gc[GTK_STATE_SELECTED];
gc_out = widget->style->text_gc[GTK_STATE_NORMAL];
}
if (view->bg_histogram)
bg_max = gimp_histogram_view_get_maximum (view, view->bg_histogram,
view->channel);
gc_in = widget->style->text_gc[GTK_STATE_SELECTED];
gc_out = widget->style->text_gc[GTK_STATE_NORMAL];
bg_gc_in = widget->style->mid_gc[GTK_STATE_SELECTED];
bg_gc_out = widget->style->mid_gc[GTK_STATE_NORMAL];
if (view->channel == GIMP_HISTOGRAM_RGB)
{
@ -357,17 +365,27 @@ gimp_histogram_view_expose (GtkWidget *widget,
for (c = 0; c < 3; c++)
gimp_histogram_view_draw_spike (view, GIMP_HISTOGRAM_RED + c,
widget->style->black_gc,
x, i, j, max, height, border);
NULL,
x, i, j, max, bg_max, height, border);
for (c = 0; c < 3; c++)
gimp_histogram_view_draw_spike (view, GIMP_HISTOGRAM_RED + c,
rgb_gc[c],
x, i, j, max, height, border);
}
NULL,
x, i, j, max, bg_max, height, border);
gimp_histogram_view_draw_spike (view, view->channel,
in_selection ? gc_in : gc_out,
x, i, j, max, height, border);
gimp_histogram_view_draw_spike (view, view->channel,
in_selection ? gc_in : gc_out,
NULL,
x, i, j, max, bg_max, height, border);
}
else
{
gimp_histogram_view_draw_spike (view, view->channel,
in_selection ? gc_in : gc_out,
in_selection ? bg_gc_in : bg_gc_out,
x, i, j, max, bg_max, height, border);
}
}
if (view->channel == GIMP_HISTOGRAM_RGB)
@ -383,43 +401,70 @@ static void
gimp_histogram_view_draw_spike (GimpHistogramView *view,
GimpHistogramChannel channel,
GdkGC *gc,
GdkGC *bg_gc,
gint x,
gint i,
gint j,
gdouble max,
gdouble bg_max,
gint height,
gint border)
{
gdouble value = 0.0;
gdouble value = 0.0;
gdouble bg_value = 0.0;
gint y;
gint bg_y;
do
if (view->histogram)
{
gdouble v = gimp_histogram_get_value (view->histogram, channel, i++);
do
{
gdouble v = gimp_histogram_get_value (view->histogram, channel, i++);
if (v > value)
value = v;
if (v > value)
value = v;
}
while (i < j);
}
while (i < j);
if (value <= 0.0)
if (bg_gc && view->bg_histogram)
{
do
{
gdouble v = gimp_histogram_get_value (view->bg_histogram, channel, i++);
if (v > bg_value)
bg_value = v;
}
while (i < j);
}
if (value <= 0.0 && bg_value <= 0.0)
return;
switch (view->scale)
{
case GIMP_HISTOGRAM_SCALE_LINEAR:
y = (gint) (((height - 2) * value) / max);
y = (gint) (((height - 2) * value) / max);
bg_y = (gint) (((height - 2) * bg_value) / bg_max);
break;
case GIMP_HISTOGRAM_SCALE_LOGARITHMIC:
y = (gint) (((height - 2) * log (value)) / max);
y = (gint) (((height - 2) * log (value)) / max);
bg_y = (gint) (((height - 2) * log (bg_value)) / bg_max);
break;
default:
y = 0;
y = 0;
bg_y = 0;
break;
}
if (bg_gc)
gdk_draw_line (GTK_WIDGET (view)->window, bg_gc,
x + border, height + border - 1,
x + border, height + border - bg_y - 1);
gdk_draw_line (GTK_WIDGET (view)->window, gc,
x + border, height + border - 1,
x + border, height + border - y - 1);
@ -513,6 +558,12 @@ gimp_histogram_view_set_histogram (GimpHistogramView *view,
GimpHistogram *histogram)
{
g_return_if_fail (GIMP_IS_HISTOGRAM_VIEW (view));
#if 0
g_return_if_fail (histogram == NULL ||
view->bg_histogram == NULL ||
gimp_histogram_n_channels (view->bg_histogram) ==
gimp_histogram_n_channels (histogram));
#endif
if (view->histogram != histogram)
{
@ -533,6 +584,37 @@ gimp_histogram_view_get_histogram (GimpHistogramView *view)
return view->histogram;
}
void
gimp_histogram_view_set_background (GimpHistogramView *view,
GimpHistogram *histogram)
{
g_return_if_fail (GIMP_IS_HISTOGRAM_VIEW (view));
#if 0
g_return_if_fail (histogram == NULL ||
view->histogram == NULL ||
gimp_histogram_n_channels (view->histogram) ==
gimp_histogram_n_channels (histogram));
#endif
if (view->bg_histogram != histogram)
{
view->bg_histogram = histogram;
if (histogram && view->channel >= gimp_histogram_n_channels (histogram))
gimp_histogram_view_set_channel (view, GIMP_HISTOGRAM_VALUE);
}
gtk_widget_queue_draw (GTK_WIDGET (view));
}
GimpHistogram *
gimp_histogram_view_get_background (GimpHistogramView *view)
{
g_return_val_if_fail (GIMP_IS_HISTOGRAM_VIEW (view), NULL);
return view->bg_histogram;
}
void
gimp_histogram_view_set_channel (GimpHistogramView *view,
GimpHistogramChannel channel)

View File

@ -38,6 +38,7 @@ struct _GimpHistogramView
GtkDrawingArea parent_instance;
GimpHistogram *histogram;
GimpHistogram *bg_histogram;
GimpHistogramChannel channel;
GimpHistogramScale scale;
gint start;
@ -51,36 +52,40 @@ struct _GimpHistogramViewClass
{
GtkDrawingAreaClass parent_class;
gboolean light_histogram;
void (* range_changed) (GimpHistogramView *view,
gint start,
gint end);
};
GType gimp_histogram_view_get_type (void) G_GNUC_CONST;
GType gimp_histogram_view_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_histogram_view_new (gboolean range);
GtkWidget * gimp_histogram_view_new (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_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_background (GimpHistogramView *view,
GimpHistogram *histogram);
GimpHistogram * gimp_histogram_view_get_background (GimpHistogramView *view);
void gimp_histogram_view_set_scale (GimpHistogramView *view,
GimpHistogramScale scale);
GimpHistogramScale gimp_histogram_view_get_scale (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_range (GimpHistogramView *view,
gint start,
gint end);
void gimp_histogram_view_get_range (GimpHistogramView *view,
gint *start,
gint *end);
void gimp_histogram_view_set_scale (GimpHistogramView *view,
GimpHistogramScale scale);
GimpHistogramScale
gimp_histogram_view_get_scale (GimpHistogramView *view);
void gimp_histogram_view_set_range (GimpHistogramView *view,
gint start,
gint end);
void gimp_histogram_view_get_range (GimpHistogramView *view,
gint *start,
gint *end);
#endif /* __GIMP_HISTOGRAM_VIEW_H__ */