From 292cb01fc2416048006d047f6c8cf0c6186aaadd Mon Sep 17 00:00:00 2001 From: Alx Sa Date: Fri, 7 Jun 2024 03:09:43 +0000 Subject: [PATCH] python: Port arguments code to use functions This patch ports the first-party Python plug-ins to use the new argument API. This restores the ability to add dropdown menus from enums and Gimp.Choice parameters, and also allows defaults to be set for custom datatypes like Gegl.Color. --- plug-ins/python/colorxhtml.py | 41 ++--- plug-ins/python/foggify.py | 57 ++---- plug-ins/python/gradients-save-as-css.py | 26 +-- plug-ins/python/histogram-export.py | 81 ++------ plug-ins/python/palette-offset.py | 98 +++------- plug-ins/python/palette-sort.py | 175 ++++++++---------- plug-ins/python/palette-to-gradient.py | 54 ++---- plug-ins/python/spyro-plus.py | 224 +++++++++++------------ plug-ins/python/test-dialog.py | 39 ++-- 9 files changed, 280 insertions(+), 515 deletions(-) diff --git a/plug-ins/python/colorxhtml.py b/plug-ins/python/colorxhtml.py index 6240b8e2d7..cf5ab18d09 100755 --- a/plug-ins/python/colorxhtml.py +++ b/plug-ins/python/colorxhtml.py @@ -265,30 +265,6 @@ def export_colorxhtml(procedure, run_mode, image, file, metadata, config, data): class ColorXhtml(Gimp.PlugIn): - ## Parameters ## - __gproperties__ = { - "source-file":(bool, - _("_Read characters from file, if true, or use text entry"), - _("_Read characters from file, if true, or use text entry"), - False, - GObject.ParamFlags.READWRITE), - "characters": (str, - _("_File to read or characters to use"), - _("_File to read or characters to use"), - "foo", - GObject.ParamFlags.READWRITE), - "font-size": (int, - _("Fo_nt size in pixels"), - _("Fo_nt size in pixels"), - 5, 100, 10, - GObject.ParamFlags.READWRITE), - "separate": (bool, - _("_Write a separate CSS file"), - _("_Write a separate CSS file"), - False, - GObject.ParamFlags.READWRITE) - } - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -314,10 +290,19 @@ class ColorXhtml(Gimp.PlugIn): procedure.set_extensions ("html,xhtml"); - procedure.add_argument_from_property(self, "source-file") - procedure.add_argument_from_property(self, "characters") - procedure.add_argument_from_property(self, "font-size") - procedure.add_argument_from_property(self, "separate") + procedure.add_boolean_argument ("source-file", + _("_Read characters from file, if true, or use text entry"), + _("Read characters from file, if true, or use text entry"), + False, GObject.ParamFlags.READWRITE) + procedure.add_string_argument ("characters", _("_File to read or characters to use"), + _("File to read or characters to use"), + "foo", GObject.ParamFlags.READWRITE) + procedure.add_int_argument ("font-size", _("Fo_nt size in pixels"), + _("Font size in pixels"), 5, 100, 10, + GObject.ParamFlags.READWRITE) + procedure.add_boolean_argument ("separate", _("_Write a separate CSS file"), + _("Write a separate CSS file"), + False, GObject.ParamFlags.READWRITE) return procedure diff --git a/plug-ins/python/foggify.py b/plug-ins/python/foggify.py index af8eb2c817..a7c9ad2a84 100755 --- a/plug-ins/python/foggify.py +++ b/plug-ins/python/foggify.py @@ -31,19 +31,6 @@ def N_(message): return message def _(message): return GLib.dgettext(None, message) def foggify(procedure, run_mode, image, n_drawables, drawables, config, data): - Gegl.init(None) - - _color = Gegl.Color.new("black") - _color.set_rgba(0.94, 0, 0, 1.0) - - # Work around not being able to set default color by only setting it - # when color in our config is None. This won't help when resetting to - # factory default. This also fixes a critical when running without - # changing the color away from None. - color = config.get_property('color') - if color is None: - config.set_property('color', _color) - if run_mode == Gimp.RunMode.INTERACTIVE: GimpUi.init('python-fu-foggify') @@ -105,32 +92,6 @@ def foggify(procedure, run_mode, image, n_drawables, drawables, config, data): return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error()) class Foggify (Gimp.PlugIn): - ## Parameters ## - __gproperties__ = { - "name": (str, - _("Layer _name"), - _("Layer name"), - _("Clouds"), - GObject.ParamFlags.READWRITE), - "turbulence": (float, - _("_Turbulence"), - _("Turbulence"), - 0.0, 7.0, 1.0, - GObject.ParamFlags.READWRITE), - "opacity": (float, - _("O_pacity"), - _("Opacity"), - 0.0, 100.0, 100.0, - GObject.ParamFlags.READWRITE), - } - # I use a different syntax for this property because I think it is - # supposed to allow setting a default, except it doesn't seem to - # work. I still leave it this way for now until we figure this out - # as it should be the better syntax. - color = GObject.Property(type =Gegl.Color, default=None, - nick =_("_Fog color"), - blurb=_("Fog color")) - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -139,6 +100,11 @@ class Foggify (Gimp.PlugIn): return [ 'python-fu-foggify' ] def do_create_procedure(self, name): + Gegl.init(None) + + _color = Gegl.Color.new("black") + _color.set_rgba(0.94, 0.71, 0.27, 1.0) + procedure = Gimp.ImageProcedure.new(self, name, Gimp.PDBProcType.PLUGIN, foggify, None) @@ -154,10 +120,15 @@ class Foggify (Gimp.PlugIn): "1999,2007") procedure.add_menu_path ("/Filters/Decor") - procedure.add_argument_from_property(self, "name") - procedure.add_argument_from_property(self, "color") - procedure.add_argument_from_property(self, "turbulence") - procedure.add_argument_from_property(self, "opacity") + procedure.add_string_argument ("name", _("Layer _name"), _("Layer name"), + _("Clouds"), GObject.ParamFlags.READWRITE) + procedure.add_color_argument ("color", _("_Fog color"), _("_Fog color"), + True, _color, GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("turbulence", _("_Turbulence"), _("Turbulence"), + 0.0, 7.0, 1.0, GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("opacity", _("O_pacity"), _("Opacity"), + 0.0, 100.0, 100.0, GObject.ParamFlags.READWRITE) + return procedure Gimp.main(Foggify.__gtype__, sys.argv) diff --git a/plug-ins/python/gradients-save-as-css.py b/plug-ins/python/gradients-save-as-css.py index f3a20d77bd..2d1fc82d40 100755 --- a/plug-ins/python/gradients-save-as-css.py +++ b/plug-ins/python/gradients-save-as-css.py @@ -177,21 +177,6 @@ def gradient_css_save(procedure, config, data): GLib.Error('File saving failed: {}'.format(file.get_path()))) class GradientsSaveAsCSS (Gimp.PlugIn): - ## Parameters ## - __gproperties__ = { - "run-mode": (Gimp.RunMode, - _("Run mode"), - _("The run mode"), - Gimp.RunMode.NONINTERACTIVE, - GObject.ParamFlags.READWRITE), - "gradient": (Gimp.Gradient, - _("_Gradient to use"), "", - GObject.ParamFlags.READWRITE), - "file": (Gio.File, - _("_File"), None, - GObject.ParamFlags.READWRITE), - } - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -213,9 +198,14 @@ class GradientsSaveAsCSS (Gimp.PlugIn): "2011") procedure.add_menu_path('/Gradients Menu') - procedure.add_argument_from_property(self, "run-mode") - procedure.add_argument_from_property(self, "gradient") - procedure.add_argument_from_property(self, "file") + procedure.add_enum_argument ("run-mode", _("Run mode"), + _("The run mode"), Gimp.RunMode, + Gimp.RunMode.NONINTERACTIVE, + GObject.ParamFlags.READWRITE) + procedure.add_gradient_argument ("gradient", _("_Gradient to use"), + "", GObject.ParamFlags.READWRITE) + procedure.add_file_argument ("file", _("_File"), + "", GObject.ParamFlags.READWRITE) return procedure Gimp.main(GradientsSaveAsCSS.__gtype__, sys.argv) diff --git a/plug-ins/python/histogram-export.py b/plug-ins/python/histogram-export.py index 83c5d6313b..9385c1857d 100644 --- a/plug-ins/python/histogram-export.py +++ b/plug-ins/python/histogram-export.py @@ -87,14 +87,6 @@ class StringEnum: return key raise AttributeError("No such key string " + key) - -OUTPUT_FORMAT_LABELS = (_("Pixel count"), _("Normalized"), _("Percent")) -output_format_enum = StringEnum( - "pixel count", OUTPUT_FORMAT_LABELS[0], - "normalized", OUTPUT_FORMAT_LABELS[1], - "percent", OUTPUT_FORMAT_LABELS[2] -) - def histogram_export(procedure, img, layers, gio_file, bucket_size, sample_average, output_format): layers = img.list_selected_layers() @@ -139,12 +131,12 @@ def histogram_export(procedure, img, layers, gio_file, histo_config.set_property('channel', channel) result = histo_proc.run(histo_config) - if output_format == output_format_enum.pixel_count: + if output_format == "pixel-count": count = int(result.index(5)) else: pixels = result.index(4) count = (result.index(5) / pixels) if pixels else 0 - if output_format == output_format_enum.percent: + if output_format == "percent": count = "%.2f%%" % (count * 100) row.append(str(count)) writer.writerow(row) @@ -177,30 +169,7 @@ def run(procedure, run_mode, image, n_layers, layers, config, data): GimpUi.init("histogram-export.py") dialog = GimpUi.ProcedureDialog.new(procedure, config, _("Histogram Export...")) - vbox = dialog.fill_box ("histogram-box", ["file", "bucket-size", "sample-average"]) - - #TODO: For now, we'll manually create a GimpStringComboBox - #for the GUI version of 'output-format'. Once we can - #use Gimp.Choice in Python, we can replace the str - #parameter without changing any third-party function calls - hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) - vbox.pack_start(hbox, False, False, 0) - hbox.set_visible(True) - - label = Gtk.Label.new_with_mnemonic(_("Output _format")) - hbox.pack_start(label, False, False, 0) - label.set_visible(True) - - output_format_store = store = Gtk.ListStore(str, str) - output_format_store.append(["pixel count", OUTPUT_FORMAT_LABELS[0]]) - output_format_store.append(["normalized", OUTPUT_FORMAT_LABELS[1]]) - output_format_store.append(["percent", OUTPUT_FORMAT_LABELS[2]]) - - combo = GimpUi.prop_string_combo_box_new (config, "output-format", output_format_store, 0, 1) - hbox.pack_start(combo, False, False, 0) - combo.set_visible(True) - - dialog.fill(["histogram-box"]) + dialog.fill() if not dialog.run(): return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, @@ -223,32 +192,6 @@ def run(procedure, run_mode, image, n_layers, layers, config, data): class HistogramExport(Gimp.PlugIn): - - ## Parameters ## - __gproperties__ = { - # TODO: GFile props still don't have labels + only load existing files - # (here we likely want to create a new file). - "file": (Gio.File, - _("Histogram File"), - "Histogram export file", - GObject.ParamFlags.READWRITE), - "bucket-size": (float, - _("_Bucket Size"), - "Bucket Size", - 0.001, 1.0, 0.01, - GObject.ParamFlags.READWRITE), - "sample-average": (bool, - _("Sample _Average"), - "Sample Average", - False, - GObject.ParamFlags.READWRITE), - "output-format": (str, - _("Output _format"), - "Output format: 'pixel count', 'normalized', 'percent'", - "pixel count", - GObject.ParamFlags.READWRITE), - } - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -274,10 +217,20 @@ class HistogramExport(Gimp.PlugIn): "2014") procedure.add_menu_path("/Colors/Info/") - procedure.add_argument_from_property(self, "file") - procedure.add_argument_from_property(self, "bucket-size") - procedure.add_argument_from_property(self, "sample-average") - procedure.add_argument_from_property(self, "output-format") + # TODO: GFile props still don't have labels + only load existing files + # (here we likely want to create a new file). + procedure.add_file_argument ("file", _("Histogram File"), + _("Histogram export file"), GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("bucket-size", _("_Bucket Size"), _("Bucket Size"), + 0.001, 1.0, 0.01, GObject.ParamFlags.READWRITE) + procedure.add_boolean_argument ("sample-average", _("Sample _Average"), _("Sample Average"), + False, GObject.ParamFlags.READWRITE) + choice = Gimp.Choice.new() + choice.add("pixel-count", 0, _("Pixel Count"), "") + choice.add("normalized", 1, _("Normalized"), "") + choice.add("percent", 2, _("Percent"), "") + procedure.add_choice_argument ("output-format", _("Output _format"), _("Output format"), + choice, "percent", GObject.ParamFlags.READWRITE) return procedure diff --git a/plug-ins/python/palette-offset.py b/plug-ins/python/palette-offset.py index fbe10630ce..c5048fbed4 100644 --- a/plug-ins/python/palette-offset.py +++ b/plug-ins/python/palette-offset.py @@ -33,52 +33,6 @@ otherwise copies the given palette and returns it. """ class PaletteOffset (Gimp.PlugIn): - ## Parameter: run-mode ## - @GObject.Property(type=Gimp.RunMode, - default=Gimp.RunMode.NONINTERACTIVE, - nick="Run mode", blurb="The run mode") - def run_mode(self): - """Read-write integer property.""" - return self._run_mode - - @run_mode.setter - def run_mode(self, run_mode): - self._run_mode = run_mode - - ## Parameter: palette ## - @GObject.Property(type=Gimp.Palette, - nick= _("Palette"), - blurb= _("Palette")) - def palette(self): - return self._palette - - @palette.setter - def palette(self, palette): - self._palette = palette - - ## Parameter: amount ## - @GObject.Property(type=int, - default=1, - nick= _("Off_set"), - blurb= _("Offset")) - def amount(self): - return self._amount - - @amount.setter - def amount(self, amount): - self._amount = amount - - ## Return: new-palette ## - @GObject.Property(type=Gimp.Palette, - nick=_("The edited palette"), - blurb=_("The newly created palette when read-only, otherwise the input palette")) - def new_palette(self): - return self.new_palette - - @new_palette.setter - def new_palette(self, new_palette): - self.new_palette = new_palette - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -98,10 +52,18 @@ class PaletteOffset (Gimp.PlugIn): procedure.set_attribution("Joao S. O. Bueno Calligaris, Carol Spears", "(c) Joao S. O. Bueno Calligaris", "2004, 2006") - procedure.add_argument_from_property(self, "run-mode") - procedure.add_argument_from_property(self, "palette") - procedure.add_argument_from_property(self, "amount") - procedure.add_return_value_from_property(self, "new-palette") + procedure.add_enum_argument ("run-mode", _("Run mode"), + _("The run mode"), Gimp.RunMode, + Gimp.RunMode.NONINTERACTIVE, + GObject.ParamFlags.READWRITE) + procedure.add_palette_argument ("palette", _("_Palette"), + _("Palette"), + GObject.ParamFlags.READWRITE) + procedure.add_int_argument ("amount", _("O_ffset"), _("Offset"), + 1, GLib.MAXINT, 1, GObject.ParamFlags.READWRITE) + procedure.add_palette_return_value ("new-palette", _("The edited palette"), + _("The newly created palette when read-only, otherwise the input palette"), + GObject.ParamFlags.READWRITE) procedure.add_menu_path ('/Palettes Menu') else: procedure = None @@ -128,34 +90,16 @@ class PaletteOffset (Gimp.PlugIn): GimpUi.init ("palette-offset.py") - use_header_bar = Gtk.Settings.get_default().get_property("gtk-dialogs-use-header") - dialog = GimpUi.Dialog(use_header_bar=use_header_bar, - title=_("Offset Palette...")) + dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config) + dialog.fill(["palette", "amount"]) + if not dialog.run(): + dialog.destroy() + return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, GLib.Error()) + else: + dialog.destroy() - dialog.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL) - dialog.add_button(_("_OK"), Gtk.ResponseType.OK) - - box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, - homogeneous=False, spacing=12) - dialog.get_content_area().add(box) - box.show() - - label = Gtk.Label.new(_("Offset")) - box.pack_start(label, False, False, 1) - label.show() - - amount = self.set_property("amount", amount) - spin = GimpUi.prop_spin_button_new(self, "amount", 1.0, 5.0, 0) - spin.set_activates_default(True) - box.pack_end(spin, False, False, 1) - spin.show() - - dialog.show() - if dialog.run() != Gtk.ResponseType.OK: - return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, - GLib.Error("Canceled")) - amount = self.get_property("amount") - config.set_property("palette", None) + amount = config.get_property("amount") + palette = config.get_property("palette") #If palette is read only, work on a copy: editable = palette.is_editable() diff --git a/plug-ins/python/palette-sort.py b/plug-ins/python/palette-sort.py index 9b9ab18989..dd746b0821 100755 --- a/plug-ins/python/palette-sort.py +++ b/plug-ins/python/palette-sort.py @@ -77,12 +77,6 @@ GRAIN_SCALE = (1.0, 1.0 , 1.0, 100., 256., 256., 256., 360.,) -SELECT_ALL = 0 -SELECT_SLICE = 1 -SELECT_AUTOSLICE = 2 -SELECT_PARTITIONED = 3 -SELECTIONS = (SELECT_ALL, SELECT_SLICE, SELECT_AUTOSLICE, SELECT_PARTITIONED) - try: from colormath.color_objects import RGBColor, LabColor, LCHabColor @@ -222,7 +216,7 @@ def palette_sort(palette, selection, slice_expr, channel1, ascending1, num_colors = palette.get_color_count() start, nrows, length = None, None, None - if selection == SELECT_AUTOSLICE: + if selection == "auto-slice": def find_index(color, startindex=0): for i in range(startindex, num_colors): c = palette.entry_get_color(i) @@ -262,9 +256,9 @@ def palette_sort(palette, selection, slice_expr, channel1, ascending1, except ValueError: # bad expression is okay here, just assume one row nrows = 1 - # remaining behavior is implemented by SELECT_SLICE 'inheritance'. - selection = SELECT_SLICE - elif selection in (SELECT_SLICE, SELECT_PARTITIONED): + # remaining behavior is implemented by "slice-array" 'inheritance'. + selection = "slice-array" + elif selection in ("slice-array", "partitioned"): start, nrows, length = parse_slice(slice_expr, num_colors) channels_getter_1 = channel_getters[channel1] @@ -283,14 +277,15 @@ def palette_sort(palette, selection, slice_expr, channel1, ascending1, result.append((index, entry)) return result - if selection == SELECT_ALL: + print (selection) + if selection == "all": entry_list = get_colors(0, num_colors) entry_list.sort(key=lambda v: v[0]) for i in range(num_colors): palette.entry_set_name(i, entry_list[i][1][0]) palette.entry_set_color(i, entry_list[i][1][1]) - elif selection == SELECT_PARTITIONED: + elif selection == "partitioned": if num_colors < (start + length * nrows) - 1: raise ValueError('Not enough entries in palette to ' 'sort complete rows! Got %d, expected >=%d' % @@ -313,13 +308,13 @@ def palette_sort(palette, selection, slice_expr, channel1, ascending1, old_partition = this_partition base = rowstart for size in partition_spans: - palette_sort(palette, SELECT_SLICE, '%d:1,%d' % (base, size), + palette_sort(palette, "slice-array", '%d:1,%d' % (base, size), channel1, ascending1, channel2, ascending2, quantize, 0, 1.0) base += size else: - # SELECT_SLICE and SELECT_AUTOSLICE + # "slice-array" and "auto-slice" stride = length if num_colors < (start + stride * nrows) - 1: raise ValueError('Not enough entries in palette to sort ' @@ -348,74 +343,7 @@ You can optionally install colormath (https://pypi.python.org/pypi/colormath/1.0 to GIMP's Python to get even more channels to choose from. """ -selections_option = [ _("All"), _("Slice / Array"), _("Autoslice (fg->bg)"), _("Partitioned") ] class PaletteSort (Gimp.PlugIn): - ## Parameters ## - __gproperties__ = { - "run-mode": (Gimp.RunMode, - _("Run mode"), - "The run mode", - Gimp.RunMode.INTERACTIVE, - GObject.ParamFlags.READWRITE), - "palette": (Gimp.Palette, - _("_Palette"), - _("Palette"), - GObject.ParamFlags.READWRITE), - "selections": (int, - _("Select_ions"), - str(selections_option), - 0, 3, 0, - GObject.ParamFlags.READWRITE), - # TODO: It would be much simpler to replace the slice expression with three - # separate parameters: start-index, number-of-rows, row_length - "slice_expr": (str, - _("Slice _expression"), - slice_expr_doc, - "", - GObject.ParamFlags.READWRITE), - "channel1": (int, - _("Channel _to sort"), - "Channel to sort: " + str(AVAILABLE_CHANNELS), - 0, len(AVAILABLE_CHANNELS), 3, - GObject.ParamFlags.READWRITE), - "ascending1": (bool, - _("_Ascending"), - _("Ascending"), - True, - GObject.ParamFlags.READWRITE), - "channel2": (int, - _("Secondary C_hannel to sort"), - "Secondary Channel to sort: " + str(AVAILABLE_CHANNELS), - 0, len(AVAILABLE_CHANNELS), 5, - GObject.ParamFlags.READWRITE), - "ascending2": (bool, - _("Ascen_ding"), - _("Ascending"), - True, - GObject.ParamFlags.READWRITE), - "quantize": (float, - _("_Quantization"), - _("Quantization"), - 0.0, 1.0, 0.0, - GObject.ParamFlags.READWRITE), - "pchannel": (int, - _("Partitionin_g channel"), - "Partitioning channel: " + str(AVAILABLE_CHANNELS), - 0, len(AVAILABLE_CHANNELS), 3, - GObject.ParamFlags.READWRITE), - "pquantize": (float, - _("Partition q_uantization"), - _("Partition quantization"), - 0.0, 1.0, 0.0, - GObject.ParamFlags.READWRITE), - - # Returned value - "new_palette": (Gimp.Palette, - _("Palette"), - _("Palette"), - GObject.ParamFlags.READWRITE), - } - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -440,18 +368,53 @@ class PaletteSort (Gimp.PlugIn): "2006-2014") procedure.add_menu_path ('/Palettes Menu') - procedure.add_argument_from_property(self, "run-mode") - procedure.add_argument_from_property(self, "palette") - procedure.add_argument_from_property(self, "selections") - procedure.add_argument_from_property(self, "slice_expr") - procedure.add_argument_from_property(self, "channel1") - procedure.add_argument_from_property(self, "ascending1") - procedure.add_argument_from_property(self, "channel2") - procedure.add_argument_from_property(self, "ascending2") - procedure.add_argument_from_property(self, "quantize") - procedure.add_argument_from_property(self, "pchannel") - procedure.add_argument_from_property(self, "pquantize") - procedure.add_return_value_from_property(self, "new_palette") + procedure.add_enum_argument ("run-mode", _("Run mode"), + _("The run mode"), Gimp.RunMode, + Gimp.RunMode.INTERACTIVE, + GObject.ParamFlags.READWRITE) + procedure.add_palette_argument ("palette", _("_Palette"), + _("Palette"), + GObject.ParamFlags.READWRITE) + + selection_choice = Gimp.Choice.new() + selection_choice.add("all", 0, _("All"), "") + selection_choice.add("slice-array", 1, _("Slice / Array"), "") + selection_choice.add("auto-slice", 2, _("Autoslice (fg->bg)"), "") + selection_choice.add("partitioned", 3, _("Partitioned"), "") + procedure.add_choice_argument ("selections", _("Select_ions"), _("Selections"), + selection_choice, "all", GObject.ParamFlags.READWRITE) + # TODO: It would be much simpler to replace the slice expression with three + # separate parameters: start-index, number-of-rows, row_length + procedure.add_string_argument ("slice-expr", _("Slice _expression"), + slice_expr_doc, "", + GObject.ParamFlags.READWRITE) + channel_choice = Gimp.Choice.new() + self.add_choices (channel_choice) + procedure.add_choice_argument ("channel1", _("Channel _to sort"), _("Channel to sort"), + channel_choice, "luma", GObject.ParamFlags.READWRITE) + procedure.add_boolean_argument ("ascending1", _("_Ascending"), _("Ascending"), + True, GObject.ParamFlags.READWRITE) + channel_choice2 = Gimp.Choice.new() + self.add_choices (channel_choice2) + procedure.add_choice_argument ("channel2", _("Secondary C_hannel to sort"), + _("Secondary Channel to sort"), channel_choice2, + "saturation", GObject.ParamFlags.READWRITE) + procedure.add_boolean_argument ("ascending2", _("Ascen_ding"), _("Ascending"), + True, GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("quantize", _("_Quantization"), + _("Quantization"), 0.0, 1.0, 0.0, + GObject.ParamFlags.READWRITE) + pchannel_choice = Gimp.Choice.new() + self.add_choices (pchannel_choice) + procedure.add_choice_argument ("pchannel", _("Partitionin_g channel"), + _("Partitioning channel"), pchannel_choice, + "luma", GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("pquantize", _("Partition q_uantization"), + _("Partition quantization"), 0.0, 1.0, 0.0, + GObject.ParamFlags.READWRITE) + + procedure.add_palette_return_value ("new-palette", _("Palette"), + _("Palette"), GObject.ParamFlags.READWRITE) return procedure @@ -478,13 +441,9 @@ class PaletteSort (Gimp.PlugIn): dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config) dialog.fill (["palette"]) - dialog.get_int_combo("selections", GimpUi.IntStore.new (selections_option)) dialog.fill (["selections","slice-expr"]) - dialog.get_int_combo("channel1", GimpUi.IntStore.new (AVAILABLE_CHANNELS)) dialog.fill (["channel1", "ascending1"]) - dialog.get_int_combo("channel2", GimpUi.IntStore.new (AVAILABLE_CHANNELS)) dialog.fill (["channel2","ascending2", "quantize"]) - dialog.get_int_combo("pchannel", GimpUi.IntStore.new (AVAILABLE_CHANNELS)) dialog.fill (["pchannel","pquantize"]) if not dialog.run(): @@ -495,13 +454,13 @@ class PaletteSort (Gimp.PlugIn): palette = config.get_property("palette") selection = config.get_property("selections") - slice_expr = config.get_property ("slice_expr") - channel1 = config.get_property("channel1") + slice_expr = config.get_property("slice-expr") + channel1 = config.get_choice_id("channel1") ascending1 = config.get_property ("ascending1") - channel2 = config.get_property("channel2") + channel2 = config.get_choice_id("channel2") ascending2 = config.get_property ("ascending2") quantize = config.get_property ("quantize") - pchannel = config.get_property("pchannel") + pchannel = config.get_choice_id("pchannel") pquantize = config.get_property ("pquantize") try: new_palette = palette_sort(palette, selection, slice_expr, channel1, ascending1, @@ -516,4 +475,18 @@ class PaletteSort (Gimp.PlugIn): return_val.insert(1, value) return return_val + def add_choices (self, choice): + #TODO: Re-incorporate LAB and LCHab options with GeglColor + choice.add("red", 0, _("Red"), "") + choice.add("green", 1, _("Green"), "") + choice.add("blue", 2, _("Blue"), "") + choice.add("luma", 3, _("Luma (Y)"), "") + choice.add("hue", 4, _("Hue"), "") + choice.add("saturation", 5, _("Saturation"), "") + choice.add("value", 6, _("Value"), "") + choice.add("saturation-hsl", 7, _("Saturation (HSL)"), "") + choice.add("lightness-hsl", 8, _("Lightness (HSL)"), "") + choice.add("index", 9, _("Index"), "") + choice.add("random", 10, _("Random"), "") + Gimp.main(PaletteSort.__gtype__, sys.argv) diff --git a/plug-ins/python/palette-to-gradient.py b/plug-ins/python/palette-to-gradient.py index 471cc279db..0f5cb1ca2f 100644 --- a/plug-ins/python/palette-to-gradient.py +++ b/plug-ins/python/palette-to-gradient.py @@ -111,43 +111,6 @@ def run(procedure, config, data): return retval class PaletteToGradient (Gimp.PlugIn): - ## Parameter: run mode ## - @GObject.Property(type=Gimp.RunMode, - default=Gimp.RunMode.NONINTERACTIVE, - nick="Run mode", blurb="The run mode") - def run_mode(self): - '''The run mode (unused)''' - return self.runmode - - @run_mode.setter - def run_mode(self, runmode): - self.runmode = runmode - - ## Parameter: palette ## - @GObject.Property(type=Gimp.Palette, - default=None, - nick= _("_Palette")) - def palette(self): - '''Palette or None for the currently selected palette''' - return self.palette - - @palette.setter - def palette(self, palette): - self.palette = palette - - ## Properties: return values ## - @GObject.Property(type=Gimp.Gradient, - default="", - nick=_("The newly created gradient"), - blurb=_("The newly created gradient")) - def new_gradient(self): - """Read-write integer property.""" - return self.new_gradient - - @new_gradient.setter - def new_gradient(self, new_gradient): - self.new_gradient = new_gradient - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -176,12 +139,17 @@ class PaletteToGradient (Gimp.PlugIn): if procedure is not None: procedure.set_attribution("Carol Spears, reproduced from previous work by Adrian Likins and Jeff Trefftz", "Carol Spears", "2006") - # We don't build a GParamSpec ourselves because passing it - # around is apparently broken in Python. Hence this trick. - # See pygobject#227 - procedure.add_argument_from_property(self, "run-mode") - procedure.add_argument_from_property(self, "palette") - procedure.add_return_value_from_property(self, "new-gradient") + + procedure.add_enum_argument ("run-mode", _("Run mode"), + _("The run mode"), Gimp.RunMode, + Gimp.RunMode.NONINTERACTIVE, + GObject.ParamFlags.READWRITE) + procedure.add_palette_argument ("palette", _("_Palette"), + _("Palette"), + GObject.ParamFlags.READWRITE) + procedure.add_gradient_return_value ("new-gradient", _("The newly created gradient"), + _("The newly created gradient"), + GObject.ParamFlags.READWRITE) procedure.add_menu_path ('/Palettes Menu') diff --git a/plug-ins/python/spyro-plus.py b/plug-ins/python/spyro-plus.py index ed0886c62a..77ea966638 100755 --- a/plug-ins/python/spyro-plus.py +++ b/plug-ins/python/spyro-plus.py @@ -480,10 +480,15 @@ class SelectionShape(Shape): return x + dist * cos(perpendicular), y + dist * sin(perpendicular) -shapes = [ - CircleShape(), RackShape(), FrameShape(), SelectionShape(), - PolygonShape(), SineShape(), BumpShape() -] +shapes = { + "circle": CircleShape(), + "rack": RackShape(), + "frame": FrameShape(), + "selection": SelectionShape(), + "polygon-star": PolygonShape(), + "sine": SineShape(), + "bumps": BumpShape() +} ### Tools @@ -651,16 +656,18 @@ class SaveToPathTool(): control_points, False) -tools = [ - PreviewTool(), - StrokePaintTool(_("PaintBrush"), "gimp-paintbrush"), - PencilTool(), AirBrushTool(), StrokeTool(), - StrokePaintTool(_("Ink"), 'gimp-ink'), - StrokePaintTool(_("MyPaintBrush"), 'gimp-mybrush') +tools = { + "preview": PreviewTool(), + "paintbrush": StrokePaintTool(_("PaintBrush"), "gimp-paintbrush"), + "penciltool": PencilTool(), + "airbrush": AirBrushTool(), + "stroke": StrokeTool(), + "ink": StrokePaintTool(_("Ink"), 'gimp-ink'), + "mypaintbrush": StrokePaintTool(_("MyPaintBrush"), 'gimp-mybrush') # Clone does not work properly when an image is not set. When that happens, drawing fails, and # I am unable to catch the error. This causes the plugin to crash, and subsequent problems with undo. # StrokePaintTool("Clone", 'gimp-clone', False) -] +} class PatternParameters: @@ -671,7 +678,7 @@ class PatternParameters: """ def __init__(self): if not hasattr(self, 'curve_type'): - self.curve_type = 0 + self.curve_type = "spyrograph" # Pattern if not hasattr(self, 'pattern_notation'): @@ -710,7 +717,7 @@ class PatternParameters: # Shape if not hasattr(self, 'shape_index'): - self.shape_index = 0 # Index in the shapes array + self.shape_index = "circle" # Index in the shapes array if not hasattr(self, 'sides'): self.sides = 5 if not hasattr(self, 'morph'): @@ -725,7 +732,7 @@ class PatternParameters: # Drawing style if not hasattr(self, 'tool_index'): - self.tool_index = 0 # Index in the tools array. + self.tool_index = "preview" # Index in the tools array. if not hasattr(self, 'long_gradient'): self.long_gradient = False @@ -1029,7 +1036,12 @@ class LissaCurveType: return False -curve_types = [SpyroCurveType(), EpitrochoidCurvetype(), SineCurveType(), LissaCurveType()] +curve_types = { + "spyrograph": SpyroCurveType(), + "epitrochoid": EpitrochoidCurvetype(), + "sine": SineCurveType(), + "lissajous": LissaCurveType() +} # Drawing engine. Also implements drawing incrementally. # We don't draw the entire stroke, because it could take several seconds, @@ -1434,10 +1446,14 @@ class SpyroWindow(): myscale.spin.set_width_chars(6) return adj, myscale - def set_combo_in_table(txt_list, table, row, callback): + def set_combo_in_table(txt_list, is_dictionary, table, row, callback): combo = Gtk.ComboBoxText.new() - for txt in txt_list: - combo.append_text(_(txt)) + if (is_dictionary == False): + for txt in txt_list: + combo.append_text(_(txt)) + else: + for key in txt_list: + combo.append (key, txt_list[key].name) combo.set_halign(Gtk.Align.FILL) table.attach(combo, 1, row, 1, 1) @@ -1455,14 +1471,14 @@ class SpyroWindow(): row = 0 label_in_table(_("Curve Type"), table, row, _("An Epitrochoid pattern is when the moving gear is on the outside of the fixed gear.")) - self.curve_type_combo = set_combo_in_table([ct.name for ct in curve_types], table, row, + self.curve_type_combo = set_combo_in_table(curve_types, True, table, row, self.curve_type_changed) row += 1 label_in_table(_("Tool"), table, row, _("The tool with which to draw the pattern. " "The Preview tool just draws quickly.")) - self.tool_combo = set_combo_in_table([tool.name for tool in tools], table, row, + self.tool_combo = set_combo_in_table(tools, True, table, row, self.tool_combo_changed) self.long_gradient_checkbox = Gtk.CheckButton(label=_("Long Gradient")) @@ -1545,12 +1561,12 @@ class SpyroWindow(): row = 0 label_in_table(_("Fixed Gear Teeth"), kit_table, row, fixed_gear_tooltip) - self.kit_outer_teeth_combo = set_combo_in_table([str(t) for t in ring_teeth], kit_table, row, + self.kit_outer_teeth_combo = set_combo_in_table([str(t) for t in ring_teeth], False, kit_table, row, self.kit_outer_teeth_combo_changed) row += 1 label_in_table(_("Moving Gear Teeth"), kit_table, row, moving_gear_tooltip) - self.kit_inner_teeth_combo = set_combo_in_table([str(t) for t in wheel_teeth], kit_table, row, + self.kit_inner_teeth_combo = set_combo_in_table([str(t) for t in wheel_teeth], False, kit_table, row, self.kit_inner_teeth_combo_changed) row += 1 @@ -1667,7 +1683,7 @@ class SpyroWindow(): "Frame hugs the boundaries of the rectangular selection, " "use hole=100 in Gear notation to touch boundary. " "Selection will hug boundaries of current selection - try something non-rectangular.")) - self.shape_combo = set_combo_in_table([shape.name for shape in shapes], table, row, + self.shape_combo = set_combo_in_table(shapes, True, table, row, self.shape_combo_changed) row += 1 @@ -1733,7 +1749,7 @@ class SpyroWindow(): row = 0 label_in_table(_("Save"), table, row, _("Choose whether to save as new layer, redraw on last active layer, or save to path")) - self.save_option_combo = set_combo_in_table(save_options, table, row, + self.save_option_combo = set_combo_in_table(save_options, False, table, row, self.save_option_changed) self.save_option_combo.show() @@ -1918,7 +1934,7 @@ class SpyroWindow(): def update_view(self): """ Update the UI to reflect the values in the Pattern Parameters. """ - self.curve_type_combo.set_active(self.p.curve_type) + self.curve_type_combo.set_active_id(self.p.curve_type) self.curve_type_side_effects() self.pattern_notebook.set_current_page(pattern_notation_page[self.p.pattern_notation]) @@ -1941,7 +1957,7 @@ class SpyroWindow(): self.doughnut.set_width(self.p.doughnut_width) self.petals_changed_side_effects() - self.shape_combo.set_active(self.p.shape_index) + self.shape_combo.set_active_id(self.p.shape_index) self.shape_combo_side_effects() self.sides_adj.set_value(self.p.sides) self.morph_adj.set_value(self.p.morph) @@ -1949,7 +1965,7 @@ class SpyroWindow(): self.shape_rotation_adj.set_value(self.p.shape_rotation) self.margin_adj.set_value(self.p.margin_pixels) - self.tool_combo.set_active(self.p.tool_index) + self.tool_combo.set_active_id(self.p.tool_index) self.long_gradient_checkbox.set_active(self.p.long_gradient) self.save_option_combo.set_active(self.p.save_option) @@ -1987,7 +2003,7 @@ class SpyroWindow(): self.doughnut_width_myscale.set_sensitive(False) def curve_type_changed(self, val): - self.p.curve_type = val.get_active() + self.p.curve_type = val.get_active_id() self.curve_type_side_effects() self.redraw() @@ -2086,7 +2102,7 @@ class SpyroWindow(): self.equal_w_h_checkbox.set_sensitive(shapes[self.p.shape_index].can_equal_w_h()) def shape_combo_changed(self, val): - self.p.shape_index = val.get_active() + self.p.shape_index = val.get_active_id() self.shape_combo_side_effects() self.redraw() @@ -2116,7 +2132,7 @@ class SpyroWindow(): self.long_gradient_checkbox.set_sensitive(tools[self.p.tool_index].can_color) def tool_combo_changed(self, val): - self.p.tool_index = val.get_active() + self.p.tool_index = val.get_active_id() self.tool_changed_side_effects() self.redraw() @@ -2204,80 +2220,6 @@ class SpyroWindow(): class SpyrogimpPlusPlugin(Gimp.PlugIn): - - ## Parameters ## - __gproperties__ = { - "curve-type" : (int, - _("The curve type { Spyrograph (0), Epitrochoid (1), Sine (2), Lissajous(3) }"), - _("The curve type { Spyrograph (0), Epitrochoid (1), Sine (2), Lissajous(3) }"), - 0, 3, 0, - GObject.ParamFlags.READWRITE), - "shape": (int, - _("Shape of fixed gear"), - _("Shape of fixed gear"), - 0, GLib.MAXINT, 0, - GObject.ParamFlags.READWRITE), - "sides": (int, - _("Number of sides of fixed gear (3 or greater). Only used by some shapes."), - _("Number of sides of fixed gear (3 or greater). Only used by some shapes."), - 3, GLib.MAXINT, 3, - GObject.ParamFlags.READWRITE), - "morph": (float, - _("Morph shape of fixed gear, between 0 and 1. Only used by some shapes."), - _("Morph shape of fixed gear, between 0 and 1. Only used by some shapes."), - 0.0, 1.0, 0.0, - GObject.ParamFlags.READWRITE), - "fixed-teeth": (int, - _("Number of teeth for fixed gear"), - _("Number of teeth for fixed gear"), - 0, GLib.MAXINT, 96, - GObject.ParamFlags.READWRITE), - "moving-teeth": (int, - _("Number of teeth for moving gear"), - _("Number of teeth for moving gear"), - 0, GLib.MAXINT, 36, - GObject.ParamFlags.READWRITE), - "hole-percent": (float, - _("Location of hole in moving gear in percent, where 100 means that " - "the hole is at the edge of the gear, and 0 means the hole is at the center"), - _("Location of hole in moving gear in percent, where 100 means that " - "the hole is at the edge of the gear, and 0 means the hole is at the center"), - 0.0, 100.0, 100.0, - GObject.ParamFlags.READWRITE), - "margin": (int, - _("Margin from selection, in pixels"), - _("Margin from selection, in pixels"), - 0, GLib.MAXINT, 0, - GObject.ParamFlags.READWRITE), - "equal-w-h": (bool, - _("Make height and width equal"), - _("Make height and width equal"), - False, - GObject.ParamFlags.READWRITE), - "pattern-rotation": (float, - _("Pattern rotation, in degrees"), - _("Pattern rotation, in degrees"), - -360.0, 360.0, 0.0, - GObject.ParamFlags.READWRITE), - "shape-rotation": (float, - _("Shape rotation of fixed gear, in degrees"), - _("Shape rotation of fixed gear, in degrees"), - -360.0, 360.0, 0.0, - GObject.ParamFlags.READWRITE), - "tool": (int, - _("Tool to use for drawing the pattern."), - _("Tool to use for drawing the pattern."), - 0, GLib.MAXINT, 1, - GObject.ParamFlags.READWRITE), - "long-gradient" : (bool, - _("Whether to apply a long gradient to match the length of the pattern. " - "Only applicable to some of the tools."), - _("Whether to apply a long gradient to match the length of the pattern. " - "Only applicable to some of the tools."), - False, - GObject.ParamFlags.READWRITE), - } - ## GimpPlugIn virtual methods ## def do_set_i18n(self, procname): return True, 'gimp30-python', None @@ -2302,19 +2244,67 @@ class SpyrogimpPlusPlugin(Gimp.PlugIn): "2018") procedure.add_menu_path ("/Filters/Render/") - procedure.add_argument_from_property(self, "curve-type") - procedure.add_argument_from_property(self, "shape") - procedure.add_argument_from_property(self, "sides") - procedure.add_argument_from_property(self, "morph") - procedure.add_argument_from_property(self, "fixed-teeth") - procedure.add_argument_from_property(self, "moving-teeth") - procedure.add_argument_from_property(self, "hole_percent") - procedure.add_argument_from_property(self, "margin") - procedure.add_argument_from_property(self, "equal-w-h") - procedure.add_argument_from_property(self, "pattern-rotation") - procedure.add_argument_from_property(self, "shape-rotation") - procedure.add_argument_from_property(self, "tool") - procedure.add_argument_from_property(self, "long-gradient") + curve_choice = Gimp.Choice.new() + curve_choice.add("spyrograph", 0, _("Spyrograph"), "") + curve_choice.add("epitrochoid", 1, _("Epitrochoid"), "") + curve_choice.add("sine", 2, _("Sine"), "") + curve_choice.add("lissajous", 3, _("Lissajous"), "") + procedure.add_choice_argument ("curve-type", _("Curve Type"), _("Curve Type"), + curve_choice, "spyrograph", GObject.ParamFlags.READWRITE) + shape_choice = Gimp.Choice.new() + shape_choice.add("circle", 0, _("Circle"), "") + shape_choice.add("rack", 1, _("rack"), "") + shape_choice.add("frame", 2, _("frame"), "") + shape_choice.add("selection", 3, _("Selection"), "") + shape_choice.add("polygon-star", 4, _("Polygon-Star"), "") + shape_choice.add("sine", 5, _("Sine"), "") + shape_choice.add("bumps", 6, _("Bumps"), "") + procedure.add_choice_argument ("shape", _("Shape"), _("Shape"), + shape_choice, "circle", GObject.ParamFlags.READWRITE) + procedure.add_int_argument ("sides", _("Si_des"), + _("Number of sides of fixed gear (3 or greater). Only used by some shapes."), + 3, GLib.MAXINT, 3, GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("morph", _("_Morph"), + _("Morph shape of fixed gear, between 0 and 1. Only used by some shapes."), + 0.0, 1.0, 0.0, GObject.ParamFlags.READWRITE) + procedure.add_int_argument ("fixed-teeth", _("Fi_xed Gear Teeth"), + _("Number of teeth for fixed gear."), + 0, GLib.MAXINT, 96, GObject.ParamFlags.READWRITE) + procedure.add_int_argument ("moving-teeth", _("Mo_ving Gear Teeth"), + _("Number of teeth for fixed gear."), + 0, GLib.MAXINT, 36, GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("hole_percent", _("_Hole Radius (%)"), + _("Location of hole in moving gear in percent, where 100 means that " + "the hole is at the edge of the gear, and 0 means the hole is at the center"), + 0.0, 100.0, 100.0, GObject.ParamFlags.READWRITE) + procedure.add_int_argument ("margin", _("Margin (_px)"), + _("Margin from selection, in pixels"), + 0, GLib.MAXINT, 0, GObject.ParamFlags.READWRITE) + procedure.add_boolean_argument ("equal-w-h", _("Make width and height equal"), + _("Make width and height equal"), + False, GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("pattern-rotation", _("_Rotation"), + _("Pattern rotation, in degrees"), + -360.0, 360.0, 0.0, GObject.ParamFlags.READWRITE) + procedure.add_double_argument ("shape-rotation", _("_Rotation"), + _("Shape rotation of fixed gear, in degrees"), + -360.0, 360.0, 0.0, GObject.ParamFlags.READWRITE) + tool_choice = Gimp.Choice.new() + tool_choice.add("preview", 0, _("Preview"), "") + tool_choice.add("paintbrush", 1, _("PaintBrush"), "") + tool_choice.add("pencil", 2, _("Pencil"), "") + tool_choice.add("airbrush", 3, _("AirBrush"), "") + tool_choice.add("stroke", 4, _("Stroke"), "") + tool_choice.add("ink", 5, _("Ink"), "") + tool_choice.add("mypaintbrush", 6, _("MyPaintBrush"), "") + #TODO: Add Clone option once it's fixed + procedure.add_choice_argument ("tool", _("Tool"), _("Tool"), + tool_choice, "preview", GObject.ParamFlags.READWRITE) + procedure.add_boolean_argument ("long-gradient", + _("Long _Gradient"), + _("Whether to apply a long gradient to match the length of the pattern. " + "Only applicable to some of the tools."), + False, GObject.ParamFlags.READWRITE) return procedure diff --git a/plug-ins/python/test-dialog.py b/plug-ins/python/test-dialog.py index d48fd0f6c2..b6e21e6961 100644 --- a/plug-ins/python/test-dialog.py +++ b/plug-ins/python/test-dialog.py @@ -26,6 +26,8 @@ from gi.repository import Gio import time import sys +def N_(message): return message +def _(message): return GLib.dgettext(None, message) ''' A Python plugin. @@ -126,25 +128,6 @@ def test_dialog(procedure, run_mode, image, n_drawables, drawables, config, data class TestDialogPlugin (Gimp.PlugIn): - ## Parameters ## - # See comments about this in foggify.py, from which we borrowed - - brush = GObject.Property(type = Gimp.Brush, - nick = "_Brush", - blurb = "Brush") - font = GObject.Property(type = Gimp.Font, - nick = "_Font", - blurb = "Font") - gradient = GObject.Property(type = Gimp.Gradient, - nick = "_Gradient", - blurb = "Gradient") - palette = GObject.Property(type = Gimp.Palette, - nick = "_Palette", - blurb = "Palette") - pattern = GObject.Property(type = Gimp.Pattern, - nick = "Pa_ttern", - blurb = "Pattern") - # FUTURE all other Gimp classes that have GimpParamSpecs ## GimpPlugIn virtual methods ## @@ -169,11 +152,19 @@ class TestDialogPlugin (Gimp.PlugIn): # Top level menu "Test" procedure.add_menu_path ("/Filters/Development/Demos") - procedure.add_argument_from_property(self, "brush") - procedure.add_argument_from_property(self, "font") - procedure.add_argument_from_property(self, "gradient") - procedure.add_argument_from_property(self, "palette") - procedure.add_argument_from_property(self, "pattern") + procedure.add_brush_argument ("brush", _("_Brush"), _("Brush"), + GObject.ParamFlags.READWRITE) + procedure.add_font_argument ("font", _("_Font"), _("Font"), + GObject.ParamFlags.READWRITE) + procedure.add_gradient_argument ("gradient", _("_Gradient"), + _("Gradient"), + GObject.ParamFlags.READWRITE) + procedure.add_palette_argument ("palette", _("_Palette"), + _("Palette"), + GObject.ParamFlags.READWRITE) + procedure.add_pattern_argument ("pattern", _("Pa_ttern"), + _("Pattern"), + GObject.ParamFlags.READWRITE) return procedure