meerk40t 0.9.3001__py2.py3-none-any.whl → 0.9.7010__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/__init__.py +1 -1
- meerk40t/balormk/balor_params.py +167 -167
- meerk40t/balormk/clone_loader.py +457 -457
- meerk40t/balormk/controller.py +1566 -1512
- meerk40t/balormk/cylindermod.py +64 -0
- meerk40t/balormk/device.py +966 -1959
- meerk40t/balormk/driver.py +778 -591
- meerk40t/balormk/galvo_commands.py +1195 -0
- meerk40t/balormk/gui/balorconfig.py +237 -111
- meerk40t/balormk/gui/balorcontroller.py +191 -184
- meerk40t/balormk/gui/baloroperationproperties.py +116 -115
- meerk40t/balormk/gui/corscene.py +845 -0
- meerk40t/balormk/gui/gui.py +179 -147
- meerk40t/balormk/livelightjob.py +466 -382
- meerk40t/balormk/mock_connection.py +131 -109
- meerk40t/balormk/plugin.py +133 -135
- meerk40t/balormk/usb_connection.py +306 -301
- meerk40t/camera/__init__.py +1 -1
- meerk40t/camera/camera.py +514 -397
- meerk40t/camera/gui/camerapanel.py +1241 -1095
- meerk40t/camera/gui/gui.py +58 -58
- meerk40t/camera/plugin.py +441 -399
- meerk40t/ch341/__init__.py +27 -27
- meerk40t/ch341/ch341device.py +628 -628
- meerk40t/ch341/libusb.py +595 -589
- meerk40t/ch341/mock.py +171 -171
- meerk40t/ch341/windriver.py +157 -157
- meerk40t/constants.py +13 -0
- meerk40t/core/__init__.py +1 -1
- meerk40t/core/bindalias.py +550 -539
- meerk40t/core/core.py +47 -47
- meerk40t/core/cutcode/cubiccut.py +73 -73
- meerk40t/core/cutcode/cutcode.py +315 -312
- meerk40t/core/cutcode/cutgroup.py +141 -137
- meerk40t/core/cutcode/cutobject.py +192 -185
- meerk40t/core/cutcode/dwellcut.py +37 -37
- meerk40t/core/cutcode/gotocut.py +29 -29
- meerk40t/core/cutcode/homecut.py +29 -29
- meerk40t/core/cutcode/inputcut.py +34 -34
- meerk40t/core/cutcode/linecut.py +33 -33
- meerk40t/core/cutcode/outputcut.py +34 -34
- meerk40t/core/cutcode/plotcut.py +335 -335
- meerk40t/core/cutcode/quadcut.py +61 -61
- meerk40t/core/cutcode/rastercut.py +168 -148
- meerk40t/core/cutcode/waitcut.py +34 -34
- meerk40t/core/cutplan.py +1843 -1316
- meerk40t/core/drivers.py +330 -329
- meerk40t/core/elements/align.py +801 -669
- meerk40t/core/elements/branches.py +1844 -1507
- meerk40t/core/elements/clipboard.py +229 -219
- meerk40t/core/elements/element_treeops.py +4561 -2837
- meerk40t/core/elements/element_types.py +125 -105
- meerk40t/core/elements/elements.py +4329 -3617
- meerk40t/core/elements/files.py +117 -64
- meerk40t/core/elements/geometry.py +473 -224
- meerk40t/core/elements/grid.py +467 -316
- meerk40t/core/elements/materials.py +158 -94
- meerk40t/core/elements/notes.py +50 -38
- meerk40t/core/elements/offset_clpr.py +933 -912
- meerk40t/core/elements/offset_mk.py +963 -955
- meerk40t/core/elements/penbox.py +339 -267
- meerk40t/core/elements/placements.py +300 -83
- meerk40t/core/elements/render.py +785 -687
- meerk40t/core/elements/shapes.py +2618 -2092
- meerk40t/core/elements/trace.py +651 -563
- meerk40t/core/elements/tree_commands.py +415 -409
- meerk40t/core/elements/undo_redo.py +116 -58
- meerk40t/core/elements/wordlist.py +319 -200
- meerk40t/core/exceptions.py +9 -9
- meerk40t/core/laserjob.py +220 -220
- meerk40t/core/logging.py +63 -63
- meerk40t/core/node/blobnode.py +83 -86
- meerk40t/core/node/bootstrap.py +105 -103
- meerk40t/core/node/branch_elems.py +40 -31
- meerk40t/core/node/branch_ops.py +45 -38
- meerk40t/core/node/branch_regmark.py +48 -41
- meerk40t/core/node/cutnode.py +29 -32
- meerk40t/core/node/effect_hatch.py +375 -257
- meerk40t/core/node/effect_warp.py +398 -0
- meerk40t/core/node/effect_wobble.py +441 -309
- meerk40t/core/node/elem_ellipse.py +404 -309
- meerk40t/core/node/elem_image.py +1082 -801
- meerk40t/core/node/elem_line.py +358 -292
- meerk40t/core/node/elem_path.py +259 -201
- meerk40t/core/node/elem_point.py +129 -102
- meerk40t/core/node/elem_polyline.py +310 -246
- meerk40t/core/node/elem_rect.py +376 -286
- meerk40t/core/node/elem_text.py +445 -418
- meerk40t/core/node/filenode.py +59 -40
- meerk40t/core/node/groupnode.py +138 -74
- meerk40t/core/node/image_processed.py +777 -766
- meerk40t/core/node/image_raster.py +156 -113
- meerk40t/core/node/layernode.py +31 -31
- meerk40t/core/node/mixins.py +135 -107
- meerk40t/core/node/node.py +1427 -1304
- meerk40t/core/node/nutils.py +117 -114
- meerk40t/core/node/op_cut.py +462 -335
- meerk40t/core/node/op_dots.py +296 -251
- meerk40t/core/node/op_engrave.py +414 -311
- meerk40t/core/node/op_image.py +755 -369
- meerk40t/core/node/op_raster.py +787 -522
- meerk40t/core/node/place_current.py +37 -40
- meerk40t/core/node/place_point.py +329 -126
- meerk40t/core/node/refnode.py +58 -47
- meerk40t/core/node/rootnode.py +225 -219
- meerk40t/core/node/util_console.py +48 -48
- meerk40t/core/node/util_goto.py +84 -65
- meerk40t/core/node/util_home.py +61 -61
- meerk40t/core/node/util_input.py +102 -102
- meerk40t/core/node/util_output.py +102 -102
- meerk40t/core/node/util_wait.py +65 -65
- meerk40t/core/parameters.py +709 -707
- meerk40t/core/planner.py +875 -785
- meerk40t/core/plotplanner.py +656 -652
- meerk40t/core/space.py +120 -113
- meerk40t/core/spoolers.py +706 -705
- meerk40t/core/svg_io.py +1836 -1549
- meerk40t/core/treeop.py +534 -445
- meerk40t/core/undos.py +278 -124
- meerk40t/core/units.py +784 -680
- meerk40t/core/view.py +393 -322
- meerk40t/core/webhelp.py +62 -62
- meerk40t/core/wordlist.py +513 -504
- meerk40t/cylinder/cylinder.py +247 -0
- meerk40t/cylinder/gui/cylindersettings.py +41 -0
- meerk40t/cylinder/gui/gui.py +24 -0
- meerk40t/device/__init__.py +1 -1
- meerk40t/device/basedevice.py +322 -123
- meerk40t/device/devicechoices.py +50 -0
- meerk40t/device/dummydevice.py +163 -128
- meerk40t/device/gui/defaultactions.py +618 -602
- meerk40t/device/gui/effectspanel.py +114 -0
- meerk40t/device/gui/formatterpanel.py +253 -290
- meerk40t/device/gui/warningpanel.py +337 -260
- meerk40t/device/mixins.py +13 -13
- meerk40t/dxf/__init__.py +1 -1
- meerk40t/dxf/dxf_io.py +766 -554
- meerk40t/dxf/plugin.py +47 -35
- meerk40t/external_plugins.py +79 -79
- meerk40t/external_plugins_build.py +28 -28
- meerk40t/extra/cag.py +112 -116
- meerk40t/extra/coolant.py +403 -0
- meerk40t/extra/encode_detect.py +198 -0
- meerk40t/extra/ezd.py +1165 -1165
- meerk40t/extra/hershey.py +835 -340
- meerk40t/extra/imageactions.py +322 -316
- meerk40t/extra/inkscape.py +630 -622
- meerk40t/extra/lbrn.py +424 -424
- meerk40t/extra/outerworld.py +284 -0
- meerk40t/extra/param_functions.py +1542 -1556
- meerk40t/extra/potrace.py +257 -253
- meerk40t/extra/serial_exchange.py +118 -0
- meerk40t/extra/updater.py +602 -453
- meerk40t/extra/vectrace.py +147 -146
- meerk40t/extra/winsleep.py +83 -83
- meerk40t/extra/xcs_reader.py +597 -0
- meerk40t/fill/fills.py +781 -335
- meerk40t/fill/patternfill.py +1061 -1061
- meerk40t/fill/patterns.py +614 -567
- meerk40t/grbl/control.py +87 -87
- meerk40t/grbl/controller.py +990 -903
- meerk40t/grbl/device.py +1081 -768
- meerk40t/grbl/driver.py +989 -771
- meerk40t/grbl/emulator.py +532 -497
- meerk40t/grbl/gcodejob.py +783 -767
- meerk40t/grbl/gui/grblconfiguration.py +373 -298
- meerk40t/grbl/gui/grblcontroller.py +485 -271
- meerk40t/grbl/gui/grblhardwareconfig.py +269 -153
- meerk40t/grbl/gui/grbloperationconfig.py +105 -0
- meerk40t/grbl/gui/gui.py +147 -116
- meerk40t/grbl/interpreter.py +44 -44
- meerk40t/grbl/loader.py +22 -22
- meerk40t/grbl/mock_connection.py +56 -56
- meerk40t/grbl/plugin.py +294 -264
- meerk40t/grbl/serial_connection.py +93 -88
- meerk40t/grbl/tcp_connection.py +81 -79
- meerk40t/grbl/ws_connection.py +112 -0
- meerk40t/gui/__init__.py +1 -1
- meerk40t/gui/about.py +2042 -296
- meerk40t/gui/alignment.py +1644 -1608
- meerk40t/gui/autoexec.py +199 -0
- meerk40t/gui/basicops.py +791 -670
- meerk40t/gui/bufferview.py +77 -71
- meerk40t/gui/busy.py +170 -133
- meerk40t/gui/choicepropertypanel.py +1673 -1469
- meerk40t/gui/consolepanel.py +706 -542
- meerk40t/gui/devicepanel.py +687 -581
- meerk40t/gui/dialogoptions.py +110 -107
- meerk40t/gui/executejob.py +316 -306
- meerk40t/gui/fonts.py +90 -90
- meerk40t/gui/functionwrapper.py +252 -0
- meerk40t/gui/gui_mixins.py +729 -0
- meerk40t/gui/guicolors.py +205 -182
- meerk40t/gui/help_assets/help_assets.py +218 -201
- meerk40t/gui/helper.py +154 -0
- meerk40t/gui/hersheymanager.py +1430 -846
- meerk40t/gui/icons.py +3422 -2747
- meerk40t/gui/imagesplitter.py +555 -508
- meerk40t/gui/keymap.py +354 -344
- meerk40t/gui/laserpanel.py +892 -806
- meerk40t/gui/laserrender.py +1470 -1232
- meerk40t/gui/lasertoolpanel.py +805 -793
- meerk40t/gui/magnetoptions.py +436 -0
- meerk40t/gui/materialmanager.py +2917 -0
- meerk40t/gui/materialtest.py +1722 -1694
- meerk40t/gui/mkdebug.py +646 -359
- meerk40t/gui/mwindow.py +163 -140
- meerk40t/gui/navigationpanels.py +2605 -2467
- meerk40t/gui/notes.py +143 -142
- meerk40t/gui/opassignment.py +414 -410
- meerk40t/gui/operation_info.py +310 -299
- meerk40t/gui/plugin.py +494 -328
- meerk40t/gui/position.py +714 -669
- meerk40t/gui/preferences.py +901 -650
- meerk40t/gui/propertypanels/attributes.py +1461 -1131
- meerk40t/gui/propertypanels/blobproperty.py +117 -114
- meerk40t/gui/propertypanels/consoleproperty.py +83 -80
- meerk40t/gui/propertypanels/gotoproperty.py +77 -0
- meerk40t/gui/propertypanels/groupproperties.py +223 -217
- meerk40t/gui/propertypanels/hatchproperty.py +489 -469
- meerk40t/gui/propertypanels/imageproperty.py +2244 -1384
- meerk40t/gui/propertypanels/inputproperty.py +59 -58
- meerk40t/gui/propertypanels/opbranchproperties.py +82 -80
- meerk40t/gui/propertypanels/operationpropertymain.py +1890 -1638
- meerk40t/gui/propertypanels/outputproperty.py +59 -58
- meerk40t/gui/propertypanels/pathproperty.py +389 -380
- meerk40t/gui/propertypanels/placementproperty.py +1214 -383
- meerk40t/gui/propertypanels/pointproperty.py +140 -136
- meerk40t/gui/propertypanels/propertywindow.py +313 -181
- meerk40t/gui/propertypanels/rasterwizardpanels.py +996 -912
- meerk40t/gui/propertypanels/regbranchproperties.py +76 -0
- meerk40t/gui/propertypanels/textproperty.py +770 -755
- meerk40t/gui/propertypanels/waitproperty.py +56 -55
- meerk40t/gui/propertypanels/warpproperty.py +121 -0
- meerk40t/gui/propertypanels/wobbleproperty.py +255 -204
- meerk40t/gui/ribbon.py +2468 -2210
- meerk40t/gui/scene/scene.py +1100 -1051
- meerk40t/gui/scene/sceneconst.py +22 -22
- meerk40t/gui/scene/scenepanel.py +439 -349
- meerk40t/gui/scene/scenespacewidget.py +365 -365
- meerk40t/gui/scene/widget.py +518 -505
- meerk40t/gui/scenewidgets/affinemover.py +215 -215
- meerk40t/gui/scenewidgets/attractionwidget.py +315 -309
- meerk40t/gui/scenewidgets/bedwidget.py +120 -97
- meerk40t/gui/scenewidgets/elementswidget.py +137 -107
- meerk40t/gui/scenewidgets/gridwidget.py +785 -745
- meerk40t/gui/scenewidgets/guidewidget.py +765 -765
- meerk40t/gui/scenewidgets/laserpathwidget.py +66 -66
- meerk40t/gui/scenewidgets/machineoriginwidget.py +86 -86
- meerk40t/gui/scenewidgets/nodeselector.py +28 -28
- meerk40t/gui/scenewidgets/rectselectwidget.py +589 -346
- meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
- meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
- meerk40t/gui/scenewidgets/selectionwidget.py +2952 -2756
- meerk40t/gui/simpleui.py +357 -333
- meerk40t/gui/simulation.py +2431 -2094
- meerk40t/gui/snapoptions.py +208 -203
- meerk40t/gui/spoolerpanel.py +1227 -1180
- meerk40t/gui/statusbarwidgets/defaultoperations.py +480 -353
- meerk40t/gui/statusbarwidgets/infowidget.py +520 -483
- meerk40t/gui/statusbarwidgets/opassignwidget.py +356 -355
- meerk40t/gui/statusbarwidgets/selectionwidget.py +172 -171
- meerk40t/gui/statusbarwidgets/shapepropwidget.py +754 -236
- meerk40t/gui/statusbarwidgets/statusbar.py +272 -260
- meerk40t/gui/statusbarwidgets/statusbarwidget.py +268 -270
- meerk40t/gui/statusbarwidgets/strokewidget.py +267 -251
- meerk40t/gui/themes.py +200 -78
- meerk40t/gui/tips.py +591 -0
- meerk40t/gui/toolwidgets/circlebrush.py +35 -35
- meerk40t/gui/toolwidgets/toolcircle.py +248 -242
- meerk40t/gui/toolwidgets/toolcontainer.py +82 -77
- meerk40t/gui/toolwidgets/tooldraw.py +97 -90
- meerk40t/gui/toolwidgets/toolellipse.py +219 -212
- meerk40t/gui/toolwidgets/toolimagecut.py +25 -132
- meerk40t/gui/toolwidgets/toolline.py +39 -144
- meerk40t/gui/toolwidgets/toollinetext.py +79 -236
- meerk40t/gui/toolwidgets/toollinetext_inline.py +296 -0
- meerk40t/gui/toolwidgets/toolmeasure.py +160 -216
- meerk40t/gui/toolwidgets/toolnodeedit.py +2088 -2074
- meerk40t/gui/toolwidgets/toolnodemove.py +92 -94
- meerk40t/gui/toolwidgets/toolparameter.py +754 -668
- meerk40t/gui/toolwidgets/toolplacement.py +108 -108
- meerk40t/gui/toolwidgets/toolpoint.py +68 -59
- meerk40t/gui/toolwidgets/toolpointlistbuilder.py +294 -0
- meerk40t/gui/toolwidgets/toolpointmove.py +183 -0
- meerk40t/gui/toolwidgets/toolpolygon.py +288 -403
- meerk40t/gui/toolwidgets/toolpolyline.py +38 -196
- meerk40t/gui/toolwidgets/toolrect.py +211 -207
- meerk40t/gui/toolwidgets/toolrelocate.py +72 -72
- meerk40t/gui/toolwidgets/toolribbon.py +598 -113
- meerk40t/gui/toolwidgets/tooltabedit.py +546 -0
- meerk40t/gui/toolwidgets/tooltext.py +98 -89
- meerk40t/gui/toolwidgets/toolvector.py +213 -204
- meerk40t/gui/toolwidgets/toolwidget.py +39 -39
- meerk40t/gui/usbconnect.py +98 -91
- meerk40t/gui/utilitywidgets/buttonwidget.py +18 -18
- meerk40t/gui/utilitywidgets/checkboxwidget.py +90 -90
- meerk40t/gui/utilitywidgets/controlwidget.py +14 -14
- meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +343 -340
- meerk40t/gui/utilitywidgets/debugwidgets.py +148 -0
- meerk40t/gui/utilitywidgets/handlewidget.py +27 -27
- meerk40t/gui/utilitywidgets/harmonograph.py +450 -447
- meerk40t/gui/utilitywidgets/openclosewidget.py +40 -40
- meerk40t/gui/utilitywidgets/rotationwidget.py +54 -54
- meerk40t/gui/utilitywidgets/scalewidget.py +75 -75
- meerk40t/gui/utilitywidgets/seekbarwidget.py +183 -183
- meerk40t/gui/utilitywidgets/togglewidget.py +142 -142
- meerk40t/gui/utilitywidgets/toolbarwidget.py +8 -8
- meerk40t/gui/wordlisteditor.py +985 -931
- meerk40t/gui/wxmeerk40t.py +1444 -1169
- meerk40t/gui/wxmmain.py +5578 -4112
- meerk40t/gui/wxmribbon.py +1591 -1076
- meerk40t/gui/wxmscene.py +1635 -1453
- meerk40t/gui/wxmtree.py +2410 -2089
- meerk40t/gui/wxutils.py +1769 -1099
- meerk40t/gui/zmatrix.py +102 -102
- meerk40t/image/__init__.py +1 -1
- meerk40t/image/dither.py +429 -0
- meerk40t/image/imagetools.py +2778 -2269
- meerk40t/internal_plugins.py +150 -130
- meerk40t/kernel/__init__.py +63 -12
- meerk40t/kernel/channel.py +259 -212
- meerk40t/kernel/context.py +538 -538
- meerk40t/kernel/exceptions.py +41 -41
- meerk40t/kernel/functions.py +463 -414
- meerk40t/kernel/jobs.py +100 -100
- meerk40t/kernel/kernel.py +3809 -3571
- meerk40t/kernel/lifecycles.py +71 -71
- meerk40t/kernel/module.py +49 -49
- meerk40t/kernel/service.py +147 -147
- meerk40t/kernel/settings.py +383 -343
- meerk40t/lihuiyu/controller.py +883 -876
- meerk40t/lihuiyu/device.py +1181 -1069
- meerk40t/lihuiyu/driver.py +1466 -1372
- meerk40t/lihuiyu/gui/gui.py +127 -106
- meerk40t/lihuiyu/gui/lhyaccelgui.py +377 -363
- meerk40t/lihuiyu/gui/lhycontrollergui.py +741 -651
- meerk40t/lihuiyu/gui/lhydrivergui.py +470 -446
- meerk40t/lihuiyu/gui/lhyoperationproperties.py +238 -237
- meerk40t/lihuiyu/gui/tcpcontroller.py +226 -190
- meerk40t/lihuiyu/interpreter.py +53 -53
- meerk40t/lihuiyu/laserspeed.py +450 -450
- meerk40t/lihuiyu/loader.py +90 -90
- meerk40t/lihuiyu/parser.py +404 -404
- meerk40t/lihuiyu/plugin.py +101 -102
- meerk40t/lihuiyu/tcp_connection.py +111 -109
- meerk40t/main.py +231 -165
- meerk40t/moshi/builder.py +788 -781
- meerk40t/moshi/controller.py +505 -499
- meerk40t/moshi/device.py +495 -442
- meerk40t/moshi/driver.py +862 -696
- meerk40t/moshi/gui/gui.py +78 -76
- meerk40t/moshi/gui/moshicontrollergui.py +538 -522
- meerk40t/moshi/gui/moshidrivergui.py +87 -75
- meerk40t/moshi/plugin.py +43 -43
- meerk40t/network/console_server.py +102 -57
- meerk40t/network/kernelserver.py +10 -9
- meerk40t/network/tcp_server.py +142 -140
- meerk40t/network/udp_server.py +103 -77
- meerk40t/network/web_server.py +390 -0
- meerk40t/newly/controller.py +1158 -1144
- meerk40t/newly/device.py +874 -732
- meerk40t/newly/driver.py +540 -412
- meerk40t/newly/gui/gui.py +219 -188
- meerk40t/newly/gui/newlyconfig.py +116 -101
- meerk40t/newly/gui/newlycontroller.py +193 -186
- meerk40t/newly/gui/operationproperties.py +51 -51
- meerk40t/newly/mock_connection.py +82 -82
- meerk40t/newly/newly_params.py +56 -56
- meerk40t/newly/plugin.py +1214 -1246
- meerk40t/newly/usb_connection.py +322 -322
- meerk40t/rotary/gui/gui.py +52 -46
- meerk40t/rotary/gui/rotarysettings.py +240 -232
- meerk40t/rotary/rotary.py +202 -98
- meerk40t/ruida/control.py +291 -91
- meerk40t/ruida/controller.py +138 -1088
- meerk40t/ruida/device.py +672 -231
- meerk40t/ruida/driver.py +534 -472
- meerk40t/ruida/emulator.py +1494 -1491
- meerk40t/ruida/exceptions.py +4 -4
- meerk40t/ruida/gui/gui.py +71 -76
- meerk40t/ruida/gui/ruidaconfig.py +239 -72
- meerk40t/ruida/gui/ruidacontroller.py +187 -184
- meerk40t/ruida/gui/ruidaoperationproperties.py +48 -47
- meerk40t/ruida/loader.py +54 -52
- meerk40t/ruida/mock_connection.py +57 -109
- meerk40t/ruida/plugin.py +124 -87
- meerk40t/ruida/rdjob.py +2084 -945
- meerk40t/ruida/serial_connection.py +116 -0
- meerk40t/ruida/tcp_connection.py +146 -0
- meerk40t/ruida/udp_connection.py +73 -0
- meerk40t/svgelements.py +9671 -9669
- meerk40t/tools/driver_to_path.py +584 -579
- meerk40t/tools/geomstr.py +5583 -4680
- meerk40t/tools/jhfparser.py +357 -292
- meerk40t/tools/kerftest.py +904 -890
- meerk40t/tools/livinghinges.py +1168 -1033
- meerk40t/tools/pathtools.py +987 -949
- meerk40t/tools/pmatrix.py +234 -0
- meerk40t/tools/pointfinder.py +942 -942
- meerk40t/tools/polybool.py +940 -940
- meerk40t/tools/rasterplotter.py +1660 -547
- meerk40t/tools/shxparser.py +989 -901
- meerk40t/tools/ttfparser.py +726 -446
- meerk40t/tools/zinglplotter.py +595 -593
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/LICENSE +21 -21
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/METADATA +150 -139
- meerk40t-0.9.7010.dist-info/RECORD +445 -0
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/WHEEL +1 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/top_level.txt +0 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/zip-safe +1 -1
- meerk40t/balormk/elementlightjob.py +0 -159
- meerk40t-0.9.3001.dist-info/RECORD +0 -437
- test/bootstrap.py +0 -63
- test/test_cli.py +0 -12
- test/test_core_cutcode.py +0 -418
- test/test_core_elements.py +0 -144
- test/test_core_plotplanner.py +0 -397
- test/test_core_viewports.py +0 -312
- test/test_drivers_grbl.py +0 -108
- test/test_drivers_lihuiyu.py +0 -443
- test/test_drivers_newly.py +0 -113
- test/test_element_degenerate_points.py +0 -43
- test/test_elements_classify.py +0 -97
- test/test_elements_penbox.py +0 -22
- test/test_file_svg.py +0 -176
- test/test_fill.py +0 -155
- test/test_geomstr.py +0 -1523
- test/test_geomstr_nodes.py +0 -18
- test/test_imagetools_actualize.py +0 -306
- test/test_imagetools_wizard.py +0 -258
- test/test_kernel.py +0 -200
- test/test_laser_speeds.py +0 -3303
- test/test_length.py +0 -57
- test/test_lifecycle.py +0 -66
- test/test_operations.py +0 -251
- test/test_operations_hatch.py +0 -57
- test/test_ruida.py +0 -19
- test/test_spooler.py +0 -22
- test/test_tools_rasterplotter.py +0 -29
- test/test_wobble.py +0 -133
- test/test_zingl.py +0 -124
- {test → meerk40t/cylinder}/__init__.py +0 -0
- /meerk40t/{core/element_commands.py → cylinder/gui/__init__.py} +0 -0
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/entry_points.txt +0 -0
@@ -1,346 +1,589 @@
|
|
1
|
-
"""
|
2
|
-
Specifically draws the rectangle selection box and deals with emphasis of selected objects.
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
import
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
self.
|
71
|
-
self.
|
72
|
-
self.
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
#
|
148
|
-
if
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
self.
|
178
|
-
self.
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
self.
|
197
|
-
self.
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
self.
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
self.
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
1
|
+
"""
|
2
|
+
Specifically draws the rectangle selection box and deals with emphasis of selected objects.
|
3
|
+
Special case: if the user did not move the mouse within the first 0.5 seconds after
|
4
|
+
the initial mouse press then we assume a drag move.
|
5
|
+
"""
|
6
|
+
from time import perf_counter
|
7
|
+
|
8
|
+
import numpy as np
|
9
|
+
import wx
|
10
|
+
|
11
|
+
from meerk40t.core.elements.element_types import elem_nodes
|
12
|
+
from meerk40t.gui.scene.scene import (
|
13
|
+
HITCHAIN_HIT,
|
14
|
+
RESPONSE_CHAIN,
|
15
|
+
RESPONSE_CONSUME,
|
16
|
+
RESPONSE_DROP,
|
17
|
+
)
|
18
|
+
from meerk40t.gui.scene.widget import Widget
|
19
|
+
from meerk40t.gui.wxutils import get_matrix_scale, get_gc_full_scale
|
20
|
+
from meerk40t.tools.geomstr import NON_GEOMETRY_TYPES
|
21
|
+
|
22
|
+
|
23
|
+
class RectSelectWidget(Widget):
|
24
|
+
"""
|
25
|
+
SceneWidget
|
26
|
+
|
27
|
+
Rectangle Selection Widget, draws the selection rectangle if left-clicked and dragged
|
28
|
+
"""
|
29
|
+
|
30
|
+
# selection_method = 1 = hit, 2 = cross, 3 = enclose
|
31
|
+
SELECTION_TOUCH = 1
|
32
|
+
SELECTION_CROSS = 2
|
33
|
+
SELECTION_ENCLOSE = 3
|
34
|
+
selection_text_shift = " Previously selected remain selected!"
|
35
|
+
selection_text_control = " Invert selection state of elements!"
|
36
|
+
|
37
|
+
# 2 | 1 Define Selection method per sector, movement of mouse from point of origin into that sector...
|
38
|
+
# - + -
|
39
|
+
# 3 | 0
|
40
|
+
#
|
41
|
+
selection_method = [
|
42
|
+
SELECTION_ENCLOSE,
|
43
|
+
SELECTION_ENCLOSE,
|
44
|
+
SELECTION_TOUCH,
|
45
|
+
SELECTION_TOUCH,
|
46
|
+
] # Selection rectangle to the right: enclose, to the left: touch
|
47
|
+
|
48
|
+
was_lb_raised = False
|
49
|
+
|
50
|
+
def __init__(self, scene):
|
51
|
+
Widget.__init__(self, scene, all=True)
|
52
|
+
# Color for selection rectangle (hit, cross, enclose)
|
53
|
+
self.selection_style = [
|
54
|
+
[
|
55
|
+
self.scene.colors.color_selection1,
|
56
|
+
wx.PENSTYLE_DOT_DASH,
|
57
|
+
"Select all elements the selection rectangle touches.",
|
58
|
+
],
|
59
|
+
[
|
60
|
+
self.scene.colors.color_selection2,
|
61
|
+
wx.PENSTYLE_DOT,
|
62
|
+
"Select all elements the selection rectangle crosses.",
|
63
|
+
],
|
64
|
+
[
|
65
|
+
self.scene.colors.color_selection3,
|
66
|
+
wx.PENSTYLE_SHORT_DASH,
|
67
|
+
"Select all elements the selection rectangle encloses.",
|
68
|
+
],
|
69
|
+
]
|
70
|
+
self.selection_pen = wx.Pen()
|
71
|
+
self.selection_pen.SetColour(self.selection_style[0][0])
|
72
|
+
self.selection_pen.SetWidth(25)
|
73
|
+
self.selection_pen.SetStyle(self.selection_style[0][1])
|
74
|
+
# want to have sharp edges
|
75
|
+
self.selection_pen.SetJoin(wx.JOIN_MITER)
|
76
|
+
self.start_location = None
|
77
|
+
self.end_location = None
|
78
|
+
self.modifiers = []
|
79
|
+
self.mouse_down_time = 0
|
80
|
+
self.scene.context.setting(bool, "delayed_move", True)
|
81
|
+
self.mode = "select"
|
82
|
+
self.can_drag_move = False
|
83
|
+
|
84
|
+
def hit(self):
|
85
|
+
return HITCHAIN_HIT
|
86
|
+
|
87
|
+
store_last_msg = ""
|
88
|
+
|
89
|
+
@property
|
90
|
+
def sector(self):
|
91
|
+
sx = self.start_location[0]
|
92
|
+
sy = self.start_location[1]
|
93
|
+
ex = self.end_location[0]
|
94
|
+
ey = self.end_location[1]
|
95
|
+
if sx <= ex:
|
96
|
+
if sy <= ey:
|
97
|
+
return 0
|
98
|
+
else:
|
99
|
+
return 1
|
100
|
+
else:
|
101
|
+
if sy <= ey:
|
102
|
+
return 3
|
103
|
+
else:
|
104
|
+
return 2
|
105
|
+
|
106
|
+
def rect_select(self, elements, sx, sy, ex, ey):
|
107
|
+
sector = self.sector
|
108
|
+
selected = False
|
109
|
+
# We don't want every single element to to issue a signal
|
110
|
+
with elements.signalfree("emphasized"):
|
111
|
+
for node in elements.elems():
|
112
|
+
try:
|
113
|
+
q = node.bounds
|
114
|
+
except AttributeError:
|
115
|
+
continue # This element has no bounds.
|
116
|
+
if q is None:
|
117
|
+
continue
|
118
|
+
if hasattr(node, "hidden") and node.hidden:
|
119
|
+
continue
|
120
|
+
if hasattr(node, "can_emphasize") and not node.can_emphasize:
|
121
|
+
continue
|
122
|
+
xmin = q[0]
|
123
|
+
ymin = q[1]
|
124
|
+
xmax = q[2]
|
125
|
+
ymax = q[3]
|
126
|
+
# no hit
|
127
|
+
cover = 0
|
128
|
+
# Check Hit
|
129
|
+
# The rectangles don't overlap if
|
130
|
+
# one rectangle's minimum in some dimension
|
131
|
+
# is greater than the other's maximum in
|
132
|
+
# that dimension.
|
133
|
+
if not ((sx > xmax) or (xmin > ex) or (sy > ymax) or (ymin > ey)):
|
134
|
+
cover = self.SELECTION_TOUCH
|
135
|
+
# If selection rect is fully inside an object then ignore
|
136
|
+
if sx > xmin and ex < xmax and sy > ymin and ey < ymax:
|
137
|
+
cover = 0
|
138
|
+
|
139
|
+
# Check Cross
|
140
|
+
if (
|
141
|
+
((sx <= xmin) and (xmax <= ex))
|
142
|
+
and not ((sy > ymax) or (ey < ymin))
|
143
|
+
or ((sy <= ymin) and (ymax <= ey))
|
144
|
+
and not ((sx > xmax) or (ex < xmin))
|
145
|
+
):
|
146
|
+
cover = self.SELECTION_CROSS
|
147
|
+
# Check contain
|
148
|
+
if ((sx <= xmin) and (xmax <= ex)) and ((sy <= ymin) and (ymax <= ey)):
|
149
|
+
cover = self.SELECTION_ENCLOSE
|
150
|
+
|
151
|
+
if "shift" in self.modifiers:
|
152
|
+
# Add Selection
|
153
|
+
if cover >= self.selection_method[sector]:
|
154
|
+
node.emphasized = True
|
155
|
+
node.selected = True
|
156
|
+
selected = True
|
157
|
+
elif "ctrl" in self.modifiers:
|
158
|
+
# Invert Selection
|
159
|
+
if cover >= self.selection_method[sector]:
|
160
|
+
node.emphasized = not node.emphasized
|
161
|
+
node.selected = node.emphasized
|
162
|
+
selected = True
|
163
|
+
else:
|
164
|
+
# Replace Selection
|
165
|
+
if cover >= self.selection_method[sector]:
|
166
|
+
node.emphasized = True
|
167
|
+
node.selected = True
|
168
|
+
selected = True
|
169
|
+
else:
|
170
|
+
node.emphasized = False
|
171
|
+
node.selected = False
|
172
|
+
if selected:
|
173
|
+
self.scene.context.signal("element_clicked")
|
174
|
+
|
175
|
+
def update_statusmsg(self, value):
|
176
|
+
if value != self.store_last_msg:
|
177
|
+
self.store_last_msg = value
|
178
|
+
self.scene.context.signal("statusmsg", value)
|
179
|
+
|
180
|
+
# debug_msg = ""
|
181
|
+
|
182
|
+
def event(
|
183
|
+
self, window_pos=None, space_pos=None, event_type=None, modifiers=None, **kwargs
|
184
|
+
):
|
185
|
+
def contains(box, x, y=None):
|
186
|
+
if box is None:
|
187
|
+
return False
|
188
|
+
if y is None:
|
189
|
+
y = x[1]
|
190
|
+
x = x[0]
|
191
|
+
return box[0] <= x <= box[2] and box[1] <= y <= box[3]
|
192
|
+
|
193
|
+
def move_to(dx, dy):
|
194
|
+
if dx == 0 and dy == 0:
|
195
|
+
return
|
196
|
+
# self.total_dx += dx
|
197
|
+
# self.total_dy += dy
|
198
|
+
b = self.scene.context.elements._emphasized_bounds
|
199
|
+
if b is None:
|
200
|
+
b = self.scene.context.elements.selected_area()
|
201
|
+
if b is None:
|
202
|
+
# There is no emphasized bounds or selected area.
|
203
|
+
return
|
204
|
+
allowlockmove = self.scene.context.elements.lock_allows_move
|
205
|
+
with self.scene.context.elements.undofree():
|
206
|
+
for e in self.scene.context.elements.flat(
|
207
|
+
types=elem_nodes, emphasized=True
|
208
|
+
):
|
209
|
+
if not e.can_move(allowlockmove):
|
210
|
+
continue
|
211
|
+
e.matrix.post_translate(dx, dy)
|
212
|
+
# We would normally not adjust the node properties,
|
213
|
+
# but the pure adjustment of the bbox is hopefully not hurting
|
214
|
+
e.translated(dx, dy)
|
215
|
+
self.scene.context.elements.update_bounds(
|
216
|
+
[b[0] + dx, b[1] + dy, b[2] + dx, b[3] + dy]
|
217
|
+
)
|
218
|
+
self.scene.request_refresh()
|
219
|
+
|
220
|
+
if modifiers is not None:
|
221
|
+
self.modifiers = modifiers
|
222
|
+
|
223
|
+
elements = self.scene.context.elements
|
224
|
+
if event_type == "leftdown":
|
225
|
+
self.mouse_down_time = perf_counter()
|
226
|
+
self.mode = "unclear"
|
227
|
+
self.start_location = space_pos
|
228
|
+
self.end_location = space_pos
|
229
|
+
if contains(self.scene.context.elements._emphasized_bounds, space_pos):
|
230
|
+
self.can_drag_move = True
|
231
|
+
# print ("RectSelect consumed leftdown")
|
232
|
+
return RESPONSE_CONSUME
|
233
|
+
elif event_type == "leftclick":
|
234
|
+
# That's too fast
|
235
|
+
# still chaining though
|
236
|
+
self.scene.request_refresh()
|
237
|
+
self.reset()
|
238
|
+
return RESPONSE_CHAIN
|
239
|
+
elif event_type == "leftup":
|
240
|
+
if self.mode == "select":
|
241
|
+
if self.start_location is None:
|
242
|
+
return RESPONSE_CHAIN
|
243
|
+
_ = self.scene.context._
|
244
|
+
self.update_statusmsg(_("Status"))
|
245
|
+
elements.validate_selected_area()
|
246
|
+
sx = min(self.start_location[0], self.end_location[0])
|
247
|
+
sy = min(self.start_location[1], self.end_location[1])
|
248
|
+
ex = max(self.start_location[0], self.end_location[0])
|
249
|
+
ey = max(self.start_location[1], self.end_location[1])
|
250
|
+
self.rect_select(elements, sx, sy, ex, ey)
|
251
|
+
|
252
|
+
self.scene.request_refresh()
|
253
|
+
self.scene.context.signal("select_emphasized_tree", 0)
|
254
|
+
else:
|
255
|
+
|
256
|
+
def shortest_distance(p1, p2, tuplemode):
|
257
|
+
"""
|
258
|
+
Calculates the shortest distance between two arrays of 2-dimensional points.
|
259
|
+
"""
|
260
|
+
# Calculate the Euclidean distance between each point in p1 and p2
|
261
|
+
if tuplemode:
|
262
|
+
# For an array of tuples:
|
263
|
+
dist = np.sqrt(np.sum((p1[:, np.newaxis] - p2) ** 2, axis=2))
|
264
|
+
else:
|
265
|
+
# For an array of complex numbers
|
266
|
+
dist = np.abs(p1[:, np.newaxis] - p2[np.newaxis, :])
|
267
|
+
|
268
|
+
# Find the minimum distance and its corresponding indices
|
269
|
+
min_dist = np.min(dist)
|
270
|
+
if np.isnan(min_dist):
|
271
|
+
return None, 0, 0
|
272
|
+
min_indices = np.argwhere(dist == min_dist)
|
273
|
+
|
274
|
+
# Return the coordinates of the two points
|
275
|
+
return min_dist, p1[min_indices[0][0]], p2[min_indices[0][1]]
|
276
|
+
|
277
|
+
b = self.scene.context.elements._emphasized_bounds
|
278
|
+
if b is None:
|
279
|
+
b = self.scene.context.elements.selected_area()
|
280
|
+
matrix = self.scene.widget_root.scene_widget.matrix
|
281
|
+
did_snap_to_point = False
|
282
|
+
if (
|
283
|
+
self.scene.context.snap_points
|
284
|
+
and "shift" not in modifiers
|
285
|
+
and b is not None
|
286
|
+
):
|
287
|
+
gap = self.scene.context.action_attract_len / get_matrix_scale(matrix)
|
288
|
+
# We gather all points of non-selected elements,
|
289
|
+
# but only those that lie within the boundaries
|
290
|
+
# of the selected area
|
291
|
+
# We compare every point of the selected elements
|
292
|
+
# with the points of the non-selected elements (provided they
|
293
|
+
# lie within the selection area plus boundary) and look for
|
294
|
+
# the closest distance.
|
295
|
+
|
296
|
+
# t1 = perf_counter()
|
297
|
+
other_points = []
|
298
|
+
selected_points = []
|
299
|
+
for e in self.scene.context.elements.elems():
|
300
|
+
if e.emphasized:
|
301
|
+
target = selected_points
|
302
|
+
else:
|
303
|
+
target = other_points
|
304
|
+
if not hasattr(e, "as_geometry"):
|
305
|
+
continue
|
306
|
+
geom = e.as_geometry()
|
307
|
+
last = None
|
308
|
+
for seg in geom.segments[: geom.index]:
|
309
|
+
start = seg[0]
|
310
|
+
seg_type = geom._segtype(seg)
|
311
|
+
end = seg[4]
|
312
|
+
if seg_type in NON_GEOMETRY_TYPES:
|
313
|
+
continue
|
314
|
+
if np.isnan(start) or np.isnan(end):
|
315
|
+
print (f"Strange, encountered within rectselect a segment with type: {seg_type} and start={start}, end={end} - coming from element type {e.type}\nPlease inform the developers")
|
316
|
+
continue
|
317
|
+
if start != last:
|
318
|
+
xx = start.real
|
319
|
+
yy = start.imag
|
320
|
+
ignore = (
|
321
|
+
xx < b[0] - gap
|
322
|
+
or xx > b[2] + gap
|
323
|
+
or yy < b[1] - gap
|
324
|
+
or yy > b[3] + gap
|
325
|
+
)
|
326
|
+
if not ignore:
|
327
|
+
target.append(start)
|
328
|
+
xx = end.real
|
329
|
+
yy = end.imag
|
330
|
+
ignore = (
|
331
|
+
xx < b[0] - gap
|
332
|
+
or xx > b[2] + gap
|
333
|
+
or yy < b[1] - gap
|
334
|
+
or yy > b[3] + gap
|
335
|
+
)
|
336
|
+
if not ignore:
|
337
|
+
target.append(end)
|
338
|
+
last = end
|
339
|
+
# t2 = perf_counter()
|
340
|
+
if (
|
341
|
+
other_points is not None
|
342
|
+
and selected_points is not None
|
343
|
+
and len(other_points) > 0
|
344
|
+
and len(selected_points) > 0
|
345
|
+
):
|
346
|
+
np_other = np.asarray(other_points)
|
347
|
+
np_selected = np.asarray(selected_points)
|
348
|
+
dist, pt1, pt2 = shortest_distance(np_other, np_selected, False)
|
349
|
+
|
350
|
+
if dist is not None and dist < gap:
|
351
|
+
did_snap_to_point = True
|
352
|
+
dx = pt1.real - pt2.real
|
353
|
+
dy = pt1.imag - pt2.imag
|
354
|
+
move_to(dx, dy)
|
355
|
+
# Get new value
|
356
|
+
b = self.scene.context.elements._emphasized_bounds
|
357
|
+
# t3 = perf_counter()
|
358
|
+
# print (f"Snap, compared {len(selected_points)} pts to {len(other_points)} pts. Total time: {t3-t1:.2f}sec, Generation: {t2-t1:.2f}sec, shortest: {t3-t2:.2f}sec")
|
359
|
+
if (
|
360
|
+
self.scene.context.snap_grid
|
361
|
+
and "shift" not in modifiers
|
362
|
+
and b is not None
|
363
|
+
and not did_snap_to_point
|
364
|
+
):
|
365
|
+
# t1 = perf_counter()
|
366
|
+
gap = self.scene.context.grid_attract_len / get_matrix_scale(matrix)
|
367
|
+
# Check for corner points + center:
|
368
|
+
selected_points = (
|
369
|
+
(b[0], b[1]),
|
370
|
+
(b[2], b[1]),
|
371
|
+
(b[0], b[3]),
|
372
|
+
(b[2], b[3]),
|
373
|
+
((b[0] + b[2]) / 2, (b[1] + b[3]) / 2),
|
374
|
+
)
|
375
|
+
other_points = self.scene.pane.grid.grid_points
|
376
|
+
if (
|
377
|
+
other_points is not None
|
378
|
+
and selected_points is not None
|
379
|
+
and len(other_points) > 0
|
380
|
+
and len(selected_points) > 0
|
381
|
+
):
|
382
|
+
np_other = np.asarray(other_points)
|
383
|
+
np_selected = np.asarray(selected_points)
|
384
|
+
dist, pt1, pt2 = shortest_distance(np_other, np_selected, True)
|
385
|
+
if dist is not None and dist < gap:
|
386
|
+
# did_snap_to_point = True
|
387
|
+
dx = pt1[0] - pt2[0]
|
388
|
+
dy = pt1[1] - pt2[1]
|
389
|
+
move_to(dx, dy)
|
390
|
+
# Get new value
|
391
|
+
b = self.scene.context.elements._emphasized_bounds
|
392
|
+
|
393
|
+
# t2 = perf_counter()
|
394
|
+
# print (f"Corner-points, compared {len(selected_points)} pts to {len(other_points)} pts. Total time: {t2-t1:.2f}sec")
|
395
|
+
# Even then magnets win!
|
396
|
+
dx, dy = self.scene.pane.revised_magnet_bound(b)
|
397
|
+
move_to(dx, dy)
|
398
|
+
|
399
|
+
self.reset()
|
400
|
+
|
401
|
+
return RESPONSE_CONSUME
|
402
|
+
elif event_type == "move":
|
403
|
+
if self.mode == "unclear":
|
404
|
+
current_time = perf_counter()
|
405
|
+
# print (f"{current_time - self.mouse_down_time:.2f}sec.")
|
406
|
+
if current_time - self.mouse_down_time > 0.5 and self.can_drag_move:
|
407
|
+
self.mode = "move"
|
408
|
+
self.scene.cursor("sizing")
|
409
|
+
else:
|
410
|
+
self.mode = "select"
|
411
|
+
self.scene.cursor("arrow")
|
412
|
+
|
413
|
+
if self.mode == "select":
|
414
|
+
self.scene.request_refresh()
|
415
|
+
self.end_location = space_pos
|
416
|
+
elif self.mode == "move":
|
417
|
+
dx = space_pos[4]
|
418
|
+
dy = space_pos[5]
|
419
|
+
move_to(dx, dy)
|
420
|
+
|
421
|
+
return RESPONSE_CONSUME
|
422
|
+
elif event_type == "lost":
|
423
|
+
self.reset()
|
424
|
+
return RESPONSE_CONSUME
|
425
|
+
return RESPONSE_DROP
|
426
|
+
|
427
|
+
def reset(self):
|
428
|
+
self.start_location = None
|
429
|
+
self.end_location = None
|
430
|
+
self.mode = "unclear"
|
431
|
+
self.mouse_down_time = 0
|
432
|
+
self.can_drag_move = False
|
433
|
+
self.scene.cursor("arrow")
|
434
|
+
|
435
|
+
def draw_rectangle(self, gc, x0, y0, x1, y1, tcolor, tstyle):
|
436
|
+
# Linux / Darwin do not recognize the GraphicsContext TransformationMatrix
|
437
|
+
# when drawing dashed/dotted lines, so they always appear to be solid
|
438
|
+
# (even if they are dotted on a microscopic level)
|
439
|
+
# To circumvent this issue, we scale the gc back
|
440
|
+
gc.PushState()
|
441
|
+
sx, sy = get_gc_full_scale(gc)
|
442
|
+
gc.Scale(1 / sx, 1 / sy)
|
443
|
+
self.selection_pen.SetColour(tcolor)
|
444
|
+
self.selection_pen.SetStyle(tstyle)
|
445
|
+
gc.SetPen(self.selection_pen)
|
446
|
+
linewidth = 1
|
447
|
+
try:
|
448
|
+
self.selection_pen.SetWidth(linewidth)
|
449
|
+
except TypeError:
|
450
|
+
self.selection_pen.SetWidth(int(linewidth))
|
451
|
+
gc.SetPen(self.selection_pen)
|
452
|
+
gc.StrokeLine(x0 * sx, y0 * sy, x1 * sx, y0 * sy)
|
453
|
+
gc.StrokeLine(x1 * sx, y0 * sy, x1 * sx, y1 * sy)
|
454
|
+
gc.StrokeLine(x1 * sx, y1 * sy, x0 * sx, y1 * sy)
|
455
|
+
gc.StrokeLine(x0 * sx, y1 * sy, x0 * sx, y0 * sy)
|
456
|
+
gc.PopState()
|
457
|
+
|
458
|
+
def draw_tiny_indicator(self, gc, symbol, x0, y0, x1, y1, tcolor, tstyle):
|
459
|
+
# Linux / Darwin do not recognize the GraphicsContext TransformationMatrix
|
460
|
+
# when drawing dashed/dotted lines, so they always appear to be solid
|
461
|
+
# (even if they are dotted on a microscopic level)
|
462
|
+
# To circumvent this issue, we scale the gc back
|
463
|
+
gc.PushState()
|
464
|
+
sx, sy = get_gc_full_scale(gc)
|
465
|
+
# print (f"sx={sx}, sy={sy}")
|
466
|
+
gc.Scale(1 / sx, 1 / sy)
|
467
|
+
self.selection_pen.SetColour(tcolor)
|
468
|
+
self.selection_pen.SetStyle(tstyle)
|
469
|
+
|
470
|
+
linewidth = 1
|
471
|
+
try:
|
472
|
+
self.selection_pen.SetWidth(linewidth)
|
473
|
+
except TypeError:
|
474
|
+
self.selection_pen.SetWidth(int(linewidth))
|
475
|
+
gc.SetPen(self.selection_pen)
|
476
|
+
delta_X = 15.0
|
477
|
+
delta_Y = 15.0
|
478
|
+
x0 *= sx
|
479
|
+
x1 *= sx
|
480
|
+
y0 *= sx
|
481
|
+
y1 *= sx
|
482
|
+
if abs(x1 - x0) > delta_X and abs(y1 - y0) > delta_Y: # Don't draw if too tiny
|
483
|
+
# Draw tiny '+' in corner of pointer
|
484
|
+
x_signum = +1 * delta_X if x0 < x1 else -1 * delta_X
|
485
|
+
y_signum = +1 * delta_Y if y0 < y1 else -1 * delta_X
|
486
|
+
ax1 = x1 - x_signum
|
487
|
+
ay1 = y1 - y_signum
|
488
|
+
|
489
|
+
gc.SetPen(self.selection_pen)
|
490
|
+
gc.StrokeLine(ax1, y1, ax1, ay1)
|
491
|
+
gc.StrokeLine(ax1, ay1, x1, ay1)
|
492
|
+
font_size = 10.0
|
493
|
+
if font_size < 1.0:
|
494
|
+
font_size = 1.0
|
495
|
+
try:
|
496
|
+
font = wx.Font(
|
497
|
+
font_size,
|
498
|
+
wx.FONTFAMILY_SWISS,
|
499
|
+
wx.FONTSTYLE_NORMAL,
|
500
|
+
wx.FONTWEIGHT_NORMAL,
|
501
|
+
)
|
502
|
+
except TypeError:
|
503
|
+
font = wx.Font(
|
504
|
+
int(font_size),
|
505
|
+
wx.FONTFAMILY_SWISS,
|
506
|
+
wx.FONTSTYLE_NORMAL,
|
507
|
+
wx.FONTWEIGHT_NORMAL,
|
508
|
+
)
|
509
|
+
gc.SetFont(font, tcolor)
|
510
|
+
(t_width, t_height) = gc.GetTextExtent(symbol)
|
511
|
+
gc.DrawText(
|
512
|
+
symbol, (ax1 + x1) / 2 - t_width / 2, (ay1 + y1) / 2 - t_height / 2
|
513
|
+
)
|
514
|
+
if (
|
515
|
+
abs(x1 - x0) > 2 * delta_X and abs(y1 - y0) > 2 * delta_Y
|
516
|
+
): # Don't draw if too tiny
|
517
|
+
# Draw second symbol at origin
|
518
|
+
ax1 = x0 + x_signum
|
519
|
+
ay1 = y0 + y_signum
|
520
|
+
gc.StrokeLine(ax1, y0, ax1, ay1)
|
521
|
+
gc.StrokeLine(ax1, ay1, x0, ay1)
|
522
|
+
gc.DrawText(
|
523
|
+
symbol, (ax1 + x0) / 2 - t_width / 2, (ay1 + y0) / 2 - t_height / 2
|
524
|
+
)
|
525
|
+
gc.PopState()
|
526
|
+
|
527
|
+
def process_draw(self, gc):
|
528
|
+
"""
|
529
|
+
Draw the selection rectangle
|
530
|
+
"""
|
531
|
+
if (
|
532
|
+
self.mode == "select"
|
533
|
+
and self.start_location is not None
|
534
|
+
and self.end_location is not None
|
535
|
+
):
|
536
|
+
self.selection_style[0][0] = self.scene.colors.color_selection1
|
537
|
+
self.selection_style[1][0] = self.scene.colors.color_selection2
|
538
|
+
self.selection_style[2][0] = self.scene.colors.color_selection3
|
539
|
+
x0 = self.start_location[0]
|
540
|
+
y0 = self.start_location[1]
|
541
|
+
x1 = self.end_location[0]
|
542
|
+
y1 = self.end_location[1]
|
543
|
+
sector = self.sector
|
544
|
+
|
545
|
+
_ = self.scene.context._
|
546
|
+
statusmsg = _(self.selection_style[self.selection_method[sector] - 1][2])
|
547
|
+
if "shift" in self.modifiers:
|
548
|
+
statusmsg += _(self.selection_text_shift)
|
549
|
+
elif "ctrl" in self.modifiers:
|
550
|
+
statusmsg += _(self.selection_text_control)
|
551
|
+
|
552
|
+
self.update_statusmsg(statusmsg)
|
553
|
+
gcstyle = self.selection_style[self.selection_method[sector] - 1][0]
|
554
|
+
gccolor = self.selection_style[self.selection_method[sector] - 1][1]
|
555
|
+
self.draw_rectangle(
|
556
|
+
gc,
|
557
|
+
x0,
|
558
|
+
y0,
|
559
|
+
x1,
|
560
|
+
y1,
|
561
|
+
gcstyle,
|
562
|
+
gccolor,
|
563
|
+
)
|
564
|
+
|
565
|
+
# Determine Colour on selection mode: standard (from left top to right bottom) = Blue, else Green
|
566
|
+
# Draw indicator...
|
567
|
+
if "shift" in self.modifiers:
|
568
|
+
self.draw_tiny_indicator(
|
569
|
+
gc,
|
570
|
+
"+",
|
571
|
+
x0,
|
572
|
+
y0,
|
573
|
+
x1,
|
574
|
+
y1,
|
575
|
+
gcstyle,
|
576
|
+
gccolor,
|
577
|
+
)
|
578
|
+
|
579
|
+
elif "ctrl" in self.modifiers:
|
580
|
+
self.draw_tiny_indicator(
|
581
|
+
gc,
|
582
|
+
"^",
|
583
|
+
x0,
|
584
|
+
y0,
|
585
|
+
x1,
|
586
|
+
y1,
|
587
|
+
self.selection_style[self.selection_method[sector] - 1][0],
|
588
|
+
self.selection_style[self.selection_method[sector] - 1][1],
|
589
|
+
)
|