diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 89a996fba1..bdae032f36 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Ultimaker B.V. +# Copyright (c) 2022 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt @@ -9,6 +9,7 @@ from UM import i18nCatalog from UM.Logger import Logger from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.SettingFunction import SettingFunction # To format setting functions differently. import os @@ -173,12 +174,19 @@ class QualitySettingsModel(ListModel): label = definition.label if self._i18n_catalog: label = self._i18n_catalog.i18nc(definition.key + " label", label) + if profile_value_source == "quality_changes": + label = f"{label}" # Make setting name italic if it's derived from the quality-changes profile. + + if isinstance(profile_value, SettingFunction): + profile_value_display = self._i18n_catalog.i18nc("@info:status", "Calculated") + else: + profile_value_display = "" if profile_value is None else str(profile_value) items.append({ "key": definition.key, "label": label, "unit": definition.unit, - "profile_value": "" if profile_value is None else str(profile_value), # it is for display only + "profile_value": profile_value_display, "profile_value_source": profile_value_source, "user_value": "" if user_value is None else str(user_value), "category": current_category diff --git a/plugins/CuraDrive/src/qml/components/BackupList.qml b/plugins/CuraDrive/src/qml/components/BackupList.qml index a4a460a885..8392792808 100644 --- a/plugins/CuraDrive/src/qml/components/BackupList.qml +++ b/plugins/CuraDrive/src/qml/components/BackupList.qml @@ -1,39 +1,34 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 -import UM 1.1 as UM +import UM 1.5 as UM -ScrollView +ListView { - property alias model: backupList.model - width: parent.width clip: true - ListView + ScrollBar.vertical: UM.ScrollBar {} + + delegate: Item { - id: backupList - width: parent.width - delegate: Item + // Add a margin, otherwise the scrollbar is on top of the right most component + width: parent.width - UM.Theme.getSize("scrollbar").width + height: childrenRect.height + + BackupListItem { - // Add a margin, otherwise the scrollbar is on top of the right most component - width: parent.width - UM.Theme.getSize("default_margin").width - height: childrenRect.height + id: backupListItem + width: parent.width + } - BackupListItem - { - id: backupListItem - width: parent.width - } - - Rectangle - { - id: divider - color: UM.Theme.getColor("lining") - height: UM.Theme.getSize("default_lining").height - } + Rectangle + { + id: divider + color: UM.Theme.getColor("lining") + height: UM.Theme.getSize("default_lining").height } } } diff --git a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml index 0e55efeb39..5f594cb79e 100644 --- a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml @@ -1,8 +1,9 @@ -// Copyright (C) 2021 Ultimaker B.V. +//Copyright (C) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.10 +import Qt.labs.qmlmodels 1.0 +import QtQuick 2.15 import QtQuick.Window 2.2 -import QtQuick.Controls 1.4 as OldControls // TableView doesn't exist in the QtQuick Controls 2.x in 5.10, so use the old one import QtQuick.Controls 2.3 import UM 1.2 as UM @@ -56,52 +57,32 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - - Cura.TableView + //We can't use Cura's TableView here, since in Cura >= 5.0 this uses QtQuick.TableView, while in Cura < 5.0 this uses QtControls1.TableView. + //So we have to define our own. Once support for 4.13 and earlier is dropped, we can switch to Cura.TableView. + Table { id: filesTableView anchors.fill: parent - model: manager.digitalFactoryFileModel - visible: model.count != 0 && manager.retrievingFileStatus != DF.RetrievalStatus.InProgress - selectionMode: OldControls.SelectionMode.SingleSelection - onDoubleClicked: + anchors.margins: parent.border.width + + columnHeaders: ["Name", "Uploaded by", "Uploaded at"] + model: TableModel + { + TableModelColumn { display: "fileName" } + TableModelColumn { display: "username" } + TableModelColumn { display: "uploadedAt" } + rows: manager.digitalFactoryFileModel.items + } + + onCurrentRowChanged: + { + manager.setSelectedFileIndices([currentRow]); + } + onDoubleClicked: function(row) { manager.setSelectedFileIndices([row]); openFilesButton.clicked(); } - - OldControls.TableViewColumn - { - id: fileNameColumn - role: "fileName" - title: "Name" - width: Math.round(filesTableView.width / 3) - } - - OldControls.TableViewColumn - { - id: usernameColumn - role: "username" - title: "Uploaded by" - width: Math.round(filesTableView.width / 3) - } - - OldControls.TableViewColumn - { - role: "uploadedAt" - title: "Uploaded at" - } - - Connections - { - target: filesTableView.selection - function onSelectionChanged() - { - let newSelection = []; - filesTableView.selection.forEach(function(rowIndex) { newSelection.push(rowIndex); }); - manager.setSelectedFileIndices(newSelection); - } - } } Label @@ -160,7 +141,6 @@ Item { // Make sure no files are selected when the file model changes filesTableView.currentRow = -1 - filesTableView.selection.clear() } } } @@ -186,7 +166,7 @@ Item anchors.bottom: parent.bottom anchors.right: parent.right text: "Open" - enabled: filesTableView.selection.count > 0 + enabled: filesTableView.currentRow >= 0 onClicked: { manager.openSelectedFiles() diff --git a/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml index 139333c150..8d72ed9ff4 100644 --- a/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml @@ -1,8 +1,9 @@ -// Copyright (C) 2021 Ultimaker B.V. +//Copyright (C) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. +import Qt.labs.qmlmodels 1.0 import QtQuick 2.10 import QtQuick.Window 2.2 -import QtQuick.Controls 1.4 as OldControls // TableView doesn't exist in the QtQuick Controls 2.x in 5.10, so use the old one import QtQuick.Controls 2.3 import UM 1.2 as UM @@ -85,35 +86,22 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - - Cura.TableView + //We can't use Cura's TableView here, since in Cura >= 5.0 this uses QtQuick.TableView, while in Cura < 5.0 this uses QtControls1.TableView. + //So we have to define our own. Once support for 4.13 and earlier is dropped, we can switch to Cura.TableView. + Table { id: filesTableView anchors.fill: parent - model: manager.digitalFactoryFileModel - visible: model.count != 0 && manager.retrievingFileStatus != DF.RetrievalStatus.InProgress - selectionMode: OldControls.SelectionMode.NoSelection + anchors.margins: parent.border.width - OldControls.TableViewColumn + allowSelection: false + columnHeaders: ["Name", "Uploaded by", "Uploaded at"] + model: TableModel { - id: fileNameColumn - role: "fileName" - title: "@tableViewColumn:title", "Name" - width: Math.round(filesTableView.width / 3) - } - - OldControls.TableViewColumn - { - id: usernameColumn - role: "username" - title: "Uploaded by" - width: Math.round(filesTableView.width / 3) - } - - OldControls.TableViewColumn - { - role: "uploadedAt" - title: "Uploaded at" + TableModelColumn { display: "fileName" } + TableModelColumn { display: "username" } + TableModelColumn { display: "uploadedAt" } + rows: manager.digitalFactoryFileModel.items } } @@ -172,8 +160,7 @@ Item function onItemsChanged() { // Make sure no files are selected when the file model changes - filesTableView.currentRow = -1 - filesTableView.selection.clear() + filesTableView.currentRow = -1; } } } diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml new file mode 100644 index 0000000000..2e4c89dfa1 --- /dev/null +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -0,0 +1,200 @@ +//Copyright (C) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. + +import Qt.labs.qmlmodels 1.0 +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +import UM 1.2 as UM + +/* + * A re-sizeable table of data. + * + * This table combines a list of headers with a TableView to show certain roles in a table. + * The columns of the table can be resized. + * When the table becomes too big, you can scroll through the table. When a column becomes too small, the contents of + * the table are elided. + * The table gets Cura's themeing. + */ +Item +{ + id: tableBase + + required property var columnHeaders //The text to show in the headers of each column. + property alias model: tableView.model //A TableModel to display in this table. To use a ListModel for the rows, use "rows: listModel.items" + property int currentRow: -1 //The selected row index. + property var onDoubleClicked: function(row) {} //Something to execute when double clicked. Accepts one argument: The index of the row that was clicked on. + property bool allowSelection: true //Whether to allow the user to select items. + + Row + { + id: headerBar + Repeater + { + id: headerRepeater + model: columnHeaders + Rectangle + { + width: Math.max(1, Math.round(tableBase.width / headerRepeater.count)) + height: UM.Theme.getSize("section").height + + color: UM.Theme.getColor("secondary") + + Label + { + id: contentText + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("narrow_margin").width + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("narrow_margin").width + + text: modelData + font: UM.Theme.getFont("medium_bold") + color: UM.Theme.getColor("text") + elide: Text.ElideRight + } + Rectangle //Resize handle. + { + anchors + { + right: parent.right + top: parent.top + bottom: parent.bottom + } + width: UM.Theme.getSize("thick_lining").width + + color: UM.Theme.getColor("thick_lining") + + MouseArea + { + anchors.fill: parent + + cursorShape: Qt.SizeHorCursor + drag + { + target: parent + axis: Drag.XAxis + } + onMouseXChanged: + { + if(drag.active) + { + let new_width = parent.parent.width + mouseX; + let sum_widths = mouseX; + for(let i = 0; i < headerBar.children.length; ++i) + { + sum_widths += headerBar.children[i].width; + } + if(sum_widths > tableBase.width) + { + new_width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view. + } + let width_fraction = new_width / tableBase.width; //Scale with the same fraction along with the total width, if the table is resized. + parent.parent.width = Qt.binding(function() { return tableBase.width * width_fraction }); + } + } + } + } + + onWidthChanged: + { + tableView.forceLayout(); //Rescale table cells underneath as well. + } + } + } + } + + TableView + { + id: tableView + anchors + { + top: headerBar.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + + clip: true + ScrollBar.vertical: ScrollBar + { + // Vertical ScrollBar, styled similarly to the scrollBar in the settings panel + id: verticalScrollBar + visible: tableView.contentHeight > tableView.height + + background: Rectangle + { + implicitWidth: UM.Theme.getSize("scrollbar").width + radius: Math.round(implicitWidth / 2) + color: UM.Theme.getColor("scrollbar_background") + } + + contentItem: Rectangle + { + id: scrollViewHandle + implicitWidth: UM.Theme.getSize("scrollbar").width + radius: Math.round(implicitWidth / 2) + + color: verticalScrollBar.pressed ? UM.Theme.getColor("scrollbar_handle_down") : verticalScrollBar.hovered ? UM.Theme.getColor("scrollbar_handle_hover") : UM.Theme.getColor("scrollbar_handle") + Behavior on color { ColorAnimation { duration: 50; } } + } + } + columnWidthProvider: function(column) + { + return headerBar.children[column].width; //Cells get the same width as their column header. + } + + delegate: Rectangle + { + implicitHeight: Math.max(1, cellContent.height) + + color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) + + Label + { + id: cellContent + width: parent.width + + text: display + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + TextMetrics + { + id: cellTextMetrics + text: cellContent.text + font: cellContent.font + elide: cellContent.elide + elideWidth: cellContent.width + } + UM.TooltipArea + { + anchors.fill: parent + + text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided. + onClicked: + { + if(tableBase.allowSelection) + { + tableBase.currentRow = row; //Select this row. + } + } + onDoubleClicked: + { + tableBase.onDoubleClicked(row); + } + } + } + + Connections + { + target: model + function onRowCountChanged() + { + tableView.contentY = 0; //When the number of rows is reduced, make sure to scroll back to the start. + } + } + } +} \ No newline at end of file diff --git a/plugins/ImageReader/ConfigUI.qml b/plugins/ImageReader/ConfigUI.qml index a3dceed50d..70a26d17d4 100644 --- a/plugins/ImageReader/ConfigUI.qml +++ b/plugins/ImageReader/ConfigUI.qml @@ -1,8 +1,9 @@ -// Copyright (c) 2015 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.1 -import QtQuick.Controls 1.1 +import QtQuick.Controls 1.1 as OldControls +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 @@ -27,20 +28,24 @@ UM.Dialog rowSpacing: 4 * screenScaleFactor columns: 1 - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","The maximum distance of each pixel from \"Base.\"") - Row { + Row + { width: parent.width - Label { + Label + { text: catalog.i18nc("@action:label", "Height (mm)") width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - TextField { + OldControls.TextField + { id: peak_height objectName: "Peak_Height" validator: RegExpValidator {regExp: /^\d{0,3}([\,|\.]\d*)?$/} @@ -50,20 +55,24 @@ UM.Dialog } } - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","The base height from the build plate in millimeters.") - Row { + Row + { width: parent.width - Label { + Label + { text: catalog.i18nc("@action:label", "Base (mm)") width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - TextField { + OldControls.TextField + { id: base_height objectName: "Base_Height" validator: RegExpValidator {regExp: /^\d{0,3}([\,|\.]\d*)?$/} @@ -73,20 +82,24 @@ UM.Dialog } } - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","The width in millimeters on the build plate.") - Row { + Row + { width: parent.width - Label { + Label + { text: catalog.i18nc("@action:label", "Width (mm)") width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - TextField { + OldControls.TextField + { id: width objectName: "Width" focus: true @@ -97,19 +110,23 @@ UM.Dialog } } - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","The depth in millimeters on the build plate") - Row { + Row + { width: parent.width - Label { + Label + { text: catalog.i18nc("@action:label", "Depth (mm)") width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - TextField { + OldControls.TextField + { id: depth objectName: "Depth" focus: true @@ -120,20 +137,24 @@ UM.Dialog } } - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","For lithophanes dark pixels should correspond to thicker locations in order to block more light coming through. For height maps lighter pixels signify higher terrain, so lighter pixels should correspond to thicker locations in the generated 3D model.") - Row { + Row + { width: parent.width //Empty label so 2 column layout works. - Label { + Label + { text: "" width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - ComboBox { + OldControls.ComboBox + { id: lighter_is_higher objectName: "Lighter_Is_Higher" model: [ catalog.i18nc("@item:inlistbox","Darker is higher"), catalog.i18nc("@item:inlistbox","Lighter is higher") ] @@ -143,19 +164,23 @@ UM.Dialog } } - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","For lithophanes a simple logarithmic model for translucency is available. For height maps the pixel values correspond to heights linearly.") - Row { + Row + { width: parent.width - Label { + Label + { text: "Color Model" width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - ComboBox { + OldControls.ComboBox + { id: color_model objectName: "ColorModel" model: [ catalog.i18nc("@item:inlistbox","Linear"), catalog.i18nc("@item:inlistbox","Translucency") ] @@ -165,20 +190,24 @@ UM.Dialog } } - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","The percentage of light penetrating a print with a thickness of 1 millimeter. Lowering this value increases the contrast in dark regions and decreases the contrast in light regions of the image.") visible: color_model.currentText == catalog.i18nc("@item:inlistbox","Translucency") - Row { + Row + { width: parent.width - Label { + Label + { text: catalog.i18nc("@action:label", "1mm Transmittance (%)") width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - TextField { + OldControls.TextField + { id: transmittance objectName: "Transmittance" focus: true @@ -189,28 +218,34 @@ UM.Dialog } } - UM.TooltipArea { + UM.TooltipArea + { Layout.fillWidth:true height: childrenRect.height text: catalog.i18nc("@info:tooltip","The amount of smoothing to apply to the image.") - Row { + Row + { width: parent.width - Label { + Label + { text: catalog.i18nc("@action:label", "Smoothing") width: 150 * screenScaleFactor anchors.verticalCenter: parent.verticalCenter } - Item { + Item + { width: 180 * screenScaleFactor height: 20 * screenScaleFactor Layout.fillWidth: true - Slider { + Slider + { id: smoothing objectName: "Smoothing" - maximumValue: 100.0 + from: 0.0 + to: 100.0 stepSize: 1.0 width: 180 onValueChanged: { manager.onSmoothingChanged(value) } @@ -221,14 +256,14 @@ UM.Dialog } rightButtons: [ - Button + OldControls.Button { id:ok_button text: catalog.i18nc("@action:button","OK"); onClicked: { manager.onOkButtonClicked() } enabled: true }, - Button + OldControls.Button { id:cancel_button text: catalog.i18nc("@action:button","Cancel"); diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 8c4c00a3a5..0f0ffac8cd 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2019 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. +//Copyright (c) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 import QtQuick.Controls 2.3 @@ -111,6 +111,7 @@ Cura.MachineAction model: tabNameModel delegate: UM.TabRowButton { + checked: model.index == 0 text: model.name } } diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index c97989c449..098876e368 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -1,9 +1,10 @@ -// Copyright (c) 2021 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2022 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.2 +import QtQuick.Controls 1.2 as OldControls import QtQuick.Controls.Styles 1.2 +import QtQuick.Controls 2.15 import UM 1.5 as UM import Cura 1.0 as Cura @@ -76,7 +77,7 @@ Item id: meshTypeButtons spacing: UM.Theme.getSize("default_margin").width - Button + OldControls.Button { id: normalButton text: catalog.i18nc("@label", "Normal model") @@ -88,7 +89,7 @@ Item z: 4 } - Button + OldControls.Button { id: supportMeshButton text: catalog.i18nc("@label", "Print as support") @@ -100,7 +101,7 @@ Item z: 3 } - Button + OldControls.Button { id: overlapMeshButton text: catalog.i18nc("@label", "Modify settings for overlaps") @@ -112,7 +113,7 @@ Item z: 2 } - Button + OldControls.Button { id: antiOverhangMeshButton text: catalog.i18nc("@label", "Don't support overlaps") @@ -179,189 +180,187 @@ Item height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight) visible: currentMeshType != "anti_overhang_mesh" - ScrollView + ListView { + id: contents height: parent.height width: UM.Theme.getSize("setting").width + UM.Theme.getSize("default_margin").width - style: UM.Theme.styles.scrollview - ListView + ScrollBar.vertical: UM.ScrollBar {} + clip: true + spacing: UM.Theme.getSize("default_lining").height + + model: UM.SettingDefinitionsModel { - id: contents - spacing: UM.Theme.getSize("default_lining").height - - model: UM.SettingDefinitionsModel + id: addedSettingsModel + containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" + expanded: [ "*" ] + filter: { - id: addedSettingsModel - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - expanded: [ "*" ] - filter: + if (printSequencePropertyProvider.properties.value == "one_at_a_time") { - if (printSequencePropertyProvider.properties.value == "one_at_a_time") + return {"settable_per_meshgroup": true} + } + return {"settable_per_mesh": true} + } + exclude: + { + var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ] + + if (currentMeshType == "support_mesh") + { + excluded_settings = excluded_settings.concat(base.allCategoriesExceptSupport) + } + return excluded_settings + } + + visibilityHandler: Cura.PerObjectSettingVisibilityHandler + { + id: visibility_handler + selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId") + } + + // For some reason the model object is updated after removing him from the memory and + // it happens only on Windows. For this reason, set the destroyed value manually. + Component.onDestruction: + { + setDestroyed(true) + } + } + + delegate: Row + { + spacing: - UM.Theme.getSize("default_margin").width + Loader + { + id: settingLoader + width: UM.Theme.getSize("setting").width + height: UM.Theme.getSize("section").height + enabled: provider.properties.enabled === "True" + property var definition: model + property var settingDefinitionsModel: addedSettingsModel + property var propertyProvider: provider + property var globalPropertyProvider: inheritStackProvider + property var externalResetHandler: false + + //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 + //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, + //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. + asynchronous: model.type != "enum" && model.type != "extruder" + + onLoaded: + { + settingLoader.item.showRevertButton = false + settingLoader.item.showInheritButton = false + settingLoader.item.showLinkedSettingIcon = false + settingLoader.item.doDepthIndentation = false + settingLoader.item.doQualityUserSettingEmphasis = false + } + + sourceComponent: + { + switch(model.type) { - return {"settable_per_meshgroup": true} + case "int": + return settingTextField + case "[int]": + return settingTextField + case "float": + return settingTextField + case "enum": + return settingComboBox + case "extruder": + return settingExtruder + case "optional_extruder": + return settingOptionalExtruder + case "bool": + return settingCheckBox + case "str": + return settingTextField + case "category": + return settingCategory + default: + return settingUnknown } - return {"settable_per_mesh": true} - } - exclude: - { - var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ] - - if (currentMeshType == "support_mesh") - { - excluded_settings = excluded_settings.concat(base.allCategoriesExceptSupport) - } - return excluded_settings - } - - visibilityHandler: Cura.PerObjectSettingVisibilityHandler - { - id: visibility_handler - selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId") - } - - // For some reason the model object is updated after removing him from the memory and - // it happens only on Windows. For this reason, set the destroyed value manually. - Component.onDestruction: - { - setDestroyed(true) } } - delegate: Row + OldControls.Button { - spacing: - UM.Theme.getSize("default_margin").width - Loader + width: Math.round(UM.Theme.getSize("setting").height / 2) + height: UM.Theme.getSize("setting").height + + onClicked: addedSettingsModel.setVisible(model.key, false) + + style: ButtonStyle { - id: settingLoader - width: UM.Theme.getSize("setting").width - height: UM.Theme.getSize("section").height - enabled: provider.properties.enabled === "True" - property var definition: model - property var settingDefinitionsModel: addedSettingsModel - property var propertyProvider: provider - property var globalPropertyProvider: inheritStackProvider - property var externalResetHandler: false - - //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 - //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, - //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. - asynchronous: model.type != "enum" && model.type != "extruder" - - onLoaded: + background: Item { - settingLoader.item.showRevertButton = false - settingLoader.item.showInheritButton = false - settingLoader.item.showLinkedSettingIcon = false - settingLoader.item.doDepthIndentation = false - settingLoader.item.doQualityUserSettingEmphasis = false - } - - sourceComponent: - { - switch(model.type) + UM.RecolorImage { - case "int": - return settingTextField - case "[int]": - return settingTextField - case "float": - return settingTextField - case "enum": - return settingComboBox - case "extruder": - return settingExtruder - case "optional_extruder": - return settingOptionalExtruder - case "bool": - return settingCheckBox - case "str": - return settingTextField - case "category": - return settingCategory - default: - return settingUnknown + anchors.verticalCenter: parent.verticalCenter + width: parent.width + height: width + sourceSize.height: width + color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") + source: UM.Theme.getIcon("Minus") } } } + } - Button + // Specialty provider that only watches global_inherits (we can't filter on what property changed we get events + // so we bypass that to make a dedicated provider). + UM.SettingPropertyProvider + { + id: provider + + containerStackId: UM.ActiveTool.properties.getValue("ContainerID") + key: model.key + watchedProperties: [ "value", "enabled", "validationState" ] + storeIndex: 0 + removeUnusedValue: false + } + + UM.SettingPropertyProvider + { + id: inheritStackProvider + containerStackId: UM.ActiveTool.properties.getValue("ContainerID") + key: model.key + watchedProperties: [ "limit_to_extruder" ] + } + + Connections + { + target: inheritStackProvider + function onPropertiesChanged() { provider.forcePropertiesChanged() } + } + + Connections + { + target: UM.ActiveTool + function onPropertiesChanged() { - width: Math.round(UM.Theme.getSize("setting").height / 2) - height: UM.Theme.getSize("setting").height - - onClicked: addedSettingsModel.setVisible(model.key, false) - - style: ButtonStyle + // the values cannot be bound with UM.ActiveTool.properties.getValue() calls, + // so here we connect to the signal and update the those values. + if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined") { - background: Item + const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId") + if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId) { - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - width: parent.width - height: width - sourceSize.height: width - color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") - source: UM.Theme.getIcon("Minus") - } + addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId } } - } - - // Specialty provider that only watches global_inherits (we can't filter on what property changed we get events - // so we bypass that to make a dedicated provider). - UM.SettingPropertyProvider - { - id: provider - - containerStackId: UM.ActiveTool.properties.getValue("ContainerID") - key: model.key - watchedProperties: [ "value", "enabled", "validationState" ] - storeIndex: 0 - removeUnusedValue: false - } - - UM.SettingPropertyProvider - { - id: inheritStackProvider - containerStackId: UM.ActiveTool.properties.getValue("ContainerID") - key: model.key - watchedProperties: [ "limit_to_extruder" ] - } - - Connections - { - target: inheritStackProvider - function onPropertiesChanged() { provider.forcePropertiesChanged() } - } - - Connections - { - target: UM.ActiveTool - function onPropertiesChanged() + if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined") { - // the values cannot be bound with UM.ActiveTool.properties.getValue() calls, - // so here we connect to the signal and update the those values. - if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined") + const containerId = UM.ActiveTool.properties.getValue("ContainerID") + if (provider.containerStackId != containerId) { - const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId") - if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId) - { - addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId - } + provider.containerStackId = containerId } - if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined") + if (inheritStackProvider.containerStackId != containerId) { - const containerId = UM.ActiveTool.properties.getValue("ContainerID") - if (provider.containerStackId != containerId) - { - provider.containerStackId = containerId - } - if (inheritStackProvider.containerStackId != containerId) - { - inheritStackProvider.containerStackId = containerId - } + inheritStackProvider.containerStackId = containerId } } } diff --git a/plugins/PerObjectSettingsTool/SettingPickDialog.qml b/plugins/PerObjectSettingsTool/SettingPickDialog.qml index 18f36b2651..16590c68f1 100644 --- a/plugins/PerObjectSettingsTool/SettingPickDialog.qml +++ b/plugins/PerObjectSettingsTool/SettingPickDialog.qml @@ -1,7 +1,10 @@ -import QtQuick 2.2 -import QtQuick.Controls 1.2 +// Copyright (c) 2022 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. -import UM 1.2 as UM +import QtQuick 2.2 +import QtQuick.Controls 2.2 + +import UM 1.5 as UM import Cura 1.0 as Cura import ".." @@ -67,10 +70,9 @@ UM.Dialog text: catalog.i18nc("@label:checkbox", "Show all") } - ScrollView + ListView { - id: scrollView - + id: listview anchors { top: filterInput.bottom @@ -78,47 +80,47 @@ UM.Dialog right: parent.right bottom: parent.bottom } - ListView + + ScrollBar.vertical: UM.ScrollBar {} + clip: true + + model: UM.SettingDefinitionsModel { - id: listview - model: UM.SettingDefinitionsModel + id: definitionsModel + containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" + visibilityHandler: UM.SettingPreferenceVisibilityHandler {} + expanded: [ "*" ] + exclude: { - id: definitionsModel - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - visibilityHandler: UM.SettingPreferenceVisibilityHandler {} - expanded: [ "*" ] - exclude: - { - var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ] - excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings) - return excluded_settings - } - showAll: toggleShowAll.checked || filterInput.text !== "" + var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ] + excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings) + return excluded_settings } - delegate: Loader - { - id: loader - - width: listview.width - height: model.type != undefined ? UM.Theme.getSize("section").height : 0 - - property var definition: model - property var settingDefinitionsModel: definitionsModel - - asynchronous: true - source: - { - switch(model.type) - { - case "category": - return "PerObjectCategory.qml" - default: - return "PerObjectItem.qml" - } - } - } - Component.onCompleted: settingPickDialog.updateFilter() + showAll: toggleShowAll.checked || filterInput.text !== "" } + delegate: Loader + { + id: loader + + width: listview.width + height: model.type != undefined ? UM.Theme.getSize("section").height : 0 + + property var definition: model + property var settingDefinitionsModel: definitionsModel + + asynchronous: true + source: + { + switch(model.type) + { + case "category": + return "PerObjectCategory.qml" + default: + return "PerObjectItem.qml" + } + } + } + Component.onCompleted: settingPickDialog.updateFilter() } rightButtons: [ diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index afafa432b5..d4ed30dea6 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V. +// Copyright (c) 2022 Jaime van Kessel, Ultimaker B.V. // The PostProcessingPlugin is released under the terms of the AGPLv3 or higher. import QtQuick 2.2 @@ -8,7 +8,7 @@ import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.0 as Cura UM.Dialog @@ -34,7 +34,7 @@ UM.Dialog UM.I18nCatalog{id: catalog; name: "cura"} id: base property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width) - property int textMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) + property int textMargin: UM.Theme.getSize("narrow_margin").width property string activeScriptName SystemPalette{ id: palette } SystemPalette{ id: disabledPalette; colorGroup: SystemPalette.Disabled } @@ -44,19 +44,18 @@ UM.Dialog { id: selectedScriptGroup } - Item + Column { id: activeScripts - anchors.left: parent.left width: base.columnWidth height: parent.height + spacing: base.textMargin + Label { id: activeScriptsHeader text: catalog.i18nc("@label", "Post Processing Scripts") - anchors.top: parent.top - anchors.topMargin: base.textMargin anchors.left: parent.left anchors.leftMargin: base.textMargin anchors.right: parent.right @@ -67,22 +66,24 @@ UM.Dialog ListView { id: activeScriptsList - anchors { - top: activeScriptsHeader.bottom left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width right: parent.right rightMargin: base.textMargin - topMargin: base.textMargin - leftMargin: UM.Theme.getSize("default_margin").width } + height: Math.min(contentHeight, parent.height - parent.spacing * 2 - activeScriptsHeader.height - addButton.height) //At the window height, start scrolling this one. - height: childrenRect.height + clip: true + ScrollBar.vertical: UM.ScrollBar + { + id: activeScriptsScrollBar + } model: manager.scriptList delegate: Item { - width: parent.width + width: parent.width - activeScriptsScrollBar.width height: activeScriptButton.height Button { @@ -132,8 +133,7 @@ UM.Dialog text: "x" width: 20 * screenScaleFactor height: 20 * screenScaleFactor - anchors.right:parent.right - anchors.rightMargin: base.textMargin + anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter onClicked: manager.removeScriptByIndex(index) contentItem: Item @@ -221,8 +221,6 @@ UM.Dialog text: catalog.i18nc("@action", "Add a script") anchors.left: parent.left anchors.leftMargin: base.textMargin - anchors.top: activeScriptsList.bottom - anchors.topMargin: base.textMargin onClicked: scriptsMenu.open() } Menu @@ -275,9 +273,9 @@ UM.Dialog color: UM.Theme.getColor("text") } - ScrollView + ListView { - id: scrollView + id: listview anchors { top: scriptSpecsHeader.bottom @@ -288,123 +286,121 @@ UM.Dialog bottom: parent.bottom } + ScrollBar.vertical: UM.ScrollBar {} + clip: true visible: manager.selectedScriptDefinitionId != "" + spacing: UM.Theme.getSize("default_lining").height - ListView + model: UM.SettingDefinitionsModel { - id: listview - spacing: UM.Theme.getSize("default_lining").height - model: UM.SettingDefinitionsModel - { - id: definitionsModel - containerId: manager.selectedScriptDefinitionId - showAll: true - } + id: definitionsModel + containerId: manager.selectedScriptDefinitionId + showAll: true + } - delegate: Loader - { - id: settingLoader + delegate: Loader + { + id: settingLoader - width: parent.width - height: + width: listview.width + height: + { + if(provider.properties.enabled == "True") { - if(provider.properties.enabled == "True") + if(model.type != undefined) { - if(model.type != undefined) - { - return UM.Theme.getSize("section").height - } - else - { - return 0 - } + return UM.Theme.getSize("section").height } else { return 0 } } - Behavior on height { NumberAnimation { duration: 100 } } - opacity: provider.properties.enabled == "True" ? 1 : 0 - - Behavior on opacity { NumberAnimation { duration: 100 } } - enabled: opacity > 0 - - property var definition: model - property var settingDefinitionsModel: definitionsModel - property var propertyProvider: provider - property var globalPropertyProvider: inheritStackProvider - - //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 - //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, - //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. - asynchronous: model.type != "enum" && model.type != "extruder" - - onLoaded: + else { - settingLoader.item.showRevertButton = false - settingLoader.item.showInheritButton = false - settingLoader.item.showLinkedSettingIcon = false - settingLoader.item.doDepthIndentation = false - settingLoader.item.doQualityUserSettingEmphasis = false + return 0 + } + } + Behavior on height { NumberAnimation { duration: 100 } } + opacity: provider.properties.enabled == "True" ? 1 : 0 + + Behavior on opacity { NumberAnimation { duration: 100 } } + enabled: opacity > 0 + + property var definition: model + property var settingDefinitionsModel: definitionsModel + property var propertyProvider: provider + property var globalPropertyProvider: inheritStackProvider + + //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 + //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, + //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. + asynchronous: model.type != "enum" && model.type != "extruder" + + onLoaded: + { + settingLoader.item.showRevertButton = false + settingLoader.item.showInheritButton = false + settingLoader.item.showLinkedSettingIcon = false + settingLoader.item.doDepthIndentation = false + settingLoader.item.doQualityUserSettingEmphasis = false + } + + sourceComponent: + { + switch(model.type) + { + case "int": + return settingTextField + case "float": + return settingTextField + case "enum": + return settingComboBox + case "extruder": + return settingExtruder + case "bool": + return settingCheckBox + case "str": + return settingTextField + case "category": + return settingCategory + default: + return settingUnknown + } + } + + UM.SettingPropertyProvider + { + id: provider + containerStackId: manager.selectedScriptStackId + key: model.key ? model.key : "None" + watchedProperties: [ "value", "enabled", "state", "validationState" ] + storeIndex: 0 + } + + // Specialty provider that only watches global_inherits (we can't filter on what property changed we get events + // so we bypass that to make a dedicated provider). + UM.SettingPropertyProvider + { + id: inheritStackProvider + containerStack: Cura.MachineManager.activeMachine + key: model.key ? model.key : "None" + watchedProperties: [ "limit_to_extruder" ] + } + + Connections + { + target: item + + function onShowTooltip(text) + { + tooltip.text = text + var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0) + tooltip.show(position) + tooltip.target.x = position.x + 1 } - sourceComponent: - { - switch(model.type) - { - case "int": - return settingTextField - case "float": - return settingTextField - case "enum": - return settingComboBox - case "extruder": - return settingExtruder - case "bool": - return settingCheckBox - case "str": - return settingTextField - case "category": - return settingCategory - default: - return settingUnknown - } - } - - UM.SettingPropertyProvider - { - id: provider - containerStackId: manager.selectedScriptStackId - key: model.key ? model.key : "None" - watchedProperties: [ "value", "enabled", "state", "validationState" ] - storeIndex: 0 - } - - // Specialty provider that only watches global_inherits (we can't filter on what property changed we get events - // so we bypass that to make a dedicated provider). - UM.SettingPropertyProvider - { - id: inheritStackProvider - containerStack: Cura.MachineManager.activeMachine - key: model.key ? model.key : "None" - watchedProperties: [ "limit_to_extruder" ] - } - - Connections - { - target: item - - function onShowTooltip(text) - { - tooltip.text = text - var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0) - tooltip.show(position) - tooltip.target.x = position.x + 1 - } - - function onHideTooltip() { tooltip.hide() } - } + function onHideTooltip() { tooltip.hide() } } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index a690a1b2cb..30d3db0715 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -1,7 +1,7 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.5 as Cura import QtQuick 2.2 @@ -109,53 +109,51 @@ Cura.MachineAction width: Math.round(parent.width * 0.5) spacing: UM.Theme.getSize("default_margin").height - ScrollView + ListView { - id: objectListContainer + id: listview width: parent.width height: base.height - contentRow.y - discoveryTip.height - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - ListView - { - id: listview - model: manager.foundDevices - width: parent.width - currentIndex: -1 - onCurrentIndexChanged: - { - base.selectedDevice = listview.model[currentIndex]; - // Only allow connecting if the printer has responded to API query since the last refresh - base.completeProperties = base.selectedDevice != null && base.selectedDevice.getProperty("incomplete") != "true"; - } - Component.onCompleted: manager.startDiscovery() - delegate: Rectangle - { - height: printNameLabel.height - color: ListView.isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase - width: listview.width - Label - { - id: printNameLabel - height: contentHeight - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - text: listview.model[index].name - color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text - elide: Text.ElideRight - renderType: Text.NativeRendering - } - MouseArea + ScrollBar.vertical: UM.ScrollBar {} + clip: true + + model: manager.foundDevices + currentIndex: -1 + onCurrentIndexChanged: + { + base.selectedDevice = listview.model[currentIndex]; + // Only allow connecting if the printer has responded to API query since the last refresh + base.completeProperties = base.selectedDevice != null && base.selectedDevice.getProperty("incomplete") != "true"; + } + Component.onCompleted: manager.startDiscovery() + delegate: Rectangle + { + height: printNameLabel.height + color: ListView.isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase + width: listview.width + Label + { + id: printNameLabel + height: contentHeight + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.right: parent.right + text: listview.model[index].name + color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text + elide: Text.ElideRight + renderType: Text.NativeRendering + } + + MouseArea + { + anchors.fill: parent; + onClicked: { - anchors.fill: parent; - onClicked: + if(!parent.ListView.isCurrentItem) { - if(!parent.ListView.isCurrentItem) - { - parent.ListView.view.currentIndex = index; - } + parent.ListView.view.currentIndex = index; } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml index 44d8f80bb3..87b7cab83e 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -1,8 +1,8 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.15 import UM 1.5 as UM import Cura 1.0 as Cura @@ -22,7 +22,7 @@ Item id: queuedLabel anchors { - left: queuedPrintJobs.left + left: printJobList.left top: parent.top } font: UM.Theme.getFont("large") @@ -34,7 +34,7 @@ Item id: manageQueueLabel anchors { - right: queuedPrintJobs.right + right: printJobList.right verticalCenter: queuedLabel.verticalCenter } height: 18 * screenScaleFactor // TODO: Theme! @@ -78,7 +78,7 @@ Item id: printJobQueueHeadings anchors { - left: queuedPrintJobs.left + left: printJobList.left leftMargin: UM.Theme.getSize("narrow_margin").width top: queuedLabel.bottom topMargin: 24 * screenScaleFactor // TODO: Theme! @@ -121,41 +121,42 @@ Item } } - ScrollView + ListView { - id: queuedPrintJobs + id: printJobList anchors { bottom: parent.bottom horizontalCenter: parent.horizontalCenter top: printJobQueueHeadings.bottom - topMargin: 12 * screenScaleFactor // TODO: Theme! + topMargin: UM.Theme.getSize("default_margin").width } - style: UM.Theme.styles.scrollview width: parent.width - ListView + ScrollBar.vertical: UM.ScrollBar { - id: printJobList - anchors.fill: parent - delegate: MonitorPrintJobCard + id: printJobScrollBar + } + spacing: UM.Theme.getSize("narrow_margin").width + clip: true + + delegate: MonitorPrintJobCard + { + anchors { - anchors - { - left: parent.left - right: parent.right - } - printJob: modelData + left: parent.left + right: parent.right + rightMargin: printJobScrollBar.width } - model: + printJob: modelData + } + model: + { + if (OutputDevice.receivedData) { - if (OutputDevice.receivedData) - { - return OutputDevice.queuedPrintJobs - } - return [null, null] + return OutputDevice.queuedPrintJobs } - spacing: 6 // TODO: Theme! + return [null, null] } } } diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index 1936dc9047..e2a89ece59 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -5,7 +5,7 @@ import QtQuick 2.2 import QtQuick.Controls 2.9 import QtQuick.Window 2.1 -import UM 1.1 as UM +import UM 1.5 as UM UM.Dialog { @@ -89,81 +89,79 @@ UM.Dialog anchors.topMargin: UM.Theme.getSize("default_margin").height } - ScrollView + ListView { - id: credits + id: projectsList anchors.top: creditsNotes.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width height: base.height - y - (2 * UM.Theme.getSize("default_margin").height + closeButton.height) - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - ListView + + ScrollBar.vertical: UM.ScrollBar { - id: projectsList + id: projectsListScrollBar + } - width: parent.width + delegate: Row + { + spacing: UM.Theme.getSize("narrow_margin").width + Label + { + text: "%2".arg(model.url).arg(model.name) + width: (projectsList.width * 0.25) | 0 + elide: Text.ElideRight + onLinkActivated: Qt.openUrlExternally(link) + } + Label + { + text: model.description + elide: Text.ElideRight + width: ((projectsList.width * 0.6) | 0) - parent.spacing * 2 - projectsListScrollBar.width + } + Label + { + text: model.license + elide: Text.ElideRight + width: (projectsList.width * 0.15) | 0 + } + } + model: ListModel + { + id: projectsModel + } + Component.onCompleted: + { + projectsModel.append({ name: "Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" }); + projectsModel.append({ name: "Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" }); + projectsModel.append({ name: "CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" }); + projectsModel.append({ name: "libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" }); - delegate: Row - { - Label - { - text: "%2".arg(model.url).arg(model.name) - width: (projectsList.width * 0.25) | 0 - elide: Text.ElideRight - onLinkActivated: Qt.openUrlExternally(link) - } - Label - { - text: model.description - elide: Text.ElideRight - width: (projectsList.width * 0.6) | 0 - } - Label - { - text: model.license - elide: Text.ElideRight - width: (projectsList.width * 0.15) | 0 - } - } - model: ListModel - { - id: projectsModel - } - Component.onCompleted: - { - projectsModel.append({ name: "Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" }); - projectsModel.append({ name: "Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" }); - projectsModel.append({ name: "CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" }); - projectsModel.append({ name: "libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" }); - - projectsModel.append({ name: "Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" }); - projectsModel.append({ name: "Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" }); - projectsModel.append({ name: "PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" }); - projectsModel.append({ name: "SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" }); - projectsModel.append({ name: "Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" }); - projectsModel.append({ name: "SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" }); - projectsModel.append({ name: "NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" }); - projectsModel.append({ name: "NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" }); - projectsModel.append({ name: "Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" }); - projectsModel.append({ name: "libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" }); - projectsModel.append({ name: "libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" }); - projectsModel.append({ name: "PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" }); - projectsModel.append({ name: "python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" }); - projectsModel.append({ name: "Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" }); - projectsModel.append({ name: "Pyclipper", description: catalog.i18nc("@label", "Python bindings for Clipper"), license: "MIT", url: "https://github.com/fonttools/pyclipper" }); - projectsModel.append({ name: "mypy", description: catalog.i18nc("@Label", "Static type checker for Python"), license: "MIT", url: "http://mypy-lang.org/" }); - projectsModel.append({ name: "certifi", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "MPL", url: "https://github.com/certifi/python-certifi" }); - projectsModel.append({ name: "cryptography", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "APACHE and BSD", url: "https://cryptography.io/" }); - projectsModel.append({ name: "Sentry", description: catalog.i18nc("@Label", "Python Error tracking library"), license: "BSD 2-Clause 'Simplified'", url: "https://sentry.io/for/python/" }); - projectsModel.append({ name: "libnest2d", description: catalog.i18nc("@label", "Polygon packing library, developed by Prusa Research"), license: "LGPL", url: "https://github.com/tamasmeszaros/libnest2d" }); - projectsModel.append({ name: "pynest2d", description: catalog.i18nc("@label", "Python bindings for libnest2d"), license: "LGPL", url: "https://github.com/Ultimaker/pynest2d" }); - projectsModel.append({ name: "keyring", description: catalog.i18nc("@label", "Support library for system keyring access"), license: "MIT", url: "https://github.com/jaraco/keyring" }); - projectsModel.append({ name: "pywin32", description: catalog.i18nc("@label", "Python extensions for Microsoft Windows"), license: "PSF", url: "https://github.com/mhammond/pywin32" }); - projectsModel.append({ name: "Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" }); - projectsModel.append({ name: "Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" }); - projectsModel.append({ name: "AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" }); - } + projectsModel.append({ name: "Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" }); + projectsModel.append({ name: "Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" }); + projectsModel.append({ name: "PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" }); + projectsModel.append({ name: "SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" }); + projectsModel.append({ name: "Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" }); + projectsModel.append({ name: "SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" }); + projectsModel.append({ name: "NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" }); + projectsModel.append({ name: "NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" }); + projectsModel.append({ name: "Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" }); + projectsModel.append({ name: "libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" }); + projectsModel.append({ name: "libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" }); + projectsModel.append({ name: "PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" }); + projectsModel.append({ name: "python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" }); + projectsModel.append({ name: "Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" }); + projectsModel.append({ name: "Pyclipper", description: catalog.i18nc("@label", "Python bindings for Clipper"), license: "MIT", url: "https://github.com/fonttools/pyclipper" }); + projectsModel.append({ name: "mypy", description: catalog.i18nc("@Label", "Static type checker for Python"), license: "MIT", url: "http://mypy-lang.org/" }); + projectsModel.append({ name: "certifi", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "MPL", url: "https://github.com/certifi/python-certifi" }); + projectsModel.append({ name: "cryptography", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "APACHE and BSD", url: "https://cryptography.io/" }); + projectsModel.append({ name: "Sentry", description: catalog.i18nc("@Label", "Python Error tracking library"), license: "BSD 2-Clause 'Simplified'", url: "https://sentry.io/for/python/" }); + projectsModel.append({ name: "libnest2d", description: catalog.i18nc("@label", "Polygon packing library, developed by Prusa Research"), license: "LGPL", url: "https://github.com/tamasmeszaros/libnest2d" }); + projectsModel.append({ name: "pynest2d", description: catalog.i18nc("@label", "Python bindings for libnest2d"), license: "LGPL", url: "https://github.com/Ultimaker/pynest2d" }); + projectsModel.append({ name: "keyring", description: catalog.i18nc("@label", "Support library for system keyring access"), license: "MIT", url: "https://github.com/jaraco/keyring" }); + projectsModel.append({ name: "pywin32", description: catalog.i18nc("@label", "Python extensions for Microsoft Windows"), license: "PSF", url: "https://github.com/mhammond/pywin32" }); + projectsModel.append({ name: "Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" }); + projectsModel.append({ name: "Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" }); + projectsModel.append({ name: "AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" }); } } diff --git a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml index 0a9d317d2d..c6ee4f31e6 100644 --- a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml +++ b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml @@ -1,14 +1,15 @@ -// Copyright (c) 2020 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. +//Copyright (c) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. +import Qt.labs.qmlmodels 1.0 import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls 2.15 as NewControls +import QtQuick.Controls 1.1 as OldControls +import QtQuick.Controls 2.15 import QtQuick.Dialogs 1.2 import QtQuick.Window 2.1 import UM 1.2 as UM -import Cura 1.0 as Cura +import Cura 1.6 as Cura UM.Dialog { @@ -17,6 +18,8 @@ UM.Dialog minimumWidth: UM.Theme.getSize("popup_dialog").width minimumHeight: UM.Theme.getSize("popup_dialog").height + width: minimumWidth + height: minimumHeight property var changesModel: Cura.UserChangesModel{ id: userChangesModel} onVisibilityChanged: { @@ -68,72 +71,31 @@ UM.Dialog anchors.bottom: optionRow.top anchors.left: parent.left anchors.right: parent.right - TableView + + Cura.TableView { - anchors.fill: parent - height: base.height - 150 id: tableView - Component + anchors { - id: labelDelegate - Label - { - property var extruder_name: userChangesModel.getItem(styleData.row).extruder - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - elide: Text.ElideRight - font: UM.Theme.getFont("system") - text: - { - var result = styleData.value - if (extruder_name != "") - { - result += " (" + extruder_name + ")" - } - return result - } - } + top: parent.top + left: parent.left + right: parent.right } + height: base.height - 150 - Component + columnHeaders: [ + catalog.i18nc("@title:column", "Profile settings"), + Cura.MachineManager.activeQualityDisplayNameMap["main"], + catalog.i18nc("@title:column", "Current changes") + ] + model: TableModel { - id: defaultDelegate - Label - { - text: styleData.value - font: UM.Theme.getFont("system") - } + TableModelColumn { display: "label" } + TableModelColumn { display: "original_value" } + TableModelColumn { display: "user_value" } + rows: userChangesModel.items } - - TableViewColumn - { - role: "label" - title: catalog.i18nc("@title:column", "Profile settings") - delegate: labelDelegate - width: (tableView.width * 0.4) | 0 - } - TableViewColumn - { - role: "original_value" - title: Cura.MachineManager.activeQualityDisplayNameMap["main"] - width: (tableView.width * 0.3) | 0 - delegate: defaultDelegate - } - TableViewColumn - { - role: "user_value" - title: catalog.i18nc("@title:column", "Current changes") - width: (tableView.width * 0.3) | 0 - } - section.property: "category" - section.delegate: Label - { - text: section - font.bold: true - } - - model: userChangesModel + sectionRole: "category" } } @@ -146,7 +108,7 @@ UM.Dialog anchors.margins: UM.Theme.getSize("default_margin").width height: childrenRect.height - NewControls.ComboBox + ComboBox { id: discardOrKeepProfileChangesDropDownButton width: 300 @@ -193,7 +155,7 @@ UM.Dialog anchors.margins: UM.Theme.getSize("default_margin").width height: childrenRect.height - Button + OldControls.Button { id: discardButton text: catalog.i18nc("@action:button", "Discard changes"); @@ -206,7 +168,7 @@ UM.Dialog isDefault: true } - Button + OldControls.Button { id: keepButton text: catalog.i18nc("@action:button", "Keep changes"); diff --git a/resources/qml/Dialogs/WorkspaceSummaryDialog.qml b/resources/qml/Dialogs/WorkspaceSummaryDialog.qml index 1e03a35d0a..5278168a77 100644 --- a/resources/qml/Dialogs/WorkspaceSummaryDialog.qml +++ b/resources/qml/Dialogs/WorkspaceSummaryDialog.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -6,7 +6,7 @@ import QtQuick.Controls 2.9 import QtQuick.Layouts 1.3 import QtQuick.Window 2.2 -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.0 as Cura UM.Dialog @@ -81,6 +81,19 @@ UM.Dialog bottom: controls.top bottomMargin: UM.Theme.getSize("default_margin").height } + + ScrollBar.vertical: UM.ScrollBar + { + parent: scroll + anchors + { + top: parent.top + right: parent.right + bottom: parent.bottom + } + } + clip: true + ColumnLayout { spacing: UM.Theme.getSize("default_margin").height diff --git a/resources/qml/MachineSettings/GcodeTextArea.qml b/resources/qml/MachineSettings/GcodeTextArea.qml index f8bd02de3b..5292b4f83a 100644 --- a/resources/qml/MachineSettings/GcodeTextArea.qml +++ b/resources/qml/MachineSettings/GcodeTextArea.qml @@ -1,11 +1,11 @@ -// Copyright (c) 2020 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 -import UM 1.3 as UM +import UM 1.5 as UM import Cura 1.1 as Cura @@ -45,7 +45,7 @@ UM.TooltipArea renderType: Text.NativeRendering } - ScrollView + Flickable { anchors.top: titleLabel.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height @@ -53,26 +53,9 @@ UM.TooltipArea anchors.left: parent.left anchors.right: parent.right - background: Rectangle - { - color: UM.Theme.getColor("main_background") - anchors.fill: parent + ScrollBar.vertical: UM.ScrollBar {} - border.color: - { - if (!gcodeTextArea.enabled) - { - return UM.Theme.getColor("setting_control_disabled_border") - } - if (gcodeTextArea.hovered || gcodeTextArea.activeFocus) - { - return UM.Theme.getColor("setting_control_border_highlight") - } - return UM.Theme.getColor("setting_control_border") - } - } - - TextArea + TextArea.flickable: TextArea { id: gcodeTextArea @@ -92,6 +75,27 @@ UM.TooltipArea propertyProvider.setPropertyValue("value", text) } } + + background: Rectangle + { + color: UM.Theme.getColor("main_background") + anchors.fill: parent + anchors.margins: -border.width //Wrap the border around the parent. + + border.color: + { + if (!gcodeTextArea.enabled) + { + return UM.Theme.getColor("setting_control_disabled_border") + } + if (gcodeTextArea.hovered || gcodeTextArea.activeFocus) + { + return UM.Theme.getColor("setting_control_border_highlight") + } + return UM.Theme.getColor("setting_control_border") + } + border.width: UM.Theme.getSize("default_lining").width + } } } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index de70b0e0f4..1867ed6a4a 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -1,10 +1,10 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 2.3 -import UM 1.4 as UM +import UM 1.5 as UM import Cura 1.0 as Cura Item @@ -67,18 +67,14 @@ Item contentHeight: configurationList.height clip: true - ScrollBar.vertical.policy: (configurationList.height > maximumHeight) ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff //The AsNeeded policy also hides it when the cursor is away, and we don't want that. - ScrollBar.vertical.background: Rectangle - { - implicitWidth: UM.Theme.getSize("scrollbar").width - radius: width / 2 - color: UM.Theme.getColor("scrollbar_background") - } - ScrollBar.vertical.contentItem: Rectangle - { - implicitWidth: UM.Theme.getSize("scrollbar").width - radius: width / 2 - color: UM.Theme.getColor(parent.pressed ? "scrollbar_handle_down" : parent.hovered ? "scrollbar_handle_hover" : "scrollbar_handle") + ScrollBar.vertical: UM.ScrollBar { + parent: container + anchors + { + top: parent.top + right: parent.right + bottom: parent.bottom + } } ButtonGroup diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index bacee0bc24..4069341f25 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2019 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. +//Copyright (c) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.6 import QtQuick.Controls 2.0 @@ -92,6 +92,7 @@ Item model: extrudersModel delegate: UM.TabRowButton { + checked: model.index == 0 contentItem: Item { Cura.ExtruderIcon diff --git a/resources/qml/ObjectSelector.qml b/resources/qml/ObjectSelector.qml index 5f7de1f301..db68ff6c03 100644 --- a/resources/qml/ObjectSelector.qml +++ b/resources/qml/ObjectSelector.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -76,7 +76,7 @@ Item id: contents width: parent.width visible: objectSelector.opened - height: visible ? listView.height : 0 + height: visible ? listView.height + border.width * 2 : 0 color: UM.Theme.getColor("main_background") border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") @@ -99,23 +99,22 @@ Item ListView { id: listView - clip: true anchors { left: parent.left right: parent.right + top: parent.top margins: UM.Theme.getSize("default_lining").width } - - ScrollBar.vertical: ScrollBar - { - hoverEnabled: true - } - property real maximumHeight: UM.Theme.getSize("objects_menu_size").height - height: Math.min(contentHeight, maximumHeight) + ScrollBar.vertical: UM.ScrollBar + { + id: scrollBar + } + clip: true + model: Cura.ObjectsModel {} delegate: ObjectItemButton @@ -128,7 +127,7 @@ Item value: model.selected } text: model.name - width: listView.width + width: listView.width - scrollBar.width property bool outsideBuildArea: model.outside_build_area property int perObjectSettingsCount: model.per_object_settings_count property string meshType: model.mesh_type diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index c012acdd07..aed31b510b 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -2,12 +2,11 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 -import QtQuick.Controls 1.1 +import QtQuick.Controls 1.1 as OldControls +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.3 as NewControls - -import UM 1.1 as UM +import UM 1.5 as UM import Cura 1.1 as Cura UM.PreferencesPage @@ -133,10 +132,22 @@ UM.PreferencesPage width: parent.width height: parent.height + ScrollBar.vertical: UM.ScrollBar + { + id: preferencesScrollBar + parent: preferencesScrollView + anchors + { + top: parent.top + bottom: parent.bottom + right: parent.right + } + } + Column { UM.I18nCatalog{id: catalog; name: "cura"} - width: preferencesScrollView.viewport.width + width: preferencesScrollView.width - preferencesScrollBar.width Label { @@ -192,7 +203,7 @@ UM.PreferencesPage } } - NewControls.ComboBox + ComboBox { id: languageComboBox @@ -255,7 +266,7 @@ UM.PreferencesPage } } - NewControls.ComboBox + ComboBox { id: themeComboBox @@ -531,7 +542,7 @@ UM.PreferencesPage } } - NewControls.ComboBox + ComboBox { id: cameraComboBox @@ -688,7 +699,7 @@ UM.PreferencesPage text: catalog.i18nc("@window:text", "Default behavior when opening a project file: ") } - NewControls.ComboBox + ComboBox { id: choiceOnOpenProjectDropDownButton width: Math.round(250 * screenScaleFactor) @@ -755,7 +766,7 @@ UM.PreferencesPage text: catalog.i18nc("@window:text", "Default behavior for changed setting values when switching to a different profile: ") } - NewControls.ComboBox + ComboBox { id: choiceOnProfileOverrideDropDownButton width: Math.round(250 * screenScaleFactor) @@ -858,7 +869,7 @@ UM.PreferencesPage } } - ExclusiveGroup { id: curaUpdatesGroup } + OldControls.ExclusiveGroup { id: curaUpdatesGroup } UM.TooltipArea { width: childrenRect.width @@ -866,7 +877,7 @@ UM.PreferencesPage text: catalog.i18nc("@info:tooltip", "When checking for updates, only check for stable releases.") anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - RadioButton + OldControls.RadioButton { text: catalog.i18nc("@option:radio", "Stable releases only") exclusiveGroup: curaUpdatesGroup @@ -882,7 +893,7 @@ UM.PreferencesPage text: catalog.i18nc("@info:tooltip", "When checking for updates, check for both stable and for beta releases.") anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - RadioButton + OldControls.RadioButton { text: catalog.i18nc("@option:radio", "Stable and Beta releases") exclusiveGroup: curaUpdatesGroup diff --git a/resources/qml/Preferences/Materials/MaterialsPage.qml b/resources/qml/Preferences/Materials/MaterialsPage.qml index 6ec23f001f..549e0cc00d 100644 --- a/resources/qml/Preferences/Materials/MaterialsPage.qml +++ b/resources/qml/Preferences/Materials/MaterialsPage.qml @@ -1,12 +1,13 @@ -// Copyright (c) 2021 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.15 +import QtQuick.Controls 1.4 as OldControls import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.2 -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.5 as Cura Item @@ -102,7 +103,7 @@ Item height: childrenRect.height // Activate button - Button + OldControls.Button { id: activateMenuButton text: catalog.i18nc("@action:button", "Activate") @@ -120,7 +121,7 @@ Item } // Create button - Button + OldControls.Button { id: createMenuButton text: catalog.i18nc("@action:button", "Create") @@ -135,7 +136,7 @@ Item } // Duplicate button - Button + OldControls.Button { id: duplicateMenuButton text: catalog.i18nc("@action:button", "Duplicate"); @@ -150,7 +151,7 @@ Item } // Remove button - Button + OldControls.Button { id: removeMenuButton text: catalog.i18nc("@action:button", "Remove") @@ -165,7 +166,7 @@ Item } // Import button - Button + OldControls.Button { id: importMenuButton text: catalog.i18nc("@action:button", "Import") @@ -179,7 +180,7 @@ Item } // Export button - Button + OldControls.Button { id: exportMenuButton text: catalog.i18nc("@action:button", "Export") @@ -193,7 +194,7 @@ Item } //Sync button. - Button + OldControls.Button { id: syncMaterialsButton text: catalog.i18nc("@action:button Sending materials to printers", "Sync with Printers") @@ -207,7 +208,8 @@ Item } } - Item { + Item + { id: contentsItem anchors { @@ -271,22 +273,26 @@ Item bottom: parent.bottom left: parent.left } - - Rectangle - { - parent: viewport - anchors.fill: parent - color: palette.light - } - width: (parent.width * 0.4) | 0 - frameVisible: true - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + + clip: true + ScrollBar.vertical: UM.ScrollBar + { + id: materialScrollBar + parent: materialScrollView + anchors + { + top: parent.top + right: parent.right + bottom: parent.bottom + } + } + contentHeight: materialListView.height //For some reason, this is not determined automatically with this ScrollView. Very weird! MaterialsList { id: materialListView - width: materialScrollView.viewport.width + width: materialScrollView.width - materialScrollBar.width } } diff --git a/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml b/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml index 2d2918072a..cc2985a8a8 100644 --- a/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml +++ b/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml @@ -1,4 +1,4 @@ -//Copyright (c) 2021 Ultimaker B.V. +//Copyright (c) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.15 @@ -253,204 +253,202 @@ Window onClicked: Qt.openUrlExternally("https://support.ultimaker.com/hc/en-us/articles/360012019239?utm_source=cura&utm_medium=software&utm_campaign=sync-material-wizard-troubleshoot-cloud-printer") } } - ScrollView + ListView { - id: printerListScrollView + id: printerList width: parent.width Layout.preferredWidth: width Layout.fillHeight: true + clip: true - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - - ListView + ScrollBar.vertical: UM.ScrollBar { - id: printerList - width: parent.width - spacing: UM.Theme.getSize("default_margin").height + id: printerListScrollBar + } + spacing: UM.Theme.getSize("default_margin").height - model: cloudPrinterList - delegate: Rectangle + model: cloudPrinterList + delegate: Rectangle + { + id: delegateContainer + color: "transparent" + border.color: UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width + width: printerList.width - printerListScrollBar.width + height: UM.Theme.getSize("card").height + + property string syncStatus: { - id: delegateContainer - color: "transparent" - border.color: UM.Theme.getColor("lining") - border.width: UM.Theme.getSize("default_lining").width - width: printerListScrollView.width - height: UM.Theme.getSize("card").height - - property string syncStatus: + var printer_id = model.metadata["host_guid"] + if(syncModel.printerStatus[printer_id] === undefined) //No status information available. Could be added after we started syncing. { - var printer_id = model.metadata["host_guid"] - if(syncModel.printerStatus[printer_id] === undefined) //No status information available. Could be added after we started syncing. - { - return "idle"; - } - return syncModel.printerStatus[printer_id]; + return "idle"; + } + return syncModel.printerStatus[printer_id]; + } + + Cura.IconWithText + { + anchors + { + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: Math.round(parent.height - height) / 2 //Equal margin on the left as above and below. + right: parent.right + rightMargin: Math.round(parent.height - height) / 2 } - Cura.IconWithText - { - anchors - { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: Math.round(parent.height - height) / 2 //Equal margin on the left as above and below. - right: parent.right - rightMargin: Math.round(parent.height - height) / 2 - } + text: model.name + font: UM.Theme.getFont("medium") - text: model.name - font: UM.Theme.getFont("medium") - - source: UM.Theme.getIcon("Printer", "medium") - iconColor: UM.Theme.getColor("machine_selector_printer_icon") - iconSize: UM.Theme.getSize("machine_selector_icon").width - - //Printer status badge (always cloud, but whether it's online or offline). - UM.RecolorImage - { - width: UM.Theme.getSize("printer_status_icon").width - height: UM.Theme.getSize("printer_status_icon").height - anchors - { - bottom: parent.bottom - bottomMargin: -Math.round(height / 6) - left: parent.left - leftMargin: parent.iconSize - Math.round(width * 5 / 6) - } - - source: UM.Theme.getIcon("CloudBadge", "low") - color: UM.Theme.getColor("primary") - - //Make a themeable circle in the background so we can change it in other themes. - Rectangle - { - anchors.centerIn: parent - width: parent.width - 1.5 //1.5 pixels smaller (at least sqrt(2), regardless of pixel scale) so that the circle doesn't show up behind the icon due to anti-aliasing. - height: parent.height - 1.5 - radius: width / 2 - color: UM.Theme.getColor("connection_badge_background") - z: parent.z - 1 - } - } - } + source: UM.Theme.getIcon("Printer", "medium") + iconColor: UM.Theme.getColor("machine_selector_printer_icon") + iconSize: UM.Theme.getSize("machine_selector_icon").width + //Printer status badge (always cloud, but whether it's online or offline). UM.RecolorImage { - id: printerSpinner - width: UM.Theme.getSize("section_icon").width - height: width - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below. + width: UM.Theme.getSize("printer_status_icon").width + height: UM.Theme.getSize("printer_status_icon").height + anchors + { + bottom: parent.bottom + bottomMargin: -Math.round(height / 6) + left: parent.left + leftMargin: parent.iconSize - Math.round(width * 5 / 6) + } - visible: delegateContainer.syncStatus === "uploading" - source: UM.Theme.getIcon("ArrowDoubleCircleRight") + source: UM.Theme.getIcon("CloudBadge", "low") color: UM.Theme.getColor("primary") - RotationAnimator + //Make a themeable circle in the background so we can change it in other themes. + Rectangle { - target: printerSpinner - from: 0 - to: 360 - duration: 1000 - loops: Animation.Infinite - running: true + anchors.centerIn: parent + width: parent.width - 1.5 //1.5 pixels smaller (at least sqrt(2), regardless of pixel scale) so that the circle doesn't show up behind the icon due to anti-aliasing. + height: parent.height - 1.5 + radius: width / 2 + color: UM.Theme.getColor("connection_badge_background") + z: parent.z - 1 } } - UM.StatusIcon - { - width: UM.Theme.getSize("section_icon").width - height: width - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below. - - visible: delegateContainer.syncStatus === "failed" || delegateContainer.syncStatus === "success" - status: delegateContainer.syncStatus === "success" ? UM.StatusIcon.Status.POSITIVE : UM.StatusIcon.Status.ERROR - } } - footer: Item + UM.RecolorImage { - width: printerListScrollView.width - height: { - if(!visible) - { - return 0; - } - let h = UM.Theme.getSize("card").height + printerListTroubleshooting.height + UM.Theme.getSize("default_margin").height * 2; //1 margin between content and footer, 1 for troubleshooting link. - return h; - } - visible: includeOfflinePrinterList.count - cloudPrinterList.count > 0 && typeof syncModel !== "undefined" && syncModel.exportUploadStatus === "idle" - Rectangle + id: printerSpinner + width: UM.Theme.getSize("section_icon").width + height: width + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below. + + visible: delegateContainer.syncStatus === "uploading" + source: UM.Theme.getIcon("ArrowDoubleCircleRight") + color: UM.Theme.getColor("primary") + + RotationAnimator { - anchors.fill: parent - anchors.topMargin: UM.Theme.getSize("default_margin").height + target: printerSpinner + from: 0 + to: 360 + duration: 1000 + loops: Animation.Infinite + running: true + } + } + UM.StatusIcon + { + width: UM.Theme.getSize("section_icon").width + height: width + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below. - border.color: UM.Theme.getColor("lining") - border.width: UM.Theme.getSize("default_lining").width - color: "transparent" + visible: delegateContainer.syncStatus === "failed" || delegateContainer.syncStatus === "success" + status: delegateContainer.syncStatus === "success" ? UM.StatusIcon.Status.POSITIVE : UM.StatusIcon.Status.ERROR + } + } - Row + footer: Item + { + width: printerList.width - printerListScrollBar + height: { + if(!visible) + { + return 0; + } + let h = UM.Theme.getSize("card").height + printerListTroubleshooting.height + UM.Theme.getSize("default_margin").height * 2; //1 margin between content and footer, 1 for troubleshooting link. + return h; + } + visible: includeOfflinePrinterList.count - cloudPrinterList.count > 0 && typeof syncModel !== "undefined" && syncModel.exportUploadStatus === "idle" + Rectangle + { + anchors.fill: parent + anchors.topMargin: UM.Theme.getSize("default_margin").height + + border.color: UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width + color: "transparent" + + Row + { + anchors { - anchors + fill: parent + margins: Math.round(UM.Theme.getSize("card").height - UM.Theme.getSize("machine_selector_icon").width) / 2 //Same margin as in other cards. + } + spacing: UM.Theme.getSize("default_margin").width + + UM.StatusIcon + { + id: infoIcon + width: UM.Theme.getSize("section_icon").width + height: width + //Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings. + anchors.top: parent.top + anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2) + + status: UM.StatusIcon.Status.WARNING + } + + Column + { + //Fill the total width. Can't use layouts because we need the anchors for vertical alignment. + width: parent.width - infoIcon.width - refreshListButton.width - parent.spacing * 2 + + spacing: UM.Theme.getSize("default_margin").height + + UM.Label { - fill: parent - margins: Math.round(UM.Theme.getSize("card").height - UM.Theme.getSize("machine_selector_icon").width) / 2 //Same margin as in other cards. + id: printersMissingText + text: catalog.i18nc("@text Asking the user whether printers are missing in a list.", "Printers missing?") + + "\n" + + catalog.i18nc("@text", "Make sure all your printers are turned ON and connected to Digital Factory.") + font: UM.Theme.getFont("medium") + elide: Text.ElideRight } - spacing: UM.Theme.getSize("default_margin").width - - UM.StatusIcon + Cura.TertiaryButton { - id: infoIcon - width: UM.Theme.getSize("section_icon").width - height: width - //Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings. - anchors.top: parent.top - anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2) + id: printerListTroubleshooting + leftPadding: 0 //Want to visually align this to the text. - status: UM.StatusIcon.Status.WARNING + text: catalog.i18nc("@button", "Troubleshooting") + iconSource: UM.Theme.getIcon("LinkExternal") + onClicked: Qt.openUrlExternally("https://support.ultimaker.com/hc/en-us/articles/360012019239?utm_source=cura&utm_medium=software&utm_campaign=sync-material-wizard-troubleshoot-cloud-printer") } + } - Column - { - //Fill the total width. Can't use layouts because we need the anchors for vertical alignment. - width: parent.width - infoIcon.width - refreshListButton.width - parent.spacing * 2 + Cura.SecondaryButton + { + id: refreshListButton + //Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings. + anchors.top: parent.top + anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2) - spacing: UM.Theme.getSize("default_margin").height - - UM.Label - { - id: printersMissingText - text: catalog.i18nc("@text Asking the user whether printers are missing in a list.", "Printers missing?") - + "\n" - + catalog.i18nc("@text", "Make sure all your printers are turned ON and connected to Digital Factory.") - font: UM.Theme.getFont("medium") - elide: Text.ElideRight - } - Cura.TertiaryButton - { - id: printerListTroubleshooting - leftPadding: 0 //Want to visually align this to the text. - - text: catalog.i18nc("@button", "Troubleshooting") - iconSource: UM.Theme.getIcon("LinkExternal") - onClicked: Qt.openUrlExternally("https://support.ultimaker.com/hc/en-us/articles/360012019239?utm_source=cura&utm_medium=software&utm_campaign=sync-material-wizard-troubleshoot-cloud-printer") - } - } - - Cura.SecondaryButton - { - id: refreshListButton - //Fake anchor.verticalCenter: printersMissingText.verticalCenter, since we can't anchor to things that aren't siblings. - anchors.top: parent.top - anchors.topMargin: Math.round(printersMissingText.height / 2 - height / 2) - - text: catalog.i18nc("@button", "Refresh List") - iconSource: UM.Theme.getIcon("ArrowDoubleCircleRight") - onClicked: Cura.API.account.sync(true) - } + text: catalog.i18nc("@button", "Refresh List") + iconSource: UM.Theme.getIcon("ArrowDoubleCircleRight") + onClicked: Cura.API.account.sync(true) } } } diff --git a/resources/qml/Preferences/Materials/MaterialsView.qml b/resources/qml/Preferences/Materials/MaterialsView.qml index 2c68973e55..8de4d03241 100644 --- a/resources/qml/Preferences/Materials/MaterialsView.qml +++ b/resources/qml/Preferences/Materials/MaterialsView.qml @@ -1,16 +1,17 @@ -// Copyright (c) 2017 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.15 +import QtQuick.Controls 1.4 as OldControls import QtQuick.Dialogs 1.2 -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.0 as Cura import ".." // Access to ReadOnlyTextArea.qml -TabView +Item { id: base @@ -67,400 +68,419 @@ TabView } } - Tab + UM.TabRow { - title: catalog.i18nc("@title", "Information") - - anchors.margins: UM.Theme.getSize("default_margin").width - - ScrollView + id: pageSelectorTabRow + UM.TabRowButton { - id: scrollView - anchors.fill: parent - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - flickableItem.flickableDirection: Flickable.VerticalFlick - frameVisible: true - - property real columnWidth: (viewport.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0 - - Flow - { - id: containerGrid - - x: UM.Theme.getSize("default_margin").width - y: UM.Theme.getSize("default_lining").height - - width: base.width - property real rowHeight: brandTextField.height + UM.Theme.getSize("default_lining").height - - MessageDialog - { - id: confirmDiameterChangeDialog - - icon: StandardIcon.Question; - title: catalog.i18nc("@title:window", "Confirm Diameter Change") - text: catalog.i18nc("@label (%1 is a number)", "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?".arg(new_diameter_value)) - standardButtons: StandardButton.Yes | StandardButton.No - modality: Qt.ApplicationModal - - property var new_diameter_value: null; - property var old_diameter_value: null; - property var old_approximate_diameter_value: null; - - onYes: - { - base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString()); - base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value); - // CURA-6868 Make sure to update the extruder to user a diameter-compatible material. - Cura.MachineManager.updateMaterialWithVariant() - base.resetSelectedMaterial() - } - - onNo: - { - base.properties.diameter = old_diameter_value; - diameterSpinBox.value = Qt.binding(function() { return base.properties.diameter }) - } - - onRejected: no() - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") } - ReadOnlyTextField - { - id: displayNameTextField; - width: scrollView.columnWidth; - text: properties.name; - readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialDisplayName(properties.name, text) - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") } - ReadOnlyTextField - { - id: brandTextField; - width: scrollView.columnWidth; - text: properties.brand; - readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialBrand(properties.brand, text) - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") } - ReadOnlyTextField - { - id: materialTypeField; - width: scrollView.columnWidth; - text: properties.material; - readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialType(properties.material, text) - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") } - Row - { - width: scrollView.columnWidth - height: parent.rowHeight - spacing: Math.round(UM.Theme.getSize("default_margin").width / 2) - - // color indicator square - Rectangle - { - id: colorSelector - color: properties.color_code - - width: Math.round(colorLabel.height * 0.75) - height: Math.round(colorLabel.height * 0.75) - border.width: UM.Theme.getSize("default_lining").height - - anchors.verticalCenter: parent.verticalCenter - - // open the color selection dialog on click - MouseArea - { - anchors.fill: parent - onClicked: colorDialog.open() - enabled: base.editingEnabled - } - } - - // pretty color name text field - ReadOnlyTextField - { - id: colorLabel; - width: parent.width - colorSelector.width - parent.spacing - text: properties.color_name; - readOnly: !base.editingEnabled - onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text) - } - - // popup dialog to select a new color - // if successful it sets the properties.color_code value to the new color - ColorDialog - { - id: colorDialog - color: properties.color_code - onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color) - } - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } - - Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") } - ReadOnlySpinBox - { - id: densitySpinBox - width: scrollView.columnWidth - value: properties.density - decimals: 2 - suffix: " g/cm³" - stepSize: 0.01 - readOnly: !base.editingEnabled - - onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value) - onValueChanged: updateCostPerMeter() - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") } - ReadOnlySpinBox - { - id: diameterSpinBox - width: scrollView.columnWidth - value: properties.diameter - decimals: 2 - suffix: " mm" - stepSize: 0.01 - readOnly: !base.editingEnabled - - onEditingFinished: - { - // This does not use a SettingPropertyProvider, because we need to make the change to all containers - // which derive from the same base_file - var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter"); - var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); - var new_approximate_diameter = getApproximateDiameter(value); - if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter) - { - confirmDiameterChangeDialog.old_diameter_value = old_diameter; - confirmDiameterChangeDialog.new_diameter_value = value; - confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter; - - confirmDiameterChangeDialog.open() - } - else { - base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString()); - base.setMetaDataEntry("properties/diameter", properties.diameter, value); - } - } - onValueChanged: updateCostPerMeter() - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") } - SpinBox - { - id: spoolCostSpinBox - width: scrollView.columnWidth - value: base.getMaterialPreferenceValue(properties.guid, "spool_cost") - prefix: base.currency + " " - decimals: 2 - maximumValue: 100000000 - - onValueChanged: - { - base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value)) - updateCostPerMeter() - } - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") } - SpinBox - { - id: spoolWeightSpinBox - width: scrollView.columnWidth - value: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight")) - suffix: " g" - stepSize: 100 - decimals: 0 - maximumValue: 10000 - - onValueChanged: - { - base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value)) - updateCostPerMeter() - } - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") } - Label - { - width: scrollView.columnWidth - text: "~ %1 m".arg(Math.round(base.spoolLength)) - verticalAlignment: Qt.AlignVCenter - height: parent.rowHeight - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") } - Label - { - width: scrollView.columnWidth - text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency) - verticalAlignment: Qt.AlignVCenter - height: parent.rowHeight - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible } - Label - { - width: 2 * scrollView.columnWidth - verticalAlignment: Qt.AlignVCenter - text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames) - wrapMode: Text.WordWrap - visible: unlinkMaterialButton.visible - } - Button - { - id: unlinkMaterialButton - text: catalog.i18nc("@label", "Unlink Material") - visible: base.linkedMaterialNames != "" - onClicked: - { - Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode) - base.reevaluateLinkedMaterials = true - } - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } - - Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") } - - ReadOnlyTextArea - { - text: properties.description; - width: 2 * scrollView.columnWidth - wrapMode: Text.WordWrap - - readOnly: !base.editingEnabled; - - onEditingFinished: base.setMetaDataEntry("description", properties.description, text) - } - - Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") } - - ReadOnlyTextArea - { - text: properties.adhesion_info; - width: 2 * scrollView.columnWidth - wrapMode: Text.WordWrap - - readOnly: !base.editingEnabled; - - onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text) - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } - } - - function updateCostPerMeter() - { - base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value); - base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value); - } + text: catalog.i18nc("@title", "Information") + property string activeView: "information" //To determine which page gets displayed. + } + UM.TabRowButton + { + text: catalog.i18nc("@label", "Print settings") + property string activeView: "settings" } } - Tab + ScrollView { - title: catalog.i18nc("@label", "Print settings") + id: informationPage anchors { - leftMargin: UM.Theme.getSize("default_margin").width - topMargin: UM.Theme.getSize("default_margin").height - bottomMargin: UM.Theme.getSize("default_margin").height - rightMargin: 0 + top: pageSelectorTabRow.bottom + left: parent.left + right: parent.right + bottom: parent.bottom } - ScrollView + ScrollBar.vertical: UM.ScrollBar { - anchors.fill: parent; - - ListView + parent: informationPage + anchors { - model: UM.SettingDefinitionsModel + top: parent.top + right: parent.right + bottom: parent.bottom + } + } + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + clip: true + visible: pageSelectorTabRow.currentItem.activeView === "information" + + property real columnWidth: (width * 0.5 - UM.Theme.getSize("default_margin").width) | 0 + + Flow + { + id: containerGrid + + x: UM.Theme.getSize("default_margin").width + y: UM.Theme.getSize("default_lining").height + + width: base.width + property real rowHeight: brandTextField.height + UM.Theme.getSize("default_lining").height + + MessageDialog + { + id: confirmDiameterChangeDialog + + icon: StandardIcon.Question; + title: catalog.i18nc("@title:window", "Confirm Diameter Change") + text: catalog.i18nc("@label (%1 is a number)", "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?".arg(new_diameter_value)) + standardButtons: StandardButton.Yes | StandardButton.No + modality: Qt.ApplicationModal + + property var new_diameter_value: null; + property var old_diameter_value: null; + property var old_approximate_diameter_value: null; + + onYes: { - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } - expanded: ["*"] + base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString()); + base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value); + // CURA-6868 Make sure to update the extruder to user a diameter-compatible material. + Cura.MachineManager.updateMaterialWithVariant() + base.resetSelectedMaterial() } - delegate: UM.TooltipArea + onNo: { - width: childrenRect.width - height: childrenRect.height - text: model.description - Label - { - id: label - width: base.firstColumnWidth; - height: spinBox.height + UM.Theme.getSize("default_lining").height - text: model.label - elide: Text.ElideRight - verticalAlignment: Qt.AlignVCenter - } - ReadOnlySpinBox - { - id: spinBox - anchors.left: label.right - value: - { - // In case the setting is not in the material... - if (!isNaN(parseFloat(materialPropertyProvider.properties.value))) - { - return parseFloat(materialPropertyProvider.properties.value); - } - // ... we search in the variant, and if it is not there... - if (!isNaN(parseFloat(variantPropertyProvider.properties.value))) - { - return parseFloat(variantPropertyProvider.properties.value); - } - // ... then look in the definition container. - if (!isNaN(parseFloat(machinePropertyProvider.properties.value))) - { - return parseFloat(machinePropertyProvider.properties.value); - } - return 0; - } - width: base.secondColumnWidth - readOnly: !base.editingEnabled - suffix: " " + model.unit - maximumValue: 99999 - decimals: model.unit == "mm" ? 2 : 0 + base.properties.diameter = old_diameter_value; + diameterSpinBox.value = Qt.binding(function() { return base.properties.diameter }) + } - onEditingFinished: materialPropertyProvider.setPropertyValue("value", value) - } + onRejected: no() + } - UM.ContainerPropertyProvider + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") } + ReadOnlyTextField + { + id: displayNameTextField; + width: informationPage.columnWidth; + text: properties.name; + readOnly: !base.editingEnabled; + onEditingFinished: base.updateMaterialDisplayName(properties.name, text) + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") } + ReadOnlyTextField + { + id: brandTextField; + width: informationPage.columnWidth; + text: properties.brand; + readOnly: !base.editingEnabled; + onEditingFinished: base.updateMaterialBrand(properties.brand, text) + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") } + ReadOnlyTextField + { + id: materialTypeField; + width: informationPage.columnWidth; + text: properties.material; + readOnly: !base.editingEnabled; + onEditingFinished: base.updateMaterialType(properties.material, text) + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") } + Row + { + width: informationPage.columnWidth + height: parent.rowHeight + spacing: Math.round(UM.Theme.getSize("default_margin").width / 2) + + // color indicator square + Rectangle + { + id: colorSelector + color: properties.color_code + + width: Math.round(colorLabel.height * 0.75) + height: Math.round(colorLabel.height * 0.75) + border.width: UM.Theme.getSize("default_lining").height + + anchors.verticalCenter: parent.verticalCenter + + // open the color selection dialog on click + MouseArea { - id: materialPropertyProvider - containerId: base.containerId - watchedProperties: [ "value" ] - key: model.key - } - UM.ContainerPropertyProvider - { - id: variantPropertyProvider - containerId: Cura.MachineManager.activeStack.variant.id - watchedProperties: [ "value" ] - key: model.key - } - UM.ContainerPropertyProvider - { - id: machinePropertyProvider - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - watchedProperties: [ "value" ] - key: model.key + anchors.fill: parent + onClicked: colorDialog.open() + enabled: base.editingEnabled } } + + // pretty color name text field + ReadOnlyTextField + { + id: colorLabel; + width: parent.width - colorSelector.width - parent.spacing + text: properties.color_name; + readOnly: !base.editingEnabled + onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text) + } + + // popup dialog to select a new color + // if successful it sets the properties.color_code value to the new color + ColorDialog + { + id: colorDialog + color: properties.color_code + onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color) + } + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") } + ReadOnlySpinBox + { + id: densitySpinBox + width: informationPage.columnWidth + value: properties.density + decimals: 2 + suffix: " g/cm³" + stepSize: 0.01 + readOnly: !base.editingEnabled + + onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value) + onValueChanged: updateCostPerMeter() + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") } + ReadOnlySpinBox + { + id: diameterSpinBox + width: informationPage.columnWidth + value: properties.diameter + decimals: 2 + suffix: " mm" + stepSize: 0.01 + readOnly: !base.editingEnabled + + onEditingFinished: + { + // This does not use a SettingPropertyProvider, because we need to make the change to all containers + // which derive from the same base_file + var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter"); + var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); + var new_approximate_diameter = getApproximateDiameter(value); + if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter) + { + confirmDiameterChangeDialog.old_diameter_value = old_diameter; + confirmDiameterChangeDialog.new_diameter_value = value; + confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter; + + confirmDiameterChangeDialog.open() + } + else { + base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString()); + base.setMetaDataEntry("properties/diameter", properties.diameter, value); + } + } + onValueChanged: updateCostPerMeter() + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") } + OldControls.SpinBox + { + id: spoolCostSpinBox + width: informationPage.columnWidth + value: base.getMaterialPreferenceValue(properties.guid, "spool_cost") + prefix: base.currency + " " + decimals: 2 + maximumValue: 100000000 + + onValueChanged: + { + base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value)) + updateCostPerMeter() + } + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") } + OldControls.SpinBox + { + id: spoolWeightSpinBox + width: informationPage.columnWidth + value: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight")) + suffix: " g" + stepSize: 100 + decimals: 0 + maximumValue: 10000 + + onValueChanged: + { + base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value)) + updateCostPerMeter() + } + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") } + Label + { + width: informationPage.columnWidth + text: "~ %1 m".arg(Math.round(base.spoolLength)) + verticalAlignment: Qt.AlignVCenter + height: parent.rowHeight + } + + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") } + Label + { + width: informationPage.columnWidth + text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency) + verticalAlignment: Qt.AlignVCenter + height: parent.rowHeight + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible } + Label + { + width: 2 * informationPage.columnWidth + verticalAlignment: Qt.AlignVCenter + text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames) + wrapMode: Text.WordWrap + visible: unlinkMaterialButton.visible + } + OldControls.Button + { + id: unlinkMaterialButton + text: catalog.i18nc("@label", "Unlink Material") + visible: base.linkedMaterialNames != "" + onClicked: + { + Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode) + base.reevaluateLinkedMaterials = true + } + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") } + + ReadOnlyTextArea + { + text: properties.description; + width: 2 * informationPage.columnWidth + wrapMode: Text.WordWrap + + readOnly: !base.editingEnabled; + + onEditingFinished: base.setMetaDataEntry("description", properties.description, text) + } + + Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") } + + ReadOnlyTextArea + { + text: properties.adhesion_info; + width: 2 * informationPage.columnWidth + wrapMode: Text.WordWrap + + readOnly: !base.editingEnabled; + + onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text) + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + } + + function updateCostPerMeter() + { + base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value); + base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value); + } + } + + ListView + { + anchors + { + top: pageSelectorTabRow.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + + model: UM.SettingDefinitionsModel + { + containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" + visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } + expanded: ["*"] + } + ScrollBar.vertical: UM.ScrollBar {} + clip: true + visible: pageSelectorTabRow.currentItem.activeView === "settings" + + delegate: UM.TooltipArea + { + width: childrenRect.width + height: childrenRect.height + text: model.description + Label + { + id: label + width: base.firstColumnWidth; + height: spinBox.height + UM.Theme.getSize("default_lining").height + text: model.label + elide: Text.ElideRight + verticalAlignment: Qt.AlignVCenter + } + ReadOnlySpinBox + { + id: spinBox + anchors.left: label.right + value: + { + // In case the setting is not in the material... + if (!isNaN(parseFloat(materialPropertyProvider.properties.value))) + { + return parseFloat(materialPropertyProvider.properties.value); + } + // ... we search in the variant, and if it is not there... + if (!isNaN(parseFloat(variantPropertyProvider.properties.value))) + { + return parseFloat(variantPropertyProvider.properties.value); + } + // ... then look in the definition container. + if (!isNaN(parseFloat(machinePropertyProvider.properties.value))) + { + return parseFloat(machinePropertyProvider.properties.value); + } + return 0; + } + width: base.secondColumnWidth + readOnly: !base.editingEnabled + suffix: " " + model.unit + maximumValue: 99999 + decimals: model.unit == "mm" ? 2 : 0 + + onEditingFinished: materialPropertyProvider.setPropertyValue("value", value) + } + + UM.ContainerPropertyProvider + { + id: materialPropertyProvider + containerId: base.containerId + watchedProperties: [ "value" ] + key: model.key + } + UM.ContainerPropertyProvider + { + id: variantPropertyProvider + containerId: Cura.MachineManager.activeStack.variant.id + watchedProperties: [ "value" ] + key: model.key + } + UM.ContainerPropertyProvider + { + id: machinePropertyProvider + containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" + watchedProperties: [ "value" ] + key: model.key } } } diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml deleted file mode 100644 index 3c0c46ed72..0000000000 --- a/resources/qml/Preferences/ProfileTab.qml +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.4 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Tab -{ - id: base - - property int extruderPosition: -1 //Denotes the global stack. - property var qualityItem: null - - property bool isQualityItemCurrentlyActivated: - { - if (qualityItem == null) - { - return false; - } - return qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName; - } - - TableView - { - anchors.fill: parent - anchors.margins: UM.Theme.getSize("default_margin").width - id: profileSettingsView - - Component - { - id: itemDelegate - - UM.TooltipArea - { - property var setting: qualitySettings.getItem(styleData.row) - height: childrenRect.height - width: (parent != null) ? parent.width : 0 - text: - { - if (styleData.value === undefined) - { - return "" - } - return (styleData.value.substr(0,1) == "=") ? styleData.value : "" - } - - Label - { - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - text: - { - if (styleData.value === undefined) - { - return "" - } - return (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value - } - font.strikeout: styleData.column == 1 && setting.user_value != "" && base.isQualityItemCurrentlyActivated - font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && base.isQualityItemCurrentlyActivated) - opacity: font.strikeout ? 0.5 : 1 - color: styleData.textColor - elide: Text.ElideRight - } - } - } - - TableViewColumn - { - role: "label" - title: catalog.i18nc("@title:column", "Setting") - width: (parent.width * 0.4) | 0 - delegate: itemDelegate - } - TableViewColumn - { - role: "profile_value" - title: catalog.i18nc("@title:column", "Profile") - width: (parent.width * 0.18) | 0 - delegate: itemDelegate - } - TableViewColumn - { - role: "user_value" - title: catalog.i18nc("@title:column", "Current"); - visible: base.isQualityItemCurrentlyActivated - width: (parent.width * 0.18) | 0 - delegate: itemDelegate - } - TableViewColumn - { - role: "unit" - title: catalog.i18nc("@title:column", "Unit") - width: (parent.width * 0.14) | 0 - delegate: itemDelegate - } - - section.property: "category" - section.delegate: Label - { - text: section - font.bold: true - } - - model: Cura.QualitySettingsModel - { - id: qualitySettings - selectedPosition: base.extruderPosition - selectedQualityItem: base.qualityItem == null ? {} : base.qualityItem - } - - SystemPalette { id: palette } - } -} diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 9144d4dbe1..af81d97e6c 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -1,12 +1,13 @@ -// Copyright (c) 2019 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +//Copyright (c) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.15 +import QtQuick.Controls 1.4 as OldControls import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.2 -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.6 as Cura @@ -78,7 +79,7 @@ Item height: childrenRect.height // Activate button - Button + OldControls.Button { id: activateMenuButton text: catalog.i18nc("@action:button", "Activate") @@ -98,7 +99,7 @@ Item } // Create button - Button + OldControls.Button { id: createMenuButton text: catalog.i18nc("@label", "Create") @@ -115,7 +116,7 @@ Item } // Duplicate button - Button + OldControls.Button { id: duplicateMenuButton text: catalog.i18nc("@label", "Duplicate") @@ -132,7 +133,7 @@ Item } // Remove button - Button + OldControls.Button { id: removeMenuButton text: catalog.i18nc("@action:button", "Remove") @@ -146,7 +147,7 @@ Item } // Rename button - Button + OldControls.Button { id: renameMenuButton text: catalog.i18nc("@action:button", "Rename") @@ -161,7 +162,7 @@ Item } // Import button - Button + OldControls.Button { id: importMenuButton text: catalog.i18nc("@action:button", "Import") @@ -173,7 +174,7 @@ Item } // Export button - Button + OldControls.Button { id: exportMenuButton text: catalog.i18nc("@action:button", "Export") @@ -397,13 +398,13 @@ Item } visible: text != "" text: catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachine.name) - width: profileScrollView.width + width: profileBackground.width elide: Text.ElideRight } - ScrollView + Rectangle { - id: profileScrollView + id: profileBackground anchors { top: captionLabel.visible ? captionLabel.bottom : parent.top @@ -411,22 +412,20 @@ Item bottom: parent.bottom left: parent.left } + width: (parent.width * 0.4) | 0 - Rectangle - { - parent: viewport - anchors.fill: parent - color: palette.light - } - - width: true ? (parent.width * 0.4) | 0 : parent.width - frameVisible: true - clip: true + color: palette.light ListView { id: qualityListView + anchors.fill: parent + ScrollBar.vertical: UM.ScrollBar + { + id: profileScrollBar + } + clip: true model: base.qualityManagementModel Component.onCompleted: @@ -461,7 +460,7 @@ Item delegate: Rectangle { - width: profileScrollView.width + width: profileBackground.width - profileScrollBar.width height: childrenRect.height // Added this property to identify custom profiles in automated system tests (Squish) @@ -513,16 +512,24 @@ Item anchors { - left: profileScrollView.right + left: profileBackground.right leftMargin: UM.Theme.getSize("default_margin").width top: parent.top bottom: parent.bottom right: parent.right } - Item + Column { - anchors.fill: parent + id: detailsPanelHeaderColumn + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + + spacing: UM.Theme.getSize("default_margin").height visible: base.currentItem != null Item // Profile title Label @@ -546,16 +553,14 @@ Item Flow { id: currentSettingsActions + width: parent.width + visible: base.hasCurrentItem && base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName && base.currentItem.intent_category == Cura.MachineManager.activeIntentCategory - anchors.left: parent.left - anchors.right: parent.right - anchors.top: profileName.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height Button { text: catalog.i18nc("@action:button", "Update profile with current settings/overrides") - enabled: Cura.MachineManager.hasUserSettings && !base.currentItem.is_read_only + enabled: Cura.MachineManager.hasUserSettings && qualityListView.currentItem && !qualityListView.currentItem.is_read_only onClicked: Cura.ContainerManager.updateQualityChanges() } @@ -567,62 +572,57 @@ Item } } - Column + Label { - id: profileNotices - anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left - anchors.right: parent.right - spacing: UM.Theme.getSize("default_margin").height - - Label - { - id: defaultsMessage - visible: false - text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.") - wrapMode: Text.WordWrap - width: parent.width - } - Label - { - id: noCurrentSettingsMessage - visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings - text: catalog.i18nc("@action:label", "Your current settings match the selected profile.") - wrapMode: Text.WordWrap - width: parent.width - } + id: defaultsMessage + visible: false + text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.") + wrapMode: Text.WordWrap + width: parent.width + } + Label + { + id: noCurrentSettingsMessage + visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings + text: catalog.i18nc("@action:label", "Your current settings match the selected profile.") + wrapMode: Text.WordWrap + width: parent.width } - TabView + UM.TabRow { - anchors.left: parent.left - anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.right: parent.right - anchors.bottom: parent.bottom - - currentIndex: 0 - - ProfileTab + id: profileExtruderTabs + UM.TabRowButton //One extra tab for the global settings. { - title: catalog.i18nc("@title:tab", "Global Settings") - qualityItem: base.currentItem + text: catalog.i18nc("@title:tab", "Global Settings") } Repeater { model: base.extrudersModel - ProfileTab + UM.TabRowButton { - title: model.name - extruderPosition: model.index - qualityItem: base.currentItem + text: model.name } } } } + + Cura.ProfileOverview + { + anchors + { + top: detailsPanelHeaderColumn.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + + visible: detailsPanelHeaderColumn.visible + qualityItem: base.currentItem + extruderPosition: profileExtruderTabs.currentIndex - 1 + } } } } diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index d2fd5c7e94..dcd5c154d9 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -1,13 +1,11 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls 2.15 +import QtQuick.Controls 1.1 as OldControls -import QtQuick.Controls 2.3 as NewControls - -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.0 as Cura @@ -36,7 +34,7 @@ UM.PreferencesPage id: base; anchors.fill: parent; - CheckBox + OldControls.CheckBox { id: toggleVisibleSettings anchors @@ -98,7 +96,7 @@ UM.PreferencesPage onTextChanged: definitionsModel.filter = {"i18n_label|i18n_description": "*" + text} } - NewControls.ComboBox + ComboBox { id: visibilityPreset width: 150 * screenScaleFactor @@ -106,7 +104,7 @@ UM.PreferencesPage { top: parent.top right: parent.right - bottom: scrollView.top + bottom: settingsListView.top } model: settingVisibilityPresetsModel.items @@ -133,12 +131,9 @@ UM.PreferencesPage } } - ScrollView + ListView { - id: scrollView - - frameVisible: true - + id: settingsListView anchors { top: filter.bottom; @@ -147,42 +142,41 @@ UM.PreferencesPage right: parent.right; bottom: parent.bottom; } - ListView + + clip: true + ScrollBar.vertical: UM.ScrollBar {} + + model: UM.SettingDefinitionsModel { - id: settingsListView + id: definitionsModel + containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" + showAll: true + exclude: ["machine_settings", "command_line_settings"] + showAncestors: true + expanded: ["*"] + visibilityHandler: UM.SettingPreferenceVisibilityHandler {} + } - model: UM.SettingDefinitionsModel + delegate: Loader + { + id: loader + + width: settingsListView.width + height: model.type != undefined ? UM.Theme.getSize("section").height : 0 + + property var definition: model + property var settingDefinitionsModel: definitionsModel + + asynchronous: true + active: model.type != undefined + sourceComponent: { - id: definitionsModel - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - showAll: true - exclude: ["machine_settings", "command_line_settings"] - showAncestors: true - expanded: ["*"] - visibilityHandler: UM.SettingPreferenceVisibilityHandler {} - } - - delegate: Loader - { - id: loader - - width: settingsListView.width - height: model.type != undefined ? UM.Theme.getSize("section").height : 0 - - property var definition: model - property var settingDefinitionsModel: definitionsModel - - asynchronous: true - active: model.type != undefined - sourceComponent: + switch(model.type) { - switch(model.type) - { - case "category": - return settingVisibilityCategory - default: - return settingVisibilityItem - } + case "category": + return settingVisibilityCategory + default: + return settingVisibilityItem } } } diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 16356e2c69..2925a10f17 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. +//Copyright (c) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 import QtQuick.Controls 2.3 @@ -213,6 +213,7 @@ Item model: extrudersModel delegate: UM.TabRowButton { + checked: model.index == 0 contentItem: Item { Cura.ExtruderIcon diff --git a/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml b/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml index b03d9d4b54..d6901cfc7f 100644 --- a/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml +++ b/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -43,17 +43,29 @@ Popup // This repeater adds the intent labels ScrollView { + id: qualityListScrollView property real maximumHeight: screenScaleFactor * 400 contentHeight: dataColumn.height height: Math.min(contentHeight, maximumHeight) - clip: true + width: parent.width - ScrollBar.vertical.policy: height == maximumHeight ? ScrollBar.AlwaysOn: ScrollBar.AlwaysOff + clip: true + ScrollBar.vertical: UM.ScrollBar + { + id: qualityListScrollBar + parent: qualityListScrollView + anchors + { + top: parent.top + right: parent.right + bottom: parent.bottom + } + } Column { id: dataColumn - width: parent.width + width: qualityListScrollView.width - qualityListScrollBar.width Repeater { model: dataModel @@ -64,7 +76,7 @@ Popup property variant subItemModel: model.qualities height: childrenRect.height - width: popup.contentWidth + width: dataColumn.width UM.Label { @@ -137,7 +149,7 @@ Popup Item { height: childrenRect.height - width: popup.contentWidth + width: dataColumn.width UM.Label { diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 24732a31d4..4d23561bf0 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -1,9 +1,9 @@ -// Copyright (c) 2020 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 -import QtQuick.Controls 1.4 -import QtQuick.Controls 2.3 as Controls2 +import QtQuick.Controls 1.4 as OldControls +import QtQuick.Controls 2.3 import UM 1.5 as UM import Cura 1.0 as Cura @@ -73,7 +73,7 @@ Item } } - Controls2.ComboBox + ComboBox { id: supportExtruderCombobox @@ -200,7 +200,7 @@ Item } } - contentItem:UM.Label + contentItem: UM.Label { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -229,7 +229,7 @@ Item } } - popup: Controls2.Popup + popup: Popup { y: supportExtruderCombobox.height - UM.Theme.getSize("default_lining").height width: supportExtruderCombobox.width @@ -238,12 +238,12 @@ Item contentItem: ListView { - clip: true implicitHeight: contentHeight + + ScrollBar.vertical: UM.ScrollBar {} + clip: true model: supportExtruderCombobox.popup.visible ? supportExtruderCombobox.delegateModel : null currentIndex: supportExtruderCombobox.highlightedIndex - - Controls2.ScrollIndicator.vertical: Controls2.ScrollIndicator { } } background: Rectangle @@ -253,7 +253,7 @@ Item } } - delegate: Controls2.ItemDelegate + delegate: ItemDelegate { width: supportExtruderCombobox.width - 2 * UM.Theme.getSize("default_lining").width height: supportExtruderCombobox.height diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 0c2f80fb37..8bea52fab6 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -1,10 +1,10 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 2.3 -import UM 1.2 as UM +import UM 1.5 as UM import Cura 1.1 as Cura Cura.ExpandablePopup @@ -193,42 +193,27 @@ Cura.ExpandablePopup { id: popup width: UM.Theme.getSize("machine_selector_widget_content").width + height: Math.min(machineSelectorList.contentHeight + separator.height + buttonRow.height, UM.Theme.getSize("machine_selector_widget_content").height) //Maximum height is the theme entry. - ScrollView + MachineSelectorList { - id: scroll - width: parent.width - clip: true - leftPadding: UM.Theme.getSize("default_lining").width - rightPadding: UM.Theme.getSize("default_lining").width - - MachineSelectorList + id: machineSelectorList + anchors { - id: machineSelectorList - // Can't use parent.width since the parent is the flickable component and not the ScrollView - width: scroll.width - scroll.leftPadding - scroll.rightPadding - property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height - - // We use an extra property here, since we only want to to be informed about the content size changes. - onContentHeightChanged: - { - scroll.height = Math.min(contentHeight, maximumHeight) - popup.height = scroll.height + buttonRow.height - } - - Component.onCompleted: - { - scroll.height = Math.min(contentHeight, maximumHeight) - popup.height = scroll.height + buttonRow.height - } + left: parent.left + leftMargin: UM.Theme.getSize("default_lining").width + right: parent.right + rightMargin: UM.Theme.getSize("default_lining").width + top: parent.top + bottom: separator.top } + clip: true } Rectangle { id: separator - - anchors.top: scroll.bottom + anchors.bottom: buttonRow.top width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") @@ -238,8 +223,7 @@ Cura.ExpandablePopup { id: buttonRow - // The separator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar. - anchors.top: separator.top + anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter padding: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 10458ea4a4..ae2706f9ab 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -14,10 +14,15 @@ ListView section.property: "hasRemoteConnection" property real contentHeight: childrenRect.height + ScrollBar.vertical: UM.ScrollBar + { + id: scrollBar + } + section.delegate: UM.Label { text: section == "true" ? catalog.i18nc("@label", "Connected printers") : catalog.i18nc("@label", "Preset printers") - width: parent.width + width: parent.width - scrollBar.width height: UM.Theme.getSize("action_button").height leftPadding: UM.Theme.getSize("default_margin").width font: UM.Theme.getFont("medium") @@ -27,7 +32,7 @@ ListView delegate: MachineSelectorButton { text: model.name ? model.name : "" - width: listView.width + width: listView.width - scrollBar.width outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null checked: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.id == model.id : false diff --git a/resources/qml/ProfileOverview.qml b/resources/qml/ProfileOverview.qml new file mode 100644 index 0000000000..ebca4ff22e --- /dev/null +++ b/resources/qml/ProfileOverview.qml @@ -0,0 +1,42 @@ +//Copyright (c) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. + +import Qt.labs.qmlmodels 1.0 +import QtQuick 2.7 +import QtQuick.Controls 1.4 as OldControls +import QtQuick.Controls 2.15 + +import UM 1.5 as UM +import Cura 1.6 as Cura + +Cura.TableView +{ + id: profileOverview + + property var qualityItem //The quality profile to display here. + property int extruderPosition: -1 //The extruder to display. -1 denotes the global stack. + property bool isQualityItemCurrentlyActivated: qualityItem != null && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName + + Cura.QualitySettingsModel + { + id: qualitySettings + selectedPosition: profileOverview.extruderPosition + selectedQualityItem: profileOverview.qualityItem == null ? {} : profileOverview.qualityItem + } + + columnHeaders: [ + catalog.i18nc("@title:column", "Setting"), + catalog.i18nc("@title:column", "Profile"), + catalog.i18nc("@title:column", "Current"), + catalog.i18nc("@title:column Unit of measurement", "Unit") + ] + model: TableModel + { + TableModelColumn { display: "label" } + TableModelColumn { display: "profile_value" } + TableModelColumn { display: "user_value" } + TableModelColumn { display: "unit" } + rows: qualitySettings.items + } + sectionRole: "category" +} \ No newline at end of file diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index 071d9dbfe5..a7aaa99fb2 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -178,12 +178,12 @@ SettingItem contentItem: ListView { - clip: true implicitHeight: contentHeight + + ScrollBar.vertical: UM.ScrollBar {} + clip: true model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex - - ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index 19bca44460..1f4a021009 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -181,12 +181,12 @@ SettingItem contentItem: ListView { - clip: true implicitHeight: contentHeight + + ScrollBar.vertical: UM.ScrollBar {} + clip: true model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex - - ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle { diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 084d84e883..48c658e4e7 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -191,6 +191,7 @@ Item } clip: true cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item. + ScrollBar.vertical: UM.ScrollBar {} model: UM.SettingDefinitionsModel { diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index db495c3dc2..cd787a6fd6 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -1,67 +1,217 @@ -// Copyright (C) 2021 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. +//Copyright (C) 2022 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.10 -import QtQuick.Controls 1.4 as OldControls // TableView doesn't exist in the QtQuick Controls 2.x in 5.10, so use the old one -import QtQuick.Controls 2.3 -import QtQuick.Controls.Styles 1.4 +import Qt.labs.qmlmodels 1.0 +import QtQuick 2.15 +import QtQuick.Controls 2.15 import UM 1.5 as UM - -OldControls.TableView +/* + * A re-sizeable table of data. + * + * This table combines a list of headers with a TableView to show certain roles in a table. + * The columns of the table can be resized. + * When the table becomes too big, you can scroll through the table. When a column becomes too small, the contents of + * the table are elided. + * The table gets Cura's themeing. + */ +Item { - itemDelegate: Item - { - height: tableCellLabel.implicitHeight + id: tableBase - UM.Label + required property var columnHeaders //The text to show in the headers of each column. + property alias model: tableView.model //A TableModel to display in this table. To use a ListModel for the rows, use "rows: listModel.items" + property int currentRow: -1 //The selected row index. + property var onDoubleClicked: function(row) {} //Something to execute when double clicked. Accepts one argument: The index of the row that was clicked on. + property bool allowSelection: true //Whether to allow the user to select items. + property string sectionRole: "" + + Row + { + id: headerBar + Repeater { - id: tableCellLabel - color: styleData.selected ? UM.Theme.getColor("primary_button_text") : UM.Theme.getColor("text") - elide: Text.ElideRight - text: styleData.value - anchors.fill: parent - anchors.leftMargin: 10 * screenScaleFactor + id: headerRepeater + model: columnHeaders + Rectangle + { + width: Math.max(1, Math.round(tableBase.width / headerRepeater.count)) + height: UM.Theme.getSize("section").height + + color: UM.Theme.getColor("secondary") + + Label + { + id: contentText + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("narrow_margin").width + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("narrow_margin").width + + text: modelData + font: UM.Theme.getFont("medium_bold") + color: UM.Theme.getColor("text") + elide: Text.ElideRight + } + Rectangle //Resize handle. + { + anchors + { + right: parent.right + top: parent.top + bottom: parent.bottom + } + width: UM.Theme.getSize("thick_lining").width + + color: UM.Theme.getColor("thick_lining") + + MouseArea + { + anchors.fill: parent + + cursorShape: Qt.SizeHorCursor + drag + { + target: parent + axis: Drag.XAxis + } + onMouseXChanged: + { + if(drag.active) + { + let new_width = parent.parent.width + mouseX; + let sum_widths = mouseX; + for(let i = 0; i < headerBar.children.length; ++i) + { + sum_widths += headerBar.children[i].width; + } + if(sum_widths > tableBase.width) + { + new_width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view. + } + let width_fraction = new_width / tableBase.width; //Scale with the same fraction along with the total width, if the table is resized. + parent.parent.width = Qt.binding(function() { return tableBase.width * width_fraction }); + } + } + } + } + + onWidthChanged: + { + tableView.forceLayout(); //Rescale table cells underneath as well. + } + } } } - rowDelegate: Rectangle + TableView { - color: styleData.selected ? UM.Theme.getColor("primary_button") : UM.Theme.getColor("main_background") - height: UM.Theme.getSize("table_row").height + id: tableView + anchors + { + top: headerBar.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + + clip: true + ScrollBar.vertical: UM.ScrollBar {} + columnWidthProvider: function(column) + { + return headerBar.children[column].width; //Cells get the same width as their column header. + } + + delegate: Rectangle + { + implicitHeight: Math.max(1, cellContent.height) + + color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) + + Label + { + id: cellContent + width: parent.width + + text: display + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + TextMetrics + { + id: cellTextMetrics + text: cellContent.text + font: cellContent.font + elide: cellContent.elide + elideWidth: cellContent.width + } + UM.TooltipArea + { + anchors.fill: parent + + text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided. + onClicked: + { + if(tableBase.allowSelection) + { + tableBase.currentRow = row; //Select this row. + } + } + onDoubleClicked: + { + tableBase.onDoubleClicked(row); + } + } + } + + Connections + { + target: model + function onRowCountChanged() + { + tableView.contentY = 0; //When the number of rows is reduced, make sure to scroll back to the start. + } + } } - // Use the old styling technique since it's the only way to make the scrollbars themed in the TableView - style: TableViewStyle + Connections { - backgroundColor: UM.Theme.getColor("main_background") - - handle: Rectangle + target: model + function onRowsChanged() { - // Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars - implicitWidth: UM.Theme.getSize("scrollbar").width - implicitHeight: UM.Theme.getSize("scrollbar").width - radius: width / 2 - color: UM.Theme.getColor(styleData.pressed ? "scrollbar_handle_down" : (styleData.hovered ? "scrollbar_handle_hover" : "scrollbar_handle")) - } + let first_column = model.columns[0].display; + if(model.rows.length > 0 && model.rows[0][first_column].startsWith("")) //First item is already a section header. + { + return; //Assume we already added section headers. Prevent infinite recursion. + } + if(sectionRole === "" || model.rows.length == 0) //No section headers, or no items at all. + { + tableView.model.rows = model.rows; + return; + } - scrollBarBackground: Rectangle - { - // Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars - implicitWidth: UM.Theme.getSize("scrollbar").width - implicitHeight: UM.Theme.getSize("scrollbar").width - color: UM.Theme.getColor("main_background") + //Insert section headers in the rows. + let last_section = ""; + let new_rows = []; + for(let i = 0; i < model.rows.length; ++i) + { + let item_section = model.rows[i][sectionRole]; + if(item_section !== last_section) //Starting a new section. + { + let section_header = {}; + for(let key in model.rows[i]) + { + section_header[key] = (key === first_column) ? "" + item_section + "" : ""; //Put the section header in the first column. + } + new_rows.push(section_header); //Add a row representing a section header. + last_section = item_section; + } + new_rows.push(model.rows[i]); + } + tableView.model.rows = new_rows; } - - // The little rectangle between the vertical and horizontal scrollbars - corner: Rectangle - { - color: UM.Theme.getColor("main_background") - } - - // Override the control arrows - incrementControl: Item { } - decrementControl: Item { } } } \ No newline at end of file diff --git a/resources/qml/WelcomePages/AddCloudPrintersView.qml b/resources/qml/WelcomePages/AddCloudPrintersView.qml index e33d519f22..0b94d21fae 100644 --- a/resources/qml/WelcomePages/AddCloudPrintersView.qml +++ b/resources/qml/WelcomePages/AddCloudPrintersView.qml @@ -1,11 +1,11 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 -import UM 1.3 as UM +import UM 1.5 as UM import Cura 1.7 as Cura @@ -22,7 +22,7 @@ Item property bool searchingForCloudPrinters: true property var discoveredCloudPrintersModel: CuraApplication.getDiscoveredCloudPrintersModel() - // The area where either the discoveredCloudPrintersScrollView or the busyIndicator will be displayed + // The area where either the discoveredCloudPrintersList or the busyIndicator will be displayed Item { id: cloudPrintersContent @@ -126,14 +126,9 @@ Item // The scrollView that contains the list of newly discovered Ultimaker Cloud printers. Visible only when // there is at least a new cloud printer. - ScrollView + ListView { - id: discoveredCloudPrintersScrollView - width: parent.width - clip : true - ScrollBar.horizontal.policy: ScrollBar.AsNeeded - ScrollBar.vertical.policy: ScrollBar.AsNeeded - visible: discoveredCloudPrintersModel.count > 0 + id: discoveredCloudPrintersList anchors { top: cloudPrintersAddedTitle.bottom @@ -144,52 +139,47 @@ Item bottom: parent.bottom } - Column + ScrollBar.vertical: UM.ScrollBar {} + clip : true + visible: discoveredCloudPrintersModel.count > 0 + spacing: UM.Theme.getSize("wide_margin").height + + model: discoveredCloudPrintersModel + delegate: Item { - id: discoveredPrintersColumn - spacing: 2 * UM.Theme.getSize("default_margin").height + width: discoveredCloudPrintersList.width + height: contentColumn.height - Repeater + Column { - id: discoveredCloudPrintersRepeater - model: discoveredCloudPrintersModel - delegate: Item + id: contentColumn + Label { - width: discoveredCloudPrintersScrollView.width - height: contentColumn.height - - Column - { - id: contentColumn - Label - { - id: cloudPrinterNameLabel - leftPadding: UM.Theme.getSize("default_margin").width - text: model.name - font: UM.Theme.getFont("large_bold") - color: UM.Theme.getColor("text") - elide: Text.ElideRight - } - Label - { - id: cloudPrinterTypeLabel - leftPadding: 2 * UM.Theme.getSize("default_margin").width - topPadding: UM.Theme.getSize("thin_margin").height - text: {"Type: " + model.machine_type} - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text") - elide: Text.ElideRight - } - Label - { - id: cloudPrinterFirmwareVersionLabel - leftPadding: 2 * UM.Theme.getSize("default_margin").width - text: {"Firmware version: " + model.firmware_version} - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text") - elide: Text.ElideRight - } - } + id: cloudPrinterNameLabel + leftPadding: UM.Theme.getSize("default_margin").width + text: model.name ? model.name : "" + font: UM.Theme.getFont("large_bold") + color: UM.Theme.getColor("text") + elide: Text.ElideRight + } + Label + { + id: cloudPrinterTypeLabel + leftPadding: 2 * UM.Theme.getSize("default_margin").width + topPadding: UM.Theme.getSize("thin_margin").height + text: {"Type: " + model.machine_type} + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") + elide: Text.ElideRight + } + Label + { + id: cloudPrinterFirmwareVersionLabel + leftPadding: 2 * UM.Theme.getSize("default_margin").width + text: {"Firmware version: " + model.firmware_version} + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") + elide: Text.ElideRight } } } diff --git a/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml b/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml index e34452623d..d2d48267de 100644 --- a/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -74,118 +74,93 @@ Item Row { id: localPrinterSelectionItem - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top + anchors.fill: parent - // ScrollView + ListView for selecting a local printer to add - Cura.ScrollView + //Selecting a local printer to add from this list. + ListView { - id: scrollView - - height: childrenHeight + id: machineList width: Math.floor(parent.width * 0.48) + height: parent.height - ListView + clip: true + ScrollBar.vertical: UM.ScrollBar {} + + model: UM.DefinitionContainersModel { - id: machineList - - // CURA-6793 - // Enabling the buffer seems to cause the blank items issue. When buffer is enabled, if the ListView's - // individual item has a dynamic change on its visibility, the ListView doesn't redraw itself. - // The default value of cacheBuffer is platform-dependent, so we explicitly disable it here. - cacheBuffer: 0 - boundsBehavior: Flickable.StopAtBounds - flickDeceleration: 20000 // To prevent the flicking behavior. - model: UM.DefinitionContainersModel - { - id: machineDefinitionsModel - filter: { "visible": true } - sectionProperty: "manufacturer" - preferredSections: preferredCategories - } - - section.property: "section" - section.delegate: sectionHeader - delegate: machineButton + id: machineDefinitionsModel + filter: { "visible": true } + sectionProperty: "manufacturer" + preferredSections: preferredCategories } - Component + section.property: "section" + section.delegate: Button { - id: sectionHeader + id: button + width: machineList.width + height: UM.Theme.getSize("action_button").height + text: section - Button + property bool isActive: base.currentSection == section + + background: Rectangle { - id: button - width: ListView.view.width + anchors.fill: parent + color: isActive ? UM.Theme.getColor("setting_control_highlight") : "transparent" + } + + contentItem: Item + { + width: childrenRect.width height: UM.Theme.getSize("action_button").height - text: section - property bool isActive: base.currentSection == section - - background: Rectangle + UM.RecolorImage { - anchors.fill: parent - color: isActive ? UM.Theme.getColor("setting_control_highlight") : "transparent" + id: arrow + anchors.left: parent.left + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: height + color: UM.Theme.getColor("text") + source: base.currentSection == section ? UM.Theme.getIcon("ChevronSingleDown") : UM.Theme.getIcon("ChevronSingleRight") } - contentItem: Item + UM.Label { - width: childrenRect.width - height: UM.Theme.getSize("action_button").height - - UM.RecolorImage - { - id: arrow - anchors.left: parent.left - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height - color: UM.Theme.getColor("text") - source: base.currentSection == section ? UM.Theme.getIcon("ChevronSingleDown") : UM.Theme.getIcon("ChevronSingleRight") - } - - UM.Label - { - id: label - anchors.left: arrow.right - anchors.leftMargin: UM.Theme.getSize("default_margin").width - text: button.text - font: UM.Theme.getFont("default_bold") - } + id: label + anchors.left: arrow.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + text: button.text + font: UM.Theme.getFont("default_bold") } + } - onClicked: - { - base.currentSection = section - base.updateCurrentItemUponSectionChange() - } + onClicked: + { + base.currentSection = section + base.updateCurrentItemUponSectionChange() } } - Component + delegate: Cura.RadioButton { - id: machineButton - - Cura.RadioButton + id: radioButton + anchors { - id: radioButton - anchors - { - left: parent !== null ? parent.left: undefined - leftMargin: UM.Theme.getSize("standard_list_lineheight").width + left: parent !== null ? parent.left : undefined + leftMargin: UM.Theme.getSize("standard_list_lineheight").width - right: parent !== null ? parent.right: undefined - rightMargin: UM.Theme.getSize("default_margin").width - } - height: visible ? UM.Theme.getSize("standard_list_lineheight").height : 0 - - checked: ListView.view.currentIndex == index - text: name - visible: base.currentSection.toLowerCase() === section.toLowerCase() - onClicked: ListView.view.currentIndex = index + right: parent !== null ? parent.right : undefined + rightMargin: UM.Theme.getSize("default_margin").width } + height: visible ? UM.Theme.getSize("standard_list_lineheight").height : 0 //This causes the scrollbar to vary in length due to QTBUG-76830. + + checked: machineList.currentIndex == index + text: name + visible: base.currentSection.toLowerCase() === section.toLowerCase() + onClicked: machineList.currentIndex = index } } @@ -194,7 +169,7 @@ Item { id: verticalLine anchors.top: parent.top - height: childrenHeight - UM.Theme.getSize("default_lining").height + height: parent.height - UM.Theme.getSize("default_lining").height width: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") } diff --git a/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml b/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml index edf6fe5974..dbf68ce701 100644 --- a/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml +++ b/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -45,11 +45,9 @@ Item } contentComponent: networkPrinterListComponent - Component { id: networkPrinterListComponent - AddNetworkPrinterScrollView { id: networkPrinterScrollView @@ -95,20 +93,13 @@ Item } contentComponent: localPrinterListComponent - Component { id: localPrinterListComponent - AddLocalPrinterScrollView { id: localPrinterView - property int childrenHeight: backButton.y - addLocalPrinterDropDown.y - UM.Theme.getSize("expandable_component_content_header").height - UM.Theme.getSize("default_margin").height - - onChildrenHeightChanged: - { - addLocalPrinterDropDown.children[1].height = childrenHeight - } + height: backButton.y - addLocalPrinterDropDown.y - UM.Theme.getSize("expandable_component_content_header").height - UM.Theme.getSize("default_margin").height } } } diff --git a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml index 51f69dfa30..64f194dd56 100644 --- a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -17,7 +17,7 @@ Item id: base height: networkPrinterInfo.height + controlsRectangle.height - property alias maxItemCountAtOnce: networkPrinterScrollView.maxItemCountAtOnce + property alias maxItemCountAtOnce: networkPrinterListView.maxItemCountAtOnce property var currentItem: (networkPrinterListView.currentIndex >= 0) ? networkPrinterListView.model[networkPrinterListView.currentIndex] : null @@ -29,7 +29,7 @@ Item Item { id: networkPrinterInfo - height: networkPrinterScrollView.visible ? networkPrinterScrollView.height : noPrinterLabel.height + height: networkPrinterListView.visible ? networkPrinterListView.height : noPrinterLabel.height anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top @@ -44,104 +44,90 @@ Item visible: networkPrinterListView.count == 0 // Do not show if there are discovered devices. } - ScrollView + ListView { - id: networkPrinterScrollView + id: networkPrinterListView anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - - ScrollBar.horizontal.policy: ScrollBar.AsNeeded - ScrollBar.vertical.policy: ScrollBar.AsNeeded - - property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll. height: Math.min(contentHeight, (maxItemCountAtOnce * UM.Theme.getSize("action_button").height) - UM.Theme.getSize("default_margin").height) + ScrollBar.vertical: UM.ScrollBar + { + id: networkPrinterScrollBar + } + clip: true + property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll. visible: networkPrinterListView.count > 0 - clip: true + model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined + cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item. - ListView + section.property: "modelData.sectionName" + section.criteria: ViewSection.FullString + section.delegate: UM.Label { - id: networkPrinterListView - anchors.fill: parent - model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + width: parent.width - networkPrinterScrollBar.width - UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("setting_control").height + text: section + color: UM.Theme.getColor("small_button_text") + } - section.property: "modelData.sectionName" - section.criteria: ViewSection.FullString - section.delegate: sectionHeading - boundsBehavior: Flickable.StopAtBounds - flickDeceleration: 20000 // To prevent the flicking behavior. - cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item. - - Component.onCompleted: + Component.onCompleted: + { + var toSelectIndex = -1 + // Select the first one that's not "unknown" and is the host a group by default. + for (var i = 0; i < count; i++) { - var toSelectIndex = -1 - // Select the first one that's not "unknown" and is the host a group by default. - for (var i = 0; i < count; i++) + if (!model[i].isUnknownMachineType && model[i].isHostOfGroup) { - if (!model[i].isUnknownMachineType && model[i].isHostOfGroup) - { - toSelectIndex = i - break - } - } - currentIndex = toSelectIndex - } - - // CURA-6483 For some reason currentIndex can be reset to 0. This check is here to prevent automatically - // selecting an unknown or non-host printer. - onCurrentIndexChanged: - { - var item = model[currentIndex] - if (!item || item.isUnknownMachineType || !item.isHostOfGroup) - { - currentIndex = -1 + toSelectIndex = i + break } } + currentIndex = toSelectIndex + } - Component + // CURA-6483 For some reason currentIndex can be reset to 0. This check is here to prevent automatically + // selecting an unknown or non-host printer. + onCurrentIndexChanged: + { + var item = model[currentIndex] + if (!item || item.isUnknownMachineType || !item.isHostOfGroup) { - id: sectionHeading + currentIndex = -1 + } + } - UM.Label - { - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("setting_control").height - text: section - color: UM.Theme.getColor("small_button_text") - } + delegate: Cura.MachineSelectorButton + { + text: modelData.device.name + + width: networkPrinterListView.width - networkPrinterScrollBar.width + outputDevice: modelData.device + + enabled: !modelData.isUnknownMachineType && modelData.isHostOfGroup + + 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 } + + function updateMachineTypes() + { + printerTypesList = [ modelData.readableMachineType ] } - delegate: Cura.MachineSelectorButton + checkable: false + selected: networkPrinterListView.currentIndex == model.index + onClicked: { - text: modelData.device.name - - width: networkPrinterListView.width - outputDevice: modelData.device - - enabled: !modelData.isUnknownMachineType && modelData.isHostOfGroup - - 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 } - - function updateMachineTypes() - { - printerTypesList = [ modelData.readableMachineType ] - } - - checkable: false - selected: ListView.view.currentIndex == model.index - onClicked: - { - ListView.view.currentIndex = index - } + networkPrinterListView.currentIndex = index } } } diff --git a/resources/qml/WelcomePages/ChangelogContent.qml b/resources/qml/WelcomePages/ChangelogContent.qml index 6af6137887..7c3b1adfc3 100644 --- a/resources/qml/WelcomePages/ChangelogContent.qml +++ b/resources/qml/WelcomePages/ChangelogContent.qml @@ -37,8 +37,6 @@ Item anchors.left: parent.left anchors.right: parent.right - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - textArea.text: CuraApplication.getTextManager().getChangeLogText() textArea.textFormat: Text.RichText textArea.wrapMode: Text.WordWrap diff --git a/resources/qml/WelcomePages/DropDownWidget.qml b/resources/qml/WelcomePages/DropDownWidget.qml index 2639a8eb43..90e1900d35 100644 --- a/resources/qml/WelcomePages/DropDownWidget.qml +++ b/resources/qml/WelcomePages/DropDownWidget.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -61,7 +61,7 @@ Item anchors.left: header.left anchors.right: header.right // Add 2x lining, because it needs a bit of space on the top and the bottom. - height: contentLoader.item.height + 2 * UM.Theme.getSize("thick_lining").height + height: contentLoader.item ? contentLoader.item.height + 2 * UM.Theme.getSize("thick_lining").height : 0 border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") diff --git a/resources/qml/WelcomePages/WhatsNewContent.qml b/resources/qml/WelcomePages/WhatsNewContent.qml index 179fc372c9..c56f8880ed 100644 --- a/resources/qml/WelcomePages/WhatsNewContent.qml +++ b/resources/qml/WelcomePages/WhatsNewContent.qml @@ -113,8 +113,6 @@ Item right: subpageImage.right } - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - back_color: UM.Theme.getColor("viewport_overlay") do_borders: false diff --git a/resources/qml/Widgets/ComboBox.qml b/resources/qml/Widgets/ComboBox.qml index 1d6b26e2ce..b92daad9c4 100644 --- a/resources/qml/Widgets/ComboBox.qml +++ b/resources/qml/Widgets/ComboBox.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 @@ -100,12 +100,12 @@ ComboBox contentItem: ListView { - clip: true implicitHeight: contentHeight + + ScrollBar.vertical: UM.ScrollBar {} + clip: true model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex - - ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle diff --git a/resources/qml/Widgets/ScrollView.qml b/resources/qml/Widgets/ScrollView.qml deleted file mode 100644 index 9e7531994c..0000000000 --- a/resources/qml/Widgets/ScrollView.qml +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2020 Ultimaker B.V. -// Toolbox is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.10 -import QtQuick.Controls 2.3 - -import UM 1.1 as UM - -ScrollView -{ - clip: true - - // Setting this property to false hides the scrollbar both when the scrollbar is not needed (child height < height) - // and when the scrollbar is not actively being hovered or pressed - property bool scrollAlwaysVisible: true - - ScrollBar.vertical: ScrollBar - { - hoverEnabled: true - policy: parent.scrollAlwaysVisible ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded - anchors.top: parent.top - anchors.right: parent.right - anchors.bottom: parent.bottom - - contentItem: Rectangle - { - implicitWidth: UM.Theme.getSize("scrollbar").width - opacity: (parent.active || parent.parent.scrollAlwaysVisible) ? 1.0 : 0.0 - radius: Math.round(width / 2) - color: - { - if (parent.pressed) - { - return UM.Theme.getColor("scrollbar_handle_down") - } - else if (parent.hovered) - { - return UM.Theme.getColor("scrollbar_handle_hover") - } - return UM.Theme.getColor("scrollbar_handle") - } - Behavior on color { ColorAnimation { duration: 100; } } - Behavior on opacity { NumberAnimation { duration: 100 } } - } - } -} \ No newline at end of file diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml index 6becf75cb1..7d8f6b886d 100644 --- a/resources/qml/Widgets/ScrollableTextArea.qml +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -1,35 +1,39 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 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 UM 1.5 as UM import Cura 1.1 as Cura // // Cura-style TextArea with scrolls // -ScrollView +Flickable { - property alias textArea: _textArea - + id: scrollableTextAreaBase + property bool do_borders: true property var back_color: UM.Theme.getColor("main_background") - property var do_borders: true + property alias textArea: flickableTextArea - clip: true + ScrollBar.vertical: UM.ScrollBar {} - background: Rectangle // Border + TextArea.flickable: TextArea { - color: back_color - border.color: UM.Theme.getColor("thick_lining") - border.width: do_borders ? UM.Theme.getSize("default_lining").width : 0 - } + id: flickableTextArea + + background: Rectangle //Providing the background color and border. + { + anchors.fill: parent + anchors.margins: -border.width + + color: scrollableTextAreaBase.back_color + border.color: UM.Theme.getColor("thick_lining") + border.width: scrollableTextAreaBase.do_borders ? UM.Theme.getSize("default_lining").width : 0 + } - TextArea - { - id: _textArea font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") textFormat: TextEdit.PlainText @@ -37,4 +41,4 @@ ScrollView wrapMode: Text.Wrap selectByMouse: true } -} +} \ No newline at end of file diff --git a/resources/qml/qmldir b/resources/qml/qmldir index df2518c988..27f916ebde 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -4,6 +4,7 @@ MachineSelector 1.0 MachineSelector.qml MachineSelectorButton 1.0 MachineSelectorButton.qml CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml PrintSetupSelector 1.0 PrintSetupSelector.qml +ProfileOverview 1.6 ProfileOverview.qml ActionButton 1.0 ActionButton.qml MaterialMenu 1.0 MaterialMenu.qml NozzleMenu 1.0 NozzleMenu.qml