meerk40t 0.9.2000__py2.py3-none-any.whl → 0.9.3001__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerk40t/balormk/balor_params.py +1 -43
- meerk40t/balormk/controller.py +1 -41
- meerk40t/balormk/device.py +16 -22
- meerk40t/balormk/driver.py +4 -4
- meerk40t/balormk/gui/balorconfig.py +2 -2
- meerk40t/balormk/gui/balorcontroller.py +13 -5
- meerk40t/balormk/gui/baloroperationproperties.py +0 -46
- meerk40t/balormk/gui/gui.py +17 -17
- meerk40t/camera/gui/camerapanel.py +18 -11
- meerk40t/core/cutcode/rastercut.py +3 -1
- meerk40t/core/cutplan.py +145 -14
- meerk40t/core/elements/clipboard.py +18 -9
- meerk40t/core/elements/element_treeops.py +320 -180
- meerk40t/core/elements/element_types.py +7 -2
- meerk40t/core/elements/elements.py +53 -27
- meerk40t/core/elements/geometry.py +8 -0
- meerk40t/core/elements/offset_clpr.py +129 -4
- meerk40t/core/elements/offset_mk.py +3 -1
- meerk40t/core/elements/shapes.py +28 -25
- meerk40t/core/laserjob.py +7 -0
- meerk40t/core/node/bootstrap.py +4 -0
- meerk40t/core/node/effect_hatch.py +85 -96
- meerk40t/core/node/effect_wobble.py +309 -0
- meerk40t/core/node/elem_image.py +49 -19
- meerk40t/core/node/elem_line.py +60 -0
- meerk40t/core/node/elem_rect.py +5 -3
- meerk40t/core/node/image_processed.py +766 -0
- meerk40t/core/node/image_raster.py +113 -0
- meerk40t/core/node/node.py +120 -1
- meerk40t/core/node/op_cut.py +2 -8
- meerk40t/core/node/op_dots.py +0 -8
- meerk40t/core/node/op_engrave.py +2 -18
- meerk40t/core/node/op_image.py +22 -35
- meerk40t/core/node/op_raster.py +0 -9
- meerk40t/core/planner.py +32 -2
- meerk40t/core/svg_io.py +699 -461
- meerk40t/core/treeop.py +191 -0
- meerk40t/core/undos.py +15 -1
- meerk40t/core/units.py +14 -4
- meerk40t/device/dummydevice.py +3 -2
- meerk40t/device/gui/defaultactions.py +43 -55
- meerk40t/device/gui/formatterpanel.py +58 -49
- meerk40t/device/gui/warningpanel.py +12 -12
- meerk40t/device/mixins.py +13 -0
- meerk40t/dxf/dxf_io.py +9 -5
- meerk40t/extra/ezd.py +28 -26
- meerk40t/extra/imageactions.py +300 -308
- meerk40t/extra/lbrn.py +19 -2
- meerk40t/fill/fills.py +6 -6
- meerk40t/fill/patternfill.py +1061 -1061
- meerk40t/fill/patterns.py +2 -6
- meerk40t/grbl/controller.py +168 -52
- meerk40t/grbl/device.py +23 -18
- meerk40t/grbl/driver.py +39 -0
- meerk40t/grbl/emulator.py +79 -19
- meerk40t/grbl/gcodejob.py +10 -0
- meerk40t/grbl/gui/grblconfiguration.py +2 -2
- meerk40t/grbl/gui/grblcontroller.py +24 -8
- meerk40t/grbl/gui/grblhardwareconfig.py +153 -0
- meerk40t/grbl/gui/gui.py +17 -14
- meerk40t/grbl/mock_connection.py +15 -34
- meerk40t/grbl/plugin.py +0 -4
- meerk40t/grbl/serial_connection.py +2 -1
- meerk40t/gui/about.py +8 -5
- meerk40t/gui/alignment.py +10 -6
- meerk40t/gui/basicops.py +27 -17
- meerk40t/gui/bufferview.py +2 -2
- meerk40t/gui/choicepropertypanel.py +101 -13
- meerk40t/gui/consolepanel.py +12 -9
- meerk40t/gui/devicepanel.py +38 -25
- meerk40t/gui/executejob.py +6 -4
- meerk40t/gui/help_assets/help_assets.py +13 -10
- meerk40t/gui/hersheymanager.py +8 -6
- meerk40t/gui/icons.py +1951 -3065
- meerk40t/gui/imagesplitter.py +14 -7
- meerk40t/gui/keymap.py +3 -3
- meerk40t/gui/laserpanel.py +151 -84
- meerk40t/gui/laserrender.py +61 -70
- meerk40t/gui/lasertoolpanel.py +8 -7
- meerk40t/gui/materialtest.py +3 -3
- meerk40t/gui/mkdebug.py +254 -1
- meerk40t/gui/navigationpanels.py +321 -180
- meerk40t/gui/notes.py +3 -3
- meerk40t/gui/opassignment.py +12 -12
- meerk40t/gui/operation_info.py +13 -13
- meerk40t/gui/plugin.py +5 -0
- meerk40t/gui/position.py +20 -18
- meerk40t/gui/preferences.py +21 -6
- meerk40t/gui/propertypanels/attributes.py +70 -22
- meerk40t/gui/propertypanels/blobproperty.py +2 -2
- meerk40t/gui/propertypanels/consoleproperty.py +2 -2
- meerk40t/gui/propertypanels/groupproperties.py +3 -3
- meerk40t/gui/propertypanels/hatchproperty.py +11 -18
- meerk40t/gui/propertypanels/imageproperty.py +4 -3
- meerk40t/gui/propertypanels/opbranchproperties.py +1 -1
- meerk40t/gui/propertypanels/pathproperty.py +2 -2
- meerk40t/gui/propertypanels/pointproperty.py +2 -2
- meerk40t/gui/propertypanels/propertywindow.py +4 -4
- meerk40t/gui/propertypanels/textproperty.py +3 -3
- meerk40t/gui/propertypanels/wobbleproperty.py +204 -0
- meerk40t/gui/ribbon.py +367 -259
- meerk40t/gui/scene/scene.py +31 -5
- meerk40t/gui/scenewidgets/elementswidget.py +12 -4
- meerk40t/gui/scenewidgets/gridwidget.py +2 -2
- meerk40t/gui/scenewidgets/laserpathwidget.py +7 -2
- meerk40t/gui/scenewidgets/machineoriginwidget.py +6 -2
- meerk40t/gui/scenewidgets/relocatewidget.py +1 -1
- meerk40t/gui/scenewidgets/reticlewidget.py +9 -0
- meerk40t/gui/scenewidgets/selectionwidget.py +12 -7
- meerk40t/gui/simpleui.py +95 -8
- meerk40t/gui/simulation.py +44 -36
- meerk40t/gui/spoolerpanel.py +124 -26
- meerk40t/gui/statusbarwidgets/defaultoperations.py +18 -6
- meerk40t/gui/statusbarwidgets/infowidget.py +2 -2
- meerk40t/gui/statusbarwidgets/opassignwidget.py +12 -12
- meerk40t/gui/statusbarwidgets/shapepropwidget.py +45 -18
- meerk40t/gui/statusbarwidgets/statusbar.py +11 -4
- meerk40t/gui/themes.py +78 -0
- meerk40t/gui/toolwidgets/toolcircle.py +2 -1
- meerk40t/gui/toolwidgets/toolellipse.py +2 -1
- meerk40t/gui/toolwidgets/toolimagecut.py +132 -0
- meerk40t/gui/toolwidgets/toolline.py +144 -0
- meerk40t/gui/toolwidgets/toolnodeedit.py +72 -145
- meerk40t/gui/toolwidgets/toolpoint.py +1 -1
- meerk40t/gui/toolwidgets/toolpolygon.py +8 -55
- meerk40t/gui/toolwidgets/toolrect.py +2 -1
- meerk40t/gui/usbconnect.py +2 -2
- meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +2 -2
- meerk40t/gui/utilitywidgets/harmonograph.py +7 -7
- meerk40t/gui/utilitywidgets/scalewidget.py +1 -1
- meerk40t/gui/wordlisteditor.py +33 -18
- meerk40t/gui/wxmeerk40t.py +166 -66
- meerk40t/gui/wxmmain.py +236 -157
- meerk40t/gui/wxmribbon.py +49 -25
- meerk40t/gui/wxmscene.py +49 -38
- meerk40t/gui/wxmtree.py +216 -85
- meerk40t/gui/wxutils.py +62 -4
- meerk40t/image/imagetools.py +443 -15
- meerk40t/internal_plugins.py +2 -10
- meerk40t/kernel/kernel.py +12 -4
- meerk40t/lihuiyu/controller.py +7 -7
- meerk40t/lihuiyu/device.py +3 -1
- meerk40t/lihuiyu/driver.py +3 -0
- meerk40t/lihuiyu/gui/gui.py +8 -8
- meerk40t/lihuiyu/gui/lhyaccelgui.py +2 -2
- meerk40t/lihuiyu/gui/lhycontrollergui.py +73 -27
- meerk40t/lihuiyu/gui/lhydrivergui.py +2 -2
- meerk40t/lihuiyu/gui/tcpcontroller.py +22 -9
- meerk40t/main.py +6 -1
- meerk40t/moshi/controller.py +5 -5
- meerk40t/moshi/device.py +5 -2
- meerk40t/moshi/driver.py +4 -0
- meerk40t/moshi/gui/gui.py +8 -8
- meerk40t/moshi/gui/moshicontrollergui.py +24 -8
- meerk40t/moshi/gui/moshidrivergui.py +2 -2
- meerk40t/newly/controller.py +2 -0
- meerk40t/newly/device.py +9 -2
- meerk40t/newly/driver.py +4 -0
- meerk40t/newly/gui/gui.py +16 -17
- meerk40t/newly/gui/newlyconfig.py +2 -2
- meerk40t/newly/gui/newlycontroller.py +13 -5
- meerk40t/rotary/gui/gui.py +2 -2
- meerk40t/rotary/gui/rotarysettings.py +2 -2
- meerk40t/ruida/device.py +3 -0
- meerk40t/ruida/driver.py +4 -0
- meerk40t/ruida/gui/gui.py +6 -6
- meerk40t/ruida/gui/ruidaconfig.py +2 -2
- meerk40t/ruida/gui/ruidacontroller.py +13 -5
- meerk40t/svgelements.py +9 -9
- meerk40t/tools/geomstr.py +849 -153
- meerk40t/tools/kerftest.py +8 -4
- meerk40t/tools/livinghinges.py +15 -8
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/METADATA +21 -16
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/RECORD +185 -177
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/entry_points.txt +0 -1
- test/test_core_elements.py +8 -24
- test/test_file_svg.py +88 -0
- test/test_fill.py +9 -9
- test/test_geomstr.py +258 -8
- test/test_kernel.py +4 -0
- test/test_tools_rasterplotter.py +29 -0
- meerk40t/extra/embroider.py +0 -56
- meerk40t/extra/pathoptimize.py +0 -249
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/WHEEL +0 -0
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.2000.dist-info → meerk40t-0.9.3001.dist-info}/zip-safe +0 -0
meerk40t/gui/spoolerpanel.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import threading
|
1
2
|
import time
|
2
3
|
from math import isinf, isnan
|
3
4
|
from pathlib import Path
|
@@ -8,13 +9,14 @@ from wx import aui
|
|
8
9
|
|
9
10
|
from meerk40t.gui.icons import (
|
10
11
|
STD_ICON_SIZE,
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
get_default_icon_size,
|
13
|
+
icons8_emergency_stop_button,
|
14
|
+
icons8_pause,
|
15
|
+
icons8_route,
|
14
16
|
)
|
15
17
|
from meerk40t.gui.mwindow import MWindow
|
16
18
|
from meerk40t.gui.wxutils import HoverButton
|
17
|
-
from meerk40t.kernel import get_safe_path, signal_listener
|
19
|
+
from meerk40t.kernel import Job, get_safe_path, signal_listener
|
18
20
|
|
19
21
|
_ = wx.GetTranslation
|
20
22
|
|
@@ -105,20 +107,24 @@ class SpoolerPanel(wx.Panel):
|
|
105
107
|
self.combo_device.SetSelection(0) # All by default...
|
106
108
|
self.button_pause = wx.Button(self.win_top, wx.ID_ANY, _("Pause"))
|
107
109
|
self.button_pause.SetToolTip(_("Pause/Resume the laser"))
|
108
|
-
self.button_pause.SetBitmap(
|
110
|
+
self.button_pause.SetBitmap(
|
111
|
+
icons8_pause.GetBitmap(resize=0.5 * get_default_icon_size())
|
112
|
+
)
|
109
113
|
self.button_stop = HoverButton(self.win_top, wx.ID_ANY, _("Abort"))
|
110
114
|
self.button_stop.SetToolTip(_("Stop the laser"))
|
111
115
|
self.button_stop.SetBitmap(
|
112
|
-
|
113
|
-
resize=
|
116
|
+
icons8_emergency_stop_button.GetBitmap(
|
117
|
+
resize=0.5 * get_default_icon_size(),
|
118
|
+
color=self.context.themes.get("stop_fg"),
|
119
|
+
keepalpha=True,
|
114
120
|
)
|
115
121
|
)
|
116
122
|
self.button_stop.SetBitmapFocus(
|
117
|
-
|
123
|
+
icons8_emergency_stop_button.GetBitmap(resize=0.5 * get_default_icon_size())
|
118
124
|
)
|
119
|
-
self.button_stop.SetBackgroundColour(
|
120
|
-
self.button_stop.SetForegroundColour(
|
121
|
-
self.button_stop.SetFocusColour(
|
125
|
+
self.button_stop.SetBackgroundColour(self.context.themes.get("stop_bg"))
|
126
|
+
self.button_stop.SetForegroundColour(self.context.themes.get("stop_fg"))
|
127
|
+
self.button_stop.SetFocusColour(self.context.themes.get("stop_fg_focus"))
|
122
128
|
|
123
129
|
self.list_job_spool = wx.ListCtrl(
|
124
130
|
self.win_top,
|
@@ -180,11 +186,24 @@ class SpoolerPanel(wx.Panel):
|
|
180
186
|
self.set_pause_color()
|
181
187
|
if self.context.spool_history_clear_on_start:
|
182
188
|
self.clear_history()
|
189
|
+
# We set a timer job that will periodically check the spooler queue
|
190
|
+
# in case no signal was received
|
191
|
+
self.shown = False
|
192
|
+
self.update_lock = threading.Lock()
|
193
|
+
self.timerjob = Job(
|
194
|
+
process=self.update_queue,
|
195
|
+
job_name="spooler-update",
|
196
|
+
interval=5,
|
197
|
+
run_main=True,
|
198
|
+
)
|
183
199
|
|
184
200
|
def __set_properties(self):
|
185
201
|
# begin wxGlade: SpoolerPanel.__set_properties
|
186
202
|
self.combo_device.SetToolTip(_("Select the device"))
|
187
203
|
self.list_job_spool.SetToolTip(_("List and modify the queued operations"))
|
204
|
+
self.button_clear_history.SetToolTip(
|
205
|
+
_("Clear spooler history (right click for more options)")
|
206
|
+
)
|
188
207
|
self.list_job_spool.AppendColumn(_("#"), format=wx.LIST_FORMAT_LEFT, width=58)
|
189
208
|
self.list_job_spool.AppendColumn(
|
190
209
|
_("Device"),
|
@@ -492,6 +511,13 @@ class SpoolerPanel(wx.Panel):
|
|
492
511
|
return
|
493
512
|
|
494
513
|
menu = wx.Menu()
|
514
|
+
item = menu.Append(
|
515
|
+
wx.ID_ANY,
|
516
|
+
f"{str(element)[:30]} [{spooler.context.label}]",
|
517
|
+
"",
|
518
|
+
wx.ITEM_NORMAL,
|
519
|
+
)
|
520
|
+
item.Enable(False)
|
495
521
|
can_enable = False
|
496
522
|
action = _("Remove")
|
497
523
|
if element.status == "Running":
|
@@ -507,21 +533,46 @@ class SpoolerPanel(wx.Panel):
|
|
507
533
|
|
508
534
|
item = menu.Append(
|
509
535
|
wx.ID_ANY,
|
510
|
-
f"{action}
|
536
|
+
f"{action}",
|
511
537
|
"",
|
512
538
|
wx.ITEM_NORMAL,
|
513
539
|
)
|
514
540
|
info_tuple = [spooler, element, remove_mode]
|
515
541
|
self.Bind(wx.EVT_MENU, self.on_menu_popup_delete(info_tuple), item)
|
542
|
+
# Are there more loops than just one?
|
543
|
+
if hasattr(element, "loops"):
|
544
|
+
# Still something to go?
|
545
|
+
if element.loops > 1 and element.loops_executed < element.loops:
|
546
|
+
item = menu.Append(
|
547
|
+
wx.ID_ANY,
|
548
|
+
_("Finish after this loop"),
|
549
|
+
_(
|
550
|
+
"Stop the current execution after the succesful execution of this loop"
|
551
|
+
),
|
552
|
+
wx.ITEM_NORMAL,
|
553
|
+
)
|
554
|
+
info_tuple = [spooler, element]
|
555
|
+
self.Bind(wx.EVT_MENU, self.on_menu_popup_stop_loop(info_tuple), item)
|
556
|
+
if not isinf(element.loops):
|
557
|
+
item = menu.Append(
|
558
|
+
wx.ID_ANY,
|
559
|
+
_("add another loop"),
|
560
|
+
_("add another loop to this job"),
|
561
|
+
wx.ITEM_NORMAL,
|
562
|
+
)
|
563
|
+
info_tuple = [spooler, element]
|
564
|
+
self.Bind(wx.EVT_MENU, self.on_menu_popup_add_loop(info_tuple), item)
|
565
|
+
|
516
566
|
if can_enable:
|
517
567
|
item = menu.Append(
|
518
568
|
wx.ID_ANY,
|
519
|
-
f"{action2}
|
569
|
+
f"{action2}",
|
520
570
|
"",
|
521
571
|
wx.ITEM_NORMAL,
|
522
572
|
)
|
523
573
|
info_tuple = [spooler, element]
|
524
574
|
self.Bind(wx.EVT_MENU, self.on_menu_popup_toggle_enable(info_tuple), item)
|
575
|
+
menu.AppendSeparator()
|
525
576
|
item = menu.Append(wx.ID_ANY, _("Clear All"), "", wx.ITEM_NORMAL)
|
526
577
|
self.Bind(wx.EVT_MENU, self.on_menu_popup_clear(element), item)
|
527
578
|
|
@@ -564,19 +615,52 @@ class SpoolerPanel(wx.Panel):
|
|
564
615
|
return delete
|
565
616
|
|
566
617
|
def on_menu_popup_toggle_enable(self, element):
|
567
|
-
def
|
618
|
+
def routine(event=None):
|
568
619
|
spooler = element[0]
|
569
620
|
job = element[1]
|
570
621
|
job.enabled = not job.enabled
|
571
622
|
self.refresh_spooler_list()
|
572
623
|
|
573
|
-
return
|
624
|
+
return routine
|
625
|
+
|
626
|
+
# def on_menu_popup_next_placement(self, element):
|
627
|
+
# def routine(event=None):
|
628
|
+
# spooler = element[0]
|
629
|
+
# job = element[1]
|
630
|
+
# if hasattr(job, "jump_to_next"):
|
631
|
+
# job.jump_to_next()
|
632
|
+
# self.refresh_spooler_list()
|
633
|
+
|
634
|
+
# return routine
|
635
|
+
|
636
|
+
def on_menu_popup_stop_loop(self, element):
|
637
|
+
def routine(event=None):
|
638
|
+
spooler = element[0]
|
639
|
+
job = element[1]
|
640
|
+
if hasattr(job, "stop_after_loop"):
|
641
|
+
job.stop_after_loop()
|
642
|
+
self.refresh_spooler_list()
|
643
|
+
|
644
|
+
return routine
|
645
|
+
|
646
|
+
def on_menu_popup_add_loop(self, element):
|
647
|
+
def routine(event=None):
|
648
|
+
spooler = element[0]
|
649
|
+
job = element[1]
|
650
|
+
if hasattr(job, "add_another_loop"):
|
651
|
+
job.add_another_loop()
|
652
|
+
self.refresh_spooler_list()
|
653
|
+
|
654
|
+
return routine
|
574
655
|
|
575
656
|
def pane_show(self, *args):
|
657
|
+
self.shown = True
|
658
|
+
self.context.schedule(self.timerjob)
|
576
659
|
self.refresh_spooler_list()
|
577
660
|
|
578
661
|
def pane_hide(self, *args):
|
579
|
-
|
662
|
+
self.context.unschedule(self.timerjob)
|
663
|
+
self.shown = False
|
580
664
|
|
581
665
|
@staticmethod
|
582
666
|
def _name_str(named_obj):
|
@@ -908,15 +992,18 @@ class SpoolerPanel(wx.Panel):
|
|
908
992
|
self.list_job_history.SetItem(list_id, col_id, new_data)
|
909
993
|
|
910
994
|
def set_pause_color(self):
|
911
|
-
|
995
|
+
new_bg_color = None
|
996
|
+
new_fg_color = None
|
912
997
|
new_caption = _("Pause")
|
913
998
|
try:
|
914
999
|
if self.context.device.driver.paused:
|
915
|
-
|
1000
|
+
new_bg_color = self.context.themes.get("pause_bg")
|
1001
|
+
new_fg_color = self.context.themes.get("pause_fg")
|
916
1002
|
new_caption = _("Resume")
|
917
1003
|
except AttributeError:
|
918
1004
|
pass
|
919
|
-
self.button_pause.SetBackgroundColour(
|
1005
|
+
self.button_pause.SetBackgroundColour(new_bg_color)
|
1006
|
+
self.button_pause.SetForegroundColour(new_fg_color)
|
920
1007
|
self.button_pause.SetLabelText(new_caption)
|
921
1008
|
|
922
1009
|
@signal_listener("pause")
|
@@ -958,11 +1045,19 @@ class SpoolerPanel(wx.Panel):
|
|
958
1045
|
|
959
1046
|
@signal_listener("driver;position")
|
960
1047
|
@signal_listener("emulator;position")
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
1048
|
+
@signal_listener("pipe;usb_status")
|
1049
|
+
def on_device_update(self, origin, *args):
|
1050
|
+
doit = True
|
1051
|
+
with self.update_lock:
|
1052
|
+
# Only update every 2 seconds or so
|
1053
|
+
dtime = time.time()
|
1054
|
+
if dtime - self._last_invokation < 2:
|
1055
|
+
doit = False
|
1056
|
+
else:
|
1057
|
+
self._last_invokation = dtime
|
1058
|
+
if not doit:
|
965
1059
|
return
|
1060
|
+
|
966
1061
|
# Two things (at least) could go wrong:
|
967
1062
|
# 1) You are in the wrong queue, ie there's a job running in the background a
|
968
1063
|
# that provides an update but the user has changed the device so a different
|
@@ -975,7 +1070,6 @@ class SpoolerPanel(wx.Panel):
|
|
975
1070
|
listctrl = self.list_job_spool
|
976
1071
|
except RuntimeError:
|
977
1072
|
return
|
978
|
-
self._last_invokation = dtime
|
979
1073
|
for list_id, entry in enumerate(self.queue_entries):
|
980
1074
|
spooler = entry[0]
|
981
1075
|
qindex = entry[1]
|
@@ -1040,6 +1134,10 @@ class SpoolerPanel(wx.Panel):
|
|
1040
1134
|
self.refresh_spooler_list()
|
1041
1135
|
self.refresh_history()
|
1042
1136
|
|
1137
|
+
def update_queue(self):
|
1138
|
+
if self.shown:
|
1139
|
+
self.on_device_update(None)
|
1140
|
+
|
1043
1141
|
|
1044
1142
|
class JobSpooler(MWindow):
|
1045
1143
|
def __init__(self, *args, **kwds):
|
@@ -1052,7 +1150,7 @@ class JobSpooler(MWindow):
|
|
1052
1150
|
)
|
1053
1151
|
self.add_module_delegate(self.panel)
|
1054
1152
|
_icon = wx.NullIcon
|
1055
|
-
_icon.CopyFromBitmap(
|
1153
|
+
_icon.CopyFromBitmap(icons8_route.GetBitmap())
|
1056
1154
|
self.SetIcon(_icon)
|
1057
1155
|
self.SetTitle(_("Job Spooler"))
|
1058
1156
|
self.Layout()
|
@@ -1064,7 +1162,7 @@ class JobSpooler(MWindow):
|
|
1064
1162
|
"button/control/Spooler",
|
1065
1163
|
{
|
1066
1164
|
"label": _("Spooler"),
|
1067
|
-
"icon":
|
1165
|
+
"icon": icons8_route,
|
1068
1166
|
"tip": _("Opens Spooler Window"),
|
1069
1167
|
"action": lambda v: kernel.console("window toggle JobSpooler\n"),
|
1070
1168
|
"priority": -1,
|
@@ -133,13 +133,13 @@ class DefaultOperationWidget(StatusBarWidget):
|
|
133
133
|
fontsize = 8
|
134
134
|
elif len(opid) > 4:
|
135
135
|
fontsize = 6
|
136
|
-
|
136
|
+
# use_theme=False is needed as othewise colors will get reversed
|
137
137
|
icon = EmptyIcon(
|
138
138
|
size=(self.iconsize, min(self.iconsize, self.height)),
|
139
139
|
color=wx.Colour(swizzlecolor(op.color)),
|
140
140
|
msg=opid,
|
141
141
|
ptsize=fontsize,
|
142
|
-
).GetBitmap(noadjustment=True)
|
142
|
+
).GetBitmap(noadjustment=True, use_theme=False)
|
143
143
|
btn.SetBitmap(icon)
|
144
144
|
op_label = op.label
|
145
145
|
if op_label is None:
|
@@ -175,11 +175,13 @@ class DefaultOperationWidget(StatusBarWidget):
|
|
175
175
|
|
176
176
|
def on_button_left(self, event):
|
177
177
|
button = event.GetEventObject()
|
178
|
+
shift_pressed = event.ShiftDown()
|
179
|
+
# print (f"Shift: {event.ShiftDown()}, ctrl={event.ControlDown()}, alt={event.AltDown()}, bitmask={event.GetModifiers()}")
|
178
180
|
idx = 0
|
179
181
|
while idx < len(self.assign_buttons):
|
180
182
|
if button is self.assign_buttons[idx]:
|
181
183
|
node = self.assign_operations[idx]
|
182
|
-
self.execute_on(node)
|
184
|
+
self.execute_on(node, shift_pressed)
|
183
185
|
break
|
184
186
|
idx += 1
|
185
187
|
|
@@ -289,9 +291,19 @@ class DefaultOperationWidget(StatusBarWidget):
|
|
289
291
|
self.first_to_show = 0
|
290
292
|
self.Show(True)
|
291
293
|
|
292
|
-
def execute_on(self, targetop):
|
293
|
-
|
294
|
-
self.context.elements.
|
294
|
+
def execute_on(self, targetop, use_parent):
|
295
|
+
targetdata = []
|
296
|
+
data = list(self.context.elements.elems(emphasized=True))
|
297
|
+
for node in data:
|
298
|
+
add_node = node
|
299
|
+
if use_parent:
|
300
|
+
if node.parent is not None and node.parent.type.startswith("effect"):
|
301
|
+
add_node = node.parent
|
302
|
+
if add_node not in targetdata:
|
303
|
+
targetdata.append(add_node)
|
304
|
+
|
305
|
+
self.context.elements.assign_default_operation(targetdata, targetop)
|
306
|
+
self.context.elements.set_emphasis(data)
|
295
307
|
|
296
308
|
self.reset_tooltips()
|
297
309
|
|
@@ -8,7 +8,7 @@ from meerk40t.core.elements.element_types import elem_nodes
|
|
8
8
|
from meerk40t.core.laserjob import LaserJob
|
9
9
|
from meerk40t.core.node.node import Node
|
10
10
|
from meerk40t.core.units import UNITS_PER_INCH, Length
|
11
|
-
from meerk40t.gui.icons import
|
11
|
+
from meerk40t.gui.icons import icons8_up
|
12
12
|
from meerk40t.gui.statusbarwidgets.statusbarwidget import StatusBarWidget
|
13
13
|
from meerk40t.svgelements import Color
|
14
14
|
|
@@ -47,7 +47,7 @@ class SimpleInfoWidget(StatusBarWidget):
|
|
47
47
|
self.btn_next = wx.StaticBitmap(
|
48
48
|
self.parent,
|
49
49
|
id=wx.ID_ANY,
|
50
|
-
bitmap=
|
50
|
+
bitmap=icons8_up.GetBitmap(resize=20),
|
51
51
|
size=wx.Size(20, 20),
|
52
52
|
style=wx.BORDER_RAISED,
|
53
53
|
)
|
@@ -2,12 +2,12 @@ import wx
|
|
2
2
|
|
3
3
|
from meerk40t.core.elements.element_types import op_nodes
|
4
4
|
from meerk40t.gui.icons import (
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
icon_effect_hatch,
|
6
|
+
icon_points,
|
7
|
+
icons8_direction,
|
8
|
+
icons8_image,
|
9
|
+
icons8_laser_beam,
|
10
|
+
icons8_laserbeam_weak,
|
11
11
|
)
|
12
12
|
from meerk40t.gui.laserrender import swizzlecolor
|
13
13
|
from meerk40t.svgelements import Color
|
@@ -230,7 +230,7 @@ class OperationAssignWidget(StatusBarWidget):
|
|
230
230
|
d = None
|
231
231
|
if node.type == "op raster":
|
232
232
|
c, d = get_color()
|
233
|
-
result =
|
233
|
+
result = icons8_direction.GetBitmap(
|
234
234
|
color=c,
|
235
235
|
resize=(iconsize, iconsize),
|
236
236
|
noadjustment=True,
|
@@ -238,7 +238,7 @@ class OperationAssignWidget(StatusBarWidget):
|
|
238
238
|
)
|
239
239
|
elif node.type == "op image":
|
240
240
|
c, d = get_color()
|
241
|
-
result =
|
241
|
+
result = icons8_image.GetBitmap(
|
242
242
|
color=c,
|
243
243
|
resize=(iconsize, iconsize),
|
244
244
|
noadjustment=True,
|
@@ -246,7 +246,7 @@ class OperationAssignWidget(StatusBarWidget):
|
|
246
246
|
)
|
247
247
|
elif node.type == "op engrave":
|
248
248
|
c, d = get_color()
|
249
|
-
result =
|
249
|
+
result = icons8_laserbeam_weak.GetBitmap(
|
250
250
|
color=c,
|
251
251
|
resize=(iconsize, iconsize),
|
252
252
|
noadjustment=True,
|
@@ -254,7 +254,7 @@ class OperationAssignWidget(StatusBarWidget):
|
|
254
254
|
)
|
255
255
|
elif node.type == "op cut":
|
256
256
|
c, d = get_color()
|
257
|
-
result =
|
257
|
+
result = icons8_laser_beam.GetBitmap(
|
258
258
|
color=c,
|
259
259
|
resize=(iconsize, iconsize),
|
260
260
|
noadjustment=True,
|
@@ -262,7 +262,7 @@ class OperationAssignWidget(StatusBarWidget):
|
|
262
262
|
)
|
263
263
|
elif node.type == "op dots":
|
264
264
|
c, d = get_color()
|
265
|
-
result =
|
265
|
+
result = icon_points.GetBitmap(
|
266
266
|
color=c,
|
267
267
|
resize=(iconsize, iconsize),
|
268
268
|
noadjustment=True,
|
@@ -284,7 +284,7 @@ class OperationAssignWidget(StatusBarWidget):
|
|
284
284
|
self.assign_buttons[myidx].SetBitmap(wx.NullBitmap)
|
285
285
|
else:
|
286
286
|
self.assign_buttons[myidx].SetBitmap(image)
|
287
|
-
# self.assign_buttons[myidx].SetBitmapDisabled(
|
287
|
+
# self.assign_buttons[myidx].SetBitmapDisabled(icons8_unlock.GetBitmap(color=Color("Grey"), resize=(self.iconsize, self.iconsize), noadjustment=True, keepalpha=True))
|
288
288
|
self.assign_buttons[myidx].SetToolTip(
|
289
289
|
str(node)
|
290
290
|
+ "\n"
|
@@ -1,14 +1,14 @@
|
|
1
1
|
import wx
|
2
2
|
|
3
3
|
from meerk40t.gui.icons import (
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
icon_cap_butt,
|
5
|
+
icon_cap_round,
|
6
|
+
icon_cap_square,
|
7
|
+
icon_fill_evenodd,
|
8
|
+
icon_fill_nonzero,
|
9
|
+
icon_join_bevel,
|
10
|
+
icon_join_miter,
|
11
|
+
icon_join_round,
|
12
12
|
)
|
13
13
|
|
14
14
|
from .statusbarwidget import StatusBarWidget
|
@@ -38,7 +38,12 @@ class LinecapWidget(StatusBarWidget):
|
|
38
38
|
self.btn_cap_butt = wx.StaticBitmap(
|
39
39
|
self.parent, id=wx.ID_ANY, size=wx.Size(30, -1), style=wx.BORDER_RAISED
|
40
40
|
)
|
41
|
-
|
41
|
+
|
42
|
+
self.btn_cap_butt.SetBitmap(
|
43
|
+
icon_cap_butt.GetBitmap(
|
44
|
+
resize=max(20, self.parent.available_height - 4), buffer=1
|
45
|
+
)
|
46
|
+
)
|
42
47
|
self.btn_cap_butt.SetMaxSize(wx.Size(50, -1))
|
43
48
|
self.btn_cap_butt.SetToolTip(_("Set the end of the lines to a butt-shape"))
|
44
49
|
self.btn_cap_butt.Bind(wx.EVT_LEFT_DOWN, self.on_cap_butt)
|
@@ -46,7 +51,11 @@ class LinecapWidget(StatusBarWidget):
|
|
46
51
|
self.btn_cap_round = wx.StaticBitmap(
|
47
52
|
self.parent, id=wx.ID_ANY, size=wx.Size(30, -1), style=wx.BORDER_RAISED
|
48
53
|
)
|
49
|
-
self.btn_cap_round.SetBitmap(
|
54
|
+
self.btn_cap_round.SetBitmap(
|
55
|
+
icon_cap_round.GetBitmap(
|
56
|
+
resize=max(20, self.parent.available_height - 4), buffer=1
|
57
|
+
)
|
58
|
+
)
|
50
59
|
self.btn_cap_round.SetMaxSize(wx.Size(50, -1))
|
51
60
|
self.btn_cap_round.SetToolTip(_("Set the end of the lines to a round-shape"))
|
52
61
|
self.btn_cap_round.Bind(wx.EVT_LEFT_DOWN, self.on_cap_round)
|
@@ -54,7 +63,12 @@ class LinecapWidget(StatusBarWidget):
|
|
54
63
|
self.btn_cap_square = wx.StaticBitmap(
|
55
64
|
self.parent, id=wx.ID_ANY, size=wx.Size(30, -1), style=wx.BORDER_RAISED
|
56
65
|
)
|
57
|
-
|
66
|
+
|
67
|
+
self.btn_cap_square.SetBitmap(
|
68
|
+
icon_cap_square.GetBitmap(
|
69
|
+
resize=max(20, self.parent.available_height - 4), buffer=1
|
70
|
+
)
|
71
|
+
)
|
58
72
|
self.btn_cap_square.SetMaxSize(wx.Size(50, -1))
|
59
73
|
self.btn_cap_square.SetToolTip(_("Set the end of the lines to a square-shape"))
|
60
74
|
self.btn_cap_square.Bind(wx.EVT_LEFT_DOWN, self.on_cap_square)
|
@@ -101,7 +115,12 @@ class LinejoinWidget(StatusBarWidget):
|
|
101
115
|
self.btn_join_bevel = wx.StaticBitmap(
|
102
116
|
self.parent, id=wx.ID_ANY, size=wx.Size(25, -1), style=wx.BORDER_RAISED
|
103
117
|
)
|
104
|
-
|
118
|
+
|
119
|
+
self.btn_join_bevel.SetBitmap(
|
120
|
+
icon_join_bevel.GetBitmap(
|
121
|
+
resize=max(20, self.parent.available_height - 4), buffer=1
|
122
|
+
)
|
123
|
+
)
|
105
124
|
self.btn_join_bevel.SetMaxSize(wx.Size(50, -1))
|
106
125
|
self.btn_join_bevel.SetToolTip(_("Set the join of the lines to a bevel-shape"))
|
107
126
|
self.btn_join_bevel.Bind(wx.EVT_LEFT_DOWN, self.on_join_bevel)
|
@@ -109,7 +128,11 @@ class LinejoinWidget(StatusBarWidget):
|
|
109
128
|
self.btn_join_round = wx.StaticBitmap(
|
110
129
|
self.parent, id=wx.ID_ANY, size=wx.Size(25, -1), style=wx.BORDER_RAISED
|
111
130
|
)
|
112
|
-
self.btn_join_round.SetBitmap(
|
131
|
+
self.btn_join_round.SetBitmap(
|
132
|
+
icon_join_round.GetBitmap(
|
133
|
+
resize=max(20, self.parent.available_height - 4), buffer=1
|
134
|
+
)
|
135
|
+
)
|
113
136
|
self.btn_join_round.SetMaxSize(wx.Size(50, -1))
|
114
137
|
self.btn_join_round.SetToolTip(_("Set the join of lines to a round-shape"))
|
115
138
|
self.btn_join_round.Bind(wx.EVT_LEFT_DOWN, self.on_join_round)
|
@@ -117,18 +140,22 @@ class LinejoinWidget(StatusBarWidget):
|
|
117
140
|
self.btn_join_miter = wx.StaticBitmap(
|
118
141
|
self.parent, id=wx.ID_ANY, size=wx.Size(25, -1), style=wx.BORDER_RAISED
|
119
142
|
)
|
120
|
-
self.btn_join_miter.SetBitmap(
|
143
|
+
self.btn_join_miter.SetBitmap(
|
144
|
+
icon_join_miter.GetBitmap(
|
145
|
+
resize=max(20, self.parent.available_height - 4), buffer=1
|
146
|
+
)
|
147
|
+
)
|
121
148
|
self.btn_join_miter.SetMaxSize(wx.Size(50, -1))
|
122
149
|
self.btn_join_miter.SetToolTip(_("Set the join of lines to a miter-shape"))
|
123
150
|
self.btn_join_miter.Bind(wx.EVT_LEFT_DOWN, self.on_join_miter)
|
124
151
|
|
125
152
|
# self.btn_join_arcs = wx.StaticBitmap(self.parent, id=wx.ID_ANY, size=wx.Size(25, -1), style=wx.BORDER_RAISED)
|
126
|
-
# self.btn_join_arcs.SetBitmap(
|
153
|
+
# self.btn_join_arcs.SetBitmap(icon_join_round.GetBitmap(noadjustment=True))
|
127
154
|
# self.btn_join_arcs.SetToolTip(_("Set the join of lines to an arc-shape"))
|
128
155
|
# self.btn_join_arcs.Bind(wx.EVT_LEFT_DOWN, self.on_join_arcs)
|
129
156
|
|
130
157
|
# self.btn_join_miterclip = wx.StaticBitmap(self.parent, id=wx.ID_ANY, size=wx.Size(25, -1), style=wx.BORDER_RAISED)
|
131
|
-
# self.btn_join_miterclip.SetBitmap(
|
158
|
+
# self.btn_join_miterclip.SetBitmap(icon_join_miter.GetBitmap(noadjustment=True))
|
132
159
|
# self.btn_join_miterclip.SetToolTip(_("Set the join of lines to a miter-clip-shape"))
|
133
160
|
# self.btn_join_miterclip.Bind(wx.EVT_LEFT_DOWN, self.on_join_miterclip)
|
134
161
|
|
@@ -182,14 +209,14 @@ class FillruleWidget(StatusBarWidget):
|
|
182
209
|
self.parent, id=wx.ID_ANY, size=wx.Size(30, -1), style=wx.BORDER_RAISED
|
183
210
|
)
|
184
211
|
self.btn_fill_nonzero.SetMaxSize(wx.Size(50, -1))
|
185
|
-
self.btn_fill_nonzero.SetBitmap(
|
212
|
+
self.btn_fill_nonzero.SetBitmap(icon_fill_nonzero.GetBitmap(noadjustment=True))
|
186
213
|
self.btn_fill_nonzero.SetToolTip(_("Set the fillstyle to non-zero (regular)"))
|
187
214
|
self.btn_fill_nonzero.Bind(wx.EVT_LEFT_DOWN, self.on_fill_nonzero)
|
188
215
|
|
189
216
|
self.btn_fill_evenodd = wx.StaticBitmap(
|
190
217
|
self.parent, id=wx.ID_ANY, size=wx.Size(30, -1), style=wx.BORDER_RAISED
|
191
218
|
)
|
192
|
-
self.btn_fill_evenodd.SetBitmap(
|
219
|
+
self.btn_fill_evenodd.SetBitmap(icon_fill_evenodd.GetBitmap(noadjustment=True))
|
193
220
|
self.btn_fill_evenodd.SetMaxSize(wx.Size(50, -1))
|
194
221
|
self.btn_fill_evenodd.SetToolTip(
|
195
222
|
_("Set the fillstyle to even-odd (alternating areas)")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import wx
|
2
2
|
|
3
|
-
from meerk40t.gui.icons import
|
3
|
+
from meerk40t.gui.icons import icons8_circled_right
|
4
4
|
|
5
5
|
|
6
6
|
class CustomStatusBar(wx.StatusBar):
|
@@ -32,12 +32,14 @@ class CustomStatusBar(wx.StatusBar):
|
|
32
32
|
btn = wx.StaticBitmap(
|
33
33
|
self,
|
34
34
|
id=wx.ID_ANY,
|
35
|
-
bitmap=
|
36
|
-
|
35
|
+
bitmap=icons8_circled_right.GetBitmap(
|
36
|
+
resize=max(20, self.available_height - 4), buffer=1
|
37
|
+
),
|
38
|
+
size=wx.Size(self.available_height - 2, self.available_height - 2),
|
37
39
|
# style=wx.BORDER_RAISED,
|
38
40
|
)
|
39
41
|
# btn.SetBackgroundColour(wx.RED)
|
40
|
-
# btn.SetBitmap(
|
42
|
+
# btn.SetBitmap(icons8_circled_right.GetBitmap(noadjustment=True, color=Color("red")))
|
41
43
|
btn.Show(False)
|
42
44
|
btn.Bind(wx.EVT_LEFT_DOWN, self.on_button_next)
|
43
45
|
btn.Bind(wx.EVT_RIGHT_DOWN, self.on_button_prev)
|
@@ -49,6 +51,11 @@ class CustomStatusBar(wx.StatusBar):
|
|
49
51
|
self.Reposition()
|
50
52
|
self.startup = False
|
51
53
|
|
54
|
+
@property
|
55
|
+
def available_height(self):
|
56
|
+
sb_size = self.GetSize()
|
57
|
+
return sb_size[1]
|
58
|
+
|
52
59
|
def Clear(self):
|
53
60
|
"""
|
54
61
|
Resets all panels
|
meerk40t/gui/themes.py
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
"""
|
2
|
+
Basic Module to provide infmoration about the GUI
|
3
|
+
"""
|
4
|
+
import wx
|
5
|
+
|
6
|
+
from meerk40t.kernel import Service
|
7
|
+
|
8
|
+
|
9
|
+
class Themes(Service):
|
10
|
+
def __init__(self, kernel, index=None, *args, **kwargs):
|
11
|
+
Service.__init__(self, kernel, "themes" if index is None else f"themes{index}")
|
12
|
+
self.registered_themes = {
|
13
|
+
"system": self.load_system_default,
|
14
|
+
}
|
15
|
+
self._theme = None
|
16
|
+
self._dark = False
|
17
|
+
self._theme_properties = dict()
|
18
|
+
self.theme = "system"
|
19
|
+
|
20
|
+
@property
|
21
|
+
def dark(self):
|
22
|
+
return self._dark
|
23
|
+
|
24
|
+
@property
|
25
|
+
def theme(self):
|
26
|
+
return self._theme
|
27
|
+
|
28
|
+
@theme.setter
|
29
|
+
def theme(self, new_theme):
|
30
|
+
if new_theme in self.registered_themes:
|
31
|
+
self._theme = new_theme
|
32
|
+
self.registered_themes[new_theme]()
|
33
|
+
|
34
|
+
def get(self, property_value):
|
35
|
+
if property_value in self._theme_properties:
|
36
|
+
return self._theme_properties[property_value]
|
37
|
+
# property not found
|
38
|
+
return None
|
39
|
+
|
40
|
+
def load_system_default(self):
|
41
|
+
self._theme = "system"
|
42
|
+
self._dark = wx.SystemSettings().GetColour(wx.SYS_COLOUR_WINDOW)[0] < 127
|
43
|
+
from platform import system
|
44
|
+
|
45
|
+
buggy_darwin = bool(system() == "Darwin" and not self._dark)
|
46
|
+
|
47
|
+
self._theme_properties = dict()
|
48
|
+
tp = self._theme_properties
|
49
|
+
# Just a scaffold, will be extended later
|
50
|
+
# tp["button"] = wx.Button
|
51
|
+
tp["pause_bg"] = wx.Colour(200, 200, 0)
|
52
|
+
# wx.Colour("ORANGE") if self._dark else wx.Colour("YELLOW")
|
53
|
+
tp["pause_fg"] = wx.Colour("WHITE") if self._dark else wx.Colour("BLACK")
|
54
|
+
# Start Button
|
55
|
+
tp["start_bg"] = wx.Colour(0, 127, 0)
|
56
|
+
tp["start_fg"] = wx.Colour("WHITE")
|
57
|
+
tp["start_bg_inactive"] = (
|
58
|
+
wx.Colour("DARK SLATE GREY") if self._dark else wx.Colour(0, 127, 0)
|
59
|
+
)
|
60
|
+
tp["start_fg_focus"] = wx.BLACK
|
61
|
+
# Stop button
|
62
|
+
tp["stop_bg"] = wx.Colour(127, 0, 0) # red
|
63
|
+
tp["stop_fg"] = wx.Colour("WHITE")
|
64
|
+
tp["stop_fg_focus"] = wx.BLACK
|
65
|
+
|
66
|
+
tp["arm_bg"] = wx.Colour(0, 127, 0) # green
|
67
|
+
tp["arm_fg"] = wx.WHITE
|
68
|
+
tp["arm_bg_inactive"] = (
|
69
|
+
# wx.Colour("MAROON") if self._dark else wx.Colour("PALE_GREEN")
|
70
|
+
wx.Colour(127, 0, 0)
|
71
|
+
)
|
72
|
+
tp["arm_fg_focus"] = wx.BLACK
|
73
|
+
|
74
|
+
if buggy_darwin:
|
75
|
+
for key, item in tp.items():
|
76
|
+
if isinstance(item, wx.Colour):
|
77
|
+
# System default
|
78
|
+
tp[key] = None
|