1
/* LIBGIMP - The GIMP Library
2
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
5
* Copyright (C) 2002-2007 Michael Natterer <mitch@gimp.org>
6
* Sven Neumann <sven@gimp.org>
8
* This library is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public
14
* License along with this library; if not, write to the
15
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16
* Boston, MA 02111-1307, USA.
25
#include "libgimpcolor/gimpcolor.h"
26
#include "libgimpmath/gimpmath.h"
27
#include "libgimpbase/gimpbase.h"
28
#include "libgimpconfig/gimpconfig.h"
30
#include "gimpwidgets.h"
32
#include "libgimp/libgimp-intl.h"
35
/* utility function prototypes */
37
static void set_param_spec (GObject *object,
39
GParamSpec *param_spec);
40
static void set_radio_spec (GObject *object,
41
GParamSpec *param_spec);
42
static GParamSpec * get_param_spec (GObject *object);
44
static GParamSpec * find_param_spec (GObject *object,
45
const gchar *property_name,
47
static GParamSpec * check_param_spec (GObject *object,
48
const gchar *property_name,
51
static GParamSpec * check_param_spec_w (GObject *object,
52
const gchar *property_name,
56
static gboolean get_numeric_values (GObject *object,
57
GParamSpec *param_spec,
63
static void connect_notify (GObject *config,
64
const gchar *property_name,
66
gpointer callback_data);
73
static void gimp_prop_check_button_callback (GtkWidget *widget,
75
static void gimp_prop_check_button_notify (GObject *config,
76
GParamSpec *param_spec,
80
* gimp_prop_check_button_new:
81
* @config: Object to which property is attached.
82
* @property_name: Name of boolean property controlled by checkbutton.
83
* @label: Label to give checkbutton (including mnemonic).
85
* Creates a #GtkCheckButton that displays and sets the specified
88
* Return value: The newly created #GtkCheckButton widget.
93
gimp_prop_check_button_new (GObject *config,
94
const gchar *property_name,
97
GParamSpec *param_spec;
101
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
102
g_return_val_if_fail (property_name != NULL, NULL);
104
param_spec = check_param_spec_w (config, property_name,
105
G_TYPE_PARAM_BOOLEAN, G_STRFUNC);
109
g_object_get (config,
110
property_name, &value,
113
button = gtk_check_button_new_with_mnemonic (label);
114
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), value);
116
set_param_spec (G_OBJECT (button), button, param_spec);
118
g_signal_connect (button, "toggled",
119
G_CALLBACK (gimp_prop_check_button_callback),
122
connect_notify (config, property_name,
123
G_CALLBACK (gimp_prop_check_button_notify),
130
gimp_prop_check_button_callback (GtkWidget *widget,
133
GParamSpec *param_spec;
135
param_spec = get_param_spec (G_OBJECT (widget));
139
g_object_set (config,
140
param_spec->name, GTK_TOGGLE_BUTTON (widget)->active,
143
gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (widget));
147
gimp_prop_check_button_notify (GObject *config,
148
GParamSpec *param_spec,
153
g_object_get (config,
154
param_spec->name, &value,
157
if (GTK_TOGGLE_BUTTON (button)->active != value)
159
g_signal_handlers_block_by_func (button,
160
gimp_prop_check_button_callback,
163
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), value);
164
gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (button));
166
g_signal_handlers_unblock_by_func (button,
167
gimp_prop_check_button_callback,
173
static void gimp_prop_enum_check_button_callback (GtkWidget *widget,
175
static void gimp_prop_enum_check_button_notify (GObject *config,
176
GParamSpec *param_spec,
180
* gimp_prop_enum_check_button_new:
181
* @config: Object to which property is attached.
182
* @property_name: Name of enum property controlled by checkbutton.
183
* @label: Label to give checkbutton (including mnemonic).
184
* @false_value: Enum value corresponding to unchecked state.
185
* @true_value: Enum value corresonding to checked state.
187
* Creates a #GtkCheckButton that displays and sets the specified
188
* property of type Enum. Note that this widget only allows two values
189
* for the enum, one corresponding to the "checked" state and the
190
* other to the "unchecked" state.
192
* Return value: The newly created #GtkCheckButton widget.
197
gimp_prop_enum_check_button_new (GObject *config,
198
const gchar *property_name,
203
GParamSpec *param_spec;
207
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
208
g_return_val_if_fail (property_name != NULL, NULL);
210
param_spec = check_param_spec_w (config, property_name,
211
G_TYPE_PARAM_ENUM, G_STRFUNC);
215
g_object_get (config,
216
property_name, &value,
219
button = gtk_check_button_new_with_mnemonic (label);
220
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
221
value == true_value);
223
if (value != false_value && value != true_value)
224
gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
226
set_param_spec (G_OBJECT (button), button, param_spec);
228
g_object_set_data (G_OBJECT (button), "false-value",
229
GINT_TO_POINTER (false_value));
230
g_object_set_data (G_OBJECT (button), "true-value",
231
GINT_TO_POINTER (true_value));
233
g_signal_connect (button, "toggled",
234
G_CALLBACK (gimp_prop_enum_check_button_callback),
237
connect_notify (config, property_name,
238
G_CALLBACK (gimp_prop_enum_check_button_notify),
245
gimp_prop_enum_check_button_callback (GtkWidget *widget,
248
GParamSpec *param_spec;
252
param_spec = get_param_spec (G_OBJECT (widget));
256
false_value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
258
true_value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
261
g_object_set (config,
263
GTK_TOGGLE_BUTTON (widget)->active ? true_value : false_value,
266
gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (widget), FALSE);
268
gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (widget));
272
gimp_prop_enum_check_button_notify (GObject *config,
273
GParamSpec *param_spec,
279
gboolean active = FALSE;
280
gboolean inconsistent = FALSE;
282
g_object_get (config,
283
param_spec->name, &value,
286
false_value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
288
true_value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
291
if (value == true_value)
293
else if (value != false_value)
296
gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button),
299
if (GTK_TOGGLE_BUTTON (button)->active != active)
301
g_signal_handlers_block_by_func (button,
302
gimp_prop_enum_check_button_callback,
305
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), active);
306
gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (button));
308
g_signal_handlers_unblock_by_func (button,
309
gimp_prop_enum_check_button_callback,
315
/*************************/
316
/* int/enum combo box */
317
/*************************/
319
static void gimp_prop_int_combo_box_callback (GtkWidget *widget,
321
static void gimp_prop_int_combo_box_notify (GObject *config,
322
GParamSpec *param_spec,
326
* gimp_prop_int_combo_box_new:
327
* @config: Object to which property is attached.
328
* @property_name: Name of int property controlled by combo box.
329
* @store: #GimpIntStore holding list of labels, values, etc.
331
* Creates a #GimpIntComboBox widget to display and set the specified
332
* property. The contents of the widget are determined by @store,
333
* which should be created using gimp_int_store_new().
335
* Return value: The newly created #GimpIntComboBox widget, optionally
336
* wrapped into a #GtkEventBox.
341
gimp_prop_int_combo_box_new (GObject *config,
342
const gchar *property_name,
345
GParamSpec *param_spec;
346
GtkWidget *combo_box;
350
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
351
g_return_val_if_fail (property_name != NULL, NULL);
353
param_spec = check_param_spec_w (config, property_name,
354
G_TYPE_PARAM_INT, G_STRFUNC);
358
g_object_get (config,
359
property_name, &value,
362
combo_box = g_object_new (GIMP_TYPE_INT_COMBO_BOX,
366
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo_box), value);
368
g_signal_connect (combo_box, "changed",
369
G_CALLBACK (gimp_prop_int_combo_box_callback),
372
/* can't set a tooltip on a combo_box */
373
if (g_param_spec_get_blurb (param_spec))
375
widget = gtk_event_box_new ();
376
gtk_container_add (GTK_CONTAINER (widget), combo_box);
377
gtk_widget_show (combo_box);
384
set_param_spec (G_OBJECT (combo_box), widget, param_spec);
386
connect_notify (config, property_name,
387
G_CALLBACK (gimp_prop_int_combo_box_notify),
394
* gimp_prop_enum_combo_box_new:
395
* @config: Object to which property is attached.
396
* @property_name: Name of enum property controlled by combo box.
397
* @minimum: Smallest allowed value of enum.
398
* @maximum: Largest allowed value of enum.
400
* Creates a #GimpIntComboBox widget to display and set the specified
401
* enum property. The @mimimum_value and @maximum_value give the
402
* possibility of restricting the allowed range to a subset of the
403
* enum. If the two values are equal (e.g., 0, 0), then the full
404
* range of the Enum is used.
406
* Return value: The newly created #GimpEnumComboBox widget, optionally
407
* wrapped into a #GtkEventBox.
412
gimp_prop_enum_combo_box_new (GObject *config,
413
const gchar *property_name,
417
GParamSpec *param_spec;
418
GtkWidget *combo_box;
422
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
423
g_return_val_if_fail (property_name != NULL, NULL);
425
param_spec = check_param_spec_w (config, property_name,
426
G_TYPE_PARAM_ENUM, G_STRFUNC);
430
g_object_get (config,
431
property_name, &value,
434
if (minimum != maximum)
438
store = gimp_enum_store_new_with_range (param_spec->value_type,
441
combo_box = g_object_new (GIMP_TYPE_ENUM_COMBO_BOX,
445
g_object_unref (store);
449
combo_box = gimp_enum_combo_box_new (param_spec->value_type);
452
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo_box), value);
454
g_signal_connect (combo_box, "changed",
455
G_CALLBACK (gimp_prop_int_combo_box_callback),
458
/* can't set a tooltip on a combo_box */
459
if (g_param_spec_get_blurb (param_spec))
461
widget = gtk_event_box_new ();
462
gtk_container_add (GTK_CONTAINER (widget), combo_box);
463
gtk_widget_show (combo_box);
470
set_param_spec (G_OBJECT (combo_box), widget, param_spec);
472
connect_notify (config, property_name,
473
G_CALLBACK (gimp_prop_int_combo_box_notify),
480
gimp_prop_int_combo_box_callback (GtkWidget *widget,
483
GParamSpec *param_spec;
486
param_spec = get_param_spec (G_OBJECT (widget));
490
if (gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &value))
492
g_object_set (config,
493
param_spec->name, value,
499
gimp_prop_int_combo_box_notify (GObject *config,
500
GParamSpec *param_spec,
501
GtkWidget *combo_box)
505
g_object_get (config,
506
param_spec->name, &value,
509
g_signal_handlers_block_by_func (combo_box,
510
gimp_prop_int_combo_box_callback,
513
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo_box), value);
515
g_signal_handlers_unblock_by_func (combo_box,
516
gimp_prop_int_combo_box_callback,
521
/************************/
522
/* boolean combo box */
523
/************************/
525
static void gimp_prop_boolean_combo_box_callback (GtkWidget *widget,
527
static void gimp_prop_boolean_combo_box_notify (GObject *config,
528
GParamSpec *param_spec,
533
* gimp_prop_boolean_combo_box_new:
534
* @config: Object to which property is attached.
535
* @property_name: Name of boolean property controlled by combo box.
536
* @true_text: Label used for entry corresponding to %TRUE value.
537
* @false_text: Label used for entry corresponding to %FALSE value.
539
* Creates a #GtkComboBox widget to display and set the specified
540
* boolean property. The combo box will have two entries, one
541
* displaying the @true_text label, the other displaying the
544
* Return value: The newly created #GtkComboBox widget, optionally
545
* wrapped into a #GtkEventBox..
550
gimp_prop_boolean_combo_box_new (GObject *config,
551
const gchar *property_name,
552
const gchar *true_text,
553
const gchar *false_text)
555
GParamSpec *param_spec;
556
GtkWidget *combo_box;
560
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
561
g_return_val_if_fail (property_name != NULL, NULL);
563
param_spec = check_param_spec_w (config, property_name,
564
G_TYPE_PARAM_BOOLEAN, G_STRFUNC);
568
g_object_get (config,
569
property_name, &value,
572
combo_box = gtk_combo_box_new_text ();
574
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), true_text);
575
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), false_text);
577
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), value ? 0 : 1);
579
g_signal_connect (combo_box, "changed",
580
G_CALLBACK (gimp_prop_boolean_combo_box_callback),
583
/* can't set a tooltip on a combo_box */
584
if (g_param_spec_get_blurb (param_spec))
586
widget = gtk_event_box_new ();
587
gtk_container_add (GTK_CONTAINER (widget), combo_box);
588
gtk_widget_show (combo_box);
595
set_param_spec (G_OBJECT (combo_box), widget, param_spec);
597
connect_notify (config, property_name,
598
G_CALLBACK (gimp_prop_boolean_combo_box_notify),
605
gimp_prop_boolean_combo_box_callback (GtkWidget *widget,
608
GParamSpec *param_spec;
611
param_spec = get_param_spec (G_OBJECT (widget));
615
value = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
617
g_object_set (config,
618
param_spec->name, value ? FALSE : TRUE,
623
gimp_prop_boolean_combo_box_notify (GObject *config,
624
GParamSpec *param_spec,
625
GtkWidget *combo_box)
629
g_object_get (config,
630
param_spec->name, &value,
633
g_signal_handlers_block_by_func (combo_box,
634
gimp_prop_boolean_combo_box_callback,
637
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), value ? 0 : 1);
639
g_signal_handlers_unblock_by_func (combo_box,
640
gimp_prop_boolean_combo_box_callback,
649
static void gimp_prop_radio_button_callback (GtkWidget *widget,
651
static void gimp_prop_radio_button_notify (GObject *config,
652
GParamSpec *param_spec,
657
* gimp_prop_enum_radio_frame_new:
658
* @config: Object to which property is attached.
659
* @property_name: Name of enum property controlled by the radio buttons.
660
* @title: Label for the frame holding the buttons
661
* @minimum: Smallest value of enum to be included.
662
* @maximum: Largest value of enum to be included.
664
* Creates a group of radio buttons which function to set and display
665
* the specified enum property. The @minimum and @maximum arguments
666
* allow only a subset of the enum to be used. If the two arguments
667
* are equal (e.g., 0, 0), then the full range of the enum will be used.
669
* Return value: A #GimpFrame containing the radio buttons.
674
gimp_prop_enum_radio_frame_new (GObject *config,
675
const gchar *property_name,
680
GParamSpec *param_spec;
685
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
686
g_return_val_if_fail (property_name != NULL, NULL);
688
param_spec = check_param_spec_w (config, property_name,
689
G_TYPE_PARAM_ENUM, G_STRFUNC);
693
g_object_get (config,
694
property_name, &value,
697
if (minimum != maximum)
699
frame = gimp_enum_radio_frame_new_with_range (param_spec->value_type,
701
gtk_label_new (title),
702
G_CALLBACK (gimp_prop_radio_button_callback),
708
frame = gimp_enum_radio_frame_new (param_spec->value_type,
709
gtk_label_new (title),
710
G_CALLBACK (gimp_prop_radio_button_callback),
715
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
717
set_radio_spec (G_OBJECT (button), param_spec);
719
connect_notify (config, property_name,
720
G_CALLBACK (gimp_prop_radio_button_notify),
723
g_object_set_data (G_OBJECT (frame), "radio-button", button);
729
* gimp_prop_enum_radio_box_new:
730
* @config: Object to which property is attached.
731
* @property_name: Name of enum property controlled by the radio buttons.
732
* @minimum: Smallest value of enum to be included.
733
* @maximum: Largest value of enum to be included.
735
* Creates a group of radio buttons which function to set and display
736
* the specified enum property. The @minimum and @maximum arguments
737
* allow only a subset of the enum to be used. If the two arguments
738
* are equal (e.g., 0, 0), then the full range of the enum will be used.
739
* If you want to assign a label to the group of radio buttons, use
740
* gimp_prop_enum_radio_frame_new() instead of this function.
742
* Return value: A #GtkVBox containing the radio buttons.
747
gimp_prop_enum_radio_box_new (GObject *config,
748
const gchar *property_name,
752
GParamSpec *param_spec;
757
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
758
g_return_val_if_fail (property_name != NULL, NULL);
760
param_spec = check_param_spec_w (config, property_name,
761
G_TYPE_PARAM_ENUM, G_STRFUNC);
765
g_object_get (config,
766
property_name, &value,
769
if (minimum != maximum)
771
vbox = gimp_enum_radio_box_new_with_range (param_spec->value_type,
773
G_CALLBACK (gimp_prop_radio_button_callback),
779
vbox = gimp_enum_radio_box_new (param_spec->value_type,
780
G_CALLBACK (gimp_prop_radio_button_callback),
785
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
787
set_radio_spec (G_OBJECT (button), param_spec);
789
connect_notify (config, property_name,
790
G_CALLBACK (gimp_prop_radio_button_notify),
793
g_object_set_data (G_OBJECT (vbox), "radio-button", button);
803
static void gimp_prop_enum_label_notify (GObject *config,
804
GParamSpec *param_spec,
808
* gimp_prop_enum_label_new:
809
* @config: Object to which property is attached.
810
* @property_name: Name of enum property to be displayed.
812
* Return value: The newly created #GimpEnumLabel widget.
817
gimp_prop_enum_label_new (GObject *config,
818
const gchar *property_name)
820
GParamSpec *param_spec;
824
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
825
g_return_val_if_fail (property_name != NULL, NULL);
827
param_spec = check_param_spec (config, property_name,
828
G_TYPE_PARAM_ENUM, G_STRFUNC);
832
g_object_get (config,
833
property_name, &value,
836
label = gimp_enum_label_new (param_spec->value_type, value);
838
set_param_spec (G_OBJECT (label), NULL, param_spec);
840
connect_notify (config, property_name,
841
G_CALLBACK (gimp_prop_enum_label_notify),
848
gimp_prop_enum_label_notify (GObject *config,
849
GParamSpec *param_spec,
854
g_object_get (config,
855
param_spec->name, &value,
858
gimp_enum_label_set_value (GIMP_ENUM_LABEL (label), value);
863
* gimp_prop_boolean_radio_frame_new:
864
* @config: Object to which property is attached.
865
* @property_name: Name of boolean property controlled by the radio buttons.
866
* @title: Label for the frame.
867
* @true_text: Label for the button corresponding to %TRUE.
868
* @false_text: Label for the button corresponding to %FALSE.
870
* Creates a pair of radio buttons which function to set and display
871
* the specified boolean property.
873
* Return value: A #GimpFrame containing the radio buttons.
878
gimp_prop_boolean_radio_frame_new (GObject *config,
879
const gchar *property_name,
881
const gchar *true_text,
882
const gchar *false_text)
884
GParamSpec *param_spec;
889
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
890
g_return_val_if_fail (property_name != NULL, NULL);
892
param_spec = check_param_spec_w (config, property_name,
893
G_TYPE_PARAM_BOOLEAN, G_STRFUNC);
897
g_object_get (config,
898
property_name, &value,
902
gimp_int_radio_group_new (TRUE, title,
903
G_CALLBACK (gimp_prop_radio_button_callback),
906
false_text, FALSE, &button,
907
true_text, TRUE, NULL,
911
set_radio_spec (G_OBJECT (button), param_spec);
913
connect_notify (config, property_name,
914
G_CALLBACK (gimp_prop_radio_button_notify),
917
g_object_set_data (G_OBJECT (frame), "radio-button", button);
923
* gimp_prop_enum_stock_box_new:
924
* @config: Object to which property is attached.
925
* @property_name: Name of enum property controlled by the radio buttons.
926
* @stock_prefix: The prefix of the group of stock ids to use.
927
* @minimum: Smallest value of enum to be included.
928
* @maximum: Largest value of enum to be included.
930
* Creates a horizontal box of radio buttons with stock icons, which
931
* function to set and display the value of the specified Enum
932
* property. The stock_id for each icon is created by appending the
933
* enum_value's nick to the given @stock_prefix. See
934
* gimp_enum_stock_box_new() for more information.
936
* Return value: A #GimpEnumStockBox containing the radio buttons.
941
gimp_prop_enum_stock_box_new (GObject *config,
942
const gchar *property_name,
943
const gchar *stock_prefix,
947
GParamSpec *param_spec;
952
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
953
g_return_val_if_fail (property_name != NULL, NULL);
955
param_spec = check_param_spec_w (config, property_name,
956
G_TYPE_PARAM_ENUM, G_STRFUNC);
960
g_object_get (config,
961
property_name, &value,
964
if (minimum != maximum)
966
box = gimp_enum_stock_box_new_with_range (param_spec->value_type,
970
G_CALLBACK (gimp_prop_radio_button_callback),
976
box = gimp_enum_stock_box_new (param_spec->value_type,
979
G_CALLBACK (gimp_prop_radio_button_callback),
984
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
986
set_radio_spec (G_OBJECT (button), param_spec);
988
connect_notify (config, property_name,
989
G_CALLBACK (gimp_prop_radio_button_notify),
996
gimp_prop_radio_button_callback (GtkWidget *widget,
999
if (GTK_TOGGLE_BUTTON (widget)->active)
1001
GParamSpec *param_spec;
1004
param_spec = get_param_spec (G_OBJECT (widget));
1008
value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
1011
g_object_set (config,
1012
param_spec->name, value,
1018
gimp_prop_radio_button_notify (GObject *config,
1019
GParamSpec *param_spec,
1024
g_object_get (config,
1025
param_spec->name, &value,
1028
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (button), value);
1036
static void gimp_prop_adjustment_callback (GtkAdjustment *adjustment,
1038
static void gimp_prop_adjustment_notify (GObject *config,
1039
GParamSpec *param_spec,
1040
GtkAdjustment *adjustment);
1043
* gimp_prop_spin_button_new:
1044
* @config: Object to which property is attached.
1045
* @property_name: Name of double property controlled by the spin button.
1046
* @step_increment: Step size.
1047
* @page_increment: Page size.
1048
* @digits: Number of digits after decimal point to display.
1050
* Creates a spin button to set and display the value of the
1051
* specified double property.
1053
* Return value: A new #GimpSpinButton.
1058
gimp_prop_spin_button_new (GObject *config,
1059
const gchar *property_name,
1060
gdouble step_increment,
1061
gdouble page_increment,
1064
GParamSpec *param_spec;
1065
GtkWidget *spinbutton;
1066
GtkObject *adjustment;
1071
param_spec = find_param_spec (config, property_name, G_STRFUNC);
1075
if (! get_numeric_values (config,
1076
param_spec, &value, &lower, &upper, G_STRFUNC))
1079
if (! G_IS_PARAM_SPEC_DOUBLE (param_spec))
1082
spinbutton = gimp_spin_button_new (&adjustment,
1083
value, lower, upper,
1084
step_increment, page_increment,
1087
set_param_spec (G_OBJECT (adjustment), spinbutton, param_spec);
1089
g_signal_connect (adjustment, "value-changed",
1090
G_CALLBACK (gimp_prop_adjustment_callback),
1093
connect_notify (config, property_name,
1094
G_CALLBACK (gimp_prop_adjustment_notify),
1101
* gimp_prop_hscale_new:
1102
* @config: Object to which property is attached.
1103
* @property_name: Name of integer or double property controlled by the scale.
1104
* @step_increment: Step size.
1105
* @page_increment: Page size.
1106
* @digits: Number of digits after decimal point to display.
1108
* Creates a horizontal scale to control the value of the specified
1109
* integer or double property.
1111
* Return value: A new #GtkScale.
1116
gimp_prop_hscale_new (GObject *config,
1117
const gchar *property_name,
1118
gdouble step_increment,
1119
gdouble page_increment,
1122
GParamSpec *param_spec;
1124
GtkObject *adjustment;
1129
param_spec = find_param_spec (config, property_name, G_STRFUNC);
1133
if (! get_numeric_values (config,
1134
param_spec, &value, &lower, &upper, G_STRFUNC))
1137
if (! G_IS_PARAM_SPEC_DOUBLE (param_spec))
1140
adjustment = gtk_adjustment_new (value, lower, upper,
1141
step_increment, page_increment, 0.0);
1143
scale = g_object_new (GTK_TYPE_HSCALE,
1144
"adjustment", adjustment,
1148
set_param_spec (G_OBJECT (adjustment), scale, param_spec);
1150
g_signal_connect (adjustment, "value-changed",
1151
G_CALLBACK (gimp_prop_adjustment_callback),
1154
connect_notify (config, property_name,
1155
G_CALLBACK (gimp_prop_adjustment_notify),
1162
* gimp_prop_scale_entry_new:
1163
* @config: Object to which property is attached.
1164
* @property_name: Name of double property controlled by the spin button.
1165
* @table: The #GtkTable the widgets will be attached to.
1166
* @column: The column to start with.
1167
* @row: The row to attach the widgets.
1168
* @label: The text for the #GtkLabel which will appear left of
1170
* @step_increment: Step size.
1171
* @page_increment: Page size.
1172
* @digits: Number of digits after decimal point to display.
1173
* @limit_scale: %TRUE if the range of possible values of the
1174
* GtkSpinButton should be the same as of the GtkHScale.
1175
* @lower_limit: The spinbutton's lower boundary if @limit_scale is %FALSE.
1176
* @upper_limit: The spinbutton's upper boundary if @limit_scale is %FALSE.
1178
* Creates a #GimpScaleEntry (slider and spin button) to set and
1179
* display the value of the specified double property. See
1180
* gimp_scale_entry_new() for more information.
1182
* Return value: The #GtkSpinButton's #GtkAdjustment.
1187
gimp_prop_scale_entry_new (GObject *config,
1188
const gchar *property_name,
1193
gdouble step_increment,
1194
gdouble page_increment,
1196
gboolean limit_scale,
1197
gdouble lower_limit,
1198
gdouble upper_limit)
1200
GParamSpec *param_spec;
1201
GtkObject *adjustment;
1202
const gchar *tooltip;
1207
param_spec = find_param_spec (config, property_name, G_STRFUNC);
1211
if (! get_numeric_values (config,
1212
param_spec, &value, &lower, &upper, G_STRFUNC))
1215
tooltip = dgettext (gimp_type_get_translation_domain (G_OBJECT_TYPE (config)),
1216
g_param_spec_get_blurb (param_spec));
1220
adjustment = gimp_scale_entry_new (table, column, row,
1222
value, lower, upper,
1223
step_increment, page_increment,
1231
adjustment = gimp_scale_entry_new (table, column, row,
1233
value, lower_limit, upper_limit,
1234
step_increment, page_increment,
1236
FALSE, lower, upper,
1241
set_param_spec (G_OBJECT (adjustment), NULL, param_spec);
1243
g_signal_connect (adjustment, "value-changed",
1244
G_CALLBACK (gimp_prop_adjustment_callback),
1247
connect_notify (config, property_name,
1248
G_CALLBACK (gimp_prop_adjustment_notify),
1255
* gimp_prop_opacity_entry_new:
1256
* @config: Object to which property is attached.
1257
* @property_name: Name of double property controlled by the spin button.
1258
* @table: The #GtkTable the widgets will be attached to.
1259
* @column: The column to start with.
1260
* @row: The row to attach the widgets.
1261
* @label: The text for the #GtkLabel which will appear left of the
1264
* Creates a #GimpScaleEntry (slider and spin button) to set and
1265
* display the value of the specified double property, which should
1266
* represent an "opacity" variable with range 0 to 100. See
1267
* gimp_scale_entry_new() for more information.
1269
* Return value: The #GtkSpinButton's #GtkAdjustment.
1274
gimp_prop_opacity_entry_new (GObject *config,
1275
const gchar *property_name,
1281
GParamSpec *param_spec;
1282
GtkObject *adjustment;
1283
const gchar *tooltip;
1288
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
1289
g_return_val_if_fail (property_name != NULL, NULL);
1291
param_spec = check_param_spec_w (config, property_name,
1292
G_TYPE_PARAM_DOUBLE, G_STRFUNC);
1296
g_object_get (config, property_name, &value, NULL);
1298
tooltip = dgettext (gimp_type_get_translation_domain (G_OBJECT_TYPE (config)),
1299
g_param_spec_get_blurb (param_spec));
1302
lower = G_PARAM_SPEC_DOUBLE (param_spec)->minimum * 100.0;
1303
upper = G_PARAM_SPEC_DOUBLE (param_spec)->maximum * 100.0;
1305
adjustment = gimp_scale_entry_new (table, column, row,
1307
value, lower, upper,
1313
set_param_spec (G_OBJECT (adjustment), NULL, param_spec);
1314
g_object_set_data (G_OBJECT (adjustment),
1315
"opacity-scale", GINT_TO_POINTER (TRUE));
1317
g_signal_connect (adjustment, "value-changed",
1318
G_CALLBACK (gimp_prop_adjustment_callback),
1321
connect_notify (config, property_name,
1322
G_CALLBACK (gimp_prop_adjustment_notify),
1330
gimp_prop_adjustment_callback (GtkAdjustment *adjustment,
1333
GParamSpec *param_spec;
1335
param_spec = get_param_spec (G_OBJECT (adjustment));
1339
if (G_IS_PARAM_SPEC_INT (param_spec))
1341
g_object_set (config,
1342
param_spec->name, (gint) adjustment->value,
1345
else if (G_IS_PARAM_SPEC_UINT (param_spec))
1347
g_object_set (config,
1348
param_spec->name, (guint) adjustment->value,
1351
else if (G_IS_PARAM_SPEC_LONG (param_spec))
1353
g_object_set (config,
1354
param_spec->name, (glong) adjustment->value,
1357
else if (G_IS_PARAM_SPEC_ULONG (param_spec))
1359
g_object_set (config,
1360
param_spec->name, (gulong) adjustment->value,
1363
else if (G_IS_PARAM_SPEC_INT64 (param_spec))
1365
g_object_set (config,
1366
param_spec->name, (gint64) adjustment->value,
1369
else if (G_IS_PARAM_SPEC_UINT64 (param_spec))
1371
g_object_set (config,
1372
param_spec->name, (guint64) adjustment->value,
1375
else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
1379
if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (adjustment),
1381
value = adjustment->value / 100.0;
1383
value = adjustment->value;
1385
g_object_set (config, param_spec->name, value, NULL);
1390
gimp_prop_adjustment_notify (GObject *config,
1391
GParamSpec *param_spec,
1392
GtkAdjustment *adjustment)
1396
if (G_IS_PARAM_SPEC_INT (param_spec))
1400
g_object_get (config, param_spec->name, &int_value, NULL);
1404
else if (G_IS_PARAM_SPEC_UINT (param_spec))
1408
g_object_get (config, param_spec->name, &uint_value, NULL);
1412
else if (G_IS_PARAM_SPEC_LONG (param_spec))
1416
g_object_get (config, param_spec->name, &long_value, NULL);
1420
else if (G_IS_PARAM_SPEC_ULONG (param_spec))
1424
g_object_get (config, param_spec->name, &ulong_value, NULL);
1426
value = ulong_value;
1428
else if (G_IS_PARAM_SPEC_INT64 (param_spec))
1432
g_object_get (config, param_spec->name, &int64_value, NULL);
1434
value = int64_value;
1436
else if (G_IS_PARAM_SPEC_UINT64 (param_spec))
1438
guint64 uint64_value;
1440
g_object_get (config, param_spec->name, &uint64_value, NULL);
1442
#if defined _MSC_VER && (_MSC_VER < 1300)
1443
value = (gint64) uint64_value;
1445
value = uint64_value;
1448
else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
1450
g_object_get (config, param_spec->name, &value, NULL);
1452
if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (adjustment),
1458
g_warning ("%s: unhandled param spec of type %s",
1459
G_STRFUNC, G_PARAM_SPEC_TYPE_NAME (param_spec));
1463
if (adjustment->value != value)
1465
g_signal_handlers_block_by_func (adjustment,
1466
gimp_prop_adjustment_callback,
1469
gtk_adjustment_set_value (adjustment, value);
1471
g_signal_handlers_unblock_by_func (adjustment,
1472
gimp_prop_adjustment_callback,
1482
static void gimp_prop_memsize_callback (GimpMemsizeEntry *entry,
1484
static void gimp_prop_memsize_notify (GObject *config,
1485
GParamSpec *param_spec,
1486
GimpMemsizeEntry *entry);
1489
* gimp_prop_memsize_entry_new:
1490
* @config: Object to which property is attached.
1491
* @property_name: Name of memsize property.
1493
* Creates a #GimpMemsizeEntry (spin button and option menu) to set
1494
* and display the value of the specified memsize property. See
1495
* gimp_memsize_entry_new() for more information.
1497
* Return value: A new #GimpMemsizeEntry.
1502
gimp_prop_memsize_entry_new (GObject *config,
1503
const gchar *property_name)
1505
GParamSpec *param_spec;
1506
GParamSpecUInt64 *uint64_spec;
1510
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
1511
g_return_val_if_fail (property_name != NULL, NULL);
1513
param_spec = check_param_spec_w (config, property_name,
1514
GIMP_TYPE_PARAM_MEMSIZE, G_STRFUNC);
1518
g_object_get (config,
1519
property_name, &value,
1522
uint64_spec = G_PARAM_SPEC_UINT64 (param_spec);
1524
g_return_val_if_fail (uint64_spec->minimum <= GIMP_MAX_MEMSIZE, NULL);
1525
g_return_val_if_fail (uint64_spec->maximum <= GIMP_MAX_MEMSIZE, NULL);
1527
entry = gimp_memsize_entry_new (value,
1528
uint64_spec->minimum,
1529
uint64_spec->maximum);
1531
set_param_spec (G_OBJECT (entry),
1532
GIMP_MEMSIZE_ENTRY (entry)->spinbutton,
1535
g_signal_connect (entry, "value-changed",
1536
G_CALLBACK (gimp_prop_memsize_callback),
1539
connect_notify (config, property_name,
1540
G_CALLBACK (gimp_prop_memsize_notify),
1548
gimp_prop_memsize_callback (GimpMemsizeEntry *entry,
1551
GParamSpec *param_spec;
1553
param_spec = get_param_spec (G_OBJECT (entry));
1557
g_return_if_fail (G_IS_PARAM_SPEC_UINT64 (param_spec));
1559
g_object_set (config,
1560
param_spec->name, gimp_memsize_entry_get_value (entry),
1565
gimp_prop_memsize_notify (GObject *config,
1566
GParamSpec *param_spec,
1567
GimpMemsizeEntry *entry)
1571
g_return_if_fail (G_IS_PARAM_SPEC_UINT64 (param_spec));
1573
g_object_get (config,
1574
param_spec->name, &value,
1577
if (entry->value != value)
1579
g_signal_handlers_block_by_func (entry,
1580
gimp_prop_memsize_callback,
1583
gimp_memsize_entry_set_value (entry, value);
1585
g_signal_handlers_unblock_by_func (entry,
1586
gimp_prop_memsize_callback,
1596
static void gimp_prop_label_notify (GObject *config,
1597
GParamSpec *param_spec,
1601
* gimp_prop_label_new:
1602
* @config: Object to which property is attached.
1603
* @property_name: Name of string property.
1605
* Creates a #GtkLabel to display the value of the specified property.
1606
* The property should be a string property or at least transformable
1607
* to a string. If the user should be able to edit the string, use
1608
* gimp_prop_entry_new() instead.
1610
* Return value: A new #GtkLabel widget.
1615
gimp_prop_label_new (GObject *config,
1616
const gchar *property_name)
1618
GParamSpec *param_spec;
1621
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
1622
g_return_val_if_fail (property_name != NULL, NULL);
1624
param_spec = find_param_spec (config, property_name, G_STRFUNC);
1629
if (! g_value_type_transformable (param_spec->value_type, G_TYPE_STRING))
1631
g_warning ("%s: property '%s' of %s is not transformable to string",
1634
g_type_name (param_spec->owner_type));
1638
label = gtk_label_new (NULL);
1640
set_param_spec (G_OBJECT (label), label, param_spec);
1642
connect_notify (config, property_name,
1643
G_CALLBACK (gimp_prop_label_notify),
1646
gimp_prop_label_notify (config, param_spec, label);
1652
gimp_prop_label_notify (GObject *config,
1653
GParamSpec *param_spec,
1656
GValue value = { 0, };
1658
g_value_init (&value, param_spec->value_type);
1660
g_object_get_property (config, param_spec->name, &value);
1662
if (G_VALUE_HOLDS_STRING (&value))
1664
const gchar *str = g_value_get_string (&value);
1666
gtk_label_set_text (GTK_LABEL (label), str ? str : "");
1670
GValue str_value = { 0, };
1673
g_value_init (&str_value, G_TYPE_STRING);
1674
g_value_transform (&value, &str_value);
1676
str = g_value_get_string (&str_value);
1678
gtk_label_set_text (GTK_LABEL (label), str ? str : "");
1680
g_value_unset (&str_value);
1683
g_value_unset (&value);
1691
static void gimp_prop_entry_callback (GtkWidget *entry,
1693
static void gimp_prop_entry_notify (GObject *config,
1694
GParamSpec *param_spec,
1698
* gimp_prop_entry_new:
1699
* @config: Object to which property is attached.
1700
* @property_name: Name of string property.
1701
* @max_len: Maximum allowed length of string.
1703
* Creates a #GtkEntry to set and display the value of the specified
1706
* Return value: A new #GtkEntry widget.
1711
gimp_prop_entry_new (GObject *config,
1712
const gchar *property_name,
1715
GParamSpec *param_spec;
1719
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
1720
g_return_val_if_fail (property_name != NULL, NULL);
1722
param_spec = check_param_spec (config, property_name,
1723
G_TYPE_PARAM_STRING, G_STRFUNC);
1727
g_object_get (config,
1728
property_name, &value,
1731
entry = gtk_entry_new ();
1732
gtk_entry_set_text (GTK_ENTRY (entry), value ? value : "");
1737
gtk_entry_set_max_length (GTK_ENTRY (entry), max_len);
1739
gtk_editable_set_editable (GTK_EDITABLE (entry),
1740
param_spec->flags & G_PARAM_WRITABLE);
1742
set_param_spec (G_OBJECT (entry), entry, param_spec);
1744
g_signal_connect (entry, "changed",
1745
G_CALLBACK (gimp_prop_entry_callback),
1748
connect_notify (config, property_name,
1749
G_CALLBACK (gimp_prop_entry_notify),
1756
gimp_prop_entry_callback (GtkWidget *entry,
1759
GParamSpec *param_spec;
1762
param_spec = get_param_spec (G_OBJECT (entry));
1766
text = gtk_entry_get_text (GTK_ENTRY (entry));
1768
g_signal_handlers_block_by_func (config,
1769
gimp_prop_entry_notify,
1772
g_object_set (config,
1773
param_spec->name, text,
1776
g_signal_handlers_unblock_by_func (config,
1777
gimp_prop_entry_notify,
1782
gimp_prop_entry_notify (GObject *config,
1783
GParamSpec *param_spec,
1788
g_object_get (config,
1789
param_spec->name, &value,
1792
g_signal_handlers_block_by_func (entry,
1793
gimp_prop_entry_callback,
1796
gtk_entry_set_text (GTK_ENTRY (entry), value ? value : "");
1798
g_signal_handlers_unblock_by_func (entry,
1799
gimp_prop_entry_callback,
1810
static void gimp_prop_text_buffer_callback (GtkTextBuffer *text_buffer,
1812
static void gimp_prop_text_buffer_notify (GObject *config,
1813
GParamSpec *param_spec,
1814
GtkTextBuffer *text_buffer);
1817
* gimp_prop_text_buffer_new:
1818
* @config: Object to which property is attached.
1819
* @property_name: Name of string property.
1820
* @max_len: Maximum allowed length of text (in characters).
1822
* Creates a #GtkTextBuffer to set and display the value of the
1823
* specified string property. Unless the string is expected to
1824
* contain multiple lines or a large amount of text, use
1825
* gimp_prop_entry_new() instead. See #GtkTextView for information on
1826
* how to insert a text buffer into a visible widget.
1828
* If @max_len is 0 or negative, the text buffer allows an unlimited
1829
* number of characters to be entered.
1831
* Return value: A new #GtkTextBuffer.
1836
gimp_prop_text_buffer_new (GObject *config,
1837
const gchar *property_name,
1840
GParamSpec *param_spec;
1841
GtkTextBuffer *text_buffer;
1844
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
1845
g_return_val_if_fail (property_name != NULL, NULL);
1847
param_spec = check_param_spec_w (config, property_name,
1848
G_TYPE_PARAM_STRING, G_STRFUNC);
1852
g_object_get (config,
1853
property_name, &value,
1856
text_buffer = gtk_text_buffer_new (NULL);
1857
gtk_text_buffer_set_text (text_buffer, value ? value : "", -1);
1862
g_object_set_data (G_OBJECT (text_buffer), "max-len",
1863
GINT_TO_POINTER (max_len));
1865
set_param_spec (G_OBJECT (text_buffer), NULL, param_spec);
1867
g_signal_connect (text_buffer, "changed",
1868
G_CALLBACK (gimp_prop_text_buffer_callback),
1871
connect_notify (config, property_name,
1872
G_CALLBACK (gimp_prop_text_buffer_notify),
1879
gimp_prop_text_buffer_callback (GtkTextBuffer *text_buffer,
1882
GParamSpec *param_spec;
1883
GtkTextIter start_iter;
1884
GtkTextIter end_iter;
1888
param_spec = get_param_spec (G_OBJECT (text_buffer));
1892
gtk_text_buffer_get_bounds (text_buffer, &start_iter, &end_iter);
1893
text = gtk_text_buffer_get_text (text_buffer, &start_iter, &end_iter, FALSE);
1895
max_len = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (text_buffer),
1898
if (max_len > 0 && g_utf8_strlen (text, -1) > max_len)
1900
g_message (dngettext (GETTEXT_PACKAGE "-libgimp",
1901
"This text input field is limited to %d character.",
1902
"This text input field is limited to %d characters.",
1905
gtk_text_buffer_get_iter_at_offset (text_buffer,
1906
&start_iter, max_len - 1);
1907
gtk_text_buffer_get_end_iter (text_buffer, &end_iter);
1909
/* this calls us recursively, but in the else branch */
1910
gtk_text_buffer_delete (text_buffer, &start_iter, &end_iter);
1914
g_signal_handlers_block_by_func (config,
1915
gimp_prop_text_buffer_notify,
1918
g_object_set (config,
1919
param_spec->name, text,
1922
g_signal_handlers_unblock_by_func (config,
1923
gimp_prop_text_buffer_notify,
1931
gimp_prop_text_buffer_notify (GObject *config,
1932
GParamSpec *param_spec,
1933
GtkTextBuffer *text_buffer)
1937
g_object_get (config,
1938
param_spec->name, &value,
1941
g_signal_handlers_block_by_func (text_buffer,
1942
gimp_prop_text_buffer_callback,
1945
gtk_text_buffer_set_text (text_buffer, value ? value : "", -1);
1947
g_signal_handlers_unblock_by_func (text_buffer,
1948
gimp_prop_text_buffer_callback,
1955
/***********************/
1956
/* string combo box */
1957
/***********************/
1959
static void gimp_prop_string_combo_box_callback (GtkWidget *widget,
1961
static void gimp_prop_string_combo_box_notify (GObject *config,
1962
GParamSpec *param_spec,
1966
* gimp_prop_string_combo_box_new:
1967
* @config: Object to which property is attached.
1968
* @property_name: Name of int property controlled by combo box.
1969
* @model: #GtkTreeStore holding list of values
1970
* @id_column: column in @store that holds string IDs
1971
* @label_column: column in @store that holds labels to use in the combo-box
1973
* Creates a #GimpStringComboBox widget to display and set the
1974
* specified property. The contents of the widget are determined by
1977
* Return value: The newly created #GimpStringComboBox widget, optionally
1978
* wrapped into a #GtkEventBox.
1983
gimp_prop_string_combo_box_new (GObject *config,
1984
const gchar *property_name,
1985
GtkTreeModel *model,
1989
GParamSpec *param_spec;
1990
GtkWidget *combo_box;
1994
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
1995
g_return_val_if_fail (property_name != NULL, NULL);
1996
g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1998
param_spec = check_param_spec_w (config, property_name,
1999
G_TYPE_PARAM_STRING, G_STRFUNC);
2003
g_object_get (config,
2004
property_name, &value,
2007
combo_box = gimp_string_combo_box_new (model, id_column, label_column);
2009
gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (combo_box), value);
2011
g_signal_connect (combo_box, "changed",
2012
G_CALLBACK (gimp_prop_string_combo_box_callback),
2015
/* can't set a tooltip on a combo_box */
2016
if (g_param_spec_get_blurb (param_spec))
2018
widget = gtk_event_box_new ();
2019
gtk_container_add (GTK_CONTAINER (widget), combo_box);
2020
gtk_widget_show (combo_box);
2027
set_param_spec (G_OBJECT (combo_box), widget, param_spec);
2029
connect_notify (config, property_name,
2030
G_CALLBACK (gimp_prop_string_combo_box_notify),
2037
gimp_prop_string_combo_box_callback (GtkWidget *widget,
2040
GParamSpec *param_spec;
2043
param_spec = get_param_spec (G_OBJECT (widget));
2047
value = gimp_string_combo_box_get_active (GIMP_STRING_COMBO_BOX (widget));
2049
g_object_set (config,
2050
param_spec->name, value,
2057
gimp_prop_string_combo_box_notify (GObject *config,
2058
GParamSpec *param_spec,
2059
GtkWidget *combo_box)
2063
g_object_get (config,
2064
param_spec->name, &value,
2067
g_signal_handlers_block_by_func (combo_box,
2068
gimp_prop_string_combo_box_callback,
2071
gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (combo_box), value);
2073
g_signal_handlers_unblock_by_func (combo_box,
2074
gimp_prop_string_combo_box_callback,
2081
/*************************/
2082
/* file chooser button */
2083
/*************************/
2086
static GtkWidget * gimp_prop_file_chooser_button_setup (GtkWidget *button,
2088
GParamSpec *param_spec);
2089
static void gimp_prop_file_chooser_button_callback (GtkFileChooser *button,
2091
static void gimp_prop_file_chooser_button_notify (GObject *config,
2092
GParamSpec *param_spec,
2093
GtkFileChooser *button);
2097
* gimp_prop_file_chooser_button_new:
2098
* @config: object to which property is attached.
2099
* @property_name: name of path property.
2100
* @title: the title of the browse dialog.
2101
* @action: the open mode for the widget.
2103
* Creates a #GtkFileChooserButton to edit the specified path property.
2105
* Note that #GtkFileChooserButton implements the #GtkFileChooser
2106
* interface; you can use the #GtkFileChooser API with it.
2108
* Return value: A new #GtkFileChooserButton.
2113
gimp_prop_file_chooser_button_new (GObject *config,
2114
const gchar *property_name,
2116
GtkFileChooserAction action)
2118
GParamSpec *param_spec;
2121
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
2122
g_return_val_if_fail (property_name != NULL, NULL);
2124
param_spec = check_param_spec_w (config, property_name,
2125
GIMP_TYPE_PARAM_CONFIG_PATH, G_STRFUNC);
2129
button = gtk_file_chooser_button_new (title, action);
2131
return gimp_prop_file_chooser_button_setup (button, config, param_spec);
2135
* gimp_prop_file_chooser_button_new_with_dialog:
2136
* @config: object to which property is attached.
2137
* @property_name: name of path property.
2138
* @dialog: the #GtkFileChooserDialog widget to use.
2140
* Creates a #GtkFileChooserButton to edit the specified path property.
2142
* The button uses @dialog as it's file-picking window. Note that @dialog
2143
* must be a #GtkFileChooserDialog (or subclass) and must not have
2144
* %GTK_DIALOG_DESTROY_WITH_PARENT set.
2146
* Note that #GtkFileChooserButton implements the #GtkFileChooser
2147
* interface; you can use the #GtkFileChooser API with it.
2149
* Return value: A new #GtkFileChooserButton.
2154
gimp_prop_file_chooser_button_new_with_dialog (GObject *config,
2155
const gchar *property_name,
2158
GParamSpec *param_spec;
2162
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
2163
g_return_val_if_fail (property_name != NULL, NULL);
2164
g_return_val_if_fail (GTK_IS_FILE_CHOOSER_DIALOG (dialog), NULL);
2166
param_spec = check_param_spec_w (config, property_name,
2167
GIMP_TYPE_PARAM_CONFIG_PATH, G_STRFUNC);
2171
/* work around bug in GtkFileChooserButton */
2172
title = g_strdup (gtk_window_get_title (GTK_WINDOW (dialog)));
2174
button = gtk_file_chooser_button_new_with_dialog (dialog);
2178
gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (button),
2183
return gimp_prop_file_chooser_button_setup (button, config, param_spec);
2187
gimp_prop_file_chooser_button_setup (GtkWidget *button,
2189
GParamSpec *param_spec)
2195
g_object_get (config,
2196
param_spec->name, &value,
2199
filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
2204
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (button), filename);
2208
/* can't set a tooltip on a file-chooser button */
2209
if (g_param_spec_get_blurb (param_spec))
2211
widget = gtk_event_box_new ();
2212
gtk_container_add (GTK_CONTAINER (widget), button);
2213
gtk_widget_show (button);
2220
set_param_spec (G_OBJECT (button), widget, param_spec);
2222
g_signal_connect (button, "selection-changed",
2223
G_CALLBACK (gimp_prop_file_chooser_button_callback),
2226
connect_notify (config, param_spec->name,
2227
G_CALLBACK (gimp_prop_file_chooser_button_notify),
2234
gimp_prop_file_chooser_button_callback (GtkFileChooser *button,
2237
GParamSpec *param_spec;
2241
param_spec = get_param_spec (G_OBJECT (button));
2245
value = gtk_file_chooser_get_filename (button);
2246
utf8 = value ? g_filename_to_utf8 (value, -1, NULL, NULL, NULL) : NULL;
2249
g_object_get (config,
2250
param_spec->name, &value,
2253
if (! (value && utf8 && strcmp (value, utf8) == 0))
2255
g_signal_handlers_block_by_func (config,
2256
gimp_prop_file_chooser_button_notify,
2259
g_object_set (config,
2260
param_spec->name, utf8,
2263
g_signal_handlers_unblock_by_func (config,
2264
gimp_prop_file_chooser_button_notify,
2273
gimp_prop_file_chooser_button_notify (GObject *config,
2274
GParamSpec *param_spec,
2275
GtkFileChooser *button)
2280
g_object_get (config,
2281
param_spec->name, &value,
2284
filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
2287
g_signal_handlers_block_by_func (button,
2288
gimp_prop_file_chooser_button_callback,
2292
gtk_file_chooser_set_filename (button, filename);
2294
gtk_file_chooser_unselect_all (button);
2296
g_signal_handlers_unblock_by_func (button,
2297
gimp_prop_file_chooser_button_callback,
2308
static void gimp_prop_path_editor_path_callback (GimpPathEditor *editor,
2310
static void gimp_prop_path_editor_writable_callback (GimpPathEditor *editor,
2312
static void gimp_prop_path_editor_path_notify (GObject *config,
2313
GParamSpec *param_spec,
2314
GimpPathEditor *editor);
2315
static void gimp_prop_path_editor_writable_notify (GObject *config,
2316
GParamSpec *param_spec,
2317
GimpPathEditor *editor);
2320
gimp_prop_path_editor_new (GObject *config,
2321
const gchar *path_property_name,
2322
const gchar *writable_property_name,
2323
const gchar *filesel_title)
2325
GParamSpec *path_param_spec;
2326
GParamSpec *writable_param_spec = NULL;
2331
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
2332
g_return_val_if_fail (path_property_name != NULL, NULL);
2334
path_param_spec = check_param_spec_w (config, path_property_name,
2335
GIMP_TYPE_PARAM_CONFIG_PATH, G_STRFUNC);
2336
if (! path_param_spec)
2339
if (writable_property_name)
2341
writable_param_spec = check_param_spec_w (config, writable_property_name,
2342
GIMP_TYPE_PARAM_CONFIG_PATH,
2344
if (! writable_param_spec)
2348
g_object_get (config,
2349
path_property_name, &value,
2352
filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
2355
editor = gimp_path_editor_new (filesel_title, filename);
2358
if (writable_property_name)
2360
g_object_get (config,
2361
writable_property_name, &value,
2364
filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
2367
gimp_path_editor_set_writable_path (GIMP_PATH_EDITOR (editor), filename);
2371
g_object_set_data (G_OBJECT (editor), "gimp-config-param-spec-path",
2374
g_signal_connect (editor, "path-changed",
2375
G_CALLBACK (gimp_prop_path_editor_path_callback),
2378
connect_notify (config, path_property_name,
2379
G_CALLBACK (gimp_prop_path_editor_path_notify),
2382
if (writable_property_name)
2384
g_object_set_data (G_OBJECT (editor), "gimp-config-param-spec-writable",
2385
writable_param_spec);
2387
g_signal_connect (editor, "writable-changed",
2388
G_CALLBACK (gimp_prop_path_editor_writable_callback),
2391
connect_notify (config, writable_property_name,
2392
G_CALLBACK (gimp_prop_path_editor_writable_notify),
2400
gimp_prop_path_editor_path_callback (GimpPathEditor *editor,
2403
GParamSpec *path_param_spec;
2404
GParamSpec *writable_param_spec;
2408
path_param_spec = g_object_get_data (G_OBJECT (editor),
2409
"gimp-config-param-spec-path");
2410
writable_param_spec = g_object_get_data (G_OBJECT (editor),
2411
"gimp-config-param-spec-writable");
2412
if (! path_param_spec)
2415
value = gimp_path_editor_get_path (editor);
2416
utf8 = g_filename_to_utf8 (value, -1, NULL, NULL, NULL);
2419
g_signal_handlers_block_by_func (config,
2420
gimp_prop_path_editor_path_notify,
2423
g_object_set (config,
2424
path_param_spec->name, utf8,
2427
g_signal_handlers_unblock_by_func (config,
2428
gimp_prop_path_editor_path_notify,
2433
if (writable_param_spec)
2435
value = gimp_path_editor_get_writable_path (editor);
2436
utf8 = g_filename_to_utf8 (value, -1, NULL, NULL, NULL);
2439
g_signal_handlers_block_by_func (config,
2440
gimp_prop_path_editor_writable_notify,
2443
g_object_set (config,
2444
writable_param_spec->name, utf8,
2447
g_signal_handlers_unblock_by_func (config,
2448
gimp_prop_path_editor_writable_notify,
2456
gimp_prop_path_editor_writable_callback (GimpPathEditor *editor,
2459
GParamSpec *param_spec;
2463
param_spec = g_object_get_data (G_OBJECT (editor),
2464
"gimp-config-param-spec-writable");
2468
value = gimp_path_editor_get_writable_path (editor);
2469
utf8 = g_filename_to_utf8 (value, -1, NULL, NULL, NULL);
2472
g_signal_handlers_block_by_func (config,
2473
gimp_prop_path_editor_writable_notify,
2476
g_object_set (config,
2477
param_spec->name, utf8,
2480
g_signal_handlers_unblock_by_func (config,
2481
gimp_prop_path_editor_writable_notify,
2488
gimp_prop_path_editor_path_notify (GObject *config,
2489
GParamSpec *param_spec,
2490
GimpPathEditor *editor)
2495
g_object_get (config,
2496
param_spec->name, &value,
2499
filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
2502
g_signal_handlers_block_by_func (editor,
2503
gimp_prop_path_editor_path_callback,
2506
gimp_path_editor_set_path (editor, filename);
2508
g_signal_handlers_unblock_by_func (editor,
2509
gimp_prop_path_editor_path_callback,
2516
gimp_prop_path_editor_writable_notify (GObject *config,
2517
GParamSpec *param_spec,
2518
GimpPathEditor *editor)
2523
g_object_get (config,
2524
param_spec->name, &value,
2527
filename = value ? gimp_config_path_expand (value, TRUE, NULL) : NULL;
2530
g_signal_handlers_block_by_func (editor,
2531
gimp_prop_path_editor_writable_callback,
2534
gimp_path_editor_set_writable_path (editor, filename);
2536
g_signal_handlers_unblock_by_func (editor,
2537
gimp_prop_path_editor_writable_callback,
2548
static void gimp_prop_size_entry_callback (GimpSizeEntry *sizeentry,
2550
static void gimp_prop_size_entry_notify (GObject *config,
2551
GParamSpec *param_spec,
2552
GimpSizeEntry *sizeentry);
2553
static void gimp_prop_size_entry_notify_unit (GObject *config,
2554
GParamSpec *param_spec,
2555
GimpSizeEntry *sizeentry);
2559
* gimp_prop_size_entry_new:
2560
* @config: Object to which property is attached.
2561
* @property_name: Name of int or double property.
2562
* @unit_property_name: Name of unit property.
2563
* @unit_format: A printf-like unit-format string as is used with
2564
* gimp_unit_menu_new().
2565
* @update_policy: How the automatic pixel <-> real-world-unit
2566
* calculations should be done.
2567
* @resolution: The resolution (in dpi) for the field.
2569
* Creates a #GimpSizeEntry to set and display the specified double or
2570
* int property, and its associated unit property. Note that this
2571
* function is only suitable for creating a size entry holding a
2572
* single value. Use gimp_prop_coordinates_new() to create a size
2573
* entry holding two values.
2575
* Return value: A new #GimpSizeEntry widget.
2580
gimp_prop_size_entry_new (GObject *config,
2581
const gchar *property_name,
2582
const gchar *unit_property_name,
2583
const gchar *unit_format,
2584
GimpSizeEntryUpdatePolicy update_policy,
2587
GtkWidget *sizeentry;
2588
GParamSpec *param_spec;
2589
GParamSpec *unit_param_spec;
2590
gboolean show_pixels;
2594
GimpUnit unit_value;
2596
param_spec = find_param_spec (config, property_name, G_STRFUNC);
2600
if (! get_numeric_values (config,
2601
param_spec, &value, &lower, &upper, G_STRFUNC))
2604
if (unit_property_name)
2606
GValue value = { 0 };
2608
unit_param_spec = check_param_spec_w (config, unit_property_name,
2609
GIMP_TYPE_PARAM_UNIT, G_STRFUNC);
2610
if (! unit_param_spec)
2613
g_value_init (&value, unit_param_spec->value_type);
2614
g_value_set_int (&value, GIMP_UNIT_PIXEL);
2616
(g_param_value_validate (unit_param_spec, &value) == FALSE);
2617
g_value_unset (&value);
2619
g_object_get (config,
2620
unit_property_name, &unit_value,
2625
unit_param_spec = NULL;
2626
unit_value = GIMP_UNIT_INCH;
2627
show_pixels = FALSE;
2630
sizeentry = gimp_size_entry_new (1, unit_value, unit_format,
2632
ceil (log (upper) / log (10) + 2),
2634
gtk_table_set_col_spacing (GTK_TABLE (sizeentry), 1, 4);
2636
set_param_spec (NULL,
2637
gimp_size_entry_get_help_widget (GIMP_SIZE_ENTRY (sizeentry),
2641
if (unit_param_spec)
2642
set_param_spec (NULL,
2643
GIMP_SIZE_ENTRY (sizeentry)->unitmenu, unit_param_spec);
2645
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (sizeentry), unit_value);
2647
if (update_policy == GIMP_SIZE_ENTRY_UPDATE_SIZE)
2648
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 0,
2651
gimp_size_entry_set_value_boundaries (GIMP_SIZE_ENTRY (sizeentry), 0,
2654
gimp_size_entry_set_value (GIMP_SIZE_ENTRY (sizeentry), 0, value);
2656
g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec",
2659
g_signal_connect (sizeentry, "value-changed",
2660
G_CALLBACK (gimp_prop_size_entry_callback),
2663
connect_notify (config, property_name,
2664
G_CALLBACK (gimp_prop_size_entry_notify),
2667
if (unit_property_name)
2669
g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-unit",
2672
g_signal_connect (sizeentry, "unit-changed",
2673
G_CALLBACK (gimp_prop_size_entry_callback),
2676
connect_notify (config, unit_property_name,
2677
G_CALLBACK (gimp_prop_size_entry_notify_unit),
2685
gimp_prop_size_entry_callback (GimpSizeEntry *sizeentry,
2688
GParamSpec *param_spec;
2689
GParamSpec *unit_param_spec;
2691
GimpUnit unit_value;
2693
param_spec = g_object_get_data (G_OBJECT (sizeentry),
2694
"gimp-config-param-spec");
2698
unit_param_spec = g_object_get_data (G_OBJECT (sizeentry),
2699
"gimp-config-param-spec-unit");
2701
value = gimp_size_entry_get_value (sizeentry, 0);
2702
unit_value = gimp_size_entry_get_unit (sizeentry);
2704
if (unit_param_spec)
2708
g_object_get (config,
2709
unit_param_spec->name, &old_unit,
2712
if (unit_value == old_unit)
2713
unit_param_spec = NULL;
2716
if (G_IS_PARAM_SPEC_INT (param_spec))
2718
g_object_set (config,
2719
param_spec->name, ROUND (value),
2722
unit_param_spec->name : NULL, unit_value,
2726
else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
2728
g_object_set (config,
2729
param_spec->name, value,
2732
unit_param_spec->name : NULL, unit_value,
2739
gimp_prop_size_entry_notify (GObject *config,
2740
GParamSpec *param_spec,
2741
GimpSizeEntry *sizeentry)
2745
if (G_IS_PARAM_SPEC_INT (param_spec))
2749
g_object_get (config,
2750
param_spec->name, &int_value,
2757
g_object_get (config,
2758
param_spec->name, &value,
2762
if (value != gimp_size_entry_get_value (sizeentry, 0))
2764
g_signal_handlers_block_by_func (sizeentry,
2765
gimp_prop_size_entry_callback,
2768
gimp_size_entry_set_value (sizeentry, 0, value);
2770
g_signal_handlers_unblock_by_func (sizeentry,
2771
gimp_prop_size_entry_callback,
2777
gimp_prop_size_entry_notify_unit (GObject *config,
2778
GParamSpec *param_spec,
2779
GimpSizeEntry *sizeentry)
2783
g_object_get (config,
2784
param_spec->name, &value,
2787
if (value != gimp_size_entry_get_unit (sizeentry))
2789
g_signal_handlers_block_by_func (sizeentry,
2790
gimp_prop_size_entry_callback,
2793
gimp_size_entry_set_unit (sizeentry, value);
2795
g_signal_handlers_unblock_by_func (sizeentry,
2796
gimp_prop_size_entry_callback,
2806
static void gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
2808
static void gimp_prop_coordinates_notify_x (GObject *config,
2809
GParamSpec *param_spec,
2810
GimpSizeEntry *sizeentry);
2811
static void gimp_prop_coordinates_notify_y (GObject *config,
2812
GParamSpec *param_spec,
2813
GimpSizeEntry *sizeentry);
2814
static void gimp_prop_coordinates_notify_unit (GObject *config,
2815
GParamSpec *param_spec,
2816
GimpSizeEntry *sizeentry);
2820
* gimp_prop_coordinates_new:
2821
* @config: Object to which property is attached.
2822
* @x_property_name: Name of int or double property for X coordinate.
2823
* @y_property_name: Name of int or double property for Y coordinate.
2824
* @unit_property_name: Name of unit property.
2825
* @unit_format: A printf-like unit-format string as is used with
2826
* gimp_unit_menu_new().
2827
* @update_policy: How the automatic pixel <-> real-world-unit
2828
* calculations should be done.
2829
* @xresolution: The resolution (in dpi) for the X coordinate.
2830
* @yresolution: The resolution (in dpi) for the Y coordinate.
2831
* @has_chainbutton: Whether to add a chainbutton to the size entry.
2833
* Creates a #GimpSizeEntry to set and display two double or int
2834
* properties, which will usually represent X and Y coordinates, and
2835
* their associated unit property.
2837
* Return value: A new #GimpSizeEntry widget.
2842
gimp_prop_coordinates_new (GObject *config,
2843
const gchar *x_property_name,
2844
const gchar *y_property_name,
2845
const gchar *unit_property_name,
2846
const gchar *unit_format,
2847
GimpSizeEntryUpdatePolicy update_policy,
2848
gdouble xresolution,
2849
gdouble yresolution,
2850
gboolean has_chainbutton)
2852
GtkWidget *sizeentry;
2853
GtkWidget *chainbutton = NULL;
2855
sizeentry = gimp_size_entry_new (2, GIMP_UNIT_INCH, unit_format,
2856
FALSE, FALSE, TRUE, 10,
2859
if (has_chainbutton)
2861
chainbutton = gimp_chain_button_new (GIMP_CHAIN_BOTTOM);
2862
gtk_table_attach_defaults (GTK_TABLE (sizeentry), chainbutton,
2864
gtk_widget_show (chainbutton);
2867
if (! gimp_prop_coordinates_connect (config,
2876
gtk_widget_destroy (sizeentry);
2884
gimp_prop_coordinates_connect (GObject *config,
2885
const gchar *x_property_name,
2886
const gchar *y_property_name,
2887
const gchar *unit_property_name,
2888
GtkWidget *sizeentry,
2889
GtkWidget *chainbutton,
2890
gdouble xresolution,
2891
gdouble yresolution)
2893
GParamSpec *x_param_spec;
2894
GParamSpec *y_param_spec;
2895
GParamSpec *unit_param_spec;
2896
gdouble x_value, x_lower, x_upper;
2897
gdouble y_value, y_lower, y_upper;
2898
GimpUnit unit_value;
2899
gdouble *old_x_value;
2900
gdouble *old_y_value;
2901
GimpUnit *old_unit_value;
2902
gboolean chain_checked;
2904
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (sizeentry), FALSE);
2905
g_return_val_if_fail (GIMP_SIZE_ENTRY (sizeentry)->number_of_fields == 2,
2907
g_return_val_if_fail (chainbutton == NULL ||
2908
GIMP_IS_CHAIN_BUTTON (chainbutton), FALSE);
2910
x_param_spec = find_param_spec (config, x_property_name, G_STRFUNC);
2914
y_param_spec = find_param_spec (config, y_property_name, G_STRFUNC);
2918
if (! get_numeric_values (config, x_param_spec,
2919
&x_value, &x_lower, &x_upper, G_STRFUNC) ||
2920
! get_numeric_values (config, y_param_spec,
2921
&y_value, &y_lower, &y_upper, G_STRFUNC))
2924
if (unit_property_name)
2926
unit_param_spec = check_param_spec_w (config, unit_property_name,
2927
GIMP_TYPE_PARAM_UNIT, G_STRFUNC);
2928
if (! unit_param_spec)
2931
g_object_get (config,
2932
unit_property_name, &unit_value,
2937
unit_param_spec = NULL;
2938
unit_value = GIMP_UNIT_INCH;
2941
set_param_spec (NULL,
2942
gimp_size_entry_get_help_widget (GIMP_SIZE_ENTRY (sizeentry),
2945
set_param_spec (NULL,
2946
gimp_size_entry_get_help_widget (GIMP_SIZE_ENTRY (sizeentry),
2950
if (unit_param_spec)
2951
set_param_spec (NULL,
2952
GIMP_SIZE_ENTRY (sizeentry)->unitmenu, unit_param_spec);
2954
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (sizeentry), unit_value);
2956
switch (GIMP_SIZE_ENTRY (sizeentry)->update_policy)
2958
case GIMP_SIZE_ENTRY_UPDATE_SIZE:
2959
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 0,
2960
xresolution, FALSE);
2961
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 1,
2962
yresolution, FALSE);
2963
chain_checked = (ABS (x_value - y_value) < 1);
2966
case GIMP_SIZE_ENTRY_UPDATE_RESOLUTION:
2967
chain_checked = (ABS (x_value - y_value) < GIMP_MIN_RESOLUTION);
2971
chain_checked = (x_value == y_value);
2975
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry), 0,
2977
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry), 1,
2980
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 0, x_value);
2981
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 1, y_value);
2983
g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-x",
2985
g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-y",
2988
old_x_value = g_new0 (gdouble, 1);
2989
*old_x_value = x_value;
2990
g_object_set_data_full (G_OBJECT (sizeentry), "old-x-value",
2992
(GDestroyNotify) g_free);
2994
old_y_value = g_new0 (gdouble, 1);
2995
*old_y_value = y_value;
2996
g_object_set_data_full (G_OBJECT (sizeentry), "old-y-value",
2998
(GDestroyNotify) g_free);
3003
gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chainbutton), TRUE);
3005
g_object_set_data (G_OBJECT (sizeentry), "chainbutton", chainbutton);
3008
g_signal_connect (sizeentry, "value-changed",
3009
G_CALLBACK (gimp_prop_coordinates_callback),
3011
g_signal_connect (sizeentry, "refval-changed",
3012
G_CALLBACK (gimp_prop_coordinates_callback),
3015
connect_notify (config, x_property_name,
3016
G_CALLBACK (gimp_prop_coordinates_notify_x),
3018
connect_notify (config, y_property_name,
3019
G_CALLBACK (gimp_prop_coordinates_notify_y),
3022
if (unit_property_name)
3024
g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-unit",
3027
old_unit_value = g_new0 (GimpUnit, 1);
3028
*old_unit_value = unit_value;
3029
g_object_set_data_full (G_OBJECT (sizeentry), "old-unit-value",
3031
(GDestroyNotify) g_free);
3033
g_signal_connect (sizeentry, "unit-changed",
3034
G_CALLBACK (gimp_prop_coordinates_callback),
3037
connect_notify (config, unit_property_name,
3038
G_CALLBACK (gimp_prop_coordinates_notify_unit),
3046
gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
3049
GParamSpec *x_param_spec;
3050
GParamSpec *y_param_spec;
3051
GParamSpec *unit_param_spec;
3054
GimpUnit unit_value;
3055
gdouble *old_x_value;
3056
gdouble *old_y_value;
3057
GimpUnit *old_unit_value;
3060
x_param_spec = g_object_get_data (G_OBJECT (sizeentry),
3061
"gimp-config-param-spec-x");
3062
y_param_spec = g_object_get_data (G_OBJECT (sizeentry),
3063
"gimp-config-param-spec-y");
3065
if (! x_param_spec || ! y_param_spec)
3068
unit_param_spec = g_object_get_data (G_OBJECT (sizeentry),
3069
"gimp-config-param-spec-unit");
3071
x_value = gimp_size_entry_get_refval (sizeentry, 0);
3072
y_value = gimp_size_entry_get_refval (sizeentry, 1);
3073
unit_value = gimp_size_entry_get_unit (sizeentry);
3075
old_x_value = g_object_get_data (G_OBJECT (sizeentry), "old-x-value");
3076
old_y_value = g_object_get_data (G_OBJECT (sizeentry), "old-y-value");
3077
old_unit_value = g_object_get_data (G_OBJECT (sizeentry), "old-unit-value");
3079
if (! old_x_value || ! old_y_value || (unit_param_spec && ! old_unit_value))
3083
* FIXME: if the entry was created using gimp_coordinates_new, then
3084
* the chain button is handled automatically and the following block
3085
* of code is unnecessary (and, in fact, redundant).
3087
if (x_value != y_value)
3089
GtkWidget *chainbutton;
3091
chainbutton = g_object_get_data (G_OBJECT (sizeentry), "chainbutton");
3094
gimp_chain_button_get_active (GIMP_CHAIN_BUTTON (chainbutton)) &&
3095
! g_object_get_data (G_OBJECT (chainbutton), "constrains-ratio"))
3097
if (x_value != *old_x_value)
3099
else if (y_value != *old_y_value)
3104
backwards = (*old_x_value == x_value);
3106
if (*old_x_value == x_value &&
3107
*old_y_value == y_value &&
3108
(old_unit_value == NULL || *old_unit_value == unit_value))
3111
*old_x_value = x_value;
3112
*old_y_value = y_value;
3115
*old_unit_value = unit_value;
3117
if (unit_param_spec)
3118
g_object_set (config,
3119
unit_param_spec->name, unit_value,
3122
if (G_IS_PARAM_SPEC_INT (x_param_spec) &&
3123
G_IS_PARAM_SPEC_INT (y_param_spec))
3126
g_object_set (config,
3127
y_param_spec->name, ROUND (y_value),
3128
x_param_spec->name, ROUND (x_value),
3131
g_object_set (config,
3132
x_param_spec->name, ROUND (x_value),
3133
y_param_spec->name, ROUND (y_value),
3137
else if (G_IS_PARAM_SPEC_DOUBLE (x_param_spec) &&
3138
G_IS_PARAM_SPEC_DOUBLE (y_param_spec))
3141
g_object_set (config,
3142
y_param_spec->name, y_value,
3143
x_param_spec->name, x_value,
3146
g_object_set (config,
3147
x_param_spec->name, x_value,
3148
y_param_spec->name, y_value,
3154
gimp_prop_coordinates_notify_x (GObject *config,
3155
GParamSpec *param_spec,
3156
GimpSizeEntry *sizeentry)
3160
if (G_IS_PARAM_SPEC_INT (param_spec))
3164
g_object_get (config,
3165
param_spec->name, &int_value,
3172
g_object_get (config,
3173
param_spec->name, &value,
3177
if (value != gimp_size_entry_get_refval (sizeentry, 0))
3179
g_signal_handlers_block_by_func (sizeentry,
3180
gimp_prop_coordinates_callback,
3183
gimp_size_entry_set_refval (sizeentry, 0, value);
3185
g_signal_handlers_unblock_by_func (sizeentry,
3186
gimp_prop_coordinates_callback,
3192
gimp_prop_coordinates_notify_y (GObject *config,
3193
GParamSpec *param_spec,
3194
GimpSizeEntry *sizeentry)
3198
if (G_IS_PARAM_SPEC_INT (param_spec))
3202
g_object_get (config,
3203
param_spec->name, &int_value,
3210
g_object_get (config,
3211
param_spec->name, &value,
3215
if (value != gimp_size_entry_get_refval (sizeentry, 1))
3217
g_signal_handlers_block_by_func (sizeentry,
3218
gimp_prop_coordinates_callback,
3221
gimp_size_entry_set_refval (sizeentry, 1, value);
3223
g_signal_handlers_unblock_by_func (sizeentry,
3224
gimp_prop_coordinates_callback,
3230
gimp_prop_coordinates_notify_unit (GObject *config,
3231
GParamSpec *param_spec,
3232
GimpSizeEntry *sizeentry)
3236
g_object_get (config,
3237
param_spec->name, &value,
3240
if (value != gimp_size_entry_get_unit (sizeentry))
3242
g_signal_handlers_block_by_func (sizeentry,
3243
gimp_prop_coordinates_callback,
3246
gimp_size_entry_set_unit (sizeentry, value);
3248
g_signal_handlers_unblock_by_func (sizeentry,
3249
gimp_prop_coordinates_callback,
3259
static void gimp_prop_color_area_callback (GtkWidget *widget,
3261
static void gimp_prop_color_area_notify (GObject *config,
3262
GParamSpec *param_spec,
3266
* gimp_prop_color_area_new:
3267
* @config: Object to which property is attached.
3268
* @property_name: Name of RGB property.
3269
* @width: Width of color area.
3270
* @height: Height of color area.
3271
* @type: How transparency is represented.
3273
* Creates a #GimpColorArea to set and display the value of an RGB
3276
* Return value: A new #GimpColorArea widget.
3281
gimp_prop_color_area_new (GObject *config,
3282
const gchar *property_name,
3285
GimpColorAreaType type)
3287
GParamSpec *param_spec;
3291
param_spec = check_param_spec_w (config, property_name,
3292
GIMP_TYPE_PARAM_RGB, G_STRFUNC);
3296
g_object_get (config,
3297
property_name, &value,
3300
area = gimp_color_area_new (value, type,
3301
GDK_BUTTON1_MASK | GDK_BUTTON2_MASK);
3302
gtk_widget_set_size_request (area, width, height);
3306
set_param_spec (G_OBJECT (area), area, param_spec);
3308
g_signal_connect (area, "color-changed",
3309
G_CALLBACK (gimp_prop_color_area_callback),
3312
connect_notify (config, property_name,
3313
G_CALLBACK (gimp_prop_color_area_notify),
3320
gimp_prop_color_area_callback (GtkWidget *area,
3323
GParamSpec *param_spec;
3326
param_spec = get_param_spec (G_OBJECT (area));
3330
gimp_color_area_get_color (GIMP_COLOR_AREA (area), &value);
3332
g_signal_handlers_block_by_func (config,
3333
gimp_prop_color_area_notify,
3336
g_object_set (config,
3337
param_spec->name, &value,
3340
g_signal_handlers_unblock_by_func (config,
3341
gimp_prop_color_area_notify,
3346
gimp_prop_color_area_notify (GObject *config,
3347
GParamSpec *param_spec,
3352
g_object_get (config,
3353
param_spec->name, &value,
3356
g_signal_handlers_block_by_func (area,
3357
gimp_prop_color_area_callback,
3360
gimp_color_area_set_color (GIMP_COLOR_AREA (area), value);
3364
g_signal_handlers_unblock_by_func (area,
3365
gimp_prop_color_area_callback,
3374
static void gimp_prop_unit_menu_callback (GtkWidget *menu,
3376
static void gimp_prop_unit_menu_notify (GObject *config,
3377
GParamSpec *param_spec,
3381
* gimp_prop_unit_menu_new:
3382
* @config: Object to which property is attached.
3383
* @property_name: Name of Unit property.
3384
* @unit_format: A printf-like format string which is used to create
3387
* Creates a #GimpUnitMenu to set and display the value of a Unit
3388
* property. See gimp_unit_menu_new() for more information.
3390
* Return value: A new #GimpUnitMenu widget.
3395
gimp_prop_unit_menu_new (GObject *config,
3396
const gchar *property_name,
3397
const gchar *unit_format)
3399
GParamSpec *param_spec;
3402
GValue value = { 0, };
3403
gboolean show_pixels;
3404
gboolean show_percent;
3406
param_spec = check_param_spec_w (config, property_name,
3407
GIMP_TYPE_PARAM_UNIT, G_STRFUNC);
3411
g_value_init (&value, param_spec->value_type);
3413
g_value_set_int (&value, GIMP_UNIT_PIXEL);
3414
show_pixels = (g_param_value_validate (param_spec, &value) == FALSE);
3416
g_value_set_int (&value, GIMP_UNIT_PERCENT);
3417
show_percent = (g_param_value_validate (param_spec, &value) == FALSE);
3419
g_value_unset (&value);
3421
g_object_get (config,
3422
property_name, &unit,
3425
menu = gimp_unit_menu_new (unit_format,
3426
unit, show_pixels, show_percent, TRUE);
3428
set_param_spec (G_OBJECT (menu), menu, param_spec);
3430
g_signal_connect (menu, "unit-changed",
3431
G_CALLBACK (gimp_prop_unit_menu_callback),
3434
connect_notify (config, property_name,
3435
G_CALLBACK (gimp_prop_unit_menu_notify),
3442
gimp_prop_unit_menu_callback (GtkWidget *menu,
3445
GParamSpec *param_spec;
3448
param_spec = get_param_spec (G_OBJECT (menu));
3452
gimp_unit_menu_update (menu, &unit);
3454
g_signal_handlers_block_by_func (config,
3455
gimp_prop_unit_menu_notify,
3458
g_object_set (config,
3459
param_spec->name, unit,
3462
g_signal_handlers_unblock_by_func (config,
3463
gimp_prop_unit_menu_notify,
3468
gimp_prop_unit_menu_notify (GObject *config,
3469
GParamSpec *param_spec,
3474
g_object_get (config,
3475
param_spec->name, &unit,
3478
g_signal_handlers_block_by_func (menu,
3479
gimp_prop_unit_menu_callback,
3482
gimp_unit_menu_set_unit (GIMP_UNIT_MENU (menu), unit);
3483
gimp_unit_menu_update (menu, &unit);
3485
g_signal_handlers_unblock_by_func (menu,
3486
gimp_prop_unit_menu_callback,
3495
static void gimp_prop_stock_image_notify (GObject *config,
3496
GParamSpec *param_spec,
3500
* gimp_prop_stock_image_new:
3501
* @config: Object to which property is attached.
3502
* @property_name: Name of string property.
3503
* @icon_size: Size of desired stock image.
3505
* Creates a widget to display a stock image representing the value of the
3506
* specified string property, which should encode a Stock ID.
3507
* See gtk_image_new_from_stock() for more information.
3509
* Return value: A new #GtkImage widget.
3514
gimp_prop_stock_image_new (GObject *config,
3515
const gchar *property_name,
3516
GtkIconSize icon_size)
3518
GParamSpec *param_spec;
3522
param_spec = check_param_spec (config, property_name,
3523
G_TYPE_PARAM_STRING, G_STRFUNC);
3527
g_object_get (config,
3528
property_name, &stock_id,
3531
image = gtk_image_new_from_stock (stock_id, icon_size);
3536
set_param_spec (G_OBJECT (image), image, param_spec);
3538
connect_notify (config, property_name,
3539
G_CALLBACK (gimp_prop_stock_image_notify),
3546
gimp_prop_stock_image_notify (GObject *config,
3547
GParamSpec *param_spec,
3552
g_object_get (config,
3553
param_spec->name, &stock_id,
3556
gtk_image_set_from_stock (GTK_IMAGE (image), stock_id,
3557
GTK_IMAGE (image)->icon_size);
3568
static void gimp_prop_expanded_notify (GtkExpander *expander,
3569
GParamSpec *param_spec,
3571
static void gimp_prop_expander_notify (GObject *config,
3572
GParamSpec *param_spec,
3573
GtkExpander *expander);
3577
* gimp_prop_expander_new:
3578
* @config: Object to which property is attached.
3579
* @property_name: Name of boolean property.
3580
* @label: Label for expander.
3582
* Creates a #GtkExpander controlled by the specified boolean property.
3583
* A value of %TRUE for the property corresponds to the expanded state
3586
* Return value: A new #GtkExpander widget.
3591
gimp_prop_expander_new (GObject *config,
3592
const gchar *property_name,
3595
GParamSpec *param_spec;
3596
GtkWidget *expander;
3599
param_spec = check_param_spec_w (config, property_name,
3600
G_TYPE_PARAM_BOOLEAN, G_STRFUNC);
3604
g_object_get (config,
3605
property_name, &value,
3608
expander = g_object_new (GTK_TYPE_EXPANDER,
3613
set_param_spec (G_OBJECT (expander), expander, param_spec);
3615
g_signal_connect (expander, "notify::expanded",
3616
G_CALLBACK (gimp_prop_expanded_notify),
3619
connect_notify (config, property_name,
3620
G_CALLBACK (gimp_prop_expander_notify),
3627
gimp_prop_expanded_notify (GtkExpander *expander,
3628
GParamSpec *param_spec,
3631
param_spec = get_param_spec (G_OBJECT (expander));
3635
g_object_set (config,
3636
param_spec->name, gtk_expander_get_expanded (expander),
3641
gimp_prop_expander_notify (GObject *config,
3642
GParamSpec *param_spec,
3643
GtkExpander *expander)
3647
g_object_get (config,
3648
param_spec->name, &value,
3651
if (gtk_expander_get_expanded (expander) != value)
3653
g_signal_handlers_block_by_func (expander,
3654
gimp_prop_expanded_notify,
3657
gtk_expander_set_expanded (expander, value);
3659
g_signal_handlers_unblock_by_func (expander,
3660
gimp_prop_expanded_notify,
3666
/*******************************/
3667
/* private utility functions */
3668
/*******************************/
3670
static GQuark param_spec_quark = 0;
3673
set_param_spec (GObject *object,
3675
GParamSpec *param_spec)
3679
if (! param_spec_quark)
3680
param_spec_quark = g_quark_from_static_string ("gimp-config-param-spec");
3682
g_object_set_qdata (object, param_spec_quark, param_spec);
3687
const gchar *blurb = g_param_spec_get_blurb (param_spec);
3691
const gchar *domain;
3693
domain = gimp_type_get_translation_domain (param_spec->owner_type);
3694
gimp_help_set_help_data (widget, dgettext (domain, blurb), NULL);
3700
set_radio_spec (GObject *object,
3701
GParamSpec *param_spec)
3705
for (list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (object));
3707
list = g_slist_next (list))
3709
set_param_spec (list->data, NULL, param_spec);
3714
get_param_spec (GObject *object)
3716
if (! param_spec_quark)
3717
param_spec_quark = g_quark_from_static_string ("gimp-config-param-spec");
3719
return g_object_get_qdata (object, param_spec_quark);
3723
find_param_spec (GObject *object,
3724
const gchar *property_name,
3725
const gchar *strloc)
3727
GParamSpec *param_spec;
3729
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
3733
g_warning ("%s: %s has no property named '%s'",
3735
g_type_name (G_TYPE_FROM_INSTANCE (object)),
3742
check_param_spec (GObject *object,
3743
const gchar *property_name,
3745
const gchar *strloc)
3747
GParamSpec *param_spec;
3749
param_spec = find_param_spec (object, property_name, strloc);
3751
if (param_spec && ! g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), type))
3753
g_warning ("%s: property '%s' of %s is not a %s",
3756
g_type_name (param_spec->owner_type),
3757
g_type_name (type));
3765
check_param_spec_w (GObject *object,
3766
const gchar *property_name,
3768
const gchar *strloc)
3770
GParamSpec *param_spec;
3772
param_spec = check_param_spec (object, property_name, type, strloc);
3775
(param_spec->flags & G_PARAM_WRITABLE) == 0)
3777
g_warning ("%s: property '%s' of %s is writable",
3780
g_type_name (param_spec->owner_type));
3788
get_numeric_values (GObject *object,
3789
GParamSpec *param_spec,
3793
const gchar *strloc)
3795
if (G_IS_PARAM_SPEC_INT (param_spec))
3797
GParamSpecInt *int_spec = G_PARAM_SPEC_INT (param_spec);
3800
g_object_get (object, param_spec->name, &int_value, NULL);
3803
*lower = int_spec->minimum;
3804
*upper = int_spec->maximum;
3806
else if (G_IS_PARAM_SPEC_UINT (param_spec))
3808
GParamSpecUInt *uint_spec = G_PARAM_SPEC_UINT (param_spec);
3811
g_object_get (object, param_spec->name, &uint_value, NULL);
3813
*value = uint_value;
3814
*lower = uint_spec->minimum;
3815
*upper = uint_spec->maximum;
3817
else if (G_IS_PARAM_SPEC_DOUBLE (param_spec))
3819
GParamSpecDouble *double_spec = G_PARAM_SPEC_DOUBLE (param_spec);
3821
g_object_get (object, param_spec->name, value, NULL);
3823
*lower = double_spec->minimum;
3824
*upper = double_spec->maximum;
3828
g_warning ("%s: property '%s' of %s is not numeric",
3831
g_type_name (G_TYPE_FROM_INSTANCE (object)));
3839
connect_notify (GObject *config,
3840
const gchar *property_name,
3842
gpointer callback_data)
3846
notify_name = g_strconcat ("notify::", property_name, NULL);
3848
g_signal_connect_object (config, notify_name, callback, callback_data, 0);
3850
g_free (notify_name);