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
meerk40t/gui/wxmtree.py CHANGED
@@ -9,42 +9,48 @@ from ..svgelements import Color
9
9
  from .basicops import BasicOpPanel
10
10
  from .icons import (
11
11
  get_default_scale_factor,
12
+ icon_bell,
13
+ icon_bmap_text,
14
+ icon_canvas,
15
+ icon_close_window,
16
+ icon_console,
17
+ icon_effect_hatch,
18
+ icon_effect_wobble,
19
+ icon_external,
20
+ icon_internal,
21
+ icon_line,
12
22
  icon_meerk40t,
13
- icons8_bell_20,
14
- icons8_canvas_20,
15
- icons8_close_window_20,
16
- icons8_diagonal_20,
17
- icons8_direction_20,
18
- icons8_file_20,
19
- icons8_ghost_20,
20
- icons8_group_objects_20,
21
- icons8_home_20,
22
- icons8_home_location_20,
23
- icons8_image_20,
24
- icons8_input_20,
25
- icons8_journey_20,
26
- icons8_laser_beam_20,
27
- icons8_line_20,
28
- icons8_lock_50,
29
- icons8_output_20,
30
- icons8_oval_20,
31
- icons8_polyline_50,
32
- icons8_prototype_20,
23
+ icon_mk_ellipse,
24
+ icon_mk_polyline,
25
+ icon_mk_rectangular,
26
+ icon_path,
27
+ icon_points,
28
+ icon_regmarks,
29
+ icon_return,
30
+ icon_round_stop,
31
+ icon_timer,
32
+ icon_tree,
33
+ icon_warning,
34
+ icons8_direction,
35
+ icons8_file,
36
+ icons8_ghost,
37
+ icons8_group_objects,
38
+ icons8_home_filled,
39
+ icons8_image,
40
+ icons8_laser_beam,
41
+ icons8_laserbeam_weak,
42
+ icons8_lock,
33
43
  icons8_r_white,
34
- icons8_rectangular_20,
35
- icons8_return_20,
36
- icons8_scatter_plot_20,
37
- icons8_small_beam_20,
38
- icons8_smartphone_ram_50,
39
- icons8_stop_gesture_20,
40
- icons8_system_task_20,
41
- icons8_timer_20,
42
- icons8_type_50,
43
- icons8_warning_shield_20,
44
44
  )
45
45
  from .laserrender import DRAW_MODE_ICONS, LaserRender, swizzlecolor
46
46
  from .mwindow import MWindow
47
- from .wxutils import create_menu, get_key_name, is_navigation_key
47
+ from .wxutils import (
48
+ StaticBoxSizer,
49
+ create_menu,
50
+ dip_size,
51
+ get_key_name,
52
+ is_navigation_key,
53
+ )
48
54
 
49
55
  _ = wx.GetTranslation
50
56
 
@@ -115,11 +121,19 @@ class TreePanel(wx.Panel):
115
121
  | wx.TR_HIDE_ROOT
116
122
  | wx.TR_LINES_AT_ROOT,
117
123
  )
118
- if wx.SystemSettings().GetColour(wx.SYS_COLOUR_WINDOW)[0] < 127:
124
+ # try:
125
+ # res = wx.SystemSettings().GetAppearance().IsDark()
126
+ # except AttributeError:
127
+ # res = wx.SystemSettings().GetColour(wx.SYS_COLOUR_WINDOW)[0] < 127
128
+ res = wx.SystemSettings().GetColour(wx.SYS_COLOUR_WINDOW)[0] < 127
129
+ if res:
119
130
  self.wxtree.SetBackgroundColour(wx.Colour(50, 50, 50))
120
131
 
132
+ self.setup_warn_panel()
133
+
121
134
  main_sizer = wx.BoxSizer(wx.VERTICAL)
122
135
  main_sizer.Add(self.wxtree, 1, wx.EXPAND, 0)
136
+ main_sizer.Add(self.warn_panel, 0, wx.EXPAND, 0)
123
137
  self.SetSizer(main_sizer)
124
138
  self.__set_tree()
125
139
  self.wxtree.Bind(wx.EVT_KEY_UP, self.on_key_up)
@@ -128,6 +142,95 @@ class TreePanel(wx.Panel):
128
142
 
129
143
  self.context.signal("rebuild_tree")
130
144
 
145
+ def setup_warn_panel(self):
146
+ def fix_unassigned_create(event):
147
+ previous = self.context.elements.classify_autogenerate
148
+ self.context.elements.classify_autogenerate = True
149
+ target_list = list(self.context.elements.unassigned_elements())
150
+ self.context.elements.classify(target_list)
151
+ self.context.elements.classify_autogenerate = previous
152
+ self.context.elements.signal("refresh_tree")
153
+
154
+ def fix_unassigned_used(event):
155
+ previous = self.context.elements.classify_autogenerate
156
+ self.context.elements.classify_autogenerate = False
157
+ target_list = list(self.context.elements.unassigned_elements())
158
+ self.context.elements.classify(target_list)
159
+ self.context.elements.classify_autogenerate = previous
160
+ self.context.elements.signal("refresh_tree")
161
+
162
+ def fix_unburnt(event):
163
+ for node in self.context.elements.elems():
164
+ will_be_burnt = False
165
+ first_op = None
166
+ for refnode in node._references:
167
+ op = refnode.parent
168
+ if op is not None:
169
+ try:
170
+ if op.output:
171
+ will_be_burnt = True
172
+ break
173
+ else:
174
+ if first_op is None:
175
+ first_op = op
176
+ except AttributeError:
177
+ pass
178
+ if not will_be_burnt and first_op is not None:
179
+ try:
180
+ first_op.output = True
181
+ self.context.elements.signal(
182
+ "element_property_update", first_op
183
+ )
184
+ self.context.elements.signal("warn_state_update")
185
+ except AttributeError:
186
+ pass
187
+
188
+ self.warn_panel = wx.BoxSizer(wx.HORIZONTAL)
189
+ unassigned_frame = StaticBoxSizer(self, wx.ID_ANY, "Unassigned", wx.HORIZONTAL)
190
+ unburnt_frame = StaticBoxSizer(self, wx.ID_ANY, "Non-burnt", wx.HORIZONTAL)
191
+ self.btn_fix_assign_create = wx.Button(self, wx.ID_ANY, "Assign (+new)")
192
+ self.btn_fix_assign_existing = wx.Button(self, wx.ID_ANY, "Assign")
193
+ self.btn_fix_unburnt = wx.Button(self, wx.ID_ANY, "Enable")
194
+ self.btn_fix_assign_create.SetToolTip(
195
+ _("Classify unassigned elements and create operations if necessary")
196
+ )
197
+ self.btn_fix_assign_existing.SetToolTip(
198
+ _("Classify unassigned elements and use only existing operations")
199
+ )
200
+ self.btn_fix_unburnt.SetToolTip(
201
+ _("Reactivate disabled operations that prevent elements from being burnt")
202
+ )
203
+
204
+ unassigned_frame.Add(self.btn_fix_assign_create, 0, wx.EXPAND, 0)
205
+ unassigned_frame.Add(self.btn_fix_assign_existing, 0, wx.EXPAND, 0)
206
+ unburnt_frame.Add(self.btn_fix_unburnt, 0, wx.EXPAND, 0)
207
+ self.warn_panel.Add(unassigned_frame, 1, wx.EXPAND, 0)
208
+ self.warn_panel.Add(unburnt_frame, 1, wx.EXPAND, 0)
209
+ self._last_issue = None
210
+ self.warn_panel.Show(False)
211
+ self.warn_panel.ShowItems(False)
212
+ self.Bind(wx.EVT_BUTTON, fix_unassigned_create, self.btn_fix_assign_create)
213
+ self.Bind(wx.EVT_BUTTON, fix_unassigned_used, self.btn_fix_assign_existing)
214
+ self.Bind(wx.EVT_BUTTON, fix_unburnt, self.btn_fix_unburnt)
215
+ # self.Show(False)
216
+
217
+ def check_for_issues(self):
218
+ non_assigned, non_burn = self.context.elements.have_unburnable_elements()
219
+ self.btn_fix_assign_create.Enable(non_assigned)
220
+ self.btn_fix_assign_existing.Enable(non_assigned)
221
+ self.btn_fix_unburnt.Enable(non_burn)
222
+ new_issue = non_assigned or non_burn
223
+ if self._last_issue == new_issue:
224
+ return
225
+ self._last_issue = new_issue
226
+ if new_issue:
227
+ self.warn_panel.Show(True)
228
+ self.warn_panel.ShowItems(True)
229
+ else:
230
+ self.warn_panel.Show(False)
231
+ self.warn_panel.ShowItems(False)
232
+ self.Layout()
233
+
131
234
  def __set_tree(self):
132
235
  self.shadow_tree = ShadowTree(
133
236
  self.context.elements, self.GetParent(), self.wxtree, self.context
@@ -216,6 +319,7 @@ class TreePanel(wx.Panel):
216
319
  def on_warn_state_update(self, origin, *args):
217
320
  # Updates the warning state, using signal to avoid unnecessary calls
218
321
  self.shadow_tree.update_warn_sign()
322
+ self.check_for_issues()
219
323
 
220
324
  @signal_listener("select_emphasized_tree")
221
325
  def on_shadow_select_emphasized_tree(self, origin, *args):
@@ -365,7 +469,7 @@ class ElementsTree(MWindow):
365
469
  self.panel = TreePanel(self, wx.ID_ANY, context=self.context)
366
470
  self.add_module_delegate(self.panel)
367
471
  _icon = wx.NullIcon
368
- _icon.CopyFromBitmap(icons8_smartphone_ram_50.GetBitmap())
472
+ _icon.CopyFromBitmap(icon_tree.GetBitmap())
369
473
  self.SetIcon(_icon)
370
474
  self.SetTitle(_("Tree"))
371
475
 
@@ -400,49 +504,51 @@ class ShadowTree:
400
504
  self.tree_images = None
401
505
  self.name = "Project"
402
506
  self._freeze = False
403
- self.iconsize = 20
507
+ testsize = dip_size(self, 20, 20)
508
+ self.iconsize = testsize[1]
404
509
  self.iconstates = {}
405
510
  self.last_call = 0
406
511
 
407
- fact = get_default_scale_factor()
408
- if fact > 1.0:
409
- self.iconsize = int(self.iconsize * fact)
512
+ # fact = get_default_scale_factor()
513
+ # if fact > 1.0:
514
+ # self.iconsize = int(self.iconsize * fact)
410
515
 
411
516
  self.do_not_select = False
412
517
  self.was_already_expanded = []
413
518
  service.add_service_delegate(self)
414
519
  self.setup_state_images()
415
520
  self.default_images = {
416
- "console home -f": icons8_home_20,
417
- "console move_abs": icons8_return_20,
418
- "console beep": icons8_bell_20,
419
- "console interrupt": icons8_stop_gesture_20,
420
- "console quit": icons8_close_window_20,
421
- "util wait": icons8_timer_20,
422
- "util home": icons8_home_20,
423
- "util goto": icons8_return_20,
424
- "util output": icons8_output_20,
425
- "util input": icons8_input_20,
426
- "util console": icons8_system_task_20,
427
- "op engrave": icons8_small_beam_20,
428
- "op cut": icons8_laser_beam_20,
429
- "op image": icons8_image_20,
430
- "op raster": icons8_direction_20,
431
- "op dots": icons8_scatter_plot_20,
432
- "effect hatch": icons8_diagonal_20,
433
- "place current": icons8_home_location_20,
434
- "place point": icons8_home_location_20,
435
- "elem point": icons8_scatter_plot_20,
436
- "file": icons8_file_20,
437
- "group": icons8_group_objects_20,
438
- "elem rect": icons8_rectangular_20,
439
- "elem ellipse": icons8_oval_20,
440
- "elem image": icons8_image_20,
441
- "elem path": icons8_journey_20,
442
- "elem line": icons8_line_20,
443
- "elem polyline": icons8_polyline_50,
444
- "elem text": icons8_type_50,
445
- "blob": icons8_file_20,
521
+ "console home -f": icons8_home_filled,
522
+ "console move_abs": icon_return,
523
+ "console beep": icon_bell,
524
+ "console interrupt": icon_round_stop,
525
+ "console quit": icon_close_window,
526
+ "util wait": icon_timer,
527
+ "util home": icons8_home_filled,
528
+ "util goto": icon_return,
529
+ "util output": icon_external,
530
+ "util input": icon_internal,
531
+ "util console": icon_console,
532
+ "op engrave": icons8_laserbeam_weak,
533
+ "op cut": icons8_laser_beam,
534
+ "op image": icons8_image,
535
+ "op raster": icons8_direction,
536
+ "op dots": icon_points,
537
+ "effect hatch": icon_effect_hatch,
538
+ "effect wobble": icon_effect_wobble,
539
+ "place current": icons8_home_filled,
540
+ "place point": icons8_home_filled,
541
+ "elem point": icon_points,
542
+ "file": icons8_file,
543
+ "group": icons8_group_objects,
544
+ "elem rect": icon_mk_rectangular,
545
+ "elem ellipse": icon_mk_ellipse,
546
+ "elem image": icons8_image,
547
+ "elem path": icon_path,
548
+ "elem line": icon_line,
549
+ "elem polyline": icon_mk_polyline,
550
+ "elem text": icon_bmap_text,
551
+ "blob": icons8_file,
446
552
  }
447
553
  self.image_cache = []
448
554
  self.cache_hits = 0
@@ -461,23 +567,31 @@ class ShadowTree:
461
567
  self.state_images = wx.ImageList()
462
568
  self.iconstates = {}
463
569
  self.state_images.Create(width=self.iconsize, height=self.iconsize)
464
- image = icons8_lock_50.GetBitmap(
465
- resize=(self.iconsize, self.iconsize), noadjustment=True
570
+ image = icons8_lock.GetBitmap(
571
+ resize=(self.iconsize, self.iconsize),
572
+ noadjustment=True,
573
+ buffer=1,
466
574
  )
467
575
  image_id = self.state_images.Add(bitmap=image)
468
576
  self.iconstates["lock"] = image_id
469
577
  image = icons8_r_white.GetBitmap(
470
- resize=(self.iconsize, self.iconsize), noadjustment=True
578
+ resize=(self.iconsize, self.iconsize),
579
+ noadjustment=True,
580
+ buffer=1,
471
581
  )
472
582
  image_id = self.state_images.Add(bitmap=image)
473
583
  self.iconstates["refobject"] = image_id
474
- image = icons8_warning_shield_20.GetBitmap(
475
- resize=(self.iconsize, self.iconsize), noadjustment=True
584
+ image = icon_warning.GetBitmap(
585
+ resize=(self.iconsize, self.iconsize),
586
+ noadjustment=True,
587
+ buffer=1,
476
588
  )
477
589
  image_id = self.state_images.Add(bitmap=image)
478
590
  self.iconstates["warning"] = image_id
479
- image = icons8_ghost_20.GetBitmap(
480
- resize=(self.iconsize, self.iconsize), noadjustment=True
591
+ image = icons8_ghost.GetBitmap(
592
+ resize=(self.iconsize, self.iconsize),
593
+ noadjustment=True,
594
+ buffer=1,
481
595
  )
482
596
  image_id = self.state_images.Add(bitmap=image)
483
597
  self.iconstates["ghost"] = image_id
@@ -870,9 +984,13 @@ class ShadowTree:
870
984
  return
871
985
 
872
986
  self.wxtree._freeze = False
873
- self.wxtree.Expand(self.elements.get(type="branch elems")._item)
874
- self.wxtree.Expand(self.elements.get(type="branch reg")._item)
875
- self.update_warn_sign()
987
+ branch_elems_item = self.elements.get(type="branch elems")._item
988
+ if branch_elems_item:
989
+ self.wxtree.Expand(branch_elems_item)
990
+ branch_reg_item = self.elements.get(type="branch reg")._item
991
+ if branch_reg_item:
992
+ self.wxtree.Expand(branch_reg_item)
993
+ self.context.elements.signal("warn_state_update")
876
994
  self.context.elements.set_end_time("full_load", display=True, delete=True)
877
995
 
878
996
  def update_warn_sign(self):
@@ -1003,7 +1121,10 @@ class ShadowTree:
1003
1121
  self.set_icon(
1004
1122
  elemtree,
1005
1123
  icon_meerk40t.GetBitmap(
1006
- False, resize=(self.iconsize, self.iconsize), noadjustment=True
1124
+ False,
1125
+ resize=(self.iconsize, self.iconsize),
1126
+ noadjustment=True,
1127
+ buffer=1,
1007
1128
  ),
1008
1129
  )
1009
1130
  self.register_children(elemtree)
@@ -1011,8 +1132,10 @@ class ShadowTree:
1011
1132
  node_operations = elemtree.get(type="branch ops")
1012
1133
  self.set_icon(
1013
1134
  node_operations,
1014
- icons8_laser_beam_20.GetBitmap(
1015
- resize=(self.iconsize, self.iconsize), noadjustment=True
1135
+ icons8_laser_beam.GetBitmap(
1136
+ resize=(self.iconsize, self.iconsize),
1137
+ noadjustment=True,
1138
+ buffer=1,
1016
1139
  ),
1017
1140
  )
1018
1141
 
@@ -1022,16 +1145,20 @@ class ShadowTree:
1022
1145
  node_elements = elemtree.get(type="branch elems")
1023
1146
  self.set_icon(
1024
1147
  node_elements,
1025
- icons8_canvas_20.GetBitmap(
1026
- resize=(self.iconsize, self.iconsize), noadjustment=True
1148
+ icon_canvas.GetBitmap(
1149
+ resize=(self.iconsize, self.iconsize),
1150
+ noadjustment=True,
1151
+ buffer=1,
1027
1152
  ),
1028
1153
  )
1029
1154
 
1030
1155
  node_registration = elemtree.get(type="branch reg")
1031
1156
  self.set_icon(
1032
1157
  node_registration,
1033
- icons8_prototype_20.GetBitmap(
1034
- resize=(self.iconsize, self.iconsize), noadjustment=True
1158
+ icon_regmarks.GetBitmap(
1159
+ resize=(self.iconsize, self.iconsize),
1160
+ noadjustment=True,
1161
+ buffer=1,
1035
1162
  ),
1036
1163
  )
1037
1164
  self.update_op_labels()
@@ -1267,7 +1394,7 @@ class ShadowTree:
1267
1394
  and node.fill.argb is not None
1268
1395
  ):
1269
1396
  c = node.fill
1270
- elif node.type.startswith("elem "):
1397
+ elif node.type.startswith("elem ") or node.type.startswith("effect "):
1271
1398
  if (
1272
1399
  hasattr(node, "stroke")
1273
1400
  and node.stroke is not None
@@ -1308,6 +1435,7 @@ class ShadowTree:
1308
1435
  color=c,
1309
1436
  resize=(self.iconsize, self.iconsize),
1310
1437
  noadjustment=True,
1438
+ buffer=1,
1311
1439
  )
1312
1440
  cached_id = self.tree_images.Add(bitmap=image)
1313
1441
  # print(f"Store id {cached_id} for {c} - {found}")
@@ -1712,6 +1840,9 @@ class ShadowTree:
1712
1840
  # have led to the creation of a new reference
1713
1841
  # node. For whatever reason this is not recognised
1714
1842
  # otherwise...
1843
+ if not self.dragging_nodes:
1844
+ # Dragging nodes were cleared (we must have rebuilt the entire tree)
1845
+ return
1715
1846
  for node in self.dragging_nodes:
1716
1847
  if node.type.startswith("op"):
1717
1848
  self.context.signal("tree_changed")
meerk40t/gui/wxutils.py CHANGED
@@ -13,9 +13,15 @@ from meerk40t.core.units import ACCEPTED_UNITS, Angle, Length
13
13
  _ = wx.GetTranslation
14
14
 
15
15
 
16
+ ##############
17
+ # DYNAMIC CHOICE
18
+ # NODE MENU
19
+ ##############
20
+
21
+
16
22
  def create_menu_for_choices(gui, choices: List[dict]) -> wx.Menu:
17
23
  """
18
- Creates a menu for a given choices table
24
+ Creates a menu for a given choices table.
19
25
 
20
26
  Processes submenus, references, radio_state as needed.
21
27
  """
@@ -92,6 +98,13 @@ def create_menu_for_choices(gui, choices: List[dict]) -> wx.Menu:
92
98
 
93
99
 
94
100
  def create_choices_for_node(node, elements) -> List[dict]:
101
+ """
102
+ Converts a node tree operation menu to a choices dictionary to display the menu items in a choice panel.
103
+
104
+ @param node:
105
+ @param elements:
106
+ @return:
107
+ """
95
108
  choices = []
96
109
  from meerk40t.core.treeop import get_tree_operation_for_node
97
110
 
@@ -121,6 +134,9 @@ def create_menu_for_node_TEST(gui, node, elements) -> wx.Menu:
121
134
  """
122
135
  Test code towards unifying choices and tree nodes into choices that parse to menus.
123
136
 
137
+ This is unused experimental code. Testing the potential inter-relationships between choices for the choice panels
138
+ and dynamic node menus.
139
+
124
140
  @param gui:
125
141
  @param node:
126
142
  @param elements:
@@ -130,6 +146,11 @@ def create_menu_for_node_TEST(gui, node, elements) -> wx.Menu:
130
146
  return create_menu_for_choices(gui, choices)
131
147
 
132
148
 
149
+ ##############
150
+ # DYNAMIC NODE MENU
151
+ ##############
152
+
153
+
133
154
  def create_menu_for_node(gui, node, elements, optional_2nd_node=None) -> wx.Menu:
134
155
  """
135
156
  Create menu for a particular node. Does not invoke the menu.
@@ -329,9 +350,18 @@ def create_menu(gui, node, elements):
329
350
  menu.Destroy()
330
351
 
331
352
 
353
+ ##############
354
+ # GUI CONTROL OVERRIDES
355
+ ##############
356
+
357
+
332
358
  class TextCtrl(wx.TextCtrl):
333
- # Just to add someof the more common things we need, i.e. smaller default size...
334
- #
359
+ """
360
+ Just to add some of the more common things we need, i.e. smaller default size...
361
+
362
+ Allow text boxes of specific types so that we can have consistent options for dealing with them.
363
+ """
364
+
335
365
  def __init__(
336
366
  self,
337
367
  parent,
@@ -427,6 +457,21 @@ class TextCtrl(wx.TextCtrl):
427
457
  maxw = 100
428
458
  minpattern = "0000"
429
459
  maxpattern = "999999999.99mm"
460
+ if self._check == "length":
461
+ minpattern = "0000"
462
+ maxpattern = "999999999.99mm"
463
+ elif self._check == "percent":
464
+ minpattern = "0000"
465
+ maxpattern = "99.99%"
466
+ elif self._check == "float":
467
+ minpattern = "0000"
468
+ maxpattern = "99999.99"
469
+ elif self._check == "angle":
470
+ minpattern = "0000"
471
+ maxpattern = "9999.99deg"
472
+ elif self._check == "int":
473
+ minpattern = "0000"
474
+ maxpattern = "-999999"
430
475
  # Let's be a bit more specific: what is the minimum size of the textcontrol fonts
431
476
  # to hold these patterns
432
477
  tfont = self.GetFont()
@@ -634,7 +679,7 @@ class TextCtrl(wx.TextCtrl):
634
679
 
635
680
  def on_char(self, event):
636
681
  proceed = True
637
- # The French awerty keyboard generates numbers by pressing Shift + some key
682
+ # The French azerty keyboard generates numbers by pressing Shift + some key
638
683
  # Under Linux this is not properly translated by GetUnicodeKey and
639
684
  # is hence leading to a 'wrong' character being recognised (the original key).
640
685
  # So we can't rely on a proper representation if the Shift-Key
@@ -723,6 +768,11 @@ class TextCtrl(wx.TextCtrl):
723
768
 
724
769
 
725
770
  class CheckBox(wx.CheckBox):
771
+ """
772
+ This checkbox replaces wx.Checkbox and creates a series of mouse over tool tips to permit Linux tooltips that
773
+ otherwise do not show.
774
+ """
775
+
726
776
  def __init__(
727
777
  self,
728
778
  *args,
@@ -796,6 +846,10 @@ class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin):
796
846
 
797
847
 
798
848
  class HoverButton(wx.Button):
849
+ """
850
+ Provide a button with Hover-Color changing ability.
851
+ """
852
+
799
853
  def __init__(self, parent, ID, label):
800
854
  super().__init__(parent, ID, label)
801
855
  self._focus_color = None
@@ -857,6 +911,10 @@ class HoverButton(wx.Button):
857
911
  # event.Skip()
858
912
 
859
913
 
914
+ ##############
915
+ # GUI KEYSTROKE FUNCTIONS
916
+ ##############
917
+
860
918
  WX_METAKEYS = [
861
919
  wx.WXK_START,
862
920
  wx.WXK_WINDOWS_LEFT,