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:
Kurt Loeffler 2016-01-13 20:00:30 -08:00
parent b8cf51349c
commit b28bfc9602
3 changed files with 235 additions and 61 deletions

View file

@ -10,13 +10,13 @@ import UM 1.1 as UM
UM.Dialog UM.Dialog
{ {
width: 250*Screen.devicePixelRatio; width: 350*Screen.devicePixelRatio;
minimumWidth: 250*Screen.devicePixelRatio; minimumWidth: 350*Screen.devicePixelRatio;
maximumWidth: 250*Screen.devicePixelRatio; maximumWidth: 350*Screen.devicePixelRatio;
height: 200*Screen.devicePixelRatio; height: 220*Screen.devicePixelRatio;
minimumHeight: 200*Screen.devicePixelRatio; minimumHeight: 220*Screen.devicePixelRatio;
maximumHeight: 200*Screen.devicePixelRatio; maximumHeight: 220*Screen.devicePixelRatio;
modality: Qt.Modal modality: Qt.Modal
@ -30,58 +30,158 @@ UM.Dialog
Layout.fillWidth: true Layout.fillWidth: true
columnSpacing: 16 columnSpacing: 16
rowSpacing: 4 rowSpacing: 4
columns: 2 columns: 1
Text { UM.TooltipArea {
text: catalog.i18nc("@action:label","Size (mm)")
Layout.fillWidth:true Layout.fillWidth:true
} height: childrenRect.height
TextField { text: catalog.i18nc("@info:tooltip","The maximum distance of each pixel from \"Base.\"")
id: size Row {
focus: true width: parent.width
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 1; top: 500;} height: childrenRect.height
text: "120"
onTextChanged: { manager.onSizeChanged(text) } 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 { UM.TooltipArea {
text: catalog.i18nc("@action:label","Base Height (mm)")
Layout.fillWidth:true Layout.fillWidth:true
} height: childrenRect.height
TextField { text: catalog.i18nc("@info:tooltip","The base height from the build plate in millimeters.")
id: base_height Row {
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 0; top: 500;} width: parent.width
text: "2" height: childrenRect.height
onTextChanged: { manager.onBaseHeightChanged(text) }
}
Text { Text {
text: catalog.i18nc("@action:label","Peak Height (mm)") 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 Layout.fillWidth:true
} height: childrenRect.height
TextField { text: catalog.i18nc("@info:tooltip","The width in millimeters on the build plate.")
id: peak_height Row {
validator: DoubleValidator {notation: DoubleValidator.StandardNotation; bottom: 0; top: 500;} width: parent.width
text: "12" height: childrenRect.height
onTextChanged: { manager.onPeakHeightChanged(text) }
}
Text { Text {
text: catalog.i18nc("@action:label","Smoothing") 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 Layout.fillWidth:true
} height: childrenRect.height
Rectangle { text: catalog.i18nc("@info:tooltip","The depth in millimeters on the build plate")
width: 100 Row {
height: 20 width: parent.width
color: "transparent" height: childrenRect.height
Slider { Text {
id: smoothing text: catalog.i18nc("@action:label","Depth (mm)")
maximumValue: 100.0 width: 150
stepSize: 1.0 anchors.verticalCenter: parent.verticalCenter
value: 1 }
width: 100 TextField {
onValueChanged: { manager.onSmoothingChanged(value) } 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) }
}
}
} }
} }
} }

View file

@ -23,6 +23,20 @@ class ImageReader(MeshReader):
self._ui = ImageReaderUI(self) self._ui = ImageReaderUI(self)
def preRead(self, file_name): 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.showConfigUI()
self._ui.waitForUIToClose() self._ui.waitForUIToClose()
@ -31,9 +45,10 @@ class ImageReader(MeshReader):
return MeshReader.PreReadResult.accepted return MeshReader.PreReadResult.accepted
def read(self, file_name): 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 mesh = None
scene_node = None scene_node = None
@ -56,9 +71,10 @@ class ImageReader(MeshReader):
img = img.scaled(width, height, Qt.IgnoreAspectRatio) img = img.scaled(width, height, Qt.IgnoreAspectRatio)
base_height = max(base_height, 0) base_height = max(base_height, 0)
peak_height = max(peak_height, -base_height)
xz_size = max(xz_size, 1) 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: if width > height:
scale_vector.setZ(scale_vector.z * aspect) scale_vector.setZ(scale_vector.z * aspect)
@ -92,6 +108,9 @@ class ImageReader(MeshReader):
Job.yieldThread() Job.yieldThread()
if image_color_invert:
height_data = 1-height_data
for i in range(0, blur_iterations): for i in range(0, blur_iterations):
copy = numpy.pad(height_data, ((1, 1), (1, 1)), mode='edge') copy = numpy.pad(height_data, ((1, 1), (1, 1)), mode='edge')

View file

@ -24,15 +24,32 @@ class ImageReaderUI(QObject):
self._ui_view = None self._ui_view = None
self.show_config_ui_trigger.connect(self._actualShowConfigUI) self.show_config_ui_trigger.connect(self._actualShowConfigUI)
# There are corresponding values for these fields in ConfigUI.qml. self.defaultWidth = 120
# If you change the values here, consider updating ConfigUI.qml as well. self.defaultDepth = 120
self.size = 120
self.base_height = 2 self._aspect = 1
self.peak_height = 12 self._width = self.defaultWidth
self._depth = self.defaultDepth
self.base_height = 1
self.peak_height = 10
self.smoothing = 1 self.smoothing = 1
self.image_color_invert = False;
self._ui_lock = threading.Lock() self._ui_lock = threading.Lock()
self._cancelled = False 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): def getCancelled(self):
return self._cancelled return self._cancelled
@ -47,10 +64,20 @@ class ImageReaderUI(QObject):
self.show_config_ui_trigger.emit() self.show_config_ui_trigger.emit()
def _actualShowConfigUI(self): def _actualShowConfigUI(self):
self._disable_size_callbacks = True
if self._ui_view is None: if self._ui_view is None:
self._createConfigUI() self._createConfigUI()
self._ui_view.show() 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): def _createConfigUI(self):
if self._ui_view is None: if self._ui_view is None:
Logger.log("d", "Creating ImageReader config UI") 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._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint);
self._disable_size_callbacks = False
@pyqtSlot() @pyqtSlot()
def onOkButtonClicked(self): def onOkButtonClicked(self):
self._cancelled = False self._cancelled = False
@ -75,11 +104,30 @@ class ImageReaderUI(QObject):
self._ui_lock.release() self._ui_lock.release()
@pyqtSlot(str) @pyqtSlot(str)
def onSizeChanged(self, value): def onWidthChanged(self, value):
if (len(value) > 0): if self._ui_view and not self._disable_size_callbacks:
self.size = float(value) if (len(value) > 0):
else: self._width = float(value)
self.size = 0 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) @pyqtSlot(str)
def onBaseHeightChanged(self, value): def onBaseHeightChanged(self, value):
@ -98,3 +146,10 @@ class ImageReaderUI(QObject):
@pyqtSlot(float) @pyqtSlot(float)
def onSmoothingChanged(self, value): def onSmoothingChanged(self, value):
self.smoothing = int(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