mirror of https://github.com/GNOME/gimp.git
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.
This commit is contained in:
parent
d1c4457fa3
commit
292cb01fc2
|
@ -265,30 +265,6 @@ def export_colorxhtml(procedure, run_mode, image, file, metadata, config, data):
|
||||||
|
|
||||||
|
|
||||||
class ColorXhtml(Gimp.PlugIn):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -314,10 +290,19 @@ class ColorXhtml(Gimp.PlugIn):
|
||||||
|
|
||||||
procedure.set_extensions ("html,xhtml");
|
procedure.set_extensions ("html,xhtml");
|
||||||
|
|
||||||
procedure.add_argument_from_property(self, "source-file")
|
procedure.add_boolean_argument ("source-file",
|
||||||
procedure.add_argument_from_property(self, "characters")
|
_("_Read characters from file, if true, or use text entry"),
|
||||||
procedure.add_argument_from_property(self, "font-size")
|
_("Read characters from file, if true, or use text entry"),
|
||||||
procedure.add_argument_from_property(self, "separate")
|
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
|
return procedure
|
||||||
|
|
||||||
|
|
|
@ -31,19 +31,6 @@ def N_(message): return message
|
||||||
def _(message): return GLib.dgettext(None, message)
|
def _(message): return GLib.dgettext(None, message)
|
||||||
|
|
||||||
def foggify(procedure, run_mode, image, n_drawables, drawables, config, data):
|
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:
|
if run_mode == Gimp.RunMode.INTERACTIVE:
|
||||||
GimpUi.init('python-fu-foggify')
|
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())
|
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
|
||||||
|
|
||||||
class Foggify (Gimp.PlugIn):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -139,6 +100,11 @@ class Foggify (Gimp.PlugIn):
|
||||||
return [ 'python-fu-foggify' ]
|
return [ 'python-fu-foggify' ]
|
||||||
|
|
||||||
def do_create_procedure(self, name):
|
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,
|
procedure = Gimp.ImageProcedure.new(self, name,
|
||||||
Gimp.PDBProcType.PLUGIN,
|
Gimp.PDBProcType.PLUGIN,
|
||||||
foggify, None)
|
foggify, None)
|
||||||
|
@ -154,10 +120,15 @@ class Foggify (Gimp.PlugIn):
|
||||||
"1999,2007")
|
"1999,2007")
|
||||||
procedure.add_menu_path ("<Image>/Filters/Decor")
|
procedure.add_menu_path ("<Image>/Filters/Decor")
|
||||||
|
|
||||||
procedure.add_argument_from_property(self, "name")
|
procedure.add_string_argument ("name", _("Layer _name"), _("Layer name"),
|
||||||
procedure.add_argument_from_property(self, "color")
|
_("Clouds"), GObject.ParamFlags.READWRITE)
|
||||||
procedure.add_argument_from_property(self, "turbulence")
|
procedure.add_color_argument ("color", _("_Fog color"), _("_Fog color"),
|
||||||
procedure.add_argument_from_property(self, "opacity")
|
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
|
return procedure
|
||||||
|
|
||||||
Gimp.main(Foggify.__gtype__, sys.argv)
|
Gimp.main(Foggify.__gtype__, sys.argv)
|
||||||
|
|
|
@ -177,21 +177,6 @@ def gradient_css_save(procedure, config, data):
|
||||||
GLib.Error('File saving failed: {}'.format(file.get_path())))
|
GLib.Error('File saving failed: {}'.format(file.get_path())))
|
||||||
|
|
||||||
class GradientsSaveAsCSS (Gimp.PlugIn):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -213,9 +198,14 @@ class GradientsSaveAsCSS (Gimp.PlugIn):
|
||||||
"2011")
|
"2011")
|
||||||
procedure.add_menu_path('<Gradients>/Gradients Menu')
|
procedure.add_menu_path('<Gradients>/Gradients Menu')
|
||||||
|
|
||||||
procedure.add_argument_from_property(self, "run-mode")
|
procedure.add_enum_argument ("run-mode", _("Run mode"),
|
||||||
procedure.add_argument_from_property(self, "gradient")
|
_("The run mode"), Gimp.RunMode,
|
||||||
procedure.add_argument_from_property(self, "file")
|
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
|
return procedure
|
||||||
|
|
||||||
Gimp.main(GradientsSaveAsCSS.__gtype__, sys.argv)
|
Gimp.main(GradientsSaveAsCSS.__gtype__, sys.argv)
|
||||||
|
|
|
@ -87,14 +87,6 @@ class StringEnum:
|
||||||
return key
|
return key
|
||||||
raise AttributeError("No such key string " + 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,
|
def histogram_export(procedure, img, layers, gio_file,
|
||||||
bucket_size, sample_average, output_format):
|
bucket_size, sample_average, output_format):
|
||||||
layers = img.list_selected_layers()
|
layers = img.list_selected_layers()
|
||||||
|
@ -139,12 +131,12 @@ def histogram_export(procedure, img, layers, gio_file,
|
||||||
histo_config.set_property('channel', channel)
|
histo_config.set_property('channel', channel)
|
||||||
result = histo_proc.run(histo_config)
|
result = histo_proc.run(histo_config)
|
||||||
|
|
||||||
if output_format == output_format_enum.pixel_count:
|
if output_format == "pixel-count":
|
||||||
count = int(result.index(5))
|
count = int(result.index(5))
|
||||||
else:
|
else:
|
||||||
pixels = result.index(4)
|
pixels = result.index(4)
|
||||||
count = (result.index(5) / pixels) if pixels else 0
|
count = (result.index(5) / pixels) if pixels else 0
|
||||||
if output_format == output_format_enum.percent:
|
if output_format == "percent":
|
||||||
count = "%.2f%%" % (count * 100)
|
count = "%.2f%%" % (count * 100)
|
||||||
row.append(str(count))
|
row.append(str(count))
|
||||||
writer.writerow(row)
|
writer.writerow(row)
|
||||||
|
@ -177,30 +169,7 @@ def run(procedure, run_mode, image, n_layers, layers, config, data):
|
||||||
GimpUi.init("histogram-export.py")
|
GimpUi.init("histogram-export.py")
|
||||||
|
|
||||||
dialog = GimpUi.ProcedureDialog.new(procedure, config, _("Histogram Export..."))
|
dialog = GimpUi.ProcedureDialog.new(procedure, config, _("Histogram Export..."))
|
||||||
vbox = dialog.fill_box ("histogram-box", ["file", "bucket-size", "sample-average"])
|
dialog.fill()
|
||||||
|
|
||||||
#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"])
|
|
||||||
|
|
||||||
if not dialog.run():
|
if not dialog.run():
|
||||||
return procedure.new_return_values(Gimp.PDBStatusType.CANCEL,
|
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):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -274,10 +217,20 @@ class HistogramExport(Gimp.PlugIn):
|
||||||
"2014")
|
"2014")
|
||||||
procedure.add_menu_path("<Image>/Colors/Info/")
|
procedure.add_menu_path("<Image>/Colors/Info/")
|
||||||
|
|
||||||
procedure.add_argument_from_property(self, "file")
|
# TODO: GFile props still don't have labels + only load existing files
|
||||||
procedure.add_argument_from_property(self, "bucket-size")
|
# (here we likely want to create a new file).
|
||||||
procedure.add_argument_from_property(self, "sample-average")
|
procedure.add_file_argument ("file", _("Histogram File"),
|
||||||
procedure.add_argument_from_property(self, "output-format")
|
_("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
|
return procedure
|
||||||
|
|
||||||
|
|
|
@ -33,52 +33,6 @@ otherwise copies the given palette and returns it.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class PaletteOffset (Gimp.PlugIn):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -98,10 +52,18 @@ class PaletteOffset (Gimp.PlugIn):
|
||||||
procedure.set_attribution("Joao S. O. Bueno Calligaris, Carol Spears",
|
procedure.set_attribution("Joao S. O. Bueno Calligaris, Carol Spears",
|
||||||
"(c) Joao S. O. Bueno Calligaris",
|
"(c) Joao S. O. Bueno Calligaris",
|
||||||
"2004, 2006")
|
"2004, 2006")
|
||||||
procedure.add_argument_from_property(self, "run-mode")
|
procedure.add_enum_argument ("run-mode", _("Run mode"),
|
||||||
procedure.add_argument_from_property(self, "palette")
|
_("The run mode"), Gimp.RunMode,
|
||||||
procedure.add_argument_from_property(self, "amount")
|
Gimp.RunMode.NONINTERACTIVE,
|
||||||
procedure.add_return_value_from_property(self, "new-palette")
|
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>/Palettes Menu')
|
procedure.add_menu_path ('<Palettes>/Palettes Menu')
|
||||||
else:
|
else:
|
||||||
procedure = None
|
procedure = None
|
||||||
|
@ -128,34 +90,16 @@ class PaletteOffset (Gimp.PlugIn):
|
||||||
|
|
||||||
GimpUi.init ("palette-offset.py")
|
GimpUi.init ("palette-offset.py")
|
||||||
|
|
||||||
use_header_bar = Gtk.Settings.get_default().get_property("gtk-dialogs-use-header")
|
dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config)
|
||||||
dialog = GimpUi.Dialog(use_header_bar=use_header_bar,
|
dialog.fill(["palette", "amount"])
|
||||||
title=_("Offset Palette..."))
|
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)
|
amount = config.get_property("amount")
|
||||||
dialog.add_button(_("_OK"), Gtk.ResponseType.OK)
|
palette = config.get_property("palette")
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
#If palette is read only, work on a copy:
|
#If palette is read only, work on a copy:
|
||||||
editable = palette.is_editable()
|
editable = palette.is_editable()
|
||||||
|
|
|
@ -77,12 +77,6 @@ GRAIN_SCALE = (1.0, 1.0 , 1.0,
|
||||||
100., 256., 256.,
|
100., 256., 256.,
|
||||||
256., 360.,)
|
256., 360.,)
|
||||||
|
|
||||||
SELECT_ALL = 0
|
|
||||||
SELECT_SLICE = 1
|
|
||||||
SELECT_AUTOSLICE = 2
|
|
||||||
SELECT_PARTITIONED = 3
|
|
||||||
SELECTIONS = (SELECT_ALL, SELECT_SLICE, SELECT_AUTOSLICE, SELECT_PARTITIONED)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from colormath.color_objects import RGBColor, LabColor, LCHabColor
|
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()
|
num_colors = palette.get_color_count()
|
||||||
|
|
||||||
start, nrows, length = None, None, None
|
start, nrows, length = None, None, None
|
||||||
if selection == SELECT_AUTOSLICE:
|
if selection == "auto-slice":
|
||||||
def find_index(color, startindex=0):
|
def find_index(color, startindex=0):
|
||||||
for i in range(startindex, num_colors):
|
for i in range(startindex, num_colors):
|
||||||
c = palette.entry_get_color(i)
|
c = palette.entry_get_color(i)
|
||||||
|
@ -262,9 +256,9 @@ def palette_sort(palette, selection, slice_expr, channel1, ascending1,
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# bad expression is okay here, just assume one row
|
# bad expression is okay here, just assume one row
|
||||||
nrows = 1
|
nrows = 1
|
||||||
# remaining behavior is implemented by SELECT_SLICE 'inheritance'.
|
# remaining behavior is implemented by "slice-array" 'inheritance'.
|
||||||
selection = SELECT_SLICE
|
selection = "slice-array"
|
||||||
elif selection in (SELECT_SLICE, SELECT_PARTITIONED):
|
elif selection in ("slice-array", "partitioned"):
|
||||||
start, nrows, length = parse_slice(slice_expr, num_colors)
|
start, nrows, length = parse_slice(slice_expr, num_colors)
|
||||||
|
|
||||||
channels_getter_1 = channel_getters[channel1]
|
channels_getter_1 = channel_getters[channel1]
|
||||||
|
@ -283,14 +277,15 @@ def palette_sort(palette, selection, slice_expr, channel1, ascending1,
|
||||||
result.append((index, entry))
|
result.append((index, entry))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
if selection == SELECT_ALL:
|
print (selection)
|
||||||
|
if selection == "all":
|
||||||
entry_list = get_colors(0, num_colors)
|
entry_list = get_colors(0, num_colors)
|
||||||
entry_list.sort(key=lambda v: v[0])
|
entry_list.sort(key=lambda v: v[0])
|
||||||
for i in range(num_colors):
|
for i in range(num_colors):
|
||||||
palette.entry_set_name(i, entry_list[i][1][0])
|
palette.entry_set_name(i, entry_list[i][1][0])
|
||||||
palette.entry_set_color(i, entry_list[i][1][1])
|
palette.entry_set_color(i, entry_list[i][1][1])
|
||||||
|
|
||||||
elif selection == SELECT_PARTITIONED:
|
elif selection == "partitioned":
|
||||||
if num_colors < (start + length * nrows) - 1:
|
if num_colors < (start + length * nrows) - 1:
|
||||||
raise ValueError('Not enough entries in palette to '
|
raise ValueError('Not enough entries in palette to '
|
||||||
'sort complete rows! Got %d, expected >=%d' %
|
'sort complete rows! Got %d, expected >=%d' %
|
||||||
|
@ -313,13 +308,13 @@ def palette_sort(palette, selection, slice_expr, channel1, ascending1,
|
||||||
old_partition = this_partition
|
old_partition = this_partition
|
||||||
base = rowstart
|
base = rowstart
|
||||||
for size in partition_spans:
|
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,
|
channel1, ascending1,
|
||||||
channel2, ascending2,
|
channel2, ascending2,
|
||||||
quantize, 0, 1.0)
|
quantize, 0, 1.0)
|
||||||
base += size
|
base += size
|
||||||
else:
|
else:
|
||||||
# SELECT_SLICE and SELECT_AUTOSLICE
|
# "slice-array" and "auto-slice"
|
||||||
stride = length
|
stride = length
|
||||||
if num_colors < (start + stride * nrows) - 1:
|
if num_colors < (start + stride * nrows) - 1:
|
||||||
raise ValueError('Not enough entries in palette to sort '
|
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.
|
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):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -440,18 +368,53 @@ class PaletteSort (Gimp.PlugIn):
|
||||||
"2006-2014")
|
"2006-2014")
|
||||||
procedure.add_menu_path ('<Palettes>/Palettes Menu')
|
procedure.add_menu_path ('<Palettes>/Palettes Menu')
|
||||||
|
|
||||||
procedure.add_argument_from_property(self, "run-mode")
|
procedure.add_enum_argument ("run-mode", _("Run mode"),
|
||||||
procedure.add_argument_from_property(self, "palette")
|
_("The run mode"), Gimp.RunMode,
|
||||||
procedure.add_argument_from_property(self, "selections")
|
Gimp.RunMode.INTERACTIVE,
|
||||||
procedure.add_argument_from_property(self, "slice_expr")
|
GObject.ParamFlags.READWRITE)
|
||||||
procedure.add_argument_from_property(self, "channel1")
|
procedure.add_palette_argument ("palette", _("_Palette"),
|
||||||
procedure.add_argument_from_property(self, "ascending1")
|
_("Palette"),
|
||||||
procedure.add_argument_from_property(self, "channel2")
|
GObject.ParamFlags.READWRITE)
|
||||||
procedure.add_argument_from_property(self, "ascending2")
|
|
||||||
procedure.add_argument_from_property(self, "quantize")
|
selection_choice = Gimp.Choice.new()
|
||||||
procedure.add_argument_from_property(self, "pchannel")
|
selection_choice.add("all", 0, _("All"), "")
|
||||||
procedure.add_argument_from_property(self, "pquantize")
|
selection_choice.add("slice-array", 1, _("Slice / Array"), "")
|
||||||
procedure.add_return_value_from_property(self, "new_palette")
|
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
|
return procedure
|
||||||
|
|
||||||
|
@ -478,13 +441,9 @@ class PaletteSort (Gimp.PlugIn):
|
||||||
dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config)
|
dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config)
|
||||||
|
|
||||||
dialog.fill (["palette"])
|
dialog.fill (["palette"])
|
||||||
dialog.get_int_combo("selections", GimpUi.IntStore.new (selections_option))
|
|
||||||
dialog.fill (["selections","slice-expr"])
|
dialog.fill (["selections","slice-expr"])
|
||||||
dialog.get_int_combo("channel1", GimpUi.IntStore.new (AVAILABLE_CHANNELS))
|
|
||||||
dialog.fill (["channel1", "ascending1"])
|
dialog.fill (["channel1", "ascending1"])
|
||||||
dialog.get_int_combo("channel2", GimpUi.IntStore.new (AVAILABLE_CHANNELS))
|
|
||||||
dialog.fill (["channel2","ascending2", "quantize"])
|
dialog.fill (["channel2","ascending2", "quantize"])
|
||||||
dialog.get_int_combo("pchannel", GimpUi.IntStore.new (AVAILABLE_CHANNELS))
|
|
||||||
dialog.fill (["pchannel","pquantize"])
|
dialog.fill (["pchannel","pquantize"])
|
||||||
|
|
||||||
if not dialog.run():
|
if not dialog.run():
|
||||||
|
@ -495,13 +454,13 @@ class PaletteSort (Gimp.PlugIn):
|
||||||
|
|
||||||
palette = config.get_property("palette")
|
palette = config.get_property("palette")
|
||||||
selection = config.get_property("selections")
|
selection = config.get_property("selections")
|
||||||
slice_expr = config.get_property ("slice_expr")
|
slice_expr = config.get_property("slice-expr")
|
||||||
channel1 = config.get_property("channel1")
|
channel1 = config.get_choice_id("channel1")
|
||||||
ascending1 = config.get_property ("ascending1")
|
ascending1 = config.get_property ("ascending1")
|
||||||
channel2 = config.get_property("channel2")
|
channel2 = config.get_choice_id("channel2")
|
||||||
ascending2 = config.get_property ("ascending2")
|
ascending2 = config.get_property ("ascending2")
|
||||||
quantize = config.get_property ("quantize")
|
quantize = config.get_property ("quantize")
|
||||||
pchannel = config.get_property("pchannel")
|
pchannel = config.get_choice_id("pchannel")
|
||||||
pquantize = config.get_property ("pquantize")
|
pquantize = config.get_property ("pquantize")
|
||||||
try:
|
try:
|
||||||
new_palette = palette_sort(palette, selection, slice_expr, channel1, ascending1,
|
new_palette = palette_sort(palette, selection, slice_expr, channel1, ascending1,
|
||||||
|
@ -516,4 +475,18 @@ class PaletteSort (Gimp.PlugIn):
|
||||||
return_val.insert(1, value)
|
return_val.insert(1, value)
|
||||||
return return_val
|
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)
|
Gimp.main(PaletteSort.__gtype__, sys.argv)
|
||||||
|
|
|
@ -111,43 +111,6 @@ def run(procedure, config, data):
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
class PaletteToGradient (Gimp.PlugIn):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -176,12 +139,17 @@ class PaletteToGradient (Gimp.PlugIn):
|
||||||
if procedure is not None:
|
if procedure is not None:
|
||||||
procedure.set_attribution("Carol Spears, reproduced from previous work by Adrian Likins and Jeff Trefftz",
|
procedure.set_attribution("Carol Spears, reproduced from previous work by Adrian Likins and Jeff Trefftz",
|
||||||
"Carol Spears", "2006")
|
"Carol Spears", "2006")
|
||||||
# We don't build a GParamSpec ourselves because passing it
|
|
||||||
# around is apparently broken in Python. Hence this trick.
|
procedure.add_enum_argument ("run-mode", _("Run mode"),
|
||||||
# See pygobject#227
|
_("The run mode"), Gimp.RunMode,
|
||||||
procedure.add_argument_from_property(self, "run-mode")
|
Gimp.RunMode.NONINTERACTIVE,
|
||||||
procedure.add_argument_from_property(self, "palette")
|
GObject.ParamFlags.READWRITE)
|
||||||
procedure.add_return_value_from_property(self, "new-gradient")
|
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>/Palettes Menu')
|
procedure.add_menu_path ('<Palettes>/Palettes Menu')
|
||||||
|
|
||||||
|
|
|
@ -480,10 +480,15 @@ class SelectionShape(Shape):
|
||||||
return x + dist * cos(perpendicular), y + dist * sin(perpendicular)
|
return x + dist * cos(perpendicular), y + dist * sin(perpendicular)
|
||||||
|
|
||||||
|
|
||||||
shapes = [
|
shapes = {
|
||||||
CircleShape(), RackShape(), FrameShape(), SelectionShape(),
|
"circle": CircleShape(),
|
||||||
PolygonShape(), SineShape(), BumpShape()
|
"rack": RackShape(),
|
||||||
]
|
"frame": FrameShape(),
|
||||||
|
"selection": SelectionShape(),
|
||||||
|
"polygon-star": PolygonShape(),
|
||||||
|
"sine": SineShape(),
|
||||||
|
"bumps": BumpShape()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
### Tools
|
### Tools
|
||||||
|
@ -651,16 +656,18 @@ class SaveToPathTool():
|
||||||
control_points, False)
|
control_points, False)
|
||||||
|
|
||||||
|
|
||||||
tools = [
|
tools = {
|
||||||
PreviewTool(),
|
"preview": PreviewTool(),
|
||||||
StrokePaintTool(_("PaintBrush"), "gimp-paintbrush"),
|
"paintbrush": StrokePaintTool(_("PaintBrush"), "gimp-paintbrush"),
|
||||||
PencilTool(), AirBrushTool(), StrokeTool(),
|
"penciltool": PencilTool(),
|
||||||
StrokePaintTool(_("Ink"), 'gimp-ink'),
|
"airbrush": AirBrushTool(),
|
||||||
StrokePaintTool(_("MyPaintBrush"), 'gimp-mybrush')
|
"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
|
# 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.
|
# I am unable to catch the error. This causes the plugin to crash, and subsequent problems with undo.
|
||||||
# StrokePaintTool("Clone", 'gimp-clone', False)
|
# StrokePaintTool("Clone", 'gimp-clone', False)
|
||||||
]
|
}
|
||||||
|
|
||||||
|
|
||||||
class PatternParameters:
|
class PatternParameters:
|
||||||
|
@ -671,7 +678,7 @@ class PatternParameters:
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if not hasattr(self, 'curve_type'):
|
if not hasattr(self, 'curve_type'):
|
||||||
self.curve_type = 0
|
self.curve_type = "spyrograph"
|
||||||
|
|
||||||
# Pattern
|
# Pattern
|
||||||
if not hasattr(self, 'pattern_notation'):
|
if not hasattr(self, 'pattern_notation'):
|
||||||
|
@ -710,7 +717,7 @@ class PatternParameters:
|
||||||
|
|
||||||
# Shape
|
# Shape
|
||||||
if not hasattr(self, 'shape_index'):
|
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'):
|
if not hasattr(self, 'sides'):
|
||||||
self.sides = 5
|
self.sides = 5
|
||||||
if not hasattr(self, 'morph'):
|
if not hasattr(self, 'morph'):
|
||||||
|
@ -725,7 +732,7 @@ class PatternParameters:
|
||||||
|
|
||||||
# Drawing style
|
# Drawing style
|
||||||
if not hasattr(self, 'tool_index'):
|
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'):
|
if not hasattr(self, 'long_gradient'):
|
||||||
self.long_gradient = False
|
self.long_gradient = False
|
||||||
|
|
||||||
|
@ -1029,7 +1036,12 @@ class LissaCurveType:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
curve_types = [SpyroCurveType(), EpitrochoidCurvetype(), SineCurveType(), LissaCurveType()]
|
curve_types = {
|
||||||
|
"spyrograph": SpyroCurveType(),
|
||||||
|
"epitrochoid": EpitrochoidCurvetype(),
|
||||||
|
"sine": SineCurveType(),
|
||||||
|
"lissajous": LissaCurveType()
|
||||||
|
}
|
||||||
|
|
||||||
# Drawing engine. Also implements drawing incrementally.
|
# Drawing engine. Also implements drawing incrementally.
|
||||||
# We don't draw the entire stroke, because it could take several seconds,
|
# 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)
|
myscale.spin.set_width_chars(6)
|
||||||
return adj, myscale
|
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()
|
combo = Gtk.ComboBoxText.new()
|
||||||
for txt in txt_list:
|
if (is_dictionary == False):
|
||||||
combo.append_text(_(txt))
|
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)
|
combo.set_halign(Gtk.Align.FILL)
|
||||||
table.attach(combo, 1, row, 1, 1)
|
table.attach(combo, 1, row, 1, 1)
|
||||||
|
@ -1455,14 +1471,14 @@ class SpyroWindow():
|
||||||
row = 0
|
row = 0
|
||||||
label_in_table(_("Curve Type"), table, row,
|
label_in_table(_("Curve Type"), table, row,
|
||||||
_("An Epitrochoid pattern is when the moving gear is on the outside of the fixed gear."))
|
_("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)
|
self.curve_type_changed)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
label_in_table(_("Tool"), table, row,
|
label_in_table(_("Tool"), table, row,
|
||||||
_("The tool with which to draw the pattern. "
|
_("The tool with which to draw the pattern. "
|
||||||
"The Preview tool just draws quickly."))
|
"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.tool_combo_changed)
|
||||||
|
|
||||||
self.long_gradient_checkbox = Gtk.CheckButton(label=_("Long Gradient"))
|
self.long_gradient_checkbox = Gtk.CheckButton(label=_("Long Gradient"))
|
||||||
|
@ -1545,12 +1561,12 @@ class SpyroWindow():
|
||||||
|
|
||||||
row = 0
|
row = 0
|
||||||
label_in_table(_("Fixed Gear Teeth"), kit_table, row, fixed_gear_tooltip)
|
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)
|
self.kit_outer_teeth_combo_changed)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
label_in_table(_("Moving Gear Teeth"), kit_table, row, moving_gear_tooltip)
|
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)
|
self.kit_inner_teeth_combo_changed)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
|
@ -1667,7 +1683,7 @@ class SpyroWindow():
|
||||||
"Frame hugs the boundaries of the rectangular selection, "
|
"Frame hugs the boundaries of the rectangular selection, "
|
||||||
"use hole=100 in Gear notation to touch boundary. "
|
"use hole=100 in Gear notation to touch boundary. "
|
||||||
"Selection will hug boundaries of current selection - try something non-rectangular."))
|
"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)
|
self.shape_combo_changed)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
|
@ -1733,7 +1749,7 @@ class SpyroWindow():
|
||||||
row = 0
|
row = 0
|
||||||
label_in_table(_("Save"), table, row,
|
label_in_table(_("Save"), table, row,
|
||||||
_("Choose whether to save as new layer, redraw on last active layer, or save to path"))
|
_("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_changed)
|
||||||
self.save_option_combo.show()
|
self.save_option_combo.show()
|
||||||
|
|
||||||
|
@ -1918,7 +1934,7 @@ class SpyroWindow():
|
||||||
|
|
||||||
def update_view(self):
|
def update_view(self):
|
||||||
""" Update the UI to reflect the values in the Pattern Parameters. """
|
""" 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.curve_type_side_effects()
|
||||||
|
|
||||||
self.pattern_notebook.set_current_page(pattern_notation_page[self.p.pattern_notation])
|
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.doughnut.set_width(self.p.doughnut_width)
|
||||||
self.petals_changed_side_effects()
|
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.shape_combo_side_effects()
|
||||||
self.sides_adj.set_value(self.p.sides)
|
self.sides_adj.set_value(self.p.sides)
|
||||||
self.morph_adj.set_value(self.p.morph)
|
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.shape_rotation_adj.set_value(self.p.shape_rotation)
|
||||||
|
|
||||||
self.margin_adj.set_value(self.p.margin_pixels)
|
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.long_gradient_checkbox.set_active(self.p.long_gradient)
|
||||||
self.save_option_combo.set_active(self.p.save_option)
|
self.save_option_combo.set_active(self.p.save_option)
|
||||||
|
|
||||||
|
@ -1987,7 +2003,7 @@ class SpyroWindow():
|
||||||
self.doughnut_width_myscale.set_sensitive(False)
|
self.doughnut_width_myscale.set_sensitive(False)
|
||||||
|
|
||||||
def curve_type_changed(self, val):
|
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.curve_type_side_effects()
|
||||||
self.redraw()
|
self.redraw()
|
||||||
|
|
||||||
|
@ -2086,7 +2102,7 @@ class SpyroWindow():
|
||||||
self.equal_w_h_checkbox.set_sensitive(shapes[self.p.shape_index].can_equal_w_h())
|
self.equal_w_h_checkbox.set_sensitive(shapes[self.p.shape_index].can_equal_w_h())
|
||||||
|
|
||||||
def shape_combo_changed(self, val):
|
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.shape_combo_side_effects()
|
||||||
self.redraw()
|
self.redraw()
|
||||||
|
|
||||||
|
@ -2116,7 +2132,7 @@ class SpyroWindow():
|
||||||
self.long_gradient_checkbox.set_sensitive(tools[self.p.tool_index].can_color)
|
self.long_gradient_checkbox.set_sensitive(tools[self.p.tool_index].can_color)
|
||||||
|
|
||||||
def tool_combo_changed(self, val):
|
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.tool_changed_side_effects()
|
||||||
self.redraw()
|
self.redraw()
|
||||||
|
|
||||||
|
@ -2204,80 +2220,6 @@ class SpyroWindow():
|
||||||
|
|
||||||
|
|
||||||
class SpyrogimpPlusPlugin(Gimp.PlugIn):
|
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 ##
|
## GimpPlugIn virtual methods ##
|
||||||
def do_set_i18n(self, procname):
|
def do_set_i18n(self, procname):
|
||||||
return True, 'gimp30-python', None
|
return True, 'gimp30-python', None
|
||||||
|
@ -2302,19 +2244,67 @@ class SpyrogimpPlusPlugin(Gimp.PlugIn):
|
||||||
"2018")
|
"2018")
|
||||||
procedure.add_menu_path ("<Image>/Filters/Render/")
|
procedure.add_menu_path ("<Image>/Filters/Render/")
|
||||||
|
|
||||||
procedure.add_argument_from_property(self, "curve-type")
|
curve_choice = Gimp.Choice.new()
|
||||||
procedure.add_argument_from_property(self, "shape")
|
curve_choice.add("spyrograph", 0, _("Spyrograph"), "")
|
||||||
procedure.add_argument_from_property(self, "sides")
|
curve_choice.add("epitrochoid", 1, _("Epitrochoid"), "")
|
||||||
procedure.add_argument_from_property(self, "morph")
|
curve_choice.add("sine", 2, _("Sine"), "")
|
||||||
procedure.add_argument_from_property(self, "fixed-teeth")
|
curve_choice.add("lissajous", 3, _("Lissajous"), "")
|
||||||
procedure.add_argument_from_property(self, "moving-teeth")
|
procedure.add_choice_argument ("curve-type", _("Curve Type"), _("Curve Type"),
|
||||||
procedure.add_argument_from_property(self, "hole_percent")
|
curve_choice, "spyrograph", GObject.ParamFlags.READWRITE)
|
||||||
procedure.add_argument_from_property(self, "margin")
|
shape_choice = Gimp.Choice.new()
|
||||||
procedure.add_argument_from_property(self, "equal-w-h")
|
shape_choice.add("circle", 0, _("Circle"), "")
|
||||||
procedure.add_argument_from_property(self, "pattern-rotation")
|
shape_choice.add("rack", 1, _("rack"), "")
|
||||||
procedure.add_argument_from_property(self, "shape-rotation")
|
shape_choice.add("frame", 2, _("frame"), "")
|
||||||
procedure.add_argument_from_property(self, "tool")
|
shape_choice.add("selection", 3, _("Selection"), "")
|
||||||
procedure.add_argument_from_property(self, "long-gradient")
|
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
|
return procedure
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@ from gi.repository import Gio
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
def N_(message): return message
|
||||||
|
def _(message): return GLib.dgettext(None, message)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
A Python plugin.
|
A Python plugin.
|
||||||
|
@ -126,25 +128,6 @@ def test_dialog(procedure, run_mode, image, n_drawables, drawables, config, data
|
||||||
|
|
||||||
|
|
||||||
class TestDialogPlugin (Gimp.PlugIn):
|
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
|
# FUTURE all other Gimp classes that have GimpParamSpecs
|
||||||
|
|
||||||
## GimpPlugIn virtual methods ##
|
## GimpPlugIn virtual methods ##
|
||||||
|
@ -169,11 +152,19 @@ class TestDialogPlugin (Gimp.PlugIn):
|
||||||
# Top level menu "Test"
|
# Top level menu "Test"
|
||||||
procedure.add_menu_path ("<Image>/Filters/Development/Demos")
|
procedure.add_menu_path ("<Image>/Filters/Development/Demos")
|
||||||
|
|
||||||
procedure.add_argument_from_property(self, "brush")
|
procedure.add_brush_argument ("brush", _("_Brush"), _("Brush"),
|
||||||
procedure.add_argument_from_property(self, "font")
|
GObject.ParamFlags.READWRITE)
|
||||||
procedure.add_argument_from_property(self, "gradient")
|
procedure.add_font_argument ("font", _("_Font"), _("Font"),
|
||||||
procedure.add_argument_from_property(self, "palette")
|
GObject.ParamFlags.READWRITE)
|
||||||
procedure.add_argument_from_property(self, "pattern")
|
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
|
return procedure
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue