summaryrefslogtreecommitdiff
path: root/lib/extensions/params.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/extensions/params.py')
-rw-r--r--lib/extensions/params.py164
1 files changed, 125 insertions, 39 deletions
diff --git a/lib/extensions/params.py b/lib/extensions/params.py
index c96b9691..b60183e5 100644
--- a/lib/extensions/params.py
+++ b/lib/extensions/params.py
@@ -9,13 +9,13 @@ import os
import sys
from collections import defaultdict
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 (FillStitch, Clone, EmbroideryElement, Polyline,
SatinColumn, Stroke)
from ..elements.clone import is_clone
from ..gui import PresetsPanel, SimulatorPreview, WarningPanel
@@ -25,6 +25,11 @@ from ..utils import get_resource_dir
from .base import InkstitchExtension
+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 +43,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
@@ -46,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
@@ -66,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()
@@ -76,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()
@@ -98,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:
@@ -113,8 +121,21 @@ 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.Fit()
+ self.Layout()
+
+ if event:
+ event.Skip()
+
def pair_changed(self, value):
- # print self.name, "pair_changed", value
new_value = not value
if self.enabled() != new_value:
@@ -169,7 +190,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)
@@ -207,19 +227,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
@@ -245,35 +271,70 @@ 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 is 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)
+
+ 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): # noqa: C901
+
# 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:
- 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)
- 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 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)
+ if param.type == 'boolean':
if len(param.values) > 1:
input = wx.CheckBox(self, style=wx.CHK_3STATE)
input.Set3StateValue(wx.CHK_UNDETERMINED)
@@ -287,8 +348,12 @@ 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 = 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:
@@ -298,27 +363,42 @@ class ParamsTab(ScrolledPanel):
self.param_inputs[param.name] = input
- 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)
+ col4 = wx.StaticText(self, label=param.unit or "")
+
+ 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)
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()
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])
@@ -344,7 +424,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)
@@ -362,7 +443,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"))
@@ -481,7 +563,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)
@@ -520,8 +603,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:
@@ -548,7 +630,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
@@ -614,7 +697,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 == "":
@@ -634,14 +718,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()