Display (uncomplete) configuration UI to export PCB file

CURA-11561
This commit is contained in:
Erwan MATHIEU 2024-01-26 14:01:26 +01:00
parent edd5cee41a
commit b5b0575baf
10 changed files with 466 additions and 0 deletions

View file

@ -0,0 +1,37 @@
# Copyright (c) 2024 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication, QUrl
from PyQt6.QtGui import QDesktopServices
from typing import List, Optional, Dict, cast
from cura.Machines.Models.MachineListModel import MachineListModel
from cura.Machines.Models.IntentTranslations import intent_translations
from cura.Settings.GlobalStack import GlobalStack
from UM.Application import Application
from UM.FlameProfiler import pyqtSlot
from UM.i18n import i18nCatalog
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry
from UM.Settings.ContainerRegistry import ContainerRegistry
import os
import threading
import time
from cura.CuraApplication import CuraApplication
i18n_catalog = i18nCatalog("cura")
class PCBDialog(QObject):
def __init__(self, parent = None) -> None:
super().__init__(parent)
plugin_path = os.path.dirname(__file__)
dialog_path = os.path.join(plugin_path, 'PCBDialog.qml')
self._view = CuraApplication.getInstance().createQmlComponent(dialog_path, {"manager": self})
def show(self) -> None:
self._view.show()

View file

@ -0,0 +1,148 @@
// Copyright (c) 2024 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import QtQuick.Window 2.2
import UM 1.5 as UM
import Cura 1.1 as Cura
import PCBWriter 1.0 as PCBWriter
UM.Dialog
{
id: workspaceDialog
title: catalog.i18nc("@title:window", "Export pre-configured build batch")
margin: UM.Theme.getSize("default_margin").width
minimumWidth: UM.Theme.getSize("modal_window_minimum").width
minimumHeight: UM.Theme.getSize("modal_window_minimum").height
backgroundColor: UM.Theme.getColor("detail_background")
headerComponent: Rectangle
{
UM.I18nCatalog { id: catalog; name: "cura" }
height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").height
color: UM.Theme.getColor("main_background")
ColumnLayout
{
id: headerColumn
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.rightMargin: anchors.leftMargin
UM.Label
{
id: titleLabel
text: catalog.i18nc("@action:title", "Summary - Pre-configured build batch")
font: UM.Theme.getFont("large")
}
UM.Label
{
id: descriptionLabel
text: catalog.i18nc("@action:description", "When exporting a build batch, all the models present on the build plate will be included with their current position, orientation and scale. You can also select which per-extruder or per-model settings should be included to ensure a proper printing of the batch, even on different printers.")
font: UM.Theme.getFont("default")
wrapMode: Text.Wrap
Layout.maximumWidth: headerColumn.width
}
}
}
Rectangle
{
anchors.fill: parent
color: UM.Theme.getColor("main_background")
PCBWriter.SettingsExportModel{ id: settingsExportModel }
ListView
{
id: settingsExportList
anchors.fill: parent
anchors.margins: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").height
model: settingsExportModel.settingsGroups
clip: true
ScrollBar.vertical: UM.ScrollBar { id: verticalScrollBar }
delegate: SettingsSelectionGroup { Layout.margins: 0 }
}
// Flickable
// {
// Column
// {
// width: parent.width - scrollbar.width - UM.Theme.getSize("default_margin").width
// height: childrenRect.height
//
// spacing: UM.Theme.getSize("default_margin").height
// leftPadding: UM.Theme.getSize("default_margin").width
// rightPadding: leftPadding
// topPadding: UM.Theme.getSize("default_margin").height
// bottomPadding: topPadding
// }
// }
}
footerComponent: Rectangle
{
color: warning ? UM.Theme.getColor("warning") : "transparent"
anchors.bottom: parent.bottom
width: parent.width
height: childrenRect.height + (warning ? 2 * workspaceDialog.margin : workspaceDialog.margin)
Column
{
height: childrenRect.height
spacing: workspaceDialog.margin
anchors.leftMargin: workspaceDialog.margin
anchors.rightMargin: workspaceDialog.margin
anchors.bottomMargin: workspaceDialog.margin
anchors.topMargin: warning ? workspaceDialog.margin : 0
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
RowLayout
{
id: warningRow
height: childrenRect.height
visible: warning
spacing: workspaceDialog.margin
UM.ColorImage
{
width: UM.Theme.getSize("extruder_icon").width
height: UM.Theme.getSize("extruder_icon").height
source: UM.Theme.getIcon("Warning")
}
UM.Label
{
id: warningText
text: catalog.i18nc("@label", "This project contains materials or plugins that are currently not installed in Cura.<br/>Install the missing packages and reopen the project.")
}
}
Loader
{
width: parent.width
height: childrenRect.height
sourceComponent: buttonRow
}
}
}
buttonSpacing: UM.Theme.getSize("wide_margin").width
}

View file

@ -0,0 +1,67 @@
# Copyright (c) 2024 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import json
import re
from threading import Lock
from typing import Optional, cast, List, Dict, Pattern, Set
from UM.Mesh.MeshWriter import MeshWriter
from UM.Math.Vector import Vector
from UM.Logger import Logger
from UM.Math.Matrix import Matrix
from UM.Application import Application
from UM.Message import Message
from UM.Resources import Resources
from UM.Scene.SceneNode import SceneNode
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer
from PyQt6.QtQml import qmlRegisterType
from cura.CuraApplication import CuraApplication
from cura.CuraPackageManager import CuraPackageManager
from cura.Settings import CuraContainerStack
from cura.Utils.Threading import call_on_qt_thread
from cura.Snapshot import Snapshot
from PyQt6.QtCore import QBuffer
import pySavitar as Savitar
import numpy
import datetime
import zipfile
import UM.Application
from .PCBDialog import PCBDialog
from .SettingsExportModel import SettingsExportModel
from .SettingsExportGroup import SettingsExportGroup
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
class PCBWriter(MeshWriter):
def __init__(self):
super().__init__()
qmlRegisterType(SettingsExportModel, "PCBWriter", 1, 0, "SettingsExportModel")
qmlRegisterType(SettingsExportGroup, "PCBWriter", 1, 0, "SettingsExportGroup")
#qmlRegisterUncreatableType(SettingsExportGroup.Category, "PCBWriter", 1, 0, "SettingsExportGroup.Category")
self._config_dialog = None
self._main_thread_lock = Lock()
def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode) -> bool:
self._main_thread_lock.acquire()
# Start configuration window in main application thread
CuraApplication.getInstance().callLater(self._write, stream, nodes, mode)
self._main_thread_lock.acquire() # Block until lock has been released, meaning the config is over
self._main_thread_lock.release()
return True
def _write(self, stream, nodes, mode):
self._config_dialog = PCBDialog()
self._config_dialog.show()

View file

@ -0,0 +1,24 @@
# Copyright (c) 2024 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt6.QtCore import Qt, QObject, pyqtProperty
from UM.FlameProfiler import pyqtSlot
from UM.Application import Application
from UM.Qt.ListModel import ListModel
from UM.Logger import Logger
class SettingsExport():
def __init__(self):
super().__init__()
self._name = "Generate Support"
self._value = "Enabled"
@pyqtProperty(str, constant=True)
def name(self):
return self._name
@pyqtProperty(str, constant=True)
def value(self):
return self._value

View file

@ -0,0 +1,59 @@
# Copyright (c) 2024 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from enum import IntEnum
from PyQt6.QtCore import Qt, QObject, pyqtProperty, pyqtEnum
from UM.FlameProfiler import pyqtSlot
from UM.Application import Application
from UM.Qt.ListModel import ListModel
from UM.Logger import Logger
from .SettingExport import SettingsExport
class SettingsExportGroup(QObject):
@pyqtEnum
class Category(IntEnum):
Global = 0
Extruder = 1
Model = 2
def __init__(self, name, category, category_details = '', extruder_index = 0, extruder_color = ''):
super().__init__()
self._name = name
self._settings = []
self._category = category
self._category_details = category_details
self._extruder_index = extruder_index
self._extruder_color = extruder_color
self._updateSettings()
@pyqtProperty(str, constant=True)
def name(self):
return self._name
@pyqtProperty(list, constant=True)
def settings(self):
return self._settings
@pyqtProperty(int, constant=True)
def category(self):
return self._category
@pyqtProperty(str, constant=True)
def category_details(self):
return self._category_details
@pyqtProperty(int, constant=True)
def extruder_index(self):
return self._extruder_index
@pyqtProperty(str, constant=True)
def extruder_color(self):
return self._extruder_color
def _updateSettings(self):
self._settings.append(SettingsExport())
self._settings.append(SettingsExport())

View file

@ -0,0 +1,31 @@
# Copyright (c) 2024 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt6.QtCore import QObject, Qt, pyqtProperty
from UM.FlameProfiler import pyqtSlot
from UM.Application import Application
from UM.Qt.ListModel import ListModel
from UM.Logger import Logger
from .SettingsExportGroup import SettingsExportGroup
class SettingsExportModel(QObject):
def __init__(self, parent = None):
super().__init__(parent)
self._settingsGroups = []
self._updateSettingsExportGroups()
@pyqtProperty(list, constant=True)
def settingsGroups(self):
return self._settingsGroups
def _updateSettingsExportGroups(self):
self._settingsGroups.append(SettingsExportGroup("Global settings", SettingsExportGroup.Category.Global))
self._settingsGroups.append(SettingsExportGroup("Extruder settings", SettingsExportGroup.Category.Extruder, extruder_index=1, extruder_color='#ff0000'))
self._settingsGroups.append(SettingsExportGroup("Extruder settings", SettingsExportGroup.Category.Extruder, extruder_index=8, extruder_color='#008fff'))
self._settingsGroups.append(SettingsExportGroup("Model settings",
SettingsExportGroup.Category.Model, 'hypercube.stl'))
self._settingsGroups.append(SettingsExportGroup("Model settings",
SettingsExportGroup.Category.Model, 'homer-simpson.stl'))

View file

@ -0,0 +1,70 @@
// Copyright (c) 2024 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import QtQuick.Window 2.2
import UM 1.5 as UM
import Cura 1.1 as Cura
import PCBWriter 1.0 as PCBWriter
Column
{
id: settingsGroup
UM.I18nCatalog { id: catalog; name: "cura" }
Row
{
id: settingsGroupTitleRow
spacing: UM.Theme.getSize("default_margin").width
Item
{
id: icon
anchors.verticalCenter: parent.verticalCenter
height: UM.Theme.getSize("medium_button_icon").height
width: height
UM.ColorImage
{
id: settingsMainImage
anchors.fill: parent
source:
{
switch(modelData.category)
{
case PCBWriter.SettingsExportGroup.Global:
return UM.Theme.getIcon("Sliders")
case PCBWriter.SettingsExportGroup.Model:
return UM.Theme.getIcon("View3D")
default:
return ""
}
}
color: UM.Theme.getColor("text")
}
Cura.ExtruderIcon
{
id: settingsExtruderIcon
anchors.fill: parent
visible: modelData.category === PCBWriter.SettingsExportGroup.Extruder
text: (modelData.extruder_index + 1).toString()
font: UM.Theme.getFont("tiny_emphasis")
materialColor: modelData.extruder_color
}
}
UM.Label
{
id: settingsTitle
text: modelData.name + (modelData.category_details ? ' (%1)'.arg(modelData.category_details) : '')
anchors.verticalCenter: parent.verticalCenter
font: UM.Theme.getFont("default_bold")
}
}
}

View file

@ -0,0 +1,21 @@
# Copyright (c) 2024 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import sys
from . import PCBWriter
from UM.i18n import i18nCatalog
i18n_catalog = i18nCatalog("cura")
def getMetaData():
return {"mesh_writer": {
"output": [{
"extension": "pcb",
"description": i18n_catalog.i18nc("@item:inlistbox", "Pre-Configured Batch file"),
"mime_type": "application/vnd.um.preconfigured-batch+3mf",
"mode": PCBWriter.PCBWriter.OutputMode.BinaryMode
}]
}}
def register(app):
return {"mesh_writer": PCBWriter.PCBWriter() }

View file

@ -0,0 +1,8 @@
{
"name": "Pre-Configured Batch Writer",
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for writing Pre-Configured Batch files.",
"api": 8,
"i18n-catalog": "cura"
}

View file

@ -15,6 +15,7 @@ Item
property int iconSize: UM.Theme.getSize("extruder_icon").width property int iconSize: UM.Theme.getSize("extruder_icon").width
property string iconVariant: "medium" property string iconVariant: "medium"
property alias font: extruderNumberText.font property alias font: extruderNumberText.font
property alias text: extruderNumberText.text
implicitWidth: iconSize implicitWidth: iconSize
implicitHeight: iconSize implicitHeight: iconSize