diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index 2b97feec82..7065b71735 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -253,21 +253,21 @@ class ConvexHullDecorator(SceneNodeDecorator): ## Offset the convex hull with settings that influence the collision area. # - # This also applies a minimum offset of 0.5mm, because of edge cases due - # to the rounding we apply. - # # \param convex_hull Polygon of the original convex hull. # \return New Polygon instance that is offset with everything that # influences the collision area. def _offsetHull(self, convex_hull): - horizontal_expansion = max(0.5, self._getSettingProperty("xy_offset", "value")) - expansion_polygon = Polygon(numpy.array([ - [-horizontal_expansion, -horizontal_expansion], - [-horizontal_expansion, horizontal_expansion], - [horizontal_expansion, horizontal_expansion], - [horizontal_expansion, -horizontal_expansion] - ], numpy.float32)) - return convex_hull.getMinkowskiHull(expansion_polygon) + horizontal_expansion = self._getSettingProperty("xy_offset", "value") + if horizontal_expansion != 0: + expansion_polygon = Polygon(numpy.array([ + [-horizontal_expansion, -horizontal_expansion], + [-horizontal_expansion, horizontal_expansion], + [horizontal_expansion, horizontal_expansion], + [horizontal_expansion, -horizontal_expansion] + ], numpy.float32)) + return convex_hull.getMinkowskiHull(expansion_polygon) + else: + return convex_hull def _onChanged(self, *args): self._raft_thickness = self._build_volume.getRaftThickness() diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py index c696081ca3..7e54cabacd 100755 --- a/plugins/LayerView/LayerView.py +++ b/plugins/LayerView/LayerView.py @@ -163,6 +163,8 @@ class LayerView(View): self._current_layer_num = 0 if self._current_layer_num > self._max_layers: self._current_layer_num = self._max_layers + if self._current_layer_num < self._minimum_layer_num: + self._minimum_layer_num = self._current_layer_num self._startUpdateTopLayers() @@ -173,6 +175,10 @@ class LayerView(View): self._minimum_layer_num = value if self._minimum_layer_num < 0: self._minimum_layer_num = 0 + if self._minimum_layer_num > self._max_layers: + self._minimum_layer_num = self._max_layers + if self._minimum_layer_num > self._current_layer_num: + self._current_layer_num = self._minimum_layer_num self._startUpdateTopLayers() @@ -279,13 +285,15 @@ class LayerView(View): def event(self, event): modifiers = QApplication.keyboardModifiers() - ctrl_is_active = modifiers == Qt.ControlModifier + ctrl_is_active = modifiers & Qt.ControlModifier + shift_is_active = modifiers & Qt.ShiftModifier if event.type == Event.KeyPressEvent and ctrl_is_active: + amount = 10 if shift_is_active else 1 if event.key == KeyEvent.UpKey: - self.setLayer(self._current_layer_num + 1) + self.setLayer(self._current_layer_num + amount) return True if event.key == KeyEvent.DownKey: - self.setLayer(self._current_layer_num - 1) + self.setLayer(self._current_layer_num - amount) return True if event.type == Event.ViewActivateEvent: diff --git a/plugins/LayerView/LayerView.qml b/plugins/LayerView/LayerView.qml index a24409e8d6..cb8a27d55d 100644 --- a/plugins/LayerView/LayerView.qml +++ b/plugins/LayerView/LayerView.qml @@ -10,7 +10,6 @@ import UM 1.0 as UM Item { - id: base width: { if (UM.LayerView.compatibilityMode) { return UM.Theme.getSize("layerview_menu_size_compatibility").width; @@ -324,86 +323,254 @@ Item } - Slider - { - id: sliderMinimumLayer - - anchors { - top: parent.top - bottom: parent.bottom - right: layerViewMenu.right - margins: UM.Theme.getSize("slider_layerview_margin").height - rightMargin: UM.Theme.getSize("slider_layerview_margin").width * 0.8 - } - width: UM.Theme.getSize("slider_layerview_size").width - orientation: Qt.Vertical - minimumValue: 0; - maximumValue: UM.LayerView.numLayers - 1; - stepSize: 1 - - property real pixelsPerStep: ((height - UM.Theme.getSize("slider_handle").height) / (maximumValue - minimumValue)) * stepSize - - value: UM.LayerView.minimumLayer - onValueChanged: { - UM.LayerView.setMinimumLayer(value) - if (value > UM.LayerView.currentLayer) { - UM.LayerView.setCurrentLayer(value); - } - } - - style: UM.Theme.styles.slider; - } - - Slider + Item { id: slider + width: handleSize + height: parent.height - 2*UM.Theme.getSize("slider_layerview_margin").height + anchors.top: parent.top + anchors.topMargin: UM.Theme.getSize("slider_layerview_margin").height + anchors.right: layerViewMenu.right + anchors.rightMargin: UM.Theme.getSize("slider_layerview_margin").width - anchors { - top: parent.top - bottom: parent.bottom - right: layerViewMenu.right - margins: UM.Theme.getSize("slider_layerview_margin").height - rightMargin: UM.Theme.getSize("slider_layerview_margin").width * 0.2 + property real handleSize: UM.Theme.getSize("slider_handle").width + property real handleRadius: handleSize / 2 + property real minimumRangeHandleSize: UM.Theme.getSize("slider_handle").width / 2 + property real trackThickness: UM.Theme.getSize("slider_groove").width + property real trackRadius: trackThickness / 2 + property real trackBorderWidth: UM.Theme.getSize("default_lining").width + property color upperHandleColor: UM.Theme.getColor("slider_handle") + property color lowerHandleColor: UM.Theme.getColor("slider_handle") + property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill") + property color trackColor: UM.Theme.getColor("slider_groove") + property color trackBorderColor: UM.Theme.getColor("slider_groove_border") + + property real maximumValue: UM.LayerView.numLayers + property real minimumValue: 0 + property real minimumRange: 0 + property bool roundValues: true + + property var activeHandle: upperHandle + property bool layersVisible: UM.LayerView.layerActivity && Printer.platformActivity ? true : false + + function getUpperValueFromHandle() + { + var result = upperHandle.y / (height - (2 * handleSize + minimumRangeHandleSize)); + result = maximumValue + result * (minimumValue - (maximumValue - minimumRange)); + result = roundValues ? Math.round(result) | 0 : result; + return result; } - width: UM.Theme.getSize("slider_layerview_size").width - orientation: Qt.Vertical - minimumValue: 0; - maximumValue: UM.LayerView.numLayers; - stepSize: 1 + function getLowerValueFromHandle() + { + var result = (lowerHandle.y - (handleSize + minimumRangeHandleSize)) / (height - (2 * handleSize + minimumRangeHandleSize)); + result = maximumValue - minimumRange + result * (minimumValue - (maximumValue - minimumRange)); + result = roundValues ? Math.round(result) : result; + return result; + } - property real pixelsPerStep: ((height - UM.Theme.getSize("slider_handle").height) / (maximumValue - minimumValue)) * stepSize; + function setUpperValue(value) + { + var value = (value - maximumValue) / (minimumValue - maximumValue); + var new_upper_y = Math.round(value * (height - (2 * handleSize + minimumRangeHandleSize))); - value: UM.LayerView.currentLayer - onValueChanged: { + if(new_upper_y != upperHandle.y) + { + upperHandle.y = new_upper_y; + } + rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height); + } + + function setLowerValue(value) + { + var value = (value - maximumValue) / (minimumValue - maximumValue); + var new_lower_y = Math.round((handleSize + minimumRangeHandleSize) + value * (height - (2 * handleSize + minimumRangeHandleSize))); + + if(new_lower_y != lowerHandle.y) + { + lowerHandle.y = new_lower_y; + } + rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height); + } + + Connections + { + target: UM.LayerView + onMinimumLayerChanged: slider.setLowerValue(UM.LayerView.minimumLayer) + onCurrentLayerChanged: slider.setUpperValue(UM.LayerView.currentLayer) + } + + Rectangle { + width: parent.trackThickness + height: parent.height - parent.handleSize + radius: parent.trackRadius + anchors.centerIn: parent + color: parent.trackColor + border.width: parent.trackBorderWidth; + border.color: parent.trackBorderColor; + } + + Item { + id: rangeHandle + y: upperHandle.y + upperHandle.height + width: parent.handleSize + height: parent.minimumRangeHandleSize + anchors.horizontalCenter: parent.horizontalCenter + + visible: slider.layersVisible + + property real value: UM.LayerView.currentLayer + function setValue(value) + { + var range = upperHandle.value - lowerHandle.value; + value = Math.min(value, slider.maximumValue); + value = Math.max(value, slider.minimumValue + range); UM.LayerView.setCurrentLayer(value); - if (value < UM.LayerView.minimumLayer) { - UM.LayerView.setMinimumLayer(value); - } + UM.LayerView.setMinimumLayer(value - range); } - style: UM.Theme.styles.slider; + Rectangle { + anchors.centerIn: parent + width: parent.parent.trackThickness - 2 * parent.parent.trackBorderWidth + height: parent.height + parent.parent.handleSize + color: parent.parent.rangeHandleColor + } - Rectangle + MouseArea { + anchors.fill: parent + + drag.target: parent + drag.axis: Drag.YAxis + drag.minimumY: upperHandle.height + drag.maximumY: parent.parent.height - (parent.height + lowerHandle.height) + + onPressed: parent.parent.activeHandle = rangeHandle + onPositionChanged: + { + upperHandle.y = parent.y - upperHandle.height + lowerHandle.y = parent.y + parent.height + + var upper_value = slider.getUpperValueFromHandle(); + var lower_value = upper_value - (upperHandle.value - lowerHandle.value); + UM.LayerView.setCurrentLayer(upper_value); + UM.LayerView.setMinimumLayer(lower_value); + } + } + } + + Rectangle { + id: upperHandle + y: parent.height - (parent.minimumRangeHandleSize + 2 * parent.handleSize) + width: parent.handleSize + height: parent.handleSize + anchors.horizontalCenter: parent.horizontalCenter + radius: parent.handleRadius + color: parent.upperHandleColor + + visible: slider.layersVisible + + property real value: UM.LayerView.currentLayer + function setValue(value) + { + UM.LayerView.setCurrentLayer(value); + } + + MouseArea { + anchors.fill: parent + + drag.target: parent + drag.axis: Drag.YAxis + drag.minimumY: 0 + drag.maximumY: parent.parent.height - (2 * parent.parent.handleSize + parent.parent.minimumRangeHandleSize) + + onPressed: parent.parent.activeHandle = upperHandle + onPositionChanged: + { + if(lowerHandle.y - (upperHandle.y + upperHandle.height) < parent.parent.minimumRangeHandleSize) + { + lowerHandle.y = upperHandle.y + upperHandle.height + parent.parent.minimumRangeHandleSize; + } + rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height); + + UM.LayerView.setCurrentLayer(slider.getUpperValueFromHandle()); + } + } + } + + Rectangle { + id: lowerHandle + y: parent.height - parent.handleSize + width: parent.handleSize + height: parent.handleSize + anchors.horizontalCenter: parent.horizontalCenter + radius: parent.handleRadius + color: parent.lowerHandleColor + + visible: slider.layersVisible + + property real value: UM.LayerView.minimumLayer + function setValue(value) + { + UM.LayerView.setMinimumLayer(value); + } + + MouseArea { + anchors.fill: parent + + drag.target: parent + drag.axis: Drag.YAxis + drag.minimumY: upperHandle.height + parent.parent.minimumRangeHandleSize + drag.maximumY: parent.parent.height - parent.height + + onPressed: parent.parent.activeHandle = lowerHandle + onPositionChanged: + { + if(lowerHandle.y - (upperHandle.y + upperHandle.height) < parent.parent.minimumRangeHandleSize) + { + upperHandle.y = lowerHandle.y - (upperHandle.height + parent.parent.minimumRangeHandleSize); + } + rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height) + + UM.LayerView.setMinimumLayer(slider.getLowerValueFromHandle()); + } + } + } + + UM.PointingRectangle { x: parent.width + UM.Theme.getSize("slider_layerview_background").width / 2; - y: parent.height - (parent.value * parent.pixelsPerStep) - UM.Theme.getSize("slider_handle").height * 1.25; + y: Math.floor(slider.activeHandle.y + slider.activeHandle.height / 2 - height / 2); - height: UM.Theme.getSize("slider_handle").height + UM.Theme.getSize("default_margin").height + target: Qt.point(0, slider.activeHandle.y + slider.activeHandle.height / 2) + arrowSize: UM.Theme.getSize("default_arrow").width + + height: (Math.floor(UM.Theme.getSize("slider_handle").height + UM.Theme.getSize("default_margin").height) / 2) * 2 // Make sure height has an integer middle so drawing a pointy border is easier width: valueLabel.width + UM.Theme.getSize("default_margin").width Behavior on height { NumberAnimation { duration: 50; } } - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("slider_groove_border") - color: UM.Theme.getColor("tool_panel_background") + color: UM.Theme.getColor("lining"); - visible: UM.LayerView.layerActivity && Printer.platformActivity ? true : false + visible: slider.layersVisible + + UM.PointingRectangle + { + color: UM.Theme.getColor("tool_panel_background") + target: Qt.point(0, height / 2 + UM.Theme.getSize("default_lining").width) + arrowSize: UM.Theme.getSize("default_arrow").width + anchors.fill: parent + anchors.margins: UM.Theme.getSize("default_lining").width + + MouseArea //Catch all mouse events (so scene doesnt handle them) + { + anchors.fill: parent + } + } TextField { id: valueLabel property string maxValue: slider.maximumValue + 1 - text: slider.value + 1 + text: slider.activeHandle.value + 1 horizontalAlignment: TextInput.AlignRight; onEditingFinished: { @@ -413,7 +580,7 @@ Item cursorPosition = 0; if(valueLabel.text != '') { - slider.value = valueLabel.text - 1; + slider.activeHandle.setValue(valueLabel.text - 1); } } validator: IntValidator { bottom: 1; top: slider.maximumValue + 1; } @@ -429,6 +596,9 @@ Item font: UM.Theme.getFont("default"); background: Item { } } + + Keys.onUpPressed: slider.activeHandle.setValue(slider.activeHandle.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) + Keys.onDownPressed: slider.activeHandle.setValue(slider.activeHandle.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) } BusyIndicator diff --git a/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py index 9f0a8b20f5..b89ed58f18 100644 --- a/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py @@ -327,6 +327,9 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): ## Set the authentication state. # \param auth_state \type{AuthState} Enum value representing the new auth state def setAuthenticationState(self, auth_state): + if auth_state == self._authentication_state: + return # Nothing to do here. + if auth_state == AuthState.AuthenticationRequested: Logger.log("d", "Authentication state changed to authentication requested.") self.setAcceptsCommands(False) @@ -367,9 +370,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._authentication_timer.stop() self._authentication_counter = 0 - if auth_state != self._authentication_state: - self._authentication_state = auth_state - self.authenticationStateChanged.emit() + self._authentication_state = auth_state + self.authenticationStateChanged.emit() authenticationStateChanged = pyqtSignal() diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 7f75c8361e..008e332eca 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1325,8 +1325,9 @@ "unit": "°", "type": "float", "minimum_value": "0", - "maximum_value": "90", + "minimum_value_warning": "2", "maximum_value_warning": "45", + "maximum_value": "90", "default_value": 20, "enabled": "expand_upper_skins or expand_lower_skins", "settable_per_mesh": true, diff --git a/resources/themes/cura/theme.json b/resources/themes/cura/theme.json index bd3fbb6dc6..fa4bf2ee92 100644 --- a/resources/themes/cura/theme.json +++ b/resources/themes/cura/theme.json @@ -292,7 +292,7 @@ "slider_handle": [1.5, 1.5], "slider_layerview_size": [1.0, 22.0], "slider_layerview_background": [4.0, 0.0], - "slider_layerview_margin": [3.0, 1.0], + "slider_layerview_margin": [1.0, 1.0], "layerview_menu_size": [16.5, 21.0], "layerview_menu_size_compatibility": [22, 23.0],