From 0fcf8bb97ced8df552cd0283b4ea009b6ca42623 Mon Sep 17 00:00:00 2001 From: Andreas Date: Thu, 21 Oct 2021 16:24:40 +0200 Subject: added tangential and guided fill --- lib/extensions/__init__.py | 2 + lib/extensions/base.py | 12 +---- lib/extensions/cleanup.py | 4 +- lib/extensions/params.py | 81 +++++++++++++++++++++++++++---- lib/extensions/selection_to_guide_line.py | 67 +++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 21 deletions(-) create mode 100644 lib/extensions/selection_to_guide_line.py (limited to 'lib/extensions') diff --git a/lib/extensions/__init__.py b/lib/extensions/__init__.py index b6e0d1d1..933720c9 100644 --- a/lib/extensions/__init__.py +++ b/lib/extensions/__init__.py @@ -39,6 +39,7 @@ from .print_pdf import Print from .remove_embroidery_settings import RemoveEmbroiderySettings from .reorder import Reorder from .selection_to_pattern import SelectionToPattern +from .selection_to_guide_line import SelectionToGuideLine from .simulator import Simulator from .stitch_plan_preview import StitchPlanPreview from .zip import Zip @@ -52,6 +53,7 @@ __all__ = extensions = [StitchPlanPreview, Zip, Flip, SelectionToPattern, + SelectionToGuideLine, ObjectCommands, ObjectCommandsToggleVisibility, LayerCommands, diff --git a/lib/extensions/base.py b/lib/extensions/base.py index 75a07c5a..56385458 100644 --- a/lib/extensions/base.py +++ b/lib/extensions/base.py @@ -10,7 +10,6 @@ from collections.abc import MutableMapping import inkex from lxml import etree -from lxml.etree import Comment from stringcase import snakecase from ..commands import is_command, layer_commands @@ -20,8 +19,7 @@ from ..i18n import _ from ..patterns import is_pattern from ..svg import generate_unique_id from ..svg.tags import (CONNECTOR_TYPE, EMBROIDERABLE_TAGS, INKSCAPE_GROUPMODE, - NOT_EMBROIDERABLE_TAGS, SVG_CLIPPATH_TAG, SVG_DEFS_TAG, - SVG_GROUP_TAG, SVG_MASK_TAG) + NOT_EMBROIDERABLE_TAGS, SVG_DEFS_TAG, SVG_GROUP_TAG) SVG_METADATA_TAG = inkex.addNS("metadata", "svg") @@ -131,10 +129,6 @@ class InkstitchExtension(inkex.Effect): def descendants(self, node, selected=False, troubleshoot=False): # noqa: C901 nodes = [] - - if node.tag == Comment: - return [] - element = EmbroideryElement(node) if element.has_command('ignore_object'): @@ -147,9 +141,7 @@ class InkstitchExtension(inkex.Effect): if (node.tag in EMBROIDERABLE_TAGS or node.tag == SVG_GROUP_TAG) and element.get_style('display', 'inline') is None: return [] - # defs, masks and clippaths can contain embroiderable elements - # but should never be rendered directly. - if node.tag in [SVG_DEFS_TAG, SVG_MASK_TAG, SVG_CLIPPATH_TAG]: + if node.tag == SVG_DEFS_TAG: return [] # command connectors with a fill color set, will glitch into the elements list diff --git a/lib/extensions/cleanup.py b/lib/extensions/cleanup.py index a38818b8..ae95041b 100644 --- a/lib/extensions/cleanup.py +++ b/lib/extensions/cleanup.py @@ -5,7 +5,7 @@ from inkex import NSS, Boolean, errormsg -from ..elements import Fill, Stroke +from ..elements import AutoFill, Stroke from ..i18n import _ from .base import InkstitchExtension @@ -38,7 +38,7 @@ class Cleanup(InkstitchExtension): return for element in self.elements: - if (isinstance(element, Fill) and self.rm_fill and element.shape.area < self.fill_threshold): + if (isinstance(element, AutoFill) and self.rm_fill and element.shape.area < self.fill_threshold): element.node.getparent().remove(element.node) count += 1 if (isinstance(element, Stroke) and self.rm_stroke and diff --git a/lib/extensions/params.py b/lib/extensions/params.py index c96b9691..8021d5d7 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -7,15 +7,15 @@ import os import sys -from collections import defaultdict +from collections import defaultdict,namedtuple from copy import copy -from itertools import groupby +from itertools import groupby,zip_longest import wx from wx.lib.scrolledpanel import ScrolledPanel from ..commands import is_command, is_command_symbol -from ..elements import (AutoFill, Clone, EmbroideryElement, Fill, Polyline, +from ..elements import (AutoFill, Clone, EmbroideryElement, Polyline, SatinColumn, Stroke) from ..elements.clone import is_clone from ..gui import PresetsPanel, SimulatorPreview, WarningPanel @@ -25,6 +25,14 @@ from ..utils import get_resource_dir from .base import InkstitchExtension +#ChoiceWidgets = namedtuple("ChoiceWidgets", "param widget last_initialized_choice") + + + +def grouper(iterable_obj, count, fillvalue=None): + args = [iter(iterable_obj)] * count + return zip_longest(*args, fillvalue=fillvalue) + class ParamsTab(ScrolledPanel): def __init__(self, *args, **kwargs): self.params = kwargs.pop('params', []) @@ -38,6 +46,8 @@ class ParamsTab(ScrolledPanel): self.dependent_tabs = [] self.parent_tab = None self.param_inputs = {} + self.choice_widgets = defaultdict(list) + self.dict_of_choices = {} self.paired_tab = None self.disable_notify_pair = False @@ -113,6 +123,19 @@ class ParamsTab(ScrolledPanel): if event: event.Skip() + def update_choice_state(self, event=None): + input = event.GetEventObject() + selection = input.GetSelection() + + param = self.inputs_to_params[input] + + self.update_choice_widgets((param, selection)) + self.settings_grid.Layout() + self.Layout() + + if event: + event.Skip() + def pair_changed(self, value): # print self.name, "pair_changed", value new_value = not value @@ -245,7 +268,30 @@ class ParamsTab(ScrolledPanel): # end wxGlade pass - def __do_layout(self): + #choice tuple is None or contains ("choice widget param name", "actual selection") + def update_choice_widgets(self, choice_tuple = None): + if choice_tuple == None: #update all choices + for choice in self.dict_of_choices.values(): + self.update_choice_widgets((choice["param"].name, choice["widget"].GetSelection())) + else: + choice = self.dict_of_choices[choice_tuple[0]] + last_selection = choice["last_initialized_choice"] + current_selection = choice["widget"].GetSelection() + if last_selection != -1 and last_selection != current_selection: #Hide the old widgets + for widget in self.choice_widgets[(choice["param"].name, last_selection)]: + widget.Hide() + #self.settings_grid.Detach(widget) + + #choice_index = self.settings_grid.GetChildren().index(self.settings_grid.GetItem(choice["widget"])) #TODO: is there a better way to get the index in the sizer? + for widgets in grouper(self.choice_widgets[choice_tuple], 4): + widgets[0].Show(True) + widgets[1].Show(True) + widgets[2].Show(True) + widgets[3].Show(True) + choice["last_initialized_choice"] = current_selection + + def __do_layout(self, only_settings_grid=False): + # just to add space around the settings box = wx.BoxSizer(wx.VERTICAL) @@ -266,14 +312,20 @@ class ParamsTab(ScrolledPanel): box.Add(toggle_sizer, proportion=0, flag=wx.BOTTOM, border=10) for param in self.params: - self.settings_grid.Add(self.create_change_indicator(param.name), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) - + col1 = self.create_change_indicator(param.name) description = wx.StaticText(self, label=param.description) description.SetToolTip(param.tooltip) + + if param.select_items != None: + col1.Hide() + description.Hide() + for item in param.select_items: + self.choice_widgets[item].extend([col1, description]) + #else: + self.settings_grid.Add(col1, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) self.settings_grid.Add(description, proportion=1, flag=wx.EXPAND | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.TOP, border=5) if param.type == 'boolean': - if len(param.values) > 1: input = wx.CheckBox(self, style=wx.CHK_3STATE) input.Set3StateValue(wx.CHK_UNDETERMINED) @@ -287,6 +339,8 @@ class ParamsTab(ScrolledPanel): input = wx.Choice(self, wx.ID_ANY, choices=param.options) input.SetSelection(int(param.values[0])) input.Bind(wx.EVT_CHOICE, self.changed) + input.Bind(wx.EVT_CHOICE, self.update_choice_state) + self.dict_of_choices[param.name] = {"param": param, "widget": input, "last_initialized_choice": 1} elif len(param.values) > 1: input = wx.ComboBox(self, wx.ID_ANY, choices=sorted(str(value) for value in param.values), style=wx.CB_DROPDOWN) input.Bind(wx.EVT_COMBOBOX, self.changed) @@ -298,13 +352,22 @@ class ParamsTab(ScrolledPanel): self.param_inputs[param.name] = input + col4 = wx.StaticText(self, label=param.unit or "") + + if param.select_items != None: + input.Hide() + col4.Hide() + for item in param.select_items: + self.choice_widgets[item].extend([input, col4]) + #else: self.settings_grid.Add(input, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND | wx.LEFT, border=40) - self.settings_grid.Add(wx.StaticText(self, label=param.unit or ""), proportion=1, flag=wx.ALIGN_CENTER_VERTICAL) + self.settings_grid.Add(col4, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL) self.inputs_to_params = {v: k for k, v in self.param_inputs.items()} box.Add(self.settings_grid, proportion=1, flag=wx.ALL, border=10) self.SetSizer(box) + self.update_choice_widgets() self.Layout() @@ -521,7 +584,7 @@ class Params(InkstitchExtension): else: if element.get_style("fill", 'black') and not element.get_style("fill-opacity", 1) == "0": classes.append(AutoFill) - classes.append(Fill) + #classes.append(Fill) if element.get_style("stroke") is not None: classes.append(Stroke) if element.get_style("stroke-dasharray") is None: diff --git a/lib/extensions/selection_to_guide_line.py b/lib/extensions/selection_to_guide_line.py new file mode 100644 index 00000000..85a44bb1 --- /dev/null +++ b/lib/extensions/selection_to_guide_line.py @@ -0,0 +1,67 @@ +# Authors: see git history +# +# Copyright (c) 2021 Authors +# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. + +import inkex +from lxml import etree + +from ..i18n import _ +from ..svg.tags import SVG_PATH_TAG, SVG_POLYLINE_TAG, SVG_DEFS_TAG +from .base import InkstitchExtension + + +class SelectionToGuideLine(InkstitchExtension): + + def effect(self): + if not self.get_elements(): + return + + if not self.svg.selected: + inkex.errormsg(_("Please select one object to be marked as a guide line.")) + return + + if len(self.get_nodes())!=1: + inkex.errormsg(_("Please select only one object to be marked as a guide line.")) + return + + for guide_line in self.get_nodes(): + if guide_line.tag in (SVG_PATH_TAG, SVG_POLYLINE_TAG): + self.set_marker(guide_line) + + def set_marker(self, node): + xpath = ".//marker[@id='inkstitch-guide-line-marker']" + guide_line_marker = self.document.xpath(xpath) + + if not guide_line_marker: + # get or create def element + defs = self.document.find(SVG_DEFS_TAG) + if defs is None: + defs = etree.SubElement(self.document, SVG_DEFS_TAG) + + # insert marker + marker = """ + + + + + """ # noqa: E501 + defs.append(etree.fromstring(marker)) + + # attach marker to node + style = node.get('style') or '' + style = style.split(";") + style = [i for i in style if not i.startswith('marker-start')] + style.append('marker-start:url(#inkstitch-guide-line-marker)') + node.set('style', ";".join(style)) -- cgit v1.2.3 From 125db3f83b3b330df757f7cc0faf6489b3cb348d Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 29 Oct 2021 16:18:22 +0200 Subject: Applied style guide --- lib/extensions/params.py | 125 ++++++++++++++++++------------ lib/extensions/selection_to_guide_line.py | 8 +- 2 files changed, 81 insertions(+), 52 deletions(-) (limited to 'lib/extensions') diff --git a/lib/extensions/params.py b/lib/extensions/params.py index 8021d5d7..30f6ba1d 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -7,9 +7,9 @@ import os import sys -from collections import defaultdict,namedtuple +from collections import defaultdict from copy import copy -from itertools import groupby,zip_longest +from itertools import groupby, zip_longest import wx from wx.lib.scrolledpanel import ScrolledPanel @@ -25,14 +25,11 @@ from ..utils import get_resource_dir from .base import InkstitchExtension -#ChoiceWidgets = namedtuple("ChoiceWidgets", "param widget last_initialized_choice") - - - def grouper(iterable_obj, count, fillvalue=None): args = [iter(iterable_obj)] * count return zip_longest(*args, fillvalue=fillvalue) + class ParamsTab(ScrolledPanel): def __init__(self, *args, **kwargs): self.params = kwargs.pop('params', []) @@ -56,14 +53,16 @@ class ParamsTab(ScrolledPanel): if toggles: self.toggle = toggles[0] self.params.remove(self.toggle) - self.toggle_checkbox = wx.CheckBox(self, label=self.toggle.description) + self.toggle_checkbox = wx.CheckBox( + self, label=self.toggle.description) value = any(self.toggle.values) if self.toggle.inverse: value = not value self.toggle_checkbox.SetValue(value) - self.toggle_checkbox.Bind(wx.EVT_CHECKBOX, self.update_toggle_state) + self.toggle_checkbox.Bind( + wx.EVT_CHECKBOX, self.update_toggle_state) self.toggle_checkbox.Bind(wx.EVT_CHECKBOX, self.changed) self.param_inputs[self.toggle.name] = self.toggle_checkbox @@ -76,7 +75,8 @@ class ParamsTab(ScrolledPanel): self.settings_grid.AddGrowableCol(1, 2) self.settings_grid.SetFlexibleDirection(wx.HORIZONTAL) - self.pencil_icon = wx.Image(os.path.join(get_resource_dir("icons"), "pencil_20x20.png")).ConvertToBitmap() + self.pencil_icon = wx.Image(os.path.join(get_resource_dir( + "icons"), "pencil_20x20.png")).ConvertToBitmap() self.__set_properties() self.__do_layout() @@ -230,19 +230,25 @@ class ParamsTab(ScrolledPanel): if len(self.nodes) == 1: description = _("These settings will be applied to 1 object.") else: - description = _("These settings will be applied to %d objects.") % len(self.nodes) + description = _( + "These settings will be applied to %d objects.") % len(self.nodes) if any(len(param.values) > 1 for param in self.params): - description += "\n • " + _("Some settings had different values across objects. Select a value from the dropdown or enter a new one.") + description += "\n • " + \ + _("Some settings had different values across objects. Select a value from the dropdown or enter a new one.") if self.dependent_tabs: if len(self.dependent_tabs) == 1: - description += "\n • " + _("Disabling this tab will disable the following %d tabs.") % len(self.dependent_tabs) + description += "\n • " + \ + _("Disabling this tab will disable the following %d tabs.") % len( + self.dependent_tabs) else: - description += "\n • " + _("Disabling this tab will disable the following tab.") + description += "\n • " + \ + _("Disabling this tab will disable the following tab.") if self.paired_tab: - description += "\n • " + _("Enabling this tab will disable %s and vice-versa.") % self.paired_tab.name + description += "\n • " + \ + _("Enabling this tab will disable %s and vice-versa.") % self.paired_tab.name self.description_text = description @@ -268,21 +274,21 @@ class ParamsTab(ScrolledPanel): # end wxGlade pass - #choice tuple is None or contains ("choice widget param name", "actual selection") - def update_choice_widgets(self, choice_tuple = None): - if choice_tuple == None: #update all choices + # choice tuple is None or contains ("choice widget param name", "actual selection") + def update_choice_widgets(self, choice_tuple=None): + if choice_tuple is None: # update all choices for choice in self.dict_of_choices.values(): - self.update_choice_widgets((choice["param"].name, choice["widget"].GetSelection())) + self.update_choice_widgets( + (choice["param"].name, choice["widget"].GetSelection())) else: choice = self.dict_of_choices[choice_tuple[0]] - last_selection = choice["last_initialized_choice"] + last_selection = choice["last_initialized_choice"] current_selection = choice["widget"].GetSelection() - if last_selection != -1 and last_selection != current_selection: #Hide the old widgets + if last_selection != -1 and last_selection != current_selection: # Hide the old widgets for widget in self.choice_widgets[(choice["param"].name, last_selection)]: widget.Hide() - #self.settings_grid.Detach(widget) - - #choice_index = self.settings_grid.GetChildren().index(self.settings_grid.GetItem(choice["widget"])) #TODO: is there a better way to get the index in the sizer? + # self.settings_grid.Detach(widget) + for widgets in grouper(self.choice_widgets[choice_tuple], 4): widgets[0].Show(True) widgets[1].Show(True) @@ -295,20 +301,24 @@ class ParamsTab(ScrolledPanel): # just to add space around the settings box = wx.BoxSizer(wx.VERTICAL) - summary_box = wx.StaticBox(self, wx.ID_ANY, label=_("Inkscape objects")) + summary_box = wx.StaticBox( + self, wx.ID_ANY, label=_("Inkscape objects")) sizer = wx.StaticBoxSizer(summary_box, wx.HORIZONTAL) self.description = wx.StaticText(self) self.update_description() self.description.SetLabel(self.description_text) self.description_container = box self.Bind(wx.EVT_SIZE, self.resized) - sizer.Add(self.description, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) + sizer.Add(self.description, proportion=0, + flag=wx.EXPAND | wx.ALL, border=5) box.Add(sizer, proportion=0, flag=wx.ALL, border=5) if self.toggle: toggle_sizer = wx.BoxSizer(wx.HORIZONTAL) - toggle_sizer.Add(self.create_change_indicator(self.toggle.name), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) - toggle_sizer.Add(self.toggle_checkbox, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) + toggle_sizer.Add(self.create_change_indicator( + self.toggle.name), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) + toggle_sizer.Add(self.toggle_checkbox, proportion=0, + flag=wx.ALIGN_CENTER_VERTICAL) box.Add(toggle_sizer, proportion=0, flag=wx.BOTTOM, border=10) for param in self.params: @@ -316,14 +326,16 @@ class ParamsTab(ScrolledPanel): description = wx.StaticText(self, label=param.description) description.SetToolTip(param.tooltip) - if param.select_items != None: + if param.select_items is not None: col1.Hide() description.Hide() for item in param.select_items: self.choice_widgets[item].extend([col1, description]) - #else: - self.settings_grid.Add(col1, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) - self.settings_grid.Add(description, proportion=1, flag=wx.EXPAND | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.TOP, border=5) + # else: + self.settings_grid.Add( + col1, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) + self.settings_grid.Add(description, proportion=1, flag=wx.EXPAND | + wx.RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.TOP, border=5) if param.type == 'boolean': if len(param.values) > 1: @@ -340,9 +352,11 @@ class ParamsTab(ScrolledPanel): input.SetSelection(int(param.values[0])) input.Bind(wx.EVT_CHOICE, self.changed) input.Bind(wx.EVT_CHOICE, self.update_choice_state) - self.dict_of_choices[param.name] = {"param": param, "widget": input, "last_initialized_choice": 1} + self.dict_of_choices[param.name] = { + "param": param, "widget": input, "last_initialized_choice": 1} elif len(param.values) > 1: - input = wx.ComboBox(self, wx.ID_ANY, choices=sorted(str(value) for value in param.values), style=wx.CB_DROPDOWN) + input = wx.ComboBox(self, wx.ID_ANY, choices=sorted( + str(value) for value in param.values), style=wx.CB_DROPDOWN) input.Bind(wx.EVT_COMBOBOX, self.changed) input.Bind(wx.EVT_TEXT, self.changed) else: @@ -354,14 +368,16 @@ class ParamsTab(ScrolledPanel): col4 = wx.StaticText(self, label=param.unit or "") - if param.select_items != None: + if param.select_items is not None: input.Hide() col4.Hide() for item in param.select_items: self.choice_widgets[item].extend([input, col4]) - #else: - self.settings_grid.Add(input, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND | wx.LEFT, border=40) - self.settings_grid.Add(col4, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL) + # else: + self.settings_grid.Add( + input, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND | wx.LEFT, border=40) + self.settings_grid.Add( + col4, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL) self.inputs_to_params = {v: k for k, v in self.param_inputs.items()} @@ -372,16 +388,20 @@ class ParamsTab(ScrolledPanel): self.Layout() def create_change_indicator(self, param): - indicator = wx.Button(self, style=wx.BORDER_NONE | wx.BU_NOTEXT, size=(28, 28)) - indicator.SetToolTip(_('Click to force this parameter to be saved when you click "Apply and Quit"')) - indicator.Bind(wx.EVT_BUTTON, lambda event: self.enable_change_indicator(param)) + indicator = wx.Button(self, style=wx.BORDER_NONE | + wx.BU_NOTEXT, size=(28, 28)) + indicator.SetToolTip( + _('Click to force this parameter to be saved when you click "Apply and Quit"')) + indicator.Bind( + wx.EVT_BUTTON, lambda event: self.enable_change_indicator(param)) self.param_change_indicators[param] = indicator return indicator def enable_change_indicator(self, param): self.param_change_indicators[param].SetBitmapLabel(self.pencil_icon) - self.param_change_indicators[param].SetToolTip(_('This parameter will be saved when you click "Apply and Quit"')) + self.param_change_indicators[param].SetToolTip( + _('This parameter will be saved when you click "Apply and Quit"')) self.changed_inputs.add(self.param_inputs[param]) @@ -407,7 +427,8 @@ class SettingsFrame(wx.Frame): _("Embroidery Params") ) - icon = wx.Icon(os.path.join(get_resource_dir("icons"), "inkstitch256x256.png")) + icon = wx.Icon(os.path.join( + get_resource_dir("icons"), "inkstitch256x256.png")) self.SetIcon(icon) self.notebook = wx.Notebook(self, wx.ID_ANY) @@ -425,7 +446,8 @@ class SettingsFrame(wx.Frame): self.cancel_button.Bind(wx.EVT_BUTTON, self.cancel) self.Bind(wx.EVT_CLOSE, self.cancel) - self.use_last_button = wx.Button(self, wx.ID_ANY, _("Use Last Settings")) + self.use_last_button = wx.Button( + self, wx.ID_ANY, _("Use Last Settings")) self.use_last_button.Bind(wx.EVT_BUTTON, self.use_last) self.apply_button = wx.Button(self, wx.ID_ANY, _("Apply and Quit")) @@ -544,7 +566,8 @@ class SettingsFrame(wx.Frame): for tab in self.tabs: self.notebook.AddPage(tab, tab.name) sizer_1.Add(self.warning_panel, 0, flag=wx.EXPAND | wx.ALL, border=10) - sizer_1.Add(self.notebook, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT, 10) + sizer_1.Add(self.notebook, 1, wx.EXPAND | + wx.LEFT | wx.TOP | wx.RIGHT, 10) sizer_1.Add(self.presets_panel, 0, flag=wx.EXPAND | wx.ALL, border=10) sizer_3.Add(self.cancel_button, 0, wx.RIGHT, 5) sizer_3.Add(self.use_last_button, 0, wx.RIGHT | wx.BOTTOM, 5) @@ -584,7 +607,7 @@ class Params(InkstitchExtension): else: if element.get_style("fill", 'black') and not element.get_style("fill-opacity", 1) == "0": classes.append(AutoFill) - #classes.append(Fill) + # classes.append(Fill) if element.get_style("stroke") is not None: classes.append(Stroke) if element.get_style("stroke-dasharray") is None: @@ -611,7 +634,8 @@ class Params(InkstitchExtension): else: getter = 'get_param' - values = [item for item in (getattr(node, getter)(param.name, param.default) for node in nodes) if item is not None] + values = [item for item in (getattr(node, getter)( + param.name, param.default) for node in nodes) if item is not None] return values @@ -677,7 +701,8 @@ class Params(InkstitchExtension): for group, params in self.group_params(params): tab_name = group or cls.element_name - tab = ParamsTab(parent, id=wx.ID_ANY, name=tab_name, params=list(params), nodes=nodes) + tab = ParamsTab(parent, id=wx.ID_ANY, name=tab_name, + params=list(params), nodes=nodes) new_tabs.append(tab) if group == "": @@ -697,14 +722,16 @@ class Params(InkstitchExtension): def effect(self): try: app = wx.App() - frame = SettingsFrame(tabs_factory=self.create_tabs, on_cancel=self.cancel) + frame = SettingsFrame( + tabs_factory=self.create_tabs, on_cancel=self.cancel) # position left, center current_screen = wx.Display.GetFromPoint(wx.GetMousePosition()) display = wx.Display(current_screen) display_size = display.GetClientArea() frame_size = frame.GetSize() - frame.SetPosition((int(display_size[0]), int(display_size[3]/2 - frame_size[1]/2))) + frame.SetPosition((int(display_size[0]), int( + display_size[3]/2 - frame_size[1]/2))) frame.Show() app.MainLoop() diff --git a/lib/extensions/selection_to_guide_line.py b/lib/extensions/selection_to_guide_line.py index 85a44bb1..e11cdb4e 100644 --- a/lib/extensions/selection_to_guide_line.py +++ b/lib/extensions/selection_to_guide_line.py @@ -18,11 +18,13 @@ class SelectionToGuideLine(InkstitchExtension): return if not self.svg.selected: - inkex.errormsg(_("Please select one object to be marked as a guide line.")) + inkex.errormsg( + _("Please select one object to be marked as a guide line.")) return - if len(self.get_nodes())!=1: - inkex.errormsg(_("Please select only one object to be marked as a guide line.")) + if len(self.get_nodes()) != 1: + inkex.errormsg( + _("Please select only one object to be marked as a guide line.")) return for guide_line in self.get_nodes(): -- cgit v1.2.3 From 8d19cdc59d00836fdf3ef037f31e7130771f84d2 Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 28 Jan 2022 21:54:20 +0100 Subject: adjusted selection_to_guide_line to match new marker creation way --- lib/extensions/selection_to_guide_line.py | 55 ++++--------------------------- 1 file changed, 6 insertions(+), 49 deletions(-) (limited to 'lib/extensions') diff --git a/lib/extensions/selection_to_guide_line.py b/lib/extensions/selection_to_guide_line.py index e11cdb4e..a0d32601 100644 --- a/lib/extensions/selection_to_guide_line.py +++ b/lib/extensions/selection_to_guide_line.py @@ -4,10 +4,10 @@ # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. import inkex -from lxml import etree from ..i18n import _ -from ..svg.tags import SVG_PATH_TAG, SVG_POLYLINE_TAG, SVG_DEFS_TAG +from ..marker import set_marker +from ..svg.tags import EMBROIDERABLE_TAGS from .base import InkstitchExtension @@ -18,52 +18,9 @@ class SelectionToGuideLine(InkstitchExtension): return if not self.svg.selected: - inkex.errormsg( - _("Please select one object to be marked as a guide line.")) + inkex.errormsg(_("Please select at least one object to be marked as a guide line.")) return - if len(self.get_nodes()) != 1: - inkex.errormsg( - _("Please select only one object to be marked as a guide line.")) - return - - for guide_line in self.get_nodes(): - if guide_line.tag in (SVG_PATH_TAG, SVG_POLYLINE_TAG): - self.set_marker(guide_line) - - def set_marker(self, node): - xpath = ".//marker[@id='inkstitch-guide-line-marker']" - guide_line_marker = self.document.xpath(xpath) - - if not guide_line_marker: - # get or create def element - defs = self.document.find(SVG_DEFS_TAG) - if defs is None: - defs = etree.SubElement(self.document, SVG_DEFS_TAG) - - # insert marker - marker = """ - - - - - """ # noqa: E501 - defs.append(etree.fromstring(marker)) - - # attach marker to node - style = node.get('style') or '' - style = style.split(";") - style = [i for i in style if not i.startswith('marker-start')] - style.append('marker-start:url(#inkstitch-guide-line-marker)') - node.set('style', ";".join(style)) + for pattern in self.get_nodes(): + if pattern.tag in EMBROIDERABLE_TAGS: + set_marker(pattern, 'start', 'guide-line') -- cgit v1.2.3 From 82216b184c669d6dea26672e5c0771146e62ca39 Mon Sep 17 00:00:00 2001 From: Kaalleen Date: Sat, 29 Jan 2022 09:53:50 +0100 Subject: remove some pattern and marker mixups and some style issues --- lib/extensions/base.py | 6 +++--- lib/extensions/params.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/extensions') diff --git a/lib/extensions/base.py b/lib/extensions/base.py index 56385458..cf846324 100644 --- a/lib/extensions/base.py +++ b/lib/extensions/base.py @@ -16,7 +16,7 @@ from ..commands import is_command, layer_commands from ..elements import EmbroideryElement, nodes_to_elements from ..elements.clone import is_clone from ..i18n import _ -from ..patterns import is_pattern +from ..marker import has_marker from ..svg import generate_unique_id from ..svg.tags import (CONNECTOR_TYPE, EMBROIDERABLE_TAGS, INKSCAPE_GROUPMODE, NOT_EMBROIDERABLE_TAGS, SVG_DEFS_TAG, SVG_GROUP_TAG) @@ -161,10 +161,10 @@ class InkstitchExtension(inkex.Effect): if selected: if node.tag == SVG_GROUP_TAG: pass - elif (node.tag in EMBROIDERABLE_TAGS or is_clone(node)) and not is_pattern(node): + elif (node.tag in EMBROIDERABLE_TAGS or is_clone(node)) and not has_marker(node, 'pattern'): nodes.append(node) # add images, text and patterns for the troubleshoot extension - elif troubleshoot and (node.tag in NOT_EMBROIDERABLE_TAGS or is_pattern(node)): + elif troubleshoot and (node.tag in NOT_EMBROIDERABLE_TAGS or has_marker(node, 'pattern')): nodes.append(node) return nodes diff --git a/lib/extensions/params.py b/lib/extensions/params.py index 30f6ba1d..55963625 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -296,7 +296,7 @@ class ParamsTab(ScrolledPanel): widgets[3].Show(True) choice["last_initialized_choice"] = current_selection - def __do_layout(self, only_settings_grid=False): + def __do_layout(self, only_settings_grid=False): # noqa: C901 # just to add space around the settings box = wx.BoxSizer(wx.VERTICAL) -- cgit v1.2.3 From 3d1600ed039c9078bcb4a28328ab60eb96994dfd Mon Sep 17 00:00:00 2001 From: Kaalleen Date: Sun, 30 Jan 2022 15:48:51 +0100 Subject: * autofill to fillstitch * remove too complex warning for fillstitch * some marker adjustments --- lib/extensions/base.py | 6 +++--- lib/extensions/cleanup.py | 4 ++-- lib/extensions/params.py | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'lib/extensions') diff --git a/lib/extensions/base.py b/lib/extensions/base.py index cf846324..949f947e 100644 --- a/lib/extensions/base.py +++ b/lib/extensions/base.py @@ -161,10 +161,10 @@ class InkstitchExtension(inkex.Effect): if selected: if node.tag == SVG_GROUP_TAG: pass - elif (node.tag in EMBROIDERABLE_TAGS or is_clone(node)) and not has_marker(node, 'pattern'): + elif (node.tag in EMBROIDERABLE_TAGS or is_clone(node)) and not has_marker(node): nodes.append(node) - # add images, text and patterns for the troubleshoot extension - elif troubleshoot and (node.tag in NOT_EMBROIDERABLE_TAGS or has_marker(node, 'pattern')): + # add images, text and elements with a marker for the troubleshoot extension + elif troubleshoot and (node.tag in NOT_EMBROIDERABLE_TAGS or has_marker(node)): nodes.append(node) return nodes diff --git a/lib/extensions/cleanup.py b/lib/extensions/cleanup.py index ae95041b..4c350d62 100644 --- a/lib/extensions/cleanup.py +++ b/lib/extensions/cleanup.py @@ -5,7 +5,7 @@ from inkex import NSS, Boolean, errormsg -from ..elements import AutoFill, Stroke +from ..elements import FillStitch, Stroke from ..i18n import _ from .base import InkstitchExtension @@ -38,7 +38,7 @@ class Cleanup(InkstitchExtension): return for element in self.elements: - if (isinstance(element, AutoFill) and self.rm_fill and element.shape.area < self.fill_threshold): + if (isinstance(element, FillStitch) and self.rm_fill and element.shape.area < self.fill_threshold): element.node.getparent().remove(element.node) count += 1 if (isinstance(element, Stroke) and self.rm_stroke and diff --git a/lib/extensions/params.py b/lib/extensions/params.py index 55963625..69a559ce 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -15,7 +15,7 @@ import wx from wx.lib.scrolledpanel import ScrolledPanel from ..commands import is_command, is_command_symbol -from ..elements import (AutoFill, Clone, EmbroideryElement, Polyline, +from ..elements import (FillStitch, Clone, EmbroideryElement, Polyline, SatinColumn, Stroke) from ..elements.clone import is_clone from ..gui import PresetsPanel, SimulatorPreview, WarningPanel @@ -606,8 +606,7 @@ class Params(InkstitchExtension): classes.append(Clone) else: if element.get_style("fill", 'black') and not element.get_style("fill-opacity", 1) == "0": - classes.append(AutoFill) - # classes.append(Fill) + classes.append(FillStitch) if element.get_style("stroke") is not None: classes.append(Stroke) if element.get_style("stroke-dasharray") is None: -- cgit v1.2.3 From d514eac81937bb64815239dd3aa96e38d6556a32 Mon Sep 17 00:00:00 2001 From: Andreas Date: Wed, 2 Feb 2022 21:19:31 +0100 Subject: adjusting namings --- lib/extensions/params.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/extensions') diff --git a/lib/extensions/params.py b/lib/extensions/params.py index 69a559ce..e50d97d0 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -86,7 +86,6 @@ class ParamsTab(ScrolledPanel): # end wxGlade def pair(self, tab): - # print self.name, "paired with", tab.name self.paired_tab = tab self.update_description() @@ -108,7 +107,6 @@ class ParamsTab(ScrolledPanel): def update_toggle_state(self, event=None, notify_pair=True): enable = self.enabled() - # print self.name, "update_toggle_state", enable for child in self.settings_grid.GetChildren(): widget = child.GetWindow() if widget: @@ -137,7 +135,6 @@ class ParamsTab(ScrolledPanel): event.Skip() def pair_changed(self, value): - # print self.name, "pair_changed", value new_value = not value if self.enabled() != new_value: @@ -192,7 +189,6 @@ class ParamsTab(ScrolledPanel): def apply(self): values = self.get_values() for node in self.nodes: - # print >> sys.stderr, "apply: ", self.name, node.id, values for name, value in values.items(): node.set_param(name, value) -- cgit v1.2.3 From e65aaebbcab1ca6fbcf99d9f3665af423e02c2f5 Mon Sep 17 00:00:00 2001 From: Kaalleen Date: Wed, 4 May 2022 20:04:39 +0200 Subject: rebase corrections --- lib/extensions/base.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'lib/extensions') diff --git a/lib/extensions/base.py b/lib/extensions/base.py index 949f947e..cf94714c 100644 --- a/lib/extensions/base.py +++ b/lib/extensions/base.py @@ -8,10 +8,12 @@ import os import re from collections.abc import MutableMapping -import inkex from lxml import etree +from lxml.etree import Comment from stringcase import snakecase +import inkex + from ..commands import is_command, layer_commands from ..elements import EmbroideryElement, nodes_to_elements from ..elements.clone import is_clone @@ -19,7 +21,8 @@ from ..i18n import _ from ..marker import has_marker from ..svg import generate_unique_id from ..svg.tags import (CONNECTOR_TYPE, EMBROIDERABLE_TAGS, INKSCAPE_GROUPMODE, - NOT_EMBROIDERABLE_TAGS, SVG_DEFS_TAG, SVG_GROUP_TAG) + NOT_EMBROIDERABLE_TAGS, SVG_CLIPPATH_TAG, SVG_DEFS_TAG, + SVG_GROUP_TAG, SVG_MASK_TAG) SVG_METADATA_TAG = inkex.addNS("metadata", "svg") @@ -129,6 +132,10 @@ class InkstitchExtension(inkex.Effect): def descendants(self, node, selected=False, troubleshoot=False): # noqa: C901 nodes = [] + + if node.tag == Comment: + return [] + element = EmbroideryElement(node) if element.has_command('ignore_object'): @@ -141,7 +148,9 @@ class InkstitchExtension(inkex.Effect): if (node.tag in EMBROIDERABLE_TAGS or node.tag == SVG_GROUP_TAG) and element.get_style('display', 'inline') is None: return [] - if node.tag == SVG_DEFS_TAG: + # defs, masks and clippaths can contain embroiderable elements + # but should never be rendered directly. + if node.tag in [SVG_DEFS_TAG, SVG_MASK_TAG, SVG_CLIPPATH_TAG]: return [] # command connectors with a fill color set, will glitch into the elements list -- cgit v1.2.3 From 672bded1259589d609d1a6656df5537c5da20569 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Fri, 6 May 2022 21:03:56 -0400 Subject: shapely geoms fixes --- lib/extensions/break_apart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/extensions') diff --git a/lib/extensions/break_apart.py b/lib/extensions/break_apart.py index 5bfd88a4..581e49bc 100644 --- a/lib/extensions/break_apart.py +++ b/lib/extensions/break_apart.py @@ -83,7 +83,7 @@ class BreakApart(InkstitchExtension): if diff.geom_type == 'MultiPolygon': polygons.remove(other) polygons.remove(polygon) - for p in diff: + for p in diff.geoms: polygons.append(p) # it is possible, that a polygons overlap with multiple # polygons, this means, we need to start all over again -- cgit v1.2.3