1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
#include "libgimpwidgets/gimpwidgets.h"
25
#include "widgets-types.h"
27
#include "base/gimphistogram.h"
28
#include "base/pixel-region.h"
30
#include "config/gimpbaseconfig.h"
32
#include "core/gimp.h"
33
#include "core/gimpdrawable.h"
34
#include "core/gimpdrawable-histogram.h"
35
#include "core/gimpimage.h"
37
#include "gimpdocked.h"
38
#include "gimpenumcombobox.h"
39
#include "gimpenumstore.h"
40
#include "gimphelp-ids.h"
41
#include "gimphistogrambox.h"
42
#include "gimphistogrameditor.h"
43
#include "gimphistogramview.h"
44
#include "gimppropwidgets.h"
45
#include "gimpsessioninfo.h"
46
#include "gimpwidgets-utils.h"
48
#include "gimp-intl.h"
51
static void gimp_histogram_editor_class_init (GimpHistogramEditorClass *klass);
52
static void gimp_histogram_editor_init (GimpHistogramEditor *editor);
53
static void gimp_histogram_editor_docked_iface_init (GimpDockedInterface *docked_iface);
54
static void gimp_histogram_editor_set_aux_info (GimpDocked *docked,
56
static GList * gimp_histogram_editor_get_aux_info (GimpDocked *docked);
58
static void gimp_histogram_editor_set_image (GimpImageEditor *editor,
60
static void gimp_histogram_editor_layer_changed (GimpImage *gimage,
61
GimpHistogramEditor *editor);
62
static void gimp_histogram_editor_update (GimpHistogramEditor *editor);
64
static gboolean gimp_histogram_editor_idle_update (GimpHistogramEditor *editor);
65
static gboolean gimp_histogram_editor_item_visible (GtkTreeModel *model,
68
static void gimp_histogram_editor_menu_update (GimpHistogramEditor *editor);
69
static void gimp_histogram_editor_info_update (GimpHistogramEditor *editor);
72
static GimpImageEditorClass *parent_class = NULL;
73
static GimpDockedInterface *parent_docked_iface = NULL;
77
gimp_histogram_editor_get_type (void)
79
static GType editor_type = 0;
83
static const GTypeInfo editor_info =
85
sizeof (GimpHistogramEditorClass),
87
(GBaseFinalizeFunc) NULL,
88
(GClassInitFunc) gimp_histogram_editor_class_init,
89
NULL, /* class_finalize */
90
NULL, /* class_data */
91
sizeof (GimpHistogramEditor),
93
(GInstanceInitFunc) gimp_histogram_editor_init,
95
static const GInterfaceInfo docked_iface_info =
97
(GInterfaceInitFunc) gimp_histogram_editor_docked_iface_init,
98
NULL, /* iface_finalize */
102
editor_type = g_type_register_static (GIMP_TYPE_IMAGE_EDITOR,
103
"GimpHistogramEditor",
105
g_type_add_interface_static (editor_type, GIMP_TYPE_DOCKED,
113
gimp_histogram_editor_class_init (GimpHistogramEditorClass* klass)
115
GimpImageEditorClass *image_editor_class = GIMP_IMAGE_EDITOR_CLASS (klass);
117
parent_class = g_type_class_peek_parent (klass);
119
image_editor_class->set_image = gimp_histogram_editor_set_image;
123
gimp_histogram_editor_init (GimpHistogramEditor *editor)
125
GimpHistogramView *view;
132
const gchar *gimp_histogram_editor_labels[] =
142
editor->drawable = NULL;
143
editor->histogram = NULL;
145
editor->box = gimp_histogram_box_new ();
147
editor->name = label = gtk_label_new (_("(None)"));
148
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
149
gimp_label_set_attributes (GTK_LABEL (editor->name),
150
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
152
gtk_box_pack_start (GTK_BOX (editor), label, FALSE, FALSE, 0);
153
gtk_widget_show (label);
155
view = GIMP_HISTOGRAM_BOX (editor->box)->view;
157
hbox = gtk_hbox_new (FALSE, 6);
158
gtk_box_pack_start (GTK_BOX (editor), hbox, FALSE, FALSE, 0);
159
gtk_widget_show (hbox);
161
label = gtk_label_new (_("Channel:"));
162
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
163
gtk_widget_show (label);
165
editor->menu = menu = gimp_prop_enum_combo_box_new (G_OBJECT (view),
168
gimp_enum_combo_box_set_stock_prefix (GIMP_ENUM_COMBO_BOX (menu),
170
gimp_enum_combo_box_set_visible (GIMP_ENUM_COMBO_BOX (editor->menu),
171
gimp_histogram_editor_item_visible,
173
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (editor->menu),
175
gtk_box_pack_start (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
176
gtk_widget_show (menu);
178
menu = gimp_prop_enum_stock_box_new (G_OBJECT (view),
179
"histogram-scale", "gimp-histogram",
181
gtk_box_pack_end (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
182
gtk_widget_show (menu);
184
gtk_box_pack_start (GTK_BOX (editor), editor->box, TRUE, TRUE, 0);
185
gtk_widget_show (GTK_WIDGET (editor->box));
187
g_signal_connect_swapped (view, "range_changed",
188
G_CALLBACK (gimp_histogram_editor_info_update),
190
g_signal_connect_swapped (view, "notify::histogram-channel",
191
G_CALLBACK (gimp_histogram_editor_info_update),
194
table = gtk_table_new (3, 4, FALSE);
195
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
196
gtk_box_pack_start (GTK_BOX (editor), table, FALSE, FALSE, 0);
197
gtk_widget_show (table);
199
for (i = 0; i < 6; i++)
201
gint x = (i / 3) * 2;
204
label = gtk_label_new (gettext (gimp_histogram_editor_labels[i]));
205
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
206
gtk_table_attach (GTK_TABLE (table), label, x, x + 1, y, y + 1,
207
GTK_FILL, GTK_FILL, 2, 2);
208
gtk_widget_show (label);
210
editor->labels[i] = label = gtk_label_new (NULL);
211
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
212
gtk_table_attach (GTK_TABLE (table), label, x + 1, x + 2, y, y + 1,
213
GTK_FILL, GTK_FILL, 2, 2);
214
gtk_widget_show (label);
219
gimp_histogram_editor_docked_iface_init (GimpDockedInterface *docked_iface)
221
parent_docked_iface = g_type_interface_peek_parent (docked_iface);
223
docked_iface->set_aux_info = gimp_histogram_editor_set_aux_info;
224
docked_iface->get_aux_info = gimp_histogram_editor_get_aux_info;
228
gimp_histogram_editor_set_aux_info (GimpDocked *docked,
231
GimpHistogramEditor *editor = GIMP_HISTOGRAM_EDITOR (docked);
232
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
234
if (parent_docked_iface->set_aux_info)
235
parent_docked_iface->set_aux_info (docked, aux_info);
237
gimp_session_info_aux_set_props (G_OBJECT (view), aux_info,
244
gimp_histogram_editor_get_aux_info (GimpDocked *docked)
246
GimpHistogramEditor *editor = GIMP_HISTOGRAM_EDITOR (docked);
247
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
250
aux_info = gimp_session_info_aux_new_from_props (G_OBJECT (view),
255
if (parent_docked_iface->get_aux_info)
256
return g_list_concat (parent_docked_iface->get_aux_info (docked),
263
gimp_histogram_editor_set_image (GimpImageEditor *image_editor,
266
GimpHistogramEditor *editor = GIMP_HISTOGRAM_EDITOR (image_editor);
267
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
269
if (image_editor->gimage)
273
g_source_remove (editor->idle_id);
277
g_signal_handlers_disconnect_by_func (image_editor->gimage,
278
gimp_histogram_editor_layer_changed,
280
g_signal_handlers_disconnect_by_func (image_editor->gimage,
281
gimp_histogram_editor_menu_update,
284
if (editor->histogram)
286
gimp_histogram_free (editor->histogram);
287
editor->histogram = NULL;
290
gimp_histogram_view_set_histogram (view, NULL);
293
GIMP_IMAGE_EDITOR_CLASS (parent_class)->set_image (image_editor, gimage);
298
gimp_histogram_new (GIMP_BASE_CONFIG (gimage->gimp->config));
300
gimp_histogram_view_set_histogram (view, editor->histogram);
302
g_signal_connect_object (gimage, "mode_changed",
303
G_CALLBACK (gimp_histogram_editor_menu_update),
304
editor, G_CONNECT_SWAPPED);
305
g_signal_connect_object (gimage, "active_layer_changed",
306
G_CALLBACK (gimp_histogram_editor_layer_changed),
308
g_signal_connect_object (gimage, "mask_changed",
309
G_CALLBACK (gimp_histogram_editor_update),
310
editor, G_CONNECT_SWAPPED);
313
gimp_histogram_editor_layer_changed (gimage, editor);
317
gimp_histogram_editor_new (void)
319
return g_object_new (GIMP_TYPE_HISTOGRAM_EDITOR, NULL);
323
gimp_histogram_editor_layer_changed (GimpImage *gimage,
324
GimpHistogramEditor *editor)
328
if (editor->drawable)
330
g_signal_handlers_disconnect_by_func (editor->drawable,
331
gimp_histogram_editor_menu_update,
333
g_signal_handlers_disconnect_by_func (editor->drawable,
334
gimp_histogram_editor_update,
336
editor->drawable = NULL;
340
editor->drawable = (GimpDrawable *) gimp_image_get_active_layer (gimage);
342
gimp_histogram_editor_menu_update (editor);
344
if (editor->drawable)
346
name = gimp_object_get_name (GIMP_OBJECT (editor->drawable));
348
g_signal_connect_object (editor->drawable, "invalidate_preview",
349
G_CALLBACK (gimp_histogram_editor_update),
350
editor, G_CONNECT_SWAPPED);
351
g_signal_connect_object (editor->drawable, "alpha_changed",
352
G_CALLBACK (gimp_histogram_editor_menu_update),
353
editor, G_CONNECT_SWAPPED);
355
gimp_histogram_editor_update (editor);
361
if (editor->histogram)
363
gimp_histogram_calculate (editor->histogram, NULL, NULL);
364
gtk_widget_queue_draw GTK_WIDGET (editor->box);
365
gimp_histogram_editor_info_update (editor);
369
gtk_label_set_text (GTK_LABEL (editor->name), name);
373
gimp_histogram_editor_update (GimpHistogramEditor *editor)
376
g_source_remove (editor->idle_id);
378
editor->idle_id = g_idle_add_full (G_PRIORITY_LOW,
379
(GSourceFunc) gimp_histogram_editor_idle_update,
381
(GDestroyNotify) NULL);
385
gimp_histogram_editor_idle_update (GimpHistogramEditor *editor)
389
if (editor->drawable && editor->histogram)
391
gimp_drawable_calculate_histogram (editor->drawable, editor->histogram);
392
gtk_widget_queue_draw GTK_WIDGET (editor->box);
393
gimp_histogram_editor_info_update (editor);
400
gimp_histogram_editor_channel_valid (GimpHistogramEditor *editor,
401
GimpHistogramChannel channel)
403
if (editor->drawable)
407
case GIMP_HISTOGRAM_VALUE:
410
case GIMP_HISTOGRAM_RED:
411
case GIMP_HISTOGRAM_GREEN:
412
case GIMP_HISTOGRAM_BLUE:
413
case GIMP_HISTOGRAM_RGB:
414
return gimp_drawable_is_rgb (editor->drawable);
416
case GIMP_HISTOGRAM_ALPHA:
417
return gimp_drawable_has_alpha (editor->drawable);
425
gimp_histogram_editor_item_visible (GtkTreeModel *model,
429
GimpHistogramEditor *editor = GIMP_HISTOGRAM_EDITOR (data);
430
GimpHistogramChannel channel;
432
gtk_tree_model_get (model, iter,
433
GIMP_INT_STORE_VALUE, &channel,
436
return gimp_histogram_editor_channel_valid (editor, channel);
440
gimp_histogram_editor_menu_update (GimpHistogramEditor *editor)
442
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
445
model = gtk_combo_box_get_model (GTK_COMBO_BOX (editor->menu));
446
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
448
if (! gimp_histogram_editor_channel_valid (editor, view->channel))
450
gimp_histogram_view_set_channel (view, GIMP_HISTOGRAM_VALUE);
455
gimp_histogram_editor_info_update (GimpHistogramEditor *editor)
457
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
458
GimpHistogram *hist = editor->histogram;
466
pixels = gimp_histogram_get_count (hist, view->channel, 0, 255);
467
count = gimp_histogram_get_count (hist, view->channel,
468
view->start, view->end);
470
g_snprintf (text, sizeof (text), "%3.1f",
471
gimp_histogram_get_mean (hist, view->channel,
472
view->start, view->end));
473
gtk_label_set_text (GTK_LABEL (editor->labels[0]), text);
475
g_snprintf (text, sizeof (text), "%3.1f",
476
gimp_histogram_get_std_dev (hist, view->channel,
477
view->start, view->end));
478
gtk_label_set_text (GTK_LABEL (editor->labels[1]), text);
480
g_snprintf (text, sizeof (text), "%3.1f",
481
(gdouble) gimp_histogram_get_median (hist, view->channel,
484
gtk_label_set_text (GTK_LABEL (editor->labels[2]), text);
486
g_snprintf (text, sizeof (text), "%8d", (gint) pixels);
487
gtk_label_set_text (GTK_LABEL (editor->labels[3]), text);
489
g_snprintf (text, sizeof (text), "%8d", (gint) count);
490
gtk_label_set_text (GTK_LABEL (editor->labels[4]), text);
492
g_snprintf (text, sizeof (text), "%4.1f", (pixels > 0 ?
493
(100.0 * count / pixels) :
495
gtk_label_set_text (GTK_LABEL (editor->labels[5]), text);
501
for (i = 0; i < 6; i++)
502
gtk_label_set_text (GTK_LABEL (editor->labels[i]), NULL);