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.
Files changed (187) hide show
  1. meerk40t/balormk/balor_params.py +1 -43
  2. meerk40t/balormk/controller.py +1 -41
  3. meerk40t/balormk/device.py +16 -22
  4. meerk40t/balormk/driver.py +4 -4
  5. meerk40t/balormk/gui/balorconfig.py +2 -2
  6. meerk40t/balormk/gui/balorcontroller.py +13 -5
  7. meerk40t/balormk/gui/baloroperationproperties.py +0 -46
  8. meerk40t/balormk/gui/gui.py +17 -17
  9. meerk40t/camera/gui/camerapanel.py +18 -11
  10. meerk40t/core/cutcode/rastercut.py +3 -1
  11. meerk40t/core/cutplan.py +145 -14
  12. meerk40t/core/elements/clipboard.py +18 -9
  13. meerk40t/core/elements/element_treeops.py +320 -180
  14. meerk40t/core/elements/element_types.py +7 -2
  15. meerk40t/core/elements/elements.py +53 -27
  16. meerk40t/core/elements/geometry.py +8 -0
  17. meerk40t/core/elements/offset_clpr.py +129 -4
  18. meerk40t/core/elements/offset_mk.py +3 -1
  19. meerk40t/core/elements/shapes.py +28 -25
  20. meerk40t/core/laserjob.py +7 -0
  21. meerk40t/core/node/bootstrap.py +4 -0
  22. meerk40t/core/node/effect_hatch.py +85 -96
  23. meerk40t/core/node/effect_wobble.py +309 -0
  24. meerk40t/core/node/elem_image.py +49 -19
  25. meerk40t/core/node/elem_line.py +60 -0
  26. meerk40t/core/node/elem_rect.py +5 -3
  27. meerk40t/core/node/image_processed.py +766 -0
  28. meerk40t/core/node/image_raster.py +113 -0
  29. meerk40t/core/node/node.py +120 -1
  30. meerk40t/core/node/op_cut.py +2 -8
  31. meerk40t/core/node/op_dots.py +0 -8
  32. meerk40t/core/node/op_engrave.py +2 -18
  33. meerk40t/core/node/op_image.py +22 -35
  34. meerk40t/core/node/op_raster.py +0 -9
  35. meerk40t/core/planner.py +32 -2
  36. meerk40t/core/svg_io.py +699 -461
  37. meerk40t/core/treeop.py +191 -0
  38. meerk40t/core/undos.py +15 -1
  39. meerk40t/core/units.py +14 -4
  40. meerk40t/device/dummydevice.py +3 -2
  41. meerk40t/device/gui/defaultactions.py +43 -55
  42. meerk40t/device/gui/formatterpanel.py +58 -49
  43. meerk40t/device/gui/warningpanel.py +12 -12
  44. meerk40t/device/mixins.py +13 -0
  45. meerk40t/dxf/dxf_io.py +9 -5
  46. meerk40t/extra/ezd.py +28 -26
  47. meerk40t/extra/imageactions.py +300 -308
  48. meerk40t/extra/lbrn.py +19 -2
  49. meerk40t/fill/fills.py +6 -6
  50. meerk40t/fill/patternfill.py +1061 -1061
  51. meerk40t/fill/patterns.py +2 -6
  52. meerk40t/grbl/controller.py +168 -52
  53. meerk40t/grbl/device.py +23 -18
  54. meerk40t/grbl/driver.py +39 -0
  55. meerk40t/grbl/emulator.py +79 -19
  56. meerk40t/grbl/gcodejob.py +10 -0
  57. meerk40t/grbl/gui/grblconfiguration.py +2 -2
  58. meerk40t/grbl/gui/grblcontroller.py +24 -8
  59. meerk40t/grbl/gui/grblhardwareconfig.py +153 -0
  60. meerk40t/grbl/gui/gui.py +17 -14
  61. meerk40t/grbl/mock_connection.py +15 -34
  62. meerk40t/grbl/plugin.py +0 -4
  63. meerk40t/grbl/serial_connection.py +2 -1
  64. meerk40t/gui/about.py +8 -5
  65. meerk40t/gui/alignment.py +10 -6
  66. meerk40t/gui/basicops.py +27 -17
  67. meerk40t/gui/bufferview.py +2 -2
  68. meerk40t/gui/choicepropertypanel.py +101 -13
  69. meerk40t/gui/consolepanel.py +12 -9
  70. meerk40t/gui/devicepanel.py +38 -25
  71. meerk40t/gui/executejob.py +6 -4
  72. meerk40t/gui/help_assets/help_assets.py +13 -10
  73. meerk40t/gui/hersheymanager.py +8 -6
  74. meerk40t/gui/icons.py +1951 -3065
  75. meerk40t/gui/imagesplitter.py +14 -7
  76. meerk40t/gui/keymap.py +3 -3
  77. meerk40t/gui/laserpanel.py +151 -84
  78. meerk40t/gui/laserrender.py +61 -70
  79. meerk40t/gui/lasertoolpanel.py +8 -7
  80. meerk40t/gui/materialtest.py +3 -3
  81. meerk40t/gui/mkdebug.py +254 -1
  82. meerk40t/gui/navigationpanels.py +321 -180
  83. meerk40t/gui/notes.py +3 -3
  84. meerk40t/gui/opassignment.py +12 -12
  85. meerk40t/gui/operation_info.py +13 -13
  86. meerk40t/gui/plugin.py +5 -0
  87. meerk40t/gui/position.py +20 -18
  88. meerk40t/gui/preferences.py +21 -6
  89. meerk40t/gui/propertypanels/attributes.py +70 -22
  90. meerk40t/gui/propertypanels/blobproperty.py +2 -2
  91. meerk40t/gui/propertypanels/consoleproperty.py +2 -2
  92. meerk40t/gui/propertypanels/groupproperties.py +3 -3
  93. meerk40t/gui/propertypanels/hatchproperty.py +11 -18
  94. meerk40t/gui/propertypanels/imageproperty.py +4 -3
  95. meerk40t/gui/propertypanels/opbranchproperties.py +1 -1
  96. meerk40t/gui/propertypanels/pathproperty.py +2 -2
  97. meerk40t/gui/propertypanels/pointproperty.py +2 -2
  98. meerk40t/gui/propertypanels/propertywindow.py +4 -4
  99. meerk40t/gui/propertypanels/textproperty.py +3 -3
  100. meerk40t/gui/propertypanels/wobbleproperty.py +204 -0
  101. meerk40t/gui/ribbon.py +367 -259
  102. meerk40t/gui/scene/scene.py +31 -5
  103. meerk40t/gui/scenewidgets/elementswidget.py +12 -4
  104. meerk40t/gui/scenewidgets/gridwidget.py +2 -2
  105. meerk40t/gui/scenewidgets/laserpathwidget.py +7 -2
  106. meerk40t/gui/scenewidgets/machineoriginwidget.py +6 -2
  107. meerk40t/gui/scenewidgets/relocatewidget.py +1 -1
  108. meerk40t/gui/scenewidgets/reticlewidget.py +9 -0
  109. meerk40t/gui/scenewidgets/selectionwidget.py +12 -7
  110. meerk40t/gui/simpleui.py +95 -8
  111. meerk40t/gui/simulation.py +44 -36
  112. meerk40t/gui/spoolerpanel.py +124 -26
  113. meerk40t/gui/statusbarwidgets/defaultoperations.py +18 -6
  114. meerk40t/gui/statusbarwidgets/infowidget.py +2 -2
  115. meerk40t/gui/statusbarwidgets/opassignwidget.py +12 -12
  116. meerk40t/gui/statusbarwidgets/shapepropwidget.py +45 -18
  117. meerk40t/gui/statusbarwidgets/statusbar.py +11 -4
  118. meerk40t/gui/themes.py +78 -0
  119. meerk40t/gui/toolwidgets/toolcircle.py +2 -1
  120. meerk40t/gui/toolwidgets/toolellipse.py +2 -1
  121. meerk40t/gui/toolwidgets/toolimagecut.py +132 -0
  122. meerk40t/gui/toolwidgets/toolline.py +144 -0
  123. meerk40t/gui/toolwidgets/toolnodeedit.py +72 -145
  124. meerk40t/gui/toolwidgets/toolpoint.py +1 -1
  125. meerk40t/gui/toolwidgets/toolpolygon.py +8 -55
  126. meerk40t/gui/toolwidgets/toolrect.py +2 -1
  127. meerk40t/gui/usbconnect.py +2 -2
  128. meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +2 -2
  129. meerk40t/gui/utilitywidgets/harmonograph.py +7 -7
  130. meerk40t/gui/utilitywidgets/scalewidget.py +1 -1
  131. meerk40t/gui/wordlisteditor.py +33 -18
  132. meerk40t/gui/wxmeerk40t.py +166 -66
  133. meerk40t/gui/wxmmain.py +236 -157
  134. meerk40t/gui/wxmribbon.py +49 -25
  135. meerk40t/gui/wxmscene.py +49 -38
  136. meerk40t/gui/wxmtree.py +216 -85
  137. meerk40t/gui/wxutils.py +62 -4
  138. meerk40t/image/imagetools.py +443 -15
  139. meerk40t/internal_plugins.py +2 -10
  140. meerk40t/kernel/kernel.py +12 -4
  141. meerk40t/lihuiyu/controller.py +7 -7
  142. meerk40t/lihuiyu/device.py +3 -1
  143. meerk40t/lihuiyu/driver.py +3 -0
  144. meerk40t/lihuiyu/gui/gui.py +8 -8
  145. meerk40t/lihuiyu/gui/lhyaccelgui.py +2 -2
  146. meerk40t/lihuiyu/gui/lhycontrollergui.py +73 -27
  147. meerk40t/lihuiyu/gui/lhydrivergui.py +2 -2
  148. meerk40t/lihuiyu/gui/tcpcontroller.py +22 -9
  149. meerk40t/main.py +6 -1
  150. meerk40t/moshi/controller.py +5 -5
  151. meerk40t/moshi/device.py +5 -2
  152. meerk40t/moshi/driver.py +4 -0
  153. meerk40t/moshi/gui/gui.py +8 -8
  154. meerk40t/moshi/gui/moshicontrollergui.py +24 -8
  155. meerk40t/moshi/gui/moshidrivergui.py +2 -2
  156. meerk40t/newly/controller.py +2 -0
  157. meerk40t/newly/device.py +9 -2
  158. meerk40t/newly/driver.py +4 -0
  159. meerk40t/newly/gui/gui.py +16 -17
  160. meerk40t/newly/gui/newlyconfig.py +2 -2
  161. meerk40t/newly/gui/newlycontroller.py +13 -5
  162. meerk40t/rotary/gui/gui.py +2 -2
  163. meerk40t/rotary/gui/rotarysettings.py +2 -2
  164. meerk40t/ruida/device.py +3 -0
  165. meerk40t/ruida/driver.py +4 -0
  166. meerk40t/ruida/gui/gui.py +6 -6
  167. meerk40t/ruida/gui/ruidaconfig.py +2 -2
  168. meerk40t/ruida/gui/ruidacontroller.py +13 -5
  169. meerk40t/svgelements.py +9 -9
  170. meerk40t/tools/geomstr.py +849 -153
  171. meerk40t/tools/kerftest.py +8 -4
  172. meerk40t/tools/livinghinges.py +15 -8
  173. {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/METADATA +21 -16
  174. {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/RECORD +185 -177
  175. {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/entry_points.txt +0 -1
  176. test/test_core_elements.py +8 -24
  177. test/test_file_svg.py +88 -0
  178. test/test_fill.py +9 -9
  179. test/test_geomstr.py +258 -8
  180. test/test_kernel.py +4 -0
  181. test/test_tools_rasterplotter.py +29 -0
  182. meerk40t/extra/embroider.py +0 -56
  183. meerk40t/extra/pathoptimize.py +0 -249
  184. {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/LICENSE +0 -0
  185. {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/WHEEL +0 -0
  186. {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/top_level.txt +0 -0
  187. {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/zip-safe +0 -0
@@ -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.request_refresh_for_animation()
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.request_refresh()
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
- if event_type == "rightdown" and not modifiers:
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
- self.scene.context("tool_menu")
87
- return RESPONSE_CONSUME
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(float(self.scene.context.device.view.unit_width), self.max_x)
294
- self.max_y = min(float(self.scene.context.device.view.unit_height), self.max_y)
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.laserpath = [[0, 0] for _ in range(1000)], [[0, 0] for _ in range(1000)]
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(1000)], [[0, 0] for _ in range(1000)]
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
- gc.DrawRectangle(dev0x - margin, dev0y - margin, margin * 2, margin * 2)
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.icons8_center_of_gravity_50.GetBitmap()
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(None)
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(None)
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(None)
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(None)
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
- for optional in ("fill", "stroke"):
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 optional in ("wxfont", "mktext", "mkfont", "mkfontsize"):
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 icons8_computer_support_50, icons8_opened_folder_50
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 availible panel.
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.HORIZONTAL)
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(icons8_opened_folder_50.GetBitmap())
39
- sizer_buttons.Add(self.button_load, 0, wx.ALIGN_CENTER_VERTICAL, 0)
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(icons8_computer_support_50.GetBitmap())
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", (Jog, {"icon_size": 20}))
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))
@@ -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
- icons8_bell_20,
30
- icons8_close_window_20,
31
- icons8_home_20,
32
- icons8_image_50,
33
- icons8_input_20,
34
- icons8_laser_beam_hazard2_50,
35
- icons8_output_20,
36
- icons8_pause_50,
37
- icons8_play_50,
38
- icons8_return_20,
39
- icons8_route_50,
40
- icons8_stop_gesture_20,
41
- icons8_system_task_20,
42
- icons8_timer_20,
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", icons8_bell_20],
111
- ["interrupt", icons8_stop_gesture_20],
112
- ["quit", icons8_close_window_20],
113
- ["wait", icons8_timer_20],
114
- ["home", icons8_home_20],
115
- ["goto", icons8_return_20],
116
- ["origin", icons8_return_20],
117
- ["output", icons8_output_20],
118
- ["input", icons8_input_20],
119
- ["cutcode", icons8_laser_beam_hazard2_50],
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", icons8_system_task_20],
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
- if optimise_at_start:
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(icons8_play_50.GetBitmap())
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(icons8_route_50.GetBitmap())
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(icons8_pause_50.GetBitmap())
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(icons8_play_50.GetBitmap())
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
- icons8_image_50.GetBitmap(),
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(icons8_laser_beam_hazard2_50.GetBitmap())
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": icons8_laser_beam_hazard2_50,
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,