diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index e59c4e2895..5376f6e6ce 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -198,6 +198,8 @@ class CuraApplication(QtApplication): self._container_manager = None self._object_manager = None + self._extruders_model = None + self._extruders_model_with_optional = None self._build_plate_model = None self._multi_build_plate_model = None self._setting_visibility_presets_model = None @@ -855,6 +857,19 @@ class CuraApplication(QtApplication): self._object_manager = ObjectsModel.createObjectsModel() return self._object_manager + @pyqtSlot(result = QObject) + def getExtrudersModel(self, *args) -> "ExtrudersModel": + if self._extruders_model is None: + self._extruders_model = ExtrudersModel(self) + return self._extruders_model + + @pyqtSlot(result = QObject) + def getExtrudersModelWithOptional(self, *args) -> "ExtrudersModel": + if self._extruders_model_with_optional is None: + self._extruders_model_with_optional = ExtrudersModel(self) + self._extruders_model_with_optional.setAddOptionalExtruder(True) + return self._extruders_model_with_optional + @pyqtSlot(result = QObject) def getMultiBuildPlateModel(self, *args) -> MultiBuildPlateModel: if self._multi_build_plate_model is None: diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py index 9d97106d6b..785ff5b9b9 100644 --- a/cura/Machines/Models/NozzleModel.py +++ b/cura/Machines/Models/NozzleModel.py @@ -33,8 +33,6 @@ class NozzleModel(ListModel): def _update(self): Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__)) - self.items.clear() - global_stack = self._machine_manager.activeMachine if global_stack is None: self.setItems([]) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index e19617c8ef..076cebf60d 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty, QTimer +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer from typing import Iterable from UM.i18n import i18nCatalog @@ -78,8 +78,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self._update_extruder_timer.setSingleShot(True) self._update_extruder_timer.timeout.connect(self.__updateExtruders) - self._simple_names = False - self._active_machine_extruders = [] # type: Iterable[ExtruderStack] self._add_optional_extruder = False @@ -101,21 +99,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def addOptionalExtruder(self): return self._add_optional_extruder - ## Set the simpleNames property. - def setSimpleNames(self, simple_names): - if simple_names != self._simple_names: - self._simple_names = simple_names - self.simpleNamesChanged.emit() - self._updateExtruders() - - ## Emitted when the simpleNames property changes. - simpleNamesChanged = pyqtSignal() - - ## Whether or not the model should show all definitions regardless of visibility. - @pyqtProperty(bool, fset = setSimpleNames, notify = simpleNamesChanged) - def simpleNames(self): - return self._simple_names - ## Links to the stack-changed signal of the new extruders when an extruder # is swapped out or added in the current machine. # @@ -221,7 +204,12 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "enabled": True, "color": "#ffffff", "index": -1, - "definition": "" + "definition": "", + "material": "", + "variant": "", + "stack": None, + "material_brand": "", + "color_name": "", } items.append(item) if self._items != items: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c375ce01d1..e26b82e487 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -88,12 +88,14 @@ class MachineManager(QObject): self._onGlobalContainerChanged() - ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + extruder_manager = self._application.getExtruderManager() + + extruder_manager.activeExtruderChanged.connect(self._onActiveExtruderStackChanged) self._onActiveExtruderStackChanged() - ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) - ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) - ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) + extruder_manager.activeExtruderChanged.connect(self.activeMaterialChanged) + extruder_manager.activeExtruderChanged.connect(self.activeVariantChanged) + extruder_manager.activeExtruderChanged.connect(self.activeQualityChanged) self.globalContainerChanged.connect(self.activeStackChanged) self.globalValueChanged.connect(self.activeStackValueChanged) diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index fce43243bd..210a5794d4 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty +from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot from UM.Application import Application @@ -16,12 +16,12 @@ class SimpleModeSettingsManager(QObject): self._is_profile_user_created = False # True when profile was custom created by user self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized) - self._machine_manager.activeQualityGroupChanged.connect(self._updateIsProfileUserCreated) - self._machine_manager.activeQualityChangesGroupChanged.connect(self._updateIsProfileUserCreated) + self._machine_manager.activeQualityGroupChanged.connect(self.updateIsProfileUserCreated) + self._machine_manager.activeQualityChangesGroupChanged.connect(self.updateIsProfileUserCreated) # update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts self._updateIsProfileCustomized() - self._updateIsProfileUserCreated() + self.updateIsProfileUserCreated() isProfileCustomizedChanged = pyqtSignal() isProfileUserCreatedChanged = pyqtSignal() @@ -61,7 +61,8 @@ class SimpleModeSettingsManager(QObject): def isProfileUserCreated(self): return self._is_profile_user_created - def _updateIsProfileUserCreated(self): + @pyqtSlot() + def updateIsProfileUserCreated(self) -> None: quality_changes_keys = set() if not self._machine_manager.activeMachine: diff --git a/cura/Stages/CuraStage.py b/cura/Stages/CuraStage.py index e8537fb6b9..844b0d0768 100644 --- a/cura/Stages/CuraStage.py +++ b/cura/Stages/CuraStage.py @@ -24,10 +24,6 @@ class CuraStage(Stage): def mainComponent(self) -> QUrl: return self.getDisplayComponent("main") - @pyqtProperty(QUrl, constant = True) - def sidebarComponent(self) -> QUrl: - return self.getDisplayComponent("sidebar") - @pyqtProperty(QUrl, constant = True) def stageMenuComponent(self) -> QUrl: return self.getDisplayComponent("menu") \ No newline at end of file diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index c88a721a84..d8efe6f8b8 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -13,7 +13,7 @@ import Cura 1.0 as Cura Cura.MachineAction { id: base - property var extrudersModel: Cura.ExtrudersModel{} + property var extrudersModel: CuraApplication.getExtrudersModel() property int extruderTabsCount: 0 property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : "" diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index 1f287fc0fa..8f113735ee 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -35,6 +35,6 @@ Item property real maximumWidth: parent.width property real maximumHeight: parent.height - sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null + sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem : null } } diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index b7980bc30b..b62d65254d 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -100,7 +100,7 @@ Item source: UM.Theme.getIcon("load") width: UM.Theme.getSize("button_icon").width height: UM.Theme.getSize("button_icon").height - color: UM.Theme.getColor("toolbar_button_text") + color: UM.Theme.getColor("icon") sourceSize.height: height } diff --git a/plugins/PrepareStage/PrepareStage.py b/plugins/PrepareStage/PrepareStage.py index b22f3385b8..b0f862dc48 100644 --- a/plugins/PrepareStage/PrepareStage.py +++ b/plugins/PrepareStage/PrepareStage.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os.path from UM.Application import Application @@ -15,9 +15,5 @@ class PrepareStage(CuraStage): Application.getInstance().engineCreatedSignal.connect(self._engineCreated) def _engineCreated(self): - sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), - "PrepareSidebar.qml") - menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("PrepareStage"), "PrepareMenu.qml") self.addDisplayComponent("menu", menu_component_path) - self.addDisplayComponent("sidebar", sidebar_component_path) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 9f43252126..eec254c0dd 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -163,7 +163,7 @@ Cura.ExpandableComponent Repeater { - model: Cura.ExtrudersModel{} + model: CuraApplication.getExtrudersModel() CheckBox { diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index b9ad5c8829..797d6dabec 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -12,7 +12,6 @@ from UM.Math.Color import Color from UM.View.GL.OpenGL import OpenGL from cura.Settings.ExtruderManager import ExtruderManager -from cura.Settings.ExtrudersModel import ExtrudersModel import math @@ -29,13 +28,16 @@ class SolidView(View): self._non_printing_shader = None self._support_mesh_shader = None - self._extruders_model = ExtrudersModel() + self._extruders_model = None self._theme = None def beginRendering(self): scene = self.getController().getScene() renderer = self.getRenderer() + if not self._extruders_model: + self._extruders_model = Application.getInstance().getExtrudersModel() + if not self._theme: self._theme = Application.getInstance().getTheme() diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml new file mode 100644 index 0000000000..3dcae6d602 --- /dev/null +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -0,0 +1,104 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import UM 1.0 as UM +import Cura 1.1 as Cura +Item +{ + id: ratingWidget + + property real rating: 0 + property int indexHovered: -1 + property string packageId: "" + + property int userRating: 0 + property bool canRate: false + + signal rated(int rating) + + width: contentRow.width + height: contentRow.height + MouseArea + { + id: mouseArea + anchors.fill: parent + hoverEnabled: ratingWidget.canRate + acceptedButtons: Qt.NoButton + onExited: + { + if(ratingWidget.canRate) + { + ratingWidget.indexHovered = -1 + } + } + + Row + { + id: contentRow + height: childrenRect.height + Repeater + { + model: 5 // We need to get 5 stars + Button + { + id: control + hoverEnabled: true + onHoveredChanged: + { + if(hovered && ratingWidget.canRate) + { + indexHovered = index + } + } + + ToolTip.visible: control.hovered && !ratingWidget.canRate + ToolTip.text: !Cura.API.account.isLoggedIn ? catalog.i18nc("@label", "You need to login first before you can rate"): catalog.i18nc("@label", "You need to install the package before you can rate") + + property bool isStarFilled: + { + // If the entire widget is hovered, override the actual rating. + if(ratingWidget.indexHovered >= 0) + { + return indexHovered >= index + } + + if(ratingWidget.userRating > 0) + { + return userRating >= index +1 + } + + return rating >= index + 1 + } + + contentItem: Item {} + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + background: UM.RecolorImage + { + source: UM.Theme.getIcon(control.isStarFilled ? "star_filled" : "star_empty") + + // Unfilled stars should always have the default color. Only filled stars should change on hover + color: + { + if(!ratingWidget.canRate) + { + return UM.Theme.getColor("rating_star") + } + if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) + { + return UM.Theme.getColor("primary") + } + return UM.Theme.getColor("rating_star") + } + } + onClicked: + { + if(ratingWidget.canRate) + { + rated(index + 1) // Notify anyone who cares about this. + } + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml new file mode 100644 index 0000000000..686058f4e8 --- /dev/null +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -0,0 +1,34 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.4 +import UM 1.1 as UM +import Cura 1.1 as Cura + +Row +{ + id: rating + height: UM.Theme.getSize("rating_star").height + visible: model.average_rating > 0 //Has a rating at all. + spacing: UM.Theme.getSize("thick_lining").width + width: starIcon.width + spacing + numRatingsLabel.width + UM.RecolorImage + { + id: starIcon + source: UM.Theme.getIcon("star_filled") + color: model.user_rating == 0 ? UM.Theme.getColor("rating_star") : UM.Theme.getColor("primary") + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + } + + Label + { + id: numRatingsLabel + text: model.average_rating != undefined ? model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")": "" + verticalAlignment: Text.AlignVCenter + height: starIcon.height + width: contentWidth + anchors.verticalCenter: starIcon.verticalCenter + color: starIcon.color + font: UM.Theme.getFont("small") + renderType: Text.NativeRendering + } +} \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 7983be8aef..92b9fb1198 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -6,6 +6,8 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM +import Cura 1.1 as Cura + Item { id: page @@ -24,7 +26,7 @@ Item right: parent.right rightMargin: UM.Theme.getSize("wide_margin").width } - height: UM.Theme.getSize("toolbox_detail_header").height + height: childrenRect.height + 3 * UM.Theme.getSize("default_margin").width Rectangle { id: thumbnail @@ -37,7 +39,7 @@ Item leftMargin: UM.Theme.getSize("wide_margin").width topMargin: UM.Theme.getSize("wide_margin").height } - color: "white" //Always a white background for image (regardless of theme). + color: UM.Theme.getColor("main_background") Image { anchors.fill: parent @@ -55,19 +57,23 @@ Item top: thumbnail.top left: thumbnail.right leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("wide_margin").width - bottomMargin: UM.Theme.getSize("default_margin").height } text: details === null ? "" : (details.name || "") font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") - wrapMode: Text.WordWrap - width: parent.width - height: UM.Theme.getSize("toolbox_property_label").height + width: contentWidth + height: contentHeight renderType: Text.NativeRendering } + SmallRatingWidget + { + anchors.left: title.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: title.verticalCenter + property var model: details + } + Column { id: properties @@ -81,6 +87,13 @@ Item width: childrenRect.width height: childrenRect.height Label + { + text: catalog.i18nc("@label", "Rating") + ":" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering + } + Label { text: catalog.i18nc("@label", "Version") + ":" font: UM.Theme.getFont("default") @@ -121,6 +134,48 @@ Item } spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) height: childrenRect.height + RatingWidget + { + id: rating + visible: details.type == "plugin" + packageId: details.id != undefined ? details.id: "" + userRating: details.user_rating != undefined ? details.user_rating: 0 + canRate: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn + + onRated: + { + toolbox.ratePackage(details.id, rating) + // HACK: This is a far from optimal solution, but without major refactoring, this is the best we can + // do. Since a rework of this is scheduled, it shouldn't live that long... + var index = toolbox.pluginsAvailableModel.find("id", details.id) + if(index != -1) + { + if(details.user_rating == 0) // User never rated before. + { + toolbox.pluginsAvailableModel.setProperty(index, "num_ratings", details.num_ratings + 1) + } + + toolbox.pluginsAvailableModel.setProperty(index, "user_rating", rating) + + + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. + base.selection = toolbox.pluginsAvailableModel.getItem(index) + return + } + index = toolbox.pluginsShowcaseModel.find("id", details.id) + if(index != -1) + { + if(details.user_rating == 0) // User never rated before. + { + toolbox.pluginsShowcaseModel.setProperty(index, "user_rating", rating) + } + toolbox.pluginsShowcaseModel.setProperty(index, "num_ratings", details.num_ratings + 1) + + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. + base.selection = toolbox.pluginsShowcaseModel.getItem(index) + } + } + } Label { text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) @@ -170,13 +225,6 @@ Item renderType: Text.NativeRendering } } - Rectangle - { - color: UM.Theme.getColor("lining") - width: parent.width - height: UM.Theme.getSize("default_lining").height - anchors.bottom: parent.bottom - } } ToolboxDetailList { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 357e9e9a72..58e4f070e0 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 import UM 1.1 as UM +import Cura 1.1 as Cura Item { @@ -14,94 +15,13 @@ Item property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) height: childrenRect.height Layout.alignment: Qt.AlignTop | Qt.AlignLeft - Rectangle - { - id: highlight - anchors.fill: parent - opacity: 0.0 - color: UM.Theme.getColor("primary") - } - Row - { - width: parent.width - height: childrenRect.height - spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) - Rectangle - { - id: thumbnail - width: UM.Theme.getSize("toolbox_thumbnail_small").width - height: UM.Theme.getSize("toolbox_thumbnail_small").height - color: "white" - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - Image - { - anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width - height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width - fillMode: Image.PreserveAspectFit - source: model.icon_url || "../images/logobot.svg" - mipmap: true - } - UM.RecolorImage - { - width: (parent.width * 0.4) | 0 - height: (parent.height * 0.4) | 0 - anchors - { - bottom: parent.bottom - right: parent.right - } - sourceSize.height: height - visible: installedPackages != 0 - color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") - source: "../images/installed_check.svg" - } - } - Column - { - width: parent.width - thumbnail.width - parent.spacing - spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) - anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - Label - { - id: name - text: model.name - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") - renderType: Text.NativeRendering - } - Label - { - id: info - text: model.description - maximumLineCount: 2 - elide: Text.ElideRight - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("default") - renderType: Text.NativeRendering - } - } - } + MouseArea { anchors.fill: parent hoverEnabled: true - onEntered: - { - thumbnail.border.color = UM.Theme.getColor("primary") - highlight.opacity = 0.1 - } - onExited: - { - thumbnail.border.color = UM.Theme.getColor("lining") - highlight.opacity = 0.0 - } + onEntered: thumbnail.border.color = UM.Theme.getColor("primary") + onExited: thumbnail.border.color = UM.Theme.getColor("lining") onClicked: { base.selection = model @@ -131,4 +51,83 @@ Item } } } + + Rectangle + { + id: thumbnail + width: UM.Theme.getSize("toolbox_thumbnail_small").width + height: UM.Theme.getSize("toolbox_thumbnail_small").height + color: UM.Theme.getColor("main_background") + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + + Image + { + anchors.centerIn: parent + width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width + height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + mipmap: true + } + UM.RecolorImage + { + width: (parent.width * 0.4) | 0 + height: (parent.height * 0.4) | 0 + anchors + { + bottom: parent.bottom + right: parent.right + } + sourceSize.height: height + visible: installedPackages != 0 + color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") + source: "../images/installed_check.svg" + } + } + Item + { + anchors + { + left: thumbnail.right + leftMargin: Math.floor(UM.Theme.getSize("narrow_margin").width) + right: parent.right + top: parent.top + bottom: parent.bottom + } + + Label + { + id: name + text: model.name + width: parent.width + elide: Text.ElideRight + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + } + Label + { + id: info + text: model.description + elide: Text.ElideRight + width: parent.width + wrapMode: Text.WordWrap + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("default") + anchors.top: name.bottom + anchors.bottom: rating.top + verticalAlignment: Text.AlignVCenter + maximumLineCount: 2 + } + SmallRatingWidget + { + id: rating + anchors + { + bottom: parent.bottom + left: parent.left + right: parent.right + } + } + } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index d1130cf63f..bb4f34163d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -13,91 +13,78 @@ Rectangle property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) id: tileBase width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width) - height: thumbnail.height + packageNameBackground.height + (2 * UM.Theme.getSize("default_lining").width) + height: thumbnail.height + packageName.height + rating.height + UM.Theme.getSize("default_margin").width border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - color: "transparent" - Rectangle + color: UM.Theme.getColor("main_background") + Image { id: thumbnail - color: "white" - width: UM.Theme.getSize("toolbox_thumbnail_large").width - height: UM.Theme.getSize("toolbox_thumbnail_large").height + height: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + mipmap: true anchors { top: parent.top + topMargin: UM.Theme.getSize("default_margin").height horizontalCenter: parent.horizontalCenter - topMargin: UM.Theme.getSize("default_lining").width } - Image + } + Label + { + id: packageName + text: model.name + anchors { - anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_large").width - 2 * UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height - fillMode: Image.PreserveAspectFit - source: model.icon_url || "../images/logobot.svg" - mipmap: true + horizontalCenter: parent.horizontalCenter + top: thumbnail.bottom } - UM.RecolorImage + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + renderType: Text.NativeRendering + height: UM.Theme.getSize("toolbox_heading_label").height + width: parent.width - UM.Theme.getSize("default_margin").width + wrapMode: Text.WordWrap + font: UM.Theme.getFont("medium_bold") + } + UM.RecolorImage + { + width: (parent.width * 0.20) | 0 + height: width + anchors { - width: (parent.width * 0.3) | 0 - height: (parent.height * 0.3) | 0 - anchors - { - bottom: parent.bottom - right: parent.right - bottomMargin: UM.Theme.getSize("default_lining").width - } - visible: installedPackages != 0 - color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") - source: "../images/installed_check.svg" + bottom: bottomBorder.top + right: parent.right } + visible: installedPackages != 0 + color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") + source: "../images/installed_check.svg" + } + + SmallRatingWidget + { + id: rating + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height + anchors.horizontalCenter: parent.horizontalCenter } Rectangle { - id: packageNameBackground + id: bottomBorder color: UM.Theme.getColor("primary") - anchors - { - top: thumbnail.bottom - horizontalCenter: parent.horizontalCenter - } - height: UM.Theme.getSize("toolbox_heading_label").height + anchors.bottom: parent.bottom width: parent.width - Label - { - id: packageName - text: model.name - anchors - { - horizontalCenter: parent.horizontalCenter - } - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - height: UM.Theme.getSize("toolbox_heading_label").height - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("button_text") - font: UM.Theme.getFont("medium_bold") - renderType: Text.NativeRendering - } + height: UM.Theme.getSize("toolbox_header_highlight").height } + MouseArea { anchors.fill: parent hoverEnabled: true - onEntered: - { - packageName.color = UM.Theme.getColor("button_text_hover") - packageNameBackground.color = UM.Theme.getColor("primary_hover") - tileBase.border.color = UM.Theme.getColor("primary_hover") - } - onExited: - { - packageName.color = UM.Theme.getColor("button_text") - packageNameBackground.color = UM.Theme.getColor("primary") - tileBase.border.color = UM.Theme.getColor("lining") - } + onEntered: tileBase.border.color = UM.Theme.getColor("primary") + onExited: tileBase.border.color = UM.Theme.getColor("lining") onClicked: { base.selection = model diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index bcc02955a2..d94fdf6bb7 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -41,6 +41,9 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 20, "links") self.addRoleName(Qt.UserRole + 21, "website") self.addRoleName(Qt.UserRole + 22, "login_required") + self.addRoleName(Qt.UserRole + 23, "average_rating") + self.addRoleName(Qt.UserRole + 24, "num_ratings") + self.addRoleName(Qt.UserRole + 25, "user_rating") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -101,7 +104,10 @@ class PackagesModel(ListModel): "tags": package["tags"] if "tags" in package else [], "links": links_dict, "website": package["website"] if "website" in package else None, - "login_required": "login-required" in package.get("tags", []) + "login_required": "login-required" in package.get("tags", []), + "average_rating": float(package.get("rating", {}).get("average", 0)), + "num_ratings": package.get("rating", {}).get("count", 0), + "user_rating": package.get("rating", {}).get("user_rating", 0) }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index b3c0277658..2229ab1f67 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -13,7 +13,6 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkRepl from UM.Logger import Logger from UM.PluginRegistry import PluginRegistry from UM.Extension import Extension -from UM.Qt.ListModel import ListModel from UM.i18n import i18nCatalog from UM.Version import Version @@ -51,17 +50,10 @@ class Toolbox(QObject, Extension): self._download_progress = 0 # type: float self._is_downloading = False # type: bool self._network_manager = None # type: Optional[QNetworkAccessManager] - self._request_header = [ - b"User-Agent", - str.encode( - "%s/%s (%s %s)" % ( - self._application.getApplicationName(), - self._application.getVersion(), - platform.system(), - platform.machine(), - ) - ) - ] + self._request_headers = [] # type: List[Tuple[bytes, bytes]] + self._updateRequestHeader() + + self._request_urls = {} # type: Dict[str, QUrl] self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated self._old_plugin_ids = set() # type: Set[str] @@ -116,6 +108,7 @@ class Toolbox(QObject, Extension): self._restart_dialog_message = "" # type: str self._application.initializationFinished.connect(self._onAppInitialized) + self._application.getCuraAPI().account.loginStateChanged.connect(self._updateRequestHeader) # Signals: # -------------------------------------------------------------------------- @@ -135,12 +128,38 @@ class Toolbox(QObject, Extension): showLicenseDialog = pyqtSignal() uninstallVariablesChanged = pyqtSignal() + def _updateRequestHeader(self): + self._request_headers = [ + (b"User-Agent", + str.encode( + "%s/%s (%s %s)" % ( + self._application.getApplicationName(), + self._application.getVersion(), + platform.system(), + platform.machine(), + ) + )) + ] + access_token = self._application.getCuraAPI().account.accessToken + if access_token: + self._request_headers.append((b"Authorization", "Bearer {}".format(access_token).encode())) + def _resetUninstallVariables(self) -> None: self._package_id_to_uninstall = None # type: Optional[str] self._package_name_to_uninstall = "" self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]] self._package_used_qualities = [] # type: List[Tuple[GlobalStack, str, str]] + @pyqtSlot(str, int) + def ratePackage(self, package_id: str, rating: int) -> None: + url = QUrl("{base_url}/packages/{package_id}/ratings".format(base_url=self._api_url, package_id = package_id)) + + self._rate_request = QNetworkRequest(url) + for header_name, header_value in self._request_headers: + cast(QNetworkRequest, self._rate_request).setRawHeader(header_name, header_value) + data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(self._application.getVersion()), rating) + self._rate_reply = cast(QNetworkAccessManager, self._network_manager).put(self._rate_request, data.encode()) + @pyqtSlot(result = str) def getLicenseDialogPluginName(self) -> str: return self._license_dialog_plugin_name @@ -531,7 +550,8 @@ class Toolbox(QObject, Extension): def _makeRequestByType(self, request_type: str) -> None: Logger.log("i", "Requesting %s metadata from server.", request_type) request = QNetworkRequest(self._request_urls[request_type]) - request.setRawHeader(*self._request_header) + for header_name, header_value in self._request_headers: + request.setRawHeader(header_name, header_value) if self._network_manager: self._network_manager.get(request) @@ -546,7 +566,8 @@ class Toolbox(QObject, Extension): if hasattr(QNetworkRequest, "RedirectPolicyAttribute"): # Patch for Qt 5.9+ cast(QNetworkRequest, self._download_request).setAttribute(QNetworkRequest.RedirectPolicyAttribute, True) - cast(QNetworkRequest, self._download_request).setRawHeader(*self._request_header) + for header_name, header_value in self._request_headers: + cast(QNetworkRequest, self._download_request).setRawHeader(header_name, header_value) self._download_reply = cast(QNetworkAccessManager, self._network_manager).get(self._download_request) self.setDownloadProgress(0) self.setIsDownloading(True) @@ -628,7 +649,7 @@ class Toolbox(QObject, Extension): else: self.setViewPage("errored") self.resetDownload() - else: + elif reply.operation() == QNetworkAccessManager.PutOperation: # Ignore any operation that is not a get operation pass diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 5eaeff2e84..d8c5d1ec28 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -97,6 +97,7 @@ Item return "" } visible: printJob + width: 120 * screenScaleFactor // TODO: Theme! // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml index cd78f1b11f..80a089cc2a 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml @@ -12,7 +12,19 @@ import UM 1.2 as UM Item { // The printer name - property alias text: printerNameLabel.text; + property var text: "" + property var tagText: { + switch(text) { + case "Ultimaker 3": + return "UM 3" + case "Ultimaker 3 Extended": + return "UM 3 EXT" + case "Ultimaker S5": + return "UM S5" + default: + return text + } + } implicitHeight: 18 * screenScaleFactor // TODO: Theme! implicitWidth: printerNameLabel.contentWidth + 12 // TODO: Theme! @@ -28,7 +40,7 @@ Item id: printerNameLabel anchors.centerIn: parent color: "#535369" // TODO: Theme! - text: "" + text: tagText font.pointSize: 10 } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 4d59e0eb6b..98ca715108 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -34,16 +34,20 @@ Component name: "cura" } - LinearGradient { + LinearGradient + { anchors.fill: parent - gradient: Gradient { - GradientStop { + gradient: Gradient + { + GradientStop + { position: 0.0 - color: "#f6f6f6" + color: "#f6f6f6" // TODO: Theme! } - GradientStop { + GradientStop + { position: 1.0 - color: "#ffffff" + color: "#ffffff" // TODO: Theme! } } } @@ -81,7 +85,8 @@ Component id: queue width: Math.min(834 * screenScaleFactor, maximumWidth) - anchors { + anchors + { bottom: parent.bottom horizontalCenter: parent.horizontalCenter top: printers.bottom @@ -210,7 +215,8 @@ Component ScrollView { id: queuedPrintJobs - anchors { + anchors + { bottom: parent.bottom horizontalCenter: parent.horizontalCenter top: printJobQueueHeadings.bottom @@ -239,7 +245,8 @@ Component } } - PrinterVideoStream { + PrinterVideoStream + { anchors.fill: parent cameraUrl: OutputDevice.activeCameraUrl visible: OutputDevice.activeCameraUrl != "" diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml index 643c8164a7..42e3b7d160 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml @@ -83,9 +83,7 @@ Item { Column { Repeater { - model: Cura.ExtrudersModel { - simpleNames: true; - } + model: CuraApplication.getExtrudersModel() Label { text: model.name; diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index c015ab8ccb..f39e267354 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3385,7 +3385,7 @@ "retraction_combing": { "label": "Combing Mode", - "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases.", + "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill.", "type": "enum", "options": { diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 7177120f35..3a9552cd9c 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -43,12 +43,13 @@ Button contentItem: Row { + spacing: UM.Theme.getSize("narrow_margin").width //Left side icon. Only displayed if !isIconOnRightSide. UM.RecolorImage { id: buttonIconLeft source: "" - height: buttonText.height + height: UM.Theme.getSize("action_button_icon").height width: visible ? height : 0 sourceSize.width: width sourceSize.height: height @@ -62,7 +63,7 @@ Button id: buttonText text: button.text color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") visible: text != "" renderType: Text.NativeRendering anchors.verticalCenter: parent.verticalCenter @@ -76,7 +77,7 @@ Button { id: buttonIconRight source: buttonIconLeft.source - height: buttonText.height + height: UM.Theme.getSize("action_button_icon").height width: visible ? height : 0 sourceSize.width: width sourceSize.height: height diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 9a6c97bcff..b56f50b9a9 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -12,6 +12,12 @@ Item { id: widget + function requestWriteToDevice() + { + UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, + { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); + } + Cura.PrimaryButton { id: saveToButton @@ -32,9 +38,8 @@ Item onClicked: { - forceActiveFocus(); - UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, - { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); + forceActiveFocus() + widget.requestWriteToDevice() } } @@ -81,6 +86,7 @@ Item delegate: Cura.ActionButton { text: model.description + visible: model.id != UM.OutputDeviceManager.activeDevice // Don't show the active device in the list color: "transparent" cornerRadius: 0 hoverColor: UM.Theme.getColor("primary") @@ -88,6 +94,7 @@ Item onClicked: { UM.OutputDeviceManager.setActiveDevice(model.id) + widget.requestWriteToDevice() popup.close() } } diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 3f53abf28f..eb6dc5b417 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -41,7 +41,7 @@ Column { left: parent.left right: printInformationPanel.left - rightMargin: UM.Theme.getSize("thin_margin").height + rightMargin: printInformationPanel.visible ? UM.Theme.getSize("thin_margin").width : 0 } Cura.IconWithText @@ -119,9 +119,9 @@ Column } height: UM.Theme.getSize("action_button").height - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Preview") + tooltip: text + fixedWidthMode: true onClicked: UM.Controller.setActiveStage("PreviewStage") visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 554273a818..2e108b05d7 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -12,10 +12,10 @@ UM.RecolorImage id: widget source: UM.Theme.getIcon("info") - width: UM.Theme.getSize("section_icon").width + width: visible ? UM.Theme.getSize("section_icon").width : 0 height: UM.Theme.getSize("section_icon").height - color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") + color: UM.Theme.getColor("icon") MouseArea { diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 18caeafb40..3756d0d452 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -60,7 +60,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") source: UM.Theme.getIcon("warning") - color: UM.Theme.getColor("warning") + iconColor: UM.Theme.getColor("warning") } // Progress bar, only visible when the backend is in the process of slice the printjob diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a4faa27b67..8ab943b93b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -252,7 +252,7 @@ UM.MainWindow anchors { // Align to the top of the stageMenu since the stageMenu may not exist - top: parent.top + top: stageMenu.source ? stageMenu.verticalCenter : parent.top left: parent.left right: parent.right bottom: parent.bottom @@ -278,16 +278,33 @@ UM.MainWindow height: UM.Theme.getSize("stage_menu").height source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" + // HACK: This is to ensure that the parent never gets set to null, as this wreaks havoc on the focus. + function onParentDestroyed() + { + printSetupSelector.parent = stageMenu + printSetupSelector.visible = false + } + property Item oldParent: null + // The printSetupSelector is defined here so that the setting list doesn't need to get re-instantiated // Every time the stage is changed. property var printSetupSelector: Cura.PrintSetupSelector { - width: UM.Theme.getSize("print_setup_widget").width - height: UM.Theme.getSize("stage_menu").height - headerCornerSide: RoundedRectangle.Direction.Right + width: UM.Theme.getSize("print_setup_widget").width + height: UM.Theme.getSize("stage_menu").height + headerCornerSide: RoundedRectangle.Direction.Right + onParentChanged: + { + if(stageMenu.oldParent !=null) + { + stageMenu.oldParent.Component.destruction.disconnect(stageMenu.onParentDestroyed) + } + stageMenu.oldParent = parent + visible = parent != stageMenu + parent.Component.destruction.connect(stageMenu.onParentDestroyed) + } } } - UM.MessageStack { anchors diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index bb0b347b7e..fcc49c9040 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -49,6 +49,7 @@ Item anchors.centerIn: parent text: index + 1 font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") width: contentWidth height: contentHeight visible: extruderEnabled diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 5530740040..24b6dc7fe2 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -15,10 +15,10 @@ Item { property alias source: icon.source property alias iconSize: icon.width + property alias iconColor: icon.color property alias color: label.color property alias text: label.text property alias font: label.font - property real margin: UM.Theme.getSize("narrow_margin").width // These properties can be used in combination with layouts. @@ -37,9 +37,9 @@ Item { id: icon width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height + height: width - color: label.color + color: UM.Theme.getColor("icon") anchors { diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index ae1c13d9c3..eecf2a1e73 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -54,16 +54,23 @@ Item { text: model.name.toUpperCase() checkable: true - checked: model.active + checked: UM.Controller.activeStage !== null && model.id == UM.Controller.activeStage.stageId + anchors.verticalCenter: parent.verticalCenter exclusiveGroup: mainWindowHeaderMenuGroup style: UM.Theme.styles.main_window_header_tab height: UM.Theme.getSize("main_window_header_button").height - onClicked: UM.Controller.setActiveStage(model.id) iconSource: model.stage.iconSource property color overlayColor: "transparent" property string overlayIconSource: "" + + // This is a trick to assure the activeStage is correctly changed. It doesn't work propertly if done in the onClicked (see CURA-6028) + MouseArea + { + anchors.fill: parent + onClicked: UM.Controller.setActiveStage(model.id) + } } } diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index 68c56c7c4b..a3ed5040b7 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -16,8 +16,8 @@ Item { id: header text: catalog.i18nc("@header", "Configurations") - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("small_button_text") height: contentHeight renderType: Text.NativeRendering diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 728a0cbe9a..862e1475a9 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -14,122 +14,117 @@ Button property var configuration: null hoverEnabled: true - height: background.height - background: Rectangle { - height: childrenRect.height color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") - border.width: parent.checked ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width + border.color: parent.checked ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width radius: UM.Theme.getSize("default_radius").width + } - Column + contentItem: Column + { + id: contentColumn + width: parent.width + padding: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("narrow_margin").height + + Row { - id: contentColumn - width: parent.width - padding: UM.Theme.getSize("wide_margin").width - spacing: UM.Theme.getSize("narrow_margin").height + id: extruderRow - Row + anchors { - id: extruderRow - - anchors - { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: childrenRect.height - - spacing: UM.Theme.getSize("default_margin").width - - Repeater - { - id: repeater - height: childrenRect.height - model: configuration.extruderConfigurations - delegate: PrintCoreConfiguration - { - width: Math.round(parent.width / 2) - printCoreConfiguration: modelData - } - } + left: parent.left + leftMargin: UM.Theme.getSize("wide_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("wide_margin").width } - //Buildplate row separator - Rectangle + spacing: UM.Theme.getSize("default_margin").width + + Repeater { - id: separator - - visible: buildplateInformation.visible - anchors + id: repeater + model: configuration.extruderConfigurations + delegate: PrintCoreConfiguration { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: visible ? Math.round(UM.Theme.getSize("default_lining").height / 2) : 0 - color: UM.Theme.getColor("lining") - } - - Item - { - id: buildplateInformation - - anchors - { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: childrenRect.height - visible: configuration.buildplateConfiguration != "" - - UM.RecolorImage - { - id: buildplateIcon - anchors.left: parent.left - width: UM.Theme.getSize("main_window_header_button_icon").width - height: UM.Theme.getSize("main_window_header_button_icon").height - source: UM.Theme.getIcon("buildplate") - color: UM.Theme.getColor("text") - } - - Label - { - id: buildplateLabel - anchors.left: buildplateIcon.right - anchors.verticalCenter: buildplateIcon.verticalCenter - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) - text: configuration.buildplateConfiguration - renderType: Text.NativeRendering - color: UM.Theme.getColor("text") + width: Math.round(parent.width / 2) + printCoreConfiguration: modelData } } } - Connections + //Buildplate row separator + Rectangle { - target: Cura.MachineManager - onCurrentConfigurationChanged: + id: separator + + visible: buildplateInformation.visible + anchors { - configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) + left: parent.left + leftMargin: UM.Theme.getSize("wide_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("wide_margin").width } + height: visible ? Math.round(UM.Theme.getSize("default_lining").height / 2) : 0 + color: UM.Theme.getColor("lining") } - Component.onCompleted: + Item + { + id: buildplateInformation + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("wide_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("wide_margin").width + } + height: childrenRect.height + visible: configuration.buildplateConfiguration != "" + + UM.RecolorImage + { + id: buildplateIcon + anchors.left: parent.left + width: UM.Theme.getSize("main_window_header_button_icon").width + height: UM.Theme.getSize("main_window_header_button_icon").height + source: UM.Theme.getIcon("buildplate") + color: UM.Theme.getColor("text") + } + + Label + { + id: buildplateLabel + anchors.left: buildplateIcon.right + anchors.verticalCenter: buildplateIcon.verticalCenter + anchors.leftMargin: UM.Theme.getSize("narrow_margin").height + text: configuration.buildplateConfiguration + renderType: Text.NativeRendering + color: UM.Theme.getColor("text") + } + } + } + + Connections + { + target: Cura.MachineManager + onCurrentConfigurationChanged: { configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) } } + Component.onCompleted: + { + configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) + } + onClicked: { Cura.MachineManager.applyRemoteConfiguration(configuration) } -} \ No newline at end of file +} diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 3cc0754284..684e575bfd 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -7,16 +7,15 @@ import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura -Column +Item { id: base property var outputDevice: null - height: childrenRect.height + 2 * padding - spacing: UM.Theme.getSize("narrow_margin").height + height: childrenRect.height function forceModelUpdate() { - // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI + // FIXME For now the model has to be removed and then created again, otherwise changes in the printer don't automatically update the UI configurationList.model = [] if (outputDevice) { @@ -24,6 +23,42 @@ Column } } + // This component will appear when there is no configurations (e.g. when losing connection) + Item + { + width: parent.width + visible: configurationList.model.length == 0 + height: label.height + UM.Theme.getSize("wide_margin").height + anchors.top: parent.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + + UM.RecolorImage + { + id: icon + + anchors.left: parent.left + anchors.verticalCenter: label.verticalCenter + + source: UM.Theme.getIcon("warning") + color: UM.Theme.getColor("warning") + width: UM.Theme.getSize("section_icon").width + height: width + } + + Label + { + id: label + anchors.left: icon.right + anchors.right: parent.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@label", "The configurations are not available because the printer is disconnected.") + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + wrapMode: Text.WordWrap + } + } + ScrollView { id: container @@ -57,7 +92,6 @@ Column id: configurationList spacing: UM.Theme.getSize("narrow_margin").height width: container.width - ((height > container.maximumHeight) ? container.ScrollBar.vertical.background.width : 0) //Make room for scroll bar if there is any. - contentHeight: childrenRect.height height: childrenRect.height section.property: "modelData.printerType" @@ -100,4 +134,4 @@ Column forceModelUpdate() } } -} \ No newline at end of file +} diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 33a317b42b..c6790ebbec 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -17,10 +17,7 @@ Cura.ExpandablePopup { id: base - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() UM.I18nCatalog { @@ -34,6 +31,7 @@ Cura.ExpandablePopup Custom } + contentPadding: UM.Theme.getSize("default_lining").width enabled: Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants || Cura.MachineManager.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change. headerItem: Item @@ -127,34 +125,41 @@ Cura.ExpandablePopup contentItem: Column { id: popupItem - width: base.width - 2 * UM.Theme.getSize("default_margin").width - height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. + width: UM.Theme.getSize("configuration_selector").width + height: implicitHeight // Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. + padding: UM.Theme.getSize("default_margin").height spacing: UM.Theme.getSize("default_margin").height - property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. + property bool is_connected: false // If current machine is connected to a printer. Only evaluated upon making popup visible. + property int configuration_method: ConfigurationMenu.ConfigurationMethod.Custom // Type of configuration being used. Only evaluated upon making popup visible. + property int manual_selected_method: -1 // It stores the configuration method selected by the user. By default the selected method is + onVisibleChanged: { - is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. - } + is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected // Re-evaluate. - property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.Auto : ConfigurationMenu.ConfigurationMethod.Custom //Auto if connected to a printer at start-up, or Custom if not. + // If the printer is not connected, we switch always to the custom mode. If is connected instead, the auto mode + // or the previous state is selected + configuration_method = is_connected ? (manual_selected_method == -1 ? ConfigurationMenu.ConfigurationMethod.Auto : manual_selected_method) : ConfigurationMenu.ConfigurationMethod.Custom + } Item { - width: parent.width + width: parent.width - 2 * parent.padding height: { - var height = 0; - if(autoConfiguration.visible) + var height = 0 + if (autoConfiguration.visible) { - height += autoConfiguration.height; + height += autoConfiguration.height } - if(customConfiguration.visible) + if (customConfiguration.visible) { - height += customConfiguration.height; + height += customConfiguration.height } - return height; + return height } + AutoConfiguration { id: autoConfiguration @@ -172,9 +177,9 @@ Cura.ExpandablePopup { id: separator visible: buttonBar.visible - x: -contentPadding + x: -parent.padding - width: base.width + width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") @@ -186,7 +191,7 @@ Cura.ExpandablePopup id: buttonBar visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible. - width: parent.width + width: parent.width - 2 * parent.padding height: childrenRect.height Cura.SecondaryButton @@ -200,7 +205,11 @@ Cura.ExpandablePopup iconSource: UM.Theme.getIcon("arrow_right") isIconOnRightSide: true - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom + onClicked: + { + popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom + popupItem.manual_selected_method = popupItem.configuration_method + } } Cura.SecondaryButton @@ -211,8 +220,18 @@ Cura.ExpandablePopup iconSource: UM.Theme.getIcon("arrow_left") - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto + onClicked: + { + popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto + popupItem.manual_selected_method = popupItem.configuration_method + } } } } + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: popupItem.manual_selected_method = -1 // When switching printers, reset the value of the manual selected method + } } diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 8429e2c093..4d6d80c1b4 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -23,8 +23,8 @@ Item { id: header text: catalog.i18nc("@header", "Custom") - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("small_button_text") height: contentHeight renderType: Text.NativeRendering @@ -51,9 +51,7 @@ Item anchors { left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width top: header.bottom topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 } @@ -74,7 +72,7 @@ Item id: printerTypeSelector text: Cura.MachineManager.activeMachineDefinitionName tooltip: Cura.MachineManager.activeMachineDefinitionName - height: UM.Theme.getSize("setting_control").height + height: UM.Theme.getSize("print_setup_big_item").height width: Math.round(parent.width * 0.7) + UM.Theme.getSize("default_margin").width anchors.right: parent.right style: UM.Theme.styles.print_setup_header_button @@ -224,7 +222,7 @@ Item Row { - height: UM.Theme.getSize("print_setup_item").height + height: UM.Theme.getSize("print_setup_big_item").height visible: Cura.MachineManager.hasMaterials Label @@ -248,7 +246,7 @@ Item text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" tooltip: text - height: UM.Theme.getSize("setting_control").height + height: UM.Theme.getSize("print_setup_big_item").height width: selectors.controlWidth style: UM.Theme.styles.print_setup_header_button @@ -262,7 +260,7 @@ Item Row { - height: UM.Theme.getSize("print_setup_item").height + height: UM.Theme.getSize("print_setup_big_item").height visible: Cura.MachineManager.hasVariants Label @@ -282,7 +280,7 @@ Item text: Cura.MachineManager.activeVariantName tooltip: Cura.MachineManager.activeVariantName - height: UM.Theme.getSize("setting_control").height + height: UM.Theme.getSize("print_setup_big_item").height width: selectors.controlWidth style: UM.Theme.styles.print_setup_header_button activeFocusOnPress: true; diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml index 1ea402d815..cb10d50ce8 100644 --- a/resources/qml/Menus/ContextMenu.qml +++ b/resources/qml/Menus/ContextMenu.qml @@ -27,7 +27,7 @@ Menu MenuItem { id: extruderHeader; text: catalog.i18ncp("@label", "Print Selected Model With:", "Print Selected Models With:", UM.Selection.selectionCount); enabled: false; visible: base.shouldShowExtruders } Instantiator { - model: Cura.ExtrudersModel { id: extrudersModel } + model: CuraApplication.getExtrudersModel() MenuItem { text: "%1: %2 - %3".arg(model.name).arg(model.material).arg(model.variant) visible: base.shouldShowExtruders diff --git a/resources/qml/MonitorSidebar.qml b/resources/qml/MonitorSidebar.qml deleted file mode 100644 index 669bdbfb8f..0000000000 --- a/resources/qml/MonitorSidebar.qml +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.10 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.3 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -import "Menus" -import "Menus/ConfigurationMenu" - - -Rectangle -{ - id: base - - property int currentModeIndex - property bool hideSettings: PrintInformation.preSliced - property bool hideView: Cura.MachineManager.activeMachineName == "" - - // Is there an output device for this printer? - property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" - property bool printerConnected: Cura.MachineManager.printerConnected - property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands - property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - - property variant printDuration: PrintInformation.currentPrintTime - property variant printMaterialLengths: PrintInformation.materialLengths - property variant printMaterialWeights: PrintInformation.materialWeights - property variant printMaterialCosts: PrintInformation.materialCosts - property variant printMaterialNames: PrintInformation.materialNames - - color: UM.Theme.getColor("main_background") - UM.I18nCatalog { id: catalog; name: "cura"} - - Timer { - id: tooltipDelayTimer - interval: 500 - repeat: false - property var item - property string text - - onTriggered: - { - base.showTooltip(base, {x: 0, y: item.y}, text); - } - } - - function showTooltip(item, position, text) - { - tooltip.text = text; - position = item.mapToItem(base, position.x - UM.Theme.getSize("default_arrow").width, position.y); - tooltip.show(position); - } - - function hideTooltip() - { - tooltip.hide(); - } - - function strPadLeft(string, pad, length) { - return (new Array(length + 1).join(pad) + string).slice(-length); - } - - function getPrettyTime(time) - { - var hours = Math.floor(time / 3600) - time -= hours * 3600 - var minutes = Math.floor(time / 60); - time -= minutes * 60 - var seconds = Math.floor(time); - - var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2); - return finalTime; - } - - MouseArea - { - anchors.fill: parent - acceptedButtons: Qt.AllButtons - - onWheel: - { - wheel.accepted = true; - } - } - - MachineSelector - { - id: machineSelection - width: base.width - configSelection.width - separator.width - height: UM.Theme.getSize("stage_menu").height - anchors.top: base.top - anchors.left: parent.left - } - - Rectangle - { - id: separator - visible: configSelection.visible - width: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 - height: UM.Theme.getSize("stage_menu").height - color: UM.Theme.getColor("thick_lining") - anchors.left: machineSelection.right - } - - CustomConfigurationSelector - { - id: configSelection - visible: isNetworkPrinter && printerConnected - width: visible ? Math.round(base.width * 0.15) : 0 - height: UM.Theme.getSize("stage_menu").height - anchors.top: base.top - anchors.right: parent.right - } - - Loader - { - id: controlItem - anchors.bottom: footerSeparator.top - anchors.top: machineSelection.bottom - anchors.left: base.left - anchors.right: base.right - sourceComponent: - { - if(connectedPrinter != null) - { - if(connectedPrinter.controlItem != null) - { - return connectedPrinter.controlItem - } - } - return null - } - } - - Loader - { - anchors.bottom: footerSeparator.top - anchors.top: machineSelection.bottom - anchors.left: base.left - anchors.right: base.right - source: - { - if(controlItem.sourceComponent == null) - { - return "PrintMonitor.qml" - } - else - { - return "" - } - } - } - - Rectangle - { - id: footerSeparator - width: parent.width - height: UM.Theme.getSize("wide_lining").height - color: UM.Theme.getColor("wide_lining") - anchors.bottom: monitorButton.top - anchors.bottomMargin: UM.Theme.getSize("thick_margin").height - } - - // MonitorButton is actually the bottom footer panel. - MonitorButton - { - id: monitorButton - implicitWidth: base.width - anchors.bottom: parent.bottom - } - - PrintSetupTooltip - { - id: tooltip - } - - UM.SettingPropertyProvider - { - id: machineExtruderCount - - containerStack: Cura.MachineManager.activeMachine - key: "machine_extruder_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: machineHeatedBed - - containerStack: Cura.MachineManager.activeMachine - key: "machine_heated_bed" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - // Make the ConfigurationSelector react when the global container changes, otherwise if Cura is not connected to the printer, - // switching printers make no reaction - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: - { - base.isNetworkPrinter = Cura.MachineManager.activeMachineNetworkKey != "" - base.printerConnected = Cura.MachineManager.printerOutputDevices.length != 0 - } - } -} diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index d7ffbb3152..7fb17b7aa1 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -16,7 +16,7 @@ Item property QtObject qualityManager: CuraApplication.getQualityManager() property var resetEnabled: false // Keep PreferencesDialog happy - property var extrudersModel: Cura.ExtrudersModel {} + property var extrudersModel: CuraApplication.getExtrudersModel() UM.I18nCatalog { id: catalog; name: "cura"; } diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index 4ed8daa55c..6d8edf0deb 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -60,11 +60,7 @@ Rectangle anchors.fill: parent - Cura.ExtrudersModel - { - id: extrudersModel - simpleNames: true - } + property var extrudersModel: CuraApplication.getExtrudersModel() OutputDeviceHeader { diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index b28c9ceb46..51eb14a441 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -16,10 +16,7 @@ Item property real padding: UM.Theme.getSize("default_margin").width property bool multipleExtruders: extrudersModel.count > 1 - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() // Profile selector row GlobalProfileSelector @@ -113,9 +110,11 @@ Item } z: tabBar.z - 1 // Don't show the border when only one extruder + border.color: tabBar.visible ? UM.Theme.getColor("lining") : "transparent" border.width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("main_background") Cura.SettingView { anchors diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 599eac957e..2d4d7f6cf1 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -26,10 +26,7 @@ Cura.ExpandableComponent headerItem: PrintSetupSelectorHeader {} - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() contentItem: PrintSetupSelectorContents {} } \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 2971415948..0da53cc1c1 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -144,6 +144,7 @@ Item anchors.horizontalCenter: parent.horizontalCenter y: UM.Theme.getSize("thin_margin").height renderType: Text.NativeRendering + color: UM.Theme.getColor("quality_slider_available") } } } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 15d40f545a..e6b3f1b9eb 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -39,6 +39,17 @@ Item { target: Cura.QualityProfilesDropDownMenuModel onItemsChanged: qualityModel.update() + onDataChanged: + { + // If a custom profile is selected and then a user decides to change any of setting the slider should show + // the reset button. After clicking the reset button the QualityProfilesDropDownMenuModel(ListModel) is + // updated before the property isProfileCustomized is called to update. + if (Cura.SimpleModeSettingsManager.isProfileCustomized) + { + Cura.SimpleModeSettingsManager.updateIsProfileUserCreated() + } + qualityModel.update() + } } Connections { diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 57e0c8ce6b..87fb664713 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -156,9 +156,10 @@ Item } //: Model used to populate the extrudelModel - Cura.ExtrudersModel + property var extruders: CuraApplication.getExtrudersModel() + Connections { - id: extruders + target: extruders onModelChanged: populateExtruderModel() } diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index 247bb3a27d..9ba78f778f 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -326,7 +326,7 @@ Item return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: { if(extruderModel == null) diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 33cf5cd1e2..ac541f707c 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -320,7 +320,7 @@ Item return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: { if(printerModel == null) diff --git a/resources/qml/PrinterOutput/MonitorSection.qml b/resources/qml/PrinterOutput/MonitorSection.qml index 7ef89dabf7..1d9df777b6 100644 --- a/resources/qml/PrinterOutput/MonitorSection.qml +++ b/resources/qml/PrinterOutput/MonitorSection.qml @@ -27,7 +27,7 @@ Item anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width text: label - font: UM.Theme.getFont("setting_category") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("setting_category_text") } } diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 7cda4f1d2e..fb8f0a58e1 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -24,49 +24,24 @@ Cura.ExpandablePopup name: "cura" } - headerItem: Item + headerItem: Cura.IconWithText { - implicitHeight: icon.height - - UM.RecolorImage + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + source: { - id: icon - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - - source: + if (isNetworkPrinter) { - if (isNetworkPrinter) + if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) { - if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) - { - return UM.Theme.getIcon("printer_group") - } - return UM.Theme.getIcon("printer_single") + return UM.Theme.getIcon("printer_group") } - return "" + return UM.Theme.getIcon("printer_single") } - width: UM.Theme.getSize("machine_selector_icon").width - height: width - - color: UM.Theme.getColor("machine_selector_printer_icon") - visible: source != "" - } - - Label - { - id: label - anchors.left: icon.visible ? icon.right : parent.left - anchors.right: parent.right - anchors.leftMargin: UM.Theme.getSize("thin_margin").width - anchors.verticalCenter: icon.verticalCenter - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - elide: Text.ElideRight - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("medium") - renderType: Text.NativeRendering + return "" } + font: UM.Theme.getFont("medium") + iconColor: UM.Theme.getColor("machine_selector_printer_icon") + iconSize: source != "" ? UM.Theme.getSize("machine_selector_icon").width: 0 UM.RecolorImage { diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index b88af35f82..39e63d27c3 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -42,7 +42,7 @@ Button } text: machineSelectorButton.text color: UM.Theme.getColor("text") - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") visible: text != "" renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 5676bcedf9..da731bcd55 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -73,7 +73,7 @@ Button text: definition.label textFormat: Text.PlainText renderType: Text.NativeRendering - font: UM.Theme.getFont("setting_category") + font: UM.Theme.getFont("default") color: { if (!base.enabled) @@ -106,26 +106,7 @@ Button width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height sourceSize.height: width - color: - { - if (!base.enabled) - { - return UM.Theme.getColor("setting_category_disabled_text") - } - else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) - { - return UM.Theme.getColor("setting_category_active_hover_text") - } - else if (base.pressed || (base.checkable && base.checked)) - { - return UM.Theme.getColor("setting_category_active_text") - } - else if (base.hovered || base.activeFocus) - { - return UM.Theme.getColor("setting_category_hover_text") - } - return UM.Theme.getColor("setting_category_text") - } + color: UM.Theme.getColor("setting_control_button") source: base.checked ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } } diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 13d2a0eb8f..a287e0c3ce 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -63,7 +63,7 @@ SettingItem sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text") + color: UM.Theme.getColor("setting_control_button") } contentItem: Label diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index e1fedd9274..6d39192de7 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -17,11 +17,16 @@ SettingItem id: control anchors.fill: parent - model: Cura.ExtrudersModel + property var extrudersModel: CuraApplication.getExtrudersModel() + + model: extrudersModel + + Connections { + target: extrudersModel onModelChanged: { - control.color = getItem(control.currentIndex).color + control.color = extrudersModel.getItem(control.currentIndex).color } } @@ -105,7 +110,7 @@ SettingItem sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text"); + color: UM.Theme.getColor("setting_control_button"); } background: Rectangle diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index 200a3f64f1..b73c7498ae 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -12,15 +12,24 @@ SettingItem id: base property var focusItem: control + // Somehow if we directory set control.model to CuraApplication.getExtrudersModelWithOptional() + // and in the Connections.onModelChanged use control.model as a reference, it will complain about + // non-existing properties such as "onModelChanged" and "getItem". I guess if we access the model + // via "control.model", it gives back a generic/abstract model instance. To avoid this, we add + // this extra property to keep the ExtrudersModel and use this in the rest of the code. + property var extrudersWithOptionalModel: CuraApplication.getExtrudersModelWithOptional() + contents: ComboBox { id: control anchors.fill: parent - model: Cura.ExtrudersModel + model: base.extrudersWithOptionalModel + + Connections { - onModelChanged: control.color = getItem(control.currentIndex).color - addOptionalExtruder: true + target: base.extrudersWithOptionalModel + onModelChanged: control.color = base.extrudersWithOptionalModel.getItem(control.currentIndex).color } textRole: "name" @@ -102,7 +111,7 @@ SettingItem sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text"); + color: UM.Theme.getColor("setting_control_button"); } background: Rectangle diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 1e335472d4..33481b9183 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -67,7 +67,7 @@ Item toolItem: UM.RecolorImage { source: UM.Theme.getIcon(model.icon) != "" ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon - color: UM.Theme.getColor("toolbar_button_text") + color: UM.Theme.getColor("icon") sourceSize: UM.Theme.getSize("button_icon") } @@ -144,10 +144,7 @@ Item } } - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() UM.PointingRectangle { diff --git a/resources/qml/ViewOrientationButton.qml b/resources/qml/ViewOrientationButton.qml index 5371f8549b..5d72de9a8d 100644 --- a/resources/qml/ViewOrientationButton.qml +++ b/resources/qml/ViewOrientationButton.qml @@ -11,5 +11,5 @@ UM.SimpleButton height: UM.Theme.getSize("small_button").height hoverColor: UM.Theme.getColor("small_button_text_hover") color: UM.Theme.getColor("small_button_text") - iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width + iconMargin: UM.Theme.getSize("thick_lining").width } \ No newline at end of file diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 0e2598a0d8..1f5a0bbc85 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -14,24 +14,28 @@ Cura.ExpandablePopup contentPadding: UM.Theme.getSize("default_lining").width contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft - property var viewModel: UM.ViewModel { } - - property var activeView: + property var viewModel: UM.ViewModel { - for (var i = 0; i < viewModel.count; i++) + onDataChanged: updateActiveView() + } + + property var activeView: null + + function updateActiveView() + { + for (var index in viewModel.items) { - if (viewModel.items[i].active) + if (viewModel.items[index].active) { - return viewModel.items[i] + activeView = viewModel.items[index] + return } } - return null + activeView = null } Component.onCompleted: { - // Nothing was active, so just return the first one (the list is sorted by priority, so the most - // important one should be returned) if (activeView == null) { UM.Controller.setActiveView(viewModel.getItem(0).id) @@ -74,8 +78,6 @@ Cura.ExpandablePopup { id: viewSelectorPopup width: viewSelector.width - 2 * viewSelector.contentPadding - leftPadding: UM.Theme.getSize("default_lining").width - rightPadding: UM.Theme.getSize("default_lining").width // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: @@ -105,7 +107,7 @@ Cura.ExpandablePopup id: buttonText text: viewsSelectorButton.text color: UM.Theme.getColor("text") - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter elide: Text.ElideRight diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 8540abf61a..cade342488 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -17,6 +17,12 @@ "border": [127, 127, 127, 255], "secondary": [95, 95, 95, 255], + "icon": [204, 204, 204, 255], + "toolbar_background": [39, 44, 48, 255], + "toolbar_button_active": [95, 95, 95, 255], + "toolbar_button_hover": [95, 95, 95, 255], + "toolbar_button_active_hover": [95, 95, 95, 255], + "main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], @@ -93,11 +99,11 @@ "scrollbar_handle_hover": [255, 255, 255, 255], "scrollbar_handle_down": [255, 255, 255, 255], - "setting_category": [39, 44, 48, 255], - "setting_category_disabled": [39, 44, 48, 255], - "setting_category_hover": [39, 44, 48, 255], - "setting_category_active": [39, 44, 48, 255], - "setting_category_active_hover": [39, 44, 48, 255], + "setting_category": [75, 80, 83, 255], + "setting_category_disabled": [75, 80, 83, 255], + "setting_category_hover": [75, 80, 83, 255], + "setting_category_active": [75, 80, 83, 255], + "setting_category_active_hover": [75, 80, 83, 255], "setting_category_text": [255, 255, 255, 152], "setting_category_disabled_text": [255, 255, 255, 101], "setting_category_hover_text": [255, 255, 255, 204], diff --git a/resources/themes/cura-light/icons/star_empty.svg b/resources/themes/cura-light/icons/star_empty.svg new file mode 100644 index 0000000000..39b5791e91 --- /dev/null +++ b/resources/themes/cura-light/icons/star_empty.svg @@ -0,0 +1,11 @@ + + + + Star Copy 8 + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/star_filled.svg b/resources/themes/cura-light/icons/star_filled.svg new file mode 100644 index 0000000000..d4e161f6c6 --- /dev/null +++ b/resources/themes/cura-light/icons/star_filled.svg @@ -0,0 +1,11 @@ + + + + Star Copy 7 + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/warning.svg b/resources/themes/cura-light/icons/warning.svg index ae8a7a6430..14b7d797d0 100644 --- a/resources/themes/cura-light/icons/warning.svg +++ b/resources/themes/cura-light/icons/warning.svg @@ -1,4 +1,11 @@ - - - + + + + Icon/warning-s + Created with Sketch. + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index c940052668..89729fc08c 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -75,7 +75,7 @@ QtObject width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height sourceSize.height: width - color: control.enabled ? Theme.getColor("setting_category_text") : Theme.getColor("setting_category_disabled_text") + color: control.enabled ? Theme.getColor("setting_control_button") : Theme.getColor("setting_category_disabled_text") source: Theme.getIcon("arrow_bottom") } Label @@ -392,7 +392,7 @@ QtObject sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: Theme.getColor("setting_control_text"); + color: Theme.getColor("setting_control_button"); } } } @@ -459,7 +459,7 @@ QtObject sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text") + color: UM.Theme.getColor("setting_control_button") } } } @@ -662,7 +662,7 @@ QtObject return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: control.text } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 1a7d377fa7..ea6c92b479 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -49,21 +49,6 @@ "size": 0.7, "weight": 50, "family": "Noto Sans" - }, - "button_tooltip": { - "size": 1.0, - "weight": 50, - "family": "Noto Sans" - }, - "setting_category": { - "size": 1.15, - "weight": 63, - "family": "Noto Sans" - }, - "action_button": { - "size": 1.15, - "weight": 50, - "family": "Noto Sans" } }, @@ -83,6 +68,8 @@ "secondary": [240, 240, 240, 255], "secondary_shadow": [216, 216, 216, 255], + "icon": [8, 7, 63, 255], + "primary_button": [38, 113, 231, 255], "primary_button_shadow": [27, 95, 202, 255], "primary_button_hover": [81, 145, 247, 255], @@ -116,7 +103,7 @@ "printer_type_label_background": [228, 228, 242, 255], - "text": [0, 0, 0, 255], + "text": [25, 25, 25, 255], "text_detail": [174, 174, 174, 128], "text_link": [50, 130, 255, 255], "text_inactive": [174, 174, 174, 255], @@ -160,6 +147,8 @@ "extruder_button_material_border": [255, 255, 255, 255], + "rating_star": [90, 90, 90, 255], + "sync_button_text": [120, 120, 120, 255], "sync_button_text_hovered": [0, 0, 0, 255], @@ -255,8 +244,8 @@ "message_button_text": [255, 255, 255, 255], "message_button_text_hover": [255, 255, 255, 255], "message_button_text_active": [255, 255, 255, 255], - "message_progressbar_background": [200, 200, 200, 255], - "message_progressbar_control": [77, 182, 226, 255], + "message_progressbar_background": [245, 245, 245, 255], + "message_progressbar_control": [50, 130, 255, 255], "tool_panel_background": [255, 255, 255, 255], @@ -347,7 +336,7 @@ }, "sizes": { - "window_minimum_size": [106, 66], + "window_minimum_size": [100, 60], "main_window_header": [0.0, 4.0], "main_window_header_button": [8, 2.35], @@ -369,9 +358,10 @@ "expandable_component_content_header": [0.0, 3.0], + "configuration_selector": [35.0, 4.0], "configuration_selector_mode_tabs": [0.0, 3.0], - "action_panel_widget": [25.0, 0.0], + "action_panel_widget": [26.0, 0.0], "action_panel_information_widget": [20.0, 0.0], "machine_selector_widget": [20.0, 4.0], @@ -402,6 +392,7 @@ "section": [0.0, 2], "section_icon": [1.6, 1.6], "section_icon_column": [2.8, 0.0], + "rating_star": [1.0, 1.0], "setting": [25.0, 1.8], "setting_control": [11.0, 2.0], @@ -420,6 +411,7 @@ "button_lining": [0, 0], "action_button": [15.0, 3.0], + "action_button_icon": [1.0, 1.0], "action_button_radius": [0.15, 0.15], "small_button": [2, 2],