meerk40t 0.9.7051__py2.py3-none-any.whl → 0.9.7910__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerk40t/balormk/controller.py +3 -3
- meerk40t/balormk/device.py +7 -0
- meerk40t/balormk/driver.py +23 -14
- meerk40t/balormk/galvo_commands.py +18 -3
- meerk40t/balormk/gui/balorconfig.py +6 -0
- meerk40t/balormk/livelightjob.py +36 -14
- meerk40t/camera/camera.py +1 -0
- meerk40t/camera/gui/camerapanel.py +154 -58
- meerk40t/camera/plugin.py +46 -5
- meerk40t/core/elements/branches.py +90 -20
- meerk40t/core/elements/elements.py +59 -37
- meerk40t/core/elements/trace.py +10 -6
- meerk40t/core/node/node.py +2 -0
- meerk40t/core/plotplanner.py +7 -4
- meerk40t/device/gui/defaultactions.py +78 -14
- meerk40t/dxf/dxf_io.py +42 -0
- meerk40t/grbl/controller.py +245 -35
- meerk40t/grbl/device.py +102 -26
- meerk40t/grbl/driver.py +8 -2
- meerk40t/grbl/gui/grblconfiguration.py +6 -0
- meerk40t/grbl/gui/grblcontroller.py +1 -1
- meerk40t/gui/about.py +7 -0
- meerk40t/gui/choicepropertypanel.py +20 -30
- meerk40t/gui/devicepanel.py +27 -16
- meerk40t/gui/help_assets/help_assets.py +126 -2
- meerk40t/gui/icons.py +15 -0
- meerk40t/gui/laserpanel.py +102 -54
- meerk40t/gui/materialtest.py +10 -0
- meerk40t/gui/mkdebug.py +268 -9
- meerk40t/gui/navigationpanels.py +74 -8
- meerk40t/gui/propertypanels/operationpropertymain.py +185 -91
- meerk40t/gui/scenewidgets/elementswidget.py +7 -1
- meerk40t/gui/scenewidgets/selectionwidget.py +24 -9
- meerk40t/gui/simulation.py +1 -1
- meerk40t/gui/statusbarwidgets/shapepropwidget.py +50 -40
- meerk40t/gui/statusbarwidgets/statusbar.py +2 -2
- meerk40t/gui/toolwidgets/toolmeasure.py +1 -1
- meerk40t/gui/toolwidgets/toolnodeedit.py +4 -1
- meerk40t/gui/toolwidgets/tooltabedit.py +9 -7
- meerk40t/gui/wxmeerk40t.py +45 -15
- meerk40t/gui/wxmmain.py +23 -9
- meerk40t/gui/wxmribbon.py +36 -0
- meerk40t/gui/wxutils.py +66 -42
- meerk40t/kernel/inhibitor.py +120 -0
- meerk40t/kernel/kernel.py +38 -0
- meerk40t/lihuiyu/controller.py +33 -3
- meerk40t/lihuiyu/device.py +99 -4
- meerk40t/lihuiyu/driver.py +65 -5
- meerk40t/lihuiyu/gui/lhycontrollergui.py +69 -24
- meerk40t/lihuiyu/gui/lhydrivergui.py +6 -0
- meerk40t/lihuiyu/laserspeed.py +17 -10
- meerk40t/lihuiyu/parser.py +23 -0
- meerk40t/main.py +2 -2
- meerk40t/moshi/gui/moshidrivergui.py +7 -0
- meerk40t/newly/controller.py +3 -2
- meerk40t/newly/device.py +23 -2
- meerk40t/newly/driver.py +8 -3
- meerk40t/newly/gui/newlyconfig.py +7 -0
- meerk40t/ruida/gui/ruidaconfig.py +7 -0
- meerk40t/tools/geomstr.py +142 -49
- meerk40t/tools/rasterplotter.py +0 -5
- meerk40t/tools/ttfparser.py +921 -168
- {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/METADATA +1 -1
- {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/RECORD +69 -68
- {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/WHEEL +0 -0
- {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/entry_points.txt +0 -0
- {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.7051.dist-info → meerk40t-0.9.7910.dist-info}/zip-safe +0 -0
@@ -159,13 +159,112 @@ I segnaposto per "data" e "ora" possono anche contenere istruzioni di formattazi
|
|
159
159
|
|
160
160
|
Per un insieme completo delle istruzioni di formattazione, vedere: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
|
161
161
|
"""
|
162
|
+
french_wordlist_howto = """
|
163
|
+
Les listes de mots vous permettent de créer des éléments de texte dans votre conception contenant du texte d'espace réservé qui est remplacé au moment de la gravure à partir de cette liste de mots. Vous pouvez ainsi graver plusieurs éléments avec des textes différents sans avoir à modifier votre conception à chaque fois.
|
164
|
+
|
165
|
+
Un espace réservé consiste en un nom entre accolades, par exemple '{PRENOM}'. Vous utilisez ce nom dans l'éditeur de listes de mots pour l'associer à l'espace réservé et l'espace réservé sera remplacé par le texte que vous saisissez dans le contenu de la liste de mots associée.
|
166
|
+
|
167
|
+
Comme exemple d'utilisation de cette fonctionnalité, imaginez que vous voulez créer un ensemble d'étiquettes de réservation de places pour un dîner, chacune avec le nom d'une personne différente. Après avoir créé le chemin de découpe pour le contour de l'étiquette de nom, par exemple un rectangle, utilisez l'outil de dessin de texte pour créer un élément de texte contenant ce qui suit :
|
168
|
+
'Cette place est réservée pour {PRENOM}'
|
169
|
+
|
170
|
+
Ensuite, vous utilisez cet éditeur de listes de mots pour créer une ou plusieurs entrées comme suit :
|
171
|
+
|-----------|------|-------|
|
172
|
+
| Nom | Type | Index |
|
173
|
+
|-----------|------|-------|
|
174
|
+
| prenom | Texte| 0 |
|
175
|
+
|-----------|------|-------|
|
176
|
+
Puis cliquez sur la ligne 'prenom' et ajoutez plusieurs éléments au panneau Contenu, par exemple :
|
177
|
+
Paul
|
178
|
+
David
|
179
|
+
Andy
|
180
|
+
Maintenant, lorsque vous exécutez la gravure, vous obtiendrez des étiquettes de place individuelles qui ont des noms différents, par exemple 'Cette place est réservée pour Andy'.
|
181
|
+
|
182
|
+
Vous pouvez utiliser autant de noms d'espaces réservés différents que vous le souhaitez dans les champs de texte de votre conception.
|
183
|
+
|
184
|
+
La valeur 'Index' dans la table de liste de mots indique quelle entrée de la liste de contenu sera utilisée ensuite, zéro signifiant la première entrée. L'index est automatiquement augmenté de un à la fin de chaque gravure.
|
185
|
+
|
186
|
+
Mais supposons que pour l'efficacité, vous voulez maintenant graver deux étiquettes de réservation de places en même temps, chacune ayant un nom différent de la même liste. Dans ce cas, si la première étiquette utilise '{NOM#+0}' et la seconde '{NOM#+1}' (notez le signe plus). '{NOM}' ou '{NOM#+0}' utilise l'entrée actuelle (pointée par la valeur Index), '{NOM#+1}' utilise l'entrée suivante après la courante, etc.
|
187
|
+
|
188
|
+
Avec l'usage ci-dessus, vous pouvez utiliser ces valeurs autant de fois que vous le souhaitez dans votre conception. Pour faire avancer l'index, vous devez cliquer sur les boutons Précédent / Suivant dans la barre d'outils.
|
189
|
+
|
190
|
+
Comme alternative à la saisie manuelle des valeurs de liste de mots en utilisant cet éditeur de listes de mots, vous pouvez utiliser un fichier CSV standard séparé par des virgules. Les noms d'espaces réservés sont définis dans la ligne d'en-tête CSV standard (la première ligne du fichier CSV), et le contenu est ensuite pris de toutes les lignes suivantes. Le moyen le plus simple de créer un fichier CSV est d'utiliser un tableur, par exemple Excel, cependant, par exemple pour les sites de commerce électronique, votre site web pourrait automatiquement créer le fichier CSV à partir des commandes passées en ligne par les clients.
|
191
|
+
|
192
|
+
Les entrées chargées à partir d'un fichier CSV sont affichées comme Type CSV, et vous pouvez définir les valeurs Index pour toutes les entrées CSV en même temps.
|
193
|
+
|
194
|
+
Note : Si votre CSV n'a pas de ligne d'en-tête, les colonnes seront nommées 'column_1', 'column_2', etc.
|
195
|
+
|
196
|
+
La liste de mots contient également quelques entrées spéciales (qui pourraient être particulièrement utiles pour les conceptions de calibrage) :
|
197
|
+
* 'version' - Version de Meerk40t
|
198
|
+
* 'date' - Date de début de la gravure
|
199
|
+
* 'time' - Heure de début de la gravure
|
200
|
+
* 'op_device' - Appareil sur lequel vous gravez
|
201
|
+
* 'op_speed' - Vitesse de l'opération courante
|
202
|
+
* 'op_power' - PPI de l'opération courante
|
203
|
+
* 'op_dpi' - DPI de l'opération courante (trame)
|
204
|
+
* 'op_passes' - Passes de l'opération courante
|
205
|
+
|
206
|
+
Les espaces réservés pour 'date' et 'time' peuvent également contenir des directives de formatage qui vous permettent de les formater selon vos conventions locales, par exemple :
|
207
|
+
{date@%d.%m.%Y} - 31.12.2022
|
208
|
+
{time@%H:%M} - 23:59
|
209
|
+
|
210
|
+
Pour un ensemble complet de directives de format, voir : https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
|
211
|
+
"""
|
212
|
+
russian_wordlist_howto = """
|
213
|
+
Списки слов позволяют создавать текстовые элементы в дизайне, содержащие текст-заполнители, которые заменяются во время выжигания содержимым из данного списка слов. Таким образом можно выжигать несколько элементов с разным текстом, не изменяя каждый раз дизайн.
|
214
|
+
|
215
|
+
Заполнитель состоит из имени в фигурных скобках, например '{ИМЯФАМИЛИЯ}'. Вы используете это имя в редакторе списков слов, чтобы связать его с заполнителем, и заполнитель будет заменен текстом, который вы введете в связанное содержимое списка слов.
|
216
|
+
|
217
|
+
В качестве примера использования этой функциональности, представьте, что вы хотите создать набор карточек для резервирования мест на ужине, каждая с именем разного человека. Создав путь резки для контура именной карточки, например прямоугольник, используйте инструмент рисования текста для создания текстового элемента, содержащего следующее:
|
218
|
+
'Это место зарезервировано для {ИМЯФАМИЛИЯ}'
|
219
|
+
|
220
|
+
Затем используйте редактор списков слов для создания одной или нескольких записей следующим образом:
|
221
|
+
|-----------|------|-------|
|
222
|
+
| Имя | Тип | Индекс|
|
223
|
+
|-----------|------|-------|
|
224
|
+
| имяфамилия| Текст| 0 |
|
225
|
+
|-----------|------|-------|
|
226
|
+
Затем нажмите на строку 'имяфамилия' и добавьте несколько элементов в панель содержимого, например:
|
227
|
+
Павел
|
228
|
+
Давид
|
229
|
+
Андрей
|
230
|
+
Теперь при выполнении выжигания вы получите индивидуальные карточки мест с разными именами, например 'Это место зарезервировано для Андрей'.
|
231
|
+
|
232
|
+
Вы можете использовать столько разных имен заполнителей, сколько захотите, в текстовых полях вашего дизайна.
|
233
|
+
|
234
|
+
Значение 'Индекс' в таблице списка слов указывает, какая запись в списке содержимого будет использована следующей, ноль означает первую запись. Индекс автоматически увеличивается на единицу в конце каждого выжигания.
|
235
|
+
|
236
|
+
Но предположим, что для эффективности вы теперь хотите выжечь две карточки резервирования мест одновременно, каждая с разным именем из того же списка. В этом случае, если первая карточка использует '{ИМЯ#+0}', а вторая '{ИМЯ#+1}' (обратите внимание на знак плюс). '{ИМЯ}' или '{ИМЯ#+0}' использует текущую запись (на которую указывает значение индекса), '{ИМЯ#+1}' использует следующую запись после текущей и т.д.
|
237
|
+
|
238
|
+
При таком использовании вы можете использовать эти значения столько раз, сколько захотите в вашем дизайне. Для продвижения индекса вам нужно нажать кнопки Пред/След в панели инструментов.
|
239
|
+
|
240
|
+
В качестве альтернативы ручному вводу значений списка слов с помощью этого редактора, вы можете использовать стандартный CSV-файл, разделенный запятыми. Имена заполнителей определяются в стандартной строке заголовка CSV (первая строка в CSV-файле), а содержимое затем берется из всех следующих строк. Самый простой способ создать CSV-файл - использовать электронную таблицу, например Excel, однако для сайтов электронной коммерции ваш веб-сайт может автоматически создать CSV-файл из заказов, размещенных онлайн клиентами.
|
241
|
+
|
242
|
+
Записи, загруженные из CSV-файла, показываются как тип CSV, и вы можете установить значения индекса для всех CSV-записей одновременно.
|
243
|
+
|
244
|
+
Примечание: Если ваш CSV не имеет строки заголовка, столбцы будут названы 'column_1', 'column_2' и т.д.
|
245
|
+
|
246
|
+
Список слов также содержит некоторые специальные записи (которые могут быть особенно полезны для калибровочных дизайнов):
|
247
|
+
* 'version' - Версия Meerk40t
|
248
|
+
* 'date' - Дата начала выжигания
|
249
|
+
* 'time' - Время начала выжигания
|
250
|
+
* 'op_device' - Устройство, на котором вы выжигаете
|
251
|
+
* 'op_speed' - Скорость текущей операции
|
252
|
+
* 'op_power' - PPI текущей операции
|
253
|
+
* 'op_dpi' - DPI текущей (растровой) операции
|
254
|
+
* 'op_passes' - Проходы операции текущей операции
|
255
|
+
|
256
|
+
Заполнители для 'date' и 'time' также могут содержать директивы форматирования, которые позволяют форматировать их согласно вашим местным соглашениям, например:
|
257
|
+
{date@%d.%m.%Y} - 31.12.2022
|
258
|
+
{time@%H:%M} - 23:59
|
259
|
+
|
260
|
+
Для полного набора директив форматирования см.: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
|
261
|
+
"""
|
162
262
|
|
163
263
|
english_material_howto = """
|
164
264
|
The Material Library Manager allows to create, maintain, use and manage operations that are customized to provide a desired effect with a given material (hence the name Material Library).
|
165
265
|
The parameters you want to use e.g. for cutting acrylic are very different from the ones you want to use to engrave a picture on slate.
|
166
266
|
You can share such a material setting with the MeerK40t community and you can benefit from the contributions of others by loading and using their settings.
|
167
267
|
"""
|
168
|
-
|
169
268
|
german_material_howto = """
|
170
269
|
Die Material-Bibliothek erlaubt es Arbeitsgangs-Einstellungen für spezifische Materialien anzulegen und zu verwalten.
|
171
270
|
Die Parameter, die man z.B. für das Schneiden von Acryl benötigt unterscheiden sich deutlich von denen, die man etwa zum Gravieren eine Fotos auf Schiefer braucht.
|
@@ -176,35 +275,60 @@ Il Gestore della libreria di materiali consente di creare, gestire, memorizzare
|
|
176
275
|
I parametri da utilizzare, ad esempio, per tagliare l'acrilico sono molto diversi da quelli da utilizzare per incidere un'immagine sull'ardesia.
|
177
276
|
È possibile condividere tali impostazioni di lavorazione dei materiali con la comunità MeerK40t e beneficiare dei contributi degli altri caricando e utilizzando le loro impostazioni.
|
178
277
|
"""
|
278
|
+
french_material_howto = """
|
279
|
+
Le gestionnaire de bibliothèque de matériaux permet de créer, maintenir, utiliser et gérer des opérations qui sont personnalisées pour fournir un effet désiré avec un matériau donné (d'où le nom Bibliothèque de matériaux).
|
280
|
+
Les paramètres que vous voulez utiliser, par exemple pour découper de l'acrylique, sont très différents de ceux que vous voulez utiliser pour graver une image sur de l'ardoise.
|
281
|
+
Vous pouvez partager de tels paramètres de matériau avec la communauté MeerK40t et vous pouvez bénéficier des contributions des autres en chargeant et en utilisant leurs paramètres.
|
282
|
+
"""
|
283
|
+
russian_material_howto = """
|
284
|
+
Менеджер библиотеки материалов позволяет создавать, поддерживать, использовать и управлять операциями, которые настроены для обеспечения желаемого эффекта с определенным материалом (отсюда и название "Библиотека материалов").
|
285
|
+
Параметры, которые вы хотите использовать, например, для резки акрила, очень отличаются от тех, которые вы хотите использовать для гравировки изображения на сланце.
|
286
|
+
Вы можете поделиться такими настройками материала с сообществом MeerK40t и можете извлечь пользу из вкладов других, загружая и используя их настройки.
|
287
|
+
"""
|
179
288
|
|
180
289
|
|
181
290
|
def asset(context, asset):
|
182
291
|
language = context.language
|
183
292
|
lang = "english"
|
293
|
+
# Language #00 : en - English
|
184
294
|
if language == 0: # ("en", "English", wx.LANGUAGE_ENGLISH)
|
185
295
|
lang = "english"
|
296
|
+
# Language #01 : it - italiano
|
186
297
|
if language == 1: # ("it", "italiano", wx.LANGUAGE_ITALIAN),
|
187
298
|
lang = "italian"
|
299
|
+
# Language #02 : fr - français
|
188
300
|
if language == 2: # ("fr", "français", wx.LANGUAGE_FRENCH),
|
189
301
|
lang = "french"
|
302
|
+
# Language #03 : de - Deutsch
|
190
303
|
if language == 3: # ("de", "Deutsch", wx.LANGUAGE_GERMAN),
|
191
304
|
lang = "german"
|
305
|
+
# Language #04 : es - español
|
192
306
|
if language == 4: # ("es", "español", wx.LANGUAGE_SPANISH),
|
193
307
|
lang = "spanish"
|
308
|
+
# Language #05 : zh - 中文
|
194
309
|
if language == 5: # ("zh", "中文", wx.LANGUAGE_CHINESE),
|
195
310
|
lang = "chinese"
|
311
|
+
# Language #06 : hu - Magyar
|
196
312
|
if language == 6: # ("hu", "Magyar", wx.LANGUAGE_HUNGARIAN),
|
197
313
|
lang = "hungarian"
|
314
|
+
# Language #07 : pt_PT - português
|
198
315
|
if language == 7: # ("pt_PT", "português", wx.LANGUAGE_PORTUGUESE),
|
199
316
|
lang = "portuguese"
|
317
|
+
# Language #08 : pt_BR - português brasileiro
|
200
318
|
if (
|
201
319
|
language == 8
|
202
320
|
): # ("pt_BR", "português brasileiro", wx.LANGUAGE_PORTUGUESE_BRAZILIAN),
|
203
321
|
lang = "portuguese_brazilian"
|
322
|
+
# Language #09 : ja - 日本
|
204
323
|
if language == 9: # ("ja", "日本", wx.LANGUAGE_JAPANESE),
|
205
324
|
lang = "japanese"
|
206
|
-
|
325
|
+
# Language #10 : nl - Nederlands
|
326
|
+
if language == 10: # ("nl", "Nederlands", wx.LANGUAGE_DUTCH),
|
207
327
|
lang = "dutch"
|
328
|
+
# Language #11 : ru - русский
|
329
|
+
if language == 11: # ("ru", "русский", wx.LANGUAGE_RUSSIAN),
|
330
|
+
lang = "russian"
|
331
|
+
|
208
332
|
text = ""
|
209
333
|
try:
|
210
334
|
text = globals()[f"{lang}_{asset}"]
|
meerk40t/gui/icons.py
CHANGED
@@ -3497,3 +3497,18 @@ icon_z_home = VectorIcon(
|
|
3497
3497
|
"M 37.5,25 h 25 l -25, 25 h 25",
|
3498
3498
|
),
|
3499
3499
|
)
|
3500
|
+
|
3501
|
+
icon_coffee = VectorIcon(
|
3502
|
+
fill=(),
|
3503
|
+
stroke=(
|
3504
|
+
"M4 20H10.9433M10.9433 20H11.0567M10.9433 20C10.9622 20.0002 10.9811 20.0002 11 20.0002C11.0189 20.0002 11.0378 20.0002 11.0567 20M10.9433 20C7.1034 19.9695 4 16.8468 4 12.9998V8.92285C4 8.41305 4.41305 8 4.92285 8H17.0767C17.5865 8 18 8.41305 18 8.92285V9M11.0567 20H18M11.0567 20C14.8966 19.9695 18 16.8468 18 12.9998M18 9H19.5C20.8807 9 22 10.1193 22 11.5C22 12.8807 20.8807 14 19.5 14H18V12.9998M18 9V12.9998M15 3L14 5M12 3L11 5M9 3L8 5",
|
3505
|
+
),
|
3506
|
+
)
|
3507
|
+
|
3508
|
+
icon_sleep = VectorIcon(
|
3509
|
+
fill=(
|
3510
|
+
"M7.953,13 L1.027,13 C0.65,13 0.311,12.769 0.16,12.411 C0.009,12.053 0.076,11.636 0.328,11.348 L5.859,4.973 L0.988,4.973 C0.465,4.973 -2.27373675e-13,4.572 -2.27373675e-13,4.028 C-2.27373675e-13,3.483 0.425,3.043 0.947,3.043 L7.973,3.043 C8.347,3.043 8.689,3.273 8.839,3.632 C8.989,3.991 8.924,4.406 8.671,4.695 L3.179,11.082 L7.952,11.082 C8.475,11.082 8.899,11.471 8.899,12.015 C8.9,12.559 8.477,13 7.953,13 L7.953,13 Z",
|
3511
|
+
"M15.755,7.935 L9.701,7.935 C9.447,7.935 9.219,7.783 9.115,7.544 C9.011,7.307 9.053,7.027 9.222,6.833 L14.338,0.964 L9.338,0.964 C8.984,0.964 9.02,0.034 9.373,0.034 L15.471,0.034 C15.724,0.034 15.917,0.151 16.021,0.388 C16.126,0.625 16.083,0.905 15.914,1.1 L10.88,6.963 L15.755,6.963 C16.109,6.964 16.109,7.935 15.755,7.935 L15.755,7.935 Z",
|
3512
|
+
),
|
3513
|
+
stroke=(),
|
3514
|
+
)
|
meerk40t/gui/laserpanel.py
CHANGED
@@ -29,7 +29,6 @@ from meerk40t.gui.wxutils import (
|
|
29
29
|
wxButton,
|
30
30
|
wxCheckBox,
|
31
31
|
wxComboBox,
|
32
|
-
wxStaticBitmap,
|
33
32
|
wxStaticText,
|
34
33
|
)
|
35
34
|
from meerk40t.kernel import lookup_listener, signal_listener
|
@@ -262,7 +261,7 @@ class LaserPanel(wx.Panel):
|
|
262
261
|
self.check_laser_arm()
|
263
262
|
|
264
263
|
self.button_outline = wxButton(self, wx.ID_ANY, _("Outline"))
|
265
|
-
self.button_outline.SetToolTip(_("Trace the outline the job"))
|
264
|
+
self.button_outline.SetToolTip(_("Trace the outline of the job"))
|
266
265
|
self.button_outline.SetBitmap(
|
267
266
|
icons8_pentagon.GetBitmap(
|
268
267
|
resize=self.icon_size,
|
@@ -332,6 +331,7 @@ class LaserPanel(wx.Panel):
|
|
332
331
|
lb_speed = wxStaticText(self, wx.ID_ANY, _("Speed"))
|
333
332
|
self.label_speed = wxStaticText(self, wx.ID_ANY, "0%")
|
334
333
|
self.slider_size = 20
|
334
|
+
self.power_mode = "relative"
|
335
335
|
self.slider_speed = wx.Slider(
|
336
336
|
self, wx.ID_ANY, value=10, minValue=1, maxValue=20
|
337
337
|
)
|
@@ -380,33 +380,67 @@ class LaserPanel(wx.Panel):
|
|
380
380
|
self.button_start_was_clicked = False
|
381
381
|
|
382
382
|
def update_override_controls(self):
|
383
|
+
def set_boundaries(slider, current_value, min_value, max_value):
|
384
|
+
slider.SetMin(min_value)
|
385
|
+
slider.SetMax(max_value)
|
386
|
+
slider.SetValue(current_value)
|
387
|
+
|
383
388
|
flag_power = False
|
384
389
|
override = False
|
385
|
-
if
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
390
|
+
if (
|
391
|
+
hasattr(self.context.device.driver, "has_adjustable_power")
|
392
|
+
and self.context.device.driver.has_adjustable_power
|
393
|
+
):
|
394
|
+
flag_power = True
|
395
|
+
# Let's establish the value and update the slider...
|
396
|
+
value = self.context.device.driver.power_scale
|
397
|
+
if value != 1:
|
398
|
+
override = True
|
399
|
+
half = self.slider_size / 2
|
400
|
+
sliderval = int(value * half)
|
401
|
+
sliderval = max(1, min(self.slider_size, sliderval))
|
402
|
+
set_boundaries(self.slider_power, sliderval, 1, self.slider_size)
|
403
|
+
self.slider_power.SetToolTip(
|
404
|
+
_("Increases/decreases the regular laser power by this amount.")
|
405
|
+
+ "\n"
|
406
|
+
+ _("This affects running jobs, so use with care!")
|
407
|
+
)
|
408
|
+
self.power_mode = "relative"
|
409
|
+
self.on_slider_power(None)
|
410
|
+
elif (
|
411
|
+
hasattr(self.context.device.driver, "has_adjustable_maximum_power")
|
412
|
+
and self.context.device.driver.has_adjustable_maximum_power
|
413
|
+
):
|
414
|
+
flag_power = True
|
415
|
+
override = True
|
416
|
+
dev_mode = getattr(self.context.kernel.root, "developer_mode", False)
|
417
|
+
# Let's establish the value and update the slider...
|
418
|
+
min_value = 1
|
419
|
+
max_value = 100 if dev_mode else 50
|
420
|
+
sliderval = min(max_value, self.context.device.driver.max_power_scale)
|
421
|
+
set_boundaries(self.slider_power, sliderval, min_value, max_value)
|
422
|
+
self.slider_power.SetToolTip(
|
423
|
+
_("Sets the maximum laser power level.")
|
424
|
+
+ "\n"
|
425
|
+
+ _("Setting this too high may cause damage to your laser tube!")
|
426
|
+
)
|
427
|
+
self.power_mode = "maximum"
|
428
|
+
self.on_slider_power(None)
|
397
429
|
flag_speed = False
|
398
|
-
if
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
430
|
+
if (
|
431
|
+
hasattr(self.context.device.driver, "has_adjustable_speed")
|
432
|
+
and self.context.device.driver.has_adjustable_speed
|
433
|
+
):
|
434
|
+
flag_speed = True
|
435
|
+
# Let's establish the value and update the slider...
|
436
|
+
value = self.context.device.driver.speed_scale
|
437
|
+
if value != 1:
|
438
|
+
override = True
|
439
|
+
half = self.slider_size / 2
|
440
|
+
sliderval = int(value * half)
|
441
|
+
sliderval = max(1, min(self.slider_size, sliderval))
|
442
|
+
set_boundaries(self.slider_speed, sliderval, 1, self.slider_size)
|
443
|
+
self.on_slider_speed(None)
|
410
444
|
|
411
445
|
self.sizer_power.Show(flag_power)
|
412
446
|
self.sizer_power.ShowItems(flag_power)
|
@@ -427,18 +461,22 @@ class LaserPanel(wx.Panel):
|
|
427
461
|
else:
|
428
462
|
self.slider_power.Enable(False)
|
429
463
|
self.slider_speed.Enable(False)
|
430
|
-
if
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
self.
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
464
|
+
if (
|
465
|
+
hasattr(self.context.device.driver, "has_adjustable_power")
|
466
|
+
and self.context.device.driver.has_adjustable_power
|
467
|
+
):
|
468
|
+
if event is not None:
|
469
|
+
self.context.device.driver.set_power_scale(1.0)
|
470
|
+
self.slider_power.SetValue(10)
|
471
|
+
self.on_slider_power(None)
|
472
|
+
if (
|
473
|
+
hasattr(self.context.device.driver, "has_adjustable_speed")
|
474
|
+
and self.context.device.driver.has_adjustable_speed
|
475
|
+
):
|
476
|
+
if event is not None:
|
477
|
+
self.context.device.driver.set_speed_scale(1.0)
|
478
|
+
self.slider_speed.SetValue(10)
|
479
|
+
self.on_slider_speed(None)
|
442
480
|
|
443
481
|
def on_slider_speed(self, event):
|
444
482
|
sliderval = self.slider_speed.GetValue()
|
@@ -452,12 +490,18 @@ class LaserPanel(wx.Panel):
|
|
452
490
|
|
453
491
|
def on_slider_power(self, event):
|
454
492
|
sliderval = self.slider_power.GetValue()
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
493
|
+
if self.power_mode == "maximum":
|
494
|
+
# Maximum power mode, so we just set the value.
|
495
|
+
if event is not None:
|
496
|
+
self.context.device.driver.max_power_scale = sliderval
|
497
|
+
msg = f"{sliderval}%"
|
498
|
+
else:
|
499
|
+
half = self.slider_size / 2
|
500
|
+
newvalue = sliderval - half # -> -9 to +10
|
501
|
+
factor = 1 + newvalue / half
|
502
|
+
if event is not None:
|
503
|
+
self.context.device.driver.set_power_scale(factor)
|
504
|
+
msg = f"{'+' if factor > 1 else ''}{100 * (factor - 1.0):.0f}%"
|
461
505
|
self.label_power.SetLabel(msg)
|
462
506
|
|
463
507
|
def on_optimize(self, event):
|
@@ -478,6 +522,14 @@ class LaserPanel(wx.Panel):
|
|
478
522
|
if self.checkbox_optimize.GetValue() != newvalue:
|
479
523
|
self.checkbox_optimize.SetValue(newvalue)
|
480
524
|
|
525
|
+
@signal_listener("pwm_mode_changed")
|
526
|
+
def on_pwm_mode_changed(self, origin, *message):
|
527
|
+
"""
|
528
|
+
This is called when the power scale of the device changes.
|
529
|
+
It updates the slider and label accordingly.
|
530
|
+
"""
|
531
|
+
self.update_override_controls()
|
532
|
+
|
481
533
|
@signal_listener("device;modified")
|
482
534
|
@signal_listener("device;renamed")
|
483
535
|
@lookup_listener("service/device/active")
|
@@ -655,13 +707,12 @@ class LaserPanel(wx.Panel):
|
|
655
707
|
self.context.setting(bool, "laserpane_hold", False)
|
656
708
|
if plan.plan and self.context.laserpane_hold:
|
657
709
|
self.context("planz spool\n")
|
710
|
+
elif self.checkbox_optimize.GetValue():
|
711
|
+
self.context(
|
712
|
+
"planz clear copy preprocess validate blob preopt optimize spool\n"
|
713
|
+
)
|
658
714
|
else:
|
659
|
-
|
660
|
-
self.context(
|
661
|
-
"planz clear copy preprocess validate blob preopt optimize spool\n"
|
662
|
-
)
|
663
|
-
else:
|
664
|
-
self.context("planz clear copy preprocess validate blob spool\n")
|
715
|
+
self.context("planz clear copy preprocess validate blob spool\n")
|
665
716
|
self.armed = False
|
666
717
|
self.check_laser_arm()
|
667
718
|
if self.context.auto_spooler:
|
@@ -807,10 +858,7 @@ class JobPanel(wx.Panel):
|
|
807
858
|
|
808
859
|
if not pathname.lower().endswith(f".{extension}"):
|
809
860
|
pathname += f".{extension}"
|
810
|
-
if self.context.planner.do_optimization
|
811
|
-
optpart = "preopt optimize "
|
812
|
-
else:
|
813
|
-
optpart = ""
|
861
|
+
optpart = "preopt optimize " if self.context.planner.do_optimization else ""
|
814
862
|
self.context(
|
815
863
|
f'planz clear copy preprocess validate blob {optpart}save_job "{pathname}"\n'
|
816
864
|
)
|
meerk40t/gui/materialtest.py
CHANGED
@@ -947,6 +947,11 @@ class TemplatePanel(wx.Panel):
|
|
947
947
|
standard_items = False
|
948
948
|
choices = self.parameters[idx][7]
|
949
949
|
self.list_options_1.Set(choices)
|
950
|
+
self.list_options_1.SetToolTip(
|
951
|
+
_("Select the values you want to test for {param}").format(
|
952
|
+
param=self.parameters[idx][2]
|
953
|
+
)
|
954
|
+
)
|
950
955
|
checked_strings = [
|
951
956
|
s for s in self.context.template_list1.split("|") if s
|
952
957
|
]
|
@@ -981,6 +986,11 @@ class TemplatePanel(wx.Panel):
|
|
981
986
|
standard_items = False
|
982
987
|
choices = self.parameters[idx][7]
|
983
988
|
self.list_options_2.Set(choices)
|
989
|
+
self.list_options_2.SetToolTip(
|
990
|
+
_("Select the values you want to test for {param}").format(
|
991
|
+
param=self.parameters[idx][2]
|
992
|
+
)
|
993
|
+
)
|
984
994
|
checked_strings = [
|
985
995
|
s for s in self.context.template_list2.split("|") if s
|
986
996
|
]
|