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. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
@ -9,6 +9,7 @@ from UM import i18nCatalog
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.SettingFunction import SettingFunction # To format setting functions differently.
import os import os
@ -173,12 +174,19 @@ class QualitySettingsModel(ListModel):
label = definition.label label = definition.label
if self._i18n_catalog: if self._i18n_catalog:
label = self._i18n_catalog.i18nc(definition.key + " label", label) 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({ items.append({
"key": definition.key, "key": definition.key,
"label": label, "label": label,
"unit": definition.unit, "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, "profile_value_source": profile_value_source,
"user_value": "" if user_value is None else str(user_value), "user_value": "" if user_value is None else str(user_value),
"category": current_category "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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3 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 clip: true
ListView ScrollBar.vertical: UM.ScrollBar {}
delegate: Item
{ {
id: backupList // Add a margin, otherwise the scrollbar is on top of the right most component
width: parent.width width: parent.width - UM.Theme.getSize("scrollbar").width
delegate: Item height: childrenRect.height
BackupListItem
{ {
// Add a margin, otherwise the scrollbar is on top of the right most component id: backupListItem
width: parent.width - UM.Theme.getSize("default_margin").width width: parent.width
height: childrenRect.height }
BackupListItem Rectangle
{ {
id: backupListItem id: divider
width: parent.width 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.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 QtQuick.Controls 2.3
import UM 1.2 as UM import UM 1.2 as UM
@ -56,52 +57,32 @@ Item
border.width: UM.Theme.getSize("default_lining").width border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining") border.color: UM.Theme.getColor("lining")
//We can't use Cura's TableView here, since in Cura >= 5.0 this uses QtQuick.TableView, while in Cura < 5.0 this uses QtControls1.TableView.
Cura.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 id: filesTableView
anchors.fill: parent anchors.fill: parent
model: manager.digitalFactoryFileModel anchors.margins: parent.border.width
visible: model.count != 0 && manager.retrievingFileStatus != DF.RetrievalStatus.InProgress
selectionMode: OldControls.SelectionMode.SingleSelection columnHeaders: ["Name", "Uploaded by", "Uploaded at"]
onDoubleClicked: 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]); manager.setSelectedFileIndices([row]);
openFilesButton.clicked(); 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 Label
@ -160,7 +141,6 @@ Item
{ {
// Make sure no files are selected when the file model changes // Make sure no files are selected when the file model changes
filesTableView.currentRow = -1 filesTableView.currentRow = -1
filesTableView.selection.clear()
} }
} }
} }
@ -186,7 +166,7 @@ Item
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
text: "Open" text: "Open"
enabled: filesTableView.selection.count > 0 enabled: filesTableView.currentRow >= 0
onClicked: onClicked:
{ {
manager.openSelectedFiles() 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 2.10
import QtQuick.Window 2.2 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 QtQuick.Controls 2.3
import UM 1.2 as UM import UM 1.2 as UM
@ -85,35 +86,22 @@ Item
border.width: UM.Theme.getSize("default_lining").width border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining") border.color: UM.Theme.getColor("lining")
//We can't use Cura's TableView here, since in Cura >= 5.0 this uses QtQuick.TableView, while in Cura < 5.0 this uses QtControls1.TableView.
Cura.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 id: filesTableView
anchors.fill: parent anchors.fill: parent
model: manager.digitalFactoryFileModel anchors.margins: parent.border.width
visible: model.count != 0 && manager.retrievingFileStatus != DF.RetrievalStatus.InProgress
selectionMode: OldControls.SelectionMode.NoSelection
OldControls.TableViewColumn allowSelection: false
columnHeaders: ["Name", "Uploaded by", "Uploaded at"]
model: TableModel
{ {
id: fileNameColumn TableModelColumn { display: "fileName" }
role: "fileName" TableModelColumn { display: "username" }
title: "@tableViewColumn:title", "Name" TableModelColumn { display: "uploadedAt" }
width: Math.round(filesTableView.width / 3) rows: manager.digitalFactoryFileModel.items
}
OldControls.TableViewColumn
{
id: usernameColumn
role: "username"
title: "Uploaded by"
width: Math.round(filesTableView.width / 3)
}
OldControls.TableViewColumn
{
role: "uploadedAt"
title: "Uploaded at"
} }
} }
@ -172,8 +160,7 @@ Item
function onItemsChanged() function onItemsChanged()
{ {
// Make sure no files are selected when the file model changes // Make sure no files are selected when the file model changes
filesTableView.currentRow = -1 filesTableView.currentRow = -1;
filesTableView.selection.clear()
} }
} }
} }

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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.1 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.Layouts 1.1
import QtQuick.Window 2.1 import QtQuick.Window 2.1
@ -27,20 +28,24 @@ UM.Dialog
rowSpacing: 4 * screenScaleFactor rowSpacing: 4 * screenScaleFactor
columns: 1 columns: 1
UM.TooltipArea { UM.TooltipArea
{
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height height: childrenRect.height
text: catalog.i18nc("@info:tooltip","The maximum distance of each pixel from \"Base.\"") text: catalog.i18nc("@info:tooltip","The maximum distance of each pixel from \"Base.\"")
Row { Row
{
width: parent.width width: parent.width
Label { Label
{
text: catalog.i18nc("@action:label", "Height (mm)") text: catalog.i18nc("@action:label", "Height (mm)")
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
TextField { OldControls.TextField
{
id: peak_height id: peak_height
objectName: "Peak_Height" objectName: "Peak_Height"
validator: RegExpValidator {regExp: /^\d{0,3}([\,|\.]\d*)?$/} validator: RegExpValidator {regExp: /^\d{0,3}([\,|\.]\d*)?$/}
@ -50,20 +55,24 @@ UM.Dialog
} }
} }
UM.TooltipArea { UM.TooltipArea
{
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height height: childrenRect.height
text: catalog.i18nc("@info:tooltip","The base height from the build plate in millimeters.") text: catalog.i18nc("@info:tooltip","The base height from the build plate in millimeters.")
Row { Row
{
width: parent.width width: parent.width
Label { Label
{
text: catalog.i18nc("@action:label", "Base (mm)") text: catalog.i18nc("@action:label", "Base (mm)")
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
TextField { OldControls.TextField
{
id: base_height id: base_height
objectName: "Base_Height" objectName: "Base_Height"
validator: RegExpValidator {regExp: /^\d{0,3}([\,|\.]\d*)?$/} validator: RegExpValidator {regExp: /^\d{0,3}([\,|\.]\d*)?$/}
@ -73,20 +82,24 @@ UM.Dialog
} }
} }
UM.TooltipArea { UM.TooltipArea
{
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height height: childrenRect.height
text: catalog.i18nc("@info:tooltip","The width in millimeters on the build plate.") text: catalog.i18nc("@info:tooltip","The width in millimeters on the build plate.")
Row { Row
{
width: parent.width width: parent.width
Label { Label
{
text: catalog.i18nc("@action:label", "Width (mm)") text: catalog.i18nc("@action:label", "Width (mm)")
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
TextField { OldControls.TextField
{
id: width id: width
objectName: "Width" objectName: "Width"
focus: true focus: true
@ -97,19 +110,23 @@ UM.Dialog
} }
} }
UM.TooltipArea { UM.TooltipArea
{
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height height: childrenRect.height
text: catalog.i18nc("@info:tooltip","The depth in millimeters on the build plate") text: catalog.i18nc("@info:tooltip","The depth in millimeters on the build plate")
Row { Row
{
width: parent.width width: parent.width
Label { Label
{
text: catalog.i18nc("@action:label", "Depth (mm)") text: catalog.i18nc("@action:label", "Depth (mm)")
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
TextField { OldControls.TextField
{
id: depth id: depth
objectName: "Depth" objectName: "Depth"
focus: true focus: true
@ -120,20 +137,24 @@ UM.Dialog
} }
} }
UM.TooltipArea { UM.TooltipArea
{
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height 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.") 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 width: parent.width
//Empty label so 2 column layout works. //Empty label so 2 column layout works.
Label { Label
{
text: "" text: ""
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
ComboBox { OldControls.ComboBox
{
id: lighter_is_higher id: lighter_is_higher
objectName: "Lighter_Is_Higher" objectName: "Lighter_Is_Higher"
model: [ catalog.i18nc("@item:inlistbox","Darker is higher"), catalog.i18nc("@item:inlistbox","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 Layout.fillWidth:true
height: childrenRect.height 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.") 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 width: parent.width
Label { Label
{
text: "Color Model" text: "Color Model"
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
ComboBox { OldControls.ComboBox
{
id: color_model id: color_model
objectName: "ColorModel" objectName: "ColorModel"
model: [ catalog.i18nc("@item:inlistbox","Linear"), catalog.i18nc("@item:inlistbox","Translucency") ] model: [ catalog.i18nc("@item:inlistbox","Linear"), catalog.i18nc("@item:inlistbox","Translucency") ]
@ -165,20 +190,24 @@ UM.Dialog
} }
} }
UM.TooltipArea { UM.TooltipArea
{
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height 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.") 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") visible: color_model.currentText == catalog.i18nc("@item:inlistbox","Translucency")
Row { Row
{
width: parent.width width: parent.width
Label { Label
{
text: catalog.i18nc("@action:label", "1mm Transmittance (%)") text: catalog.i18nc("@action:label", "1mm Transmittance (%)")
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
TextField { OldControls.TextField
{
id: transmittance id: transmittance
objectName: "Transmittance" objectName: "Transmittance"
focus: true focus: true
@ -189,28 +218,34 @@ UM.Dialog
} }
} }
UM.TooltipArea { UM.TooltipArea
{
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height height: childrenRect.height
text: catalog.i18nc("@info:tooltip","The amount of smoothing to apply to the image.") text: catalog.i18nc("@info:tooltip","The amount of smoothing to apply to the image.")
Row { Row
{
width: parent.width width: parent.width
Label { Label
{
text: catalog.i18nc("@action:label", "Smoothing") text: catalog.i18nc("@action:label", "Smoothing")
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Item { Item
{
width: 180 * screenScaleFactor width: 180 * screenScaleFactor
height: 20 * screenScaleFactor height: 20 * screenScaleFactor
Layout.fillWidth: true Layout.fillWidth: true
Slider { Slider
{
id: smoothing id: smoothing
objectName: "Smoothing" objectName: "Smoothing"
maximumValue: 100.0 from: 0.0
to: 100.0
stepSize: 1.0 stepSize: 1.0
width: 180 width: 180
onValueChanged: { manager.onSmoothingChanged(value) } onValueChanged: { manager.onSmoothingChanged(value) }
@ -221,14 +256,14 @@ UM.Dialog
} }
rightButtons: [ rightButtons: [
Button OldControls.Button
{ {
id:ok_button id:ok_button
text: catalog.i18nc("@action:button","OK"); text: catalog.i18nc("@action:button","OK");
onClicked: { manager.onOkButtonClicked() } onClicked: { manager.onOkButtonClicked() }
enabled: true enabled: true
}, },
Button OldControls.Button
{ {
id:cancel_button id:cancel_button
text: catalog.i18nc("@action:button","Cancel"); text: catalog.i18nc("@action:button","Cancel");

View file

@ -1,5 +1,5 @@
// Copyright (c) 2019 Ultimaker B.V. //Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. //Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
@ -111,6 +111,7 @@ Cura.MachineAction
model: tabNameModel model: tabNameModel
delegate: UM.TabRowButton delegate: UM.TabRowButton
{ {
checked: model.index == 0
text: model.name text: model.name
} }
} }

View file

@ -1,9 +1,10 @@
// Copyright (c) 2021 Ultimaker B.V. // Copyright (c) 2022 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2 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.Styles 1.2
import QtQuick.Controls 2.15
import UM 1.5 as UM import UM 1.5 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
@ -76,7 +77,7 @@ Item
id: meshTypeButtons id: meshTypeButtons
spacing: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width
Button OldControls.Button
{ {
id: normalButton id: normalButton
text: catalog.i18nc("@label", "Normal model") text: catalog.i18nc("@label", "Normal model")
@ -88,7 +89,7 @@ Item
z: 4 z: 4
} }
Button OldControls.Button
{ {
id: supportMeshButton id: supportMeshButton
text: catalog.i18nc("@label", "Print as support") text: catalog.i18nc("@label", "Print as support")
@ -100,7 +101,7 @@ Item
z: 3 z: 3
} }
Button OldControls.Button
{ {
id: overlapMeshButton id: overlapMeshButton
text: catalog.i18nc("@label", "Modify settings for overlaps") text: catalog.i18nc("@label", "Modify settings for overlaps")
@ -112,7 +113,7 @@ Item
z: 2 z: 2
} }
Button OldControls.Button
{ {
id: antiOverhangMeshButton id: antiOverhangMeshButton
text: catalog.i18nc("@label", "Don't support overlaps") 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) height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight)
visible: currentMeshType != "anti_overhang_mesh" visible: currentMeshType != "anti_overhang_mesh"
ScrollView ListView
{ {
id: contents
height: parent.height height: parent.height
width: UM.Theme.getSize("setting").width + UM.Theme.getSize("default_margin").width 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 id: addedSettingsModel
spacing: UM.Theme.getSize("default_lining").height containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
expanded: [ "*" ]
model: UM.SettingDefinitionsModel filter:
{ {
id: addedSettingsModel if (printSequencePropertyProvider.properties.value == "one_at_a_time")
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
expanded: [ "*" ]
filter:
{ {
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 width: Math.round(UM.Theme.getSize("setting").height / 2)
Loader height: UM.Theme.getSize("setting").height
onClicked: addedSettingsModel.setVisible(model.key, false)
style: ButtonStyle
{ {
id: settingLoader background: Item
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 UM.RecolorImage
settingLoader.item.showInheritButton = false
settingLoader.item.showLinkedSettingIcon = false
settingLoader.item.doDepthIndentation = false
settingLoader.item.doQualityUserSettingEmphasis = false
}
sourceComponent:
{
switch(model.type)
{ {
case "int": anchors.verticalCenter: parent.verticalCenter
return settingTextField width: parent.width
case "[int]": height: width
return settingTextField sourceSize.height: width
case "float": color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
return settingTextField source: UM.Theme.getIcon("Minus")
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
} }
} }
} }
}
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) // the values cannot be bound with UM.ActiveTool.properties.getValue() calls,
height: UM.Theme.getSize("setting").height // so here we connect to the signal and update the those values.
if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
onClicked: addedSettingsModel.setVisible(model.key, false)
style: ButtonStyle
{ {
background: Item const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId")
if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
{ {
UM.RecolorImage addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId
{
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")
}
} }
} }
} if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined")
// 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()
{ {
// the values cannot be bound with UM.ActiveTool.properties.getValue() calls, const containerId = UM.ActiveTool.properties.getValue("ContainerID")
// so here we connect to the signal and update the those values. if (provider.containerStackId != containerId)
if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
{ {
const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId") provider.containerStackId = containerId
if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
{
addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId
}
} }
if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined") if (inheritStackProvider.containerStackId != containerId)
{ {
const containerId = UM.ActiveTool.properties.getValue("ContainerID") inheritStackProvider.containerStackId = containerId
if (provider.containerStackId != containerId)
{
provider.containerStackId = containerId
}
if (inheritStackProvider.containerStackId != containerId)
{
inheritStackProvider.containerStackId = containerId
}
} }
} }
} }

View file

@ -1,7 +1,10 @@
import QtQuick 2.2 // Copyright (c) 2022 Ultimaker B.V.
import QtQuick.Controls 1.2 // 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 Cura 1.0 as Cura
import ".." import ".."
@ -67,10 +70,9 @@ UM.Dialog
text: catalog.i18nc("@label:checkbox", "Show all") text: catalog.i18nc("@label:checkbox", "Show all")
} }
ScrollView ListView
{ {
id: scrollView id: listview
anchors anchors
{ {
top: filterInput.bottom top: filterInput.bottom
@ -78,47 +80,47 @@ UM.Dialog
right: parent.right right: parent.right
bottom: parent.bottom bottom: parent.bottom
} }
ListView
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: UM.SettingDefinitionsModel
{ {
id: listview id: definitionsModel
model: UM.SettingDefinitionsModel containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
expanded: [ "*" ]
exclude:
{ {
id: definitionsModel var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings)
visibilityHandler: UM.SettingPreferenceVisibilityHandler {} return excluded_settings
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 !== ""
} }
delegate: Loader showAll: toggleShowAll.checked || filterInput.text !== ""
{
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()
} }
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: [ 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. // The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2 import QtQuick 2.2
@ -8,7 +8,7 @@ import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
import QtQuick.Window 2.2 import QtQuick.Window 2.2
import UM 1.2 as UM import UM 1.5 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
UM.Dialog UM.Dialog
@ -34,7 +34,7 @@ UM.Dialog
UM.I18nCatalog{id: catalog; name: "cura"} UM.I18nCatalog{id: catalog; name: "cura"}
id: base id: base
property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width) 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 property string activeScriptName
SystemPalette{ id: palette } SystemPalette{ id: palette }
SystemPalette{ id: disabledPalette; colorGroup: SystemPalette.Disabled } SystemPalette{ id: disabledPalette; colorGroup: SystemPalette.Disabled }
@ -44,19 +44,18 @@ UM.Dialog
{ {
id: selectedScriptGroup id: selectedScriptGroup
} }
Item Column
{ {
id: activeScripts id: activeScripts
anchors.left: parent.left
width: base.columnWidth width: base.columnWidth
height: parent.height height: parent.height
spacing: base.textMargin
Label Label
{ {
id: activeScriptsHeader id: activeScriptsHeader
text: catalog.i18nc("@label", "Post Processing Scripts") text: catalog.i18nc("@label", "Post Processing Scripts")
anchors.top: parent.top
anchors.topMargin: base.textMargin
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: base.textMargin anchors.leftMargin: base.textMargin
anchors.right: parent.right anchors.right: parent.right
@ -67,22 +66,24 @@ UM.Dialog
ListView ListView
{ {
id: activeScriptsList id: activeScriptsList
anchors anchors
{ {
top: activeScriptsHeader.bottom
left: parent.left left: parent.left
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right right: parent.right
rightMargin: base.textMargin 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 model: manager.scriptList
delegate: Item delegate: Item
{ {
width: parent.width width: parent.width - activeScriptsScrollBar.width
height: activeScriptButton.height height: activeScriptButton.height
Button Button
{ {
@ -132,8 +133,7 @@ UM.Dialog
text: "x" text: "x"
width: 20 * screenScaleFactor width: 20 * screenScaleFactor
height: 20 * screenScaleFactor height: 20 * screenScaleFactor
anchors.right:parent.right anchors.right: parent.right
anchors.rightMargin: base.textMargin
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
onClicked: manager.removeScriptByIndex(index) onClicked: manager.removeScriptByIndex(index)
contentItem: Item contentItem: Item
@ -221,8 +221,6 @@ UM.Dialog
text: catalog.i18nc("@action", "Add a script") text: catalog.i18nc("@action", "Add a script")
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: base.textMargin anchors.leftMargin: base.textMargin
anchors.top: activeScriptsList.bottom
anchors.topMargin: base.textMargin
onClicked: scriptsMenu.open() onClicked: scriptsMenu.open()
} }
Menu Menu
@ -275,9 +273,9 @@ UM.Dialog
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
} }
ScrollView ListView
{ {
id: scrollView id: listview
anchors anchors
{ {
top: scriptSpecsHeader.bottom top: scriptSpecsHeader.bottom
@ -288,123 +286,121 @@ UM.Dialog
bottom: parent.bottom bottom: parent.bottom
} }
ScrollBar.vertical: UM.ScrollBar {}
clip: true
visible: manager.selectedScriptDefinitionId != "" visible: manager.selectedScriptDefinitionId != ""
spacing: UM.Theme.getSize("default_lining").height
ListView model: UM.SettingDefinitionsModel
{ {
id: listview id: definitionsModel
spacing: UM.Theme.getSize("default_lining").height containerId: manager.selectedScriptDefinitionId
model: UM.SettingDefinitionsModel showAll: true
{ }
id: definitionsModel
containerId: manager.selectedScriptDefinitionId
showAll: true
}
delegate: Loader delegate: Loader
{ {
id: settingLoader id: settingLoader
width: parent.width width: listview.width
height: 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
{
return UM.Theme.getSize("section").height
}
else
{
return 0
}
} }
else else
{ {
return 0 return 0
} }
} }
Behavior on height { NumberAnimation { duration: 100 } } else
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 return 0
settingLoader.item.showInheritButton = false }
settingLoader.item.showLinkedSettingIcon = false }
settingLoader.item.doDepthIndentation = false Behavior on height { NumberAnimation { duration: 100 } }
settingLoader.item.doQualityUserSettingEmphasis = false 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: function onHideTooltip() { tooltip.hide() }
{
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() }
}
} }
} }
} }

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. // 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 Cura 1.5 as Cura
import QtQuick 2.2 import QtQuick 2.2
@ -109,53 +109,51 @@ Cura.MachineAction
width: Math.round(parent.width * 0.5) width: Math.round(parent.width * 0.5)
spacing: UM.Theme.getSize("default_margin").height spacing: UM.Theme.getSize("default_margin").height
ScrollView ListView
{ {
id: objectListContainer id: listview
width: parent.width width: parent.width
height: base.height - contentRow.y - discoveryTip.height 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; if(!parent.ListView.isCurrentItem)
onClicked:
{ {
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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 1.4 import QtQuick.Controls 2.15
import UM 1.5 as UM import UM 1.5 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
@ -22,7 +22,7 @@ Item
id: queuedLabel id: queuedLabel
anchors anchors
{ {
left: queuedPrintJobs.left left: printJobList.left
top: parent.top top: parent.top
} }
font: UM.Theme.getFont("large") font: UM.Theme.getFont("large")
@ -34,7 +34,7 @@ Item
id: manageQueueLabel id: manageQueueLabel
anchors anchors
{ {
right: queuedPrintJobs.right right: printJobList.right
verticalCenter: queuedLabel.verticalCenter verticalCenter: queuedLabel.verticalCenter
} }
height: 18 * screenScaleFactor // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme!
@ -78,7 +78,7 @@ Item
id: printJobQueueHeadings id: printJobQueueHeadings
anchors anchors
{ {
left: queuedPrintJobs.left left: printJobList.left
leftMargin: UM.Theme.getSize("narrow_margin").width leftMargin: UM.Theme.getSize("narrow_margin").width
top: queuedLabel.bottom top: queuedLabel.bottom
topMargin: 24 * screenScaleFactor // TODO: Theme! topMargin: 24 * screenScaleFactor // TODO: Theme!
@ -121,41 +121,42 @@ Item
} }
} }
ScrollView ListView
{ {
id: queuedPrintJobs id: printJobList
anchors anchors
{ {
bottom: parent.bottom bottom: parent.bottom
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter
top: printJobQueueHeadings.bottom top: printJobQueueHeadings.bottom
topMargin: 12 * screenScaleFactor // TODO: Theme! topMargin: UM.Theme.getSize("default_margin").width
} }
style: UM.Theme.styles.scrollview
width: parent.width width: parent.width
ListView ScrollBar.vertical: UM.ScrollBar
{ {
id: printJobList id: printJobScrollBar
anchors.fill: parent }
delegate: MonitorPrintJobCard spacing: UM.Theme.getSize("narrow_margin").width
clip: true
delegate: MonitorPrintJobCard
{
anchors
{ {
anchors left: parent.left
{ right: parent.right
left: parent.left rightMargin: printJobScrollBar.width
right: parent.right
}
printJob: modelData
} }
model: printJob: modelData
}
model:
{
if (OutputDevice.receivedData)
{ {
if (OutputDevice.receivedData) return OutputDevice.queuedPrintJobs
{
return OutputDevice.queuedPrintJobs
}
return [null, null]
} }
spacing: 6 // TODO: Theme! return [null, null]
} }
} }
} }

View file

@ -5,7 +5,7 @@ import QtQuick 2.2
import QtQuick.Controls 2.9 import QtQuick.Controls 2.9
import QtQuick.Window 2.1 import QtQuick.Window 2.1
import UM 1.1 as UM import UM 1.5 as UM
UM.Dialog UM.Dialog
{ {
@ -89,81 +89,79 @@ UM.Dialog
anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.topMargin: UM.Theme.getSize("default_margin").height
} }
ScrollView ListView
{ {
id: credits id: projectsList
anchors.top: creditsNotes.bottom anchors.top: creditsNotes.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width width: parent.width
height: base.height - y - (2 * UM.Theme.getSize("default_margin").height + closeButton.height) 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 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/" });
Label 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" });
text: "<a href='%1' title='%2'>%2</a>".arg(model.url).arg(model.name) projectsModel.append({ name: "Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
width: (projectsList.width * 0.25) | 0 projectsModel.append({ name: "SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" });
elide: Text.ElideRight projectsModel.append({ name: "NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
onLinkActivated: Qt.openUrlExternally(link) 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" });
Label 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" });
text: model.description projectsModel.append({ name: "PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" });
elide: Text.ElideRight projectsModel.append({ name: "python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" });
width: (projectsList.width * 0.6) | 0 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" });
Label 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" });
text: model.license projectsModel.append({ name: "cryptography", description: catalog.i18nc("@Label", "Root Certificates for validating SSL trustworthiness"), license: "APACHE and BSD", url: "https://cryptography.io/" });
elide: Text.ElideRight projectsModel.append({ name: "Sentry", description: catalog.i18nc("@Label", "Python Error tracking library"), license: "BSD 2-Clause 'Simplified'", url: "https://sentry.io/for/python/" });
width: (projectsList.width * 0.15) | 0 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" });
model: ListModel 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/" });
id: projectsModel 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" });
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" });
}
} }
} }

View file

@ -1,14 +1,15 @@
// Copyright (c) 2020 Ultimaker B.V. //Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. //Cura is released under the terms of the LGPLv3 or higher.
import Qt.labs.qmlmodels 1.0
import QtQuick 2.1 import QtQuick 2.1
import QtQuick.Controls 1.1 import QtQuick.Controls 1.1 as OldControls
import QtQuick.Controls 2.15 as NewControls import QtQuick.Controls 2.15
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Window 2.1 import QtQuick.Window 2.1
import UM 1.2 as UM import UM 1.2 as UM
import Cura 1.0 as Cura import Cura 1.6 as Cura
UM.Dialog UM.Dialog
{ {
@ -17,6 +18,8 @@ UM.Dialog
minimumWidth: UM.Theme.getSize("popup_dialog").width minimumWidth: UM.Theme.getSize("popup_dialog").width
minimumHeight: UM.Theme.getSize("popup_dialog").height minimumHeight: UM.Theme.getSize("popup_dialog").height
width: minimumWidth
height: minimumHeight
property var changesModel: Cura.UserChangesModel{ id: userChangesModel} property var changesModel: Cura.UserChangesModel{ id: userChangesModel}
onVisibilityChanged: onVisibilityChanged:
{ {
@ -68,72 +71,31 @@ UM.Dialog
anchors.bottom: optionRow.top anchors.bottom: optionRow.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
TableView
Cura.TableView
{ {
anchors.fill: parent
height: base.height - 150
id: tableView id: tableView
Component anchors
{ {
id: labelDelegate top: parent.top
Label left: parent.left
{ right: parent.right
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
}
}
} }
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 TableModelColumn { display: "label" }
Label TableModelColumn { display: "original_value" }
{ TableModelColumn { display: "user_value" }
text: styleData.value rows: userChangesModel.items
font: UM.Theme.getFont("system")
}
} }
sectionRole: "category"
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
} }
} }
@ -146,7 +108,7 @@ UM.Dialog
anchors.margins: UM.Theme.getSize("default_margin").width anchors.margins: UM.Theme.getSize("default_margin").width
height: childrenRect.height height: childrenRect.height
NewControls.ComboBox ComboBox
{ {
id: discardOrKeepProfileChangesDropDownButton id: discardOrKeepProfileChangesDropDownButton
width: 300 width: 300
@ -193,7 +155,7 @@ UM.Dialog
anchors.margins: UM.Theme.getSize("default_margin").width anchors.margins: UM.Theme.getSize("default_margin").width
height: childrenRect.height height: childrenRect.height
Button OldControls.Button
{ {
id: discardButton id: discardButton
text: catalog.i18nc("@action:button", "Discard changes"); text: catalog.i18nc("@action:button", "Discard changes");
@ -206,7 +168,7 @@ UM.Dialog
isDefault: true isDefault: true
} }
Button OldControls.Button
{ {
id: keepButton id: keepButton
text: catalog.i18nc("@action:button", "Keep changes"); 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -6,7 +6,7 @@ import QtQuick.Controls 2.9
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import QtQuick.Window 2.2 import QtQuick.Window 2.2
import UM 1.2 as UM import UM 1.5 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
UM.Dialog UM.Dialog
@ -81,6 +81,19 @@ UM.Dialog
bottom: controls.top bottom: controls.top
bottomMargin: UM.Theme.getSize("default_margin").height 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 ColumnLayout
{ {
spacing: UM.Theme.getSize("default_margin").height 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import UM 1.3 as UM import UM 1.5 as UM
import Cura 1.1 as Cura import Cura 1.1 as Cura
@ -45,7 +45,7 @@ UM.TooltipArea
renderType: Text.NativeRendering renderType: Text.NativeRendering
} }
ScrollView Flickable
{ {
anchors.top: titleLabel.bottom anchors.top: titleLabel.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.topMargin: UM.Theme.getSize("default_margin").height
@ -53,26 +53,9 @@ UM.TooltipArea
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
background: Rectangle ScrollBar.vertical: UM.ScrollBar {}
{
color: UM.Theme.getColor("main_background")
anchors.fill: parent
border.color: TextArea.flickable: TextArea
{
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
{ {
id: gcodeTextArea id: gcodeTextArea
@ -92,6 +75,27 @@ UM.TooltipArea
propertyProvider.setPropertyValue("value", text) 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import UM 1.4 as UM import UM 1.5 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
Item Item
@ -67,18 +67,14 @@ Item
contentHeight: configurationList.height contentHeight: configurationList.height
clip: true 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: UM.ScrollBar {
ScrollBar.vertical.background: Rectangle parent: container
{ anchors
implicitWidth: UM.Theme.getSize("scrollbar").width {
radius: width / 2 top: parent.top
color: UM.Theme.getColor("scrollbar_background") right: parent.right
} bottom: parent.bottom
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")
} }
ButtonGroup ButtonGroup

View file

@ -1,5 +1,5 @@
// Copyright (c) 2019 Ultimaker B.V. //Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. //Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.6 import QtQuick 2.6
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
@ -92,6 +92,7 @@ Item
model: extrudersModel model: extrudersModel
delegate: UM.TabRowButton delegate: UM.TabRowButton
{ {
checked: model.index == 0
contentItem: Item contentItem: Item
{ {
Cura.ExtruderIcon 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -76,7 +76,7 @@ Item
id: contents id: contents
width: parent.width width: parent.width
visible: objectSelector.opened visible: objectSelector.opened
height: visible ? listView.height : 0 height: visible ? listView.height + border.width * 2 : 0
color: UM.Theme.getColor("main_background") color: UM.Theme.getColor("main_background")
border.width: UM.Theme.getSize("default_lining").width border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining") border.color: UM.Theme.getColor("lining")
@ -99,23 +99,22 @@ Item
ListView ListView
{ {
id: listView id: listView
clip: true
anchors anchors
{ {
left: parent.left left: parent.left
right: parent.right right: parent.right
top: parent.top
margins: UM.Theme.getSize("default_lining").width margins: UM.Theme.getSize("default_lining").width
} }
ScrollBar.vertical: ScrollBar
{
hoverEnabled: true
}
property real maximumHeight: UM.Theme.getSize("objects_menu_size").height property real maximumHeight: UM.Theme.getSize("objects_menu_size").height
height: Math.min(contentHeight, maximumHeight) height: Math.min(contentHeight, maximumHeight)
ScrollBar.vertical: UM.ScrollBar
{
id: scrollBar
}
clip: true
model: Cura.ObjectsModel {} model: Cura.ObjectsModel {}
delegate: ObjectItemButton delegate: ObjectItemButton
@ -128,7 +127,7 @@ Item
value: model.selected value: model.selected
} }
text: model.name text: model.name
width: listView.width width: listView.width - scrollBar.width
property bool outsideBuildArea: model.outside_build_area property bool outsideBuildArea: model.outside_build_area
property int perObjectSettingsCount: model.per_object_settings_count property int perObjectSettingsCount: model.per_object_settings_count
property string meshType: model.mesh_type property string meshType: model.mesh_type

View file

@ -2,12 +2,11 @@
// Cura is released under the terms of the LGPLv3 or higher. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 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.Layouts 1.1
import QtQuick.Controls 2.3 as NewControls import UM 1.5 as UM
import UM 1.1 as UM
import Cura 1.1 as Cura import Cura 1.1 as Cura
UM.PreferencesPage UM.PreferencesPage
@ -133,10 +132,22 @@ UM.PreferencesPage
width: parent.width width: parent.width
height: parent.height height: parent.height
ScrollBar.vertical: UM.ScrollBar
{
id: preferencesScrollBar
parent: preferencesScrollView
anchors
{
top: parent.top
bottom: parent.bottom
right: parent.right
}
}
Column Column
{ {
UM.I18nCatalog{id: catalog; name: "cura"} UM.I18nCatalog{id: catalog; name: "cura"}
width: preferencesScrollView.viewport.width width: preferencesScrollView.width - preferencesScrollBar.width
Label Label
{ {
@ -192,7 +203,7 @@ UM.PreferencesPage
} }
} }
NewControls.ComboBox ComboBox
{ {
id: languageComboBox id: languageComboBox
@ -255,7 +266,7 @@ UM.PreferencesPage
} }
} }
NewControls.ComboBox ComboBox
{ {
id: themeComboBox id: themeComboBox
@ -531,7 +542,7 @@ UM.PreferencesPage
} }
} }
NewControls.ComboBox ComboBox
{ {
id: cameraComboBox id: cameraComboBox
@ -688,7 +699,7 @@ UM.PreferencesPage
text: catalog.i18nc("@window:text", "Default behavior when opening a project file: ") text: catalog.i18nc("@window:text", "Default behavior when opening a project file: ")
} }
NewControls.ComboBox ComboBox
{ {
id: choiceOnOpenProjectDropDownButton id: choiceOnOpenProjectDropDownButton
width: Math.round(250 * screenScaleFactor) 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: ") text: catalog.i18nc("@window:text", "Default behavior for changed setting values when switching to a different profile: ")
} }
NewControls.ComboBox ComboBox
{ {
id: choiceOnProfileOverrideDropDownButton id: choiceOnProfileOverrideDropDownButton
width: Math.round(250 * screenScaleFactor) width: Math.round(250 * screenScaleFactor)
@ -858,7 +869,7 @@ UM.PreferencesPage
} }
} }
ExclusiveGroup { id: curaUpdatesGroup } OldControls.ExclusiveGroup { id: curaUpdatesGroup }
UM.TooltipArea UM.TooltipArea
{ {
width: childrenRect.width width: childrenRect.width
@ -866,7 +877,7 @@ UM.PreferencesPage
text: catalog.i18nc("@info:tooltip", "When checking for updates, only check for stable releases.") text: catalog.i18nc("@info:tooltip", "When checking for updates, only check for stable releases.")
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.leftMargin: UM.Theme.getSize("default_margin").width
RadioButton OldControls.RadioButton
{ {
text: catalog.i18nc("@option:radio", "Stable releases only") text: catalog.i18nc("@option:radio", "Stable releases only")
exclusiveGroup: curaUpdatesGroup 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.") text: catalog.i18nc("@info:tooltip", "When checking for updates, check for both stable and for beta releases.")
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.leftMargin: UM.Theme.getSize("default_margin").width
RadioButton OldControls.RadioButton
{ {
text: catalog.i18nc("@option:radio", "Stable and Beta releases") text: catalog.i18nc("@option:radio", "Stable and Beta releases")
exclusiveGroup: curaUpdatesGroup 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 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.Layouts 1.3
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import UM 1.2 as UM import UM 1.5 as UM
import Cura 1.5 as Cura import Cura 1.5 as Cura
Item Item
@ -102,7 +103,7 @@ Item
height: childrenRect.height height: childrenRect.height
// Activate button // Activate button
Button OldControls.Button
{ {
id: activateMenuButton id: activateMenuButton
text: catalog.i18nc("@action:button", "Activate") text: catalog.i18nc("@action:button", "Activate")
@ -120,7 +121,7 @@ Item
} }
// Create button // Create button
Button OldControls.Button
{ {
id: createMenuButton id: createMenuButton
text: catalog.i18nc("@action:button", "Create") text: catalog.i18nc("@action:button", "Create")
@ -135,7 +136,7 @@ Item
} }
// Duplicate button // Duplicate button
Button OldControls.Button
{ {
id: duplicateMenuButton id: duplicateMenuButton
text: catalog.i18nc("@action:button", "Duplicate"); text: catalog.i18nc("@action:button", "Duplicate");
@ -150,7 +151,7 @@ Item
} }
// Remove button // Remove button
Button OldControls.Button
{ {
id: removeMenuButton id: removeMenuButton
text: catalog.i18nc("@action:button", "Remove") text: catalog.i18nc("@action:button", "Remove")
@ -165,7 +166,7 @@ Item
} }
// Import button // Import button
Button OldControls.Button
{ {
id: importMenuButton id: importMenuButton
text: catalog.i18nc("@action:button", "Import") text: catalog.i18nc("@action:button", "Import")
@ -179,7 +180,7 @@ Item
} }
// Export button // Export button
Button OldControls.Button
{ {
id: exportMenuButton id: exportMenuButton
text: catalog.i18nc("@action:button", "Export") text: catalog.i18nc("@action:button", "Export")
@ -193,7 +194,7 @@ Item
} }
//Sync button. //Sync button.
Button OldControls.Button
{ {
id: syncMaterialsButton id: syncMaterialsButton
text: catalog.i18nc("@action:button Sending materials to printers", "Sync with Printers") text: catalog.i18nc("@action:button Sending materials to printers", "Sync with Printers")
@ -207,7 +208,8 @@ Item
} }
} }
Item { Item
{
id: contentsItem id: contentsItem
anchors anchors
{ {
@ -271,22 +273,26 @@ Item
bottom: parent.bottom bottom: parent.bottom
left: parent.left left: parent.left
} }
Rectangle
{
parent: viewport
anchors.fill: parent
color: palette.light
}
width: (parent.width * 0.4) | 0 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 MaterialsList
{ {
id: materialListView 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. //Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.15 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") 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 width: parent.width
Layout.preferredWidth: width Layout.preferredWidth: width
Layout.fillHeight: true Layout.fillHeight: true
clip: true clip: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.vertical: UM.ScrollBar
ListView
{ {
id: printerList id: printerListScrollBar
width: parent.width }
spacing: UM.Theme.getSize("default_margin").height spacing: UM.Theme.getSize("default_margin").height
model: cloudPrinterList model: cloudPrinterList
delegate: Rectangle 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 var printer_id = model.metadata["host_guid"]
color: "transparent" if(syncModel.printerStatus[printer_id] === undefined) //No status information available. Could be added after we started syncing.
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"] return "idle";
if(syncModel.printerStatus[printer_id] === undefined) //No status information available. Could be added after we started syncing. }
{ 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 text: model.name
{ font: UM.Theme.getFont("medium")
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 source: UM.Theme.getIcon("Printer", "medium")
font: UM.Theme.getFont("medium") iconColor: UM.Theme.getColor("machine_selector_printer_icon")
iconSize: UM.Theme.getSize("machine_selector_icon").width
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
}
}
}
//Printer status badge (always cloud, but whether it's online or offline).
UM.RecolorImage UM.RecolorImage
{ {
id: printerSpinner width: UM.Theme.getSize("printer_status_icon").width
width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("printer_status_icon").height
height: width anchors
anchors.verticalCenter: parent.verticalCenter {
anchors.right: parent.right bottom: parent.bottom
anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below. bottomMargin: -Math.round(height / 6)
left: parent.left
leftMargin: parent.iconSize - Math.round(width * 5 / 6)
}
visible: delegateContainer.syncStatus === "uploading" source: UM.Theme.getIcon("CloudBadge", "low")
source: UM.Theme.getIcon("ArrowDoubleCircleRight")
color: UM.Theme.getColor("primary") color: UM.Theme.getColor("primary")
RotationAnimator //Make a themeable circle in the background so we can change it in other themes.
Rectangle
{ {
target: printerSpinner anchors.centerIn: parent
from: 0 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.
to: 360 height: parent.height - 1.5
duration: 1000 radius: width / 2
loops: Animation.Infinite color: UM.Theme.getColor("connection_badge_background")
running: true 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 id: printerSpinner
height: { width: UM.Theme.getSize("section_icon").width
if(!visible) height: width
{ anchors.verticalCenter: parent.verticalCenter
return 0; anchors.right: parent.right
} anchors.rightMargin: Math.round((parent.height - height) / 2) //Same margin on the right as above and below.
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: delegateContainer.syncStatus === "uploading"
} source: UM.Theme.getIcon("ArrowDoubleCircleRight")
visible: includeOfflinePrinterList.count - cloudPrinterList.count > 0 && typeof syncModel !== "undefined" && syncModel.exportUploadStatus === "idle" color: UM.Theme.getColor("primary")
Rectangle
RotationAnimator
{ {
anchors.fill: parent target: printerSpinner
anchors.topMargin: UM.Theme.getSize("default_margin").height 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") visible: delegateContainer.syncStatus === "failed" || delegateContainer.syncStatus === "success"
border.width: UM.Theme.getSize("default_lining").width status: delegateContainer.syncStatus === "success" ? UM.StatusIcon.Status.POSITIVE : UM.StatusIcon.Status.ERROR
color: "transparent" }
}
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 id: printersMissingText
margins: Math.round(UM.Theme.getSize("card").height - UM.Theme.getSize("machine_selector_icon").width) / 2 //Same margin as in other cards. 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 Cura.TertiaryButton
UM.StatusIcon
{ {
id: infoIcon id: printerListTroubleshooting
width: UM.Theme.getSize("section_icon").width leftPadding: 0 //Want to visually align this to the text.
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 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 Cura.SecondaryButton
{ {
//Fill the total width. Can't use layouts because we need the anchors for vertical alignment. id: refreshListButton
width: parent.width - infoIcon.width - refreshListButton.width - parent.spacing * 2 //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 text: catalog.i18nc("@button", "Refresh List")
iconSource: UM.Theme.getIcon("ArrowDoubleCircleRight")
UM.Label onClicked: Cura.API.account.sync(true)
{
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)
}
} }
} }
} }

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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 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 QtQuick.Dialogs 1.2
import UM 1.2 as UM import UM 1.5 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
import ".." // Access to ReadOnlyTextArea.qml import ".." // Access to ReadOnlyTextArea.qml
TabView Item
{ {
id: base id: base
@ -67,400 +68,419 @@ TabView
} }
} }
Tab UM.TabRow
{ {
title: catalog.i18nc("@title", "Information") id: pageSelectorTabRow
UM.TabRowButton
anchors.margins: UM.Theme.getSize("default_margin").width
ScrollView
{ {
id: scrollView text: catalog.i18nc("@title", "Information")
anchors.fill: parent property string activeView: "information" //To determine which page gets displayed.
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff }
flickableItem.flickableDirection: Flickable.VerticalFlick UM.TabRowButton
frameVisible: true {
text: catalog.i18nc("@label", "Print settings")
property real columnWidth: (viewport.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0 property string activeView: "settings"
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);
}
} }
} }
Tab ScrollView
{ {
title: catalog.i18nc("@label", "Print settings") id: informationPage
anchors anchors
{ {
leftMargin: UM.Theme.getSize("default_margin").width top: pageSelectorTabRow.bottom
topMargin: UM.Theme.getSize("default_margin").height left: parent.left
bottomMargin: UM.Theme.getSize("default_margin").height right: parent.right
rightMargin: 0 bottom: parent.bottom
} }
ScrollView ScrollBar.vertical: UM.ScrollBar
{ {
anchors.fill: parent; parent: informationPage
anchors
ListView
{ {
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: "" base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
expanded: ["*"] // 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 base.properties.diameter = old_diameter_value;
height: childrenRect.height diameterSpinBox.value = Qt.binding(function() { return base.properties.diameter })
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) 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 anchors.fill: parent
containerId: base.containerId onClicked: colorDialog.open()
watchedProperties: [ "value" ] enabled: base.editingEnabled
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
} }
} }
// 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. //Copyright (c) 2022 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher. //Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 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.Layouts 1.3
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import UM 1.2 as UM import UM 1.5 as UM
import Cura 1.6 as Cura import Cura 1.6 as Cura
@ -78,7 +79,7 @@ Item
height: childrenRect.height height: childrenRect.height
// Activate button // Activate button
Button OldControls.Button
{ {
id: activateMenuButton id: activateMenuButton
text: catalog.i18nc("@action:button", "Activate") text: catalog.i18nc("@action:button", "Activate")
@ -98,7 +99,7 @@ Item
} }
// Create button // Create button
Button OldControls.Button
{ {
id: createMenuButton id: createMenuButton
text: catalog.i18nc("@label", "Create") text: catalog.i18nc("@label", "Create")
@ -115,7 +116,7 @@ Item
} }
// Duplicate button // Duplicate button
Button OldControls.Button
{ {
id: duplicateMenuButton id: duplicateMenuButton
text: catalog.i18nc("@label", "Duplicate") text: catalog.i18nc("@label", "Duplicate")
@ -132,7 +133,7 @@ Item
} }
// Remove button // Remove button
Button OldControls.Button
{ {
id: removeMenuButton id: removeMenuButton
text: catalog.i18nc("@action:button", "Remove") text: catalog.i18nc("@action:button", "Remove")
@ -146,7 +147,7 @@ Item
} }
// Rename button // Rename button
Button OldControls.Button
{ {
id: renameMenuButton id: renameMenuButton
text: catalog.i18nc("@action:button", "Rename") text: catalog.i18nc("@action:button", "Rename")
@ -161,7 +162,7 @@ Item
} }
// Import button // Import button
Button OldControls.Button
{ {
id: importMenuButton id: importMenuButton
text: catalog.i18nc("@action:button", "Import") text: catalog.i18nc("@action:button", "Import")
@ -173,7 +174,7 @@ Item
} }
// Export button // Export button
Button OldControls.Button
{ {
id: exportMenuButton id: exportMenuButton
text: catalog.i18nc("@action:button", "Export") text: catalog.i18nc("@action:button", "Export")
@ -397,13 +398,13 @@ Item
} }
visible: text != "" visible: text != ""
text: catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachine.name) text: catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachine.name)
width: profileScrollView.width width: profileBackground.width
elide: Text.ElideRight elide: Text.ElideRight
} }
ScrollView Rectangle
{ {
id: profileScrollView id: profileBackground
anchors anchors
{ {
top: captionLabel.visible ? captionLabel.bottom : parent.top top: captionLabel.visible ? captionLabel.bottom : parent.top
@ -411,22 +412,20 @@ Item
bottom: parent.bottom bottom: parent.bottom
left: parent.left left: parent.left
} }
width: (parent.width * 0.4) | 0
Rectangle color: palette.light
{
parent: viewport
anchors.fill: parent
color: palette.light
}
width: true ? (parent.width * 0.4) | 0 : parent.width
frameVisible: true
clip: true
ListView ListView
{ {
id: qualityListView id: qualityListView
anchors.fill: parent
ScrollBar.vertical: UM.ScrollBar
{
id: profileScrollBar
}
clip: true
model: base.qualityManagementModel model: base.qualityManagementModel
Component.onCompleted: Component.onCompleted:
@ -461,7 +460,7 @@ Item
delegate: Rectangle delegate: Rectangle
{ {
width: profileScrollView.width width: profileBackground.width - profileScrollBar.width
height: childrenRect.height height: childrenRect.height
// Added this property to identify custom profiles in automated system tests (Squish) // Added this property to identify custom profiles in automated system tests (Squish)
@ -513,16 +512,24 @@ Item
anchors anchors
{ {
left: profileScrollView.right left: profileBackground.right
leftMargin: UM.Theme.getSize("default_margin").width leftMargin: UM.Theme.getSize("default_margin").width
top: parent.top top: parent.top
bottom: parent.bottom bottom: parent.bottom
right: parent.right 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 visible: base.currentItem != null
Item // Profile title Label Item // Profile title Label
@ -546,16 +553,14 @@ Item
Flow Flow
{ {
id: currentSettingsActions id: currentSettingsActions
width: parent.width
visible: base.hasCurrentItem && base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName && base.currentItem.intent_category == Cura.MachineManager.activeIntentCategory 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 Button
{ {
text: catalog.i18nc("@action:button", "Update profile with current settings/overrides") 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() onClicked: Cura.ContainerManager.updateQualityChanges()
} }
@ -567,62 +572,57 @@ Item
} }
} }
Column Label
{ {
id: profileNotices id: defaultsMessage
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top visible: false
anchors.topMargin: UM.Theme.getSize("default_margin").height text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.")
anchors.left: parent.left wrapMode: Text.WordWrap
anchors.right: parent.right width: parent.width
spacing: UM.Theme.getSize("default_margin").height }
Label
Label {
{ id: noCurrentSettingsMessage
id: defaultsMessage visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings
visible: false text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
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
wrapMode: Text.WordWrap width: parent.width
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 id: profileExtruderTabs
anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top UM.TabRowButton //One extra tab for the global settings.
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.right: parent.right
anchors.bottom: parent.bottom
currentIndex: 0
ProfileTab
{ {
title: catalog.i18nc("@title:tab", "Global Settings") text: catalog.i18nc("@title:tab", "Global Settings")
qualityItem: base.currentItem
} }
Repeater Repeater
{ {
model: base.extrudersModel model: base.extrudersModel
ProfileTab UM.TabRowButton
{ {
title: model.name text: model.name
extruderPosition: model.index
qualityItem: base.currentItem
} }
} }
} }
} }
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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.1 import QtQuick 2.1
import QtQuick.Controls 1.1 import QtQuick.Controls 2.15
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 as OldControls
import QtQuick.Controls 2.3 as NewControls import UM 1.5 as UM
import UM 1.2 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
@ -36,7 +34,7 @@ UM.PreferencesPage
id: base; id: base;
anchors.fill: parent; anchors.fill: parent;
CheckBox OldControls.CheckBox
{ {
id: toggleVisibleSettings id: toggleVisibleSettings
anchors anchors
@ -98,7 +96,7 @@ UM.PreferencesPage
onTextChanged: definitionsModel.filter = {"i18n_label|i18n_description": "*" + text} onTextChanged: definitionsModel.filter = {"i18n_label|i18n_description": "*" + text}
} }
NewControls.ComboBox ComboBox
{ {
id: visibilityPreset id: visibilityPreset
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
@ -106,7 +104,7 @@ UM.PreferencesPage
{ {
top: parent.top top: parent.top
right: parent.right right: parent.right
bottom: scrollView.top bottom: settingsListView.top
} }
model: settingVisibilityPresetsModel.items model: settingVisibilityPresetsModel.items
@ -133,12 +131,9 @@ UM.PreferencesPage
} }
} }
ScrollView ListView
{ {
id: scrollView id: settingsListView
frameVisible: true
anchors anchors
{ {
top: filter.bottom; top: filter.bottom;
@ -147,42 +142,41 @@ UM.PreferencesPage
right: parent.right; right: parent.right;
bottom: parent.bottom; 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 switch(model.type)
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) case "category":
{ return settingVisibilityCategory
case "category": default:
return settingVisibilityCategory return settingVisibilityItem
default:
return settingVisibilityItem
}
} }
} }
} }

View file

@ -1,5 +1,5 @@
// Copyright (c) 2018 Ultimaker B.V. //Copyright (c) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. //Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
@ -213,6 +213,7 @@ Item
model: extrudersModel model: extrudersModel
delegate: UM.TabRowButton delegate: UM.TabRowButton
{ {
checked: model.index == 0
contentItem: Item contentItem: Item
{ {
Cura.ExtruderIcon 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -43,17 +43,29 @@ Popup
// This repeater adds the intent labels // This repeater adds the intent labels
ScrollView ScrollView
{ {
id: qualityListScrollView
property real maximumHeight: screenScaleFactor * 400 property real maximumHeight: screenScaleFactor * 400
contentHeight: dataColumn.height contentHeight: dataColumn.height
height: Math.min(contentHeight, maximumHeight) 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 Column
{ {
id: dataColumn id: dataColumn
width: parent.width width: qualityListScrollView.width - qualityListScrollBar.width
Repeater Repeater
{ {
model: dataModel model: dataModel
@ -64,7 +76,7 @@ Popup
property variant subItemModel: model.qualities property variant subItemModel: model.qualities
height: childrenRect.height height: childrenRect.height
width: popup.contentWidth width: dataColumn.width
UM.Label UM.Label
{ {
@ -137,7 +149,7 @@ Popup
Item Item
{ {
height: childrenRect.height height: childrenRect.height
width: popup.contentWidth width: dataColumn.width
UM.Label 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4 as OldControls
import QtQuick.Controls 2.3 as Controls2 import QtQuick.Controls 2.3
import UM 1.5 as UM import UM 1.5 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
@ -73,7 +73,7 @@ Item
} }
} }
Controls2.ComboBox ComboBox
{ {
id: supportExtruderCombobox id: supportExtruderCombobox
@ -200,7 +200,7 @@ Item
} }
} }
contentItem:UM.Label contentItem: UM.Label
{ {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left anchors.left: parent.left
@ -229,7 +229,7 @@ Item
} }
} }
popup: Controls2.Popup popup: Popup
{ {
y: supportExtruderCombobox.height - UM.Theme.getSize("default_lining").height y: supportExtruderCombobox.height - UM.Theme.getSize("default_lining").height
width: supportExtruderCombobox.width width: supportExtruderCombobox.width
@ -238,12 +238,12 @@ Item
contentItem: ListView contentItem: ListView
{ {
clip: true
implicitHeight: contentHeight implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: supportExtruderCombobox.popup.visible ? supportExtruderCombobox.delegateModel : null model: supportExtruderCombobox.popup.visible ? supportExtruderCombobox.delegateModel : null
currentIndex: supportExtruderCombobox.highlightedIndex currentIndex: supportExtruderCombobox.highlightedIndex
Controls2.ScrollIndicator.vertical: Controls2.ScrollIndicator { }
} }
background: Rectangle background: Rectangle
@ -253,7 +253,7 @@ Item
} }
} }
delegate: Controls2.ItemDelegate delegate: ItemDelegate
{ {
width: supportExtruderCombobox.width - 2 * UM.Theme.getSize("default_lining").width width: supportExtruderCombobox.width - 2 * UM.Theme.getSize("default_lining").width
height: supportExtruderCombobox.height 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import UM 1.2 as UM import UM 1.5 as UM
import Cura 1.1 as Cura import Cura 1.1 as Cura
Cura.ExpandablePopup Cura.ExpandablePopup
@ -193,42 +193,27 @@ Cura.ExpandablePopup
{ {
id: popup id: popup
width: UM.Theme.getSize("machine_selector_widget_content").width 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 id: machineSelectorList
width: parent.width anchors
clip: true
leftPadding: UM.Theme.getSize("default_lining").width
rightPadding: UM.Theme.getSize("default_lining").width
MachineSelectorList
{ {
id: machineSelectorList left: parent.left
// Can't use parent.width since the parent is the flickable component and not the ScrollView leftMargin: UM.Theme.getSize("default_lining").width
width: scroll.width - scroll.leftPadding - scroll.rightPadding right: parent.right
property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height rightMargin: UM.Theme.getSize("default_lining").width
top: parent.top
// We use an extra property here, since we only want to to be informed about the content size changes. bottom: separator.top
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
}
} }
clip: true
} }
Rectangle Rectangle
{ {
id: separator id: separator
anchors.bottom: buttonRow.top
anchors.top: scroll.bottom
width: parent.width width: parent.width
height: UM.Theme.getSize("default_lining").height height: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining") color: UM.Theme.getColor("lining")
@ -238,8 +223,7 @@ Cura.ExpandablePopup
{ {
id: buttonRow id: buttonRow
// The separator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar. anchors.bottom: parent.bottom
anchors.top: separator.top
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
padding: UM.Theme.getSize("default_margin").width padding: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width

View file

@ -14,10 +14,15 @@ ListView
section.property: "hasRemoteConnection" section.property: "hasRemoteConnection"
property real contentHeight: childrenRect.height property real contentHeight: childrenRect.height
ScrollBar.vertical: UM.ScrollBar
{
id: scrollBar
}
section.delegate: UM.Label section.delegate: UM.Label
{ {
text: section == "true" ? catalog.i18nc("@label", "Connected printers") : catalog.i18nc("@label", "Preset printers") 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 height: UM.Theme.getSize("action_button").height
leftPadding: UM.Theme.getSize("default_margin").width leftPadding: UM.Theme.getSize("default_margin").width
font: UM.Theme.getFont("medium") font: UM.Theme.getFont("medium")
@ -27,7 +32,7 @@ ListView
delegate: MachineSelectorButton delegate: MachineSelectorButton
{ {
text: model.name ? model.name : "" text: model.name ? model.name : ""
width: listView.width width: listView.width - scrollBar.width
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
checked: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.id == model.id : false 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. // Uranium is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
@ -178,12 +178,12 @@ SettingItem
contentItem: ListView contentItem: ListView
{ {
clip: true
implicitHeight: contentHeight implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: control.popup.visible ? control.delegateModel : null model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
} }
background: Rectangle 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
@ -181,12 +181,12 @@ SettingItem
contentItem: ListView contentItem: ListView
{ {
clip: true
implicitHeight: contentHeight implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: control.popup.visible ? control.delegateModel : null model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
} }
background: Rectangle { 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
@ -191,6 +191,7 @@ Item
} }
clip: true clip: true
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item. cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
ScrollBar.vertical: UM.ScrollBar {}
model: UM.SettingDefinitionsModel model: UM.SettingDefinitionsModel
{ {

View file

@ -1,67 +1,217 @@
// Copyright (C) 2021 Ultimaker B.V. //Copyright (C) 2022 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. //Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import Qt.labs.qmlmodels 1.0
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 2.15
import QtQuick.Controls 2.3 import QtQuick.Controls 2.15
import QtQuick.Controls.Styles 1.4
import UM 1.5 as UM 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 id: tableBase
{
height: tableCellLabel.implicitHeight
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 id: headerRepeater
color: styleData.selected ? UM.Theme.getColor("primary_button_text") : UM.Theme.getColor("text") model: columnHeaders
elide: Text.ElideRight Rectangle
text: styleData.value {
anchors.fill: parent width: Math.max(1, Math.round(tableBase.width / headerRepeater.count))
anchors.leftMargin: 10 * screenScaleFactor 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") id: tableView
height: UM.Theme.getSize("table_row").height 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 Connections
style: TableViewStyle
{ {
backgroundColor: UM.Theme.getColor("main_background") target: model
function onRowsChanged()
handle: Rectangle
{ {
// Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars let first_column = model.columns[0].display;
implicitWidth: UM.Theme.getSize("scrollbar").width if(model.rows.length > 0 && model.rows[0][first_column].startsWith("<b>")) //First item is already a section header.
implicitHeight: UM.Theme.getSize("scrollbar").width {
radius: width / 2 return; //Assume we already added section headers. Prevent infinite recursion.
color: UM.Theme.getColor(styleData.pressed ? "scrollbar_handle_down" : (styleData.hovered ? "scrollbar_handle_hover" : "scrollbar_handle")) }
} if(sectionRole === "" || model.rows.length == 0) //No section headers, or no items at all.
{
tableView.model.rows = model.rows;
return;
}
scrollBarBackground: Rectangle //Insert section headers in the rows.
{ let last_section = "";
// Both implicit width and height have to be set, since the handle is used by both the horizontal and the vertical scrollbars let new_rows = [];
implicitWidth: UM.Theme.getSize("scrollbar").width for(let i = 0; i < model.rows.length; ++i)
implicitHeight: UM.Theme.getSize("scrollbar").width {
color: UM.Theme.getColor("main_background") 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import UM 1.3 as UM import UM 1.5 as UM
import Cura 1.7 as Cura import Cura 1.7 as Cura
@ -22,7 +22,7 @@ Item
property bool searchingForCloudPrinters: true property bool searchingForCloudPrinters: true
property var discoveredCloudPrintersModel: CuraApplication.getDiscoveredCloudPrintersModel() 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 Item
{ {
id: cloudPrintersContent id: cloudPrintersContent
@ -126,14 +126,9 @@ Item
// The scrollView that contains the list of newly discovered Ultimaker Cloud printers. Visible only when // The scrollView that contains the list of newly discovered Ultimaker Cloud printers. Visible only when
// there is at least a new cloud printer. // there is at least a new cloud printer.
ScrollView ListView
{ {
id: discoveredCloudPrintersScrollView id: discoveredCloudPrintersList
width: parent.width
clip : true
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AsNeeded
visible: discoveredCloudPrintersModel.count > 0
anchors anchors
{ {
top: cloudPrintersAddedTitle.bottom top: cloudPrintersAddedTitle.bottom
@ -144,52 +139,47 @@ Item
bottom: parent.bottom 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 width: discoveredCloudPrintersList.width
spacing: 2 * UM.Theme.getSize("default_margin").height height: contentColumn.height
Repeater Column
{ {
id: discoveredCloudPrintersRepeater id: contentColumn
model: discoveredCloudPrintersModel Label
delegate: Item
{ {
width: discoveredCloudPrintersScrollView.width id: cloudPrinterNameLabel
height: contentColumn.height leftPadding: UM.Theme.getSize("default_margin").width
text: model.name ? model.name : ""
Column font: UM.Theme.getFont("large_bold")
{ color: UM.Theme.getColor("text")
id: contentColumn elide: Text.ElideRight
Label }
{ Label
id: cloudPrinterNameLabel {
leftPadding: UM.Theme.getSize("default_margin").width id: cloudPrinterTypeLabel
text: model.name leftPadding: 2 * UM.Theme.getSize("default_margin").width
font: UM.Theme.getFont("large_bold") topPadding: UM.Theme.getSize("thin_margin").height
color: UM.Theme.getColor("text") text: {"Type: " + model.machine_type}
elide: Text.ElideRight font: UM.Theme.getFont("medium")
} color: UM.Theme.getColor("text")
Label elide: Text.ElideRight
{ }
id: cloudPrinterTypeLabel Label
leftPadding: 2 * UM.Theme.getSize("default_margin").width {
topPadding: UM.Theme.getSize("thin_margin").height id: cloudPrinterFirmwareVersionLabel
text: {"Type: " + model.machine_type} leftPadding: 2 * UM.Theme.getSize("default_margin").width
font: UM.Theme.getFont("medium") text: {"Firmware version: " + model.firmware_version}
color: UM.Theme.getColor("text") font: UM.Theme.getFont("medium")
elide: Text.ElideRight 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -74,118 +74,93 @@ Item
Row Row
{ {
id: localPrinterSelectionItem id: localPrinterSelectionItem
anchors.left: parent.left anchors.fill: parent
anchors.right: parent.right
anchors.top: parent.top
// ScrollView + ListView for selecting a local printer to add //Selecting a local printer to add from this list.
Cura.ScrollView ListView
{ {
id: scrollView id: machineList
height: childrenHeight
width: Math.floor(parent.width * 0.48) width: Math.floor(parent.width * 0.48)
height: parent.height
ListView clip: true
ScrollBar.vertical: UM.ScrollBar {}
model: UM.DefinitionContainersModel
{ {
id: machineList id: machineDefinitionsModel
filter: { "visible": true }
// CURA-6793 sectionProperty: "manufacturer"
// Enabling the buffer seems to cause the blank items issue. When buffer is enabled, if the ListView's preferredSections: preferredCategories
// 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
} }
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 anchors.fill: parent
width: ListView.view.width color: isActive ? UM.Theme.getColor("setting_control_highlight") : "transparent"
}
contentItem: Item
{
width: childrenRect.width
height: UM.Theme.getSize("action_button").height height: UM.Theme.getSize("action_button").height
text: section
property bool isActive: base.currentSection == section UM.RecolorImage
background: Rectangle
{ {
anchors.fill: parent id: arrow
color: isActive ? UM.Theme.getColor("setting_control_highlight") : "transparent" 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 id: label
height: UM.Theme.getSize("action_button").height anchors.left: arrow.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
UM.RecolorImage text: button.text
{ font: UM.Theme.getFont("default_bold")
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")
}
} }
}
onClicked: onClicked:
{ {
base.currentSection = section base.currentSection = section
base.updateCurrentItemUponSectionChange() base.updateCurrentItemUponSectionChange()
}
} }
} }
Component delegate: Cura.RadioButton
{ {
id: machineButton id: radioButton
anchors
Cura.RadioButton
{ {
id: radioButton left: parent !== null ? parent.left : undefined
anchors 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 right: parent !== null ? parent.right : undefined
rightMargin: UM.Theme.getSize("default_margin").width 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
} }
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 id: verticalLine
anchors.top: parent.top 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 width: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining") 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -45,11 +45,9 @@ Item
} }
contentComponent: networkPrinterListComponent contentComponent: networkPrinterListComponent
Component Component
{ {
id: networkPrinterListComponent id: networkPrinterListComponent
AddNetworkPrinterScrollView AddNetworkPrinterScrollView
{ {
id: networkPrinterScrollView id: networkPrinterScrollView
@ -95,20 +93,13 @@ Item
} }
contentComponent: localPrinterListComponent contentComponent: localPrinterListComponent
Component Component
{ {
id: localPrinterListComponent id: localPrinterListComponent
AddLocalPrinterScrollView AddLocalPrinterScrollView
{ {
id: localPrinterView id: localPrinterView
property int childrenHeight: backButton.y - addLocalPrinterDropDown.y - UM.Theme.getSize("expandable_component_content_header").height - UM.Theme.getSize("default_margin").height height: backButton.y - addLocalPrinterDropDown.y - UM.Theme.getSize("expandable_component_content_header").height - UM.Theme.getSize("default_margin").height
onChildrenHeightChanged:
{
addLocalPrinterDropDown.children[1].height = childrenHeight
}
} }
} }
} }

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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -17,7 +17,7 @@ Item
id: base id: base
height: networkPrinterInfo.height + controlsRectangle.height height: networkPrinterInfo.height + controlsRectangle.height
property alias maxItemCountAtOnce: networkPrinterScrollView.maxItemCountAtOnce property alias maxItemCountAtOnce: networkPrinterListView.maxItemCountAtOnce
property var currentItem: (networkPrinterListView.currentIndex >= 0) property var currentItem: (networkPrinterListView.currentIndex >= 0)
? networkPrinterListView.model[networkPrinterListView.currentIndex] ? networkPrinterListView.model[networkPrinterListView.currentIndex]
: null : null
@ -29,7 +29,7 @@ Item
Item Item
{ {
id: networkPrinterInfo id: networkPrinterInfo
height: networkPrinterScrollView.visible ? networkPrinterScrollView.height : noPrinterLabel.height height: networkPrinterListView.visible ? networkPrinterListView.height : noPrinterLabel.height
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
@ -44,104 +44,90 @@ Item
visible: networkPrinterListView.count == 0 // Do not show if there are discovered devices. visible: networkPrinterListView.count == 0 // Do not show if there are discovered devices.
} }
ScrollView ListView
{ {
id: networkPrinterScrollView id: networkPrinterListView
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right 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) 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 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.left: parent.left
anchors.fill: parent anchors.leftMargin: UM.Theme.getSize("default_margin").width
model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined 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" Component.onCompleted:
section.criteria: ViewSection.FullString {
section.delegate: sectionHeading var toSelectIndex = -1
boundsBehavior: Flickable.StopAtBounds // Select the first one that's not "unknown" and is the host a group by default.
flickDeceleration: 20000 // To prevent the flicking behavior. for (var i = 0; i < count; i++)
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
Component.onCompleted:
{ {
var toSelectIndex = -1 if (!model[i].isUnknownMachineType && model[i].isHostOfGroup)
// 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) toSelectIndex = i
{ break
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
} }
} }
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 delegate: Cura.MachineSelectorButton
{ {
anchors.left: parent.left text: modelData.device.name
anchors.leftMargin: UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height width: networkPrinterListView.width - networkPrinterScrollBar.width
text: section outputDevice: modelData.device
color: UM.Theme.getColor("small_button_text")
} 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 networkPrinterListView.currentIndex = index
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
}
} }
} }
} }

View file

@ -37,8 +37,6 @@ Item
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
textArea.text: CuraApplication.getTextManager().getChangeLogText() textArea.text: CuraApplication.getTextManager().getChangeLogText()
textArea.textFormat: Text.RichText textArea.textFormat: Text.RichText
textArea.wrapMode: Text.WordWrap 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -61,7 +61,7 @@ Item
anchors.left: header.left anchors.left: header.left
anchors.right: header.right anchors.right: header.right
// Add 2x lining, because it needs a bit of space on the top and the bottom. // 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.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining") border.color: UM.Theme.getColor("lining")

View file

@ -113,8 +113,6 @@ Item
right: subpageImage.right right: subpageImage.right
} }
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
back_color: UM.Theme.getColor("viewport_overlay") back_color: UM.Theme.getColor("viewport_overlay")
do_borders: false 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -100,12 +100,12 @@ ComboBox
contentItem: ListView contentItem: ListView
{ {
clip: true
implicitHeight: contentHeight implicitHeight: contentHeight
ScrollBar.vertical: UM.ScrollBar {}
clip: true
model: control.popup.visible ? control.delegateModel : null model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
} }
background: Rectangle 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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import UM 1.3 as UM import UM 1.5 as UM
import Cura 1.1 as Cura import Cura 1.1 as Cura
// //
// Cura-style TextArea with scrolls // 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 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 id: flickableTextArea
border.color: UM.Theme.getColor("thick_lining")
border.width: do_borders ? UM.Theme.getSize("default_lining").width : 0 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") font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
textFormat: TextEdit.PlainText textFormat: TextEdit.PlainText
@ -37,4 +41,4 @@ ScrollView
wrapMode: Text.Wrap wrapMode: Text.Wrap
selectByMouse: true selectByMouse: true
} }
} }

View file

@ -4,6 +4,7 @@ MachineSelector 1.0 MachineSelector.qml
MachineSelectorButton 1.0 MachineSelectorButton.qml MachineSelectorButton 1.0 MachineSelectorButton.qml
CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml
PrintSetupSelector 1.0 PrintSetupSelector.qml PrintSetupSelector 1.0 PrintSetupSelector.qml
ProfileOverview 1.6 ProfileOverview.qml
ActionButton 1.0 ActionButton.qml ActionButton 1.0 ActionButton.qml
MaterialMenu 1.0 MaterialMenu.qml MaterialMenu 1.0 MaterialMenu.qml
NozzleMenu 1.0 NozzleMenu.qml NozzleMenu 1.0 NozzleMenu.qml