meerk40t 0.9.7030__py2.py3-none-any.whl → 0.9.7040__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerk40t/balormk/clone_loader.py +3 -2
- meerk40t/balormk/controller.py +28 -11
- meerk40t/balormk/cylindermod.py +1 -0
- meerk40t/balormk/device.py +13 -9
- meerk40t/balormk/driver.py +9 -2
- meerk40t/balormk/galvo_commands.py +3 -1
- meerk40t/balormk/gui/gui.py +6 -0
- meerk40t/balormk/livelightjob.py +338 -321
- meerk40t/balormk/mock_connection.py +4 -3
- meerk40t/balormk/usb_connection.py +11 -2
- meerk40t/camera/camera.py +19 -14
- meerk40t/camera/gui/camerapanel.py +6 -0
- meerk40t/core/cutplan.py +109 -51
- meerk40t/core/elements/element_treeops.py +435 -140
- meerk40t/core/elements/elements.py +100 -9
- meerk40t/core/elements/shapes.py +259 -39
- meerk40t/core/elements/tree_commands.py +10 -5
- meerk40t/core/node/elem_ellipse.py +18 -8
- meerk40t/core/node/elem_image.py +51 -19
- meerk40t/core/node/elem_line.py +18 -8
- meerk40t/core/node/elem_path.py +18 -8
- meerk40t/core/node/elem_point.py +10 -4
- meerk40t/core/node/elem_polyline.py +19 -11
- meerk40t/core/node/elem_rect.py +18 -8
- meerk40t/core/node/elem_text.py +11 -5
- meerk40t/core/node/filenode.py +2 -8
- meerk40t/core/node/groupnode.py +11 -11
- meerk40t/core/node/image_processed.py +11 -5
- meerk40t/core/node/image_raster.py +11 -5
- meerk40t/core/node/node.py +64 -16
- meerk40t/core/node/refnode.py +2 -1
- meerk40t/core/svg_io.py +91 -34
- meerk40t/device/dummydevice.py +7 -1
- meerk40t/extra/vtracer.py +222 -0
- meerk40t/grbl/device.py +81 -8
- meerk40t/gui/about.py +20 -0
- meerk40t/gui/devicepanel.py +20 -16
- meerk40t/gui/gui_mixins.py +4 -0
- meerk40t/gui/icons.py +330 -253
- meerk40t/gui/laserpanel.py +8 -3
- meerk40t/gui/laserrender.py +41 -21
- meerk40t/gui/magnetoptions.py +158 -65
- meerk40t/gui/materialtest.py +229 -39
- meerk40t/gui/navigationpanels.py +229 -24
- meerk40t/gui/propertypanels/hatchproperty.py +2 -0
- meerk40t/gui/propertypanels/imageproperty.py +160 -106
- meerk40t/gui/ribbon.py +6 -1
- meerk40t/gui/scenewidgets/gridwidget.py +29 -32
- meerk40t/gui/scenewidgets/rectselectwidget.py +190 -192
- meerk40t/gui/simulation.py +75 -77
- meerk40t/gui/statusbarwidgets/defaultoperations.py +84 -48
- meerk40t/gui/statusbarwidgets/infowidget.py +2 -2
- meerk40t/gui/tips.py +15 -1
- meerk40t/gui/toolwidgets/toolpointmove.py +3 -1
- meerk40t/gui/wxmmain.py +242 -114
- meerk40t/gui/wxmscene.py +107 -24
- meerk40t/gui/wxmtree.py +4 -2
- meerk40t/gui/wxutils.py +60 -15
- meerk40t/image/imagetools.py +129 -65
- meerk40t/internal_plugins.py +4 -0
- meerk40t/kernel/kernel.py +39 -18
- meerk40t/kernel/settings.py +28 -9
- meerk40t/lihuiyu/device.py +24 -12
- meerk40t/main.py +1 -1
- meerk40t/moshi/device.py +20 -6
- meerk40t/network/console_server.py +22 -6
- meerk40t/newly/device.py +10 -3
- meerk40t/newly/gui/gui.py +10 -0
- meerk40t/ruida/device.py +22 -2
- meerk40t/ruida/loader.py +6 -3
- meerk40t/tools/geomstr.py +193 -125
- meerk40t/tools/rasterplotter.py +179 -93
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7040.dist-info}/METADATA +1 -1
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7040.dist-info}/RECORD +79 -78
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7040.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7040.dist-info}/WHEEL +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7040.dist-info}/entry_points.txt +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7040.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7040.dist-info}/zip-safe +0 -0
meerk40t/gui/laserpanel.py
CHANGED
@@ -18,7 +18,7 @@ from meerk40t.gui.icons import (
|
|
18
18
|
icons8_pentagon,
|
19
19
|
icons8_save,
|
20
20
|
)
|
21
|
-
from meerk40t.gui.navigationpanels import Drag, Jog,
|
21
|
+
from meerk40t.gui.navigationpanels import Drag, Jog, JogDistancePanel, MovePanel
|
22
22
|
from meerk40t.gui.wxutils import (
|
23
23
|
HoverButton,
|
24
24
|
ScrolledPanel,
|
@@ -45,7 +45,7 @@ def register_panel_laser(window, context):
|
|
45
45
|
# jog_drag = wx.Panel(window, wx.ID_ANY)
|
46
46
|
jog_drag = ScrolledPanel(window, wx.ID_ANY)
|
47
47
|
jog_drag.SetupScrolling()
|
48
|
-
jog_panel = Jog(jog_drag, wx.ID_ANY, context=context)
|
48
|
+
jog_panel = Jog(jog_drag, wx.ID_ANY, context=context, suppress_z_controls=True)
|
49
49
|
drag_panel = Drag(jog_drag, wx.ID_ANY, context=context)
|
50
50
|
distance_panel = JogDistancePanel(jog_drag, wx.ID_ANY, context=context)
|
51
51
|
main_sizer = wx.BoxSizer(wx.VERTICAL)
|
@@ -95,7 +95,7 @@ def register_panel_laser(window, context):
|
|
95
95
|
notebook.AddPage(plan_panel, _("Plan"))
|
96
96
|
notebook.AddPage(optimize_panel, _("Optimize"))
|
97
97
|
notebook.AddPage(move_panel, _("Move"))
|
98
|
-
|
98
|
+
|
99
99
|
def on_page_change(event):
|
100
100
|
event.Skip()
|
101
101
|
page = notebook.GetCurrentPage()
|
@@ -366,6 +366,8 @@ class LaserPanel(wx.Panel):
|
|
366
366
|
self.Bind(wx.EVT_CHECKBOX, self.on_optimize, self.checkbox_optimize)
|
367
367
|
# self.btn_config_laser.Bind(wx.EVT_LEFT_DOWN, self.on_config_button)
|
368
368
|
self.btn_config_laser.Bind(wx.EVT_BUTTON, self.on_config_button)
|
369
|
+
self.combo_devices.Bind(wx.EVT_RIGHT_DOWN, self.on_control_right)
|
370
|
+
self.btn_config_laser.Bind(wx.EVT_RIGHT_DOWN, self.on_control_right)
|
369
371
|
# end wxGlade
|
370
372
|
self.checkbox_adjust.SetValue(False)
|
371
373
|
self.on_check_adjust(None)
|
@@ -698,6 +700,9 @@ class LaserPanel(wx.Panel):
|
|
698
700
|
self.context(f"window open Simulation z 0 {param}\n")
|
699
701
|
self.context.kernel.busyinfo.end()
|
700
702
|
|
703
|
+
def on_control_right(self, event): # wxGlade: LaserPanel.<event_handler>
|
704
|
+
self.context("window open DeviceManager\n")
|
705
|
+
|
701
706
|
def on_combo_devices(self, event): # wxGlade: LaserPanel.<event_handler>
|
702
707
|
index = self.combo_devices.GetSelection()
|
703
708
|
try:
|
meerk40t/gui/laserrender.py
CHANGED
@@ -6,6 +6,7 @@ from PIL import Image
|
|
6
6
|
|
7
7
|
from meerk40t.core.elements.element_types import place_nodes
|
8
8
|
from meerk40t.core.node.node import Fillrule, Linecap, Linejoin, Node
|
9
|
+
from meerk40t.gui.wxutils import get_gc_scale
|
9
10
|
from meerk40t.svgelements import (
|
10
11
|
Arc,
|
11
12
|
Close,
|
@@ -39,7 +40,6 @@ from ..tools.geomstr import ( # , TYPE_RAMP
|
|
39
40
|
from .fonts import wxfont_to_svg
|
40
41
|
from .icons import icons8_image
|
41
42
|
from .zmatrix import ZMatrix
|
42
|
-
from meerk40t.gui.wxutils import get_gc_scale
|
43
43
|
|
44
44
|
DRAW_MODE_FILLS = 0x000001
|
45
45
|
DRAW_MODE_GUIDES = 0x000002
|
@@ -211,7 +211,9 @@ class LaserRender:
|
|
211
211
|
c, gc, draw_mode=draw_mode, zoomscale=zoomscale, alpha=alpha
|
212
212
|
)
|
213
213
|
|
214
|
-
def render(
|
214
|
+
def render(
|
215
|
+
self, nodes, gc, draw_mode=None, zoomscale=1.0, alpha=255, msg="unknown"
|
216
|
+
):
|
215
217
|
"""
|
216
218
|
Render scene information.
|
217
219
|
|
@@ -268,7 +270,10 @@ class LaserRender:
|
|
268
270
|
self.render_node(
|
269
271
|
node, gc, draw_mode=draw_mode, zoomscale=zoomscale, alpha=alpha
|
270
272
|
)
|
271
|
-
self.context.elements.set_end_time(
|
273
|
+
self.context.elements.set_end_time(
|
274
|
+
f"renderscene_{msg}",
|
275
|
+
message=f"Rendered: {self.nodes_rendered}, skipped: {self.nodes_skipped}, caches created: {self.caches_generated}",
|
276
|
+
)
|
272
277
|
|
273
278
|
def render_node(self, node, gc, draw_mode=None, zoomscale=1.0, alpha=255):
|
274
279
|
"""
|
@@ -282,11 +287,16 @@ class LaserRender:
|
|
282
287
|
"""
|
283
288
|
node_bb = node.bounds if hasattr(node, "bounds") else None
|
284
289
|
vis_bb = self._visible_area
|
285
|
-
if
|
286
|
-
|
287
|
-
|
288
|
-
node_bb
|
289
|
-
|
290
|
+
if (
|
291
|
+
self.suppress_it
|
292
|
+
and vis_bb is not None
|
293
|
+
and node_bb is not None
|
294
|
+
and (
|
295
|
+
node_bb[0] > vis_bb[2]
|
296
|
+
or node_bb[1] > vis_bb[3]
|
297
|
+
or node_bb[2] < vis_bb[0]
|
298
|
+
or node_bb[3] < vis_bb[1]
|
299
|
+
)
|
290
300
|
):
|
291
301
|
self.nodes_skipped += 1
|
292
302
|
return False
|
@@ -300,7 +310,7 @@ class LaserRender:
|
|
300
310
|
self.nodes_skipped += 1
|
301
311
|
return False
|
302
312
|
self.nodes_rendered += 1
|
303
|
-
if not hasattr(node, "draw"):
|
313
|
+
if not hasattr(node, "draw"): # or not hasattr(node, "_make_cache"):
|
304
314
|
# No known render method, we must define the function to draw nodes.
|
305
315
|
if node.type in (
|
306
316
|
"elem path",
|
@@ -562,10 +572,11 @@ class LaserRender:
|
|
562
572
|
self,
|
563
573
|
cutcode: CutCode,
|
564
574
|
gc: wx.GraphicsContext,
|
565
|
-
x: int = 0,
|
575
|
+
x: int = 0,
|
576
|
+
y: int = 0,
|
566
577
|
raster_as_image: bool = True,
|
567
|
-
residual
|
568
|
-
laserspot_width
|
578
|
+
residual=None,
|
579
|
+
laserspot_width=None,
|
569
580
|
):
|
570
581
|
"""
|
571
582
|
Draw cutcode object into wxPython graphics code.
|
@@ -591,7 +602,6 @@ class LaserRender:
|
|
591
602
|
return max(default_pix, pixelwidth)
|
592
603
|
|
593
604
|
def process_cut(cut, p, last_point):
|
594
|
-
|
595
605
|
def process_as_image():
|
596
606
|
image = cut.image
|
597
607
|
gc.PushState()
|
@@ -836,7 +846,9 @@ class LaserRender:
|
|
836
846
|
q = ~cache_matrix * matrix
|
837
847
|
gc.ConcatTransform(wx.GraphicsContext.CreateMatrix(gc, ZMatrix(q)))
|
838
848
|
# Applying the matrix will scale our stroke, so we scale the stroke back down.
|
839
|
-
stroke_factor =
|
849
|
+
stroke_factor = (
|
850
|
+
1.0 if q.determinant == 0 else 1.0 / sqrt(abs(q.determinant))
|
851
|
+
)
|
840
852
|
self._set_linecap_by_node(node)
|
841
853
|
self._set_linejoin_by_node(node)
|
842
854
|
sw = node.implied_stroke_width * stroke_factor
|
@@ -1140,7 +1152,9 @@ class LaserRender:
|
|
1140
1152
|
matrix = node.active_matrix
|
1141
1153
|
bounds = 0, 0, image.width, image.height
|
1142
1154
|
if matrix is not None and not matrix.is_identity():
|
1143
|
-
gc.ConcatTransform(
|
1155
|
+
gc.ConcatTransform(
|
1156
|
+
wx.GraphicsContext.CreateMatrix(gc, ZMatrix(matrix))
|
1157
|
+
)
|
1144
1158
|
except AttributeError:
|
1145
1159
|
pass
|
1146
1160
|
|
@@ -1341,15 +1355,16 @@ class LaserRender:
|
|
1341
1355
|
"""
|
1342
1356
|
if bounds is None:
|
1343
1357
|
return None
|
1358
|
+
# Cover invalid step values
|
1359
|
+
if step_x == 0:
|
1360
|
+
step_x = 1
|
1361
|
+
if step_y == 0:
|
1362
|
+
step_y = 1
|
1344
1363
|
x_min = float("inf")
|
1345
1364
|
y_min = float("inf")
|
1346
1365
|
x_max = -float("inf")
|
1347
1366
|
y_max = -float("inf")
|
1348
|
-
if not isinstance(nodes, (tuple, list))
|
1349
|
-
_nodes = [nodes]
|
1350
|
-
else:
|
1351
|
-
_nodes = nodes
|
1352
|
-
|
1367
|
+
_nodes = [nodes] if not isinstance(nodes, (tuple, list)) else nodes
|
1353
1368
|
# if it's a raster we will always translate text variables...
|
1354
1369
|
variable_translation = True
|
1355
1370
|
nodecopy = list(_nodes)
|
@@ -1415,7 +1430,12 @@ class LaserRender:
|
|
1415
1430
|
gc.ConcatTransform(wx.GraphicsContext.CreateMatrix(gc, ZMatrix(matrix)))
|
1416
1431
|
gc.SetBrush(wx.WHITE_BRUSH)
|
1417
1432
|
gc.DrawRectangle(x_min - 1, y_min - 1, x_max + 1, y_max + 1)
|
1418
|
-
self.render(
|
1433
|
+
self.render(
|
1434
|
+
_nodes,
|
1435
|
+
gc,
|
1436
|
+
draw_mode=DRAW_MODE_CACHE | DRAW_MODE_VARIABLES,
|
1437
|
+
msg="make_raster",
|
1438
|
+
)
|
1419
1439
|
img = bmp.ConvertToImage()
|
1420
1440
|
buf = img.GetData()
|
1421
1441
|
image = Image.frombuffer(
|
meerk40t/gui/magnetoptions.py
CHANGED
@@ -2,7 +2,15 @@ import wx
|
|
2
2
|
from wx import aui
|
3
3
|
|
4
4
|
from meerk40t.core.units import Length
|
5
|
-
from meerk40t.gui.wxutils import
|
5
|
+
from meerk40t.gui.wxutils import (
|
6
|
+
StaticBoxSizer,
|
7
|
+
TextCtrl,
|
8
|
+
dip_size,
|
9
|
+
wxButton,
|
10
|
+
wxCheckBox,
|
11
|
+
wxComboBox,
|
12
|
+
wxStaticText,
|
13
|
+
)
|
6
14
|
from meerk40t.kernel import signal_listener
|
7
15
|
|
8
16
|
_ = wx.GetTranslation
|
@@ -41,34 +49,54 @@ class MagnetOptionPanel(wx.Panel):
|
|
41
49
|
|
42
50
|
# Main Sizer
|
43
51
|
sizer_magnet = wx.BoxSizer(wx.VERTICAL)
|
44
|
-
sizer_affection = StaticBoxSizer(
|
52
|
+
sizer_affection = StaticBoxSizer(
|
53
|
+
self, wx.ID_ANY, _("Attraction areas..."), wx.HORIZONTAL
|
54
|
+
)
|
45
55
|
self.check_x = wxCheckBox(self, wx.ID_ANY, _("Left/Right Side"))
|
46
|
-
self.check_x.SetToolTip(
|
56
|
+
self.check_x.SetToolTip(
|
57
|
+
_("Will a magnet line attract the left/right edges of an object")
|
58
|
+
)
|
47
59
|
self.check_y = wxCheckBox(self, wx.ID_ANY, _("Top/Bottom Side"))
|
48
|
-
self.check_y.SetToolTip(
|
60
|
+
self.check_y.SetToolTip(
|
61
|
+
_("Will a magnet line attract the top/bottom edges of an object")
|
62
|
+
)
|
49
63
|
self.check_c = wxCheckBox(self, wx.ID_ANY, _("Center"))
|
50
64
|
self.check_c.SetToolTip(_("Will a magnet line attract the center of an object"))
|
51
65
|
sizer_affection.Add(self.check_x, 1, wx.EXPAND, 0)
|
52
66
|
sizer_affection.Add(self.check_y, 1, wx.EXPAND, 0)
|
53
67
|
sizer_affection.Add(self.check_c, 1, wx.EXPAND, 0)
|
54
|
-
|
55
|
-
sizer_strength = StaticBoxSizer(
|
68
|
+
|
69
|
+
sizer_strength = StaticBoxSizer(
|
70
|
+
self, wx.ID_ANY, _("Attraction strength..."), wx.HORIZONTAL
|
71
|
+
)
|
56
72
|
choices = [
|
57
|
-
_("Off"),
|
58
|
-
_("Weak"),
|
59
|
-
_("Normal"),
|
60
|
-
_("Strong"),
|
61
|
-
_("Very Strong"),
|
62
|
-
_("Enormous"),
|
73
|
+
_("Off"),
|
74
|
+
_("Weak"),
|
75
|
+
_("Normal"),
|
76
|
+
_("Strong"),
|
77
|
+
_("Very Strong"),
|
78
|
+
_("Enormous"),
|
63
79
|
]
|
64
|
-
self.cbo_strength = wxComboBox(
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
80
|
+
self.cbo_strength = wxComboBox(
|
81
|
+
self, wx.ID_ANY, choices=choices, style=wx.CB_DROPDOWN | wx.CB_READONLY
|
82
|
+
)
|
83
|
+
self.cbo_strength.SetToolTip(
|
84
|
+
_(
|
85
|
+
"Define the attraction strength from weak (very close) to enormous (from far away)"
|
86
|
+
)
|
87
|
+
)
|
88
|
+
sizer_strength.Add(self.cbo_strength, 1, wx.EXPAND, 0)
|
89
|
+
|
90
|
+
sizer_template = StaticBoxSizer(
|
91
|
+
self, wx.ID_ANY, _("Save/Load settings"), wx.HORIZONTAL
|
92
|
+
)
|
69
93
|
choices = list(self.context.kernel.keylist("magnet_config"))
|
70
|
-
self.cbo_template = wxComboBox(
|
71
|
-
|
94
|
+
self.cbo_template = wxComboBox(
|
95
|
+
self, wx.ID_ANY, choices=choices, style=wx.CB_DROPDOWN
|
96
|
+
)
|
97
|
+
self.cbo_template.SetToolTip(
|
98
|
+
_("Name to save to / load from the current settings")
|
99
|
+
)
|
72
100
|
self.btn_load = wx.Button(self, wx.ID_ANY, _("Load"))
|
73
101
|
self.btn_load.SetToolTip(_("Load an existing setting configuration"))
|
74
102
|
self.btn_save = wx.Button(self, wx.ID_ANY, _("Save"))
|
@@ -77,7 +105,6 @@ class MagnetOptionPanel(wx.Panel):
|
|
77
105
|
sizer_template.Add(self.btn_load, 0, wx.EXPAND, 0)
|
78
106
|
sizer_template.Add(self.btn_save, 0, wx.EXPAND, 0)
|
79
107
|
|
80
|
-
|
81
108
|
sizer_magnet.Add(sizer_affection, 0, wx.EXPAND, 0)
|
82
109
|
sizer_strength_template = wx.BoxSizer(wx.HORIZONTAL)
|
83
110
|
sizer_strength_template.Add(sizer_strength, 0, wx.EXPAND, 0)
|
@@ -141,11 +168,13 @@ class MagnetOptionPanel(wx.Panel):
|
|
141
168
|
self.cbo_template.SetItems(choices)
|
142
169
|
current = self.get_option_string()
|
143
170
|
for key in choices:
|
144
|
-
value = self.context.kernel.read_persistent(
|
171
|
+
value = self.context.kernel.read_persistent(
|
172
|
+
t=str, section="magnet_config", key=key, default=""
|
173
|
+
)
|
145
174
|
if value == current:
|
146
175
|
self.cbo_template.SetValue(key)
|
147
176
|
break
|
148
|
-
|
177
|
+
|
149
178
|
self.on_set_buttons(None)
|
150
179
|
|
151
180
|
def on_save_options(self, event):
|
@@ -153,14 +182,18 @@ class MagnetOptionPanel(wx.Panel):
|
|
153
182
|
if o_name is None or o_name == "":
|
154
183
|
return
|
155
184
|
options = self.get_option_string()
|
156
|
-
self.context.kernel.write_persistent(
|
185
|
+
self.context.kernel.write_persistent(
|
186
|
+
section="magnet_config", key=o_name, value=options
|
187
|
+
)
|
157
188
|
self.update_values()
|
158
189
|
|
159
190
|
def on_set_options(self, event):
|
160
191
|
o_name = self.cbo_template.GetValue()
|
161
192
|
if o_name is None or o_name == "":
|
162
193
|
return
|
163
|
-
options = self.context.kernel.read_persistent(
|
194
|
+
options = self.context.kernel.read_persistent(
|
195
|
+
t=str, section="magnet_config", key=o_name, default=""
|
196
|
+
)
|
164
197
|
if len(options) != 4:
|
165
198
|
return
|
166
199
|
p = self.scene.pane
|
@@ -169,8 +202,8 @@ class MagnetOptionPanel(wx.Panel):
|
|
169
202
|
p.magnet_attract_c = options[2] == "1"
|
170
203
|
try:
|
171
204
|
idx = int(options[3])
|
172
|
-
idx = min(5, idx)
|
173
|
-
idx = max(0, idx)
|
205
|
+
idx = min(5, idx) # Not higher than enormous
|
206
|
+
idx = max(0, idx) # Not lower than off
|
174
207
|
except ValueError:
|
175
208
|
idx = 2
|
176
209
|
p.magnet_attraction = idx
|
@@ -186,6 +219,7 @@ class MagnetOptionPanel(wx.Panel):
|
|
186
219
|
def pane_hide(self, *args):
|
187
220
|
pass
|
188
221
|
|
222
|
+
|
189
223
|
class MagnetActionPanel(wx.Panel):
|
190
224
|
def __init__(self, *args, context=None, **kwds):
|
191
225
|
# begin wxGlade: PositionPanel.__init__
|
@@ -198,14 +232,20 @@ class MagnetActionPanel(wx.Panel):
|
|
198
232
|
|
199
233
|
main_sizer = wx.BoxSizer(wx.VERTICAL)
|
200
234
|
|
201
|
-
position_sizer = StaticBoxSizer(
|
235
|
+
position_sizer = StaticBoxSizer(
|
236
|
+
self, wx.ID_ANY, _("Set single line"), wx.HORIZONTAL
|
237
|
+
)
|
202
238
|
label = wxStaticText(self, wx.ID_ANY, _("Position:"))
|
203
|
-
self.txt_coord = TextCtrl(self, wx.ID_ANY, limited
|
239
|
+
self.txt_coord = TextCtrl(self, wx.ID_ANY, limited=True, check="length")
|
204
240
|
self.btn_set_x = wxButton(self, wx.ID_ANY, "X")
|
205
241
|
self.btn_set_y = wxButton(self, wx.ID_ANY, "Y")
|
206
242
|
self.txt_coord.SetToolTip(_("Define the position of the magnet line"))
|
207
|
-
self.btn_set_x.SetToolTip(
|
208
|
-
|
243
|
+
self.btn_set_x.SetToolTip(
|
244
|
+
_("Toggle a magnet line at the position on the X-axis")
|
245
|
+
)
|
246
|
+
self.btn_set_y.SetToolTip(
|
247
|
+
_("Toggle a magnet line at the position on the Y-axis")
|
248
|
+
)
|
209
249
|
position_sizer.Add(label, 0, wx.EXPAND, 0)
|
210
250
|
position_sizer.Add(self.txt_coord, 1, wx.EXPAND, 0)
|
211
251
|
position_sizer.Add(self.btn_set_x, 0, wx.EXPAND, 0)
|
@@ -213,7 +253,9 @@ class MagnetActionPanel(wx.Panel):
|
|
213
253
|
|
214
254
|
main_sizer.Add(position_sizer, 0, wx.EXPAND, 0)
|
215
255
|
|
216
|
-
self.selection_sizer = StaticBoxSizer(
|
256
|
+
self.selection_sizer = StaticBoxSizer(
|
257
|
+
self, wx.ID_ANY, _("Set around selection"), wx.VERTICAL
|
258
|
+
)
|
217
259
|
parent = self.selection_sizer.sbox
|
218
260
|
hor_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
219
261
|
label = wxStaticText(parent, wx.ID_ANY, _("Horizontal"))
|
@@ -224,12 +266,30 @@ class MagnetActionPanel(wx.Panel):
|
|
224
266
|
self.btn_h_3 = wxButton(parent, wx.ID_ANY, "3")
|
225
267
|
self.btn_h_4 = wxButton(parent, wx.ID_ANY, "4")
|
226
268
|
self.btn_h_5 = wxButton(parent, wx.ID_ANY, "5")
|
227
|
-
self.btn_h_min.SetToolTip(
|
228
|
-
|
229
|
-
|
230
|
-
self.
|
231
|
-
|
232
|
-
|
269
|
+
self.btn_h_min.SetToolTip(
|
270
|
+
_("Toggle a magnet line at the left edge of the selection")
|
271
|
+
)
|
272
|
+
self.btn_h_center.SetToolTip(
|
273
|
+
_("Toggle a magnet line at the horizontal center of the selection")
|
274
|
+
)
|
275
|
+
self.btn_h_max.SetToolTip(
|
276
|
+
_("Toggle a magnet line at the right edge of the selection")
|
277
|
+
)
|
278
|
+
self.btn_h_3.SetToolTip(
|
279
|
+
_(
|
280
|
+
"Toggle magnet lines at 1/3 and 2/3 across the horizontal extent of the selection"
|
281
|
+
)
|
282
|
+
)
|
283
|
+
self.btn_h_4.SetToolTip(
|
284
|
+
_(
|
285
|
+
"Toggle magnet lines at 1/4, 2/4 and 3/4 across the horizontal extent of the selection"
|
286
|
+
)
|
287
|
+
)
|
288
|
+
self.btn_h_5.SetToolTip(
|
289
|
+
_(
|
290
|
+
"Toggle magnet lines at 1/5, 2/5, 3/5 and 4/5 across the horizontal extent of the selection"
|
291
|
+
)
|
292
|
+
)
|
233
293
|
hor_sizer.Add(self.btn_h_min, 0, wx.EXPAND, 0)
|
234
294
|
hor_sizer.Add(self.btn_h_center, 0, wx.EXPAND, 0)
|
235
295
|
hor_sizer.Add(self.btn_h_max, 0, wx.EXPAND, 0)
|
@@ -246,12 +306,30 @@ class MagnetActionPanel(wx.Panel):
|
|
246
306
|
self.btn_v_3 = wxButton(parent, wx.ID_ANY, "3")
|
247
307
|
self.btn_v_4 = wxButton(parent, wx.ID_ANY, "4")
|
248
308
|
self.btn_v_5 = wxButton(parent, wx.ID_ANY, "5")
|
249
|
-
self.btn_v_min.SetToolTip(
|
250
|
-
|
251
|
-
|
252
|
-
self.
|
253
|
-
|
254
|
-
|
309
|
+
self.btn_v_min.SetToolTip(
|
310
|
+
_("Toggle a magnet line at the top edge of the selection")
|
311
|
+
)
|
312
|
+
self.btn_v_center.SetToolTip(
|
313
|
+
_("Toggle a magnet line at the vertical center of the selection")
|
314
|
+
)
|
315
|
+
self.btn_v_max.SetToolTip(
|
316
|
+
_("Toggle a magnet line at the bottom edge of the selection")
|
317
|
+
)
|
318
|
+
self.btn_v_3.SetToolTip(
|
319
|
+
_(
|
320
|
+
"Toggle magnet lines at 1/3 and 2/3 across the vertical extent of the selection"
|
321
|
+
)
|
322
|
+
)
|
323
|
+
self.btn_v_4.SetToolTip(
|
324
|
+
_(
|
325
|
+
"Toggle magnet lines at 1/4, 2/4 and 3/4 across the vertical extent of the selection"
|
326
|
+
)
|
327
|
+
)
|
328
|
+
self.btn_v_5.SetToolTip(
|
329
|
+
_(
|
330
|
+
"Toggle magnet lines at 1/5, 2/5, 3/5 and 4/5 across the vertical extent of the selection"
|
331
|
+
)
|
332
|
+
)
|
255
333
|
vert_sizer.Add(self.btn_v_min, 0, wx.EXPAND, 0)
|
256
334
|
vert_sizer.Add(self.btn_v_center, 0, wx.EXPAND, 0)
|
257
335
|
vert_sizer.Add(self.btn_v_max, 0, wx.EXPAND, 0)
|
@@ -259,14 +337,24 @@ class MagnetActionPanel(wx.Panel):
|
|
259
337
|
vert_sizer.Add(self.btn_v_4, 0, wx.EXPAND, 0)
|
260
338
|
vert_sizer.Add(self.btn_v_5, 0, wx.EXPAND, 0)
|
261
339
|
for btn in (
|
262
|
-
self.btn_h_3,
|
263
|
-
self.
|
340
|
+
self.btn_h_3,
|
341
|
+
self.btn_h_4,
|
342
|
+
self.btn_h_5,
|
343
|
+
self.btn_h_min,
|
344
|
+
self.btn_h_center,
|
345
|
+
self.btn_h_max,
|
346
|
+
self.btn_v_3,
|
347
|
+
self.btn_v_4,
|
348
|
+
self.btn_v_5,
|
349
|
+
self.btn_v_min,
|
350
|
+
self.btn_v_center,
|
351
|
+
self.btn_v_max,
|
264
352
|
):
|
265
353
|
btn.SetMinSize(wx.Size(dip_size(self, 50, -1)))
|
266
|
-
|
354
|
+
|
267
355
|
self.selection_sizer.Add(hor_sizer, 0, wx.EXPAND, 0)
|
268
356
|
self.selection_sizer.Add(vert_sizer, 0, wx.EXPAND, 0)
|
269
|
-
|
357
|
+
|
270
358
|
main_sizer.Add(self.selection_sizer, 0, wx.EXPAND, 0)
|
271
359
|
|
272
360
|
sizer_actions = wx.BoxSizer(wx.HORIZONTAL)
|
@@ -303,14 +391,14 @@ class MagnetActionPanel(wx.Panel):
|
|
303
391
|
self.Bind(wx.EVT_BUTTON, self.on_clear_y, self.btn_clear_y)
|
304
392
|
self.Bind(wx.EVT_BUTTON, self.on_clear_all, self.btn_clear_all)
|
305
393
|
|
306
|
-
def toggle(self, value:float, is_x:bool):
|
394
|
+
def toggle(self, value: float, is_x: bool):
|
307
395
|
if is_x:
|
308
396
|
self.scene.pane.toggle_x_magnet(value)
|
309
397
|
else:
|
310
398
|
self.scene.pane.toggle_y_magnet(value)
|
311
399
|
self.context.signal("refresh_scene", "Scene")
|
312
|
-
|
313
|
-
def toggle_text(self, is_x:bool):
|
400
|
+
|
401
|
+
def toggle_text(self, is_x: bool):
|
314
402
|
txt = self.txt_coord.GetValue()
|
315
403
|
if not txt:
|
316
404
|
return
|
@@ -355,26 +443,28 @@ class MagnetActionPanel(wx.Panel):
|
|
355
443
|
else:
|
356
444
|
value = (bb[0] + bb[2]) / 2 if is_x else (bb[1] + bb[3]) / 2
|
357
445
|
self.toggle(value, is_x)
|
446
|
+
|
358
447
|
return handler
|
359
448
|
|
360
449
|
def set_split(self, count, axis):
|
361
450
|
def handler(event):
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
451
|
+
self.context(f"magnet split {axis} {count}\n")
|
452
|
+
# if count < 1:
|
453
|
+
# return
|
454
|
+
# is_x = axis == "x"
|
455
|
+
# bb = self.context.elements.selected_area()
|
456
|
+
# if bb is None:
|
457
|
+
# return
|
458
|
+
# min_v = bb[0] if is_x else bb[1]
|
459
|
+
# max_v = bb[2] if is_x else bb[3]
|
460
|
+
# delta = (max_v - min_v) / count
|
461
|
+
# value = min_v
|
462
|
+
# while value + delta < max_v:
|
463
|
+
# value += delta
|
464
|
+
# self.toggle(value, is_x)
|
375
465
|
|
376
466
|
return handler
|
377
|
-
|
467
|
+
|
378
468
|
def update_values(self):
|
379
469
|
flag = self.context.elements.has_emphasis()
|
380
470
|
self.selection_sizer.Enable(flag)
|
@@ -390,6 +480,7 @@ class MagnetActionPanel(wx.Panel):
|
|
390
480
|
if signal_name == "emphasized":
|
391
481
|
self.update_values()
|
392
482
|
|
483
|
+
|
393
484
|
class MagnetPanel(wx.Panel):
|
394
485
|
def __init__(self, *args, context=None, **kwds):
|
395
486
|
# begin wxGlade: PositionPanel.__init__
|
@@ -402,7 +493,9 @@ class MagnetPanel(wx.Panel):
|
|
402
493
|
sizer_main = wx.BoxSizer(wx.VERTICAL)
|
403
494
|
sizer_main.Add(self.notebook, 1, wx.EXPAND, 0)
|
404
495
|
panel_action = MagnetActionPanel(self.notebook, wx.ID_ANY, context=self.context)
|
405
|
-
panel_options = MagnetOptionPanel(
|
496
|
+
panel_options = MagnetOptionPanel(
|
497
|
+
self.notebook, wx.ID_ANY, context=self.context
|
498
|
+
)
|
406
499
|
self.panels = (panel_action, panel_options)
|
407
500
|
self.notebook.AddPage(panel_action, _("Actions"))
|
408
501
|
self.notebook.AddPage(panel_options, _("Options"))
|