diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
commit | cca66b9ec4e494c1d919bff0f71a820d8afab1fa (patch) | |
tree | 146f39ded1c938019e1ed42d30923c2ac9e86789 /share/extensions/interp_att_g.py | |
parent | Initial commit. (diff) | |
download | inkscape-cca66b9ec4e494c1d919bff0f71a820d8afab1fa.tar.xz inkscape-cca66b9ec4e494c1d919bff0f71a820d8afab1fa.zip |
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'share/extensions/interp_att_g.py')
-rwxr-xr-x | share/extensions/interp_att_g.py | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/share/extensions/interp_att_g.py b/share/extensions/interp_att_g.py new file mode 100755 index 0000000..61b8d8b --- /dev/null +++ b/share/extensions/interp_att_g.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python +# coding=utf-8 +# +# Copyright (C) 2009 Aurelio A. Heckert, aurium (a) gmail dot com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +""" +Interpolation of attributes in selected objects or group's children. +""" + +import inkex +from inkex.localization import inkex_gettext as _ +from inkex.tween import ColorInterpolator, ValueInterpolator, AttributeInterpolator +from inkex.utils import is_number + + +class InterpAttG(inkex.EffectExtension): + """ + This effect applies a value for any interpolatable attribute for all + elements inside the selected group or for all elements in a multiple selection. + """ + + def __init__(self): + super(InterpAttG, self).__init__() + self.arg_parser.add_argument( + "-a", + "--att", + type=str, + dest="att", + default="width", + help="Attribute to be interpolated.", + ) + self.arg_parser.add_argument( + "-o", + "--att-other", + type=str, + dest="att_other", + help="Other attribute (for a limited UI).", + ) + self.arg_parser.add_argument( + "-t", + "--att-other-type", + type=self.arg_class([ColorInterpolator, ValueInterpolator]), + dest="att_other_type", + help="The other attribute type.", + ) + self.arg_parser.add_argument( + "-w", + "--att-other-where", + type=str, + dest="att_other_where", + default="tag", + help="That is a tag attribute or a style attribute?", + ) + self.arg_parser.add_argument( + "-s", + "--start-val", + type=str, + dest="start_val", + default="#F00", + help="Initial interpolation value.", + ) + self.arg_parser.add_argument( + "-e", + "--end-val", + type=str, + dest="end_val", + default="#00F", + help="End interpolation value.", + ) + self.arg_parser.add_argument( + "-u", "--unit", type=str, dest="unit", default="none", help="Values unit." + ) + self.arg_parser.add_argument( + "--zsort", + type=inkex.Boolean, + dest="zsort", + default=False, + help="use z-order instead of selection order", + ) + self.arg_parser.add_argument( + "--tab", + type=str, + dest="tab", + help="The selected UI-tab when OK was pressed", + ) + + def get_elements(self): + """Returns a list of elements to work on""" + if not self.svg.selection: + return [] + + if len(self.svg.selection) > 1: + # multiple selection + if self.options.zsort: + return list(self.svg.selection.rendering_order().values()) + return list(self.svg.selection.values()) + + # must be a group + node = self.svg.selection.filter(inkex.Group).first() + return list(node) or [] + + def create_dummy_nodes(self, path): + """Create dummy nodes to use the interpolation classes defined in inkex.tween""" + pat1 = inkex.PathElement() + pat2 = inkex.PathElement() + + start_value = self.options.start_val.replace(",", ".") + end_value = self.options.end_val.replace(",", ".") + if self.options.unit != "none": + start_value += self.options.unit + end_value += self.options.unit + self.apply_value(pat1, path, start_value) + self.apply_value(pat2, path, end_value) + return pat1, pat2 + + @staticmethod + def apply_value(node, path, value): + """Applies a value to a given node. If path starts with "transform/" or "style/", the + value is applied to either transform or style.""" + if path.startswith("style/"): + att_name = path[6:] + node.style[att_name] = value + elif path.startswith("transform/"): + if not is_number(value): + raise inkex.AbortExtension( + _("Unable to set attribute {} to {}").format(path, value) + ) + if path == "transform/trans-x": + node.transform.add_translate(value, 0) + elif path == "transform/trans-y": + node.transform.add_translate(0, value) + elif path == "transform/scale": + node.transform.add_scale(value) + elif path == "transform": + node.transform @= value + else: + node.set(path, value) + + def effect(self): + method = None + if self.options.att == "other": + if self.options.att_other is None: + raise inkex.AbortExtension( + _("You selected 'Other'. Please enter an attribute to interpolate.") + ) + if self.options.att_other_where == "tag": + path = self.options.att_other + else: + path = self.options.att_other_where + "/" + self.options.att_other + method = self.options.att_other_type + else: + path = self.options.att + if self.options.att == "height" or self.options.att == "width": + method = inkex.tween.UnitValueInterpolator + + path1, path2 = self.create_dummy_nodes(path) + if path.startswith("transform"): + path = "transform" + try: + # maybe tween knows what do do with this attribute? + interpolator = AttributeInterpolator.create_from_attribute( + path1, path2, path, None + ) + except: + # okay, apparently not + interpolator = AttributeInterpolator.create_from_attribute( + path1, path2, path, method + ) + collection = self.get_elements() + if not collection: + raise inkex.AbortExtension(_("There is no selection to interpolate")) + + steps = [1.0 / (len(collection) - 1) * i for i in range(len(collection))] + + for time, node in zip(steps, collection): + new_value = interpolator.interpolate(time) + InterpAttG.apply_value(node, path, new_value) + + return True + + +if __name__ == "__main__": + InterpAttG().run() |