mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 22:47:29 -06:00
Reworked UI so that it matches 15.04 UI, and made each field in the UI do the same thing that they do in 15.04.
This commit is contained in:
parent
b8cf51349c
commit
b28bfc9602
3 changed files with 235 additions and 61 deletions
|
@ -10,13 +10,13 @@ import UM 1.1 as UM
|
|||
|
||||
UM.Dialog
|
||||
{
|
||||
width: 250*Screen.devicePixelRatio;
|
||||
minimumWidth: 250*Screen.devicePixelRatio;
|
||||
maximumWidth: 250*Screen.devicePixelRatio;
|
||||
width: 350*Screen.devicePixelRatio;
|
||||
minimumWidth: 350*Screen.devicePixelRatio;
|
||||
maximumWidth: 350*Screen.devicePixelRatio;
|
||||
|
||||
height: 200*Screen.devicePixelRatio;
|
||||
minimumHeight: 200*Screen.devicePixelRatio;
|
||||
maximumHeight: 200*Screen.devicePixelRatio;
|
||||
height: 220*Screen.devicePixelRatio;
|
||||
minimumHeight: 220*Screen.devicePixelRatio;
|
||||
maximumHeight: 220*Screen.devicePixelRatio;
|
||||
|
||||
|
||||
modality: Qt.Modal
|
||||
|
@ -30,58 +30,158 @@ UM.Dialog
|
|||
Layout.fillWidth: true
|
||||
columnSpacing: 16
|
||||
rowSpacing: 4
|
||||
columns: 2
|
||||
columns: 1
|
||||
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Size (mm)")
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
}
|
||||
TextField {
|
||||
id: size
|
||||
focus: true
|
||||
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;}
|
||||
text: "120"
|
||||
onTextChanged: { manager.onSizeChanged(text) }
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","The maximum distance of each pixel from \"Base.\"")
|
||||
Row {
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Height (mm)")
|
||||
width: 150
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: peak_height
|
||||
objectName: "Peak_Height"
|
||||
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: -500; top: 500;}
|
||||
width: 180
|
||||
onTextChanged: { manager.onPeakHeightChanged(text) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Base Height (mm)")
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
}
|
||||
TextField {
|
||||
id: base_height
|
||||
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 0; top: 500;}
|
||||
text: "2"
|
||||
onTextChanged: { manager.onBaseHeightChanged(text) }
|
||||
}
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","The base height from the build plate in millimeters.")
|
||||
Row {
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Peak Height (mm)")
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Base (mm)")
|
||||
width: 150
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: base_height
|
||||
objectName: "Base_Height"
|
||||
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 0; top: 500;}
|
||||
width: 180
|
||||
onTextChanged: { manager.onBaseHeightChanged(text) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
}
|
||||
TextField {
|
||||
id: peak_height
|
||||
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 0; top: 500;}
|
||||
text: "12"
|
||||
onTextChanged: { manager.onPeakHeightChanged(text) }
|
||||
}
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","The width in millimeters on the build plate.")
|
||||
Row {
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Smoothing")
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Width (mm)")
|
||||
width: 150
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: width
|
||||
objectName: "Width"
|
||||
focus: true
|
||||
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;}
|
||||
width: 180
|
||||
onTextChanged: { manager.onWidthChanged(text) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
}
|
||||
Rectangle {
|
||||
width: 100
|
||||
height: 20
|
||||
color: "transparent"
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","The depth in millimeters on the build plate")
|
||||
Row {
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
Slider {
|
||||
id: smoothing
|
||||
maximumValue: 100.0
|
||||
stepSize: 1.0
|
||||
value: 1
|
||||
width: 100
|
||||
onValueChanged: { manager.onSmoothingChanged(value) }
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Depth (mm)")
|
||||
width: 150
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
TextField {
|
||||
id: depth
|
||||
objectName: "Depth"
|
||||
focus: true
|
||||
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;}
|
||||
width: 180
|
||||
onTextChanged: { manager.onDepthChanged(text) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh.")
|
||||
Row {
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
//Empty label so 2 column layout works.
|
||||
Text {
|
||||
text: ""
|
||||
width: 150
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
ComboBox {
|
||||
id: image_color_invert
|
||||
objectName: "Image_Color_Invert"
|
||||
model: [ catalog.i18nc("@action:label","Lighter is higher"), catalog.i18nc("@action:label","Darker is higher") ]
|
||||
width: 180
|
||||
onCurrentIndexChanged: { manager.onImageColorInvertChanged(currentIndex) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","The amount of smoothing to apply to the image.")
|
||||
Row {
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
Text {
|
||||
text: catalog.i18nc("@action:label","Smoothing")
|
||||
width: 150
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 180
|
||||
height: 20
|
||||
Layout.fillWidth:true
|
||||
color: "transparent"
|
||||
|
||||
Slider {
|
||||
id: smoothing
|
||||
objectName: "Smoothing"
|
||||
maximumValue: 100.0
|
||||
stepSize: 1.0
|
||||
width: 180
|
||||
onValueChanged: { manager.onSmoothingChanged(value) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,20 @@ class ImageReader(MeshReader):
|
|||
self._ui = ImageReaderUI(self)
|
||||
|
||||
def preRead(self, file_name):
|
||||
img = QImage(file_name)
|
||||
|
||||
if img.isNull():
|
||||
Logger.log("e", "Image is corrupt.")
|
||||
return MeshReader.PreReadResult.failed
|
||||
|
||||
width = img.width()
|
||||
depth = img.height()
|
||||
|
||||
largest = max(width, depth)
|
||||
width = width/largest*self._ui.defaultWidth
|
||||
depth = depth/largest*self._ui.defaultDepth
|
||||
|
||||
self._ui.setWidthAndDepth(width, depth)
|
||||
self._ui.showConfigUI()
|
||||
self._ui.waitForUIToClose()
|
||||
|
||||
|
@ -31,9 +45,10 @@ class ImageReader(MeshReader):
|
|||
return MeshReader.PreReadResult.accepted
|
||||
|
||||
def read(self, file_name):
|
||||
return self._generateSceneNode(file_name, self._ui.size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512)
|
||||
size = max(self._ui.getWidth(), self._ui.getDepth())
|
||||
return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.image_color_invert)
|
||||
|
||||
def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size):
|
||||
def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, image_color_invert):
|
||||
mesh = None
|
||||
scene_node = None
|
||||
|
||||
|
@ -56,9 +71,10 @@ class ImageReader(MeshReader):
|
|||
img = img.scaled(width, height, Qt.IgnoreAspectRatio)
|
||||
|
||||
base_height = max(base_height, 0)
|
||||
peak_height = max(peak_height, -base_height)
|
||||
|
||||
xz_size = max(xz_size, 1)
|
||||
scale_vector = Vector(xz_size, max(peak_height - base_height, -base_height), xz_size)
|
||||
scale_vector = Vector(xz_size, peak_height, xz_size)
|
||||
|
||||
if width > height:
|
||||
scale_vector.setZ(scale_vector.z * aspect)
|
||||
|
@ -92,6 +108,9 @@ class ImageReader(MeshReader):
|
|||
|
||||
Job.yieldThread()
|
||||
|
||||
if image_color_invert:
|
||||
height_data = 1-height_data
|
||||
|
||||
for i in range(0, blur_iterations):
|
||||
copy = numpy.pad(height_data, ((1, 1), (1, 1)), mode='edge')
|
||||
|
||||
|
|
|
@ -24,15 +24,32 @@ class ImageReaderUI(QObject):
|
|||
self._ui_view = None
|
||||
self.show_config_ui_trigger.connect(self._actualShowConfigUI)
|
||||
|
||||
# There are corresponding values for these fields in ConfigUI.qml.
|
||||
# If you change the values here, consider updating ConfigUI.qml as well.
|
||||
self.size = 120
|
||||
self.base_height = 2
|
||||
self.peak_height = 12
|
||||
self.defaultWidth = 120
|
||||
self.defaultDepth = 120
|
||||
|
||||
self._aspect = 1
|
||||
self._width = self.defaultWidth
|
||||
self._depth = self.defaultDepth
|
||||
|
||||
self.base_height = 1
|
||||
self.peak_height = 10
|
||||
self.smoothing = 1
|
||||
self.image_color_invert = False;
|
||||
|
||||
self._ui_lock = threading.Lock()
|
||||
self._cancelled = False
|
||||
self._disable_size_callbacks = False
|
||||
|
||||
def setWidthAndDepth(self, width, depth):
|
||||
self._aspect = width/depth
|
||||
self._width = width
|
||||
self._depth = depth
|
||||
|
||||
def getWidth(self):
|
||||
return self._width
|
||||
|
||||
def getDepth(self):
|
||||
return self._depth
|
||||
|
||||
def getCancelled(self):
|
||||
return self._cancelled
|
||||
|
@ -47,10 +64,20 @@ class ImageReaderUI(QObject):
|
|||
self.show_config_ui_trigger.emit()
|
||||
|
||||
def _actualShowConfigUI(self):
|
||||
self._disable_size_callbacks = True
|
||||
|
||||
if self._ui_view is None:
|
||||
self._createConfigUI()
|
||||
self._ui_view.show()
|
||||
|
||||
self._ui_view.findChild(QObject, "Width").setProperty("text", str(self._width))
|
||||
self._ui_view.findChild(QObject, "Depth").setProperty("text", str(self._depth))
|
||||
self._disable_size_callbacks = False
|
||||
|
||||
self._ui_view.findChild(QObject, "Base_Height").setProperty("text", str(self.base_height))
|
||||
self._ui_view.findChild(QObject, "Peak_Height").setProperty("text", str(self.peak_height))
|
||||
self._ui_view.findChild(QObject, "Smoothing").setProperty("value", self.smoothing)
|
||||
|
||||
def _createConfigUI(self):
|
||||
if self._ui_view is None:
|
||||
Logger.log("d", "Creating ImageReader config UI")
|
||||
|
@ -62,6 +89,8 @@ class ImageReaderUI(QObject):
|
|||
|
||||
self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint);
|
||||
|
||||
self._disable_size_callbacks = False
|
||||
|
||||
@pyqtSlot()
|
||||
def onOkButtonClicked(self):
|
||||
self._cancelled = False
|
||||
|
@ -75,11 +104,30 @@ class ImageReaderUI(QObject):
|
|||
self._ui_lock.release()
|
||||
|
||||
@pyqtSlot(str)
|
||||
def onSizeChanged(self, value):
|
||||
if (len(value) > 0):
|
||||
self.size = float(value)
|
||||
else:
|
||||
self.size = 0
|
||||
def onWidthChanged(self, value):
|
||||
if self._ui_view and not self._disable_size_callbacks:
|
||||
if (len(value) > 0):
|
||||
self._width = float(value)
|
||||
else:
|
||||
self._width = 0
|
||||
|
||||
self._depth = self._width/self._aspect
|
||||
self._disable_size_callbacks = True
|
||||
self._ui_view.findChild(QObject, "Depth").setProperty("text", str(self._depth))
|
||||
self._disable_size_callbacks = False
|
||||
|
||||
@pyqtSlot(str)
|
||||
def onDepthChanged(self, value):
|
||||
if self._ui_view and not self._disable_size_callbacks:
|
||||
if (len(value) > 0):
|
||||
self._depth = float(value)
|
||||
else:
|
||||
self._depth = 0
|
||||
|
||||
self._width = self._depth*self._aspect
|
||||
self._disable_size_callbacks = True
|
||||
self._ui_view.findChild(QObject, "Width").setProperty("text", str(self._width))
|
||||
self._disable_size_callbacks = False
|
||||
|
||||
@pyqtSlot(str)
|
||||
def onBaseHeightChanged(self, value):
|
||||
|
@ -98,3 +146,10 @@ class ImageReaderUI(QObject):
|
|||
@pyqtSlot(float)
|
||||
def onSmoothingChanged(self, value):
|
||||
self.smoothing = int(value)
|
||||
|
||||
@pyqtSlot(int)
|
||||
def onImageColorInvertChanged(self, value):
|
||||
if (value == 1):
|
||||
self.image_color_invert = True
|
||||
else:
|
||||
self.image_color_invert = False
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue