kopia lustrzana https://github.com/inkstitch/inkstitch
Add annotations to tartan stripe editor main extension file (#3567)
rodzic
760c17b815
commit
78df0c73c6
|
@ -7,6 +7,7 @@ import sys
|
||||||
|
|
||||||
import wx
|
import wx
|
||||||
import wx.adv
|
import wx.adv
|
||||||
|
from inkex import ShapeElement
|
||||||
|
|
||||||
from ..gui.abort_message import AbortMessageApp
|
from ..gui.abort_message import AbortMessageApp
|
||||||
from ..gui.simulator import SplitSimulatorWindow
|
from ..gui.simulator import SplitSimulatorWindow
|
||||||
|
@ -19,53 +20,53 @@ from .base import InkstitchExtension
|
||||||
|
|
||||||
class Tartan(InkstitchExtension):
|
class Tartan(InkstitchExtension):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.elements = set()
|
self.nodes = set()
|
||||||
self.cancelled = False
|
self.cancelled = False
|
||||||
InkstitchExtension.__init__(self, *args, **kwargs)
|
InkstitchExtension.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self) -> None:
|
||||||
self.cancelled = True
|
self.cancelled = True
|
||||||
|
|
||||||
def get_tartan_elements(self):
|
def get_tartan_nodes(self) -> None:
|
||||||
if self.svg.selection:
|
if self.svg.selection:
|
||||||
for node in self.svg.selection:
|
for node in self.svg.selection:
|
||||||
self.get_selection(node)
|
self.get_selection(node)
|
||||||
|
|
||||||
def get_selection(self, node):
|
def get_selection(self, node: ShapeElement) -> None:
|
||||||
if node.TAG == 'g' and not node.get_id().startswith('inkstitch-tartan'):
|
if node.TAG == 'g' and not node.get_id().startswith('inkstitch-tartan'):
|
||||||
for child_node in node.iterchildren():
|
for child_node in node.iterchildren():
|
||||||
self.get_selection(child_node)
|
self.get_selection(child_node)
|
||||||
else:
|
else:
|
||||||
node = self.get_outline(node)
|
node = self.get_outline(node)
|
||||||
if node.tag in EMBROIDERABLE_TAGS and node.style('fill') is not None:
|
if node.tag in EMBROIDERABLE_TAGS and node.style('fill') is not None:
|
||||||
self.elements.add(node)
|
self.nodes.add(node)
|
||||||
|
|
||||||
def get_outline(self, node):
|
def get_outline(self, node: ShapeElement) -> ShapeElement:
|
||||||
# existing tartans are marked through their outline element
|
# existing tartans are marked through their outline node
|
||||||
# we have either selected the element itself or some other element within a tartan group
|
# we have either selected the node itself or some other nodes within a tartan group
|
||||||
if node.get(INKSTITCH_TARTAN, None) is not None:
|
if node.get(INKSTITCH_TARTAN, None) is not None:
|
||||||
return node
|
return node
|
||||||
if node.get_id().startswith('inkstitch-tartan'):
|
if node.get_id().startswith('inkstitch-tartan'):
|
||||||
for element in node.iterchildren(EMBROIDERABLE_TAGS):
|
for node in node.iterchildren(EMBROIDERABLE_TAGS):
|
||||||
if element.get(INKSTITCH_TARTAN, None):
|
if node.get(INKSTITCH_TARTAN, None):
|
||||||
return element
|
return node
|
||||||
for group in node.iterancestors(SVG_GROUP_TAG):
|
for group in node.iterancestors(SVG_GROUP_TAG):
|
||||||
if group.get_id().startswith('inkstitch-tartan'):
|
if group.get_id().startswith('inkstitch-tartan'):
|
||||||
for element in group.iterchildren(EMBROIDERABLE_TAGS):
|
for node in group.iterchildren(EMBROIDERABLE_TAGS):
|
||||||
if element.get(INKSTITCH_TARTAN, None) is not None:
|
if node.get(INKSTITCH_TARTAN, None) is not None:
|
||||||
return element
|
return node
|
||||||
# if we don't find an existing tartan, return node
|
# if we don't find an existing tartan, return node
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def effect(self):
|
def effect(self) -> None:
|
||||||
self.get_tartan_elements()
|
self.get_tartan_nodes()
|
||||||
|
|
||||||
if not self.elements:
|
if not self.nodes:
|
||||||
app = AbortMessageApp(
|
abort = AbortMessageApp(
|
||||||
_("To create a tartan pattern please select at least one element with a fill color."),
|
_("To create a tartan pattern please select at least one element with a fill color."),
|
||||||
_("https://inkstitch.org/docs/fill-tools/#tartan")
|
_("https://inkstitch.org/docs/fill-tools/#tartan")
|
||||||
)
|
)
|
||||||
app.MainLoop()
|
abort.MainLoop()
|
||||||
return
|
return
|
||||||
|
|
||||||
metadata = self.get_inkstitch_metadata()
|
metadata = self.get_inkstitch_metadata()
|
||||||
|
@ -75,7 +76,7 @@ class Tartan(InkstitchExtension):
|
||||||
frame = SplitSimulatorWindow(
|
frame = SplitSimulatorWindow(
|
||||||
title=_("Ink/Stitch Tartan"),
|
title=_("Ink/Stitch Tartan"),
|
||||||
panel_class=TartanMainPanel,
|
panel_class=TartanMainPanel,
|
||||||
elements=list(self.elements),
|
nodes=list(self.nodes),
|
||||||
on_cancel=self.cancel,
|
on_cancel=self.cancel,
|
||||||
metadata=metadata,
|
metadata=metadata,
|
||||||
background_color=background_color,
|
background_color=background_color,
|
||||||
|
|
|
@ -147,13 +147,14 @@ class EmbroideryPanel(wx.Panel):
|
||||||
if output == "svg":
|
if output == "svg":
|
||||||
self.embroidery_sizer.Show(self.svg_elements_sizer)
|
self.embroidery_sizer.Show(self.svg_elements_sizer)
|
||||||
self.embroidery_sizer.Hide(self.embroidery_element_sizer)
|
self.embroidery_sizer.Hide(self.embroidery_element_sizer)
|
||||||
for element in self.panel.elements:
|
for node in self.panel.nodes:
|
||||||
element.pop('inkstitch:fill_method')
|
node.pop('inkstitch:fill_method')
|
||||||
else:
|
else:
|
||||||
self.embroidery_sizer.Show(self.embroidery_element_sizer)
|
self.embroidery_sizer.Show(self.embroidery_element_sizer)
|
||||||
self.embroidery_sizer.Hide(self.svg_elements_sizer)
|
self.embroidery_sizer.Hide(self.svg_elements_sizer)
|
||||||
for element in self.panel.elements:
|
for node in self.panel.nodes:
|
||||||
element.set('inkstitch:fill_method', 'tartan_fill')
|
node.set('inkstitch:fill_method', 'tartan_fill')
|
||||||
|
node.style['display'] = "inline"
|
||||||
self.panel.settings['output'] = output
|
self.panel.settings['output'] = output
|
||||||
self.Layout()
|
self.Layout()
|
||||||
self.panel.update_preview()
|
self.panel.update_preview()
|
||||||
|
@ -180,8 +181,8 @@ class EmbroideryPanel(wx.Panel):
|
||||||
self.panel.update_preview()
|
self.panel.update_preview()
|
||||||
|
|
||||||
def on_param_change(self, attribute, event):
|
def on_param_change(self, attribute, event):
|
||||||
for element in self.panel.elements:
|
for node in self.panel.nodes:
|
||||||
element.set(f'inkstitch:{attribute}', str(event.GetEventObject().GetValue()))
|
node.set(f'inkstitch:{attribute}', str(event.GetEventObject().GetValue()))
|
||||||
self.panel.update_preview()
|
self.panel.update_preview()
|
||||||
|
|
||||||
def set_stitch_type(self, choice):
|
def set_stitch_type(self, choice):
|
||||||
|
|
|
@ -9,7 +9,7 @@ from copy import copy
|
||||||
import wx
|
import wx
|
||||||
import wx.adv
|
import wx.adv
|
||||||
|
|
||||||
from ...elements import FillStitch, nodes_to_elements
|
from ...elements import nodes_to_elements
|
||||||
from ...exceptions import InkstitchException, format_uncaught_exception
|
from ...exceptions import InkstitchException, format_uncaught_exception
|
||||||
from ...i18n import _
|
from ...i18n import _
|
||||||
from ...stitch_plan import stitch_groups_to_stitch_plan
|
from ...stitch_plan import stitch_groups_to_stitch_plan
|
||||||
|
@ -25,10 +25,10 @@ from . import CodePanel, CustomizePanel, EmbroideryPanel, HelpPanel
|
||||||
|
|
||||||
class TartanMainPanel(wx.Panel):
|
class TartanMainPanel(wx.Panel):
|
||||||
|
|
||||||
def __init__(self, parent, simulator, elements, metadata=None, background_color='white'):
|
def __init__(self, parent, simulator, nodes, metadata=None, background_color='white'):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.simulator = simulator
|
self.simulator = simulator
|
||||||
self.elements = elements
|
self.nodes = nodes
|
||||||
self.palette = Palette()
|
self.palette = Palette()
|
||||||
self.metadata = metadata or dict()
|
self.metadata = metadata or dict()
|
||||||
self.background_color = background_color
|
self.background_color = background_color
|
||||||
|
@ -129,7 +129,7 @@ class TartanMainPanel(wx.Panel):
|
||||||
})
|
})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.settings.update(json.loads(self.elements[0].get(INKSTITCH_TARTAN)))
|
self.settings.update(json.loads(self.nodes[0].get(INKSTITCH_TARTAN)))
|
||||||
except (TypeError, ValueError, IndexError):
|
except (TypeError, ValueError, IndexError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -147,13 +147,13 @@ class TartanMainPanel(wx.Panel):
|
||||||
self.embroidery_panel.angle_weft.SetValue(self.settings.angle_weft)
|
self.embroidery_panel.angle_weft.SetValue(self.settings.angle_weft)
|
||||||
self.embroidery_panel.min_stripe_width.SetValue(self.settings.min_stripe_width)
|
self.embroidery_panel.min_stripe_width.SetValue(self.settings.min_stripe_width)
|
||||||
self.embroidery_panel.svg_bean_stitch_repeats.SetValue(self.settings.bean_stitch_repeats)
|
self.embroidery_panel.svg_bean_stitch_repeats.SetValue(self.settings.bean_stitch_repeats)
|
||||||
self.embroidery_panel.stitch_angle.SetValue(self.elements[0].get('inkstitch:tartan_angle', -45))
|
self.embroidery_panel.stitch_angle.SetValue(self.nodes[0].get('inkstitch:tartan_angle', -45))
|
||||||
self.embroidery_panel.rows_per_thread.SetValue(self.elements[0].get('inkstitch:rows_per_thread', 2))
|
self.embroidery_panel.rows_per_thread.SetValue(self.nodes[0].get('inkstitch:rows_per_thread', 2))
|
||||||
self.embroidery_panel.row_spacing.SetValue(self.elements[0].get('inkstitch:row_spacing_mm', 0.25))
|
self.embroidery_panel.row_spacing.SetValue(self.nodes[0].get('inkstitch:row_spacing_mm', 0.25))
|
||||||
underlay = self.elements[0].get('inkstitch:fill_underlay', "True").lower() in ('yes', 'y', 'true', 't', '1')
|
underlay = self.nodes[0].get('inkstitch:fill_underlay', "True").lower() in ('yes', 'y', 'true', 't', '1')
|
||||||
self.embroidery_panel.underlay.SetValue(underlay)
|
self.embroidery_panel.underlay.SetValue(underlay)
|
||||||
self.embroidery_panel.herringbone.SetValue(self.elements[0].get('inkstitch:herringbone_width_mm', 0))
|
self.embroidery_panel.herringbone.SetValue(self.nodes[0].get('inkstitch:herringbone_width_mm', 0))
|
||||||
self.embroidery_panel.bean_stitch_repeats.SetValue(self.elements[0].get('inkstitch:bean_stitch_repeats', '0'))
|
self.embroidery_panel.bean_stitch_repeats.SetValue(self.nodes[0].get('inkstitch:bean_stitch_repeats', '0'))
|
||||||
|
|
||||||
self.update_from_code()
|
self.update_from_code()
|
||||||
|
|
||||||
|
@ -163,9 +163,9 @@ class TartanMainPanel(wx.Panel):
|
||||||
self.customize_panel.update_warp_weft()
|
self.customize_panel.update_warp_weft()
|
||||||
|
|
||||||
def save_settings(self):
|
def save_settings(self):
|
||||||
"""Save the settings into the SVG elements."""
|
"""Save the settings into the SVG nodes."""
|
||||||
for element in self.elements:
|
for node in self.nodes:
|
||||||
element.set(INKSTITCH_TARTAN, json.dumps(self.settings))
|
node.set(INKSTITCH_TARTAN, json.dumps(self.settings))
|
||||||
|
|
||||||
def get_preset_data(self):
|
def get_preset_data(self):
|
||||||
# called by self.presets_panel
|
# called by self.presets_panel
|
||||||
|
@ -213,16 +213,17 @@ class TartanMainPanel(wx.Panel):
|
||||||
stitch_groups = self._get_svg_stitch_groups()
|
stitch_groups = self._get_svg_stitch_groups()
|
||||||
else:
|
else:
|
||||||
self.save_settings()
|
self.save_settings()
|
||||||
|
elements = nodes_to_elements(self.nodes)
|
||||||
stitch_groups = []
|
stitch_groups = []
|
||||||
previous_stitch_group = None
|
previous_stitch_group = None
|
||||||
next_elements = [None]
|
next_elements = [None]
|
||||||
if len(self.elements) > 1:
|
if len(elements) > 1:
|
||||||
next_elements = self.elements[1:] + next_elements
|
next_elements = elements[1:] + next_elements
|
||||||
for element, next_element in zip(self.elements, next_elements):
|
for element, next_element in zip(elements, next_elements):
|
||||||
check_stop_flag()
|
check_stop_flag()
|
||||||
try:
|
try:
|
||||||
# copy the embroidery element to drop the cache
|
# copy the embroidery element to drop the cache
|
||||||
stitch_groups.extend(copy(FillStitch(element)).embroider(previous_stitch_group, next_element))
|
stitch_groups.extend(copy(element).embroider(previous_stitch_group, next_element))
|
||||||
if stitch_groups:
|
if stitch_groups:
|
||||||
previous_stitch_group = stitch_groups[-1]
|
previous_stitch_group = stitch_groups[-1]
|
||||||
except (SystemExit, ExitThread):
|
except (SystemExit, ExitThread):
|
||||||
|
@ -242,19 +243,19 @@ class TartanMainPanel(wx.Panel):
|
||||||
def _get_svg_stitch_groups(self):
|
def _get_svg_stitch_groups(self):
|
||||||
stitch_groups = []
|
stitch_groups = []
|
||||||
previous_stitch_group = None
|
previous_stitch_group = None
|
||||||
for element in self.elements:
|
for node in self.nodes:
|
||||||
parent = element.getparent()
|
parent = node.getparent()
|
||||||
embroidery_elements = nodes_to_elements(parent.iterdescendants())
|
elements = nodes_to_elements(parent.iterdescendants())
|
||||||
next_elements = [None]
|
next_elements = [None]
|
||||||
if len(embroidery_elements) > 1:
|
if len(elements) > 1:
|
||||||
next_elements = embroidery_elements[1:] + next_elements
|
next_elements = elements[1:] + next_elements
|
||||||
for embroidery_element, next_element in zip(embroidery_elements, next_elements):
|
for element, next_element in zip(elements, next_elements):
|
||||||
check_stop_flag()
|
check_stop_flag()
|
||||||
if embroidery_element.node == element:
|
if element.node == node:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
# copy the embroidery element to drop the cache
|
# copy the embroidery element to drop the cache
|
||||||
stitch_groups.extend(copy(embroidery_element).embroider(previous_stitch_group, next_element))
|
stitch_groups.extend(copy(element).embroider(previous_stitch_group, next_element))
|
||||||
if stitch_groups:
|
if stitch_groups:
|
||||||
previous_stitch_group = stitch_groups[-1]
|
previous_stitch_group = stitch_groups[-1]
|
||||||
except InkstitchException:
|
except InkstitchException:
|
||||||
|
@ -264,12 +265,12 @@ class TartanMainPanel(wx.Panel):
|
||||||
return stitch_groups
|
return stitch_groups
|
||||||
|
|
||||||
def update_tartan(self):
|
def update_tartan(self):
|
||||||
for element in self.elements:
|
for node in self.nodes:
|
||||||
check_stop_flag()
|
check_stop_flag()
|
||||||
if self.settings['output'] == 'svg':
|
if self.settings['output'] == 'svg':
|
||||||
TartanSvgGroup(self.settings).generate(element)
|
TartanSvgGroup(self.settings).generate(node)
|
||||||
else:
|
else:
|
||||||
prepare_tartan_fill_element(element)
|
prepare_tartan_fill_element(node)
|
||||||
|
|
||||||
def on_stitch_plan_rendered(self, stitch_plan):
|
def on_stitch_plan_rendered(self, stitch_plan):
|
||||||
self.simulator.stop()
|
self.simulator.stop()
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<name>Tartan</name>
|
<name>Tartan</name>
|
||||||
<id>org.{{ id_inkstitch }}.tartan</id>
|
<id>org.{{ id_inkstitch }}.tartan</id>
|
||||||
<param name="extension" type="string" gui-hidden="true">tartan</param>
|
<param name="extension" type="string" gui-hidden="true">tartan</param>
|
||||||
<effect implements-custom-gui="true">
|
<effect implements-custom-gui="true" show-stderr="true">
|
||||||
<object-type>all</object-type>
|
<object-type>all</object-type>
|
||||||
<icon>{{ icon_path }}inx/tartan.svg</icon>
|
<icon>{{ icon_path }}inx/tartan.svg</icon>
|
||||||
<menu-tip>Tartan stripe editor</menu-tip>
|
<menu-tip>Tartan stripe editor</menu-tip>
|
||||||
|
|
Ładowanie…
Reference in New Issue