diff --git a/cura/Scene/ConvexHullDecorator.py b/cura/Scene/ConvexHullDecorator.py index da71f6920e..1aae97942a 100644 --- a/cura/Scene/ConvexHullDecorator.py +++ b/cura/Scene/ConvexHullDecorator.py @@ -60,13 +60,11 @@ class ConvexHullDecorator(SceneNodeDecorator): previous_node = self._node # Disconnect from previous node signals if previous_node is not None and node is not previous_node: - previous_node.transformationChanged.disconnect(self._onChanged) - previous_node.parentChanged.disconnect(self._onChanged) + previous_node.boundingBoxChanged.disconnect(self._onChanged) super().setNode(node) - # Mypy doesn't understand that self._node is no longer optional, so just use the node. - node.transformationChanged.connect(self._onChanged) - node.parentChanged.connect(self._onChanged) + + node.boundingBoxChanged.connect(self._onChanged) self._onChanged() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 736cb06d49..7d0e7506b8 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -362,7 +362,6 @@ class MachineManager(QObject): # Mark global stack as invalid ConfigurationErrorMessage.getInstance().addFaultyContainers(global_stack.getId()) return # We're done here - ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder self._global_container_stack = global_stack self._application.setGlobalContainerStack(global_stack) @@ -370,6 +369,11 @@ class MachineManager(QObject): self._initMachineState(global_stack) self._onGlobalContainerChanged() + # Switch to the first enabled extruder + self.updateDefaultExtruder() + default_extruder_position = int(self.defaultExtruderPosition) + ExtruderManager.getInstance().setActiveExtruderIndex(default_extruder_position) + self.__emitChangedSignals() ## Given a definition id, return the machine with this id. @@ -1626,6 +1630,7 @@ class MachineManager(QObject): return abbr_machine + @pyqtSlot(str, result = str) def getMachineTypeNameFromId(self, machine_type_id: str) -> str: machine_type_name = "" results = self._container_registry.findDefinitionContainersMetadata(id = machine_type_id) diff --git a/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml b/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml index f941d13561..e05d8e75fc 100644 --- a/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml +++ b/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml @@ -20,12 +20,12 @@ Item anchors.right: parent.right anchors.top: parent.top - property int labelWidth: 180 - property int controlWidth: UM.Theme.getSize("setting_control").width * 3 / 4 + property int labelWidth: 210 * screenScaleFactor + property int controlWidth: (UM.Theme.getSize("setting_control").width * 3 / 4) | 0 property var labelFont: UM.Theme.getFont("medium") - property int columnWidth: (parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2 - property int columnSpacing: 3 + property int columnWidth: ((parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2) | 0 + property int columnSpacing: 3 * screenScaleFactor property int propertyStoreIndex: manager.storeContainerIndex // definition_changes property string extruderStackId: "" diff --git a/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml index ccc0548059..3287643286 100644 --- a/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml +++ b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml @@ -20,12 +20,12 @@ Item anchors.right: parent.right anchors.top: parent.top - property int labelWidth: 130 - property int controlWidth: UM.Theme.getSize("setting_control").width * 3 / 4 + property int labelWidth: 120 * screenScaleFactor + property int controlWidth: (UM.Theme.getSize("setting_control").width * 3 / 4) | 0 property var labelFont: UM.Theme.getFont("default") - property int columnWidth: (parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2 - property int columnSpacing: 3 + property int columnWidth: ((parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2) | 0 + property int columnSpacing: 3 * screenScaleFactor property int propertyStoreIndex: manager.storeContainerIndex // definition_changes property string machineStackId: Cura.MachineManager.activeMachineId diff --git a/plugins/SliceInfoPlugin/MoreInfoWindow.qml b/plugins/SliceInfoPlugin/MoreInfoWindow.qml index e00ad6730d..82d5044bed 100644 --- a/plugins/SliceInfoPlugin/MoreInfoWindow.qml +++ b/plugins/SliceInfoPlugin/MoreInfoWindow.qml @@ -1,150 +1,154 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2019 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 +import QtQuick.Controls 2.3 import QtQuick.Window 2.2 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import UM 1.3 as UM -import Cura 1.0 as Cura +import Cura 1.1 as Cura -UM.Dialog +Window { + UM.I18nCatalog { id: catalog; name: "cura" } + id: baseDialog title: catalog.i18nc("@title:window", "More information on anonymous data collection") visible: false + modality: Qt.ApplicationModal + minimumWidth: 500 * screenScaleFactor minimumHeight: 400 * screenScaleFactor width: minimumWidth height: minimumHeight - property bool allowSendData: true // for saving the user's choice + color: UM.Theme.getColor("main_background") - onAccepted: manager.setSendSliceInfo(allowSendData) + property bool allowSendData: true // for saving the user's choice onVisibilityChanged: { if (visible) { - baseDialog.allowSendData = UM.Preferences.getValue("info/send_slice_info"); + baseDialog.allowSendData = UM.Preferences.getValue("info/send_slice_info") if (baseDialog.allowSendData) { - allowSendButton.checked = true; + allowSendButton.checked = true } else { - dontSendButton.checked = true; + dontSendButton.checked = true } } } + // Main content area Item { - id: textRow - anchors - { - top: parent.top - bottom: radioButtonsRow.top - bottomMargin: UM.Theme.getSize("default_margin").height - left: parent.left - right: parent.right - } + anchors.fill: parent + anchors.margins: UM.Theme.getSize("default_margin").width - Label + Item // Text part { - id: headerText + id: textRow anchors { top: parent.top - left: parent.left - right: parent.right - } - - text: catalog.i18nc("@text:window", "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent.") - wrapMode: Text.WordWrap - } - - TextArea - { - id: exampleData - anchors - { - top: headerText.bottom - topMargin: UM.Theme.getSize("default_margin").height - bottom: parent.bottom + bottom: radioButtonsRow.top bottomMargin: UM.Theme.getSize("default_margin").height left: parent.left right: parent.right } - text: manager.getExampleData() - readOnly: true - textFormat: TextEdit.PlainText - } - } - - Column - { - id: radioButtonsRow - width: parent.width - anchors.bottom: buttonRow.top - anchors.bottomMargin: UM.Theme.getSize("default_margin").height - - ExclusiveGroup { id: group } - - RadioButton - { - id: dontSendButton - text: catalog.i18nc("@text:window", "I don't want to send this data") - exclusiveGroup: group - onClicked: + Label { - baseDialog.allowSendData = !checked; + id: headerText + anchors + { + top: parent.top + left: parent.left + right: parent.right + } + text: catalog.i18nc("@text:window", "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent.") + wrapMode: Text.WordWrap + renderType: Text.NativeRendering } - } - RadioButton - { - id: allowSendButton - text: catalog.i18nc("@text:window", "Allow sending this data to Ultimaker and help us improve Cura") - exclusiveGroup: group - onClicked: + + Cura.ScrollableTextArea { - baseDialog.allowSendData = checked; - } - } - } + anchors + { + top: headerText.bottom + topMargin: UM.Theme.getSize("default_margin").height + bottom: parent.bottom + bottomMargin: UM.Theme.getSize("default_margin").height + left: parent.left + right: parent.right + } - Item - { - id: buttonRow - anchors.bottom: parent.bottom - width: parent.width - anchors.bottomMargin: UM.Theme.getSize("default_margin").height - - UM.I18nCatalog { id: catalog; name: "cura" } - - Button - { - anchors.right: parent.right - text: catalog.i18nc("@action:button", "OK") - onClicked: - { - baseDialog.accepted() - baseDialog.hide() + textArea.text: manager.getExampleData() + textArea.readOnly: true } } - Button + Column // Radio buttons for agree and disagree { + id: radioButtonsRow anchors.left: parent.left - text: catalog.i18nc("@action:button", "Cancel") - onClicked: + anchors.right: parent.right + anchors.bottom: buttonRow.top + anchors.bottomMargin: UM.Theme.getSize("default_margin").height + + Cura.RadioButton { - baseDialog.rejected() - baseDialog.hide() + id: dontSendButton + text: catalog.i18nc("@text:window", "I don't want to send this data") + onClicked: + { + baseDialog.allowSendData = !checked + } + } + Cura.RadioButton + { + id: allowSendButton + text: catalog.i18nc("@text:window", "Allow sending this data to Ultimaker and help us improve Cura") + onClicked: + { + baseDialog.allowSendData = checked + } + } + } + + Item // Bottom buttons + { + id: buttonRow + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + + height: childrenRect.height + + Cura.PrimaryButton + { + anchors.right: parent.right + text: catalog.i18nc("@action:button", "OK") + onClicked: + { + manager.setSendSliceInfo(allowSendData) + baseDialog.hide() + } + } + + Cura.SecondaryButton + { + anchors.left: parent.left + text: catalog.i18nc("@action:button", "Cancel") + onClicked: + { + baseDialog.hide() + } } } } diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 065923c43d..3763db5534 100755 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -62,7 +62,7 @@ class SliceInfo(QObject, Extension): def showMoreInfoDialog(self): if self._more_info_dialog is None: self._more_info_dialog = self._createDialog("MoreInfoWindow.qml") - self._more_info_dialog.open() + self._more_info_dialog.show() def _createDialog(self, qml_name): Logger.log("d", "Creating dialog [%s]", qml_name) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 306ab8b137..085c5d1bde 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -559,9 +559,15 @@ class Toolbox(QObject, Extension): if self._download_reply: try: self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) - except TypeError: # Raised when the method is not connected to the signal yet. + except (TypeError, RuntimeError): # Raised when the method is not connected to the signal yet. pass # Don't need to disconnect. - self._download_reply.abort() + try: + self._download_reply.abort() + except RuntimeError: + # In some cases the garbage collector is a bit to agressive, which causes the dowload_reply + # to be deleted (especially if the machine has been put to sleep). As we don't know what exactly causes + # this (The issue probably lives in the bowels of (py)Qt somewhere), we can only catch and ignore it. + pass self._download_reply = None self._download_request = None self.setDownloadProgress(0) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 8c63e1ef1a..aa4893b3b9 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -140,7 +140,7 @@ Item { id: printerConfiguration anchors.verticalCenter: parent.verticalCenter - buildplate: printer ? "Glass" : null // 'Glass' as a default + buildplate: printer ? catalog.i18nc("@label", "Glass") : null // 'Glass' as a default configurations: { var configs = [] diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index a6bc13f3c2..8d923d3827 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -286,7 +286,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self.refreshConnections() - def _checkManualDevice(self, address): + def _checkManualDevice(self, address: str) -> None: # Check if a UM3 family device exists at this address. # If a printer responds, it will replace the preliminary printer created above # origin=manual is for tracking back the origin of the call @@ -307,7 +307,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): # - Something went wrong with checking the amount of printers the cluster has! # - Couldn't find printer at the address when trying to add it manually. if address in self._manual_instances: - self.removeManualDeviceSignal.emit(self.getPluginId(), "", address) + key = "manual:" + address + self.removeManualDevice(key, address) return if "system" in reply_url: diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 0c195e9017..6ce042f32d 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -226,6 +226,9 @@ class USBPrinterOutputDevice(PrinterOutputDevice): except SerialTimeoutException: Logger.log("w", "Timeout when sending command to printer via USB.") self._command_received.set() + except SerialException: + Logger.logException("w", "An unexpected exception occurred while writing to the serial.") + self.setConnectionState(ConnectionState.Error) def _update(self): while self._connection_state == ConnectionState.Connected and self._serial is not None: @@ -371,10 +374,17 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum)) - progress = (self._gcode_position / len(self._gcode)) + print_job = self._printers[0].activePrintJob + try: + progress = self._gcode_position / len(self._gcode) + except ZeroDivisionError: + # There is nothing to send! + if print_job is not None: + print_job.updateState("error") + return elapsed_time = int(time() - self._print_start_time) - print_job = self._printers[0].activePrintJob + if print_job is None: controller = GenericOutputController(self) controller.setCanUpdateFirmware(True) diff --git a/resources/definitions/alya3dp.def.json b/resources/definitions/alya3dp.def.json index f449a89970..7187048da0 100644 --- a/resources/definitions/alya3dp.def.json +++ b/resources/definitions/alya3dp.def.json @@ -44,7 +44,7 @@ }, "machine_end_gcode": { - "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" + "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" } } } \ No newline at end of file diff --git a/resources/definitions/alyanx3dp.def.json b/resources/definitions/alyanx3dp.def.json index efc97c09d1..085acc20c1 100644 --- a/resources/definitions/alyanx3dp.def.json +++ b/resources/definitions/alyanx3dp.def.json @@ -44,7 +44,7 @@ }, "machine_end_gcode": { - "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" + "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" } } } \ No newline at end of file diff --git a/resources/definitions/kupido.def.json b/resources/definitions/kupido.def.json index 577a63581e..191e02ba34 100644 --- a/resources/definitions/kupido.def.json +++ b/resources/definitions/kupido.def.json @@ -43,7 +43,7 @@ }, "machine_end_gcode": { - "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" + "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" } } } \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a47ab28755..55bede1866 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -211,7 +211,7 @@ UM.MainWindow for (var i = 0; i < drop.urls.length; i++) { var filename = drop.urls[i]; - if (filename.endsWith(".curapackage")) + if (filename.toLowerCase().endsWith(".curapackage")) { // Try to install plugin & close. CuraApplication.getPackageManager().installPackageViaDragAndDrop(filename); diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index 33d7958340..98e2042448 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -25,13 +25,17 @@ Button property var outputDevice: null property var printerTypesList: [] + // Indicates if only to update the printer types list when this button is checked + property bool updatePrinterTypesOnlyWhenChecked: true + property var updatePrinterTypesFunction: updatePrinterTypesList // This function converts the printer type string to another string. property var printerTypeLabelConversionFunction: Cura.MachineManager.getAbbreviatedMachineName function updatePrinterTypesList() { - printerTypesList = (outputDevice != null) ? outputDevice.uniquePrinterTypes : [] + var to_update = (updatePrinterTypesOnlyWhenChecked && checked) || !updatePrinterTypesOnlyWhenChecked + printerTypesList = (to_update && outputDevice != null) ? outputDevice.uniquePrinterTypes : [] } contentItem: Item diff --git a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml index 53a3241527..924eeb930d 100644 --- a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml @@ -97,6 +97,8 @@ Item printerTypeLabelAutoFit: true + // update printer types for all items in the list + updatePrinterTypesOnlyWhenChecked: false updatePrinterTypesFunction: updateMachineTypes // show printer type as it is printerTypeLabelConversionFunction: function(value) { return value } diff --git a/resources/qml/WelcomePages/AddPrinterByIpContent.qml b/resources/qml/WelcomePages/AddPrinterByIpContent.qml index 5ec8bd42f8..2930bc8dbe 100644 --- a/resources/qml/WelcomePages/AddPrinterByIpContent.qml +++ b/resources/qml/WelcomePages/AddPrinterByIpContent.qml @@ -69,16 +69,14 @@ Item width: parent.width anchors.top: explainLabel.bottom - TextField + Cura.TextField { id: hostnameField + width: (parent.width / 2) | 0 + height: addPrinterButton.height anchors.verticalCenter: addPrinterButton.verticalCenter anchors.left: parent.left - height: addPrinterButton.height - anchors.right: addPrinterButton.left anchors.margins: UM.Theme.getSize("default_margin").width - font: UM.Theme.getFont("default") - selectByMouse: true validator: RegExpValidator { @@ -89,11 +87,11 @@ Item onAccepted: addPrinterButton.clicked() } - Cura.PrimaryButton + Cura.SecondaryButton { id: addPrinterButton anchors.top: parent.top - anchors.right: parent.right + anchors.left: hostnameField.right anchors.margins: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Add") @@ -198,7 +196,10 @@ Item { if (UM.OutputDeviceManager.hasManualDevice) { - typeText.text = UM.OutputDeviceManager.manualDeviceProperty("printer_type") + const type_id = UM.OutputDeviceManager.manualDeviceProperty("printer_type") + var readable_type = Cura.MachineManager.getMachineTypeNameFromId(type_id) + readable_type = (readable_type != "") ? readable_type : catalog.i18nc("@label", "Unknown") + typeText.text = readable_type firmwareText.text = UM.OutputDeviceManager.manualDeviceProperty("firmware_version") addressText.text = UM.OutputDeviceManager.manualDeviceProperty("address") } @@ -240,7 +241,7 @@ Item id: backButton anchors.left: parent.left anchors.bottom: parent.bottom - text: catalog.i18nc("@button", "Cancel") + text: catalog.i18nc("@button", "Back") onClicked: base.showPreviousPage() } diff --git a/resources/qml/WelcomePages/UserAgreementContent.qml b/resources/qml/WelcomePages/UserAgreementContent.qml index 7c83df29cd..2c8196f0e1 100644 --- a/resources/qml/WelcomePages/UserAgreementContent.qml +++ b/resources/qml/WelcomePages/UserAgreementContent.qml @@ -70,7 +70,6 @@ Item onClicked: { CuraApplication.writeToLog("i", "User declined the User Agreement.") - base.endWizard() CuraApplication.closeApplication() // NOTE: Hard exit, don't use if anything needs to be saved! } } diff --git a/resources/qml/WelcomePages/WhatsNewContent.qml b/resources/qml/WelcomePages/WhatsNewContent.qml index db6cd3b576..415acae05c 100644 --- a/resources/qml/WelcomePages/WhatsNewContent.qml +++ b/resources/qml/WelcomePages/WhatsNewContent.qml @@ -27,8 +27,10 @@ Item renderType: Text.NativeRendering } - Rectangle + Cura.ScrollableTextArea { + id: whatsNewTextArea + anchors.top: titleLabel.bottom anchors.bottom: getStartedButton.top anchors.topMargin: UM.Theme.getSize("wide_margin").height @@ -36,27 +38,12 @@ Item anchors.left: parent.left anchors.right: parent.right - border.color: "#dfdfdf" - border.width: UM.Theme.getSize("default_lining").width + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - ScrollView - { - anchors.fill: parent - anchors.margins: UM.Theme.getSize("default_lining").width - - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - - TextArea - { - id: whatsNewTextArea - text: CuraApplication.getTextManager().getChangeLogText() - textFormat: Text.RichText - wrapMode: Text.WordWrap - readOnly: true - font: UM.Theme.getFont("default") - renderType: Text.NativeRendering - } - } + textArea.text: CuraApplication.getTextManager().getChangeLogText() + textArea.textFormat: Text.RichText + textArea.wrapMode: Text.WordWrap + textArea.readOnly: true } Cura.PrimaryButton diff --git a/resources/qml/Widgets/NotificationIcon.qml b/resources/qml/Widgets/NotificationIcon.qml index d06d9f16be..5cf4d17777 100644 --- a/resources/qml/Widgets/NotificationIcon.qml +++ b/resources/qml/Widgets/NotificationIcon.qml @@ -25,12 +25,16 @@ Rectangle Label { id: notificationLabel - anchors.centerIn: parent anchors.fill: parent color: UM.Theme.getColor("primary_text") horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering + + // This is a bit of a hack, but we don't really have enough room for 2 characters (eg 9+). The default font + // does have a tad bit to much spacing. So instead of adding a whole new font, we just modify it a bit for this + // specific instance. + Component.onCompleted: font.letterSpacing = -1 } } diff --git a/resources/qml/Widgets/RadioButton.qml b/resources/qml/Widgets/RadioButton.qml index eaa18c44cb..b101b3739b 100644 --- a/resources/qml/Widgets/RadioButton.qml +++ b/resources/qml/Widgets/RadioButton.qml @@ -27,6 +27,7 @@ RadioButton implicitWidth: UM.Theme.getSize("radio_button").width implicitHeight: UM.Theme.getSize("radio_button").height anchors.verticalCenter: parent.verticalCenter + anchors.alignWhenCentered: false radius: width / 2 border.width: UM.Theme.getSize("default_lining").width border.color: radioButton.hovered ? UM.Theme.getColor("small_button_text") : UM.Theme.getColor("small_button_text_hover") diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml new file mode 100644 index 0000000000..065d5e60df --- /dev/null +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -0,0 +1,32 @@ +// Copyright (c) 2019 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.10 +import QtQuick.Controls 2.3 + +import UM 1.3 as UM +import Cura 1.1 as Cura + + +// +// Cura-style TextArea with scrolls +// +ScrollView +{ + property alias textArea: _textArea + + TextArea + { + id: _textArea + font: UM.Theme.getFont("default") + textFormat: TextEdit.PlainText + renderType: Text.NativeRendering + selectByMouse: true + + background: Rectangle // Border + { + border.color: UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width + } + } +} diff --git a/resources/qml/Widgets/TextField.qml b/resources/qml/Widgets/TextField.qml index bff50fec32..05e14ec344 100644 --- a/resources/qml/Widgets/TextField.qml +++ b/resources/qml/Widgets/TextField.qml @@ -48,12 +48,22 @@ TextField background: Rectangle { id: backgroundRectangle + anchors.fill: parent anchors.margins: Math.round(UM.Theme.getSize("default_lining").width) radius: UM.Theme.getSize("setting_control_radius").width - border.color: UM.Theme.getColor("setting_control_border") - - color: UM.Theme.getColor("setting_control") + border.color: + { + if (!textField.enabled) + { + return UM.Theme.getColor("setting_control_disabled_border") + } + if (textField.hovered || textField.activeFocus) + { + return UM.Theme.getColor("setting_control_border_highlight") + } + return UM.Theme.getColor("setting_control_border") + } } } diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 11ee69766e..16ccfe2434 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -31,6 +31,7 @@ CheckBox 1.0 CheckBox.qml ComboBox 1.0 ComboBox.qml NotificationIcon 1.0 NotificationIcon.qml RadioButton 1.0 RadioButton.qml +Scrollable 1.0 Scrollable.qml TabButton 1.0 TabButton.qml TextField 1.0 TextField.qml diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f287e60310..4b2f92e6e5 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -604,7 +604,7 @@ "toolbox_action_button": [8.0, 2.5], "toolbox_loader": [2.0, 2.0], - "notification_icon": [1.4, 1.4], + "notification_icon": [1.5, 1.5], "avatar_image": [6.8, 6.8],