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,383 +1,1214 @@
|
|
1
|
-
"""
|
2
|
-
Display and Editing of the properties of 'place current', 'place point'
|
3
|
-
"""
|
4
|
-
|
5
|
-
import
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
from meerk40t.
|
10
|
-
from meerk40t.
|
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
|
-
self.
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
)
|
45
|
-
self.
|
46
|
-
self.
|
47
|
-
|
48
|
-
|
49
|
-
self.
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
"",
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
)
|
93
|
-
self.
|
94
|
-
self.
|
95
|
-
self.
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
)
|
108
|
-
|
109
|
-
self.
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
self.
|
122
|
-
_(
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
self.
|
134
|
-
|
135
|
-
self.
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
self.
|
172
|
-
|
173
|
-
|
174
|
-
self.
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
self.
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
self.
|
264
|
-
|
265
|
-
|
266
|
-
self.
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
self
|
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
|
-
self.
|
327
|
-
self.
|
328
|
-
self.
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
self.
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
self.
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
1
|
+
"""
|
2
|
+
Display and Editing of the properties of 'place current', 'place point'
|
3
|
+
"""
|
4
|
+
|
5
|
+
import math
|
6
|
+
|
7
|
+
import wx
|
8
|
+
|
9
|
+
from meerk40t.core.units import Angle, Length
|
10
|
+
from meerk40t.gui.propertypanels.attributes import IdPanel
|
11
|
+
from meerk40t.gui.wxutils import (
|
12
|
+
ScrolledPanel,
|
13
|
+
StaticBoxSizer,
|
14
|
+
TextCtrl,
|
15
|
+
set_ctrl_value,
|
16
|
+
wxButton,
|
17
|
+
wxCheckBox,
|
18
|
+
wxComboBox,
|
19
|
+
wxStaticText,
|
20
|
+
)
|
21
|
+
from meerk40t.kernel import signal_listener
|
22
|
+
from meerk40t.svgelements import Color
|
23
|
+
from meerk40t.tools.geomstr import Geomstr
|
24
|
+
|
25
|
+
_ = wx.GetTranslation
|
26
|
+
|
27
|
+
|
28
|
+
class PlacementPanel(wx.Panel):
|
29
|
+
"""
|
30
|
+
Display and Editing of the properties of 'place current', 'place point'
|
31
|
+
"""
|
32
|
+
|
33
|
+
def __init__(self, *args, context=None, node=None, **kwds):
|
34
|
+
# begin wxGlade: LayerSettingPanel.__init__
|
35
|
+
kwds["style"] = kwds.get("style", 0)
|
36
|
+
wx.Panel.__init__(self, *args, **kwds)
|
37
|
+
self.context = context
|
38
|
+
self.context.themes.set_window_colors(self)
|
39
|
+
self.operation = node
|
40
|
+
main_sizer = wx.BoxSizer(wx.VERTICAL)
|
41
|
+
self.SetHelpText("placement")
|
42
|
+
|
43
|
+
prop_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
44
|
+
first_sizer = StaticBoxSizer(self, wx.ID_ANY, "", wx.HORIZONTAL)
|
45
|
+
self.checkbox_output = wxCheckBox(self, wx.ID_ANY, _("Enable"))
|
46
|
+
self.checkbox_output.SetToolTip(
|
47
|
+
_("Enable this operation for inclusion in Execute Job.")
|
48
|
+
)
|
49
|
+
self.checkbox_output.SetValue(1)
|
50
|
+
first_sizer.Add(self.checkbox_output, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
51
|
+
info_loops = wxStaticText(self, wx.ID_ANY, _("Loops:"))
|
52
|
+
self.text_loops = TextCtrl(
|
53
|
+
self,
|
54
|
+
wx.ID_ANY,
|
55
|
+
"",
|
56
|
+
limited=True,
|
57
|
+
check="int",
|
58
|
+
style=wx.TE_PROCESS_ENTER,
|
59
|
+
)
|
60
|
+
self.text_loops.lower_limit = 1
|
61
|
+
self.loop_sizer = StaticBoxSizer(self, wx.ID_ANY, "", wx.HORIZONTAL)
|
62
|
+
self.loop_sizer.Add(info_loops, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
63
|
+
self.loop_sizer.Add(self.text_loops, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
64
|
+
self.text_loops.SetToolTip(_("Define how often this placement will be used"))
|
65
|
+
|
66
|
+
prop_sizer.Add(first_sizer, 1, wx.EXPAND, 0)
|
67
|
+
# prop_sizer.Add(self.loop_sizer, 1, wx.EXPAND, 0)
|
68
|
+
main_sizer.Add(prop_sizer, 0, 0, 0)
|
69
|
+
|
70
|
+
# X and Y
|
71
|
+
self.pos_sizer = StaticBoxSizer(self, wx.ID_ANY, _("Placement:"), wx.HORIZONTAL)
|
72
|
+
info_x = wxStaticText(self, wx.ID_ANY, _("X:"))
|
73
|
+
self.text_x = TextCtrl(
|
74
|
+
self,
|
75
|
+
wx.ID_ANY,
|
76
|
+
"",
|
77
|
+
limited=True,
|
78
|
+
check="length",
|
79
|
+
style=wx.TE_PROCESS_ENTER,
|
80
|
+
)
|
81
|
+
self.text_x.SetToolTip(_("X-Coordinate of placement"))
|
82
|
+
info_y = wxStaticText(self, wx.ID_ANY, _("Y:"))
|
83
|
+
self.text_y = TextCtrl(
|
84
|
+
self,
|
85
|
+
wx.ID_ANY,
|
86
|
+
"",
|
87
|
+
limited=True,
|
88
|
+
check="length",
|
89
|
+
style=wx.TE_PROCESS_ENTER,
|
90
|
+
)
|
91
|
+
self.text_y.SetToolTip(_("Y-Coordinate of placement"))
|
92
|
+
self.pos_sizer.Add(info_x, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
93
|
+
self.pos_sizer.Add(self.text_x, 1, wx.EXPAND, 0)
|
94
|
+
self.pos_sizer.Add(info_y, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
95
|
+
self.pos_sizer.Add(self.text_y, 1, wx.EXPAND, 0)
|
96
|
+
|
97
|
+
# Rotation
|
98
|
+
self.rot_sizer = StaticBoxSizer(self, wx.ID_ANY, _("Rotation:"), wx.HORIZONTAL)
|
99
|
+
self.text_rot = TextCtrl(
|
100
|
+
self,
|
101
|
+
wx.ID_ANY,
|
102
|
+
"",
|
103
|
+
limited=True,
|
104
|
+
check="angle",
|
105
|
+
style=wx.TE_PROCESS_ENTER,
|
106
|
+
)
|
107
|
+
self.rot_sizer.Add(self.text_rot, 1, wx.EXPAND, 0)
|
108
|
+
self.slider_angle = wx.Slider(self, wx.ID_ANY, 0, 0, 360)
|
109
|
+
self.rot_sizer.Add(self.slider_angle, 3, wx.EXPAND, 0)
|
110
|
+
ttip = _(
|
111
|
+
"The to be plotted elements can be rotated around the defined coordinate"
|
112
|
+
)
|
113
|
+
self.text_rot.SetToolTip(ttip)
|
114
|
+
self.slider_angle.SetToolTip(ttip)
|
115
|
+
|
116
|
+
pos_rot_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
117
|
+
pos_rot_sizer.Add(self.pos_sizer, 1, wx.EXPAND, 0)
|
118
|
+
pos_rot_sizer.Add(self.rot_sizer, 1, wx.EXPAND, 0)
|
119
|
+
main_sizer.Add(pos_rot_sizer, 0, wx.EXPAND, 0)
|
120
|
+
|
121
|
+
self.grid_sizer_1 = StaticBoxSizer(
|
122
|
+
self, wx.ID_ANY, _("Repetitions in X-direction"), wx.HORIZONTAL
|
123
|
+
)
|
124
|
+
info_x1 = wxStaticText(self, wx.ID_ANY, _("Repeats:"))
|
125
|
+
self.text_repeats_x = TextCtrl(
|
126
|
+
self,
|
127
|
+
wx.ID_ANY,
|
128
|
+
"",
|
129
|
+
limited=True,
|
130
|
+
check="int",
|
131
|
+
style=wx.TE_PROCESS_ENTER,
|
132
|
+
)
|
133
|
+
self.text_repeats_x.lower_limit = 0
|
134
|
+
info_x2 = wxStaticText(self, wx.ID_ANY, _("Gap:"))
|
135
|
+
self.text_gap_x = TextCtrl(
|
136
|
+
self,
|
137
|
+
wx.ID_ANY,
|
138
|
+
"",
|
139
|
+
limited=True,
|
140
|
+
check="length",
|
141
|
+
style=wx.TE_PROCESS_ENTER,
|
142
|
+
)
|
143
|
+
self.text_gap_x.SetToolTip(_("Gap in X-direction"))
|
144
|
+
self.grid_sizer_1.Add(info_x1, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
145
|
+
self.grid_sizer_1.Add(self.text_repeats_x, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
146
|
+
self.grid_sizer_1.Add(info_x2, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
147
|
+
self.grid_sizer_1.Add(self.text_gap_x, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
148
|
+
|
149
|
+
self.grid_sizer_2 = StaticBoxSizer(
|
150
|
+
self, wx.ID_ANY, _("Repetitions in Y-direction"), wx.HORIZONTAL
|
151
|
+
)
|
152
|
+
info_y1 = wxStaticText(self, wx.ID_ANY, _("Repeats:"))
|
153
|
+
self.text_repeats_y = TextCtrl(
|
154
|
+
self,
|
155
|
+
wx.ID_ANY,
|
156
|
+
"",
|
157
|
+
limited=True,
|
158
|
+
check="int",
|
159
|
+
style=wx.TE_PROCESS_ENTER,
|
160
|
+
)
|
161
|
+
self.text_repeats_y.lower_limit = 0
|
162
|
+
info_y2 = wxStaticText(self, wx.ID_ANY, _("Gap:"))
|
163
|
+
self.text_gap_y = TextCtrl(
|
164
|
+
self,
|
165
|
+
wx.ID_ANY,
|
166
|
+
"",
|
167
|
+
limited=True,
|
168
|
+
check="length",
|
169
|
+
style=wx.TE_PROCESS_ENTER,
|
170
|
+
)
|
171
|
+
self.text_repeats_x.SetToolTip(
|
172
|
+
_("How many repetitions in X-direction?\n0 = As many as possible")
|
173
|
+
)
|
174
|
+
self.text_repeats_y.SetToolTip(
|
175
|
+
_("How many repetitions in Y-direction?\n0 = As many as possible")
|
176
|
+
)
|
177
|
+
self.text_gap_x.SetToolTip(_("Gap between placements in X-direction"))
|
178
|
+
self.text_gap_y.SetToolTip(_("Gap between placements in Y-direction"))
|
179
|
+
self.grid_sizer_2.Add(info_y1, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
180
|
+
self.grid_sizer_2.Add(self.text_repeats_y, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
181
|
+
self.grid_sizer_2.Add(info_y2, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
182
|
+
self.grid_sizer_2.Add(self.text_gap_y, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
183
|
+
|
184
|
+
self.grid_sizer_3 = StaticBoxSizer(
|
185
|
+
self, wx.ID_ANY, _("Selection"), wx.HORIZONTAL
|
186
|
+
)
|
187
|
+
info_y1 = wxStaticText(self, wx.ID_ANY, _("Start-Index:"))
|
188
|
+
self.text_start_idx = TextCtrl(
|
189
|
+
self,
|
190
|
+
wx.ID_ANY,
|
191
|
+
"",
|
192
|
+
limited=True,
|
193
|
+
check="int",
|
194
|
+
style=wx.TE_PROCESS_ENTER,
|
195
|
+
)
|
196
|
+
self.text_start_idx.lower_limit = 0
|
197
|
+
info_y2 = wxStaticText(self, wx.ID_ANY, _("Count:"))
|
198
|
+
self.text_repetitions = TextCtrl(
|
199
|
+
self,
|
200
|
+
wx.ID_ANY,
|
201
|
+
"",
|
202
|
+
limited=True,
|
203
|
+
check="int",
|
204
|
+
style=wx.TE_PROCESS_ENTER,
|
205
|
+
)
|
206
|
+
self.text_start_idx.lower_limit = 0
|
207
|
+
self.text_start_idx.SetToolTip(_("First repetition to use"))
|
208
|
+
self.text_repetitions.SetToolTip(_("Repetitions to use (0=all)"))
|
209
|
+
self.grid_sizer_3.Add(info_y1, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
210
|
+
self.grid_sizer_3.Add(self.text_start_idx, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
211
|
+
self.grid_sizer_3.Add(info_y2, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
212
|
+
self.grid_sizer_3.Add(self.text_repetitions, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
213
|
+
|
214
|
+
grid_sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
|
215
|
+
grid_sizer_1.Add(self.grid_sizer_1, 1, wx.EXPAND, 0)
|
216
|
+
grid_sizer_1.Add(self.grid_sizer_2, 1, wx.EXPAND, 0)
|
217
|
+
main_sizer.Add(grid_sizer_1, 0, wx.EXPAND, 0)
|
218
|
+
grid_sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
|
219
|
+
grid_sizer_2.Add(self.loop_sizer, 1, wx.EXPAND, 0)
|
220
|
+
grid_sizer_2.Add(self.grid_sizer_3, 1, wx.EXPAND, 0)
|
221
|
+
main_sizer.Add(grid_sizer_2, 0, wx.EXPAND, 0)
|
222
|
+
self.text_alternating_x = TextCtrl(
|
223
|
+
self,
|
224
|
+
wx.ID_ANY,
|
225
|
+
"",
|
226
|
+
limited=True,
|
227
|
+
check="percent",
|
228
|
+
style=wx.TE_PROCESS_ENTER,
|
229
|
+
)
|
230
|
+
self.text_alternating_y = TextCtrl(
|
231
|
+
self,
|
232
|
+
wx.ID_ANY,
|
233
|
+
"",
|
234
|
+
limited=True,
|
235
|
+
check="percent",
|
236
|
+
style=wx.TE_PROCESS_ENTER,
|
237
|
+
)
|
238
|
+
self.slider_alternating_x = wx.Slider(self, wx.ID_ANY, 0, -200, 200)
|
239
|
+
self.slider_alternating_y = wx.Slider(self, wx.ID_ANY, 0, -200, 200)
|
240
|
+
ttip = _(
|
241
|
+
"Every other {area} can be displaced by a percentage of the gap in {direction}-direction\n"
|
242
|
+
+ "Useful for honeycomb- or other irregular patterns that need to overlap"
|
243
|
+
).format(area=_("column"), direction="X")
|
244
|
+
self.text_alternating_x.SetToolTip(ttip)
|
245
|
+
self.slider_alternating_x.SetToolTip(ttip)
|
246
|
+
self.check_alt_x = wxCheckBox(self, wx.ID_ANY)
|
247
|
+
ttip = _(
|
248
|
+
"Rotate elements every other {area}\n" + "Useful for triangular patterns."
|
249
|
+
).format(area=_("column"))
|
250
|
+
self.check_alt_x.SetToolTip(ttip)
|
251
|
+
ttip = _(
|
252
|
+
"Every other {area} can be displaced by a percentage of the gap in {direction}-direction\n"
|
253
|
+
+ "Useful for honeycomb- or other irregular patterns that need to overlap"
|
254
|
+
).format(area=_("row"), direction="Y")
|
255
|
+
self.text_alternating_y.SetToolTip(ttip)
|
256
|
+
self.slider_alternating_y.SetToolTip(ttip)
|
257
|
+
self.check_alt_y = wxCheckBox(self, wx.ID_ANY)
|
258
|
+
ttip = _(
|
259
|
+
"Rotate elements every other {area}\n" + "Useful for triangular patterns."
|
260
|
+
).format(area=_("row"))
|
261
|
+
self.check_alt_y.SetToolTip(ttip)
|
262
|
+
|
263
|
+
self.alt_x_sizer = StaticBoxSizer(
|
264
|
+
self, wx.ID_ANY, _("X-Displacement:"), wx.HORIZONTAL
|
265
|
+
)
|
266
|
+
self.alt_x_sizer.Add(self.text_alternating_x, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
267
|
+
self.alt_x_sizer.Add(self.slider_alternating_x, 3, wx.ALIGN_CENTER_VERTICAL, 0)
|
268
|
+
self.alt_x_sizer.Add(self.check_alt_x, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
269
|
+
self.alt_y_sizer = StaticBoxSizer(
|
270
|
+
self, wx.ID_ANY, _("Y-Displacement:"), wx.HORIZONTAL
|
271
|
+
)
|
272
|
+
self.alt_y_sizer.Add(self.text_alternating_y, 1, wx.EXPAND, 0)
|
273
|
+
self.alt_y_sizer.Add(self.slider_alternating_y, 3, wx.EXPAND, 0)
|
274
|
+
self.alt_y_sizer.Add(self.check_alt_y, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
275
|
+
alt_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
276
|
+
alt_sizer.Add(self.alt_x_sizer, 1, wx.EXPAND, 0)
|
277
|
+
alt_sizer.Add(self.alt_y_sizer, 1, wx.EXPAND, 0)
|
278
|
+
main_sizer.Add(alt_sizer, 0, wx.EXPAND, 0)
|
279
|
+
# Corner
|
280
|
+
|
281
|
+
self.corner_sizer = StaticBoxSizer(
|
282
|
+
self, wx.ID_ANY, _("Orientation:"), wx.HORIZONTAL
|
283
|
+
)
|
284
|
+
info_corner = wxStaticText(self, wx.ID_ANY, _("Corner:"))
|
285
|
+
self.combo_corner = wxComboBox(
|
286
|
+
self,
|
287
|
+
wx.ID_ANY,
|
288
|
+
choices=[
|
289
|
+
_("Top-Left"),
|
290
|
+
_("Top-Right"),
|
291
|
+
_("Bottom-Right"),
|
292
|
+
_("Bottom-Left"),
|
293
|
+
_("Center"),
|
294
|
+
],
|
295
|
+
style=wx.CB_DROPDOWN | wx.CB_READONLY,
|
296
|
+
)
|
297
|
+
self.combo_corner.SetToolTip(
|
298
|
+
_(
|
299
|
+
"The corner type establishes the placement of the bounding box\n"
|
300
|
+
+ "of to be plotted elements against the defined coordinate"
|
301
|
+
)
|
302
|
+
)
|
303
|
+
self.corner_sizer.Add(info_corner, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
304
|
+
self.corner_sizer.Add(self.combo_corner, 1, wx.EXPAND, 0)
|
305
|
+
info_orientation = wxStaticText(self, wx.ID_ANY, _("Orientation:"))
|
306
|
+
self.combo_orientation = wxComboBox(
|
307
|
+
self,
|
308
|
+
wx.ID_ANY,
|
309
|
+
choices=[
|
310
|
+
_("L2R (unidirectional)"),
|
311
|
+
_("L2R (bidirectional)"),
|
312
|
+
_("T2B (bidirectional)"),
|
313
|
+
],
|
314
|
+
style=wx.CB_DROPDOWN | wx.CB_READONLY,
|
315
|
+
)
|
316
|
+
self.combo_orientation.SetToolTip(
|
317
|
+
_("Orientation defines the sequence of placement points")
|
318
|
+
+ "\n"
|
319
|
+
+ _("Left to right (unidirectional)")
|
320
|
+
+ "\n"
|
321
|
+
+ _("Left to right (bidirectional)")
|
322
|
+
+ "\n"
|
323
|
+
+ _("Top to bottom (bidirectional)")
|
324
|
+
)
|
325
|
+
|
326
|
+
self.corner_sizer.Add(info_orientation, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
327
|
+
self.corner_sizer.Add(self.combo_orientation, 1, wx.EXPAND, 0)
|
328
|
+
main_sizer.Add(self.corner_sizer, 0, wx.EXPAND, 0)
|
329
|
+
|
330
|
+
main_sizer.AddSpacer(25)
|
331
|
+
self.helper_sizer = StaticBoxSizer(
|
332
|
+
self, wx.ID_ANY, _("Grid Helper (Tiling):"), wx.HORIZONTAL
|
333
|
+
)
|
334
|
+
|
335
|
+
info1 = wxStaticText(self, wx.ID_ANY, _("Shape"))
|
336
|
+
self.shape_information = (
|
337
|
+
(_("Quadratic"), _("Side"), self.generate_quadratic),
|
338
|
+
(_("Hexagon"), _("Side"), self.generate_hexagon),
|
339
|
+
(_("Circular"), _("Diameter"), self.generate_circular),
|
340
|
+
(_("Triangular"), _("Side"), self.generate_triangular),
|
341
|
+
)
|
342
|
+
choices = [e[0] for e in self.shape_information]
|
343
|
+
|
344
|
+
self.combo_shape = wxComboBox(
|
345
|
+
self, wx.ID_ANY, choices=choices, style=wx.CB_DROPDOWN | wx.CB_READONLY
|
346
|
+
)
|
347
|
+
ttip = _("Please provide some data about the intended tiling")
|
348
|
+
self.combo_shape.SetToolTip(ttip)
|
349
|
+
|
350
|
+
self.dimension_info = wxStaticText(self, wx.ID_ANY, _("Dimension"))
|
351
|
+
self.text_dimension = TextCtrl(self, wx.ID_ANY, limited=True, check="length")
|
352
|
+
self.text_dimension.SetToolTip(ttip)
|
353
|
+
|
354
|
+
self.btn_generate = wxButton(self, wx.ID_ANY, _("Define"))
|
355
|
+
self.btn_generate.SetToolTip(
|
356
|
+
_("Establishes the parameter for the selected grid-type")
|
357
|
+
)
|
358
|
+
self.check_generate = wxCheckBox(self, wx.ID_ANY)
|
359
|
+
self.check_generate.SetToolTip(
|
360
|
+
_("If set then Define will create a matching pattern too")
|
361
|
+
)
|
362
|
+
self.helper_sizer.Add(info1, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
363
|
+
self.helper_sizer.Add(self.combo_shape, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
364
|
+
self.helper_sizer.Add(self.dimension_info, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
365
|
+
self.helper_sizer.Add(self.text_dimension, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
366
|
+
self.helper_sizer.Add(self.btn_generate, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
367
|
+
self.helper_sizer.Add(self.check_generate, 0, wx.ALIGN_CENTER_VERTICAL, 0)
|
368
|
+
|
369
|
+
main_sizer.Add(self.helper_sizer, 0, wx.EXPAND, 0)
|
370
|
+
|
371
|
+
self.info_label = wxStaticText(self, wx.ID_ANY)
|
372
|
+
self.info_label.SetFont(
|
373
|
+
wx.Font(
|
374
|
+
8, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL
|
375
|
+
)
|
376
|
+
)
|
377
|
+
main_sizer.Add(self.info_label, 1, wx.EXPAND, 0)
|
378
|
+
|
379
|
+
self.combo_shape.SetSelection(0)
|
380
|
+
self.on_combo_shape(None)
|
381
|
+
self.SetSizer(main_sizer)
|
382
|
+
self.Layout()
|
383
|
+
|
384
|
+
self.Bind(wx.EVT_COMBOBOX, self.on_combo_corner, self.combo_corner)
|
385
|
+
self.Bind(wx.EVT_COMBOBOX, self.on_combo_orientation, self.combo_orientation)
|
386
|
+
self.Bind(wx.EVT_COMBOBOX, self.on_combo_shape, self.combo_shape)
|
387
|
+
self.Bind(wx.EVT_CHECKBOX, self.on_check_output, self.checkbox_output)
|
388
|
+
self.Bind(wx.EVT_CHECKBOX, self.on_check_alternate_x, self.check_alt_x)
|
389
|
+
self.Bind(wx.EVT_CHECKBOX, self.on_check_alternate_y, self.check_alt_y)
|
390
|
+
self.text_rot.SetActionRoutine(self.on_text_rot)
|
391
|
+
self.text_alternating_x.SetActionRoutine(self.on_text_alternating_x)
|
392
|
+
self.text_alternating_y.SetActionRoutine(self.on_text_alternating_y)
|
393
|
+
self.text_repeats_x.SetActionRoutine(self.on_text_nx)
|
394
|
+
self.text_repeats_y.SetActionRoutine(self.on_text_ny)
|
395
|
+
self.text_x.SetActionRoutine(self.on_text_x)
|
396
|
+
self.text_y.SetActionRoutine(self.on_text_y)
|
397
|
+
self.text_gap_x.SetActionRoutine(self.on_text_dx)
|
398
|
+
self.text_gap_y.SetActionRoutine(self.on_text_dy)
|
399
|
+
self.text_loops.SetActionRoutine(self.on_text_loops)
|
400
|
+
self.text_dimension.SetActionRoutine(self.on_dimension)
|
401
|
+
self.text_start_idx.SetActionRoutine(self.on_text_start_index)
|
402
|
+
self.text_repetitions.SetActionRoutine(self.on_text_repetitions)
|
403
|
+
self.btn_generate.Bind(wx.EVT_BUTTON, self.on_btn_generate)
|
404
|
+
self.Bind(wx.EVT_COMMAND_SCROLL, self.on_slider_angle, self.slider_angle)
|
405
|
+
self.Bind(
|
406
|
+
wx.EVT_COMMAND_SCROLL,
|
407
|
+
self.on_slider_alternating_x,
|
408
|
+
self.slider_alternating_x,
|
409
|
+
)
|
410
|
+
self.Bind(
|
411
|
+
wx.EVT_COMMAND_SCROLL,
|
412
|
+
self.on_slider_alternating_y,
|
413
|
+
self.slider_alternating_y,
|
414
|
+
)
|
415
|
+
|
416
|
+
def pane_hide(self):
|
417
|
+
pass
|
418
|
+
|
419
|
+
def pane_show(self):
|
420
|
+
pass
|
421
|
+
|
422
|
+
def accepts(self, node):
|
423
|
+
return node.type in (
|
424
|
+
"place current",
|
425
|
+
"place point",
|
426
|
+
)
|
427
|
+
|
428
|
+
def set_info_label(self):
|
429
|
+
if not self.operation:
|
430
|
+
self.info_label.SetLabel("")
|
431
|
+
return
|
432
|
+
if self.operation.start_index is None:
|
433
|
+
self.operation.start_index = 0
|
434
|
+
if self.operation.repetitions is None:
|
435
|
+
self.operation.repetitions = 0
|
436
|
+
label = ""
|
437
|
+
scene_width = self.context.device.view.unit_width
|
438
|
+
scene_height = self.context.device.view.unit_height
|
439
|
+
xloop = self.operation.nx
|
440
|
+
if xloop == 0: # as much as we can fit
|
441
|
+
if abs(self.operation.dx) < 1e-6:
|
442
|
+
xloop = 1
|
443
|
+
else:
|
444
|
+
x = self.operation.x
|
445
|
+
while x + self.operation.dx < scene_width:
|
446
|
+
x += self.operation.dx
|
447
|
+
xloop += 1
|
448
|
+
yloop = self.operation.ny
|
449
|
+
if yloop == 0: # as much as we can fit
|
450
|
+
if abs(self.operation.dy) < 1e-6:
|
451
|
+
yloop = 1
|
452
|
+
else:
|
453
|
+
y = self.operation.y
|
454
|
+
while y + self.operation.dy < scene_height:
|
455
|
+
y += self.operation.dy
|
456
|
+
yloop += 1
|
457
|
+
result = []
|
458
|
+
sorted_result = []
|
459
|
+
idx = 0
|
460
|
+
for ycount in range(yloop):
|
461
|
+
for xcount in range(xloop):
|
462
|
+
result.append(idx)
|
463
|
+
idx += 1
|
464
|
+
|
465
|
+
def idx_horizontal(row, col):
|
466
|
+
return row * xloop + col
|
467
|
+
|
468
|
+
def idx_vertical(col, row):
|
469
|
+
return row * xloop + col
|
470
|
+
|
471
|
+
if self.operation.orientation == 2:
|
472
|
+
max_outer = xloop
|
473
|
+
max_inner = yloop
|
474
|
+
func = idx_vertical
|
475
|
+
hither = True
|
476
|
+
elif self.operation.orientation == 1:
|
477
|
+
max_outer = yloop
|
478
|
+
max_inner = xloop
|
479
|
+
func = idx_horizontal
|
480
|
+
hither = True
|
481
|
+
else:
|
482
|
+
max_outer = yloop
|
483
|
+
max_inner = xloop
|
484
|
+
func = idx_horizontal
|
485
|
+
hither = False
|
486
|
+
p_idx = 0
|
487
|
+
p_count = 0
|
488
|
+
s_index = self.operation.start_index
|
489
|
+
if s_index is None:
|
490
|
+
s_index = 0
|
491
|
+
if s_index > max_outer * max_inner - 1:
|
492
|
+
s_index = max_outer * max_inner - 1
|
493
|
+
s_count = self.operation.repetitions
|
494
|
+
if s_count is None or s_count < 0:
|
495
|
+
s_count = 0
|
496
|
+
if s_count == 0:
|
497
|
+
s_count = max_inner * max_outer
|
498
|
+
|
499
|
+
for idx_outer in range(max_outer):
|
500
|
+
for idx_inner in range(max_inner):
|
501
|
+
if hither and idx_outer % 2 == 1:
|
502
|
+
sorted_idx = func(idx_outer, max_inner - 1 - idx_inner)
|
503
|
+
else:
|
504
|
+
sorted_idx = func(idx_outer, idx_inner)
|
505
|
+
# print (f"p_idx={p_idx}, p_count={p_count}, s_index={s_index}, s_count={s_count}")
|
506
|
+
if p_idx >= s_index and p_count < s_count:
|
507
|
+
sorted_result.append(result[sorted_idx])
|
508
|
+
p_count += 1
|
509
|
+
|
510
|
+
p_idx += 1
|
511
|
+
# print (result)
|
512
|
+
# print (sorted_result)
|
513
|
+
|
514
|
+
idx = 0
|
515
|
+
for ycount in range(yloop):
|
516
|
+
lbl = ""
|
517
|
+
for xcount in range(xloop):
|
518
|
+
if idx in sorted_result:
|
519
|
+
lbl += "X "
|
520
|
+
else:
|
521
|
+
lbl += "- "
|
522
|
+
|
523
|
+
idx += 1
|
524
|
+
label += lbl + "\n"
|
525
|
+
|
526
|
+
self.info_label.SetLabel(label)
|
527
|
+
|
528
|
+
def set_widgets(self, node):
|
529
|
+
def show_hide(sizer, flag):
|
530
|
+
sizer.ShowItems(flag)
|
531
|
+
sizer.Show(flag)
|
532
|
+
|
533
|
+
self.operation = node
|
534
|
+
if self.operation is None or not self.accepts(node):
|
535
|
+
self.Hide()
|
536
|
+
return
|
537
|
+
if hasattr(self.operation, "validate"):
|
538
|
+
self.operation.validate()
|
539
|
+
op = self.operation.type
|
540
|
+
is_current = bool(op == "place current")
|
541
|
+
if self.operation.output is not None:
|
542
|
+
self.checkbox_output.SetValue(self.operation.output)
|
543
|
+
if self.operation.output:
|
544
|
+
flag_enabled = True
|
545
|
+
else:
|
546
|
+
flag_enabled = False
|
547
|
+
self.text_rot.Enable(flag_enabled)
|
548
|
+
self.text_x.Enable(flag_enabled)
|
549
|
+
self.text_y.Enable(flag_enabled)
|
550
|
+
self.text_loops.Enable(flag_enabled)
|
551
|
+
self.slider_angle.Enable(flag_enabled)
|
552
|
+
self.slider_alternating_x.Enable(flag_enabled)
|
553
|
+
self.slider_alternating_y.Enable(flag_enabled)
|
554
|
+
self.slider_alternating_x.Enable(flag_enabled)
|
555
|
+
self.slider_alternating_y.Enable(flag_enabled)
|
556
|
+
self.check_alt_x.Enable(flag_enabled)
|
557
|
+
self.check_alt_y.Enable(flag_enabled)
|
558
|
+
self.text_gap_x.Enable(flag_enabled)
|
559
|
+
self.text_gap_y.Enable(flag_enabled)
|
560
|
+
self.text_repeats_x.Enable(flag_enabled)
|
561
|
+
self.text_repeats_y.Enable(flag_enabled)
|
562
|
+
|
563
|
+
show_hide(self.pos_sizer, not is_current)
|
564
|
+
show_hide(self.grid_sizer_1, not is_current)
|
565
|
+
show_hide(self.grid_sizer_2, not is_current)
|
566
|
+
show_hide(self.grid_sizer_3, not is_current)
|
567
|
+
show_hide(self.rot_sizer, not is_current)
|
568
|
+
show_hide(self.alt_x_sizer, not is_current)
|
569
|
+
show_hide(self.alt_y_sizer, not is_current)
|
570
|
+
show_hide(self.corner_sizer, not is_current)
|
571
|
+
show_hide(self.loop_sizer, not is_current)
|
572
|
+
show_hide(self.helper_sizer, not is_current)
|
573
|
+
if not is_current:
|
574
|
+
units = self.context.units_name
|
575
|
+
if units in ("inch", "inches"):
|
576
|
+
units = "in"
|
577
|
+
|
578
|
+
x = self.operation.x
|
579
|
+
if isinstance(x, str):
|
580
|
+
x = float(Length(x))
|
581
|
+
if x is None:
|
582
|
+
x = 0
|
583
|
+
y = self.operation.y
|
584
|
+
if isinstance(y, str):
|
585
|
+
y = float(Length(y))
|
586
|
+
if y is None:
|
587
|
+
y = 0
|
588
|
+
dx = self.operation.dx
|
589
|
+
if isinstance(dx, str):
|
590
|
+
dx = float(Length(dx))
|
591
|
+
if dx is None:
|
592
|
+
dx = 0
|
593
|
+
dy = self.operation.dy
|
594
|
+
if isinstance(dy, str):
|
595
|
+
dy = float(Length(dy))
|
596
|
+
if dy is None:
|
597
|
+
dy = 0
|
598
|
+
ang = self.operation.rotation
|
599
|
+
myang = Angle(ang, digits=2)
|
600
|
+
if ang is None:
|
601
|
+
ang = 0
|
602
|
+
loops = self.operation.loops
|
603
|
+
if loops is None:
|
604
|
+
loops = 1
|
605
|
+
fx = self.operation.alternate_rot_x
|
606
|
+
if isinstance(fx, str):
|
607
|
+
fx = bool(fx)
|
608
|
+
if fx is None:
|
609
|
+
fx = False
|
610
|
+
fy = self.operation.alternate_rot_y
|
611
|
+
if isinstance(fy, str):
|
612
|
+
fy = bool(fy)
|
613
|
+
if fy is None:
|
614
|
+
fy = False
|
615
|
+
self.check_alt_x.SetValue(fx)
|
616
|
+
self.check_alt_y.SetValue(fy)
|
617
|
+
set_ctrl_value(self.text_loops, str(loops))
|
618
|
+
reps = self.operation.repetitions
|
619
|
+
if reps is None:
|
620
|
+
reps = 0
|
621
|
+
set_ctrl_value(self.text_repetitions, str(reps))
|
622
|
+
s_idx = self.operation.start_index
|
623
|
+
if s_idx is None:
|
624
|
+
s_idx = 0
|
625
|
+
set_ctrl_value(self.text_start_idx, str(s_idx))
|
626
|
+
|
627
|
+
set_ctrl_value(self.text_loops, str(loops))
|
628
|
+
set_ctrl_value(self.text_repeats_x, str(self.operation.nx))
|
629
|
+
set_ctrl_value(self.text_repeats_y, str(self.operation.ny))
|
630
|
+
set_ctrl_value(
|
631
|
+
self.text_x,
|
632
|
+
f"{Length(amount=x, preferred_units=units, digits=4).preferred_length}",
|
633
|
+
)
|
634
|
+
set_ctrl_value(
|
635
|
+
self.text_y,
|
636
|
+
f"{Length(amount=y, preferred_units=units, digits=4).preferred_length}",
|
637
|
+
)
|
638
|
+
set_ctrl_value(
|
639
|
+
self.text_gap_x,
|
640
|
+
f"{Length(amount=dx, preferred_units=units, digits=4).preferred_length}",
|
641
|
+
)
|
642
|
+
set_ctrl_value(
|
643
|
+
self.text_gap_y,
|
644
|
+
f"{Length(amount=dy, preferred_units=units, digits=4).preferred_length}",
|
645
|
+
)
|
646
|
+
set_ctrl_value(self.text_rot, f"{myang.angle_degrees}")
|
647
|
+
try:
|
648
|
+
h_angle = myang.degrees
|
649
|
+
while h_angle > self.slider_angle.GetMax():
|
650
|
+
h_angle -= 360
|
651
|
+
while h_angle < self.slider_angle.GetMin():
|
652
|
+
h_angle += 360
|
653
|
+
self.slider_angle.SetValue(int(h_angle))
|
654
|
+
except ValueError:
|
655
|
+
pass
|
656
|
+
# print (self.operation.alternating_dx, type(self.operation.alternating_dx).__name__)
|
657
|
+
value = int(100.0 * self.operation.alternating_dx)
|
658
|
+
if value > 200:
|
659
|
+
value = 200
|
660
|
+
if value < -200:
|
661
|
+
value = -200
|
662
|
+
self.slider_alternating_x.SetValue(value)
|
663
|
+
self.text_alternating_x.SetValue(f"{value}%")
|
664
|
+
value = int(100.0 * self.operation.alternating_dy)
|
665
|
+
if value > 200:
|
666
|
+
value = 200
|
667
|
+
if value < -200:
|
668
|
+
value = -200
|
669
|
+
self.slider_alternating_y.SetValue(value)
|
670
|
+
self.text_alternating_y.SetValue(f"{value}%")
|
671
|
+
|
672
|
+
corner = max(min(self.operation.corner, 4), 0) # between 0 and 4
|
673
|
+
self.combo_corner.SetSelection(corner)
|
674
|
+
|
675
|
+
orientation = max(min(self.operation.orientation, 2), 0) # between 0 and 2
|
676
|
+
self.combo_orientation.SetSelection(orientation)
|
677
|
+
self.set_info_label()
|
678
|
+
|
679
|
+
self.Layout()
|
680
|
+
self.Show()
|
681
|
+
|
682
|
+
def on_text_rot(self):
|
683
|
+
if self.operation is None or not hasattr(self.operation, "rotation"):
|
684
|
+
return
|
685
|
+
try:
|
686
|
+
self.operation.rotation = Angle(self.text_rot.GetValue()).angle
|
687
|
+
self.updated()
|
688
|
+
except ValueError:
|
689
|
+
return
|
690
|
+
myang = Angle(self.operation.rotation)
|
691
|
+
try:
|
692
|
+
h_angle = myang.degrees
|
693
|
+
while h_angle > self.slider_angle.GetMax():
|
694
|
+
h_angle -= 360
|
695
|
+
while h_angle < self.slider_angle.GetMin():
|
696
|
+
h_angle += 360
|
697
|
+
self.slider_angle.SetValue(int(h_angle))
|
698
|
+
except ValueError:
|
699
|
+
pass
|
700
|
+
|
701
|
+
def on_slider_angle(self, event): # wxGlade: HatchSettingsPanel.<event_handler>
|
702
|
+
if self.operation is None or not hasattr(self.operation, "rotation"):
|
703
|
+
return
|
704
|
+
value = self.slider_angle.GetValue()
|
705
|
+
self.text_rot.SetValue(f"{value}deg")
|
706
|
+
self.on_text_rot()
|
707
|
+
|
708
|
+
def on_text_alternating_x(self):
|
709
|
+
if self.operation is None or not hasattr(self.operation, "alternating_dx"):
|
710
|
+
return
|
711
|
+
txt = self.text_alternating_x.GetValue().strip()
|
712
|
+
if not txt:
|
713
|
+
return
|
714
|
+
if txt.endswith("%"):
|
715
|
+
txt = txt[:-1]
|
716
|
+
try:
|
717
|
+
factor = float(txt) / 100.0
|
718
|
+
self.operation.alternating_dx = factor
|
719
|
+
self.updated()
|
720
|
+
except ValueError:
|
721
|
+
return
|
722
|
+
myval = self.operation.alternating_dx
|
723
|
+
if myval is None:
|
724
|
+
myval = 0
|
725
|
+
myval *= 100.0
|
726
|
+
self.slider_alternating_x.SetValue(int(myval))
|
727
|
+
|
728
|
+
def on_slider_alternating_x(self, event):
|
729
|
+
if self.operation is None or not hasattr(self.operation, "alternating_dx"):
|
730
|
+
return
|
731
|
+
value = self.slider_alternating_x.GetValue()
|
732
|
+
self.text_alternating_x.SetValue(f"{value}%")
|
733
|
+
self.on_text_alternating_x()
|
734
|
+
|
735
|
+
def on_text_alternating_y(self):
|
736
|
+
if self.operation is None or not hasattr(self.operation, "alternating_dy"):
|
737
|
+
return
|
738
|
+
txt = self.text_alternating_y.GetValue().strip()
|
739
|
+
if not txt:
|
740
|
+
return
|
741
|
+
if txt.endswith("%"):
|
742
|
+
txt = txt[:-1]
|
743
|
+
try:
|
744
|
+
factor = float(txt) / 100.0
|
745
|
+
self.operation.alternating_dy = factor
|
746
|
+
self.updated()
|
747
|
+
except ValueError:
|
748
|
+
return
|
749
|
+
myval = self.operation.alternating_dy
|
750
|
+
if myval is None:
|
751
|
+
myval = 0
|
752
|
+
myval *= 100.0
|
753
|
+
self.slider_alternating_y.SetValue(int(myval))
|
754
|
+
|
755
|
+
def on_slider_alternating_y(self, event):
|
756
|
+
if self.operation is None or not hasattr(self.operation, "alternating_dy"):
|
757
|
+
return
|
758
|
+
value = self.slider_alternating_y.GetValue()
|
759
|
+
self.text_alternating_y.SetValue(f"{value}%")
|
760
|
+
self.on_text_alternating_y()
|
761
|
+
|
762
|
+
def on_check_alternate_x(
|
763
|
+
self, event=None
|
764
|
+
): # wxGlade: OperationProperty.<event_handler>
|
765
|
+
f = bool(self.check_alt_x.GetValue())
|
766
|
+
if self.operation.alternate_rot_x != f:
|
767
|
+
self.operation.alternate_rot_x = f
|
768
|
+
self.context.elements.signal("element_property_update", self.operation)
|
769
|
+
|
770
|
+
def on_check_alternate_y(
|
771
|
+
self, event=None
|
772
|
+
): # wxGlade: OperationProperty.<event_handler>
|
773
|
+
f = bool(self.check_alt_y.GetValue())
|
774
|
+
if self.operation.alternate_rot_y != f:
|
775
|
+
self.operation.alternate_rot_y = f
|
776
|
+
self.context.elements.signal("element_property_update", self.operation)
|
777
|
+
|
778
|
+
def on_check_output(self, event=None): # wxGlade: OperationProperty.<event_handler>
|
779
|
+
if self.operation.output != bool(self.checkbox_output.GetValue()):
|
780
|
+
self.operation.output = bool(self.checkbox_output.GetValue())
|
781
|
+
self.context.elements.signal("element_property_update", self.operation)
|
782
|
+
flag = self.operation.output
|
783
|
+
self.text_x.Enable(flag)
|
784
|
+
self.text_y.Enable(flag)
|
785
|
+
self.text_rot.Enable(flag)
|
786
|
+
self.slider_angle.Enable(flag)
|
787
|
+
self.combo_corner.Enable(flag)
|
788
|
+
self.combo_orientation.Enable(flag)
|
789
|
+
|
790
|
+
def on_combo_corner(self, event):
|
791
|
+
if self.operation is None or not hasattr(self.operation, "corner"):
|
792
|
+
return
|
793
|
+
corner = self.combo_corner.GetSelection()
|
794
|
+
if corner < 0:
|
795
|
+
return
|
796
|
+
if self.operation.corner != corner:
|
797
|
+
self.operation.corner = corner
|
798
|
+
self.updated()
|
799
|
+
|
800
|
+
def on_combo_orientation(self, event):
|
801
|
+
if self.operation is None or not hasattr(self.operation, "orientation"):
|
802
|
+
return
|
803
|
+
orientation = self.combo_orientation.GetSelection()
|
804
|
+
if orientation < 0:
|
805
|
+
return
|
806
|
+
if self.operation.orientation != orientation:
|
807
|
+
self.operation.orientation = orientation
|
808
|
+
self.updated()
|
809
|
+
|
810
|
+
def on_text_x(self):
|
811
|
+
if self.operation is None or not hasattr(self.operation, "x"):
|
812
|
+
return
|
813
|
+
try:
|
814
|
+
x = float(Length(self.text_x.GetValue()))
|
815
|
+
except ValueError:
|
816
|
+
return
|
817
|
+
if self.operation.x != x:
|
818
|
+
self.operation.x = x
|
819
|
+
self.updated()
|
820
|
+
|
821
|
+
def on_text_dx(self):
|
822
|
+
if self.operation is None or not hasattr(self.operation, "dx"):
|
823
|
+
return
|
824
|
+
try:
|
825
|
+
x = float(Length(self.text_gap_x.GetValue()))
|
826
|
+
except ValueError:
|
827
|
+
return
|
828
|
+
if self.operation.dx != x:
|
829
|
+
self.operation.dx = x
|
830
|
+
self.updated()
|
831
|
+
|
832
|
+
def on_text_y(self):
|
833
|
+
if self.operation is None or not hasattr(self.operation, "y"):
|
834
|
+
return
|
835
|
+
try:
|
836
|
+
y = float(Length(self.text_y.GetValue()))
|
837
|
+
except ValueError:
|
838
|
+
return
|
839
|
+
if self.operation.y != y:
|
840
|
+
self.operation.y = y
|
841
|
+
self.updated()
|
842
|
+
|
843
|
+
def on_text_dy(self):
|
844
|
+
if self.operation is None or not hasattr(self.operation, "dy"):
|
845
|
+
return
|
846
|
+
try:
|
847
|
+
y = float(Length(self.text_gap_y.GetValue()))
|
848
|
+
except ValueError:
|
849
|
+
return
|
850
|
+
if self.operation.dy != y:
|
851
|
+
self.operation.dy = y
|
852
|
+
self.updated()
|
853
|
+
|
854
|
+
def on_text_loops(self):
|
855
|
+
if self.operation is None or not hasattr(self.operation, "loops"):
|
856
|
+
return
|
857
|
+
try:
|
858
|
+
loops = int(self.text_loops.GetValue())
|
859
|
+
if loops < 1:
|
860
|
+
loops = 1
|
861
|
+
except ValueError:
|
862
|
+
return
|
863
|
+
if self.operation.loops != loops:
|
864
|
+
self.operation.loops = loops
|
865
|
+
self.updated()
|
866
|
+
|
867
|
+
def on_text_nx(self):
|
868
|
+
if self.operation is None or not hasattr(self.operation, "nx"):
|
869
|
+
return
|
870
|
+
try:
|
871
|
+
nx = int(self.text_repeats_x.GetValue())
|
872
|
+
if nx < 0:
|
873
|
+
nx = 0
|
874
|
+
except ValueError:
|
875
|
+
return
|
876
|
+
if self.operation.nx != nx:
|
877
|
+
self.operation.nx = nx
|
878
|
+
self.set_info_label()
|
879
|
+
self.updated()
|
880
|
+
|
881
|
+
def on_text_ny(self):
|
882
|
+
if self.operation is None or not hasattr(self.operation, "ny"):
|
883
|
+
return
|
884
|
+
try:
|
885
|
+
ny = int(self.text_repeats_y.GetValue())
|
886
|
+
if ny < 0:
|
887
|
+
ny = 0
|
888
|
+
except ValueError:
|
889
|
+
return
|
890
|
+
if self.operation.ny != ny:
|
891
|
+
self.operation.ny = ny
|
892
|
+
self.set_info_label()
|
893
|
+
self.updated()
|
894
|
+
|
895
|
+
def on_text_start_index(self):
|
896
|
+
if self.operation is None or not hasattr(self.operation, "start_index"):
|
897
|
+
return
|
898
|
+
try:
|
899
|
+
start = int(self.text_start_idx.GetValue())
|
900
|
+
except ValueError:
|
901
|
+
return
|
902
|
+
if self.operation.start_index != start:
|
903
|
+
self.operation.start_index = start
|
904
|
+
self.set_info_label()
|
905
|
+
self.updated()
|
906
|
+
|
907
|
+
def on_text_repetitions(self):
|
908
|
+
if self.operation is None or not hasattr(self.operation, "repetitions"):
|
909
|
+
return
|
910
|
+
try:
|
911
|
+
start = int(self.text_repetitions.GetValue())
|
912
|
+
except ValueError:
|
913
|
+
return
|
914
|
+
if self.operation.repetitions != start:
|
915
|
+
self.operation.repetitions = start
|
916
|
+
self.set_info_label()
|
917
|
+
self.updated()
|
918
|
+
|
919
|
+
def generate_quadratic(self, dimension, sx, sy):
|
920
|
+
scene_width = self.context.device.view.width
|
921
|
+
scene_height = self.context.device.view.height
|
922
|
+
x = sx
|
923
|
+
y = sy
|
924
|
+
nx = 0
|
925
|
+
ny = 0
|
926
|
+
dx = dimension
|
927
|
+
dy = dimension
|
928
|
+
alt_x = 0
|
929
|
+
alt_y = 0
|
930
|
+
flag_x = False
|
931
|
+
flag_y = False
|
932
|
+
geom = Geomstr.rect(sx, sy, dimension, dimension)
|
933
|
+
# points = (
|
934
|
+
# sx + 1j * sy,
|
935
|
+
# sx + dimension + 1j * sy,
|
936
|
+
# sx + dimension + 1j * (sy + dimension),
|
937
|
+
# sx + 1j * (sy + dimension),
|
938
|
+
# sx + 1j * sy,
|
939
|
+
# )
|
940
|
+
# geom.polyline(points)
|
941
|
+
# geom.end()
|
942
|
+
while x + dimension <= scene_width:
|
943
|
+
x += dimension
|
944
|
+
nx += 1
|
945
|
+
while y + dimension <= scene_height:
|
946
|
+
y += dimension
|
947
|
+
ny += 1
|
948
|
+
if nx == 0:
|
949
|
+
nx = 1
|
950
|
+
if ny == 0:
|
951
|
+
ny = 1
|
952
|
+
return nx, ny, dx, dy, alt_x, alt_y, flag_x, flag_y, geom
|
953
|
+
|
954
|
+
def generate_triangular(self, dimension, sx, sy):
|
955
|
+
scene_width = self.context.device.view.width
|
956
|
+
scene_height = self.context.device.view.height
|
957
|
+
x = sx
|
958
|
+
y = sy
|
959
|
+
nx = 0
|
960
|
+
ny = 0
|
961
|
+
dx = 0.5 * dimension
|
962
|
+
dy = 0.5 * math.sqrt(3) * dimension
|
963
|
+
alt_x = 0
|
964
|
+
alt_y = 0
|
965
|
+
flag_x = True
|
966
|
+
flag_y = False
|
967
|
+
|
968
|
+
geom = Geomstr()
|
969
|
+
points = (
|
970
|
+
sx + 1j * (sy + dy),
|
971
|
+
sx + dimension + 1j * (sy + dy),
|
972
|
+
sx + 0.5 * dimension + 1j * sy,
|
973
|
+
sx + 1j * (sy + dy),
|
974
|
+
)
|
975
|
+
geom.polyline(points)
|
976
|
+
geom.end()
|
977
|
+
|
978
|
+
while x + dimension <= scene_width:
|
979
|
+
x += dx
|
980
|
+
nx += 1
|
981
|
+
while y + dimension <= scene_height:
|
982
|
+
y += dy
|
983
|
+
ny += 1
|
984
|
+
if nx == 0:
|
985
|
+
nx = 1
|
986
|
+
if ny == 0:
|
987
|
+
ny = 1
|
988
|
+
return nx, ny, dx, dy, alt_x, alt_y, flag_x, flag_y, geom
|
989
|
+
|
990
|
+
def generate_circular(self, dimension, sx, sy):
|
991
|
+
scene_width = self.context.device.view.width
|
992
|
+
scene_height = self.context.device.view.height
|
993
|
+
x = sx
|
994
|
+
y = sy
|
995
|
+
nx = 0
|
996
|
+
ny = 0
|
997
|
+
radius = dimension / 2.0
|
998
|
+
# cos(30°) * d
|
999
|
+
dx = math.cos(math.tau / 12) * dimension
|
1000
|
+
dy = dimension
|
1001
|
+
alt_x = 0
|
1002
|
+
alt_y = 0.5
|
1003
|
+
flag_x = False
|
1004
|
+
flag_y = False
|
1005
|
+
|
1006
|
+
geom = Geomstr.circle(radius, sx + radius, sy + radius, slices=4)
|
1007
|
+
while x + dimension <= scene_width:
|
1008
|
+
x += dx
|
1009
|
+
nx += 1
|
1010
|
+
|
1011
|
+
while y + dimension + radius <= scene_height:
|
1012
|
+
y += dy
|
1013
|
+
ny += 1
|
1014
|
+
|
1015
|
+
if nx == 0:
|
1016
|
+
nx = 1
|
1017
|
+
if ny == 0:
|
1018
|
+
ny = 1
|
1019
|
+
return nx, ny, dx, dy, alt_x, alt_y, flag_x, flag_y, geom
|
1020
|
+
|
1021
|
+
def generate_hexagon(self, dimension, sx, sy):
|
1022
|
+
scene_width = self.context.device.view.width
|
1023
|
+
scene_height = self.context.device.view.height
|
1024
|
+
dim_x = 2 * dimension
|
1025
|
+
dim_y = math.sqrt(3) * dimension
|
1026
|
+
x = sx
|
1027
|
+
y = sy
|
1028
|
+
nx = 0
|
1029
|
+
ny = 0
|
1030
|
+
flag_x = False
|
1031
|
+
flag_y = False
|
1032
|
+
|
1033
|
+
geom = Geomstr()
|
1034
|
+
points = (
|
1035
|
+
sx + 0.5 * dimension + 1j * sy,
|
1036
|
+
sx + 1.5 * dimension + 1j * sy,
|
1037
|
+
sx + 2 * dimension + 1j * (sy + 0.5 * dim_y),
|
1038
|
+
sx + 1.5 * dimension + 1j * (sy + dim_y),
|
1039
|
+
sx + 0.5 * dimension + 1j * (sy + dim_y),
|
1040
|
+
sx + 1j * (sy + 0.5 * dim_y),
|
1041
|
+
sx + 0.5 * dimension + 1j * sy,
|
1042
|
+
)
|
1043
|
+
geom.polyline(points)
|
1044
|
+
geom.end()
|
1045
|
+
|
1046
|
+
dx = 1.5 * dimension
|
1047
|
+
dy = math.sqrt(3.0) * dimension
|
1048
|
+
alt_x = 0
|
1049
|
+
alt_y = 0.5
|
1050
|
+
while x + dim_x <= scene_width:
|
1051
|
+
x += dx
|
1052
|
+
nx += 1
|
1053
|
+
while y + dim_y <= scene_height:
|
1054
|
+
y += dy
|
1055
|
+
ny += 1
|
1056
|
+
if nx == 0:
|
1057
|
+
nx = 1
|
1058
|
+
if ny == 0:
|
1059
|
+
ny = 1
|
1060
|
+
|
1061
|
+
return nx, ny, dx, dy, alt_x, alt_y, flag_x, flag_y, geom
|
1062
|
+
|
1063
|
+
def validate_tesselation(self):
|
1064
|
+
flag = True
|
1065
|
+
idx = self.combo_shape.GetSelection()
|
1066
|
+
if idx < 0:
|
1067
|
+
flag = False
|
1068
|
+
s = self.text_dimension.GetValue()
|
1069
|
+
if s:
|
1070
|
+
# try:
|
1071
|
+
# val = float(Length(s))
|
1072
|
+
# except ValueError:
|
1073
|
+
# val = 0
|
1074
|
+
if flag <= 0:
|
1075
|
+
flag = False
|
1076
|
+
else:
|
1077
|
+
flag = False
|
1078
|
+
self.btn_generate.Enable(flag)
|
1079
|
+
|
1080
|
+
def on_combo_shape(self, event):
|
1081
|
+
idx = self.combo_shape.GetSelection()
|
1082
|
+
if idx < 0:
|
1083
|
+
s = _("Dimension")
|
1084
|
+
else:
|
1085
|
+
s = self.shape_information[idx][1]
|
1086
|
+
self.dimension_info.SetLabel(s)
|
1087
|
+
self.Layout()
|
1088
|
+
self.validate_tesselation()
|
1089
|
+
|
1090
|
+
def on_dimension(self, *args):
|
1091
|
+
self.validate_tesselation()
|
1092
|
+
|
1093
|
+
def on_btn_generate(self, event):
|
1094
|
+
if self.operation is None or not hasattr(self.operation, "x"):
|
1095
|
+
return
|
1096
|
+
shape = self.combo_shape.GetSelection()
|
1097
|
+
if shape < 0:
|
1098
|
+
return
|
1099
|
+
s_dimen = self.text_dimension.GetValue()
|
1100
|
+
if s_dimen == "":
|
1101
|
+
return
|
1102
|
+
try:
|
1103
|
+
dimens = float(Length(s_dimen))
|
1104
|
+
if dimens == 0:
|
1105
|
+
return
|
1106
|
+
except ValueError:
|
1107
|
+
return
|
1108
|
+
try:
|
1109
|
+
sx = float(Length(self.text_x.GetValue()))
|
1110
|
+
sy = float(Length(self.text_y.GetValue()))
|
1111
|
+
except ValueError:
|
1112
|
+
return
|
1113
|
+
function = self.shape_information[shape][2]
|
1114
|
+
nx, ny, dx, dy, alt_x, alt_y, flag_x, flag_y, geom = function(dimens, sx, sy)
|
1115
|
+
self.operation.x = sx
|
1116
|
+
self.operation.y = sy
|
1117
|
+
self.operation.nx = nx
|
1118
|
+
self.operation.ny = ny
|
1119
|
+
self.operation.dx = dx
|
1120
|
+
self.operation.dy = dy
|
1121
|
+
self.operation.alternating_dx = alt_x
|
1122
|
+
self.operation.alternating_dy = alt_y
|
1123
|
+
self.operation.alternate_rot_x = flag_x
|
1124
|
+
self.operation.alternate_rot_y = flag_y
|
1125
|
+
self.operation.corner = 0
|
1126
|
+
self.operation.rotation = 0
|
1127
|
+
self.updated()
|
1128
|
+
if self.check_generate.GetValue() and geom is not None:
|
1129
|
+
# _("Create template")
|
1130
|
+
with self.context.elements.undoscope("Create template"):
|
1131
|
+
node = self.context.elements.elem_branch.add(
|
1132
|
+
type="elem path",
|
1133
|
+
geometry=geom,
|
1134
|
+
stroke=Color("blue"),
|
1135
|
+
stroke_width=1000,
|
1136
|
+
label="Template",
|
1137
|
+
)
|
1138
|
+
data = [node]
|
1139
|
+
if self.context.elements.classify_new:
|
1140
|
+
self.context.elements.classify(data)
|
1141
|
+
self.context.root.signal("refresh_scene", "Scene")
|
1142
|
+
|
1143
|
+
def updated(self):
|
1144
|
+
self.context.elements.signal("element_property_reload", self.operation)
|
1145
|
+
self.context.elements.signal("refresh_scene", "Scene")
|
1146
|
+
|
1147
|
+
|
1148
|
+
class PlacementParameterPanel(ScrolledPanel):
|
1149
|
+
name = _("Properties")
|
1150
|
+
priority = -1
|
1151
|
+
|
1152
|
+
def __init__(self, *args, context=None, node=None, **kwds):
|
1153
|
+
# begin wxGlade: ParameterPanel.__init__
|
1154
|
+
kwds["style"] = kwds.get("style", 0)
|
1155
|
+
ScrolledPanel.__init__(self, *args, **kwds)
|
1156
|
+
self.context = context
|
1157
|
+
self.context.themes.set_window_colors(self)
|
1158
|
+
self.operation = node
|
1159
|
+
self.panels = []
|
1160
|
+
|
1161
|
+
param_sizer = wx.BoxSizer(wx.VERTICAL)
|
1162
|
+
|
1163
|
+
self.id_panel = IdPanel(
|
1164
|
+
self,
|
1165
|
+
wx.ID_ANY,
|
1166
|
+
context=context,
|
1167
|
+
node=node,
|
1168
|
+
showid=False,
|
1169
|
+
)
|
1170
|
+
param_sizer.Add(self.id_panel, 0, wx.EXPAND, 0)
|
1171
|
+
self.panels.append(self.id_panel)
|
1172
|
+
|
1173
|
+
self.place_panel = PlacementPanel(self, wx.ID_ANY, context=context, node=node)
|
1174
|
+
param_sizer.Add(self.place_panel, 0, wx.EXPAND, 0)
|
1175
|
+
self.panels.append(self.place_panel)
|
1176
|
+
|
1177
|
+
self.SetSizer(param_sizer)
|
1178
|
+
|
1179
|
+
self.Layout()
|
1180
|
+
# end wxGlade
|
1181
|
+
|
1182
|
+
@signal_listener("element_property_reload")
|
1183
|
+
def on_element_property_reload(self, origin=None, *args):
|
1184
|
+
# Is this something I should care about?
|
1185
|
+
# element_property_reload provides a list of nodes that are affected
|
1186
|
+
# if self.operation isn't one of them, then we just let it slip
|
1187
|
+
for_me = False
|
1188
|
+
if len(args) > 0:
|
1189
|
+
element = args[0]
|
1190
|
+
if isinstance(element, (tuple, list)):
|
1191
|
+
for node in element:
|
1192
|
+
if node == self.operation:
|
1193
|
+
for_me = True
|
1194
|
+
break
|
1195
|
+
elif self.operation == element:
|
1196
|
+
for_me = True
|
1197
|
+
if not for_me:
|
1198
|
+
return
|
1199
|
+
|
1200
|
+
self.set_widgets(self.operation)
|
1201
|
+
self.Layout()
|
1202
|
+
|
1203
|
+
def set_widgets(self, node):
|
1204
|
+
self.operation = node
|
1205
|
+
for panel in self.panels:
|
1206
|
+
panel.set_widgets(node)
|
1207
|
+
|
1208
|
+
def pane_hide(self):
|
1209
|
+
for panel in self.panels:
|
1210
|
+
panel.pane_hide()
|
1211
|
+
|
1212
|
+
def pane_show(self):
|
1213
|
+
for panel in self.panels:
|
1214
|
+
panel.pane_show()
|