meerk40t 0.9.7051__py2.py3-none-any.whl → 0.9.7910__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 (69) hide show
  1. meerk40t/balormk/controller.py +3 -3
  2. meerk40t/balormk/device.py +7 -0
  3. meerk40t/balormk/driver.py +23 -14
  4. meerk40t/balormk/galvo_commands.py +18 -3
  5. meerk40t/balormk/gui/balorconfig.py +6 -0
  6. meerk40t/balormk/livelightjob.py +36 -14
  7. meerk40t/camera/camera.py +1 -0
  8. meerk40t/camera/gui/camerapanel.py +154 -58
  9. meerk40t/camera/plugin.py +46 -5
  10. meerk40t/core/elements/branches.py +90 -20
  11. meerk40t/core/elements/elements.py +59 -37
  12. meerk40t/core/elements/trace.py +10 -6
  13. meerk40t/core/node/node.py +2 -0
  14. meerk40t/core/plotplanner.py +7 -4
  15. meerk40t/device/gui/defaultactions.py +78 -14
  16. meerk40t/dxf/dxf_io.py +42 -0
  17. meerk40t/grbl/controller.py +245 -35
  18. meerk40t/grbl/device.py +102 -26
  19. meerk40t/grbl/driver.py +8 -2
  20. meerk40t/grbl/gui/grblconfiguration.py +6 -0
  21. meerk40t/grbl/gui/grblcontroller.py +1 -1
  22. meerk40t/gui/about.py +7 -0
  23. meerk40t/gui/choicepropertypanel.py +20 -30
  24. meerk40t/gui/devicepanel.py +27 -16
  25. meerk40t/gui/help_assets/help_assets.py +126 -2
  26. meerk40t/gui/icons.py +15 -0
  27. meerk40t/gui/laserpanel.py +102 -54
  28. meerk40t/gui/materialtest.py +10 -0
  29. meerk40t/gui/mkdebug.py +268 -9
  30. meerk40t/gui/navigationpanels.py +74 -8
  31. meerk40t/gui/propertypanels/operationpropertymain.py +185 -91
  32. meerk40t/gui/scenewidgets/elementswidget.py +7 -1
  33. meerk40t/gui/scenewidgets/selectionwidget.py +24 -9
  34. meerk40t/gui/simulation.py +1 -1
  35. meerk40t/gui/statusbarwidgets/shapepropwidget.py +50 -40
  36. meerk40t/gui/statusbarwidgets/statusbar.py +2 -2
  37. meerk40t/gui/toolwidgets/toolmeasure.py +1 -1
  38. meerk40t/gui/toolwidgets/toolnodeedit.py +4 -1
  39. meerk40t/gui/toolwidgets/tooltabedit.py +9 -7
  40. meerk40t/gui/wxmeerk40t.py +45 -15
  41. meerk40t/gui/wxmmain.py +23 -9
  42. meerk40t/gui/wxmribbon.py +36 -0
  43. meerk40t/gui/wxutils.py +66 -42
  44. meerk40t/kernel/inhibitor.py +120 -0
  45. meerk40t/kernel/kernel.py +38 -0
  46. meerk40t/lihuiyu/controller.py +33 -3
  47. meerk40t/lihuiyu/device.py +99 -4
  48. meerk40t/lihuiyu/driver.py +65 -5
  49. meerk40t/lihuiyu/gui/lhycontrollergui.py +69 -24
  50. meerk40t/lihuiyu/gui/lhydrivergui.py +6 -0
  51. meerk40t/lihuiyu/laserspeed.py +17 -10
  52. meerk40t/lihuiyu/parser.py +23 -0
  53. meerk40t/main.py +2 -2
  54. meerk40t/moshi/gui/moshidrivergui.py +7 -0
  55. meerk40t/newly/controller.py +3 -2
  56. meerk40t/newly/device.py +23 -2
  57. meerk40t/newly/driver.py +8 -3
  58. meerk40t/newly/gui/newlyconfig.py +7 -0
  59. meerk40t/ruida/gui/ruidaconfig.py +7 -0
  60. meerk40t/tools/geomstr.py +142 -49
  61. meerk40t/tools/rasterplotter.py +0 -5
  62. meerk40t/tools/ttfparser.py +921 -168
  63. {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/METADATA +1 -1
  64. {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/RECORD +69 -68
  65. {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/LICENSE +0 -0
  66. {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/WHEEL +0 -0
  67. {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/entry_points.txt +0 -0
  68. {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/top_level.txt +0 -0
  69. {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/zip-safe +0 -0
@@ -1,5 +1,17 @@
1
1
  import wx
2
2
 
3
+ from meerk40t.constants import (
4
+ RASTER_B2T,
5
+ RASTER_CROSSOVER,
6
+ RASTER_GREEDY_H,
7
+ RASTER_GREEDY_V,
8
+ RASTER_HATCH,
9
+ RASTER_L2R,
10
+ RASTER_R2L,
11
+ RASTER_SPIRAL,
12
+ RASTER_T2B,
13
+ )
14
+ from meerk40t.gui.icons import icon_letter_h
3
15
  from meerk40t.gui.wxutils import (
4
16
  ScrolledPanel,
5
17
  StaticBoxSizer,
@@ -13,19 +25,8 @@ from meerk40t.gui.wxutils import (
13
25
  wxStaticBitmap,
14
26
  wxStaticText,
15
27
  )
16
- from meerk40t.constants import (
17
- RASTER_T2B,
18
- RASTER_B2T,
19
- RASTER_R2L,
20
- RASTER_L2R,
21
- RASTER_HATCH,
22
- RASTER_GREEDY_H,
23
- RASTER_GREEDY_V,
24
- RASTER_CROSSOVER,
25
- RASTER_SPIRAL,
26
- )
27
28
  from meerk40t.kernel import lookup_listener, signal_listener
28
- from meerk40t.gui.icons import icon_letter_h
29
+
29
30
  from ...core.units import UNITS_PER_MM, Length
30
31
  from ...svgelements import Color
31
32
  from ..laserrender import swizzlecolor
@@ -44,20 +45,26 @@ _ = wx.GetTranslation
44
45
 
45
46
  def validate_raster_settings(node):
46
47
  # Make sure things are properly set...
47
- if node.raster_direction in (RASTER_T2B, ):
48
+ if node.raster_direction in (RASTER_T2B,):
48
49
  node.raster_preference_top = True
49
- elif node.raster_direction in (RASTER_B2T, ):
50
+ elif node.raster_direction in (RASTER_B2T,):
50
51
  node.raster_preference_top = False
51
- elif node.raster_direction in (RASTER_R2L, ):
52
+ elif node.raster_direction in (RASTER_R2L,):
52
53
  node.raster_preference_left = True
53
- elif node.raster_direction in (RASTER_L2R, ):
54
+ elif node.raster_direction in (RASTER_L2R,):
54
55
  node.raster_preference_left = False
55
56
  elif node.raster_direction in (RASTER_HATCH, RASTER_CROSSOVER):
56
57
  node.raster_preference_top = True
57
58
  node.raster_preference_left = True
58
- if node.raster_direction in (RASTER_CROSSOVER, RASTER_GREEDY_H, RASTER_GREEDY_V, RASTER_SPIRAL):
59
+ if node.raster_direction in (
60
+ RASTER_CROSSOVER,
61
+ RASTER_GREEDY_H,
62
+ RASTER_GREEDY_V,
63
+ RASTER_SPIRAL,
64
+ ):
59
65
  node.bidirectional = True
60
66
 
67
+
61
68
  class LayerSettingPanel(wx.Panel):
62
69
  def __init__(self, *args, context=None, node=None, **kwds):
63
70
  # begin wxGlade: LayerSettingPanel.__init__
@@ -995,7 +1002,9 @@ class PanelStartPreference(wx.Panel):
995
1002
  self.context = context
996
1003
  self.operation = node
997
1004
 
998
- sizer_main = StaticBoxSizer(self, wx.ID_ANY, _("Start Preference:"), wx.VERTICAL)
1005
+ sizer_main = StaticBoxSizer(
1006
+ self, wx.ID_ANY, _("Start Preference:"), wx.VERTICAL
1007
+ )
999
1008
 
1000
1009
  self.slider_pref_left = wx.Slider(self, wx.ID_ANY, 1, 0, 1)
1001
1010
  sizer_main.Add(self.slider_pref_left, 0, wx.EXPAND, 0)
@@ -1061,8 +1070,9 @@ class PanelStartPreference(wx.Panel):
1061
1070
  self.Hide()
1062
1071
  return
1063
1072
  if self.operation.raster_direction in (
1064
- RASTER_CROSSOVER, RASTER_SPIRAL,
1065
- ): # Crossover
1073
+ RASTER_CROSSOVER,
1074
+ RASTER_SPIRAL,
1075
+ ): # Crossover
1066
1076
  self.Hide()
1067
1077
  return
1068
1078
  validate_raster_settings(self.operation)
@@ -1106,7 +1116,7 @@ class PanelStartPreference(wx.Panel):
1106
1116
 
1107
1117
  def calculate_raster_lines(self):
1108
1118
  w, h = self._Buffer.Size
1109
- if w<10 or h<10: # Ini initialisation phase and too small anyway...
1119
+ if w < 10 or h < 10: # Ini initialisation phase and too small anyway...
1110
1120
  return
1111
1121
 
1112
1122
  from_left = self.operation.raster_preference_left
@@ -1146,9 +1156,15 @@ class PanelStartPreference(wx.Panel):
1146
1156
  d_start.append(((w * 0.95) if left else (w * 0.05), h * 0.05))
1147
1157
  d_end.append(((w * 0.95 - 4) if left else (w * 0.05 + 4), h * 0.05 + 4))
1148
1158
 
1149
- if direction in (RASTER_T2B, RASTER_B2T, RASTER_HATCH, RASTER_GREEDY_H, RASTER_CROSSOVER): # Horizontal mode, raster will be built from top to bottom (or vice versa)
1159
+ if direction in (
1160
+ RASTER_T2B,
1161
+ RASTER_B2T,
1162
+ RASTER_HATCH,
1163
+ RASTER_GREEDY_H,
1164
+ RASTER_CROSSOVER,
1165
+ ): # Horizontal mode, raster will be built from top to bottom (or vice versa)
1150
1166
  # Direction Line
1151
- if direction in (RASTER_B2T, ):
1167
+ if direction in (RASTER_B2T,):
1152
1168
  # Bottom to Top
1153
1169
  dir_arrow_up_down(False)
1154
1170
  start = int(h * 0.9)
@@ -1161,7 +1177,7 @@ class PanelStartPreference(wx.Panel):
1161
1177
  end = int(h * 0.9)
1162
1178
  step = 1000 / dpi * factor
1163
1179
  if step == 0:
1164
- step = abs(start-end) / 10
1180
+ step = abs(start - end) / 10
1165
1181
  while abs(step) > abs(start - end):
1166
1182
  step /= 2
1167
1183
  while abs(start - end) / abs(step) > 100:
@@ -1186,8 +1202,14 @@ class PanelStartPreference(wx.Panel):
1186
1202
  if bidirectional:
1187
1203
  from_left = not from_left
1188
1204
  pos += step
1189
- if direction in (RASTER_R2L, RASTER_L2R, RASTER_HATCH, RASTER_GREEDY_V, RASTER_CROSSOVER): # Vertical mode, raster will be built from left to right (or vice versa)
1190
- if direction in (RASTER_R2L, ):
1205
+ if direction in (
1206
+ RASTER_R2L,
1207
+ RASTER_L2R,
1208
+ RASTER_HATCH,
1209
+ RASTER_GREEDY_V,
1210
+ RASTER_CROSSOVER,
1211
+ ): # Vertical mode, raster will be built from left to right (or vice versa)
1212
+ if direction in (RASTER_R2L,):
1191
1213
  # Right to Left
1192
1214
  dir_arrow_left_right(False)
1193
1215
  start = int(w * 0.9)
@@ -1200,7 +1222,7 @@ class PanelStartPreference(wx.Panel):
1200
1222
  end = int(w * 0.9)
1201
1223
  step = 1000 / dpi * factor
1202
1224
  if step == 0:
1203
- step = abs(start-end) / 10
1225
+ step = abs(start - end) / 10
1204
1226
  while abs(step) > abs(start - end):
1205
1227
  step /= 2
1206
1228
  while abs(start - end) / abs(step) > 100:
@@ -1271,18 +1293,23 @@ class PanelStartPreference(wx.Panel):
1271
1293
  prefer_min_y = self.operation.raster_preference_top
1272
1294
  prefer_min_x = self.operation.raster_preference_left
1273
1295
 
1274
- self.slider_pref_left.Enable(direction in (RASTER_T2B, RASTER_B2T, RASTER_GREEDY_H, RASTER_GREEDY_V))
1275
- self.slider_pref_top.Enable(direction in (RASTER_L2R, RASTER_R2L, RASTER_GREEDY_H, RASTER_GREEDY_V))
1296
+ self.slider_pref_left.Enable(
1297
+ direction in (RASTER_T2B, RASTER_B2T, RASTER_GREEDY_H, RASTER_GREEDY_V)
1298
+ )
1299
+ self.slider_pref_top.Enable(
1300
+ direction in (RASTER_L2R, RASTER_R2L, RASTER_GREEDY_H, RASTER_GREEDY_V)
1301
+ )
1276
1302
  self.slider_pref_left.SetValue(0 if prefer_min_x else 1)
1277
1303
  self.slider_pref_top.SetValue(0 if prefer_min_y else 1)
1278
1304
 
1279
-
1280
1305
  def _reload_display(self):
1281
1306
  self.raster_lines = None
1282
1307
  self.travel_lines = None
1283
1308
  self.refresh_display()
1284
1309
 
1285
- def on_slider_pref_left(self, event=None): # wxGlade: OperationProperty.<event_handler>
1310
+ def on_slider_pref_left(
1311
+ self, event=None
1312
+ ): # wxGlade: OperationProperty.<event_handler>
1286
1313
  value = self.slider_pref_left.GetValue() == 0
1287
1314
  if self.operation.raster_preference_left != value:
1288
1315
  self.operation.raster_preference_left = value
@@ -1291,7 +1318,9 @@ class PanelStartPreference(wx.Panel):
1291
1318
  "element_property_update", self.operation, "slider_top"
1292
1319
  )
1293
1320
 
1294
- def on_slider_pref_top(self, event=None): # wxGlade: OperationProperty.<event_handler>
1321
+ def on_slider_pref_top(
1322
+ self, event=None
1323
+ ): # wxGlade: OperationProperty.<event_handler>
1295
1324
  value = self.slider_pref_top.GetValue() == 0
1296
1325
  if self.operation.raster_preference_top != value:
1297
1326
  self.operation.raster_preference_top = value
@@ -1299,6 +1328,8 @@ class PanelStartPreference(wx.Panel):
1299
1328
  self.context.elements.signal(
1300
1329
  "element_property_update", self.operation, "slider_left"
1301
1330
  )
1331
+
1332
+
1302
1333
  # end of class PanelStartPreference
1303
1334
 
1304
1335
 
@@ -1310,7 +1341,9 @@ class RasterSettingsPanel(wx.Panel):
1310
1341
  self.context = context
1311
1342
  self.operation = node
1312
1343
  iconsize = dip_size(self, 30, 20)
1313
- bmpsize = min(iconsize[0], iconsize[1]) * self.context.root.bitmap_correction_scale
1344
+ bmpsize = (
1345
+ min(iconsize[0], iconsize[1]) * self.context.root.bitmap_correction_scale
1346
+ )
1314
1347
 
1315
1348
  raster_sizer = StaticBoxSizer(self, wx.ID_ANY, _("Raster:"), wx.VERTICAL)
1316
1349
  param_sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -1318,7 +1351,9 @@ class RasterSettingsPanel(wx.Panel):
1318
1351
  sizer_dpi = StaticBoxSizer(self, wx.ID_ANY, _("DPI:"), wx.HORIZONTAL)
1319
1352
  param_sizer.Add(sizer_dpi, 1, wx.EXPAND, 0)
1320
1353
  self.check_overrule_dpi = wxCheckBox(self, wx.ID_ANY)
1321
- self.check_overrule_dpi.SetToolTip(_("Overrules image dpi settings and uses this value instead"))
1354
+ self.check_overrule_dpi.SetToolTip(
1355
+ _("Overrules image dpi settings and uses this value instead")
1356
+ )
1322
1357
  self.text_dpi = TextCtrl(
1323
1358
  self,
1324
1359
  wx.ID_ANY,
@@ -1335,36 +1370,67 @@ class RasterSettingsPanel(wx.Panel):
1335
1370
  )
1336
1371
  self.text_dpi.set_error_level(1, 100000)
1337
1372
  OPERATION_DPI_TOOLTIP = (
1338
- _('In a raster engrave, the step size is the distance between raster lines in 1/1000" ') +
1339
- _("and also the number of raster dots that get combined together.") + "\n" +
1340
- _('Because the laser dot is >> 1/1000" in diameter, at step 1 the raster lines overlap a lot, ') +
1341
- _("and consequently you can raster with steps > 1 without leaving gaps between the lines.") + "\n" +
1342
- _("The step size before you get gaps will depend on your focus and the size of your laser dot.") + "\n"+
1343
- _("Step size > 1 reduces the laser energy delivered by the same factor, so you may need to increase ") +
1344
- _("power equivalently with a higher front-panel power, a higher PPI or by rastering at a slower speed.") + "\n" +
1345
- _("Step size > 1 also turns the laser on and off fewer times, and combined with a slower speed") +
1346
- _("this can prevent your laser from stuttering.")
1373
+ _(
1374
+ 'In a raster engrave, the step size is the distance between raster lines in 1/1000" '
1375
+ )
1376
+ + _("and also the number of raster dots that get combined together.")
1377
+ + "\n"
1378
+ + _(
1379
+ 'Because the laser dot is >> 1/1000" in diameter, at step 1 the raster lines overlap a lot, '
1380
+ )
1381
+ + _(
1382
+ "and consequently you can raster with steps > 1 without leaving gaps between the lines."
1383
+ )
1384
+ + "\n"
1385
+ + _(
1386
+ "The step size before you get gaps will depend on your focus and the size of your laser dot."
1387
+ )
1388
+ + "\n"
1389
+ + _(
1390
+ "Step size > 1 reduces the laser energy delivered by the same factor, so you may need to increase "
1391
+ )
1392
+ + _(
1393
+ "power equivalently with a higher front-panel power, a higher PPI or by rastering at a slower speed."
1394
+ )
1395
+ + "\n"
1396
+ + _(
1397
+ "Step size > 1 also turns the laser on and off fewer times, and combined with a slower speed"
1398
+ )
1399
+ + _("this can prevent your laser from stuttering.")
1347
1400
  )
1348
1401
  self.text_dpi.SetToolTip(OPERATION_DPI_TOOLTIP)
1349
1402
  sizer_dpi.Add(self.check_overrule_dpi, 0, wx.EXPAND, 0)
1350
1403
  sizer_dpi.Add(self.text_dpi, 1, wx.EXPAND, 0)
1351
1404
 
1352
- sizer_optimize = StaticBoxSizer(self, wx.ID_ANY, _("Optimize movement:"), wx.HORIZONTAL)
1353
- self.check_laserdot = wxCheckBox(self, wx.ID_ANY, _("Consider laserdot") )
1405
+ sizer_optimize = StaticBoxSizer(
1406
+ self, wx.ID_ANY, _("Optimize movement:"), wx.HORIZONTAL
1407
+ )
1408
+ self.check_laserdot = wxCheckBox(self, wx.ID_ANY, _("Consider laserdot"))
1354
1409
  self.check_laserdot.SetToolTip(
1355
- _("A laser dot has a certain diameter, so for high dpi values, lines will overlap a lot.") + "\n" +
1356
- _("Active: don't burn pixels already overlapped") + "\n" +
1357
- _("Inactive: burn all pixels regardless of a possible overlap.")
1410
+ _(
1411
+ "A laser dot has a certain diameter, so for high dpi values, lines will overlap a lot."
1412
+ )
1413
+ + "\n"
1414
+ + _("Active: don't burn pixels already overlapped")
1415
+ + "\n"
1416
+ + _("Inactive: burn all pixels regardless of a possible overlap.")
1358
1417
  )
1359
1418
  sizer_optimize.Add(self.check_laserdot, 1, wx.EXPAND, 0)
1360
1419
  param_sizer.Add(sizer_optimize, 1, wx.EXPAND, 0)
1361
1420
 
1362
- self.sizer_grayscale = StaticBoxSizer(self, wx.ID_ANY, _("Override black/white image:"), wx.HORIZONTAL)
1421
+ self.sizer_grayscale = StaticBoxSizer(
1422
+ self, wx.ID_ANY, _("Override black/white image:"), wx.HORIZONTAL
1423
+ )
1363
1424
  param_sizer.Add(self.sizer_grayscale, 1, wx.EXPAND, 0)
1364
- self.check_grayscale = wxCheckBox(self, wx.ID_ANY, _("Use grayscale instead") )
1425
+ self.check_grayscale = wxCheckBox(self, wx.ID_ANY, _("Use grayscale instead"))
1365
1426
  self.check_grayscale.SetToolTip(
1366
- _("Usually a raster will be created as a grayscale picture and the burn-power of a pixel will depend on its darkness.") + "\n" +
1367
- _("If you uncheck this value then every non-white pixel (even very light ones) will become black and will be burned at full power.")
1427
+ _(
1428
+ "Usually a raster will be created as a grayscale picture and the burn-power of a pixel will depend on its darkness."
1429
+ )
1430
+ + "\n"
1431
+ + _(
1432
+ "If you uncheck this value then every non-white pixel (even very light ones) will become black and will be burned at full power."
1433
+ )
1368
1434
  )
1369
1435
  self.sizer_grayscale.Add(self.check_grayscale, 1, wx.EXPAND, 0)
1370
1436
 
@@ -1378,7 +1444,11 @@ class RasterSettingsPanel(wx.Panel):
1378
1444
  check="length",
1379
1445
  style=wx.TE_PROCESS_ENTER,
1380
1446
  )
1381
- self.text_overscan.SetToolTip(_("Padding that will be added at the end of a scanline to allow the laser to slow down"))
1447
+ self.text_overscan.SetToolTip(
1448
+ _(
1449
+ "Padding that will be added at the end of a scanline to allow the laser to slow down"
1450
+ )
1451
+ )
1382
1452
  sizer_overscan.Add(self.text_overscan, 1, wx.EXPAND, 0)
1383
1453
 
1384
1454
  raster_sizer.Add(param_sizer, 0, wx.EXPAND, 0)
@@ -1417,7 +1487,7 @@ class RasterSettingsPanel(wx.Panel):
1417
1487
  # )
1418
1488
  # self.raster_terms.extend(test_methods)
1419
1489
 
1420
- self.raster_methods = [ key for key, info in self.raster_terms ]
1490
+ self.raster_methods = [key for key, info in self.raster_terms]
1421
1491
 
1422
1492
  self.combo_raster_direction = wxComboBox(
1423
1493
  self,
@@ -1509,8 +1579,10 @@ class RasterSettingsPanel(wx.Panel):
1509
1579
  instructions = self.context.device.get_raster_instructions()
1510
1580
  unsupported = instructions.get("unsupported_opt", ())
1511
1581
  # print (f"fill raster called: {unsupported}")
1512
- self.raster_methods = [ key for key, info in self.raster_terms if key not in unsupported ]
1513
- choices = [ info for key, info in self.raster_terms if key not in unsupported ]
1582
+ self.raster_methods = [
1583
+ key for key, info in self.raster_terms if key not in unsupported
1584
+ ]
1585
+ choices = [info for key, info in self.raster_terms if key not in unsupported]
1514
1586
  self.combo_raster_direction.Clear()
1515
1587
  self.combo_raster_direction.SetItems(choices)
1516
1588
  if self.operation is not None:
@@ -1572,7 +1644,13 @@ class RasterSettingsPanel(wx.Panel):
1572
1644
  def allow_controls_according_to_optimization(self):
1573
1645
  direction = self.operation.raster_direction
1574
1646
  overscan_okay = direction not in (RASTER_GREEDY_H, RASTER_GREEDY_V)
1575
- swing_okay = direction in (RASTER_B2T, RASTER_T2B, RASTER_R2L, RASTER_L2R, RASTER_HATCH)
1647
+ swing_okay = direction in (
1648
+ RASTER_B2T,
1649
+ RASTER_T2B,
1650
+ RASTER_R2L,
1651
+ RASTER_L2R,
1652
+ RASTER_HATCH,
1653
+ )
1576
1654
  self.text_overscan.Enable(overscan_okay)
1577
1655
  self.radio_raster_swing.Enable(swing_okay)
1578
1656
  if not swing_okay:
@@ -1585,9 +1663,7 @@ class RasterSettingsPanel(wx.Panel):
1585
1663
  self.text_dpi.Enable(b)
1586
1664
  if self.operation.overrule_dpi != b:
1587
1665
  self.operation.overrule_dpi = b
1588
- self.context.signal(
1589
- "element_property_reload", self.operation, "text_dpi"
1590
- )
1666
+ self.context.signal("element_property_reload", self.operation, "text_dpi")
1591
1667
  self.context.signal("warn_state_update")
1592
1668
 
1593
1669
  def on_text_dpi(self):
@@ -1598,9 +1674,7 @@ class RasterSettingsPanel(wx.Panel):
1598
1674
  return
1599
1675
  if self.operation.dpi != value:
1600
1676
  self.operation.dpi = value
1601
- self.context.signal(
1602
- "element_property_reload", self.operation, "text_dpi"
1603
- )
1677
+ self.context.signal("element_property_reload", self.operation, "text_dpi")
1604
1678
  self.context.signal("warn_state_update")
1605
1679
 
1606
1680
  def on_check_grayscale(self, event):
@@ -1641,7 +1715,7 @@ class RasterSettingsPanel(wx.Panel):
1641
1715
  return
1642
1716
  value = self.raster_methods[idx]
1643
1717
 
1644
- if (self.operation.raster_direction != value ):
1718
+ if self.operation.raster_direction != value:
1645
1719
  self.operation.raster_direction = value
1646
1720
  validate_raster_settings(self.operation)
1647
1721
 
@@ -1674,39 +1748,59 @@ class RasterSettingsPanel(wx.Panel):
1674
1748
  unsupported = instructions.get("unsupported_opt", ())
1675
1749
 
1676
1750
  inform = {
1677
- RASTER_T2B: _("- Top To Bottom: follows the picture line by line starting at the top"),
1678
- RASTER_B2T: _("- Bottom To Top: follows the picture line by line starting at the bottom"),
1679
- RASTER_R2L: _("- Right To Left: follows the picture column by column starting at the right side"),
1680
- RASTER_L2R: _("- Left To Right: follows the picture column by column starting at the left side"),
1681
- RASTER_HATCH: _("- Crosshatch: Makes two passes: one horizontally then another one vertically"),
1682
- RASTER_GREEDY_H:
1683
- _("- Greedy horizontal: Instead of following a complete line,") + "\n" +
1684
- _(" this will choose the nearest to be drawn segment,") + "\n" +
1685
- _(" lasering these segments with vertical lines.") + "\n" +
1686
- _(" Usually much faster on an image with a lot of white pixels."),
1687
- RASTER_GREEDY_V:
1688
- _("- Greedy vertical: Instead of following a complete line,") + "\n" +
1689
- _(" this will choose the nearest to be drawn segment,") + "\n" +
1690
- _(" lasering these segments with vertical lines.") + "\n" +
1691
- _(" Usually much faster on an image with a lot of white pixels."),
1692
- RASTER_CROSSOVER:
1693
- _("- Crossover: Sweeping over the image drawing first all lines") + "\n" +
1694
- _(" with a majority of black pixels and then drawing the columns") + "\n" +
1695
- _(" where we have a majority.") + "\n" +
1696
- _(" Usually much faster on an image with a lot of white pixels."),
1697
- RASTER_SPIRAL:
1698
- _("- Spiral: Starting in the center spiralling outwards"),
1751
+ RASTER_T2B: _(
1752
+ "- Top To Bottom: follows the picture line by line starting at the top"
1753
+ ),
1754
+ RASTER_B2T: _(
1755
+ "- Bottom To Top: follows the picture line by line starting at the bottom"
1756
+ ),
1757
+ RASTER_R2L: _(
1758
+ "- Right To Left: follows the picture column by column starting at the right side"
1759
+ ),
1760
+ RASTER_L2R: _(
1761
+ "- Left To Right: follows the picture column by column starting at the left side"
1762
+ ),
1763
+ RASTER_HATCH: _(
1764
+ "- Crosshatch: Makes two passes: one horizontally then another one vertically"
1765
+ ),
1766
+ RASTER_GREEDY_H: _(
1767
+ "- Greedy horizontal: Instead of following a complete line,"
1768
+ )
1769
+ + "\n"
1770
+ + _(" this will choose the nearest to be drawn segment,")
1771
+ + "\n"
1772
+ + _(" lasering these segments with vertical lines.")
1773
+ + "\n"
1774
+ + _(" Usually much faster on an image with a lot of white pixels."),
1775
+ RASTER_GREEDY_V: _(
1776
+ "- Greedy vertical: Instead of following a complete line,"
1777
+ )
1778
+ + "\n"
1779
+ + _(" this will choose the nearest to be drawn segment,")
1780
+ + "\n"
1781
+ + _(" lasering these segments with vertical lines.")
1782
+ + "\n"
1783
+ + _(" Usually much faster on an image with a lot of white pixels."),
1784
+ RASTER_CROSSOVER: _(
1785
+ "- Crossover: Sweeping over the image drawing first all lines"
1786
+ )
1787
+ + "\n"
1788
+ + _(" with a majority of black pixels and then drawing the columns")
1789
+ + "\n"
1790
+ + _(" where we have a majority.")
1791
+ + "\n"
1792
+ + _(" Usually much faster on an image with a lot of white pixels."),
1793
+ RASTER_SPIRAL: _("- Spiral: Starting in the center spiralling outwards"),
1699
1794
  }
1700
1795
  lines = [_("You can choose from the following modes to laser an image:")]
1701
- lines.extend( [info for key, info in inform.items() if key not in unsupported] )
1796
+ lines.extend([info for key, info in inform.items() if key not in unsupported])
1702
1797
 
1703
1798
  message = "\n".join(lines)
1704
1799
  wx.MessageBox(
1705
- caption=_("Help"),
1706
- message=message,
1707
- style=wx.OK|wx.ICON_INFORMATION
1800
+ caption=_("Help"), message=message, style=wx.OK | wx.ICON_INFORMATION
1708
1801
  )
1709
1802
 
1803
+
1710
1804
  # end of class RasterSettingsPanel
1711
1805
 
1712
1806
 
@@ -1864,7 +1958,7 @@ class ParameterPanel(ScrolledPanel):
1864
1958
  # print ("EPR called from:", args)
1865
1959
  try:
1866
1960
  self.raster_panel.panel_start.on_element_property_reload(*args)
1867
- except AttributeError:
1961
+ except (AttributeError, RuntimeError):
1868
1962
  pass
1869
1963
  self.set_widgets(self.operation)
1870
1964
  self.Layout()
@@ -131,7 +131,13 @@ class ElementsWidget(Widget):
131
131
  smallest = bool(self.scene.context.select_smallest) != bool(
132
132
  "ctrl" in modifiers
133
133
  )
134
- elements.set_emphasized_by_position(space_pos, keep_old, smallest)
134
+ use_files = bool(self.scene.context.file_selection)
135
+ elements.set_emphasized_by_position(
136
+ space_pos,
137
+ keep_old_selection=keep_old,
138
+ use_smallest=smallest,
139
+ force_filenodes_too=use_files,
140
+ )
135
141
  elements.signal("select_emphasized_tree", 0)
136
142
  return RESPONSE_CONSUME
137
143
  return RESPONSE_DROP
@@ -31,9 +31,9 @@ from meerk40t.gui.scene.scene import (
31
31
  from meerk40t.gui.scene.sceneconst import HITCHAIN_HIT_AND_DELEGATE
32
32
  from meerk40t.gui.scene.widget import Widget
33
33
  from meerk40t.gui.wxutils import (
34
- dip_size,
35
34
  StaticBoxSizer,
36
35
  create_menu_for_node,
36
+ dip_size,
37
37
  get_gc_full_scale,
38
38
  get_matrix_scale,
39
39
  wxButton,
@@ -178,6 +178,7 @@ def process_event(
178
178
  else:
179
179
  return RESPONSE_CHAIN
180
180
 
181
+
181
182
  def update_elements(scene):
182
183
  elements = scene.context.elements
183
184
  with elements.undofree():
@@ -267,7 +268,9 @@ class BorderWidget(Widget):
267
268
  gc.StrokeLine(sx * center_x, sy * 0, sx * center_x, sy * self.top)
268
269
  gc.StrokeLine(sx * 0, sy * center_y, sx * self.left, sy * center_y)
269
270
  if self.show_rb:
270
- gc.StrokeLine(sx * center_x, sy * self.bottom, sx * center_x, sy * bed_h)
271
+ gc.StrokeLine(
272
+ sx * center_x, sy * self.bottom, sx * center_x, sy * bed_h
273
+ )
271
274
  gc.StrokeLine(sx * self.right, sy * center_y, sx * bed_w, sy * center_y)
272
275
 
273
276
  mypen.SetStyle(wx.PENSTYLE_DOT)
@@ -308,7 +311,9 @@ class BorderWidget(Widget):
308
311
  # Show Y-Value
309
312
  s_txt = str(Length(amount=self.top, digits=2, preferred_units=units))
310
313
  (t_width, t_height) = gc.GetTextExtent(s_txt)
311
- distance = 0.25 * t_height # No text in the way, so a minimal gap suffices
314
+ distance = (
315
+ 0.25 * t_height
316
+ ) # No text in the way, so a minimal gap suffices
312
317
  pos = self.top / 2.0 - t_height / 2
313
318
  if pos + t_height + distance >= self.top:
314
319
  pos = self.top - t_height - distance
@@ -325,7 +330,7 @@ class BorderWidget(Widget):
325
330
  rpos = bed_h - self.bottom
326
331
  s_txt = str(Length(amount=rpos, digits=2, preferred_units=units))
327
332
  (t_width, t_height) = gc.GetTextExtent(s_txt)
328
- distance = 1.5 * t_height # There's text in the way
333
+ distance = 1.5 * t_height # There's text in the way
329
334
  pos = self.bottom + rpos / 2 - t_height / 2
330
335
  if pos - t_height - distance <= self.bottom:
331
336
  pos = self.bottom + distance
@@ -804,7 +809,7 @@ class CornerWidget(Widget):
804
809
  # dx = position[4]
805
810
  # dy = position[5]
806
811
 
807
- if event == 1: # End
812
+ if event == 1: # End
808
813
  update_elements(self.scene)
809
814
  elif event == -1:
810
815
  self.scene.pane.modif_active = True
@@ -1474,7 +1479,9 @@ class MoveWidget(Widget):
1474
1479
  e.text = elements.wordlist_delta(copy_node.text, delta_wordlist)
1475
1480
  e.altered()
1476
1481
  changed_nodes.append(e)
1477
- elif elements.copy_increases_wordlist_references and hasattr(e, "mktext"):
1482
+ elif elements.copy_increases_wordlist_references and hasattr(
1483
+ e, "mktext"
1484
+ ):
1478
1485
  e.mktext = elements.wordlist_delta(e.mktext, delta_wordlist)
1479
1486
  e.altered()
1480
1487
  changed_nodes.append(e)
@@ -1629,7 +1636,7 @@ class MoveWidget(Widget):
1629
1636
 
1630
1637
  # Return the coordinates of the two points
1631
1638
  return min_dist, p1[min_indices[0][0]], p2[min_indices[0][1]]
1632
- except Exception: # out of memory eg
1639
+ except Exception: # out of memory eg
1633
1640
  return None, None, None
1634
1641
 
1635
1642
  b = elements._emphasized_bounds
@@ -1673,7 +1680,9 @@ class MoveWidget(Widget):
1673
1680
  if seg_type in NON_GEOMETRY_TYPES:
1674
1681
  continue
1675
1682
  if np.isnan(start) or np.isnan(end):
1676
- print (f"Strange, encountered within selectionwidget a segment with type: {seg_type} and start={start}, end={end} - coming from element type {e.type}\nPlease inform the developers")
1683
+ print(
1684
+ f"Strange, encountered within selectionwidget a segment with type: {seg_type} and start={start}, end={end} - coming from element type {e.type}\nPlease inform the developers"
1685
+ )
1677
1686
  continue
1678
1687
  if start != last:
1679
1688
  xx = start.real
@@ -1762,7 +1771,9 @@ class MoveWidget(Widget):
1762
1771
  move_to(lastdx, lastdy, interim=False)
1763
1772
  else:
1764
1773
  move_to(
1765
- lastdx - self.master.offset_x, lastdy - self.master.offset_y, interim=False
1774
+ lastdx - self.master.offset_x,
1775
+ lastdy - self.master.offset_y,
1776
+ interim=False,
1766
1777
  )
1767
1778
  self.check_for_magnets()
1768
1779
  # if abs(self.total_dx) + abs(self.total_dy) > 1e-3:
@@ -2715,11 +2726,13 @@ class SelectionWidget(Widget):
2715
2726
  smallest = bool(self.scene.context.select_smallest) != bool(
2716
2727
  "ctrl" in modifiers
2717
2728
  )
2729
+ use_files = bool(self.scene.context.file_selection)
2718
2730
  elements.set_emphasized_by_position(
2719
2731
  space_pos,
2720
2732
  keep_old_selection=False,
2721
2733
  use_smallest=smallest,
2722
2734
  exit_over_selection=True,
2735
+ force_filenodes_too=use_files,
2723
2736
  )
2724
2737
  # Check if reference is still existing
2725
2738
  self.scene.pane.validate_reference()
@@ -2735,11 +2748,13 @@ class SelectionWidget(Widget):
2735
2748
  smallest = bool(self.scene.context.select_smallest) != bool(
2736
2749
  "ctrl" in modifiers
2737
2750
  )
2751
+ use_files = bool(self.scene.context.file_selection)
2738
2752
  elements.set_emphasized_by_position(
2739
2753
  space_pos,
2740
2754
  keep_old_selection=False,
2741
2755
  use_smallest=smallest,
2742
2756
  exit_over_selection=True,
2757
+ force_filenodes_too=use_files,
2743
2758
  )
2744
2759
  elements.signal("activate_selected_nodes", 0)
2745
2760
  return RESPONSE_CONSUME
@@ -1133,8 +1133,8 @@ class SimulationPanel(wx.Panel, Job):
1133
1133
  self.btn_redo_it.Reparent(self.subpanel_optimize)
1134
1134
 
1135
1135
  self.checkbox_optimize.SetMinSize(dip_size(self, -1, 23))
1136
- opt_sizer.Add(self.options_optimize, 1, wx.EXPAND, 0)
1137
1136
  opt_sizer.Add(self.checkbox_optimize, 0, wx.EXPAND, 0)
1137
+ opt_sizer.Add(self.options_optimize, 1, wx.EXPAND, 0)
1138
1138
  opt_sizer.Add(self.btn_redo_it, 0, wx.EXPAND, 0)
1139
1139
  self.subpanel_optimize.SetSizer(opt_sizer)
1140
1140
  self.subpanel_optimize.Layout()