From 70a79c9b5cbea48327ce34fb76f7eec7d803bd1c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Jan 2022 16:36:46 +0100 Subject: [PATCH 01/64] Use custom scroll bar for settings list This is necessary to get the same design working in Controls 2. Contributes to issue CURA-8686. --- resources/qml/Settings/SettingView.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 { From 10303c10f9c0419df13bd6e26e166eb3e8334c2c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Jan 2022 17:15:23 +0100 Subject: [PATCH 02/64] Use new ScrollBar with controls 2 Contributes to issue CURA-8686. --- .../src/qml/components/BackupList.qml | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) 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 } } } From 7bda1336da7a33a9ce86f852165582c9208919f2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Jan 2022 17:54:13 +0100 Subject: [PATCH 03/64] Use new scrollbar with QtControls 2 scroll view A bit confusing that you have to set the parent and position manually, but okay. Contributes to issue CURA-8686. --- resources/qml/Widgets/ScrollableTextArea.qml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml index 6becf75cb1..b9ccc4271b 100644 --- a/resources/qml/Widgets/ScrollableTextArea.qml +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -1,10 +1,10 @@ -// 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 @@ -13,12 +13,26 @@ import Cura 1.1 as Cura // ScrollView { + id: scrollableTextAreaBase property alias textArea: _textArea property var back_color: UM.Theme.getColor("main_background") property var do_borders: true clip: true + ScrollBar.vertical: UM.ScrollBar + { + parent: scrollableTextAreaBase + anchors + { + right: parent.right + rightMargin: parent.background.border.width + top: parent.top + topMargin: rightMargin + bottom: parent.bottom + bottomMargin: rightMargin + } + } background: Rectangle // Border { From 7f0af55d1d5d6987a36ac4fdbe520759c9eb1e4d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Jan 2022 17:59:45 +0100 Subject: [PATCH 04/64] Fix top and bottom margins These were undefined properties otherwise. Contributes to issue CURA-8686. --- resources/qml/Widgets/ScrollableTextArea.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml index b9ccc4271b..adf81628eb 100644 --- a/resources/qml/Widgets/ScrollableTextArea.qml +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -28,9 +28,9 @@ ScrollView right: parent.right rightMargin: parent.background.border.width top: parent.top - topMargin: rightMargin + topMargin: anchors.rightMargin bottom: parent.bottom - bottomMargin: rightMargin + bottomMargin: anchors.rightMargin } } From d4381a6dd0e21bd80e884eea27066ec0f7a46c0f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Jan 2022 19:21:14 +0100 Subject: [PATCH 05/64] Get rid of double scrollbar due to flickable in scrollview The tutorials say it should work, but it doesn't. Now we make the whole thing a flickable with an attached textarea property, which does seem to work. Contributes to issue CURA-8686. --- resources/qml/Widgets/ScrollableTextArea.qml | 51 ++++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml index adf81628eb..c0801651ea 100644 --- a/resources/qml/Widgets/ScrollableTextArea.qml +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -11,39 +11,38 @@ import Cura 1.1 as Cura // // Cura-style TextArea with scrolls // -ScrollView +Flickable { id: scrollableTextAreaBase - property alias textArea: _textArea - + 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 + ScrollBar.vertical: UM.ScrollBar {} + + TextArea.flickable: TextArea { - parent: scrollableTextAreaBase - anchors + id: flickableTextArea + + background: Rectangle //Providing the background color and border. { - right: parent.right - rightMargin: parent.background.border.width - top: parent.top - topMargin: anchors.rightMargin - bottom: parent.bottom - bottomMargin: anchors.rightMargin + anchors + { + top: parent.top + topMargin: -border.width + bottom: parent.bottom + bottomMargin: -border.width + left: parent.left + leftMargin: -border.width + right: parent.right + rightMargin: -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 } - } - background: Rectangle // Border - { - color: back_color - border.color: UM.Theme.getColor("thick_lining") - border.width: 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 @@ -51,4 +50,4 @@ ScrollView wrapMode: Text.Wrap selectByMouse: true } -} +} \ No newline at end of file From f630b847886f60fffca4fe5c73c9927839f0da9d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 14:45:43 +0100 Subject: [PATCH 06/64] Replace ScrollView with QtControls2 ListView I can't update the buttons (not part of this ticket) so I kept those Controls1. The ScrollView is no longer necessary, just a ListView now with customised scroll bar. Contributes to issue CURA-8686. --- .../PerObjectSettingsPanel.qml | 321 +++++++++--------- 1 file changed, 160 insertions(+), 161 deletions(-) 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 } } } From 954a3cb1db5c61ff5688286ee128bcb6f8fa8fea Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 14:54:36 +0100 Subject: [PATCH 07/64] Replace ScrollView by ListView in settings picking dialogue The ScrollView is no longer necessary in Controls2. Just have a ListView with customised scrollbar. Contributes to issue CURA-8686. --- .../SettingPickDialog.qml | 90 ++++++++++--------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/plugins/PerObjectSettingsTool/SettingPickDialog.qml b/plugins/PerObjectSettingsTool/SettingPickDialog.qml index 18f36b2651..8ea1a774a4 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 - { - id: scrollView - + ListView + { + 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: [ From ca3f29daf72fb35afa500961b4cb4155251afa93 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 15:14:29 +0100 Subject: [PATCH 08/64] Use ListView for settings list in post-processing scripts With the customised scroll bar. Contributes to issue CURA-8686. --- .../PostProcessingPlugin.qml | 208 +++++++++--------- 1 file changed, 103 insertions(+), 105 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index afafa432b5..489254e310 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 @@ -275,9 +275,9 @@ UM.Dialog color: UM.Theme.getColor("text") } - ScrollView + ListView { - id: scrollView + id: listview anchors { top: scriptSpecsHeader.bottom @@ -288,123 +288,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() } } } } From d87551ac9cd82f910f993cd52ceb4fabcef4f783 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 17:01:16 +0100 Subject: [PATCH 09/64] Use Controls2 ListView instead of Controls1 ScrollView to scroll Just a listview with a specialised scroll bar. Contributes to issue CURA-8686. --- .../resources/qml/DiscoverUM3Action.qml | 82 +++++++++---------- 1 file changed, 40 insertions(+), 42 deletions(-) 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; } } } From 85d0749f5f77e280b0ecaeac5bf2f8eff03c1a8c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 17:27:51 +0100 Subject: [PATCH 10/64] Use Controls2 ListView instead of ScrollView for print job list No need for a ScrollView in Controls 2. And specialise the scroll bar. Be sure to also align the right side of the contents with the scroll bar though. Contributes to issue CURA-8686. --- .../resources/qml/MonitorQueue.qml | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) 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] } } } From c605b45b7c4c54ca7450aa8a77c7cb4dd19f33ac Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 17:51:37 +0100 Subject: [PATCH 11/64] Use styled scroll bar, and no ScrollView Make sure the text aligns next to the scrollbar instead of behind it, too. Contributes to issue CURA-8686. --- resources/qml/Dialogs/AboutDialog.qml | 134 +++++++++++++------------- 1 file changed, 66 insertions(+), 68 deletions(-) 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" }); } } From 1cc3aecd8cf60c957071fd1dca61d4df3a4465c4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 17:56:31 +0100 Subject: [PATCH 12/64] Use correct scrollbar and clip contents We've not been clipping this for so long, but the text really does overlap with the label and the buttons if we don't (and the text is sufficiently large). Contributes to issue CURA-8686. --- .../qml/Dialogs/WorkspaceSummaryDialog.qml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 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 From ae81b5e3e70603b72a0a95efc969614cea63da13 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 18:13:13 +0100 Subject: [PATCH 13/64] Fix flickable with custom scrollbar A bit of a hassle with the scrollbar overlapping the background here. Contributes to issue CURA-8686. --- .../qml/MachineSettings/GcodeTextArea.qml | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) 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 + } } } } From 7a1578cbc4858da485a52de7c4173792867de2cb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 18:22:49 +0100 Subject: [PATCH 14/64] Re-use component scrollbar from Uranium It's a new component so that we don't have to re-implement it everywhere. In this case we do have to anchor it correctly though because ScrollView doesn't do that by itself. Contributes to issue CURA-8686. --- .../ConfigurationListView.qml | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) 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 From 4614b3a9e1a2daf54d2eea77389b3b65a364db9d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 18:37:34 +0100 Subject: [PATCH 15/64] Use new ListView instead of ScrollView, with correct scrollbar I also fixed an undefined reference for whether a button needed to be enabled, if no profile was selected yet. The button was invisible if it was undefined, but it was still giving QML warnings. Contributes to issue CURA-8686. --- resources/qml/Preferences/ProfilesPage.qml | 53 +++++++++++----------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 9144d4dbe1..72bd2df00f 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -1,12 +1,13 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2022 Ultimaker B.V. // Uranium 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,7 +512,7 @@ Item anchors { - left: profileScrollView.right + left: profileBackground.right leftMargin: UM.Theme.getSize("default_margin").width top: parent.top bottom: parent.bottom @@ -555,7 +554,7 @@ Item 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() } @@ -594,7 +593,7 @@ Item } } - TabView + OldControls.TabView { anchors.left: parent.left anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top From bb32f25b496d2b1eeefcefd89dedfc060fbda8f3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 18:43:27 +0100 Subject: [PATCH 16/64] Replace old ScrollView with new ListView I also swapped out the old NewControls import to just be the actual Controls, and used OldControls to import the Controls1 module. This is consistent with the rest of the code base as far as I could find. Contributes to issue CURA-8686. --- .../qml/Preferences/SettingVisibilityPage.qml | 86 +++++++++---------- 1 file changed, 40 insertions(+), 46 deletions(-) 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 } } } From 52f5b91621968b9056ebd2f4317557796e2d7483 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 19:01:22 +0100 Subject: [PATCH 17/64] Upgrade material list ScrollView to Controls2 Took some effort. This was a weird one. I had to manually set the contentHeight to the height of the contents. Perhaps the ScrollBar itself was messing with it? Contributes to issue CURA-8686. --- .../Preferences/Materials/MaterialsPage.qml | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) 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 } } From 4d9039288b6a4aa7f1625b6afaac62a4b9a6e35c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Jan 2022 19:10:06 +0100 Subject: [PATCH 18/64] Use new ScrollBar for material sync dialogue Contributes to issue CURA-8686. --- .../Materials/MaterialsSyncDialog.qml | 326 +++++++++--------- 1 file changed, 162 insertions(+), 164 deletions(-) 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) } } } From 509c9068eb05677ad01f569554d9f17d1d78eccf Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 13:48:21 +0100 Subject: [PATCH 19/64] Convert all ScrollViews to Controls2 This was a bit of a doozy. One was really simple but the other one had me stumped for a while: The Controls2 version doesn't have the viewport property any more, so just use the width. Contributes to issue CURA-8686. --- .../Preferences/Materials/MaterialsView.qml | 184 +++++++++--------- 1 file changed, 97 insertions(+), 87 deletions(-) diff --git a/resources/qml/Preferences/Materials/MaterialsView.qml b/resources/qml/Preferences/Materials/MaterialsView.qml index 2c68973e55..daa47f33e9 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 +OldControls.TabView { id: base @@ -67,7 +68,7 @@ TabView } } - Tab + OldControls.Tab { title: catalog.i18nc("@title", "Information") @@ -77,11 +78,21 @@ TabView { 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 + ScrollBar.vertical: UM.ScrollBar + { + parent: scrollView + anchors + { + top: parent.top + right: parent.right + bottom: parent.bottom + } + } + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + clip: true + + property real columnWidth: (scrollView.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0 Flow { @@ -257,7 +268,7 @@ TabView } Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") } - SpinBox + OldControls.SpinBox { id: spoolCostSpinBox width: scrollView.columnWidth @@ -274,7 +285,7 @@ TabView } Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") } - SpinBox + OldControls.SpinBox { id: spoolWeightSpinBox width: scrollView.columnWidth @@ -318,7 +329,7 @@ TabView wrapMode: Text.WordWrap visible: unlinkMaterialButton.visible } - Button + OldControls.Button { id: unlinkMaterialButton text: catalog.i18nc("@label", "Unlink Material") @@ -369,7 +380,7 @@ TabView } } - Tab + OldControls.Tab { title: catalog.i18nc("@label", "Print settings") anchors @@ -380,86 +391,85 @@ TabView rightMargin: 0 } - ScrollView + ListView { - anchors.fill: parent; - - ListView + anchors.fill: parent + model: UM.SettingDefinitionsModel { - model: UM.SettingDefinitionsModel + containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" + visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } + expanded: ["*"] + } + + ScrollBar.vertical: UM.ScrollBar {} + clip: true + + delegate: UM.TooltipArea + { + width: childrenRect.width + height: childrenRect.height + text: model.description + Label { - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } - expanded: ["*"] + 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) } - delegate: UM.TooltipArea + UM.ContainerPropertyProvider { - 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 - } + 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 } } } From 7e1b92953c0401403b49d99126641d887a7814f9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 14:14:03 +0100 Subject: [PATCH 20/64] Update ScrollView to Controls 2 and customise with scrollbar Contributes to issue CURA-8686. --- resources/qml/Preferences/GeneralPage.qml | 37 +++++++++++++++-------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 7b025f889d..d92d237bcf 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 { @@ -188,7 +199,7 @@ UM.PreferencesPage } } - NewControls.ComboBox + ComboBox { id: languageComboBox @@ -242,7 +253,7 @@ UM.PreferencesPage } } - NewControls.ComboBox + ComboBox { id: themeComboBox @@ -518,7 +529,7 @@ UM.PreferencesPage } } - NewControls.ComboBox + ComboBox { id: cameraComboBox @@ -675,7 +686,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) @@ -742,7 +753,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) @@ -845,7 +856,7 @@ UM.PreferencesPage } } - ExclusiveGroup { id: curaUpdatesGroup } + OldControls.ExclusiveGroup { id: curaUpdatesGroup } UM.TooltipArea { width: childrenRect.width @@ -853,7 +864,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 @@ -869,7 +880,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 From c57126fb00899de4274e68d3f1125fda1237780f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 14:32:12 +0100 Subject: [PATCH 21/64] Use re-useable scrollbar and remove ScrollView The machine selector has the scroll view inside of the listview. It just needs to use our new scrollbar element instead of the default. Contributes to issue CURA-8686. --- .../qml/PrinterSelector/MachineSelector.qml | 46 ++++++------------- .../PrinterSelector/MachineSelectorList.qml | 9 +++- 2 files changed, 22 insertions(+), 33 deletions(-) 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 From 5041162a99f2b4fe2cd0da615f34265e95087d97 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 14:47:55 +0100 Subject: [PATCH 22/64] Use custom scroll bar for qualities+intents menu Contributes to issue CURA-8686. --- .../Custom/QualitiesWithIntentMenu.qml | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) 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 { From f94b7ce753c84bf71ac65664e67df7da735ec7e8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 14:58:55 +0100 Subject: [PATCH 23/64] Replace ScrollView+Column+Repeater by ListView with correct scrollbar Much simpler. And looks more consistent too. Contributes to issue CURA-8686. --- .../qml/WelcomePages/AddCloudPrintersView.qml | 94 +++++++++---------- 1 file changed, 42 insertions(+), 52 deletions(-) diff --git a/resources/qml/WelcomePages/AddCloudPrintersView.qml b/resources/qml/WelcomePages/AddCloudPrintersView.qml index e33d519f22..f454dc139d 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 + 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 } } } From fa2fbb99c7cc5c527e2dddf301172877ce869a03 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 16:26:48 +0100 Subject: [PATCH 24/64] Fix height and scrolling of add printer menus This fixes the irritating scrolling behaviour of the local printer menu, as well as the disappearing items (former issue which had a workaround) and makes it use a styled scroll bar. Contributes to issue CURA-8686. --- .../AddLocalPrinterScrollView.qml | 153 ++++++++---------- .../AddNetworkOrLocalPrinterContent.qml | 13 +- resources/qml/WelcomePages/DropDownWidget.qml | 4 +- 3 files changed, 68 insertions(+), 102 deletions(-) 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/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") From 9124f213ea074711755f8a6aa49281a63eab9a91 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 16:31:36 +0100 Subject: [PATCH 25/64] Prevent QML errors when model is not yet initialised I'm not sure when this happens, but it updates this text twice: Once with 'undefined' name and once with the proper name. For the user it displays the name correctly, but it may be so fast that nothing was visible. Discovered during work on CURA-8686. --- resources/qml/WelcomePages/AddCloudPrintersView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/WelcomePages/AddCloudPrintersView.qml b/resources/qml/WelcomePages/AddCloudPrintersView.qml index f454dc139d..0b94d21fae 100644 --- a/resources/qml/WelcomePages/AddCloudPrintersView.qml +++ b/resources/qml/WelcomePages/AddCloudPrintersView.qml @@ -157,7 +157,7 @@ Item { id: cloudPrinterNameLabel leftPadding: UM.Theme.getSize("default_margin").width - text: model.name + text: model.name ? model.name : "" font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") elide: Text.ElideRight From f1db69a36aaae305ec4090fff8cfc47861397e50 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 17:14:30 +0100 Subject: [PATCH 26/64] Remove extra ScrollView and customise ListView instead Contributes to issue CURA-8686. --- .../AddNetworkPrinterScrollView.qml | 147 ++++++++---------- 1 file changed, 67 insertions(+), 80 deletions(-) diff --git a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml index 51f69dfa30..752ad64f98 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,91 @@ 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 + anchors.right: networkPrinterScrollBar.left + anchors.rightMargin: 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 } } } From efc748cc994c202f0a178db83f3b5a06070a11f6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 17:16:39 +0100 Subject: [PATCH 27/64] Remove unused ScrollView widget We were not using Cura.ScrollView anywhere. Contributes to issue CURA-8686. --- resources/qml/Widgets/ScrollView.qml | 46 ---------------------------- 1 file changed, 46 deletions(-) delete mode 100644 resources/qml/Widgets/ScrollView.qml 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 From 796779316fc356065d866c9c6d5b20b68292120e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 17:33:10 +0100 Subject: [PATCH 28/64] Fix scrolling through post-processing scripts list It turns out this has been broken for a while. I don't think anyone adds that many scripts that they'd need to scroll this, but if they want to they can now. Contributes to issue CURA-8686. --- .../PostProcessingPlugin.qml | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index 489254e310..d4ed30dea6 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -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 From 08b8dcfa43d55bafbf3abcef04ba542f90910a50 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Jan 2022 17:59:41 +0100 Subject: [PATCH 29/64] Use custom scroll bar for object selector Contributes to issue CURA-8686. --- resources/qml/ObjectSelector.qml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) 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 From 4f8213703575eb2eb3f09048c625db818d6f3175 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 20 Jan 2022 17:26:49 +0100 Subject: [PATCH 30/64] Customise scrollbar for extruder selectors Contributes to issue CURA-8686. --- .../SettingPickDialog.qml | 2 +- .../RecommendedSupportSelector.qml | 20 +++++++++---------- resources/qml/Settings/SettingExtruder.qml | 8 ++++---- .../qml/Settings/SettingOptionalExtruder.qml | 8 ++++---- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/plugins/PerObjectSettingsTool/SettingPickDialog.qml b/plugins/PerObjectSettingsTool/SettingPickDialog.qml index 8ea1a774a4..16590c68f1 100644 --- a/plugins/PerObjectSettingsTool/SettingPickDialog.qml +++ b/plugins/PerObjectSettingsTool/SettingPickDialog.qml @@ -71,7 +71,7 @@ UM.Dialog } ListView - { + { id: listview anchors { 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/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 { From 643f6e7d277135a355d247727f61cb661961d14f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 20 Jan 2022 17:28:31 +0100 Subject: [PATCH 31/64] Customise scrollbar for combobox widgets Contributes to issue CURA-8686. --- resources/qml/Widgets/ComboBox.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 From 7a5db88fd8154609ca5feec612cf7d7a34b2241d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 20 Jan 2022 17:58:11 +0100 Subject: [PATCH 32/64] Update slider to Controls 2 Because Controls 1 is going out. The rest of the controls elements here are left as they were since they need to be styled. Contributes to issue CURA-8686. --- plugins/ImageReader/ConfigUI.qml | 111 ++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 38 deletions(-) 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"); From 0f61e25a77e6259291112d07f1b49315d2ae9d03 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Jan 2022 17:07:10 +0100 Subject: [PATCH 33/64] Fix anchoring width of network printer view to scrollbar You can't anchor to something that's not a parent or sibling, and the scrollbar was an... uncle? Contributes to issue CURA-8686. --- resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml index 752ad64f98..64f194dd56 100644 --- a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml @@ -69,8 +69,7 @@ Item { anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: networkPrinterScrollBar.left - anchors.rightMargin: 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") From 5f101e8233b2d3ce07f168a6ff889cd374bf61fa Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 11:58:44 +0100 Subject: [PATCH 34/64] Set checked tab for TabRowButton We're changing this so that the button doesn't set this by itself. This is necessary so that I can use this TabRowButton also when it's not in a repeater (for the global stack in the profile manager). Contributes to issue CURA-8686. --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 5 +++-- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 5 +++-- resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) 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/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/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 From 50960ce5cf720fdc13c024d5ccf162d62708fa14 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 12:09:59 +0100 Subject: [PATCH 35/64] Use UM.TabRow instead of a tab view This styles it for us automatically. However the contents of the tab disappears now. I'll have to restore that, but since that moves a bunch of code I'd rather do that in a separate commit. I also changed the item to a column so that we don't have to link up the anchors very weirdly/difficulty with all of the buttons and messages that are optional. This just automatically makes space if there need to be extra buttons and messages in between, and even deals with the spacing correctly. Contributes to issue CURA-8686. --- resources/qml/Preferences/ProfilesPage.qml | 69 ++++++++-------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 72bd2df00f..bfab7d7d52 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -519,9 +519,11 @@ Item right: parent.right } - Item + Column { anchors.fill: parent + + spacing: UM.Theme.getSize("default_margin").height visible: base.currentItem != null Item // Profile title Label @@ -545,11 +547,9 @@ 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 { @@ -566,58 +566,37 @@ 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 } - OldControls.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 + 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 } } } From cfafdf878ac41f45f6d18d5c0652ffd08382936d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 13:34:13 +0100 Subject: [PATCH 36/64] Move contents of ProfileTab to ProfileOverview file This way it is re-useable, and no longer connected to the concept of a tab view. We can then display it in the profile manager. Contributes to issue CURA-8686. --- resources/qml/Preferences/ProfileTab.qml | 118 --------------------- resources/qml/Preferences/ProfilesPage.qml | 28 ++++- resources/qml/ProfileOverview.qml | 110 +++++++++++++++++++ resources/qml/qmldir | 1 + 4 files changed, 136 insertions(+), 121 deletions(-) delete mode 100644 resources/qml/Preferences/ProfileTab.qml create mode 100644 resources/qml/ProfileOverview.qml 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 bfab7d7d52..af81d97e6c 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2022 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 2.15 @@ -521,7 +521,13 @@ 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 @@ -585,6 +591,7 @@ Item UM.TabRow { + id: profileExtruderTabs UM.TabRowButton //One extra tab for the global settings. { text: catalog.i18nc("@title:tab", "Global Settings") @@ -601,6 +608,21 @@ Item } } } + + 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/ProfileOverview.qml b/resources/qml/ProfileOverview.qml new file mode 100644 index 0000000000..b807706e13 --- /dev/null +++ b/resources/qml/ProfileOverview.qml @@ -0,0 +1,110 @@ +//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 as OldControls +import QtQuick.Controls 2.15 + +import UM 1.5 as UM +import Cura 1.6 as Cura + +OldControls.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: + { + if (qualityItem == null) + { + return false; + } + return qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName; + } + + 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 != "" && profileOverview.isQualityItemCurrentlyActivated + font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && profileOverview.isQualityItemCurrentlyActivated) + opacity: font.strikeout ? 0.5 : 1 + color: styleData.textColor + elide: Text.ElideRight + } + } + } + + OldControls.TableViewColumn + { + role: "label" + title: catalog.i18nc("@title:column", "Setting") + width: (parent.width * 0.4) | 0 + delegate: itemDelegate + } + OldControls.TableViewColumn + { + role: "profile_value" + title: catalog.i18nc("@title:column", "Profile") + width: (parent.width * 0.18) | 0 + delegate: itemDelegate + } + OldControls.TableViewColumn + { + role: "user_value" + title: catalog.i18nc("@title:column", "Current"); + visible: profileOverview.isQualityItemCurrentlyActivated + width: (parent.width * 0.18) | 0 + delegate: itemDelegate + } + OldControls.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: profileOverview.extruderPosition + selectedQualityItem: profileOverview.qualityItem == null ? {} : profileOverview.qualityItem + } +} \ 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 From 2758957d5caff3a0c97a8849006e0a6a1aed4a8a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 13:57:47 +0100 Subject: [PATCH 37/64] Use TabRow for material page selection The contents of the page is done with a simple page that becomes visible or not. The easiest solution I could think of. No StackLayout necessary here. Contributes to issue CURA-8686. --- .../Preferences/Materials/MaterialsView.qml | 764 +++++++++--------- 1 file changed, 387 insertions(+), 377 deletions(-) diff --git a/resources/qml/Preferences/Materials/MaterialsView.qml b/resources/qml/Preferences/Materials/MaterialsView.qml index daa47f33e9..8de4d03241 100644 --- a/resources/qml/Preferences/Materials/MaterialsView.qml +++ b/resources/qml/Preferences/Materials/MaterialsView.qml @@ -11,7 +11,7 @@ import Cura 1.0 as Cura import ".." // Access to ReadOnlyTextArea.qml -OldControls.TabView +Item { id: base @@ -68,410 +68,420 @@ OldControls.TabView } } - OldControls.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 - - ScrollBar.vertical: UM.ScrollBar - { - parent: scrollView - anchors - { - top: parent.top - right: parent.right - bottom: parent.bottom - } - } - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - clip: true - - property real columnWidth: (scrollView.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") } - OldControls.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") } - OldControls.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 - } - 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 * 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" } } - OldControls.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 } - ListView + ScrollBar.vertical: UM.ScrollBar { - anchors.fill: parent - model: UM.SettingDefinitionsModel + parent: informationPage + anchors { - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } - expanded: ["*"] + 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: + { + 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() } - ScrollBar.vertical: UM.ScrollBar {} - clip: true - - delegate: UM.TooltipArea + Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") } + ReadOnlyTextField { - width: childrenRect.width - height: childrenRect.height - text: model.description - Label + 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: 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: + 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 { - // 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; + anchors.fill: parent + onClicked: colorDialog.open() + enabled: base.editingEnabled } - width: base.secondColumnWidth + } + + // pretty color name text field + ReadOnlyTextField + { + id: colorLabel; + width: parent.width - colorSelector.width - parent.spacing + text: properties.color_name; readOnly: !base.editingEnabled - suffix: " " + model.unit - maximumValue: 99999 - decimals: model.unit == "mm" ? 2 : 0 - - onEditingFinished: materialPropertyProvider.setPropertyValue("value", value) + onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text) } - UM.ContainerPropertyProvider + // popup dialog to select a new color + // if successful it sets the properties.color_code value to the new color + ColorDialog { - id: materialPropertyProvider - containerId: base.containerId - watchedProperties: [ "value" ] - key: model.key + id: colorDialog + color: properties.color_code + onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color) } - UM.ContainerPropertyProvider + } + + 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: { - id: variantPropertyProvider - containerId: Cura.MachineManager.activeStack.variant.id - watchedProperties: [ "value" ] - key: model.key + // 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); + } } - UM.ContainerPropertyProvider + 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: { - id: machinePropertyProvider - containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" - watchedProperties: [ "value" ] - key: model.key + 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 + } } } From 5671b6c61f50185ea90b6ca1f6d9f45aa5f1f9e7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 17:51:48 +0100 Subject: [PATCH 38/64] Replace TableView with custom implementation I intend to copy this implementation to mainline Cura when it's done. Contributes to issue CURA-8686. --- .../resources/qml/OpenProjectFilesPage.qml | 26 +++- .../DigitalLibrary/resources/qml/Table.qml | 127 ++++++++++++++++++ 2 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 plugins/DigitalLibrary/resources/qml/Table.qml diff --git a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml index 0e55efeb39..8e77c853a3 100644 --- a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml @@ -1,6 +1,8 @@ -// 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 @@ -56,8 +58,24 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") + //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 - Cura.TableView + columnHeaders: ["Name", "Uploaded by", "Uploaded at"] + model: TableModel + { + TableModelColumn { display: "fileName" } + TableModelColumn { display: "username" } + TableModelColumn { display: "uploadedAt" } + rows: manager.digitalFactoryFileModel.items + } + } + + /*Cura.TableView { id: filesTableView anchors.fill: parent @@ -102,7 +120,7 @@ Item manager.setSelectedFileIndices(newSelection); } } - } + }*/ Label { diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml new file mode 100644 index 0000000000..c1d01ec124 --- /dev/null +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -0,0 +1,127 @@ +//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 DigitalFactory 1.0 as DF +import UM 1.5 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: tableScrollView + + 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. + + Row + { + id: headerBar + Repeater + { + id: headerRepeater + model: columnHeaders + Rectangle + { + width: Math.round(tableScrollView.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") + } + Rectangle + { + 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) + { + parent.parent.width = Math.max(10, parent.parent.width + mouseX); //Don't go smaller than 10 pixels, to make sure you can still scale it back. + } + tableView.forceLayout(); + } + } + } + } + } + } + TableView + { + 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 + { + height: UM.Theme.getSize("section").height + + color: UM.Theme.getColor((row % 2 == 0) ? "main_background": "viewport_background") + + Label + { + id: cellContent + anchors.fill: parent + + text: display + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + } + + } +} \ No newline at end of file From 59494cdace3e20f4def4b277feb1584aa62a6633 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:03:45 +0100 Subject: [PATCH 39/64] Implement selection Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index c1d01ec124..66144b3ea3 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -108,7 +108,7 @@ Item { height: UM.Theme.getSize("section").height - color: UM.Theme.getColor((row % 2 == 0) ? "main_background": "viewport_background") + color: UM.Theme.getColor((tableScrollView.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) Label { @@ -121,7 +121,14 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } + MouseArea + { + anchors.fill: parent + onClicked: + { + tableScrollView.currentRow = row; //Select this row. + } + } } - } } \ No newline at end of file From a7da4e4ef90293830fec53ba239fd5a742f590bb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:11:30 +0100 Subject: [PATCH 40/64] Fix integration with new table view Only a single selected item for the moment. Contributes to issue CURA-8686. --- .../resources/qml/OpenProjectFilesPage.qml | 55 ++----------------- 1 file changed, 6 insertions(+), 49 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml index 8e77c853a3..e0009d20e3 100644 --- a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml @@ -73,55 +73,13 @@ Item TableModelColumn { display: "uploadedAt" } rows: manager.digitalFactoryFileModel.items } + + onCurrentRowChanged: + { + manager.setSelectedFileIndices([currentRow]); + } } - /*Cura.TableView - { - id: filesTableView - anchors.fill: parent - model: manager.digitalFactoryFileModel - visible: model.count != 0 && manager.retrievingFileStatus != DF.RetrievalStatus.InProgress - selectionMode: OldControls.SelectionMode.SingleSelection - onDoubleClicked: - { - 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 { id: emptyProjectLabel @@ -178,7 +136,6 @@ Item { // Make sure no files are selected when the file model changes filesTableView.currentRow = -1 - filesTableView.selection.clear() } } } @@ -204,7 +161,7 @@ Item anchors.bottom: parent.bottom anchors.right: parent.right text: "Open" - enabled: filesTableView.selection.count > 0 + enabled: filesTableView.currentRow >= 0 onClicked: { manager.openSelectedFiles() From bbb40d9b11cae3335378d65e3cf874f22a1738b6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:19:08 +0100 Subject: [PATCH 41/64] Allow double-clicking on a file to open it Contributes to issue CURA-8686. --- .../DigitalLibrary/resources/qml/OpenProjectFilesPage.qml | 5 +++++ plugins/DigitalLibrary/resources/qml/Table.qml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml index e0009d20e3..6a03bca27b 100644 --- a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml @@ -78,6 +78,11 @@ Item { manager.setSelectedFileIndices([currentRow]); } + onDoubleClicked: function(row) + { + manager.setSelectedFileIndices([row]); + openFilesButton.clicked(); + } } Label diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 66144b3ea3..0ae97792dc 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -24,6 +24,7 @@ Item 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. Row { @@ -128,6 +129,10 @@ Item { tableScrollView.currentRow = row; //Select this row. } + onDoubleClicked: + { + tableScrollView.onDoubleClicked(row); + } } } } From 88bf1995c0b3c034453ad12fb4159fad25ba41d7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:22:38 +0100 Subject: [PATCH 42/64] Fix cell height adjusting to content To be honest, I'm not entirely sure why it only works here if I use implicitHeight instead of height. Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 0ae97792dc..d8ea65c992 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -107,14 +107,14 @@ Item delegate: Rectangle { - height: UM.Theme.getSize("section").height + implicitHeight: cellContent.height color: UM.Theme.getColor((tableScrollView.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) Label { id: cellContent - anchors.fill: parent + width: parent.width text: display verticalAlignment: Text.AlignVCenter From c6717c67f4b01c2f534ba848bd11c655766c66bc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:24:38 +0100 Subject: [PATCH 43/64] Don't let table overlap lining Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml index 6a03bca27b..6c74675227 100644 --- a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml @@ -64,6 +64,7 @@ Item { id: filesTableView anchors.fill: parent + anchors.margins: parent.border.width columnHeaders: ["Name", "Uploaded by", "Uploaded at"] model: TableModel From 279c23f5aa5127e76e7793082088afee6384ed65 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:26:15 +0100 Subject: [PATCH 44/64] Elide header text too Otherwise it just overlaps with the next column. Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index d8ea65c992..5ace6a823a 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -51,6 +51,7 @@ Item text: modelData font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("text") + elide: Text.ElideRight } Rectangle { From 2429f28b7f782842e8df38b6c5c607f04836ca5f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:31:43 +0100 Subject: [PATCH 45/64] Limit column widths to not exceed the total width of the table A bit clunky, but very effective! This way we don't have to deal with clipping or scrolling horizontally. Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 5ace6a823a..ea379b0885 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -80,6 +80,15 @@ Item if(drag.active) { parent.parent.width = Math.max(10, parent.parent.width + mouseX); //Don't go smaller than 10 pixels, to make sure you can still scale it back. + let sum_widths = 0; + for(let i = 0; i < headerBar.children.length; ++i) + { + sum_widths += headerBar.children[i].width; + } + if(sum_widths > tableScrollView.width) + { + parent.parent.width -= sum_widths - tableScrollView.width; //Limit the total width to not exceed the view. + } } tableView.forceLayout(); } From 39e29ae768718b439a254504a1a94903f09b563a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:34:04 +0100 Subject: [PATCH 46/64] Fix QML warning of 0 height from before table is filled If there is no model data, the cells will be empty and would have a height of 0. The table warns us that a height of 0 is not allowed. Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index ea379b0885..503672be4c 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -117,7 +117,7 @@ Item delegate: Rectangle { - implicitHeight: cellContent.height + implicitHeight: Math.max(1, cellContent.height) color: UM.Theme.getColor((tableScrollView.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) From 6457410a534b7d08033f5289e576865cc552592b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:37:34 +0100 Subject: [PATCH 47/64] Copy new Table implementation to Cura.TableView There we can re-use it. We can't re-use that implementation from the Digital Library itself, since that plug-in needs to be compatible with older Cura versions as well. Contributes to issue CURA-8686. --- .../DigitalLibrary/resources/qml/Table.qml | 1 - resources/qml/TableView.qml | 175 +++++++++++++----- 2 files changed, 128 insertions(+), 48 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 503672be4c..7d5750d113 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -5,7 +5,6 @@ import Qt.labs.qmlmodels 1.0 import QtQuick 2.15 import QtQuick.Controls 2.15 -import DigitalFactory 1.0 as DF import UM 1.5 as UM /* diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index db495c3dc2..7d5750d113 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -1,67 +1,148 @@ -// 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: tableScrollView - 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. + + 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.round(tableScrollView.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 + { + 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) + { + parent.parent.width = Math.max(10, parent.parent.width + mouseX); //Don't go smaller than 10 pixels, to make sure you can still scale it back. + let sum_widths = 0; + for(let i = 0; i < headerBar.children.length; ++i) + { + sum_widths += headerBar.children[i].width; + } + if(sum_widths > tableScrollView.width) + { + parent.parent.width -= sum_widths - tableScrollView.width; //Limit the total width to not exceed the view. + } + } + tableView.forceLayout(); + } + } + } + } } } - - rowDelegate: Rectangle + TableView { - color: styleData.selected ? UM.Theme.getColor("primary_button") : UM.Theme.getColor("main_background") - height: UM.Theme.getSize("table_row").height - } - - // Use the old styling technique since it's the only way to make the scrollbars themed in the TableView - style: TableViewStyle - { - backgroundColor: UM.Theme.getColor("main_background") - - handle: Rectangle + id: tableView + anchors { - // 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")) + top: headerBar.bottom + left: parent.left + right: parent.right + bottom: parent.bottom } - scrollBarBackground: Rectangle + clip: true + ScrollBar.vertical: UM.ScrollBar {} + columnWidthProvider: function(column) { - // 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") + return headerBar.children[column].width; //Cells get the same width as their column header. } - // The little rectangle between the vertical and horizontal scrollbars - corner: Rectangle + delegate: Rectangle { - color: UM.Theme.getColor("main_background") - } + implicitHeight: Math.max(1, cellContent.height) - // Override the control arrows - incrementControl: Item { } - decrementControl: Item { } + color: UM.Theme.getColor((tableScrollView.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") + } + MouseArea + { + anchors.fill: parent + onClicked: + { + tableScrollView.currentRow = row; //Select this row. + } + onDoubleClicked: + { + tableScrollView.onDoubleClicked(row); + } + } + } } } \ No newline at end of file From a4ef86609f46c879752880b630f86d484232d168 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:48:06 +0100 Subject: [PATCH 48/64] Implement option to disable selections Sometimes you don't want the user to be able to highlight certain rows. Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 3 +++ resources/qml/TableView.qml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 7d5750d113..1b12c8ec38 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -24,6 +24,7 @@ Item 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 { @@ -134,6 +135,8 @@ Item MouseArea { anchors.fill: parent + + enabled: tableScrollView.allowSelection onClicked: { tableScrollView.currentRow = row; //Select this row. diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index 7d5750d113..1b12c8ec38 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -24,6 +24,7 @@ Item 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 { @@ -134,6 +135,8 @@ Item MouseArea { anchors.fill: parent + + enabled: tableScrollView.allowSelection onClicked: { tableScrollView.currentRow = row; //Select this row. From 83953b03b433c7f6771364b15d116eeff0df2ae3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:48:45 +0100 Subject: [PATCH 49/64] Use new table element for saving files as well Re-using that component. Contributes to issue CURA-8686. --- .../resources/qml/OpenProjectFilesPage.qml | 1 - .../resources/qml/SaveProjectFilesPage.qml | 43 +++++++------------ 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml index 6c74675227..5f594cb79e 100644 --- a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml @@ -4,7 +4,6 @@ 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 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; } } } From c6eb1e668d3b89c60eab200943df2e7c5c679404 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:51:03 +0100 Subject: [PATCH 50/64] Rename tableScrollView to tableBase It is no longer a scrollview, after all, since the TableView itself already scrolls (and leaves the header nicely at the top this way). Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 16 ++++++++-------- resources/qml/TableView.qml | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 1b12c8ec38..cb4ca1fe37 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -18,7 +18,7 @@ import UM 1.5 as UM */ Item { - id: tableScrollView + 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" @@ -35,7 +35,7 @@ Item model: columnHeaders Rectangle { - width: Math.round(tableScrollView.width / headerRepeater.count) + width: Math.round(tableBase.width / headerRepeater.count) height: UM.Theme.getSize("section").height color: UM.Theme.getColor("secondary") @@ -85,9 +85,9 @@ Item { sum_widths += headerBar.children[i].width; } - if(sum_widths > tableScrollView.width) + if(sum_widths > tableBase.width) { - parent.parent.width -= sum_widths - tableScrollView.width; //Limit the total width to not exceed the view. + parent.parent.width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view. } } tableView.forceLayout(); @@ -119,7 +119,7 @@ Item { implicitHeight: Math.max(1, cellContent.height) - color: UM.Theme.getColor((tableScrollView.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) + color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) Label { @@ -136,14 +136,14 @@ Item { anchors.fill: parent - enabled: tableScrollView.allowSelection + enabled: tableBase.allowSelection onClicked: { - tableScrollView.currentRow = row; //Select this row. + tableBase.currentRow = row; //Select this row. } onDoubleClicked: { - tableScrollView.onDoubleClicked(row); + tableBase.onDoubleClicked(row); } } } diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index 1b12c8ec38..cb4ca1fe37 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -18,7 +18,7 @@ import UM 1.5 as UM */ Item { - id: tableScrollView + 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" @@ -35,7 +35,7 @@ Item model: columnHeaders Rectangle { - width: Math.round(tableScrollView.width / headerRepeater.count) + width: Math.round(tableBase.width / headerRepeater.count) height: UM.Theme.getSize("section").height color: UM.Theme.getColor("secondary") @@ -85,9 +85,9 @@ Item { sum_widths += headerBar.children[i].width; } - if(sum_widths > tableScrollView.width) + if(sum_widths > tableBase.width) { - parent.parent.width -= sum_widths - tableScrollView.width; //Limit the total width to not exceed the view. + parent.parent.width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view. } } tableView.forceLayout(); @@ -119,7 +119,7 @@ Item { implicitHeight: Math.max(1, cellContent.height) - color: UM.Theme.getColor((tableScrollView.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) + color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) Label { @@ -136,14 +136,14 @@ Item { anchors.fill: parent - enabled: tableScrollView.allowSelection + enabled: tableBase.allowSelection onClicked: { - tableScrollView.currentRow = row; //Select this row. + tableBase.currentRow = row; //Select this row. } onDoubleClicked: { - tableScrollView.onDoubleClicked(row); + tableBase.onDoubleClicked(row); } } } From 2a5abfdb01f6dc78d275895322bc7ae961f01b27 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 18:53:52 +0100 Subject: [PATCH 51/64] Downgrade UM version, re-implementing scroll bar This plug-in needs to be compatible with Cura 4.9 and up, which means we can't use UM.ScrollBar. Contributes to issue CURA-8686. --- .../DigitalLibrary/resources/qml/Table.qml | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index cb4ca1fe37..6eec4d4090 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -5,7 +5,7 @@ import Qt.labs.qmlmodels 1.0 import QtQuick 2.15 import QtQuick.Controls 2.15 -import UM 1.5 as UM +import UM 1.2 as UM /* * A re-sizeable table of data. @@ -109,7 +109,29 @@ Item } clip: true - ScrollBar.vertical: UM.ScrollBar {} + ScrollBar.vertical: ScrollBar + { + // Vertical ScrollBar, styled similarly to the scrollBar in the settings panel + id: verticalScrollBar + visible: flickableView.contentHeight > flickableView.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. From f22fea5f2245e0e4e83f07b92cea3f637c6430a3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 25 Jan 2022 19:05:54 +0100 Subject: [PATCH 52/64] Scroll back to top when contents of table change Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 11 ++++++++++- resources/qml/TableView.qml | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 6eec4d4090..b6162e9135 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -113,7 +113,7 @@ Item { // Vertical ScrollBar, styled similarly to the scrollBar in the settings panel id: verticalScrollBar - visible: flickableView.contentHeight > flickableView.height + visible: tableView.contentHeight > tableView.height background: Rectangle { @@ -169,5 +169,14 @@ Item } } } + + 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/resources/qml/TableView.qml b/resources/qml/TableView.qml index cb4ca1fe37..079e25d717 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -147,5 +147,14 @@ Item } } } + + 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 From e607ae7b92917f83f65310e433524ac1308d18e7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 11:24:41 +0100 Subject: [PATCH 53/64] Show tooltip if text got elided This way you can still see the whole text, even if the cell is too small. Handy. Contributes to issue CURA-8686. --- resources/qml/TableView.qml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index 079e25d717..8dc7cce713 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -132,14 +132,25 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } - MouseArea + TextMetrics + { + id: cellTextMetrics + text: cellContent.text + font: cellContent.font + elide: cellContent.elide + elideWidth: cellContent.width + } + UM.TooltipArea { anchors.fill: parent - enabled: tableBase.allowSelection + text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided. onClicked: { - tableBase.currentRow = row; //Select this row. + if(tableBase.allowSelection) + { + tableBase.currentRow = row; //Select this row. + } } onDoubleClicked: { From 5e5e0febb91a3fa6643cc95107f14ce3d764fc0f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 11:33:42 +0100 Subject: [PATCH 54/64] Format calculated functions in QualitySettingsModel itself That way we don't have to re-format it in the display in the table. Contributes to issue CURA-8686. --- cura/Machines/Models/QualitySettingsModel.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 89a996fba1..63d23240a8 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 @@ -174,11 +175,16 @@ class QualitySettingsModel(ListModel): if self._i18n_catalog: label = self._i18n_catalog.i18nc(definition.key + " label", label) + 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 From c973be3115679d4c90da47366be487d51e971e6a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 11:39:23 +0100 Subject: [PATCH 55/64] Use new TableView for profile overview This requires some more changes that are not yet implemented: Italic text for things that were changed in the profile, and section headers. Let's see what I can do... Contributes to issue CURA-8686. --- resources/qml/ProfileOverview.qml | 92 +++++-------------------------- 1 file changed, 13 insertions(+), 79 deletions(-) diff --git a/resources/qml/ProfileOverview.qml b/resources/qml/ProfileOverview.qml index b807706e13..eaf4373f4b 100644 --- a/resources/qml/ProfileOverview.qml +++ b/resources/qml/ProfileOverview.qml @@ -1,6 +1,7 @@ //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 @@ -8,7 +9,7 @@ import QtQuick.Controls 2.15 import UM 1.5 as UM import Cura 1.6 as Cura -OldControls.TableView +Cura.TableView { id: profileOverview @@ -24,87 +25,20 @@ OldControls.TableView return qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName; } - 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 != "" && profileOverview.isQualityItemCurrentlyActivated - font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && profileOverview.isQualityItemCurrentlyActivated) - opacity: font.strikeout ? 0.5 : 1 - color: styleData.textColor - elide: Text.ElideRight - } - } - } - - OldControls.TableViewColumn - { - role: "label" - title: catalog.i18nc("@title:column", "Setting") - width: (parent.width * 0.4) | 0 - delegate: itemDelegate - } - OldControls.TableViewColumn - { - role: "profile_value" - title: catalog.i18nc("@title:column", "Profile") - width: (parent.width * 0.18) | 0 - delegate: itemDelegate - } - OldControls.TableViewColumn - { - role: "user_value" - title: catalog.i18nc("@title:column", "Current"); - visible: profileOverview.isQualityItemCurrentlyActivated - width: (parent.width * 0.18) | 0 - delegate: itemDelegate - } - OldControls.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 + 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 + } } \ No newline at end of file From 5c71671585e6b48163528669d20e97fb7f4378c2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 14:00:29 +0100 Subject: [PATCH 56/64] Make setting names italic if changed in quality-changes profile This was the behaviour before. Contributes to issue CURA-8686. --- cura/Machines/Models/QualitySettingsModel.py | 2 ++ resources/qml/TableView.qml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 63d23240a8..bdae032f36 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -174,6 +174,8 @@ 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") diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index 8dc7cce713..1c5822ec8c 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -53,7 +53,7 @@ Item color: UM.Theme.getColor("text") elide: Text.ElideRight } - Rectangle + Rectangle //Resize handle. { anchors { From fa177f519260d3a1d71e3c54ff98b040cae28940 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 15:36:52 +0100 Subject: [PATCH 57/64] Implement section headers I'm not real happy with the limitations I had to work with here. The TableView can only accept a table of strings, so I basically had to fit everything into editing this dictionary of strings. Not the best. But it's very effective. Contributes to issue CURA-8686. --- resources/qml/ProfileOverview.qml | 1 + resources/qml/TableView.qml | 40 +++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/resources/qml/ProfileOverview.qml b/resources/qml/ProfileOverview.qml index eaf4373f4b..06a7268198 100644 --- a/resources/qml/ProfileOverview.qml +++ b/resources/qml/ProfileOverview.qml @@ -41,4 +41,5 @@ Cura.TableView TableModelColumn { display: "unit" } rows: qualitySettings.items } + sectionRole: "category" } \ No newline at end of file diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index 1c5822ec8c..c30a448ea6 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -25,6 +25,7 @@ Item 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 { @@ -97,6 +98,7 @@ Item } } } + TableView { id: tableView @@ -168,4 +170,42 @@ Item } } } + + Connections + { + target: model + function onRowsChanged() + { + 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; + } + + //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; + } + } } \ No newline at end of file From ec21b167d06776030910b0729dfaeef7169f7688 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 16:29:09 +0100 Subject: [PATCH 58/64] Resize columns when TableView is resized They should retain their width proportionally. This also fixes a case where the width of the TableView was initialised as 0 but then changed for some anchors due to weird bindings. Because it now updates the tableView when the width is changed. Contributes to issue CURA-8686. --- resources/qml/TableView.qml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index c30a448ea6..6499a4f668 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -36,7 +36,7 @@ Item model: columnHeaders Rectangle { - width: Math.round(tableBase.width / headerRepeater.count) + width: Math.max(1, Math.round(tableBase.width / headerRepeater.count)) height: UM.Theme.getSize("section").height color: UM.Theme.getColor("secondary") @@ -80,21 +80,27 @@ Item { if(drag.active) { - parent.parent.width = Math.max(10, parent.parent.width + mouseX); //Don't go smaller than 10 pixels, to make sure you can still scale it back. - let sum_widths = 0; + let new_width = parent.parent.width + mouseX; //Don't go smaller than 10 pixels, to make sure you can still scale it back. + let sum_widths = mouseX; for(let i = 0; i < headerBar.children.length; ++i) { sum_widths += headerBar.children[i].width; } if(sum_widths > tableBase.width) { - parent.parent.width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view. + 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 }); } - tableView.forceLayout(); } } } + + onWidthChanged: + { + tableView.forceLayout(); //Rescale table cells underneath as well. + } } } } From 7a1c3e1bd5cc961b044d51f94fb706bf09b5586c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 16:30:50 +0100 Subject: [PATCH 59/64] Use customised TableView for Keep/Discard Changes dialogue Had to make some more modifications to get it to work again this time, due to the way the width of the table scales with the dialogue. But it's nice now. Contributes to issue CURA-8686. --- .../DiscardOrKeepProfileChangesDialog.qml | 96 ++++++------------- resources/qml/ProfileOverview.qml | 7 +- 2 files changed, 35 insertions(+), 68 deletions(-) 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/ProfileOverview.qml b/resources/qml/ProfileOverview.qml index 06a7268198..534c261b5f 100644 --- a/resources/qml/ProfileOverview.qml +++ b/resources/qml/ProfileOverview.qml @@ -32,7 +32,12 @@ Cura.TableView 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")] + 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" } From 43d407530948de7888643e91989d581e38b02997 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 26 Jan 2022 17:24:24 +0100 Subject: [PATCH 60/64] Bring changes from TableView to Digital Library version The classes should be approximately the same. There's 2 differences now though: * The ScrollBar is re-implemented in the Digital Library because the re-useable component is not available in all Cura editions that the Digital Library needs to support. * The sections are not working. It was removing big parts of the table for some reason and I don't think it's worth debugging since this version of the table doesn't use it at all. It's also a bit faster this way. Contributes to issue CURA-8686. --- .../DigitalLibrary/resources/qml/Table.qml | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index b6162e9135..3cde4e4e1c 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -35,7 +35,7 @@ Item model: columnHeaders Rectangle { - width: Math.round(tableBase.width / headerRepeater.count) + width: Math.max(1, Math.round(tableBase.width / headerRepeater.count)) height: UM.Theme.getSize("section").height color: UM.Theme.getColor("secondary") @@ -53,7 +53,7 @@ Item color: UM.Theme.getColor("text") elide: Text.ElideRight } - Rectangle + Rectangle //Resize handle. { anchors { @@ -79,24 +79,31 @@ Item { if(drag.active) { - parent.parent.width = Math.max(10, parent.parent.width + mouseX); //Don't go smaller than 10 pixels, to make sure you can still scale it back. - let sum_widths = 0; + let new_width = parent.parent.width + mouseX; //Don't go smaller than 10 pixels, to make sure you can still scale it back. + let sum_widths = mouseX; for(let i = 0; i < headerBar.children.length; ++i) { sum_widths += headerBar.children[i].width; } if(sum_widths > tableBase.width) { - parent.parent.width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view. + 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 }); } - tableView.forceLayout(); } } } + + onWidthChanged: + { + tableView.forceLayout(); //Rescale table cells underneath as well. + } } } } + TableView { id: tableView @@ -154,14 +161,25 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } - MouseArea + TextMetrics + { + id: cellTextMetrics + text: cellContent.text + font: cellContent.font + elide: cellContent.elide + elideWidth: cellContent.width + } + UM.TooltipArea { anchors.fill: parent - enabled: tableBase.allowSelection + text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided. onClicked: { - tableBase.currentRow = row; //Select this row. + if(tableBase.allowSelection) + { + tableBase.currentRow = row; //Select this row. + } } onDoubleClicked: { From 7bc109d1f0842ebfe9a0a8db931ad595f1ecfa0b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 28 Jan 2022 10:57:00 +0100 Subject: [PATCH 61/64] Remove outdated comment It's no longer limiting the width to be at least 10 pixels, due to how it has to scale with the width of the table. Contributes to issue CURA-8686. --- plugins/DigitalLibrary/resources/qml/Table.qml | 2 +- resources/qml/TableView.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml index 3cde4e4e1c..2e4c89dfa1 100644 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ b/plugins/DigitalLibrary/resources/qml/Table.qml @@ -79,7 +79,7 @@ Item { if(drag.active) { - let new_width = parent.parent.width + mouseX; //Don't go smaller than 10 pixels, to make sure you can still scale it back. + let new_width = parent.parent.width + mouseX; let sum_widths = mouseX; for(let i = 0; i < headerBar.children.length; ++i) { diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index 6499a4f668..cd787a6fd6 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -80,7 +80,7 @@ Item { if(drag.active) { - let new_width = parent.parent.width + mouseX; //Don't go smaller than 10 pixels, to make sure you can still scale it back. + let new_width = parent.parent.width + mouseX; let sum_widths = mouseX; for(let i = 0; i < headerBar.children.length; ++i) { From 92ed791f53c96fcf99c4908423de0b5a651e70de Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 28 Jan 2022 11:06:07 +0100 Subject: [PATCH 62/64] Simplify anchors of background rectangle Contributes to issue CURA-8686. --- resources/qml/Widgets/ScrollableTextArea.qml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml index c0801651ea..7d8f6b886d 100644 --- a/resources/qml/Widgets/ScrollableTextArea.qml +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -26,17 +26,8 @@ Flickable background: Rectangle //Providing the background color and border. { - anchors - { - top: parent.top - topMargin: -border.width - bottom: parent.bottom - bottomMargin: -border.width - left: parent.left - leftMargin: -border.width - right: parent.right - rightMargin: -border.width - } + anchors.fill: parent + anchors.margins: -border.width color: scrollableTextAreaBase.back_color border.color: UM.Theme.getColor("thick_lining") From 8d10e1d5a7a6905f09fd0d3fefd7076d4338c3f1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 28 Jan 2022 11:34:44 +0100 Subject: [PATCH 63/64] Simplify check for when quality profiles are activated Should behave the same way. Contributes to issue CURA-8686. --- resources/qml/ProfileOverview.qml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/resources/qml/ProfileOverview.qml b/resources/qml/ProfileOverview.qml index 534c261b5f..ebca4ff22e 100644 --- a/resources/qml/ProfileOverview.qml +++ b/resources/qml/ProfileOverview.qml @@ -15,15 +15,7 @@ Cura.TableView 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: - { - if (qualityItem == null) - { - return false; - } - return qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName; - } + property bool isQualityItemCurrentlyActivated: qualityItem != null && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName Cura.QualitySettingsModel { From fbb72d6f0a2ce8bebe3849b768675090f152ba26 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 28 Jan 2022 15:27:47 +0100 Subject: [PATCH 64/64] Remove horizontal scrollbar policies from Cura.ScrollableTextArea There is no horizontal scrollbar any more so these are giving errors now. Contributes to issue CURA-8686. --- resources/qml/WelcomePages/ChangelogContent.qml | 2 -- resources/qml/WelcomePages/WhatsNewContent.qml | 2 -- 2 files changed, 4 deletions(-) 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/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