Merge pull request #11342 from Ultimaker/CURA-8686_views_controls2

Update views and tabs to use Controls 2
This commit is contained in:
Remco Burema 2022-01-28 17:30:48 +01:00 committed by GitHub
commit b96f58799c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 2119 additions and 1941 deletions

View file

@ -1,4 +1,4 @@
# Copyright (c) 2020 Ultimaker B.V.
# Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
@ -9,6 +9,7 @@ from UM import i18nCatalog
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.SettingFunction import SettingFunction # To format setting functions differently.
import os
@ -173,12 +174,19 @@ class QualitySettingsModel(ListModel):
label = definition.label
if self._i18n_catalog:
label = self._i18n_catalog.i18nc(definition.key + " label", label)
if profile_value_source == "quality_changes":
label = f"<i>{label}</i>" # Make setting name italic if it's derived from the quality-changes profile.
if isinstance(profile_value, SettingFunction):
profile_value_display = self._i18n_catalog.i18nc("@info:status", "Calculated")
else:
profile_value_display = "" if profile_value is None else str(profile_value)
items.append({
"key": definition.key,
"label": label,
"unit": definition.unit,
"profile_value": "" if profile_value is None else str(profile_value), # it is for display only
"profile_value": profile_value_display,
"profile_value_source": profile_value_source,
"user_value": "" if user_value is None else str(user_value),
"category": current_category

View file

@ -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
}
}
}

View file

@ -1,8 +1,9 @@
// Copyright (C) 2021 Ultimaker B.V.
//Copyright (C) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import Qt.labs.qmlmodels 1.0
import QtQuick 2.15
import QtQuick.Window 2.2
import QtQuick.Controls 1.4 as OldControls // TableView doesn't exist in the QtQuick Controls 2.x in 5.10, so use the old one
import QtQuick.Controls 2.3
import UM 1.2 as UM
@ -56,52 +57,32 @@ Item
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
Cura.TableView
//We can't use Cura's TableView here, since in Cura >= 5.0 this uses QtQuick.TableView, while in Cura < 5.0 this uses QtControls1.TableView.
//So we have to define our own. Once support for 4.13 and earlier is dropped, we can switch to Cura.TableView.
Table
{
id: filesTableView
anchors.fill: parent
model: manager.digitalFactoryFileModel
visible: model.count != 0 && manager.retrievingFileStatus != DF.RetrievalStatus.InProgress
selectionMode: OldControls.SelectionMode.SingleSelection
onDoubleClicked:
anchors.margins: parent.border.width
columnHeaders: ["Name", "Uploaded by", "Uploaded at"]
model: TableModel
{
TableModelColumn { display: "fileName" }
TableModelColumn { display: "username" }
TableModelColumn { display: "uploadedAt" }
rows: manager.digitalFactoryFileModel.items
}
onCurrentRowChanged:
{
manager.setSelectedFileIndices([currentRow]);
}
onDoubleClicked: function(row)
{
manager.setSelectedFileIndices([row]);
openFilesButton.clicked();
}
OldControls.TableViewColumn
{
id: fileNameColumn
role: "fileName"
title: "Name"
width: Math.round(filesTableView.width / 3)
}
OldControls.TableViewColumn
{
id: usernameColumn
role: "username"
title: "Uploaded by"
width: Math.round(filesTableView.width / 3)
}
OldControls.TableViewColumn
{
role: "uploadedAt"
title: "Uploaded at"
}
Connections
{
target: filesTableView.selection
function onSelectionChanged()
{
let newSelection = [];
filesTableView.selection.forEach(function(rowIndex) { newSelection.push(rowIndex); });
manager.setSelectedFileIndices(newSelection);
}
}
}
Label
@ -160,7 +141,6 @@ Item
{
// Make sure no files are selected when the file model changes
filesTableView.currentRow = -1
filesTableView.selection.clear()
}
}
}
@ -186,7 +166,7 @@ Item
anchors.bottom: parent.bottom
anchors.right: parent.right
text: "Open"
enabled: filesTableView.selection.count > 0
enabled: filesTableView.currentRow >= 0
onClicked:
{
manager.openSelectedFiles()

View file

@ -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;
}
}
}

View file

@ -0,0 +1,200 @@
//Copyright (C) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import Qt.labs.qmlmodels 1.0
import QtQuick 2.15
import QtQuick.Controls 2.15
import UM 1.2 as UM
/*
* A re-sizeable table of data.
*
* This table combines a list of headers with a TableView to show certain roles in a table.
* The columns of the table can be resized.
* When the table becomes too big, you can scroll through the table. When a column becomes too small, the contents of
* the table are elided.
* The table gets Cura's themeing.
*/
Item
{
id: tableBase
required property var columnHeaders //The text to show in the headers of each column.
property alias model: tableView.model //A TableModel to display in this table. To use a ListModel for the rows, use "rows: listModel.items"
property int currentRow: -1 //The selected row index.
property var onDoubleClicked: function(row) {} //Something to execute when double clicked. Accepts one argument: The index of the row that was clicked on.
property bool allowSelection: true //Whether to allow the user to select items.
Row
{
id: headerBar
Repeater
{
id: headerRepeater
model: columnHeaders
Rectangle
{
width: Math.max(1, Math.round(tableBase.width / headerRepeater.count))
height: UM.Theme.getSize("section").height
color: UM.Theme.getColor("secondary")
Label
{
id: contentText
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("narrow_margin").width
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("narrow_margin").width
text: modelData
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Rectangle //Resize handle.
{
anchors
{
right: parent.right
top: parent.top
bottom: parent.bottom
}
width: UM.Theme.getSize("thick_lining").width
color: UM.Theme.getColor("thick_lining")
MouseArea
{
anchors.fill: parent
cursorShape: Qt.SizeHorCursor
drag
{
target: parent
axis: Drag.XAxis
}
onMouseXChanged:
{
if(drag.active)
{
let new_width = parent.parent.width + mouseX;
let sum_widths = mouseX;
for(let i = 0; i < headerBar.children.length; ++i)
{
sum_widths += headerBar.children[i].width;
}
if(sum_widths > tableBase.width)
{
new_width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view.
}
let width_fraction = new_width / tableBase.width; //Scale with the same fraction along with the total width, if the table is resized.
parent.parent.width = Qt.binding(function() { return tableBase.width * width_fraction });
}
}
}
}
onWidthChanged:
{
tableView.forceLayout(); //Rescale table cells underneath as well.
}
}
}
}
TableView
{
id: tableView
anchors
{
top: headerBar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
ScrollBar.vertical: ScrollBar
{
// Vertical ScrollBar, styled similarly to the scrollBar in the settings panel
id: verticalScrollBar
visible: tableView.contentHeight > tableView.height
background: Rectangle
{
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: Math.round(implicitWidth / 2)
color: UM.Theme.getColor("scrollbar_background")
}
contentItem: Rectangle
{
id: scrollViewHandle
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: Math.round(implicitWidth / 2)
color: verticalScrollBar.pressed ? UM.Theme.getColor("scrollbar_handle_down") : verticalScrollBar.hovered ? UM.Theme.getColor("scrollbar_handle_hover") : UM.Theme.getColor("scrollbar_handle")
Behavior on color { ColorAnimation { duration: 50; } }
}
}
columnWidthProvider: function(column)
{
return headerBar.children[column].width; //Cells get the same width as their column header.
}
delegate: Rectangle
{
implicitHeight: Math.max(1, cellContent.height)
color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background"))
Label
{
id: cellContent
width: parent.width
text: display
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
TextMetrics
{
id: cellTextMetrics
text: cellContent.text
font: cellContent.font
elide: cellContent.elide
elideWidth: cellContent.width
}
UM.TooltipArea
{
anchors.fill: parent
text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided.
onClicked:
{
if(tableBase.allowSelection)
{
tableBase.currentRow = row; //Select this row.
}
}
onDoubleClicked:
{
tableBase.onDoubleClicked(row);
}
}
}
Connections
{
target: model
function onRowCountChanged()
{
tableView.contentY = 0; //When the number of rows is reduced, make sure to scroll back to the start.
}
}
}
}

View file

@ -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");

View file

@ -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
}
}

View file

@ -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
}
}
}

View file

@ -1,7 +1,10 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import UM 1.2 as UM
import QtQuick 2.2
import QtQuick.Controls 2.2
import UM 1.5 as UM
import Cura 1.0 as Cura
import ".."
@ -67,10 +70,9 @@ UM.Dialog
text: catalog.i18nc("@label:checkbox", "Show all")
}
ScrollView
ListView
{
id: scrollView
id: listview
anchors
{
top: filterInput.bottom
@ -78,47 +80,47 @@ UM.Dialog
right: parent.right
bottom: parent.bottom
}
ListView
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: UM.SettingDefinitionsModel
{
id: listview
model: UM.SettingDefinitionsModel
id: definitionsModel
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
expanded: [ "*" ]
exclude:
{
id: definitionsModel
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
expanded: [ "*" ]
exclude:
{
var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings)
return excluded_settings
}
showAll: toggleShowAll.checked || filterInput.text !== ""
var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings)
return excluded_settings
}
delegate: Loader
{
id: loader
width: listview.width
height: model.type != undefined ? UM.Theme.getSize("section").height : 0
property var definition: model
property var settingDefinitionsModel: definitionsModel
asynchronous: true
source:
{
switch(model.type)
{
case "category":
return "PerObjectCategory.qml"
default:
return "PerObjectItem.qml"
}
}
}
Component.onCompleted: settingPickDialog.updateFilter()
showAll: toggleShowAll.checked || filterInput.text !== ""
}
delegate: Loader
{
id: loader
width: listview.width
height: model.type != undefined ? UM.Theme.getSize("section").height : 0
property var definition: model
property var settingDefinitionsModel: definitionsModel
asynchronous: true
source:
{
switch(model.type)
{
case "category":
return "PerObjectCategory.qml"
default:
return "PerObjectItem.qml"
}
}
}
Component.onCompleted: settingPickDialog.updateFilter()
}
rightButtons: [

View file

@ -1,4 +1,4 @@
// Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V.
// Copyright (c) 2022 Jaime van Kessel, Ultimaker B.V.
// The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2
@ -8,7 +8,7 @@ import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.2
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.0 as Cura
UM.Dialog
@ -34,7 +34,7 @@ UM.Dialog
UM.I18nCatalog{id: catalog; name: "cura"}
id: base
property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width)
property int textMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
property int textMargin: UM.Theme.getSize("narrow_margin").width
property string activeScriptName
SystemPalette{ id: palette }
SystemPalette{ id: disabledPalette; colorGroup: SystemPalette.Disabled }
@ -44,19 +44,18 @@ UM.Dialog
{
id: selectedScriptGroup
}
Item
Column
{
id: activeScripts
anchors.left: parent.left
width: base.columnWidth
height: parent.height
spacing: base.textMargin
Label
{
id: activeScriptsHeader
text: catalog.i18nc("@label", "Post Processing Scripts")
anchors.top: parent.top
anchors.topMargin: base.textMargin
anchors.left: parent.left
anchors.leftMargin: base.textMargin
anchors.right: parent.right
@ -67,22 +66,24 @@ UM.Dialog
ListView
{
id: activeScriptsList
anchors
{
top: activeScriptsHeader.bottom
left: parent.left
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
rightMargin: base.textMargin
topMargin: base.textMargin
leftMargin: UM.Theme.getSize("default_margin").width
}
height: Math.min(contentHeight, parent.height - parent.spacing * 2 - activeScriptsHeader.height - addButton.height) //At the window height, start scrolling this one.
height: childrenRect.height
clip: true
ScrollBar.vertical: UM.ScrollBar
{
id: activeScriptsScrollBar
}
model: manager.scriptList
delegate: Item
{
width: parent.width
width: parent.width - activeScriptsScrollBar.width
height: activeScriptButton.height
Button
{
@ -132,8 +133,7 @@ UM.Dialog
text: "x"
width: 20 * screenScaleFactor
height: 20 * screenScaleFactor
anchors.right:parent.right
anchors.rightMargin: base.textMargin
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
onClicked: manager.removeScriptByIndex(index)
contentItem: Item
@ -221,8 +221,6 @@ UM.Dialog
text: catalog.i18nc("@action", "Add a script")
anchors.left: parent.left
anchors.leftMargin: base.textMargin
anchors.top: activeScriptsList.bottom
anchors.topMargin: base.textMargin
onClicked: scriptsMenu.open()
}
Menu
@ -275,9 +273,9 @@ UM.Dialog
color: UM.Theme.getColor("text")
}
ScrollView
ListView
{
id: scrollView
id: listview
anchors
{
top: scriptSpecsHeader.bottom
@ -288,123 +286,121 @@ UM.Dialog
bottom: parent.bottom
}
ScrollBar.vertical: UM.ScrollBar {}
clip: true
visible: manager.selectedScriptDefinitionId != ""
spacing: UM.Theme.getSize("default_lining").height
ListView
model: UM.SettingDefinitionsModel
{
id: listview
spacing: UM.Theme.getSize("default_lining").height
model: UM.SettingDefinitionsModel
{
id: definitionsModel
containerId: manager.selectedScriptDefinitionId
showAll: true
}
id: definitionsModel
containerId: manager.selectedScriptDefinitionId
showAll: true
}
delegate: Loader
{
id: settingLoader
delegate: Loader
{
id: settingLoader
width: parent.width
height:
width: listview.width
height:
{
if(provider.properties.enabled == "True")
{
if(provider.properties.enabled == "True")
if(model.type != undefined)
{
if(model.type != undefined)
{
return UM.Theme.getSize("section").height
}
else
{
return 0
}
return UM.Theme.getSize("section").height
}
else
{
return 0
}
}
Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled == "True" ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
enabled: opacity > 0
property var definition: model
property var settingDefinitionsModel: definitionsModel
property var propertyProvider: provider
property var globalPropertyProvider: inheritStackProvider
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
asynchronous: model.type != "enum" && model.type != "extruder"
onLoaded:
else
{
settingLoader.item.showRevertButton = false
settingLoader.item.showInheritButton = false
settingLoader.item.showLinkedSettingIcon = false
settingLoader.item.doDepthIndentation = false
settingLoader.item.doQualityUserSettingEmphasis = false
return 0
}
}
Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled == "True" ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
enabled: opacity > 0
property var definition: model
property var settingDefinitionsModel: definitionsModel
property var propertyProvider: provider
property var globalPropertyProvider: inheritStackProvider
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
asynchronous: model.type != "enum" && model.type != "extruder"
onLoaded:
{
settingLoader.item.showRevertButton = false
settingLoader.item.showInheritButton = false
settingLoader.item.showLinkedSettingIcon = false
settingLoader.item.doDepthIndentation = false
settingLoader.item.doQualityUserSettingEmphasis = false
}
sourceComponent:
{
switch(model.type)
{
case "int":
return settingTextField
case "float":
return settingTextField
case "enum":
return settingComboBox
case "extruder":
return settingExtruder
case "bool":
return settingCheckBox
case "str":
return settingTextField
case "category":
return settingCategory
default:
return settingUnknown
}
}
UM.SettingPropertyProvider
{
id: provider
containerStackId: manager.selectedScriptStackId
key: model.key ? model.key : "None"
watchedProperties: [ "value", "enabled", "state", "validationState" ]
storeIndex: 0
}
// Specialty provider that only watches global_inherits (we can't filter on what property changed we get events
// so we bypass that to make a dedicated provider).
UM.SettingPropertyProvider
{
id: inheritStackProvider
containerStack: Cura.MachineManager.activeMachine
key: model.key ? model.key : "None"
watchedProperties: [ "limit_to_extruder" ]
}
Connections
{
target: item
function onShowTooltip(text)
{
tooltip.text = text
var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0)
tooltip.show(position)
tooltip.target.x = position.x + 1
}
sourceComponent:
{
switch(model.type)
{
case "int":
return settingTextField
case "float":
return settingTextField
case "enum":
return settingComboBox
case "extruder":
return settingExtruder
case "bool":
return settingCheckBox
case "str":
return settingTextField
case "category":
return settingCategory
default:
return settingUnknown
}
}
UM.SettingPropertyProvider
{
id: provider
containerStackId: manager.selectedScriptStackId
key: model.key ? model.key : "None"
watchedProperties: [ "value", "enabled", "state", "validationState" ]
storeIndex: 0
}
// Specialty provider that only watches global_inherits (we can't filter on what property changed we get events
// so we bypass that to make a dedicated provider).
UM.SettingPropertyProvider
{
id: inheritStackProvider
containerStack: Cura.MachineManager.activeMachine
key: model.key ? model.key : "None"
watchedProperties: [ "limit_to_extruder" ]
}
Connections
{
target: item
function onShowTooltip(text)
{
tooltip.text = text
var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0)
tooltip.show(position)
tooltip.target.x = position.x + 1
}
function onHideTooltip() { tooltip.hide() }
}
function onHideTooltip() { tooltip.hide() }
}
}
}

View file

@ -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;
}
}
}

View file

@ -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]
}
}
}

View file

@ -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: "<a href='%1' title='%2'>%2</a>".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: "<a href='%1' title='%2'>%2</a>".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" });
}
}

View file

@ -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");

View file

@ -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

View file

@ -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
}
}
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -2,12 +2,11 @@
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.1
import QtQuick.Controls 1.1 as OldControls
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.3 as NewControls
import UM 1.1 as UM
import UM 1.5 as UM
import Cura 1.1 as Cura
UM.PreferencesPage
@ -133,10 +132,22 @@ UM.PreferencesPage
width: parent.width
height: parent.height
ScrollBar.vertical: UM.ScrollBar
{
id: preferencesScrollBar
parent: preferencesScrollView
anchors
{
top: parent.top
bottom: parent.bottom
right: parent.right
}
}
Column
{
UM.I18nCatalog{id: catalog; name: "cura"}
width: preferencesScrollView.viewport.width
width: preferencesScrollView.width - preferencesScrollBar.width
Label
{
@ -192,7 +203,7 @@ UM.PreferencesPage
}
}
NewControls.ComboBox
ComboBox
{
id: languageComboBox
@ -255,7 +266,7 @@ UM.PreferencesPage
}
}
NewControls.ComboBox
ComboBox
{
id: themeComboBox
@ -531,7 +542,7 @@ UM.PreferencesPage
}
}
NewControls.ComboBox
ComboBox
{
id: cameraComboBox
@ -688,7 +699,7 @@ UM.PreferencesPage
text: catalog.i18nc("@window:text", "Default behavior when opening a project file: ")
}
NewControls.ComboBox
ComboBox
{
id: choiceOnOpenProjectDropDownButton
width: Math.round(250 * screenScaleFactor)
@ -755,7 +766,7 @@ UM.PreferencesPage
text: catalog.i18nc("@window:text", "Default behavior for changed setting values when switching to a different profile: ")
}
NewControls.ComboBox
ComboBox
{
id: choiceOnProfileOverrideDropDownButton
width: Math.round(250 * screenScaleFactor)
@ -858,7 +869,7 @@ UM.PreferencesPage
}
}
ExclusiveGroup { id: curaUpdatesGroup }
OldControls.ExclusiveGroup { id: curaUpdatesGroup }
UM.TooltipArea
{
width: childrenRect.width
@ -866,7 +877,7 @@ UM.PreferencesPage
text: catalog.i18nc("@info:tooltip", "When checking for updates, only check for stable releases.")
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
RadioButton
OldControls.RadioButton
{
text: catalog.i18nc("@option:radio", "Stable releases only")
exclusiveGroup: curaUpdatesGroup
@ -882,7 +893,7 @@ UM.PreferencesPage
text: catalog.i18nc("@info:tooltip", "When checking for updates, check for both stable and for beta releases.")
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
RadioButton
OldControls.RadioButton
{
text: catalog.i18nc("@option:radio", "Stable and Beta releases")
exclusiveGroup: curaUpdatesGroup

View file

@ -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
}
}

View file

@ -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)
}
}
}

View file

@ -1,16 +1,17 @@
// Copyright (c) 2017 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls 2.15
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.0 as Cura
import ".." // Access to ReadOnlyTextArea.qml
TabView
Item
{
id: base
@ -67,400 +68,419 @@ TabView
}
}
Tab
UM.TabRow
{
title: catalog.i18nc("@title", "Information")
anchors.margins: UM.Theme.getSize("default_margin").width
ScrollView
id: pageSelectorTabRow
UM.TabRowButton
{
id: scrollView
anchors.fill: parent
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
flickableItem.flickableDirection: Flickable.VerticalFlick
frameVisible: true
property real columnWidth: (viewport.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0
Flow
{
id: containerGrid
x: UM.Theme.getSize("default_margin").width
y: UM.Theme.getSize("default_lining").height
width: base.width
property real rowHeight: brandTextField.height + UM.Theme.getSize("default_lining").height
MessageDialog
{
id: confirmDiameterChangeDialog
icon: StandardIcon.Question;
title: catalog.i18nc("@title:window", "Confirm Diameter Change")
text: catalog.i18nc("@label (%1 is a number)", "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?".arg(new_diameter_value))
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
property var new_diameter_value: null;
property var old_diameter_value: null;
property var old_approximate_diameter_value: null;
onYes:
{
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
// CURA-6868 Make sure to update the extruder to user a diameter-compatible material.
Cura.MachineManager.updateMaterialWithVariant()
base.resetSelectedMaterial()
}
onNo:
{
base.properties.diameter = old_diameter_value;
diameterSpinBox.value = Qt.binding(function() { return base.properties.diameter })
}
onRejected: no()
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
ReadOnlyTextField
{
id: displayNameTextField;
width: scrollView.columnWidth;
text: properties.name;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialDisplayName(properties.name, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
ReadOnlyTextField
{
id: brandTextField;
width: scrollView.columnWidth;
text: properties.brand;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialBrand(properties.brand, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
ReadOnlyTextField
{
id: materialTypeField;
width: scrollView.columnWidth;
text: properties.material;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialType(properties.material, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
Row
{
width: scrollView.columnWidth
height: parent.rowHeight
spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
// color indicator square
Rectangle
{
id: colorSelector
color: properties.color_code
width: Math.round(colorLabel.height * 0.75)
height: Math.round(colorLabel.height * 0.75)
border.width: UM.Theme.getSize("default_lining").height
anchors.verticalCenter: parent.verticalCenter
// open the color selection dialog on click
MouseArea
{
anchors.fill: parent
onClicked: colorDialog.open()
enabled: base.editingEnabled
}
}
// pretty color name text field
ReadOnlyTextField
{
id: colorLabel;
width: parent.width - colorSelector.width - parent.spacing
text: properties.color_name;
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
}
// popup dialog to select a new color
// if successful it sets the properties.color_code value to the new color
ColorDialog
{
id: colorDialog
color: properties.color_code
onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color)
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
ReadOnlySpinBox
{
id: densitySpinBox
width: scrollView.columnWidth
value: properties.density
decimals: 2
suffix: " g/cm³"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
onValueChanged: updateCostPerMeter()
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
ReadOnlySpinBox
{
id: diameterSpinBox
width: scrollView.columnWidth
value: properties.diameter
decimals: 2
suffix: " mm"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished:
{
// This does not use a SettingPropertyProvider, because we need to make the change to all containers
// which derive from the same base_file
var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter");
var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
var new_approximate_diameter = getApproximateDiameter(value);
if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter)
{
confirmDiameterChangeDialog.old_diameter_value = old_diameter;
confirmDiameterChangeDialog.new_diameter_value = value;
confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
confirmDiameterChangeDialog.open()
}
else {
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
}
}
onValueChanged: updateCostPerMeter()
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
SpinBox
{
id: spoolCostSpinBox
width: scrollView.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
prefix: base.currency + " "
decimals: 2
maximumValue: 100000000
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
SpinBox
{
id: spoolWeightSpinBox
width: scrollView.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"))
suffix: " g"
stepSize: 100
decimals: 0
maximumValue: 10000
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
Label
{
width: scrollView.columnWidth
text: "~ %1 m".arg(Math.round(base.spoolLength))
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
Label
{
width: scrollView.columnWidth
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible }
Label
{
width: 2 * scrollView.columnWidth
verticalAlignment: Qt.AlignVCenter
text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
wrapMode: Text.WordWrap
visible: unlinkMaterialButton.visible
}
Button
{
id: unlinkMaterialButton
text: catalog.i18nc("@label", "Unlink Material")
visible: base.linkedMaterialNames != ""
onClicked:
{
Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode)
base.reevaluateLinkedMaterials = true
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
ReadOnlyTextArea
{
text: properties.description;
width: 2 * scrollView.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
}
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") }
ReadOnlyTextArea
{
text: properties.adhesion_info;
width: 2 * scrollView.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
}
function updateCostPerMeter()
{
base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
}
text: catalog.i18nc("@title", "Information")
property string activeView: "information" //To determine which page gets displayed.
}
UM.TabRowButton
{
text: catalog.i18nc("@label", "Print settings")
property string activeView: "settings"
}
}
Tab
ScrollView
{
title: catalog.i18nc("@label", "Print settings")
id: informationPage
anchors
{
leftMargin: UM.Theme.getSize("default_margin").width
topMargin: UM.Theme.getSize("default_margin").height
bottomMargin: UM.Theme.getSize("default_margin").height
rightMargin: 0
top: pageSelectorTabRow.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
ScrollView
ScrollBar.vertical: UM.ScrollBar
{
anchors.fill: parent;
ListView
parent: informationPage
anchors
{
model: UM.SettingDefinitionsModel
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
clip: true
visible: pageSelectorTabRow.currentItem.activeView === "information"
property real columnWidth: (width * 0.5 - UM.Theme.getSize("default_margin").width) | 0
Flow
{
id: containerGrid
x: UM.Theme.getSize("default_margin").width
y: UM.Theme.getSize("default_lining").height
width: base.width
property real rowHeight: brandTextField.height + UM.Theme.getSize("default_lining").height
MessageDialog
{
id: confirmDiameterChangeDialog
icon: StandardIcon.Question;
title: catalog.i18nc("@title:window", "Confirm Diameter Change")
text: catalog.i18nc("@label (%1 is a number)", "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?".arg(new_diameter_value))
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
property var new_diameter_value: null;
property var old_diameter_value: null;
property var old_approximate_diameter_value: null;
onYes:
{
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
expanded: ["*"]
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
// CURA-6868 Make sure to update the extruder to user a diameter-compatible material.
Cura.MachineManager.updateMaterialWithVariant()
base.resetSelectedMaterial()
}
delegate: UM.TooltipArea
onNo:
{
width: childrenRect.width
height: childrenRect.height
text: model.description
Label
{
id: label
width: base.firstColumnWidth;
height: spinBox.height + UM.Theme.getSize("default_lining").height
text: model.label
elide: Text.ElideRight
verticalAlignment: Qt.AlignVCenter
}
ReadOnlySpinBox
{
id: spinBox
anchors.left: label.right
value:
{
// In case the setting is not in the material...
if (!isNaN(parseFloat(materialPropertyProvider.properties.value)))
{
return parseFloat(materialPropertyProvider.properties.value);
}
// ... we search in the variant, and if it is not there...
if (!isNaN(parseFloat(variantPropertyProvider.properties.value)))
{
return parseFloat(variantPropertyProvider.properties.value);
}
// ... then look in the definition container.
if (!isNaN(parseFloat(machinePropertyProvider.properties.value)))
{
return parseFloat(machinePropertyProvider.properties.value);
}
return 0;
}
width: base.secondColumnWidth
readOnly: !base.editingEnabled
suffix: " " + model.unit
maximumValue: 99999
decimals: model.unit == "mm" ? 2 : 0
base.properties.diameter = old_diameter_value;
diameterSpinBox.value = Qt.binding(function() { return base.properties.diameter })
}
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
}
onRejected: no()
}
UM.ContainerPropertyProvider
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
ReadOnlyTextField
{
id: displayNameTextField;
width: informationPage.columnWidth;
text: properties.name;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialDisplayName(properties.name, text)
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
ReadOnlyTextField
{
id: brandTextField;
width: informationPage.columnWidth;
text: properties.brand;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialBrand(properties.brand, text)
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
ReadOnlyTextField
{
id: materialTypeField;
width: informationPage.columnWidth;
text: properties.material;
readOnly: !base.editingEnabled;
onEditingFinished: base.updateMaterialType(properties.material, text)
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
Row
{
width: informationPage.columnWidth
height: parent.rowHeight
spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
// color indicator square
Rectangle
{
id: colorSelector
color: properties.color_code
width: Math.round(colorLabel.height * 0.75)
height: Math.round(colorLabel.height * 0.75)
border.width: UM.Theme.getSize("default_lining").height
anchors.verticalCenter: parent.verticalCenter
// open the color selection dialog on click
MouseArea
{
id: materialPropertyProvider
containerId: base.containerId
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: variantPropertyProvider
containerId: Cura.MachineManager.activeStack.variant.id
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: machinePropertyProvider
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
watchedProperties: [ "value" ]
key: model.key
anchors.fill: parent
onClicked: colorDialog.open()
enabled: base.editingEnabled
}
}
// pretty color name text field
ReadOnlyTextField
{
id: colorLabel;
width: parent.width - colorSelector.width - parent.spacing
text: properties.color_name;
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
}
// popup dialog to select a new color
// if successful it sets the properties.color_code value to the new color
ColorDialog
{
id: colorDialog
color: properties.color_code
onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color)
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
ReadOnlySpinBox
{
id: densitySpinBox
width: informationPage.columnWidth
value: properties.density
decimals: 2
suffix: " g/cm³"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
onValueChanged: updateCostPerMeter()
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
ReadOnlySpinBox
{
id: diameterSpinBox
width: informationPage.columnWidth
value: properties.diameter
decimals: 2
suffix: " mm"
stepSize: 0.01
readOnly: !base.editingEnabled
onEditingFinished:
{
// This does not use a SettingPropertyProvider, because we need to make the change to all containers
// which derive from the same base_file
var old_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "properties/diameter");
var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
var new_approximate_diameter = getApproximateDiameter(value);
if (new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter)
{
confirmDiameterChangeDialog.old_diameter_value = old_diameter;
confirmDiameterChangeDialog.new_diameter_value = value;
confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
confirmDiameterChangeDialog.open()
}
else {
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString());
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
}
}
onValueChanged: updateCostPerMeter()
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
OldControls.SpinBox
{
id: spoolCostSpinBox
width: informationPage.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
prefix: base.currency + " "
decimals: 2
maximumValue: 100000000
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
OldControls.SpinBox
{
id: spoolWeightSpinBox
width: informationPage.columnWidth
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight", Cura.ContainerManager.getContainerMetaDataEntry(properties.container_id, "properties/weight"))
suffix: " g"
stepSize: 100
decimals: 0
maximumValue: 10000
onValueChanged:
{
base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
Label
{
width: informationPage.columnWidth
text: "~ %1 m".arg(Math.round(base.spoolLength))
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Label { width: informationPage.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
Label
{
width: informationPage.columnWidth
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
verticalAlignment: Qt.AlignVCenter
height: parent.rowHeight
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible }
Label
{
width: 2 * informationPage.columnWidth
verticalAlignment: Qt.AlignVCenter
text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
wrapMode: Text.WordWrap
visible: unlinkMaterialButton.visible
}
OldControls.Button
{
id: unlinkMaterialButton
text: catalog.i18nc("@label", "Unlink Material")
visible: base.linkedMaterialNames != ""
onClicked:
{
Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode)
base.reevaluateLinkedMaterials = true
}
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
ReadOnlyTextArea
{
text: properties.description;
width: 2 * informationPage.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
}
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") }
ReadOnlyTextArea
{
text: properties.adhesion_info;
width: 2 * informationPage.columnWidth
wrapMode: Text.WordWrap
readOnly: !base.editingEnabled;
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
}
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
}
function updateCostPerMeter()
{
base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
}
}
ListView
{
anchors
{
top: pageSelectorTabRow.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
model: UM.SettingDefinitionsModel
{
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
expanded: ["*"]
}
ScrollBar.vertical: UM.ScrollBar {}
clip: true
visible: pageSelectorTabRow.currentItem.activeView === "settings"
delegate: UM.TooltipArea
{
width: childrenRect.width
height: childrenRect.height
text: model.description
Label
{
id: label
width: base.firstColumnWidth;
height: spinBox.height + UM.Theme.getSize("default_lining").height
text: model.label
elide: Text.ElideRight
verticalAlignment: Qt.AlignVCenter
}
ReadOnlySpinBox
{
id: spinBox
anchors.left: label.right
value:
{
// In case the setting is not in the material...
if (!isNaN(parseFloat(materialPropertyProvider.properties.value)))
{
return parseFloat(materialPropertyProvider.properties.value);
}
// ... we search in the variant, and if it is not there...
if (!isNaN(parseFloat(variantPropertyProvider.properties.value)))
{
return parseFloat(variantPropertyProvider.properties.value);
}
// ... then look in the definition container.
if (!isNaN(parseFloat(machinePropertyProvider.properties.value)))
{
return parseFloat(machinePropertyProvider.properties.value);
}
return 0;
}
width: base.secondColumnWidth
readOnly: !base.editingEnabled
suffix: " " + model.unit
maximumValue: 99999
decimals: model.unit == "mm" ? 2 : 0
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
}
UM.ContainerPropertyProvider
{
id: materialPropertyProvider
containerId: base.containerId
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: variantPropertyProvider
containerId: Cura.MachineManager.activeStack.variant.id
watchedProperties: [ "value" ]
key: model.key
}
UM.ContainerPropertyProvider
{
id: machinePropertyProvider
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
watchedProperties: [ "value" ]
key: model.key
}
}
}

View file

@ -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 }
}
}

View file

@ -1,12 +1,13 @@
// Copyright (c) 2019 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher.
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls 2.15
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import UM 1.5 as UM
import Cura 1.6 as Cura
@ -78,7 +79,7 @@ Item
height: childrenRect.height
// Activate button
Button
OldControls.Button
{
id: activateMenuButton
text: catalog.i18nc("@action:button", "Activate")
@ -98,7 +99,7 @@ Item
}
// Create button
Button
OldControls.Button
{
id: createMenuButton
text: catalog.i18nc("@label", "Create")
@ -115,7 +116,7 @@ Item
}
// Duplicate button
Button
OldControls.Button
{
id: duplicateMenuButton
text: catalog.i18nc("@label", "Duplicate")
@ -132,7 +133,7 @@ Item
}
// Remove button
Button
OldControls.Button
{
id: removeMenuButton
text: catalog.i18nc("@action:button", "Remove")
@ -146,7 +147,7 @@ Item
}
// Rename button
Button
OldControls.Button
{
id: renameMenuButton
text: catalog.i18nc("@action:button", "Rename")
@ -161,7 +162,7 @@ Item
}
// Import button
Button
OldControls.Button
{
id: importMenuButton
text: catalog.i18nc("@action:button", "Import")
@ -173,7 +174,7 @@ Item
}
// Export button
Button
OldControls.Button
{
id: exportMenuButton
text: catalog.i18nc("@action:button", "Export")
@ -397,13 +398,13 @@ Item
}
visible: text != ""
text: catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachine.name)
width: profileScrollView.width
width: profileBackground.width
elide: Text.ElideRight
}
ScrollView
Rectangle
{
id: profileScrollView
id: profileBackground
anchors
{
top: captionLabel.visible ? captionLabel.bottom : parent.top
@ -411,22 +412,20 @@ Item
bottom: parent.bottom
left: parent.left
}
width: (parent.width * 0.4) | 0
Rectangle
{
parent: viewport
anchors.fill: parent
color: palette.light
}
width: true ? (parent.width * 0.4) | 0 : parent.width
frameVisible: true
clip: true
color: palette.light
ListView
{
id: qualityListView
anchors.fill: parent
ScrollBar.vertical: UM.ScrollBar
{
id: profileScrollBar
}
clip: true
model: base.qualityManagementModel
Component.onCompleted:
@ -461,7 +460,7 @@ Item
delegate: Rectangle
{
width: profileScrollView.width
width: profileBackground.width - profileScrollBar.width
height: childrenRect.height
// Added this property to identify custom profiles in automated system tests (Squish)
@ -513,16 +512,24 @@ Item
anchors
{
left: profileScrollView.right
left: profileBackground.right
leftMargin: UM.Theme.getSize("default_margin").width
top: parent.top
bottom: parent.bottom
right: parent.right
}
Item
Column
{
anchors.fill: parent
id: detailsPanelHeaderColumn
anchors
{
left: parent.left
right: parent.right
top: parent.top
}
spacing: UM.Theme.getSize("default_margin").height
visible: base.currentItem != null
Item // Profile title Label
@ -546,16 +553,14 @@ Item
Flow
{
id: currentSettingsActions
width: parent.width
visible: base.hasCurrentItem && base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName && base.currentItem.intent_category == Cura.MachineManager.activeIntentCategory
anchors.left: parent.left
anchors.right: parent.right
anchors.top: profileName.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
Button
{
text: catalog.i18nc("@action:button", "Update profile with current settings/overrides")
enabled: Cura.MachineManager.hasUserSettings && !base.currentItem.is_read_only
enabled: Cura.MachineManager.hasUserSettings && qualityListView.currentItem && !qualityListView.currentItem.is_read_only
onClicked: Cura.ContainerManager.updateQualityChanges()
}
@ -567,62 +572,57 @@ Item
}
}
Column
Label
{
id: profileNotices
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.left: parent.left
anchors.right: parent.right
spacing: UM.Theme.getSize("default_margin").height
Label
{
id: defaultsMessage
visible: false
text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.")
wrapMode: Text.WordWrap
width: parent.width
}
Label
{
id: noCurrentSettingsMessage
visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
wrapMode: Text.WordWrap
width: parent.width
}
id: defaultsMessage
visible: false
text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.")
wrapMode: Text.WordWrap
width: parent.width
}
Label
{
id: noCurrentSettingsMessage
visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
wrapMode: Text.WordWrap
width: parent.width
}
TabView
UM.TabRow
{
anchors.left: parent.left
anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.right: parent.right
anchors.bottom: parent.bottom
currentIndex: 0
ProfileTab
id: profileExtruderTabs
UM.TabRowButton //One extra tab for the global settings.
{
title: catalog.i18nc("@title:tab", "Global Settings")
qualityItem: base.currentItem
text: catalog.i18nc("@title:tab", "Global Settings")
}
Repeater
{
model: base.extrudersModel
ProfileTab
UM.TabRowButton
{
title: model.name
extruderPosition: model.index
qualityItem: base.currentItem
text: model.name
}
}
}
}
Cura.ProfileOverview
{
anchors
{
top: detailsPanelHeaderColumn.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
visible: detailsPanelHeaderColumn.visible
qualityItem: base.currentItem
extruderPosition: profileExtruderTabs.currentIndex - 1
}
}
}
}

View file

@ -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
}
}
}

View file

@ -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

View file

@ -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
{

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,42 @@
//Copyright (c) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import Qt.labs.qmlmodels 1.0
import QtQuick 2.7
import QtQuick.Controls 1.4 as OldControls
import QtQuick.Controls 2.15
import UM 1.5 as UM
import Cura 1.6 as Cura
Cura.TableView
{
id: profileOverview
property var qualityItem //The quality profile to display here.
property int extruderPosition: -1 //The extruder to display. -1 denotes the global stack.
property bool isQualityItemCurrentlyActivated: qualityItem != null && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName
Cura.QualitySettingsModel
{
id: qualitySettings
selectedPosition: profileOverview.extruderPosition
selectedQualityItem: profileOverview.qualityItem == null ? {} : profileOverview.qualityItem
}
columnHeaders: [
catalog.i18nc("@title:column", "Setting"),
catalog.i18nc("@title:column", "Profile"),
catalog.i18nc("@title:column", "Current"),
catalog.i18nc("@title:column Unit of measurement", "Unit")
]
model: TableModel
{
TableModelColumn { display: "label" }
TableModelColumn { display: "profile_value" }
TableModelColumn { display: "user_value" }
TableModelColumn { display: "unit" }
rows: qualitySettings.items
}
sectionRole: "category"
}

View file

@ -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

View file

@ -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 {

View file

@ -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
{

View file

@ -1,67 +1,217 @@
// Copyright (C) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
//Copyright (C) 2022 Ultimaker B.V.
//Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.4 as OldControls // TableView doesn't exist in the QtQuick Controls 2.x in 5.10, so use the old one
import QtQuick.Controls 2.3
import QtQuick.Controls.Styles 1.4
import Qt.labs.qmlmodels 1.0
import QtQuick 2.15
import QtQuick.Controls 2.15
import UM 1.5 as UM
OldControls.TableView
/*
* A re-sizeable table of data.
*
* This table combines a list of headers with a TableView to show certain roles in a table.
* The columns of the table can be resized.
* When the table becomes too big, you can scroll through the table. When a column becomes too small, the contents of
* the table are elided.
* The table gets Cura's themeing.
*/
Item
{
itemDelegate: Item
{
height: tableCellLabel.implicitHeight
id: tableBase
UM.Label
required property var columnHeaders //The text to show in the headers of each column.
property alias model: tableView.model //A TableModel to display in this table. To use a ListModel for the rows, use "rows: listModel.items"
property int currentRow: -1 //The selected row index.
property var onDoubleClicked: function(row) {} //Something to execute when double clicked. Accepts one argument: The index of the row that was clicked on.
property bool allowSelection: true //Whether to allow the user to select items.
property string sectionRole: ""
Row
{
id: headerBar
Repeater
{
id: tableCellLabel
color: styleData.selected ? UM.Theme.getColor("primary_button_text") : UM.Theme.getColor("text")
elide: Text.ElideRight
text: styleData.value
anchors.fill: parent
anchors.leftMargin: 10 * screenScaleFactor
id: headerRepeater
model: columnHeaders
Rectangle
{
width: Math.max(1, Math.round(tableBase.width / headerRepeater.count))
height: UM.Theme.getSize("section").height
color: UM.Theme.getColor("secondary")
Label
{
id: contentText
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("narrow_margin").width
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("narrow_margin").width
text: modelData
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Rectangle //Resize handle.
{
anchors
{
right: parent.right
top: parent.top
bottom: parent.bottom
}
width: UM.Theme.getSize("thick_lining").width
color: UM.Theme.getColor("thick_lining")
MouseArea
{
anchors.fill: parent
cursorShape: Qt.SizeHorCursor
drag
{
target: parent
axis: Drag.XAxis
}
onMouseXChanged:
{
if(drag.active)
{
let new_width = parent.parent.width + mouseX;
let sum_widths = mouseX;
for(let i = 0; i < headerBar.children.length; ++i)
{
sum_widths += headerBar.children[i].width;
}
if(sum_widths > tableBase.width)
{
new_width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view.
}
let width_fraction = new_width / tableBase.width; //Scale with the same fraction along with the total width, if the table is resized.
parent.parent.width = Qt.binding(function() { return tableBase.width * width_fraction });
}
}
}
}
onWidthChanged:
{
tableView.forceLayout(); //Rescale table cells underneath as well.
}
}
}
}
rowDelegate: Rectangle
TableView
{
color: styleData.selected ? UM.Theme.getColor("primary_button") : UM.Theme.getColor("main_background")
height: UM.Theme.getSize("table_row").height
id: tableView
anchors
{
top: headerBar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
ScrollBar.vertical: UM.ScrollBar {}
columnWidthProvider: function(column)
{
return headerBar.children[column].width; //Cells get the same width as their column header.
}
delegate: Rectangle
{
implicitHeight: Math.max(1, cellContent.height)
color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background"))
Label
{
id: cellContent
width: parent.width
text: display
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
TextMetrics
{
id: cellTextMetrics
text: cellContent.text
font: cellContent.font
elide: cellContent.elide
elideWidth: cellContent.width
}
UM.TooltipArea
{
anchors.fill: parent
text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided.
onClicked:
{
if(tableBase.allowSelection)
{
tableBase.currentRow = row; //Select this row.
}
}
onDoubleClicked:
{
tableBase.onDoubleClicked(row);
}
}
}
Connections
{
target: model
function onRowCountChanged()
{
tableView.contentY = 0; //When the number of rows is reduced, make sure to scroll back to the start.
}
}
}
// Use the old styling technique since it's the only way to make the scrollbars themed in the TableView
style: TableViewStyle
Connections
{
backgroundColor: UM.Theme.getColor("main_background")
handle: Rectangle
target: model
function onRowsChanged()
{
// Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars
implicitWidth: UM.Theme.getSize("scrollbar").width
implicitHeight: UM.Theme.getSize("scrollbar").width
radius: width / 2
color: UM.Theme.getColor(styleData.pressed ? "scrollbar_handle_down" : (styleData.hovered ? "scrollbar_handle_hover" : "scrollbar_handle"))
}
let first_column = model.columns[0].display;
if(model.rows.length > 0 && model.rows[0][first_column].startsWith("<b>")) //First item is already a section header.
{
return; //Assume we already added section headers. Prevent infinite recursion.
}
if(sectionRole === "" || model.rows.length == 0) //No section headers, or no items at all.
{
tableView.model.rows = model.rows;
return;
}
scrollBarBackground: Rectangle
{
// Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars
implicitWidth: UM.Theme.getSize("scrollbar").width
implicitHeight: UM.Theme.getSize("scrollbar").width
color: UM.Theme.getColor("main_background")
//Insert section headers in the rows.
let last_section = "";
let new_rows = [];
for(let i = 0; i < model.rows.length; ++i)
{
let item_section = model.rows[i][sectionRole];
if(item_section !== last_section) //Starting a new section.
{
let section_header = {};
for(let key in model.rows[i])
{
section_header[key] = (key === first_column) ? "<b>" + item_section + "</b>" : ""; //Put the section header in the first column.
}
new_rows.push(section_header); //Add a row representing a section header.
last_section = item_section;
}
new_rows.push(model.rows[i]);
}
tableView.model.rows = new_rows;
}
// The little rectangle between the vertical and horizontal scrollbars
corner: Rectangle
{
color: UM.Theme.getColor("main_background")
}
// Override the control arrows
incrementControl: Item { }
decrementControl: Item { }
}
}

View file

@ -1,11 +1,11 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import UM 1.3 as UM
import UM 1.5 as UM
import Cura 1.7 as Cura
@ -22,7 +22,7 @@ Item
property bool searchingForCloudPrinters: true
property var discoveredCloudPrintersModel: CuraApplication.getDiscoveredCloudPrintersModel()
// The area where either the discoveredCloudPrintersScrollView or the busyIndicator will be displayed
// The area where either the discoveredCloudPrintersList or the busyIndicator will be displayed
Item
{
id: cloudPrintersContent
@ -126,14 +126,9 @@ Item
// The scrollView that contains the list of newly discovered Ultimaker Cloud printers. Visible only when
// there is at least a new cloud printer.
ScrollView
ListView
{
id: discoveredCloudPrintersScrollView
width: parent.width
clip : true
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AsNeeded
visible: discoveredCloudPrintersModel.count > 0
id: discoveredCloudPrintersList
anchors
{
top: cloudPrintersAddedTitle.bottom
@ -144,52 +139,47 @@ Item
bottom: parent.bottom
}
Column
ScrollBar.vertical: UM.ScrollBar {}
clip : true
visible: discoveredCloudPrintersModel.count > 0
spacing: UM.Theme.getSize("wide_margin").height
model: discoveredCloudPrintersModel
delegate: Item
{
id: discoveredPrintersColumn
spacing: 2 * UM.Theme.getSize("default_margin").height
width: discoveredCloudPrintersList.width
height: contentColumn.height
Repeater
Column
{
id: discoveredCloudPrintersRepeater
model: discoveredCloudPrintersModel
delegate: Item
id: contentColumn
Label
{
width: discoveredCloudPrintersScrollView.width
height: contentColumn.height
Column
{
id: contentColumn
Label
{
id: cloudPrinterNameLabel
leftPadding: UM.Theme.getSize("default_margin").width
text: model.name
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterTypeLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
topPadding: UM.Theme.getSize("thin_margin").height
text: {"Type: " + model.machine_type}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterFirmwareVersionLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
text: {"Firmware version: " + model.firmware_version}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
}
id: cloudPrinterNameLabel
leftPadding: UM.Theme.getSize("default_margin").width
text: model.name ? model.name : ""
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterTypeLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
topPadding: UM.Theme.getSize("thin_margin").height
text: {"Type: " + model.machine_type}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
Label
{
id: cloudPrinterFirmwareVersionLabel
leftPadding: 2 * UM.Theme.getSize("default_margin").width
text: {"Firmware version: " + model.firmware_version}
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
}
}

View file

@ -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")
}

View file

@ -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
}
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2021 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -17,7 +17,7 @@ Item
id: base
height: networkPrinterInfo.height + controlsRectangle.height
property alias maxItemCountAtOnce: networkPrinterScrollView.maxItemCountAtOnce
property alias maxItemCountAtOnce: networkPrinterListView.maxItemCountAtOnce
property var currentItem: (networkPrinterListView.currentIndex >= 0)
? networkPrinterListView.model[networkPrinterListView.currentIndex]
: null
@ -29,7 +29,7 @@ Item
Item
{
id: networkPrinterInfo
height: networkPrinterScrollView.visible ? networkPrinterScrollView.height : noPrinterLabel.height
height: networkPrinterListView.visible ? networkPrinterListView.height : noPrinterLabel.height
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
@ -44,104 +44,90 @@ Item
visible: networkPrinterListView.count == 0 // Do not show if there are discovered devices.
}
ScrollView
ListView
{
id: networkPrinterScrollView
id: networkPrinterListView
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AsNeeded
property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll.
height: Math.min(contentHeight, (maxItemCountAtOnce * UM.Theme.getSize("action_button").height) - UM.Theme.getSize("default_margin").height)
ScrollBar.vertical: UM.ScrollBar
{
id: networkPrinterScrollBar
}
clip: true
property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll.
visible: networkPrinterListView.count > 0
clip: true
model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
ListView
section.property: "modelData.sectionName"
section.criteria: ViewSection.FullString
section.delegate: UM.Label
{
id: networkPrinterListView
anchors.fill: parent
model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
width: parent.width - networkPrinterScrollBar.width - UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height
text: section
color: UM.Theme.getColor("small_button_text")
}
section.property: "modelData.sectionName"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
boundsBehavior: Flickable.StopAtBounds
flickDeceleration: 20000 // To prevent the flicking behavior.
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
Component.onCompleted:
Component.onCompleted:
{
var toSelectIndex = -1
// Select the first one that's not "unknown" and is the host a group by default.
for (var i = 0; i < count; i++)
{
var toSelectIndex = -1
// Select the first one that's not "unknown" and is the host a group by default.
for (var i = 0; i < count; i++)
if (!model[i].isUnknownMachineType && model[i].isHostOfGroup)
{
if (!model[i].isUnknownMachineType && model[i].isHostOfGroup)
{
toSelectIndex = i
break
}
}
currentIndex = toSelectIndex
}
// CURA-6483 For some reason currentIndex can be reset to 0. This check is here to prevent automatically
// selecting an unknown or non-host printer.
onCurrentIndexChanged:
{
var item = model[currentIndex]
if (!item || item.isUnknownMachineType || !item.isHostOfGroup)
{
currentIndex = -1
toSelectIndex = i
break
}
}
currentIndex = toSelectIndex
}
Component
// CURA-6483 For some reason currentIndex can be reset to 0. This check is here to prevent automatically
// selecting an unknown or non-host printer.
onCurrentIndexChanged:
{
var item = model[currentIndex]
if (!item || item.isUnknownMachineType || !item.isHostOfGroup)
{
id: sectionHeading
currentIndex = -1
}
}
UM.Label
{
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height
text: section
color: UM.Theme.getColor("small_button_text")
}
delegate: Cura.MachineSelectorButton
{
text: modelData.device.name
width: networkPrinterListView.width - networkPrinterScrollBar.width
outputDevice: modelData.device
enabled: !modelData.isUnknownMachineType && modelData.isHostOfGroup
printerTypeLabelAutoFit: true
// update printer types for all items in the list
updatePrinterTypesOnlyWhenChecked: false
updatePrinterTypesFunction: updateMachineTypes
// show printer type as it is
printerTypeLabelConversionFunction: function(value) { return value }
function updateMachineTypes()
{
printerTypesList = [ modelData.readableMachineType ]
}
delegate: Cura.MachineSelectorButton
checkable: false
selected: networkPrinterListView.currentIndex == model.index
onClicked:
{
text: modelData.device.name
width: networkPrinterListView.width
outputDevice: modelData.device
enabled: !modelData.isUnknownMachineType && modelData.isHostOfGroup
printerTypeLabelAutoFit: true
// update printer types for all items in the list
updatePrinterTypesOnlyWhenChecked: false
updatePrinterTypesFunction: updateMachineTypes
// show printer type as it is
printerTypeLabelConversionFunction: function(value) { return value }
function updateMachineTypes()
{
printerTypesList = [ modelData.readableMachineType ]
}
checkable: false
selected: ListView.view.currentIndex == model.index
onClicked:
{
ListView.view.currentIndex = index
}
networkPrinterListView.currentIndex = index
}
}
}

View file

@ -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

View file

@ -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")

View file

@ -113,8 +113,6 @@ Item
right: subpageImage.right
}
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
back_color: UM.Theme.getColor("viewport_overlay")
do_borders: false

View file

@ -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

View file

@ -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 } }
}
}
}

View file

@ -1,35 +1,39 @@
// Copyright (c) 2019 Ultimaker B.V.
// Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.3 as UM
import UM 1.5 as UM
import Cura 1.1 as Cura
//
// Cura-style TextArea with scrolls
//
ScrollView
Flickable
{
property alias textArea: _textArea
id: scrollableTextAreaBase
property bool do_borders: true
property var back_color: UM.Theme.getColor("main_background")
property var do_borders: true
property alias textArea: flickableTextArea
clip: true
ScrollBar.vertical: UM.ScrollBar {}
background: Rectangle // Border
TextArea.flickable: TextArea
{
color: back_color
border.color: UM.Theme.getColor("thick_lining")
border.width: do_borders ? UM.Theme.getSize("default_lining").width : 0
}
id: flickableTextArea
background: Rectangle //Providing the background color and border.
{
anchors.fill: parent
anchors.margins: -border.width
color: scrollableTextAreaBase.back_color
border.color: UM.Theme.getColor("thick_lining")
border.width: scrollableTextAreaBase.do_borders ? UM.Theme.getSize("default_lining").width : 0
}
TextArea
{
id: _textArea
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
textFormat: TextEdit.PlainText
@ -37,4 +41,4 @@ ScrollView
wrapMode: Text.Wrap
selectByMouse: true
}
}
}

View file

@ -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