meerk40t 0.9.2000__py2.py3-none-any.whl → 0.9.3001__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/balor_params.py +1 -43
- meerk40t/balormk/controller.py +1 -41
- meerk40t/balormk/device.py +16 -22
- meerk40t/balormk/driver.py +4 -4
- meerk40t/balormk/gui/balorconfig.py +2 -2
- meerk40t/balormk/gui/balorcontroller.py +13 -5
- meerk40t/balormk/gui/baloroperationproperties.py +0 -46
- meerk40t/balormk/gui/gui.py +17 -17
- meerk40t/camera/gui/camerapanel.py +18 -11
- meerk40t/core/cutcode/rastercut.py +3 -1
- meerk40t/core/cutplan.py +145 -14
- meerk40t/core/elements/clipboard.py +18 -9
- meerk40t/core/elements/element_treeops.py +320 -180
- meerk40t/core/elements/element_types.py +7 -2
- meerk40t/core/elements/elements.py +53 -27
- meerk40t/core/elements/geometry.py +8 -0
- meerk40t/core/elements/offset_clpr.py +129 -4
- meerk40t/core/elements/offset_mk.py +3 -1
- meerk40t/core/elements/shapes.py +28 -25
- meerk40t/core/laserjob.py +7 -0
- meerk40t/core/node/bootstrap.py +4 -0
- meerk40t/core/node/effect_hatch.py +85 -96
- meerk40t/core/node/effect_wobble.py +309 -0
- meerk40t/core/node/elem_image.py +49 -19
- meerk40t/core/node/elem_line.py +60 -0
- meerk40t/core/node/elem_rect.py +5 -3
- meerk40t/core/node/image_processed.py +766 -0
- meerk40t/core/node/image_raster.py +113 -0
- meerk40t/core/node/node.py +120 -1
- meerk40t/core/node/op_cut.py +2 -8
- meerk40t/core/node/op_dots.py +0 -8
- meerk40t/core/node/op_engrave.py +2 -18
- meerk40t/core/node/op_image.py +22 -35
- meerk40t/core/node/op_raster.py +0 -9
- meerk40t/core/planner.py +32 -2
- meerk40t/core/svg_io.py +699 -461
- meerk40t/core/treeop.py +191 -0
- meerk40t/core/undos.py +15 -1
- meerk40t/core/units.py +14 -4
- meerk40t/device/dummydevice.py +3 -2
- meerk40t/device/gui/defaultactions.py +43 -55
- meerk40t/device/gui/formatterpanel.py +58 -49
- meerk40t/device/gui/warningpanel.py +12 -12
- meerk40t/device/mixins.py +13 -0
- meerk40t/dxf/dxf_io.py +9 -5
- meerk40t/extra/ezd.py +28 -26
- meerk40t/extra/imageactions.py +300 -308
- meerk40t/extra/lbrn.py +19 -2
- meerk40t/fill/fills.py +6 -6
- meerk40t/fill/patternfill.py +1061 -1061
- meerk40t/fill/patterns.py +2 -6
- meerk40t/grbl/controller.py +168 -52
- meerk40t/grbl/device.py +23 -18
- meerk40t/grbl/driver.py +39 -0
- meerk40t/grbl/emulator.py +79 -19
- meerk40t/grbl/gcodejob.py +10 -0
- meerk40t/grbl/gui/grblconfiguration.py +2 -2
- meerk40t/grbl/gui/grblcontroller.py +24 -8
- meerk40t/grbl/gui/grblhardwareconfig.py +153 -0
- meerk40t/grbl/gui/gui.py +17 -14
- meerk40t/grbl/mock_connection.py +15 -34
- meerk40t/grbl/plugin.py +0 -4
- meerk40t/grbl/serial_connection.py +2 -1
- meerk40t/gui/about.py +8 -5
- meerk40t/gui/alignment.py +10 -6
- meerk40t/gui/basicops.py +27 -17
- meerk40t/gui/bufferview.py +2 -2
- meerk40t/gui/choicepropertypanel.py +101 -13
- meerk40t/gui/consolepanel.py +12 -9
- meerk40t/gui/devicepanel.py +38 -25
- meerk40t/gui/executejob.py +6 -4
- meerk40t/gui/help_assets/help_assets.py +13 -10
- meerk40t/gui/hersheymanager.py +8 -6
- meerk40t/gui/icons.py +1951 -3065
- meerk40t/gui/imagesplitter.py +14 -7
- meerk40t/gui/keymap.py +3 -3
- meerk40t/gui/laserpanel.py +151 -84
- meerk40t/gui/laserrender.py +61 -70
- meerk40t/gui/lasertoolpanel.py +8 -7
- meerk40t/gui/materialtest.py +3 -3
- meerk40t/gui/mkdebug.py +254 -1
- meerk40t/gui/navigationpanels.py +321 -180
- meerk40t/gui/notes.py +3 -3
- meerk40t/gui/opassignment.py +12 -12
- meerk40t/gui/operation_info.py +13 -13
- meerk40t/gui/plugin.py +5 -0
- meerk40t/gui/position.py +20 -18
- meerk40t/gui/preferences.py +21 -6
- meerk40t/gui/propertypanels/attributes.py +70 -22
- meerk40t/gui/propertypanels/blobproperty.py +2 -2
- meerk40t/gui/propertypanels/consoleproperty.py +2 -2
- meerk40t/gui/propertypanels/groupproperties.py +3 -3
- meerk40t/gui/propertypanels/hatchproperty.py +11 -18
- meerk40t/gui/propertypanels/imageproperty.py +4 -3
- meerk40t/gui/propertypanels/opbranchproperties.py +1 -1
- meerk40t/gui/propertypanels/pathproperty.py +2 -2
- meerk40t/gui/propertypanels/pointproperty.py +2 -2
- meerk40t/gui/propertypanels/propertywindow.py +4 -4
- meerk40t/gui/propertypanels/textproperty.py +3 -3
- meerk40t/gui/propertypanels/wobbleproperty.py +204 -0
- meerk40t/gui/ribbon.py +367 -259
- meerk40t/gui/scene/scene.py +31 -5
- meerk40t/gui/scenewidgets/elementswidget.py +12 -4
- meerk40t/gui/scenewidgets/gridwidget.py +2 -2
- meerk40t/gui/scenewidgets/laserpathwidget.py +7 -2
- meerk40t/gui/scenewidgets/machineoriginwidget.py +6 -2
- meerk40t/gui/scenewidgets/relocatewidget.py +1 -1
- meerk40t/gui/scenewidgets/reticlewidget.py +9 -0
- meerk40t/gui/scenewidgets/selectionwidget.py +12 -7
- meerk40t/gui/simpleui.py +95 -8
- meerk40t/gui/simulation.py +44 -36
- meerk40t/gui/spoolerpanel.py +124 -26
- meerk40t/gui/statusbarwidgets/defaultoperations.py +18 -6
- meerk40t/gui/statusbarwidgets/infowidget.py +2 -2
- meerk40t/gui/statusbarwidgets/opassignwidget.py +12 -12
- meerk40t/gui/statusbarwidgets/shapepropwidget.py +45 -18
- meerk40t/gui/statusbarwidgets/statusbar.py +11 -4
- meerk40t/gui/themes.py +78 -0
- meerk40t/gui/toolwidgets/toolcircle.py +2 -1
- meerk40t/gui/toolwidgets/toolellipse.py +2 -1
- meerk40t/gui/toolwidgets/toolimagecut.py +132 -0
- meerk40t/gui/toolwidgets/toolline.py +144 -0
- meerk40t/gui/toolwidgets/toolnodeedit.py +72 -145
- meerk40t/gui/toolwidgets/toolpoint.py +1 -1
- meerk40t/gui/toolwidgets/toolpolygon.py +8 -55
- meerk40t/gui/toolwidgets/toolrect.py +2 -1
- meerk40t/gui/usbconnect.py +2 -2
- meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +2 -2
- meerk40t/gui/utilitywidgets/harmonograph.py +7 -7
- meerk40t/gui/utilitywidgets/scalewidget.py +1 -1
- meerk40t/gui/wordlisteditor.py +33 -18
- meerk40t/gui/wxmeerk40t.py +166 -66
- meerk40t/gui/wxmmain.py +236 -157
- meerk40t/gui/wxmribbon.py +49 -25
- meerk40t/gui/wxmscene.py +49 -38
- meerk40t/gui/wxmtree.py +216 -85
- meerk40t/gui/wxutils.py +62 -4
- meerk40t/image/imagetools.py +443 -15
- meerk40t/internal_plugins.py +2 -10
- meerk40t/kernel/kernel.py +12 -4
- meerk40t/lihuiyu/controller.py +7 -7
- meerk40t/lihuiyu/device.py +3 -1
- meerk40t/lihuiyu/driver.py +3 -0
- meerk40t/lihuiyu/gui/gui.py +8 -8
- meerk40t/lihuiyu/gui/lhyaccelgui.py +2 -2
- meerk40t/lihuiyu/gui/lhycontrollergui.py +73 -27
- meerk40t/lihuiyu/gui/lhydrivergui.py +2 -2
- meerk40t/lihuiyu/gui/tcpcontroller.py +22 -9
- meerk40t/main.py +6 -1
- meerk40t/moshi/controller.py +5 -5
- meerk40t/moshi/device.py +5 -2
- meerk40t/moshi/driver.py +4 -0
- meerk40t/moshi/gui/gui.py +8 -8
- meerk40t/moshi/gui/moshicontrollergui.py +24 -8
- meerk40t/moshi/gui/moshidrivergui.py +2 -2
- meerk40t/newly/controller.py +2 -0
- meerk40t/newly/device.py +9 -2
- meerk40t/newly/driver.py +4 -0
- meerk40t/newly/gui/gui.py +16 -17
- meerk40t/newly/gui/newlyconfig.py +2 -2
- meerk40t/newly/gui/newlycontroller.py +13 -5
- meerk40t/rotary/gui/gui.py +2 -2
- meerk40t/rotary/gui/rotarysettings.py +2 -2
- meerk40t/ruida/device.py +3 -0
- meerk40t/ruida/driver.py +4 -0
- meerk40t/ruida/gui/gui.py +6 -6
- meerk40t/ruida/gui/ruidaconfig.py +2 -2
- meerk40t/ruida/gui/ruidacontroller.py +13 -5
- meerk40t/svgelements.py +9 -9
- meerk40t/tools/geomstr.py +849 -153
- meerk40t/tools/kerftest.py +8 -4
- meerk40t/tools/livinghinges.py +15 -8
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/METADATA +21 -16
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/RECORD +185 -177
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/entry_points.txt +0 -1
- test/test_core_elements.py +8 -24
- test/test_file_svg.py +88 -0
- test/test_fill.py +9 -9
- test/test_geomstr.py +258 -8
- test/test_kernel.py +4 -0
- test/test_tools_rasterplotter.py +29 -0
- meerk40t/extra/embroider.py +0 -56
- meerk40t/extra/pathoptimize.py +0 -249
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/WHEEL +0 -0
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/zip-safe +0 -0
meerk40t/gui/scene/scene.py
CHANGED
@@ -27,9 +27,6 @@ from meerk40t.gui.scene.scenespacewidget import SceneSpaceWidget
|
|
27
27
|
from meerk40t.kernel import Job, Module
|
28
28
|
from meerk40t.svgelements import Matrix, Point
|
29
29
|
|
30
|
-
# TODO: _buffer can be updated partially rather than fully rewritten, especially with some layering.
|
31
|
-
|
32
|
-
|
33
30
|
_reused_identity_widget = Matrix()
|
34
31
|
XCELLS = 15
|
35
32
|
YCELLS = 15
|
@@ -78,9 +75,22 @@ class SceneToast:
|
|
78
75
|
"""
|
79
76
|
self.countdown -= 1
|
80
77
|
if self.countdown <= 20:
|
81
|
-
self.scene.
|
78
|
+
self.scene.invalidate(
|
79
|
+
self.left - 10,
|
80
|
+
self.top - 10,
|
81
|
+
self.right + 10,
|
82
|
+
self.bottom + 10,
|
83
|
+
animate=True,
|
84
|
+
)
|
82
85
|
if self.countdown <= 0:
|
83
|
-
self.scene.
|
86
|
+
self.scene.invalidate(
|
87
|
+
self.left - 10,
|
88
|
+
self.top - 10,
|
89
|
+
self.right + 10,
|
90
|
+
self.bottom + 10,
|
91
|
+
animate=False,
|
92
|
+
)
|
93
|
+
# self.scene.request_refresh()
|
84
94
|
self.message = None
|
85
95
|
self.token = None
|
86
96
|
return self.countdown > 0
|
@@ -212,6 +222,8 @@ class Scene(Module, Job):
|
|
212
222
|
self.colors = self.context.colors
|
213
223
|
|
214
224
|
self.screen_refresh_is_requested = True
|
225
|
+
self.clip = wx.Rect(0, 0, 0, 0)
|
226
|
+
|
215
227
|
self.background_brush = wx.Brush(self.colors.color_background)
|
216
228
|
self.has_background = False
|
217
229
|
# If set this color will be used for the scene background (used during burn)
|
@@ -299,6 +311,13 @@ class Scene(Module, Job):
|
|
299
311
|
except AttributeError:
|
300
312
|
pass
|
301
313
|
|
314
|
+
def invalidate(self, min_x, min_y, max_x, max_y, animate=False):
|
315
|
+
self.clip.Union((min_x, min_y, max_x - min_x, max_y - min_y))
|
316
|
+
if animate:
|
317
|
+
self.request_refresh_for_animation()
|
318
|
+
else:
|
319
|
+
self.request_refresh()
|
320
|
+
|
302
321
|
def animate(self, widget):
|
303
322
|
with self._animate_lock:
|
304
323
|
if widget not in self._adding_widgets:
|
@@ -366,6 +385,13 @@ class Scene(Module, Job):
|
|
366
385
|
self.gui.set_buffer()
|
367
386
|
buf = self.gui.scene_buffer
|
368
387
|
dc = wx.MemoryDC()
|
388
|
+
if self.clip.width != 0 and self.clip.height != 0:
|
389
|
+
dc.SetClippingRegion(self.clip)
|
390
|
+
self.clip.SetX(0)
|
391
|
+
self.clip.SetY(0)
|
392
|
+
self.clip.SetWidth(0)
|
393
|
+
self.clip.SetHeight(0)
|
394
|
+
|
369
395
|
dc.SelectObject(buf)
|
370
396
|
if self.overrule_background is None:
|
371
397
|
self.background_brush.SetColour(self.colors.color_background)
|
@@ -73,7 +73,15 @@ class ElementsWidget(Widget):
|
|
73
73
|
return
|
74
74
|
except TypeError:
|
75
75
|
return
|
76
|
-
|
76
|
+
empty_or_right = True
|
77
|
+
if modifiers is not None:
|
78
|
+
for mod in modifiers:
|
79
|
+
if mod == "m_right":
|
80
|
+
continue
|
81
|
+
empty_or_right = False
|
82
|
+
break
|
83
|
+
|
84
|
+
if event_type == "rightdown" and empty_or_right:
|
77
85
|
if not self.scene.pane.tool_active:
|
78
86
|
if self.scene.pane.active_tool != "none":
|
79
87
|
self.scene.context("tool none")
|
@@ -82,9 +90,9 @@ class ElementsWidget(Widget):
|
|
82
90
|
self.scene.context.signal("scene_right_click")
|
83
91
|
return RESPONSE_CONSUME
|
84
92
|
elif event_type == "rightdown": # any modifier
|
85
|
-
if self.scene.context.use_toolmenu:
|
86
|
-
|
87
|
-
|
93
|
+
# if self.scene.context.use_toolmenu:
|
94
|
+
# self.scene.context("tool_menu")
|
95
|
+
# return RESPONSE_CONSUME
|
88
96
|
return RESPONSE_CHAIN
|
89
97
|
elif event_type == "leftclick":
|
90
98
|
if self.scene.pane.modif_active:
|
@@ -290,8 +290,8 @@ class GridWidget(Widget):
|
|
290
290
|
|
291
291
|
self.min_x = max(0, self.min_x)
|
292
292
|
self.min_y = max(0, self.min_y)
|
293
|
-
self.max_x = min(
|
294
|
-
self.max_y = min(
|
293
|
+
self.max_x = min(self.scene.context.space.width, self.max_x)
|
294
|
+
self.max_y = min(self.scene.context.space.height, self.max_y)
|
295
295
|
|
296
296
|
def calculate_tick_length(self):
|
297
297
|
tick_length = float(
|
@@ -19,7 +19,10 @@ class LaserPathWidget(Widget):
|
|
19
19
|
|
20
20
|
def __init__(self, scene):
|
21
21
|
Widget.__init__(self, scene, all=False)
|
22
|
-
self.
|
22
|
+
self.buffer_size = 1000
|
23
|
+
self.laserpath = [[0, 0] for _ in range(self.buffer_size)], [
|
24
|
+
[0, 0] for _ in range(self.buffer_size)
|
25
|
+
]
|
23
26
|
self.laserpath_index = 0
|
24
27
|
|
25
28
|
def init(self, context):
|
@@ -42,7 +45,9 @@ class LaserPathWidget(Widget):
|
|
42
45
|
self.laserpath_index = index
|
43
46
|
|
44
47
|
def clear_laserpath(self):
|
45
|
-
self.laserpath = [[0, 0] for _ in range(
|
48
|
+
self.laserpath = [[0, 0] for _ in range(self.buffer_size)], [
|
49
|
+
[0, 0] for _ in range(self.buffer_size)
|
50
|
+
]
|
46
51
|
self.laserpath_index = 0
|
47
52
|
|
48
53
|
def process_draw(self, gc):
|
@@ -54,9 +54,13 @@ class MachineOriginWidget(Widget):
|
|
54
54
|
y_dx, y_dy = space.display.iposition(0, 50000)
|
55
55
|
ya1_dx, ya1_dy = space.display.iposition(5000, 45000)
|
56
56
|
ya2_dx, ya2_dy = space.display.iposition(-5000, 45000)
|
57
|
-
dev0x, dev0y = space.device.view.iposition(0, 0)
|
58
57
|
gc.SetBrush(self.brush)
|
59
|
-
|
58
|
+
try:
|
59
|
+
dev0x, dev0y = space.device.view.iposition(0, 0)
|
60
|
+
gc.DrawRectangle(dev0x - margin, dev0y - margin, margin * 2, margin * 2)
|
61
|
+
except AttributeError:
|
62
|
+
# device view does not exist, so we cannot draw the device machine origin widget
|
63
|
+
pass
|
60
64
|
|
61
65
|
gc.SetBrush(wx.NullBrush)
|
62
66
|
gc.SetPen(self.x_axis_pen)
|
@@ -16,7 +16,7 @@ class RelocateWidget(Widget):
|
|
16
16
|
def __init__(self, scene, x, y):
|
17
17
|
size = 10000
|
18
18
|
Widget.__init__(self, scene, x - size, y - size, x + size, y + size)
|
19
|
-
self.bitmap = icons.
|
19
|
+
self.bitmap = icons.icons8_center_of_gravity.GetBitmap()
|
20
20
|
|
21
21
|
def hit(self):
|
22
22
|
return HITCHAIN_HIT
|
@@ -28,6 +28,7 @@ class ReticleWidget(Widget):
|
|
28
28
|
"""
|
29
29
|
context.listen("driver;position", self.on_update_driver)
|
30
30
|
context.listen("emulator;position", self.on_update_emulator)
|
31
|
+
context.listen("status;position", self.on_update_status)
|
31
32
|
|
32
33
|
def final(self, context):
|
33
34
|
"""
|
@@ -35,6 +36,7 @@ class ReticleWidget(Widget):
|
|
35
36
|
"""
|
36
37
|
context.unlisten("driver;position", self.on_update_driver)
|
37
38
|
context.unlisten("emulator;position", self.on_update_emulator)
|
39
|
+
context.unlisten("status;position", self.on_update_status)
|
38
40
|
|
39
41
|
def on_update_driver(self, origin, pos):
|
40
42
|
"""
|
@@ -50,6 +52,13 @@ class ReticleWidget(Widget):
|
|
50
52
|
self.reticles["e" + origin] = pos[2], pos[3]
|
51
53
|
self.scene.request_refresh_for_animation()
|
52
54
|
|
55
|
+
def on_update_status(self, origin, pos):
|
56
|
+
"""
|
57
|
+
Update of emulator adds and ensures the location of the e+origin position
|
58
|
+
"""
|
59
|
+
self.reticles["s" + origin] = pos[2], pos[3]
|
60
|
+
self.scene.request_refresh_for_animation()
|
61
|
+
|
53
62
|
def process_draw(self, gc):
|
54
63
|
"""
|
55
64
|
Draw all the registered reticles.
|
@@ -448,7 +448,7 @@ class RotationWidget(Widget):
|
|
448
448
|
if hasattr(e, "update"):
|
449
449
|
images.append(e)
|
450
450
|
for e in images:
|
451
|
-
e.update(
|
451
|
+
e.update(self.scene.context)
|
452
452
|
self.master.last_angle = None
|
453
453
|
self.master.start_angle = None
|
454
454
|
self.master.rotated_angle = 0
|
@@ -732,7 +732,7 @@ class CornerWidget(Widget):
|
|
732
732
|
if hasattr(e, "update"):
|
733
733
|
images.append(e)
|
734
734
|
for e in images:
|
735
|
-
e.update(
|
735
|
+
e.update(self.scene.context)
|
736
736
|
self.scene.pane.modif_active = False
|
737
737
|
self.scene.context.signal("tool_modified")
|
738
738
|
elif event == -1:
|
@@ -981,7 +981,7 @@ class SideWidget(Widget):
|
|
981
981
|
if hasattr(e, "update"):
|
982
982
|
images.append(e)
|
983
983
|
for e in images:
|
984
|
-
e.update(
|
984
|
+
e.update(self.scene.context)
|
985
985
|
self.scene.pane.modif_active = False
|
986
986
|
self.scene.context.signal("tool_modified")
|
987
987
|
elif event == -1:
|
@@ -1210,7 +1210,7 @@ class SkewWidget(Widget):
|
|
1210
1210
|
if hasattr(e, "update"):
|
1211
1211
|
images.append(e)
|
1212
1212
|
for e in images:
|
1213
|
-
e.update(
|
1213
|
+
e.update(self.scene.context)
|
1214
1214
|
self.scene.context.signal("tool_modified")
|
1215
1215
|
elif event == -1:
|
1216
1216
|
self.scene.pane.modif_active = True
|
@@ -1409,14 +1409,19 @@ class MoveWidget(Widget):
|
|
1409
1409
|
had_optional = False
|
1410
1410
|
# Need to add stroke and fill, as copy will take the
|
1411
1411
|
# default values for these attributes
|
1412
|
-
|
1412
|
+
options = ["fill", "stroke", "wxfont"]
|
1413
|
+
for optional in options:
|
1413
1414
|
if hasattr(e, optional):
|
1414
1415
|
setattr(copy_node, optional, getattr(e, optional))
|
1415
|
-
|
1416
|
-
for
|
1416
|
+
options = []
|
1417
|
+
for prop in dir(e):
|
1418
|
+
if prop.startswith("mk"):
|
1419
|
+
options.append(prop)
|
1420
|
+
for optional in options:
|
1417
1421
|
if hasattr(e, optional):
|
1418
1422
|
setattr(copy_node, optional, getattr(e, optional))
|
1419
1423
|
had_optional = True
|
1424
|
+
|
1420
1425
|
newparent.add_node(copy_node)
|
1421
1426
|
copy_nodes.append(copy_node)
|
1422
1427
|
# The copy remains at the same place, we are moving the originals,
|
meerk40t/gui/simpleui.py
CHANGED
@@ -11,15 +11,42 @@ import wx
|
|
11
11
|
from wx import aui
|
12
12
|
|
13
13
|
from ..core.exceptions import BadFileError
|
14
|
-
from .icons import
|
14
|
+
from .icons import get_default_icon_size, icons8_computer_support, icons8_opened_folder
|
15
15
|
from .mwindow import MWindow
|
16
|
+
from .navigationpanels import Drag, Jog
|
17
|
+
from .wxutils import StaticBoxSizer
|
16
18
|
|
17
19
|
_ = wx.GetTranslation
|
18
20
|
|
19
21
|
|
22
|
+
class JogMovePanel(wx.Panel):
|
23
|
+
def __init__(self, *args, context=None, icon_size=None, **kwds):
|
24
|
+
# begin wxGlade: Jog.__init__
|
25
|
+
kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
|
26
|
+
wx.Panel.__init__(self, *args, **kwds)
|
27
|
+
self.context = context
|
28
|
+
jog_panel = Jog(self, wx.ID_ANY, context=context)
|
29
|
+
drag_panel = Drag(self, wx.ID_ANY, context=context)
|
30
|
+
self.panels = [jog_panel, drag_panel]
|
31
|
+
self.main_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
32
|
+
self.main_sizer.Add(jog_panel, 1, wx.EXPAND, 0)
|
33
|
+
self.main_sizer.Add(drag_panel, 1, wx.EXPAND, 0)
|
34
|
+
self.SetSizer(self.main_sizer)
|
35
|
+
self.Layout()
|
36
|
+
self.Bind(wx.EVT_SIZE, self.on_resize)
|
37
|
+
|
38
|
+
def on_resize(self, event):
|
39
|
+
wb_size = event.GetSize()
|
40
|
+
panel_size = (wb_size[0] / 2, wb_size[1])
|
41
|
+
for p in self.panels:
|
42
|
+
if hasattr(p, "set_icons"):
|
43
|
+
p.set_icons(dimension=panel_size)
|
44
|
+
self.Layout()
|
45
|
+
|
46
|
+
|
20
47
|
class ProjectPanel(wx.Panel):
|
21
48
|
"""
|
22
|
-
Serves to allow the use of Load Project button. This couldn't be provided natively by any readily
|
49
|
+
Serves to allow the use of Load Project button. This couldn't be provided natively by any readily available panel.
|
23
50
|
"""
|
24
51
|
|
25
52
|
name = "Project"
|
@@ -31,12 +58,43 @@ class ProjectPanel(wx.Panel):
|
|
31
58
|
self.context = context
|
32
59
|
self.SetSize((400, 300))
|
33
60
|
|
34
|
-
sizer_buttons = wx.BoxSizer(wx.
|
61
|
+
sizer_buttons = wx.BoxSizer(wx.VERTICAL)
|
35
62
|
|
36
63
|
self.button_load = wx.Button(self, wx.ID_ANY, _("Load Project"))
|
37
64
|
|
38
|
-
self.button_load.SetBitmap(
|
39
|
-
|
65
|
+
self.button_load.SetBitmap(
|
66
|
+
icons8_opened_folder.GetBitmap(resize=get_default_icon_size())
|
67
|
+
)
|
68
|
+
info_panel = StaticBoxSizer(self, wx.ID_ANY, "Project-Information", wx.VERTICAL)
|
69
|
+
line1 = wx.BoxSizer(wx.HORIZONTAL)
|
70
|
+
lbl = wx.StaticText(self, wx.ID_ANY, "File:")
|
71
|
+
lbl.SetMinSize(wx.Size(70, -1))
|
72
|
+
self.info_file = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_READONLY)
|
73
|
+
line1.Add(lbl, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
74
|
+
line1.Add(self.info_file, 1, wx.EXPAND, 0)
|
75
|
+
|
76
|
+
line2 = wx.BoxSizer(wx.HORIZONTAL)
|
77
|
+
lbl = wx.StaticText(self, wx.ID_ANY, "Content:")
|
78
|
+
lbl.SetMinSize(wx.Size(70, -1))
|
79
|
+
self.info_elements = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_READONLY)
|
80
|
+
self.info_operations = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_READONLY)
|
81
|
+
line2.Add(lbl, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
82
|
+
line2.Add(self.info_elements, 1, wx.EXPAND, 0)
|
83
|
+
line2.Add(self.info_operations, 1, wx.EXPAND, 0)
|
84
|
+
|
85
|
+
line3 = wx.BoxSizer(wx.HORIZONTAL)
|
86
|
+
lbl = wx.StaticText(self, wx.ID_ANY, "Status:")
|
87
|
+
lbl.SetMinSize(wx.Size(70, -1))
|
88
|
+
self.info_status = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_READONLY)
|
89
|
+
line3.Add(lbl, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
90
|
+
line3.Add(self.info_status, 1, wx.EXPAND, 0)
|
91
|
+
|
92
|
+
info_panel.Add(line1, 0, wx.EXPAND, 0)
|
93
|
+
info_panel.Add(line2, 0, wx.EXPAND, 0)
|
94
|
+
info_panel.Add(line3, 0, wx.EXPAND, 0)
|
95
|
+
# info_panel.Add(line4, 0, wx.EXPAND, 0)
|
96
|
+
sizer_buttons.Add(self.button_load, 0, 0, 0)
|
97
|
+
sizer_buttons.Add(info_panel, 1, wx.EXPAND, 0)
|
40
98
|
|
41
99
|
self.SetSizer(sizer_buttons)
|
42
100
|
|
@@ -46,6 +104,27 @@ class ProjectPanel(wx.Panel):
|
|
46
104
|
self.Bind(wx.EVT_DROP_FILES, self.on_drop_file)
|
47
105
|
# end wxGlade
|
48
106
|
|
107
|
+
def update_info(self, pathname):
|
108
|
+
self.info_file.SetValue(pathname)
|
109
|
+
self.info_elements.SetValue(
|
110
|
+
f"{len(list(self.context.elements.elems()))} elements"
|
111
|
+
)
|
112
|
+
self.info_operations.SetValue(
|
113
|
+
f"{len(list(self.context.elements.ops()))} burn operations"
|
114
|
+
)
|
115
|
+
unass, unburn = self.context.elements.have_unburnable_elements()
|
116
|
+
status = ""
|
117
|
+
if unass:
|
118
|
+
status += "Unassigned elements! "
|
119
|
+
if unburn:
|
120
|
+
status += "Unburnable elements! "
|
121
|
+
if status == "":
|
122
|
+
status = "Ready to burn."
|
123
|
+
self.info_status.SetBackgroundColour(None)
|
124
|
+
else:
|
125
|
+
self.info_status.SetBackgroundColour(wx.YELLOW)
|
126
|
+
self.info_status.SetValue(status)
|
127
|
+
|
49
128
|
def on_load(self, event): # wxGlade: MyFrame.<event_handler>
|
50
129
|
# This code should load just specific project files rather than all importable formats.
|
51
130
|
files = self.context.elements.load_types()
|
@@ -57,6 +136,7 @@ class ProjectPanel(wx.Panel):
|
|
57
136
|
pathname = fileDialog.GetPath()
|
58
137
|
self.clear_project()
|
59
138
|
self.load(pathname)
|
139
|
+
self.update_info(pathname)
|
60
140
|
event.Skip()
|
61
141
|
|
62
142
|
def clear_project(self):
|
@@ -75,9 +155,13 @@ class ProjectPanel(wx.Panel):
|
|
75
155
|
accepted = 0
|
76
156
|
rejected = 0
|
77
157
|
rejected_files = []
|
158
|
+
validpath = ""
|
78
159
|
for pathname in event.GetFiles():
|
79
160
|
if self.load(pathname):
|
80
161
|
accepted += 1
|
162
|
+
if validpath:
|
163
|
+
validpath += ","
|
164
|
+
validpath += pathname
|
81
165
|
else:
|
82
166
|
rejected += 1
|
83
167
|
rejected_files.append(pathname)
|
@@ -91,9 +175,12 @@ class ProjectPanel(wx.Panel):
|
|
91
175
|
)
|
92
176
|
dlg.ShowModal()
|
93
177
|
dlg.Destroy()
|
178
|
+
self.update_info(validpath)
|
94
179
|
|
95
180
|
def load(self, pathname):
|
96
181
|
def unescaped(filename):
|
182
|
+
import platform
|
183
|
+
|
97
184
|
OS_NAME = platform.system()
|
98
185
|
if OS_NAME == "Windows":
|
99
186
|
newstring = filename.replace("&", "&&")
|
@@ -136,7 +223,7 @@ class SimpleUI(MWindow):
|
|
136
223
|
super().__init__(598, 429, *args, **kwds)
|
137
224
|
|
138
225
|
_icon = wx.NullIcon
|
139
|
-
_icon.CopyFromBitmap(
|
226
|
+
_icon.CopyFromBitmap(icons8_computer_support.GetBitmap())
|
140
227
|
self.SetIcon(_icon)
|
141
228
|
# begin wxGlade: Navigation.__set_properties
|
142
229
|
self.SetTitle(_("MeerK40t"))
|
@@ -218,9 +305,9 @@ class SimpleUI(MWindow):
|
|
218
305
|
from meerk40t.gui.laserpanel import LaserPanel
|
219
306
|
|
220
307
|
kernel.register("simpleui/laserpanel", (LaserPanel, None))
|
221
|
-
from meerk40t.gui.navigationpanels import Jog
|
222
308
|
|
223
|
-
kernel.register("simpleui/navigation", (
|
309
|
+
kernel.register("simpleui/navigation", (JogMovePanel, None))
|
310
|
+
|
224
311
|
from meerk40t.gui.consolepanel import ConsolePanel
|
225
312
|
|
226
313
|
kernel.register("simpleui/console", (ConsolePanel, None))
|
meerk40t/gui/simulation.py
CHANGED
@@ -26,20 +26,21 @@ from ..svgelements import Matrix
|
|
26
26
|
from .choicepropertypanel import ChoicePropertyPanel
|
27
27
|
from .icons import (
|
28
28
|
STD_ICON_SIZE,
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
29
|
+
get_default_icon_size,
|
30
|
+
icon_bell,
|
31
|
+
icon_close_window,
|
32
|
+
icon_console,
|
33
|
+
icon_external,
|
34
|
+
icon_internal,
|
35
|
+
icon_return,
|
36
|
+
icon_round_stop,
|
37
|
+
icon_timer,
|
38
|
+
icons8_circled_play,
|
39
|
+
icons8_home_filled,
|
40
|
+
icons8_image,
|
41
|
+
icons8_laser_beam_hazard,
|
42
|
+
icons8_pause,
|
43
|
+
icons8_route,
|
43
44
|
)
|
44
45
|
from .laserrender import DRAW_MODE_BACKGROUND, LaserRender
|
45
46
|
from .mwindow import MWindow
|
@@ -107,18 +108,18 @@ class OperationsPanel(wx.Panel):
|
|
107
108
|
def setup_state_images(self):
|
108
109
|
iconsize = 20
|
109
110
|
self.default_images = [
|
110
|
-
["beep",
|
111
|
-
["interrupt",
|
112
|
-
["quit",
|
113
|
-
["wait",
|
114
|
-
["home",
|
115
|
-
["goto",
|
116
|
-
["origin",
|
117
|
-
["output",
|
118
|
-
["input",
|
119
|
-
["cutcode",
|
111
|
+
["beep", icon_bell],
|
112
|
+
["interrupt", icon_round_stop],
|
113
|
+
["quit", icon_close_window],
|
114
|
+
["wait", icon_timer],
|
115
|
+
["home", icons8_home_filled],
|
116
|
+
["goto", icon_return],
|
117
|
+
["origin", icon_return],
|
118
|
+
["output", icon_external],
|
119
|
+
["input", icon_internal],
|
120
|
+
["cutcode", icons8_laser_beam_hazard],
|
120
121
|
# Intentionally the last...
|
121
|
-
["console",
|
122
|
+
["console", icon_console],
|
122
123
|
]
|
123
124
|
self.options_images = wx.ImageList()
|
124
125
|
self.options_images.Create(width=iconsize, height=iconsize)
|
@@ -832,10 +833,7 @@ class SimulationPanel(wx.Panel, Job):
|
|
832
833
|
self.panel_optimize.AddPage(self.subpanel_cutcode, _("Cutcode"))
|
833
834
|
self.checkbox_optimize = wx.CheckBox(self, wx.ID_ANY, _("Optimize"))
|
834
835
|
self.checkbox_optimize.SetToolTip(_("Enable/Disable Optimize"))
|
835
|
-
|
836
|
-
self.checkbox_optimize.SetValue(1)
|
837
|
-
else:
|
838
|
-
self.checkbox_optimize.SetValue(0)
|
836
|
+
self.checkbox_optimize.SetValue(self.context.planner.do_optimization)
|
839
837
|
self.btn_redo_it = wx.Button(self, wx.ID_ANY, _("Recalculate"))
|
840
838
|
self.btn_redo_it.Bind(wx.EVT_BUTTON, self.on_redo_it)
|
841
839
|
|
@@ -977,7 +975,9 @@ class SimulationPanel(wx.Panel, Job):
|
|
977
975
|
_("Time Estimate: Extra Time (ie to swing around)")
|
978
976
|
)
|
979
977
|
self.text_time_total.SetToolTip(_("Time Estimate: Total Time"))
|
980
|
-
self.button_play.SetBitmap(
|
978
|
+
self.button_play.SetBitmap(
|
979
|
+
icons8_circled_play.GetBitmap(resize=get_default_icon_size())
|
980
|
+
)
|
981
981
|
self.text_playback_speed.SetMinSize(dip_size(self, 55, 23))
|
982
982
|
# self.combo_device.SetToolTip(_("Select the device"))
|
983
983
|
self.button_spool.SetFont(
|
@@ -990,7 +990,9 @@ class SimulationPanel(wx.Panel, Job):
|
|
990
990
|
"Segoe UI",
|
991
991
|
)
|
992
992
|
)
|
993
|
-
self.button_spool.SetBitmap(
|
993
|
+
self.button_spool.SetBitmap(
|
994
|
+
icons8_route.GetBitmap(resize=1.5 * get_default_icon_size())
|
995
|
+
)
|
994
996
|
# end wxGlade
|
995
997
|
|
996
998
|
def __do_layout(self):
|
@@ -1547,8 +1549,10 @@ class SimulationPanel(wx.Panel, Job):
|
|
1547
1549
|
plan = self.plan_name
|
1548
1550
|
if self.checkbox_optimize.GetValue():
|
1549
1551
|
opt = " optimize"
|
1552
|
+
self.context.planner.do_optimization = True
|
1550
1553
|
else:
|
1551
1554
|
opt = ""
|
1555
|
+
self.context.planner.do_optimization = False
|
1552
1556
|
self.context(
|
1553
1557
|
f"plan{plan} clear\nplan{plan} copy preprocess validate blob preopt{opt}\n"
|
1554
1558
|
)
|
@@ -1599,12 +1603,16 @@ class SimulationPanel(wx.Panel, Job):
|
|
1599
1603
|
self.context.signal("refresh_scene", self.widget_scene.name)
|
1600
1604
|
|
1601
1605
|
def _start(self):
|
1602
|
-
self.button_play.SetBitmap(
|
1606
|
+
self.button_play.SetBitmap(
|
1607
|
+
icons8_pause.GetBitmap(resize=get_default_icon_size())
|
1608
|
+
)
|
1603
1609
|
self.context.schedule(self)
|
1604
1610
|
self.running = True
|
1605
1611
|
|
1606
1612
|
def _stop(self):
|
1607
|
-
self.button_play.SetBitmap(
|
1613
|
+
self.button_play.SetBitmap(
|
1614
|
+
icons8_circled_play.GetBitmap(resize=get_default_icon_size())
|
1615
|
+
)
|
1608
1616
|
self.context.unschedule(self)
|
1609
1617
|
self.running = False
|
1610
1618
|
|
@@ -1760,7 +1768,7 @@ class SimulationWidget(Widget):
|
|
1760
1768
|
gc.SetBrush(wx.RED_BRUSH)
|
1761
1769
|
gc.DrawRectangle(0, 0, cut._cache_width, cut._cache_height)
|
1762
1770
|
gc.DrawBitmap(
|
1763
|
-
|
1771
|
+
icons8_image.GetBitmap(),
|
1764
1772
|
0,
|
1765
1773
|
0,
|
1766
1774
|
cut._cache_width,
|
@@ -2035,7 +2043,7 @@ class Simulation(MWindow):
|
|
2035
2043
|
optimise_at_start=optimise,
|
2036
2044
|
)
|
2037
2045
|
_icon = wx.NullIcon
|
2038
|
-
_icon.CopyFromBitmap(
|
2046
|
+
_icon.CopyFromBitmap(icons8_laser_beam_hazard.GetBitmap())
|
2039
2047
|
self.SetIcon(_icon)
|
2040
2048
|
self.SetTitle(_("Simulation"))
|
2041
2049
|
|
@@ -2055,7 +2063,7 @@ class Simulation(MWindow):
|
|
2055
2063
|
"button/jobstart/Simulation",
|
2056
2064
|
{
|
2057
2065
|
"label": _("Simulate"),
|
2058
|
-
"icon":
|
2066
|
+
"icon": icons8_laser_beam_hazard,
|
2059
2067
|
"tip": _("Simulate the current laser job"),
|
2060
2068
|
"action": open_simulator,
|
2061
2069
|
"size": STD_ICON_SIZE,
|