mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-09 23:05:01 -06:00
Merge branch 'main' into CURA-9622_unable_to_scroll_long_materials_list
This commit is contained in:
commit
0a4c7869e6
295 changed files with 6538 additions and 2715 deletions
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2022 Ultimaker B.V.
|
||||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.15
|
||||
|
@ -6,8 +6,8 @@ import QtQuick.Controls 2.2
|
|||
import QtQuick.Window 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.1 as Cura
|
||||
import UM 1.7 as UM
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
|
||||
/*
|
||||
|
@ -28,8 +28,11 @@ UM.Dialog
|
|||
// however with the current implementation of the dialog this is not possible, so instead we calculate
|
||||
// the size of the dialog ourselves.
|
||||
// Ugly workaround for windows having overlapping elements due to incorrect dialog width
|
||||
minimumWidth: content.width + (Qt.platform.os == "windows" ? 4 * margin : 2 * margin)
|
||||
minimumHeight: content.height + footer.height + (Qt.platform.os == "windows" ? 5 * margin : 3 * margin)
|
||||
minimumWidth: content.width + (Qt.platform.os === "windows" ? 4 * margin : 2 * margin)
|
||||
minimumHeight: {
|
||||
const footerHeight = Math.max(okButton.height, cancelButton.height);
|
||||
return content.height + footerHeight + (Qt.platform.os === "windows" ? 5 * margin : 3 * margin);
|
||||
}
|
||||
|
||||
property alias color: colorInput.text
|
||||
property var swatchColors: [
|
||||
|
@ -119,7 +122,7 @@ UM.Dialog
|
|||
text = `#${text}`;
|
||||
}
|
||||
}
|
||||
validator: RegularExpressionValidator { regularExpression: /^#([a-fA-F0-9]{0,6})$/ }
|
||||
validator: UM.HexColorValidator {}
|
||||
}
|
||||
|
||||
Rectangle
|
||||
|
@ -136,10 +139,12 @@ UM.Dialog
|
|||
rightButtons:
|
||||
[
|
||||
Cura.TertiaryButton {
|
||||
id: cancelButton
|
||||
text: catalog.i18nc("@action:button", "Cancel")
|
||||
onClicked: base.close()
|
||||
},
|
||||
Cura.PrimaryButton {
|
||||
id: okButton
|
||||
text: catalog.i18nc("@action:button", "OK")
|
||||
onClicked: base.accept()
|
||||
}
|
||||
|
|
|
@ -496,10 +496,7 @@ UM.MainWindow
|
|||
target: Cura.Actions.addProfile
|
||||
function onTriggered()
|
||||
{
|
||||
preferences.show();
|
||||
preferences.setPage(4);
|
||||
// Create a new profile after a very short delay so the preference page has time to initiate
|
||||
createProfileTimer.start();
|
||||
createNewQualityDialog.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,15 +544,6 @@ UM.MainWindow
|
|||
}
|
||||
}
|
||||
|
||||
Timer
|
||||
{
|
||||
id: createProfileTimer
|
||||
repeat: false
|
||||
interval: 1
|
||||
|
||||
onTriggered: preferences.getCurrentItem().createProfile()
|
||||
}
|
||||
|
||||
// BlurSettings is a way to force the focus away from any of the setting items.
|
||||
// We need to do this in order to keep the bindings intact.
|
||||
Connections
|
||||
|
@ -816,11 +804,16 @@ UM.MainWindow
|
|||
Connections
|
||||
{
|
||||
target: CuraApplication
|
||||
function onShowDiscardOrKeepProfileChanges()
|
||||
function onShowCompareAndSaveProfileChanges(profileState)
|
||||
{
|
||||
discardOrKeepProfileChangesDialogLoader.sourceComponent = discardOrKeepProfileChangesDialogComponent
|
||||
discardOrKeepProfileChangesDialogLoader.item.buttonState = profileState
|
||||
discardOrKeepProfileChangesDialogLoader.item.show()
|
||||
}
|
||||
function onShowDiscardOrKeepProfileChanges()
|
||||
{
|
||||
onShowCompareAndSaveProfileChanges(DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep)
|
||||
}
|
||||
}
|
||||
|
||||
Cura.WizardDialog
|
||||
|
@ -885,6 +878,49 @@ UM.MainWindow
|
|||
}
|
||||
}
|
||||
|
||||
Cura.RenameDialog
|
||||
{
|
||||
id: createNewQualityDialog
|
||||
title: catalog.i18nc("@title:window", "Save Custom Profile")
|
||||
objectPlaceholder: catalog.i18nc("@textfield:placeholder", "New Custom Profile")
|
||||
explanation: catalog.i18nc("@info", "Custom profile name:")
|
||||
extraInfo:
|
||||
[
|
||||
UM.ColorImage
|
||||
{
|
||||
width: UM.Theme.getSize("message_type_icon").width
|
||||
height: UM.Theme.getSize("message_type_icon").height
|
||||
source: UM.Theme.getIcon("Information")
|
||||
color: UM.Theme.getColor("text")
|
||||
},
|
||||
Column
|
||||
{
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc
|
||||
(
|
||||
"@label %i will be replaced with a profile name",
|
||||
"<b>Only user changed settings will be saved in the custom profile.</b><br/>" +
|
||||
"For materials that support it, the new custom profile will inherit properties from <b>%1</b>."
|
||||
).arg(Cura.MachineManager.activeQualityOrQualityChangesName)
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.parent.width - 2 * UM.Theme.getSize("message_type_icon").width
|
||||
}
|
||||
Cura.TertiaryButton
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Learn more about Cura print profiles")
|
||||
iconSource: UM.Theme.getIcon("LinkExternal")
|
||||
isIconOnRightSide: true
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
onClicked: Qt.openUrlExternally("https://support.ultimaker.com/s/article/1667337576882")
|
||||
}
|
||||
}
|
||||
]
|
||||
okButtonText: catalog.i18nc("@button", "Save new profile")
|
||||
onAccepted: CuraApplication.getQualityManagementModel().createQualityChanges(newName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check whether a QML object has a certain type.
|
||||
* Taken from StackOverflow: https://stackoverflow.com/a/28384228 and
|
||||
|
|
|
@ -12,8 +12,13 @@ UM.Dialog
|
|||
id: base
|
||||
title: catalog.i18nc("@title:window", "Discard or Keep changes")
|
||||
|
||||
onAccepted: CuraApplication.discardOrKeepProfileChangesClosed("discard")
|
||||
onRejected: CuraApplication.discardOrKeepProfileChangesClosed("keep")
|
||||
enum ButtonsType { DiscardOrKeep, SaveFromBuiltIn, SaveFromCustom}
|
||||
property int buttonState: DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
|
||||
|
||||
onAccepted: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep ?
|
||||
CuraApplication.discardOrKeepProfileChangesClosed("discard") : Cura.Actions.addProfile.trigger()
|
||||
onRejected: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep ?
|
||||
CuraApplication.discardOrKeepProfileChangesClosed("keep") : Cura.Actions.updateProfile.trigger()
|
||||
|
||||
minimumWidth: UM.Theme.getSize("popup_dialog").width
|
||||
minimumHeight: UM.Theme.getSize("popup_dialog").height
|
||||
|
@ -98,9 +103,12 @@ UM.Dialog
|
|||
|
||||
buttonSpacing: UM.Theme.getSize("thin_margin").width
|
||||
|
||||
leftButtons: [
|
||||
leftButtons:
|
||||
[
|
||||
Cura.ComboBox
|
||||
{
|
||||
visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
|
||||
|
||||
implicitHeight: UM.Theme.getSize("combobox").height
|
||||
implicitWidth: UM.Theme.getSize("combobox").width
|
||||
|
||||
|
@ -146,12 +154,28 @@ UM.Dialog
|
|||
id: discardButton
|
||||
text: catalog.i18nc("@action:button", "Discard changes")
|
||||
onClicked: base.accept()
|
||||
visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
|
||||
},
|
||||
Cura.SecondaryButton
|
||||
{
|
||||
id: keepButton
|
||||
text: catalog.i18nc("@action:button", "Keep changes")
|
||||
onClicked: base.reject()
|
||||
visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
|
||||
},
|
||||
Cura.SecondaryButton
|
||||
{
|
||||
id: overwriteButton
|
||||
text: catalog.i18nc("@action:button", "Save as new custom profile")
|
||||
visible: buttonState != DiscardOrKeepProfileChangesDialog.ButtonsType.DiscardOrKeep
|
||||
onClicked: base.accept()
|
||||
},
|
||||
Cura.PrimaryButton
|
||||
{
|
||||
id: saveButton
|
||||
text: catalog.i18nc("@action:button", "Save changes")
|
||||
visible: buttonState == DiscardOrKeepProfileChangesDialog.ButtonsType.SaveFromCustom
|
||||
onClicked: base.reject()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -15,17 +15,23 @@ UM.Dialog
|
|||
buttonSpacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
property string object: ""
|
||||
property string objectPlaceholder: ""
|
||||
|
||||
property alias newName: nameField.text
|
||||
property bool validName: true
|
||||
property string validationError
|
||||
property string dialogTitle: catalog.i18nc("@title:window", "Rename")
|
||||
property string explanation: catalog.i18nc("@info", "Please provide a new name.")
|
||||
property string okButtonText: catalog.i18nc("@action:button", "OK")
|
||||
|
||||
// Extra Information for the user about the current rename can go here, can be left alone if not needed.
|
||||
// For example; An icon and a text-field and a tertiary button providing a link.
|
||||
property list<Item> extraInfo
|
||||
|
||||
title: dialogTitle
|
||||
backgroundColor: UM.Theme.getColor("main_background")
|
||||
minimumWidth: UM.Theme.getSize("small_popup_dialog").width
|
||||
minimumHeight: UM.Theme.getSize("small_popup_dialog").height
|
||||
minimumHeight: UM.Theme.getSize("small_popup_dialog").height + extraInfoHolder.height
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
|
||||
|
@ -55,11 +61,33 @@ UM.Dialog
|
|||
id: nameField
|
||||
width: parent.width
|
||||
text: base.object
|
||||
placeholderText: base.objectPlaceholder
|
||||
placeholderTextColor: UM.Theme.getColor("text_field_text_disabled")
|
||||
maximumLength: 40
|
||||
selectByMouse: true
|
||||
onTextChanged: base.textChanged(text)
|
||||
}
|
||||
|
||||
// spacer
|
||||
Item
|
||||
{
|
||||
height: UM.Theme.getSize("wide_margin").height
|
||||
width: height
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
id: extraInfoHolder
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: UM.Theme.getSize("default_margin").height
|
||||
}
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
children: extraInfo
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
visible: !base.validName
|
||||
|
@ -67,20 +95,23 @@ UM.Dialog
|
|||
}
|
||||
}
|
||||
|
||||
rightButtons: [
|
||||
Cura.SecondaryButton
|
||||
leftButtons:
|
||||
[
|
||||
Cura.TertiaryButton
|
||||
{
|
||||
id: cancelButton
|
||||
text: catalog.i18nc("@action:button","Cancel")
|
||||
onClicked: base.reject()
|
||||
},
|
||||
}
|
||||
]
|
||||
rightButtons:
|
||||
[
|
||||
Cura.PrimaryButton
|
||||
{
|
||||
id: okButton
|
||||
text: catalog.i18nc("@action:button", "OK")
|
||||
text: base.okButtonText
|
||||
onClicked: base.accept()
|
||||
enabled: base.validName
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -12,17 +12,14 @@ UM.ToolbarButton
|
|||
id: base
|
||||
|
||||
property var extruder
|
||||
|
||||
text: catalog.i18ncp("@label %1 is filled in with the name of an extruder", "Print Selected Model with %1", "Print Selected Models with %1", UM.Selection.selectionCount).arg(extruder.name)
|
||||
|
||||
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1
|
||||
enabled: UM.Selection.hasSelection && extruder.stack.isEnabled
|
||||
property var extruderNumberFont: UM.Theme.getFont("small_emphasis")
|
||||
|
||||
toolItem: ExtruderIcon
|
||||
{
|
||||
materialColor: extruder.color
|
||||
extruderEnabled: extruder.stack.isEnabled
|
||||
iconVariant: "default"
|
||||
font: extruderNumberFont
|
||||
property int index: extruder.index
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2021 Ultimaker B.V.
|
||||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.11
|
||||
|
@ -12,8 +12,9 @@ Item
|
|||
property color materialColor
|
||||
property alias textColor: extruderNumberText.color
|
||||
property bool extruderEnabled: true
|
||||
property var iconSize: UM.Theme.getSize("extruder_icon").width
|
||||
property int iconSize: UM.Theme.getSize("extruder_icon").width
|
||||
property string iconVariant: "medium"
|
||||
property alias font: extruderNumberText.font
|
||||
|
||||
implicitWidth: iconSize
|
||||
implicitHeight: iconSize
|
||||
|
@ -35,7 +36,6 @@ Item
|
|||
}
|
||||
UM.ColorImage
|
||||
{
|
||||
id: mainIcon
|
||||
anchors.fill: parent
|
||||
width: iconSize
|
||||
height: iconSize
|
||||
|
@ -47,12 +47,14 @@ Item
|
|||
UM.Label
|
||||
{
|
||||
id: extruderNumberText
|
||||
anchors.centerIn: parent
|
||||
text: index + 1
|
||||
font: UM.Theme.getFont("small_emphasis")
|
||||
width: contentWidth
|
||||
height: contentHeight
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: (index + 1).toString()
|
||||
font: UM.Theme.getFont("small_emphasis")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,18 +68,27 @@ UM.TooltipArea
|
|||
function updateModel()
|
||||
{
|
||||
clear()
|
||||
// Options come in as a string-representation of an OrderedDict
|
||||
if(propertyProvider.properties.options)
|
||||
|
||||
if(!propertyProvider.properties.options)
|
||||
{
|
||||
var options = propertyProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/);
|
||||
if(options)
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof propertyProvider.properties["options"] === "string")
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < propertyProvider.properties["options"].keys().length; i++)
|
||||
{
|
||||
var key = propertyProvider.properties["options"].keys()[i]
|
||||
var value = propertyProvider.properties["options"][key]
|
||||
append({ text: value, code: key })
|
||||
|
||||
if (propertyProvider.properties.value === key)
|
||||
{
|
||||
options = options[1].split("), (");
|
||||
for(var i = 0; i < options.length; i++)
|
||||
{
|
||||
var option = options[i].substring(1, options[i].length - 1).split("', '");
|
||||
append({ text: option[1], value: option[0] });
|
||||
}
|
||||
comboBox.currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +132,7 @@ UM.TooltipArea
|
|||
onActivated:
|
||||
{
|
||||
var newValue = model.get(index).value
|
||||
if (propertyProvider.properties.value != newValue)
|
||||
if (propertyProvider.properties.value !== newValue && newValue !== undefined)
|
||||
{
|
||||
if (setValueFunction !== null)
|
||||
{
|
||||
|
|
|
@ -59,7 +59,7 @@ UM.TooltipArea
|
|||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: propertyProvider
|
||||
watchedProperties: [ "value", "description" ]
|
||||
watchedProperties: [ "value", "description", "validationState" ]
|
||||
}
|
||||
|
||||
UM.Label
|
||||
|
|
|
@ -52,8 +52,13 @@ Item
|
|||
id: intentSelection
|
||||
onClicked: menu.opened ? menu.close() : menu.open()
|
||||
|
||||
anchors.right: parent.right
|
||||
width: UM.Theme.getSize("print_setup_big_item").width
|
||||
// Anchoring to the right makes much more sense here, but for some reason this component compresses from the right
|
||||
// and then expands from the left afterwards. This pushes it left by profileWarningReset.width
|
||||
// The solution is to anchor from the other direction so this does not happen.
|
||||
anchors.left: parent.left
|
||||
// This leftMargin gives us the same spacing as anchoring to the right on profileWarningReset
|
||||
anchors.leftMargin: parent.width - UM.Theme.getSize("print_setup_big_item").width
|
||||
width: profileWarningReset.visible ? UM.Theme.getSize("print_setup_big_item").width - profileWarningReset.width - UM.Theme.getSize("default_margin").width : UM.Theme.getSize("print_setup_big_item").width
|
||||
height: textLabel.contentHeight + 2 * UM.Theme.getSize("narrow_margin").height
|
||||
hoverEnabled: true
|
||||
|
||||
|
@ -152,6 +157,15 @@ Item
|
|||
}
|
||||
}
|
||||
|
||||
ProfileWarningReset
|
||||
{
|
||||
id: profileWarningReset
|
||||
width: childrenRect.width
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fullWarning: false
|
||||
}
|
||||
|
||||
QualitiesWithIntentMenu
|
||||
{
|
||||
id: menu
|
||||
|
|
|
@ -223,58 +223,6 @@ Popup
|
|||
color: borderColor
|
||||
}
|
||||
|
||||
MenuButton
|
||||
{
|
||||
labelText: Cura.Actions.addProfile.text
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
enabled: Cura.Actions.addProfile.enabled
|
||||
onClicked:
|
||||
{
|
||||
Cura.Actions.addProfile.trigger()
|
||||
popup.visible = false
|
||||
}
|
||||
}
|
||||
MenuButton
|
||||
{
|
||||
labelText: Cura.Actions.updateProfile.text
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
enabled: Cura.Actions.updateProfile.enabled
|
||||
|
||||
onClicked:
|
||||
{
|
||||
popup.visible = false
|
||||
Cura.Actions.updateProfile.trigger()
|
||||
}
|
||||
}
|
||||
MenuButton
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Discard current changes")
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
enabled: Cura.MachineManager.hasUserSettings
|
||||
|
||||
onClicked:
|
||||
{
|
||||
popup.visible = false
|
||||
Cura.ContainerManager.clearUserContainers()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
height: UM.Theme.getSize("default_lining").width
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
color: borderColor
|
||||
}
|
||||
|
||||
MenuButton
|
||||
{
|
||||
id: manageProfilesButton
|
||||
|
@ -285,18 +233,19 @@ Popup
|
|||
right: parent.right
|
||||
}
|
||||
|
||||
height: textLabel.contentHeight + 2 * UM.Theme.getSize("narrow_margin").height
|
||||
height: textLabel.contentHeight + UM.Theme.getSize("default_margin").height
|
||||
|
||||
contentItem: Item
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
height: parent.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: textLabel
|
||||
text: manageProfilesButton.text
|
||||
height: contentHeight
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
|
@ -304,6 +253,7 @@ Popup
|
|||
text: Cura.Actions.manageProfiles.shortcut
|
||||
color: UM.Theme.getColor("text_lighter")
|
||||
height: contentHeight
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
|
@ -318,7 +268,7 @@ Popup
|
|||
Item
|
||||
{
|
||||
width: 2
|
||||
height: UM.Theme.getSize("default_radius").width
|
||||
height: UM.Theme.getSize("default_radius").width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,16 @@ Item
|
|||
top: parent.top
|
||||
}
|
||||
visible: currentModeIndex == PrintSetupSelectorContents.Mode.Recommended
|
||||
height: {
|
||||
const height = base.height - (customPrintSetup.mapToItem(null, 0, 0).y + buttonRow.height + UM.Theme.getSize("default_margin").height);
|
||||
const maxHeight = UM.Preferences.getValue("view/settings_list_height");
|
||||
return Math.min(implicitHeight, height, maxHeight);
|
||||
}
|
||||
|
||||
function onModeChanged()
|
||||
{
|
||||
currentModeIndex = PrintSetupSelectorContents.Mode.Custom;
|
||||
}
|
||||
}
|
||||
|
||||
CustomPrintSetup
|
||||
|
@ -116,13 +126,21 @@ Item
|
|||
width: parent.width
|
||||
height: UM.Theme.getSize("default_lining").height
|
||||
color: UM.Theme.getColor("lining")
|
||||
visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: buttonRow
|
||||
property real padding: UM.Theme.getSize("default_margin").width
|
||||
height: recommendedButton.height + 2 * padding + (draggableArea.visible ? draggableArea.height : 0)
|
||||
height:
|
||||
{
|
||||
if (currentModeIndex == PrintSetupSelectorContents.Mode.Custom)
|
||||
{
|
||||
return recommendedButton.height + 2 * padding + (draggableArea.visible ? draggableArea.height : 0)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
anchors
|
||||
{
|
||||
|
@ -145,25 +163,6 @@ Item
|
|||
onClicked: currentModeIndex = PrintSetupSelectorContents.Mode.Recommended
|
||||
}
|
||||
|
||||
Cura.SecondaryButton
|
||||
{
|
||||
id: customSettingsButton
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
leftPadding: UM.Theme.getSize("default_margin").width
|
||||
rightPadding: UM.Theme.getSize("default_margin").width
|
||||
text: catalog.i18nc("@button", "Custom")
|
||||
iconSource: UM.Theme.getIcon("ChevronSingleRight")
|
||||
isIconOnRightSide: true
|
||||
visible: currentModeIndex == PrintSetupSelectorContents.Mode.Recommended
|
||||
onClicked:
|
||||
{
|
||||
currentModeIndex = PrintSetupSelectorContents.Mode.Custom
|
||||
updateDragPosition();
|
||||
}
|
||||
}
|
||||
|
||||
//Invisible area at the bottom with which you can resize the panel.
|
||||
MouseArea
|
||||
{
|
||||
|
|
181
resources/qml/PrintSetupSelector/ProfileWarningReset.qml
Normal file
181
resources/qml/PrintSetupSelector/ProfileWarningReset.qml
Normal file
|
@ -0,0 +1,181 @@
|
|||
// Copyright (C) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
|
||||
import UM 1.6 as UM
|
||||
import Cura 1.6 as Cura
|
||||
|
||||
import "../Dialogs"
|
||||
|
||||
Item
|
||||
{
|
||||
property bool fullWarning: true // <- Can you see the warning icon and the text, or is it just the buttons?
|
||||
|
||||
height: visible ? UM.Theme.getSize("action_button_icon").height : 0
|
||||
width: visible ? childrenRect.width: 0
|
||||
visible: Cura.MachineManager.hasUserSettings || (fullWarning && Cura.MachineManager.hasCustomQuality)
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: warningIcon
|
||||
visible: fullWarning
|
||||
color: UM.Theme.getColor("warning")
|
||||
height: UM.Theme.getSize("action_button_icon").height
|
||||
width: visible ? height : 0
|
||||
radius: width
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
UM.ColorImage
|
||||
{
|
||||
id: warningIconImage
|
||||
height: UM.Theme.getSize("action_button_icon").height
|
||||
width: height
|
||||
source: UM.Theme.getIcon("Warning", "low")
|
||||
}
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: warning
|
||||
visible: fullWarning
|
||||
width: visible ? parent.width - warningIcon.width - (compareAndSaveButton.width + resetToDefaultQualityButton.width) : 0
|
||||
anchors
|
||||
{
|
||||
left: warningIcon.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: visible ? UM.Theme.getSize("thin_margin").width : 0
|
||||
}
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
states: [
|
||||
State
|
||||
{
|
||||
name: "settings changed and custom quality"
|
||||
when: Cura.MachineManager.hasUserSettings && Cura.MachineManager.hasCustomQuality
|
||||
PropertyChanges
|
||||
{
|
||||
target: warning
|
||||
text: {
|
||||
var profile_name = Cura.MachineManager.activeQualityChangesGroup.name
|
||||
return catalog.i18nc("@info, %1 is the name of the custom profile", "<b>%1</b> custom profile is active and you overwrote some settings.").arg(profile_name)
|
||||
}
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "custom quality"
|
||||
when: Cura.MachineManager.hasCustomQuality
|
||||
PropertyChanges
|
||||
{
|
||||
target: warning
|
||||
text: {
|
||||
var profile_name = Cura.MachineManager.activeQualityChangesGroup.name
|
||||
return catalog.i18nc("@info, %1 is the name of the custom profile", "<b>%1</b> custom profile is overriding some settings.").arg(profile_name)
|
||||
}
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "recommended settings changed"
|
||||
when: Cura.MachineManager.hasUserSettings
|
||||
PropertyChanges
|
||||
{
|
||||
target: warning
|
||||
text:
|
||||
{
|
||||
var profile_name = Cura.MachineManager.activeQualityOrQualityChangesName;
|
||||
return catalog.i18nc("@info %1 is the name of a profile", "Recommended settings (for <b>%1</b>) were altered.").arg(profile_name);
|
||||
}
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "custom settings changed"
|
||||
when: Cura.SimpleModeSettingsManager.isProfileCustomized
|
||||
PropertyChanges
|
||||
{
|
||||
target: warning
|
||||
text:
|
||||
{
|
||||
var profile_name = Cura.MachineManager.activeQualityOrQualityChangesName;
|
||||
return catalog.i18nc("@info %1 is the name of a profile", "Some setting-values defined in <b>%1</b> were overridden.").arg(profile_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
UM.SimpleButton
|
||||
{
|
||||
id: resetToDefaultQualityButton
|
||||
height: UM.Theme.getSize("action_button_icon").height
|
||||
width: visible ? height : 0
|
||||
iconSource: UM.Theme.getIcon("ArrowReset")
|
||||
anchors
|
||||
{
|
||||
right: buttonsSpacer.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
visible: enabled
|
||||
color: enabled ? UM.Theme.getColor("accent_1") : UM.Theme.getColor("disabled")
|
||||
hoverColor: UM.Theme.getColor("primary_hover")
|
||||
|
||||
enabled: (fullWarning && Cura.MachineManager.hasCustomQuality) || Cura.MachineManager.hasUserSettings
|
||||
onClicked: Cura.MachineManager.resetToUseDefaultQuality()
|
||||
|
||||
UM.ToolTip
|
||||
{
|
||||
visible: parent.hovered
|
||||
y: parent.y + parent.height + UM.Theme.getSize("default_margin").height
|
||||
targetPoint: Qt.point(parent.x, Math.round(parent.y + parent.height / 2))
|
||||
tooltipText: catalog.i18nc("@info", "Reset to defaults.")
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer
|
||||
Item
|
||||
{
|
||||
id: buttonsSpacer
|
||||
width: compareAndSaveButton.visible ? UM.Theme.getSize("default_margin").width : 0
|
||||
anchors.right: compareAndSaveButton.left
|
||||
}
|
||||
|
||||
UM.SimpleButton
|
||||
{
|
||||
id: compareAndSaveButton
|
||||
height: UM.Theme.getSize("action_button_icon").height
|
||||
width: visible ? height : 0
|
||||
iconSource: UM.Theme.getIcon("Save")
|
||||
anchors
|
||||
{
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
visible: enabled
|
||||
color: enabled ? UM.Theme.getColor("accent_1") : UM.Theme.getColor("disabled")
|
||||
hoverColor: UM.Theme.getColor("primary_hover")
|
||||
|
||||
enabled: Cura.MachineManager.hasUserSettings
|
||||
onClicked: CuraApplication.showCompareAndSaveProfileChanges
|
||||
(
|
||||
Cura.MachineManager.hasCustomQuality ?
|
||||
DiscardOrKeepProfileChangesDialog.ButtonsType.SaveFromCustom :
|
||||
DiscardOrKeepProfileChangesDialog.ButtonsType.SaveFromBuiltIn
|
||||
)
|
||||
|
||||
UM.ToolTip
|
||||
{
|
||||
visible: parent.hovered
|
||||
y: parent.y + parent.height + UM.Theme.getSize("default_margin").height
|
||||
targetPoint: Qt.point(parent.x, Math.round(parent.y + parent.height / 2))
|
||||
tooltipText: catalog.i18nc("@info", "Compare and save.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
import QtQuick 2.10
|
||||
|
||||
import UM 1.6 as UM
|
||||
import Cura 1.6 as Cura
|
||||
|
||||
Item
|
||||
{
|
||||
height: visible ? UM.Theme.getSize("action_button_icon").height : 0
|
||||
visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.MachineManager.hasCustomQuality
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: warningIcon
|
||||
color: UM.Theme.getColor("um_yellow_5")
|
||||
height: UM.Theme.getSize("action_button_icon").height
|
||||
width: height
|
||||
radius: width
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
UM.ColorImage
|
||||
{
|
||||
height: UM.Theme.getSize("action_button_icon").height
|
||||
width: height
|
||||
source: UM.Theme.getIcon("Warning", "low")
|
||||
}
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: warning
|
||||
width: parent.width - warningIcon.width - resetToDefaultQualityButton.width
|
||||
anchors
|
||||
{
|
||||
left: warningIcon.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: UM.Theme.getSize("thin_margin").width
|
||||
}
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
states: [
|
||||
State
|
||||
{
|
||||
name: "settings changed and custom quality"
|
||||
when: Cura.SimpleModeSettingsManager.isProfileCustomized && Cura.MachineManager.hasCustomQuality
|
||||
PropertyChanges
|
||||
{
|
||||
target: warning
|
||||
text: {
|
||||
var profile_name = Cura.MachineManager.activeQualityChangesGroup.name
|
||||
return catalog.i18nc("@info, %1 is the name of the custom profile", "<b>%1</b> custom profile is active and you overwrote some settings.").arg(profile_name)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "custom quality"
|
||||
when: Cura.MachineManager.hasCustomQuality
|
||||
PropertyChanges
|
||||
{
|
||||
target: warning
|
||||
text: {
|
||||
var profile_name = Cura.MachineManager.activeQualityChangesGroup.name
|
||||
return catalog.i18nc("@info, %1 is the name of the custom profile", "<b>%1</b> custom profile is overriding some settings.").arg(profile_name)
|
||||
}
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "settings changed"
|
||||
when: Cura.SimpleModeSettingsManager.isProfileCustomized
|
||||
PropertyChanges
|
||||
{
|
||||
target: warning
|
||||
text: catalog.i18nc("@info", "Some settings were changed.")
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
UM.SimpleButton
|
||||
{
|
||||
id: resetToDefaultQualityButton
|
||||
height: UM.Theme.getSize("action_button_icon").height
|
||||
width: height
|
||||
iconSource: UM.Theme.getIcon("ArrowReset")
|
||||
anchors
|
||||
{
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
color: UM.Theme.getColor("accent_1")
|
||||
|
||||
onClicked:
|
||||
{
|
||||
Cura.MachineManager.resetToUseDefaultQuality()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,89 +1,37 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
|
||||
//
|
||||
// Adhesion
|
||||
//
|
||||
Item
|
||||
RecommendedSettingSection
|
||||
{
|
||||
id: enableAdhesionRow
|
||||
height: enableAdhesionContainer.height
|
||||
|
||||
property real labelColumnWidth: Math.round(width / 3)
|
||||
title: catalog.i18nc("@label", "Adhesion")
|
||||
icon: UM.Theme.getIcon("Adhesion")
|
||||
enableSectionSwitchVisible: platformAdhesionType.properties.enabled === "True"
|
||||
enableSectionSwitchChecked: platformAdhesionType.properties.value !== "skirt" && platformAdhesionType.properties.value !== "none"
|
||||
enableSectionSwitchEnabled: recommendedPrintSetup.settingsEnabled
|
||||
tooltipText: catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")
|
||||
|
||||
property var curaRecommendedMode: Cura.RecommendedMode {}
|
||||
|
||||
Cura.IconWithText
|
||||
property UM.SettingPropertyProvider platformAdhesionType: UM.SettingPropertyProvider
|
||||
{
|
||||
id: enableAdhesionRowTitle
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
source: UM.Theme.getIcon("Adhesion")
|
||||
text: catalog.i18nc("@label", "Adhesion")
|
||||
font: UM.Theme.getFont("medium")
|
||||
width: labelColumnWidth
|
||||
iconSize: UM.Theme.getSize("medium_button_icon").width
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: enableAdhesionContainer
|
||||
height: enableAdhesionCheckBox.height
|
||||
|
||||
anchors
|
||||
{
|
||||
left: enableAdhesionRowTitle.right
|
||||
right: parent.right
|
||||
verticalCenter: enableAdhesionRowTitle.verticalCenter
|
||||
}
|
||||
|
||||
UM.CheckBox
|
||||
{
|
||||
id: enableAdhesionCheckBox
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
//: Setting enable printing build-plate adhesion helper checkbox
|
||||
enabled: recommendedPrintSetup.settingsEnabled
|
||||
|
||||
visible: platformAdhesionType.properties.enabled == "True"
|
||||
checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none"
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: adhesionMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
// propagateComposedEvents used on adhesionTooltipMouseArea does not work with Controls Components.
|
||||
// It only works with other MouseAreas, so this is required
|
||||
onClicked: curaRecommendedMode.setAdhesion(!parent.checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: adhesionTooltipMouseArea
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
hoverEnabled: true
|
||||
|
||||
onEntered:base.showTooltip(enableAdhesionCheckBox, Qt.point(-enableAdhesionContainer.x - UM.Theme.getSize("thick_margin").width, 0),
|
||||
catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."));
|
||||
onExited: base.hideTooltip()
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: platformAdhesionType
|
||||
containerStack: Cura.MachineManager.activeMachine
|
||||
removeUnusedValue: false //Doesn't work with settings that are resolved.
|
||||
key: "adhesion_type"
|
||||
watchedProperties: [ "value", "resolve", "enabled" ]
|
||||
storeIndex: 0
|
||||
}
|
||||
|
||||
function onEnableSectionChanged(state)
|
||||
{
|
||||
curaRecommendedMode.setAdhesion(state)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
// Copyright (c) 2022 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
//
|
||||
// Infill
|
||||
//
|
||||
Item
|
||||
{
|
||||
id: infillRow
|
||||
height: childrenRect.height
|
||||
|
||||
property real labelColumnWidth: Math.round(width / 3)
|
||||
|
||||
// Create a binding to update the icon when the infill density changes
|
||||
Binding
|
||||
{
|
||||
target: infillRowTitle
|
||||
property: "source"
|
||||
value:
|
||||
{
|
||||
var density = parseInt(infillDensity.properties.value)
|
||||
if (parseInt(infillSteps.properties.value) != 0)
|
||||
{
|
||||
return UM.Theme.getIcon("InfillGradual")
|
||||
}
|
||||
if (density <= 0)
|
||||
{
|
||||
return UM.Theme.getIcon("Infill0")
|
||||
}
|
||||
if (density < 40)
|
||||
{
|
||||
return UM.Theme.getIcon("Infill3")
|
||||
}
|
||||
if (density < 90)
|
||||
{
|
||||
return UM.Theme.getIcon("Infill2")
|
||||
}
|
||||
return UM.Theme.getIcon("Infill100")
|
||||
}
|
||||
}
|
||||
|
||||
// We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider
|
||||
Binding
|
||||
{
|
||||
target: infillSlider
|
||||
property: "value"
|
||||
value: {
|
||||
// The infill slider has a max value of 100. When it is given a value > 100 onValueChanged updates the setting to be 100.
|
||||
// When changing to an intent with infillDensity > 100, it would always be clamped to 100.
|
||||
// This will force the slider to ignore the first onValueChanged for values > 100 so higher values can be set.
|
||||
var density = parseInt(infillDensity.properties.value)
|
||||
if (density > 100) {
|
||||
infillSlider.ignoreValueChange = true
|
||||
}
|
||||
|
||||
return density
|
||||
}
|
||||
}
|
||||
|
||||
// Here are the elements that are shown in the left column
|
||||
Cura.IconWithText
|
||||
{
|
||||
id: infillRowTitle
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
source: UM.Theme.getIcon("Infill1")
|
||||
text: catalog.i18nc("@label", "Infill") + " (%)"
|
||||
font: UM.Theme.getFont("medium")
|
||||
width: labelColumnWidth
|
||||
iconSize: UM.Theme.getSize("medium_button_icon").width
|
||||
tooltipText: catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: infillSliderContainer
|
||||
height: childrenRect.height
|
||||
|
||||
anchors
|
||||
{
|
||||
left: infillRowTitle.right
|
||||
right: parent.right
|
||||
verticalCenter: infillRowTitle.verticalCenter
|
||||
}
|
||||
|
||||
Slider
|
||||
{
|
||||
id: infillSlider
|
||||
|
||||
property var ignoreValueChange: false
|
||||
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider
|
||||
|
||||
from: 0
|
||||
to: 100
|
||||
stepSize: 1
|
||||
|
||||
// disable slider when gradual support is enabled
|
||||
enabled: parseInt(infillSteps.properties.value) == 0
|
||||
|
||||
// set initial value from stack
|
||||
value: parseInt(infillDensity.properties.value)
|
||||
|
||||
//Draw line
|
||||
background: Rectangle
|
||||
{
|
||||
id: backgroundLine
|
||||
height: UM.Theme.getSize("print_setup_slider_groove").height
|
||||
width: parent.width - UM.Theme.getSize("print_setup_slider_handle").width
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
|
||||
|
||||
Repeater
|
||||
{
|
||||
id: repeater
|
||||
anchors.fill: parent
|
||||
model: infillSlider.to / infillSlider.stepSize + 1
|
||||
|
||||
Rectangle
|
||||
{
|
||||
color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
|
||||
implicitWidth: UM.Theme.getSize("print_setup_slider_tickmarks").width
|
||||
implicitHeight: UM.Theme.getSize("print_setup_slider_tickmarks").height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
// Do not use Math.round otherwise the tickmarks won't be aligned
|
||||
// (space between steps) * index of step
|
||||
x: (backgroundLine.width / (repeater.count - 1)) * index
|
||||
|
||||
radius: Math.round(implicitWidth / 2)
|
||||
visible: (index % 10) == 0 // Only show steps of 10%
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: index
|
||||
visible: (index % 20) == 0 // Only show steps of 20%
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: UM.Theme.getSize("thin_margin").height
|
||||
color: UM.Theme.getColor("quality_slider_available")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle
|
||||
{
|
||||
id: handleButton
|
||||
x: infillSlider.leftPadding + infillSlider.visualPosition * (infillSlider.availableWidth - width)
|
||||
y: infillSlider.topPadding + infillSlider.availableHeight / 2 - height / 2
|
||||
color: infillSlider.enabled ? UM.Theme.getColor("primary") : UM.Theme.getColor("quality_slider_unavailable")
|
||||
implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width
|
||||
implicitHeight: implicitWidth
|
||||
radius: Math.round(implicitWidth / 2)
|
||||
border.color: UM.Theme.getColor("slider_groove_fill")
|
||||
border.width: UM.Theme.getSize("default_lining").height
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: infillSlider
|
||||
function onValueChanged()
|
||||
{
|
||||
if (infillSlider.ignoreValueChange)
|
||||
{
|
||||
infillSlider.ignoreValueChange = false
|
||||
return
|
||||
}
|
||||
|
||||
// Don't update if the setting value, if the slider has the same value
|
||||
if (parseInt(infillDensity.properties.value) == infillSlider.value)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
// Round the slider value to the nearest multiple of 10 (simulate step size of 10)
|
||||
var roundedSliderValue = Math.round(infillSlider.value / 10) * 10
|
||||
|
||||
// Update the slider value to represent the rounded value
|
||||
infillSlider.value = roundedSliderValue
|
||||
|
||||
// Update value only if the Recommended mode is Active,
|
||||
// Otherwise if I change the value in the Custom mode the Recommended view will try to repeat
|
||||
// same operation
|
||||
const active_mode = UM.Preferences.getValue("cura/active_mode")
|
||||
|
||||
if (visible // Workaround: 'visible' is checked because on startup in Windows it spuriously gets an 'onValueChanged' with value '0' if this isn't checked.
|
||||
&& (active_mode == 0 || active_mode == "simple"))
|
||||
{
|
||||
Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue)
|
||||
Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gradual Support Infill Checkbox
|
||||
UM.CheckBox
|
||||
{
|
||||
id: enableGradualInfillCheckBox
|
||||
property alias _hovered: enableGradualInfillMouseArea.containsMouse
|
||||
|
||||
anchors.top: infillSliderContainer.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("wide_margin").height
|
||||
anchors.left: infillSliderContainer.left
|
||||
|
||||
text: catalog.i18nc("@label", "Gradual infill")
|
||||
enabled: recommendedPrintSetup.settingsEnabled
|
||||
visible: infillSteps.properties.enabled == "True"
|
||||
checked: parseInt(infillSteps.properties.value) > 0
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: enableGradualInfillMouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: true
|
||||
|
||||
property var previousInfillDensity: parseInt(infillDensity.properties.value)
|
||||
|
||||
onClicked:
|
||||
{
|
||||
// Set to 90% only when enabling gradual infill
|
||||
var newInfillDensity;
|
||||
if (parseInt(infillSteps.properties.value) == 0)
|
||||
{
|
||||
previousInfillDensity = parseInt(infillDensity.properties.value)
|
||||
newInfillDensity = 90
|
||||
} else {
|
||||
newInfillDensity = previousInfillDensity
|
||||
}
|
||||
Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity))
|
||||
|
||||
var infill_steps_value = 0
|
||||
if (parseInt(infillSteps.properties.value) == 0)
|
||||
{
|
||||
infill_steps_value = 5
|
||||
}
|
||||
|
||||
Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value)
|
||||
}
|
||||
|
||||
onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillSliderContainer.x - UM.Theme.getSize("thick_margin").width, 0),
|
||||
catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top."))
|
||||
|
||||
onExited: base.hideTooltip()
|
||||
}
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: infillDensity
|
||||
containerStackId: Cura.MachineManager.activeStackId
|
||||
key: "infill_sparse_density"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 0
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: infillSteps
|
||||
containerStackId: Cura.MachineManager.activeStackId
|
||||
key: "gradual_infill_steps"
|
||||
watchedProperties: ["value", "enabled"]
|
||||
storeIndex: 0
|
||||
}
|
||||
}
|
|
@ -1,32 +1,42 @@
|
|||
//Copyright (c) 2022 Ultimaker B.V.
|
||||
// Copyright (c) 2022 UltiMaker
|
||||
//Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import UM 1.6 as UM
|
||||
import Cura 1.6 as Cura
|
||||
import ".."
|
||||
|
||||
Item
|
||||
ScrollView
|
||||
{
|
||||
id: recommendedPrintSetup
|
||||
|
||||
height: childrenRect.height + 2 * padding
|
||||
implicitHeight: settingsColumn.height + 2 * padding
|
||||
|
||||
property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1
|
||||
property real padding: UM.Theme.getSize("default_margin").width
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
padding: UM.Theme.getSize("default_margin").width
|
||||
|
||||
function onModeChanged() {}
|
||||
|
||||
ScrollBar.vertical: UM.ScrollBar {
|
||||
id: scroll
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
margins: parent.padding
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
id: settingsColumn
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
width: recommendedPrintSetup.width - 2 * recommendedPrintSetup.padding - (scroll.visible ? scroll.width : 0)
|
||||
|
||||
// TODO
|
||||
property real firstColumnWidth: Math.round(width / 3)
|
||||
|
@ -46,7 +56,6 @@ Item
|
|||
RecommendedResolutionSelector
|
||||
{
|
||||
id: recommendedResolutionSelector
|
||||
Layout.fillWidth: true
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
|
@ -54,55 +63,72 @@ Item
|
|||
{
|
||||
width: parent.width
|
||||
visible: !recommendedResolutionSelector.visible
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Item { height: UM.Theme.getSize("default_margin").height } // Spacer
|
||||
|
||||
ProfileWarningReset
|
||||
{
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: UM.Theme.getSize("default_margin").height
|
||||
Layout.bottomMargin: UM.Theme.getSize("thin_margin").height
|
||||
}
|
||||
|
||||
Item { height: UM.Theme.getSize("thin_margin").height + UM.Theme.getSize("narrow_margin").height} // Spacer
|
||||
|
||||
//Line between the sections.
|
||||
Rectangle
|
||||
{
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("default_lining").height
|
||||
Layout.topMargin: UM.Theme.getSize("narrow_margin").height
|
||||
Layout.bottomMargin: UM.Theme.getSize("narrow_margin").height
|
||||
Layout.fillWidth: true
|
||||
color: UM.Theme.getColor("lining")
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@label", "Print settings")
|
||||
font: UM.Theme.getFont("medium")
|
||||
}
|
||||
Item { height: UM.Theme.getSize("narrow_margin").height } //Spacer
|
||||
|
||||
RecommendedInfillDensitySelector
|
||||
Column
|
||||
{
|
||||
id: settingColumn
|
||||
width: parent.width
|
||||
labelColumnWidth: parent.firstColumnWidth
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
spacing: UM.Theme.getSize("thin_margin").height
|
||||
|
||||
RecommendedSupportSelector
|
||||
{
|
||||
width: parent.width
|
||||
labelColumnWidth: parent.firstColumnWidth
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Item
|
||||
{
|
||||
id: recommendedPrintSettingsHeader
|
||||
height: childrenRect.height
|
||||
width: parent.width
|
||||
UM.Label
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@label", "Recommended print settings")
|
||||
font: UM.Theme.getFont("medium")
|
||||
}
|
||||
|
||||
RecommendedAdhesionSelector
|
||||
{
|
||||
width: parent.width
|
||||
labelColumnWidth: parent.firstColumnWidth
|
||||
Layout.fillWidth: true
|
||||
Cura.SecondaryButton
|
||||
{
|
||||
id: customSettingsButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
text: catalog.i18nc("@button", "Show Custom")
|
||||
textFont: UM.Theme.getFont("medium_bold")
|
||||
outlineColor: "transparent"
|
||||
onClicked: onModeChanged()
|
||||
}
|
||||
}
|
||||
|
||||
RecommendedStrengthSelector
|
||||
{
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
RecommendedSupportSelector
|
||||
{
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
RecommendedAdhesionSelector
|
||||
{
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 2.10
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
|
||||
Item
|
||||
{
|
||||
id: settingItem
|
||||
width: parent.width
|
||||
Layout.minimumHeight: UM.Theme.getSize("section_header").height
|
||||
Layout.fillWidth: true
|
||||
|
||||
property alias settingControl: settingContainer.children
|
||||
property alias settingName: settingLabel.text
|
||||
property string tooltipText: ""
|
||||
property bool isCompressed: false
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: settingLabel
|
||||
width: leftColumnWidth
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
// These numbers come from the IconWithText in RecommendedSettingSection
|
||||
anchors.leftMargin: UM.Theme.getSize("medium_button_icon").width + UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: tooltipArea
|
||||
anchors.fill: settingLabel
|
||||
propagateComposedEvents: true
|
||||
hoverEnabled: true
|
||||
onEntered: base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltipText)
|
||||
onExited: base.hideTooltip()
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: settingContainer
|
||||
height: childrenRect.height
|
||||
anchors.left: settingLabel.right
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "sectionClosed" // Section is hidden when the switch in parent is off
|
||||
when: isCompressed
|
||||
PropertyChanges
|
||||
{
|
||||
target: settingItem;
|
||||
opacity: 0
|
||||
height: 0
|
||||
implicitHeight: 0
|
||||
Layout.preferredHeight: 0
|
||||
Layout.minimumHeight: 0
|
||||
enabled: false // Components can still be clickable with height 0 so they need to be disabled as well.
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
// All values are default. This state is only here for the animation.
|
||||
name: "sectionOpened"
|
||||
when: !isCompressed
|
||||
}
|
||||
]
|
||||
|
||||
transitions: Transition
|
||||
{
|
||||
from: "sectionOpened"; to: "sectionClosed"
|
||||
reversible: true
|
||||
ParallelAnimation
|
||||
{
|
||||
// Animate section compressing as it closes
|
||||
NumberAnimation { property: "Layout.minimumHeight"; duration: 100; }
|
||||
// Animate section dissapearring as it closes
|
||||
NumberAnimation { property: "opacity"; duration: 100; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 2.10
|
||||
|
||||
import UM 1.7 as UM
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
Item
|
||||
{
|
||||
id: settingSection
|
||||
property alias title: sectionTitle.text
|
||||
property alias icon: sectionTitle.source
|
||||
|
||||
property alias enableSectionSwitchVisible: enableSectionSwitch.visible
|
||||
property alias enableSectionSwitchChecked: enableSectionSwitch.checked
|
||||
property alias enableSectionSwitchEnabled: enableSectionSwitch.enabled
|
||||
property string tooltipText: ""
|
||||
property var enableSectionClicked: { return }
|
||||
property int leftColumnWidth: Math.floor(width * 0.35)
|
||||
property bool isCompressed: false
|
||||
|
||||
property alias contents: settingColumn.children
|
||||
|
||||
function onEnableSectionChanged(state) {}
|
||||
|
||||
height: childrenRect.height
|
||||
|
||||
Item
|
||||
{
|
||||
id: sectionHeader
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
height: UM.Theme.getSize("section_header").height
|
||||
|
||||
Cura.IconWithText
|
||||
{
|
||||
id: sectionTitle
|
||||
width: leftColumnWidth
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: UM.Theme.getIcon("PrintQuality")
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
iconSize: UM.Theme.getSize("medium_button_icon").width
|
||||
iconColor: UM.Theme.getColor("text")
|
||||
font: UM.Theme.getFont("medium_bold")
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: tooltipArea
|
||||
anchors.fill: sectionTitle
|
||||
propagateComposedEvents: true
|
||||
hoverEnabled: true
|
||||
onEntered: base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltipText)
|
||||
onExited: base.hideTooltip()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UM.Switch
|
||||
{
|
||||
id: enableSectionSwitch
|
||||
anchors.left: parent.left
|
||||
// These numbers come from the IconWithText in RecommendedSettingSection.
|
||||
anchors.leftMargin: leftColumnWidth + UM.Theme.getSize("medium_button_icon").width + UM.Theme.getSize("default_margin").width
|
||||
anchors.verticalCenter: sectionHeader.verticalCenter
|
||||
visible: false
|
||||
|
||||
// This delay forces the setting change to happen after the setting section open/close animation. This is so the animation is smooth.
|
||||
Timer
|
||||
{
|
||||
id: updateTimer
|
||||
interval: 500 // This interval is set long enough so you can spam click the button on/off without lag.
|
||||
repeat: false
|
||||
onTriggered: onEnableSectionChanged(enableSectionSwitch.checked)
|
||||
}
|
||||
onClicked: updateTimer.restart()
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
id: settingColumn
|
||||
width: parent.width
|
||||
spacing: UM.Theme.getSize("thin_margin").height
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: sectionHeader.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("narrow_margin").height
|
||||
}
|
||||
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "settingListClosed"
|
||||
when: !enableSectionSwitchChecked && enableSectionSwitchEnabled
|
||||
PropertyChanges
|
||||
{
|
||||
target: settingSection
|
||||
isCompressed: true
|
||||
implicitHeight: 0
|
||||
}
|
||||
PropertyChanges
|
||||
{
|
||||
target: settingColumn
|
||||
spacing: 0
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
// Use default properties. This is only here for the animation.
|
||||
name: "settingListOpened"
|
||||
when: enableSectionSwitchChecked && enableSectionSwitchEnabled
|
||||
}
|
||||
]
|
||||
|
||||
// Animate section closing
|
||||
transitions: Transition
|
||||
{
|
||||
from: "settingListOpened"; to: "settingListClosed"
|
||||
reversible: true
|
||||
// Animate section compressing as it closes
|
||||
NumberAnimation { property: "implicitHeight"; duration: 100; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 2.10
|
||||
|
||||
import UM 1.7 as UM
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
|
||||
RecommendedSettingSection
|
||||
{
|
||||
id: strengthSection
|
||||
|
||||
title: catalog.i18nc("@label", "Strength")
|
||||
icon: UM.Theme.getIcon("Hammer")
|
||||
enableSectionSwitchVisible: false
|
||||
enableSectionSwitchEnabled: false
|
||||
tooltipText: catalog.i18nc("@label", "The following settings define the strength of your part.")
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: infillSteps
|
||||
containerStackId: Cura.MachineManager.activeStackId
|
||||
key: "gradual_infill_steps"
|
||||
watchedProperties: ["value", "enabled"]
|
||||
storeIndex: 0
|
||||
}
|
||||
|
||||
contents: [
|
||||
RecommendedSettingItem
|
||||
{
|
||||
settingName: catalog.i18nc("infill_sparse_density description", "Infill Density")
|
||||
tooltipText: catalog.i18nc("@label", "Adjusts the density of infill of the print.")
|
||||
settingControl: Cura.SingleSettingSlider
|
||||
{
|
||||
height: UM.Theme.getSize("combobox").height
|
||||
width: parent.width
|
||||
settingName: "infill_sparse_density"
|
||||
updateAllExtruders: true
|
||||
// disable slider when gradual support is enabled
|
||||
enabled: parseInt(infillSteps.properties.value) === 0
|
||||
|
||||
function updateSetting(value)
|
||||
{
|
||||
Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", value)
|
||||
Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance")
|
||||
}
|
||||
}
|
||||
},
|
||||
RecommendedSettingItem
|
||||
{
|
||||
settingName: catalog.i18nc("@action:label", "Infill Pattern")
|
||||
tooltipText: catalog.i18nc("@label",
|
||||
"The pattern of the infill material of the print:\n\nFor quick prints of non functional model choose line, zig zag or lighting infill.\n\nFor functional part not subjected to a lot of stress we reccomend grid or triangle or tri hexagon.\n\nFor functional 3D prints which require high strenght in multiple directions use cubic, cubic subdivision, quarter cubic, octet, and gyroid.")
|
||||
|
||||
settingControl: Cura.SingleSettingComboBox
|
||||
{
|
||||
width: parent.width
|
||||
settingName: "infill_pattern"
|
||||
updateAllExtruders: true
|
||||
}
|
||||
},
|
||||
RecommendedSettingItem
|
||||
{
|
||||
settingName: catalog.i18nc("@action:label", "Shell Thickness")
|
||||
tooltipText: catalog.i18nc("@label", "Defines the tickness of your part side walls, roof and floor.")
|
||||
|
||||
settingControl: RowLayout
|
||||
{
|
||||
anchors.fill: parent
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
UM.ComponentWithIcon
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
source: UM.Theme.getIcon("PrintWalls")
|
||||
|
||||
Cura.SingleSettingTextField
|
||||
{
|
||||
width: parent.width
|
||||
settingName: "wall_thickness"
|
||||
updateAllExtruders: true
|
||||
validator: UM.FloatValidator {}
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
}
|
||||
UM.ComponentWithIcon
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
source: UM.Theme.getIcon("PrintTopBottom")
|
||||
|
||||
Cura.SingleSettingTextField
|
||||
{
|
||||
width: parent.width
|
||||
settingName: "top_bottom_thickness"
|
||||
updateAllExtruders: true
|
||||
validator: UM.FloatValidator {}
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,307 +1,31 @@
|
|||
// Copyright (c) 2022 Ultimaker B.V.
|
||||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
|
||||
//
|
||||
// Enable support
|
||||
//
|
||||
Item
|
||||
RecommendedSettingSection
|
||||
{
|
||||
id: enableSupportRow
|
||||
height: UM.Theme.getSize("print_setup_big_item").height
|
||||
|
||||
property real labelColumnWidth: Math.round(width / 3)
|
||||
title: catalog.i18nc("@label", "Support")
|
||||
icon: UM.Theme.getIcon("Support")
|
||||
enableSectionSwitchVisible: supportEnabled.properties.enabled == "True"
|
||||
enableSectionSwitchChecked: supportEnabled.properties.value == "True"
|
||||
enableSectionSwitchEnabled: recommendedPrintSetup.settingsEnabled
|
||||
tooltipText: catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, these parts would collapse during printing.")
|
||||
|
||||
Item
|
||||
function onEnableSectionChanged(state)
|
||||
{
|
||||
id: enableSupportContainer
|
||||
width: labelColumnWidth + enableSupportCheckBox.width
|
||||
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
rightMargin: UM.Theme.getSize("thick_margin").width
|
||||
}
|
||||
|
||||
Cura.IconWithText
|
||||
{
|
||||
id: enableSupportRowTitle
|
||||
anchors.left: parent.left
|
||||
visible: enableSupportCheckBox.visible
|
||||
source: UM.Theme.getIcon("Support")
|
||||
text: catalog.i18nc("@label", "Support")
|
||||
font: UM.Theme.getFont("medium")
|
||||
width: labelColumnWidth
|
||||
iconSize: UM.Theme.getSize("medium_button_icon").width
|
||||
tooltipText: catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")
|
||||
}
|
||||
|
||||
UM.CheckBox
|
||||
{
|
||||
id: enableSupportCheckBox
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: enableSupportRowTitle.right
|
||||
|
||||
property alias _hovered: enableSupportMouseArea.containsMouse
|
||||
|
||||
enabled: recommendedPrintSetup.settingsEnabled
|
||||
|
||||
visible: supportEnabled.properties.enabled == "True"
|
||||
checked: supportEnabled.properties.value == "True"
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: enableSupportMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
// propagateComposedEvents used on supportToolTipMouseArea does not work with Controls Components.
|
||||
// It only works with other MouseAreas, so this is required
|
||||
onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True")
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: supportToolTipMouseArea
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
hoverEnabled: true
|
||||
onEntered: base.showTooltip(enableSupportContainer, Qt.point(-enableSupportContainer.x - UM.Theme.getSize("thick_margin").width, 0),
|
||||
catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."))
|
||||
onExited: base.hideTooltip()
|
||||
}
|
||||
supportEnabled.setPropertyValue("value", state)
|
||||
}
|
||||
|
||||
ComboBox
|
||||
{
|
||||
id: supportExtruderCombobox
|
||||
|
||||
height: UM.Theme.getSize("print_setup_big_item").height
|
||||
anchors
|
||||
{
|
||||
left: enableSupportContainer.right
|
||||
right: parent.right
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
rightMargin: UM.Theme.getSize("thick_margin").width
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
enabled: recommendedPrintSetup.settingsEnabled
|
||||
visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1)
|
||||
textRole: "name" // this solves that the combobox isn't populated in the first time Cura is started
|
||||
|
||||
model: extruderModel
|
||||
|
||||
// knowing the extruder position, try to find the item index in the model
|
||||
function getIndexByPosition(position)
|
||||
{
|
||||
var itemIndex = -1 // if position is not found, return -1
|
||||
for (var item_index in model.items)
|
||||
{
|
||||
var item = model.getItem(item_index)
|
||||
if (item.index == position)
|
||||
{
|
||||
itemIndex = item_index
|
||||
break
|
||||
}
|
||||
}
|
||||
return itemIndex
|
||||
}
|
||||
|
||||
onActivated:
|
||||
{
|
||||
if (model.getItem(index).enabled)
|
||||
{
|
||||
forceActiveFocus();
|
||||
supportExtruderNr.setPropertyValue("value", model.getItem(index).index);
|
||||
} else
|
||||
{
|
||||
currentIndex = supportExtruderNr.properties.value; // keep the old value
|
||||
}
|
||||
}
|
||||
|
||||
currentIndex: (supportExtruderNr.properties.value !== undefined) ? supportExtruderNr.properties.value : 0
|
||||
|
||||
property string color: "#fff"
|
||||
Connections
|
||||
{
|
||||
target: extruderModel
|
||||
function onModelChanged()
|
||||
{
|
||||
var maybeColor = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color
|
||||
if (maybeColor)
|
||||
{
|
||||
supportExtruderCombobox.color = maybeColor
|
||||
}
|
||||
}
|
||||
}
|
||||
onCurrentIndexChanged:
|
||||
{
|
||||
var maybeColor = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color
|
||||
if(maybeColor)
|
||||
{
|
||||
supportExtruderCombobox.color = maybeColor
|
||||
}
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: supportExtruderCombobox
|
||||
property: "currentIndex"
|
||||
value: supportExtruderCombobox.getIndexByPosition(supportExtruderNr.properties.value)
|
||||
// Sometimes when the value is already changed, the model is still being built.
|
||||
// The when clause ensures that the current index is not updated when this happens.
|
||||
when: supportExtruderCombobox.model.count > 0
|
||||
}
|
||||
|
||||
indicator: UM.ColorImage
|
||||
{
|
||||
id: downArrow
|
||||
x: supportExtruderCombobox.width - width - supportExtruderCombobox.rightPadding
|
||||
y: supportExtruderCombobox.topPadding + Math.round((supportExtruderCombobox.availableHeight - height) / 2)
|
||||
|
||||
source: UM.Theme.getIcon("ChevronSingleDown")
|
||||
width: UM.Theme.getSize("standard_arrow").width
|
||||
height: UM.Theme.getSize("standard_arrow").height
|
||||
|
||||
color: UM.Theme.getColor("setting_control_button")
|
||||
}
|
||||
|
||||
background: Rectangle
|
||||
{
|
||||
color:
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_disabled")
|
||||
}
|
||||
if (supportExtruderCombobox.hovered || base.activeFocus)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_highlight")
|
||||
}
|
||||
return UM.Theme.getColor("setting_control")
|
||||
}
|
||||
radius: UM.Theme.getSize("setting_control_radius").width
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color:
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_disabled_border")
|
||||
}
|
||||
if (supportExtruderCombobox.hovered || supportExtruderCombobox.activeFocus)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_border_highlight")
|
||||
}
|
||||
return UM.Theme.getColor("setting_control_border")
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: UM.Label
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
|
||||
anchors.right: downArrow.left
|
||||
rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
|
||||
|
||||
text: supportExtruderCombobox.currentText
|
||||
textFormat: Text.PlainText
|
||||
color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
|
||||
|
||||
elide: Text.ElideLeft
|
||||
|
||||
|
||||
background: Rectangle
|
||||
{
|
||||
id: swatch
|
||||
height: Math.round(parent.height / 2)
|
||||
width: height
|
||||
radius: Math.round(width / 2)
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.rightMargin: UM.Theme.getSize("thin_margin").width
|
||||
|
||||
color: supportExtruderCombobox.color
|
||||
}
|
||||
}
|
||||
|
||||
popup: Popup
|
||||
{
|
||||
y: supportExtruderCombobox.height - UM.Theme.getSize("default_lining").height
|
||||
width: supportExtruderCombobox.width
|
||||
implicitHeight: contentItem.implicitHeight + 2 * UM.Theme.getSize("default_lining").width
|
||||
padding: UM.Theme.getSize("default_lining").width
|
||||
|
||||
contentItem: ListView
|
||||
{
|
||||
implicitHeight: contentHeight
|
||||
|
||||
ScrollBar.vertical: UM.ScrollBar {}
|
||||
clip: true
|
||||
model: supportExtruderCombobox.popup.visible ? supportExtruderCombobox.delegateModel : null
|
||||
currentIndex: supportExtruderCombobox.highlightedIndex
|
||||
}
|
||||
|
||||
background: Rectangle
|
||||
{
|
||||
color: UM.Theme.getColor("setting_control")
|
||||
border.color: UM.Theme.getColor("setting_control_border")
|
||||
}
|
||||
}
|
||||
|
||||
delegate: ItemDelegate
|
||||
{
|
||||
width: supportExtruderCombobox.width - 2 * UM.Theme.getSize("default_lining").width
|
||||
height: supportExtruderCombobox.height
|
||||
highlighted: supportExtruderCombobox.highlightedIndex == index
|
||||
|
||||
contentItem: UM.Label
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
|
||||
anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
|
||||
|
||||
text: model.name
|
||||
color: model.enabled ? UM.Theme.getColor("setting_control_text"): UM.Theme.getColor("action_button_disabled_text")
|
||||
|
||||
elide: Text.ElideRight
|
||||
rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
|
||||
|
||||
background: Rectangle
|
||||
{
|
||||
id: swatch
|
||||
height: Math.round(parent.height / 2)
|
||||
width: height
|
||||
radius: Math.round(width / 2)
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.rightMargin: UM.Theme.getSize("thin_margin").width
|
||||
|
||||
color: supportExtruderCombobox.model.getItem(index).color
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle
|
||||
{
|
||||
color: parent.highlighted ? UM.Theme.getColor("setting_control_highlight") : "transparent"
|
||||
border.color: parent.highlighted ? UM.Theme.getColor("setting_control_border_highlight") : "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property var extruderModel: CuraApplication.getExtrudersModel()
|
||||
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
property UM.SettingPropertyProvider supportEnabled: UM.SettingPropertyProvider
|
||||
{
|
||||
id: supportEnabled
|
||||
containerStack: Cura.MachineManager.activeMachine
|
||||
|
@ -310,21 +34,45 @@ Item
|
|||
storeIndex: 0
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: supportExtruderNr
|
||||
containerStack: Cura.MachineManager.activeMachine
|
||||
key: "support_extruder_nr"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 0
|
||||
}
|
||||
contents: [
|
||||
RecommendedSettingItem
|
||||
{
|
||||
settingName: catalog.i18nc("@action:label", "Support Type")
|
||||
tooltipText: catalog.i18nc("@label", "Chooses between the techniques available to generate support. \n\n\"Normal\" support creates a support structure directly below the overhanging parts and drops those areas straight down. \n\n\"Tree\" support creates branches towards the overhanging areas that support the model on the tips of those branches, and allows the branches to crawl around the model to support it from the build plate as much as possible.")
|
||||
isCompressed: enableSupportRow.isCompressed
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: machineExtruderCount
|
||||
containerStack: Cura.MachineManager.activeMachine
|
||||
key: "machine_extruder_count"
|
||||
watchedProperties: ["value"]
|
||||
storeIndex: 0
|
||||
}
|
||||
settingControl: Cura.SingleSettingComboBox
|
||||
{
|
||||
width: parent.width
|
||||
settingName: "support_structure"
|
||||
}
|
||||
},
|
||||
RecommendedSettingItem
|
||||
{
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
settingName: catalog.i18nc("@action:label", "Print with")
|
||||
tooltipText: catalog.i18nc("@label", "The extruder train to use for printing the support. This is used in multi-extrusion.")
|
||||
// Hide this component when there is only one extruder
|
||||
enabled: Cura.ExtruderManager.enabledExtruderCount > 1
|
||||
visible: Cura.ExtruderManager.enabledExtruderCount > 1
|
||||
isCompressed: enableSupportRow.isCompressed || Cura.ExtruderManager.enabledExtruderCount <= 1
|
||||
|
||||
settingControl: Cura.SingleSettingExtruderSelectorBar
|
||||
{
|
||||
extruderSettingName: "support_extruder_nr"
|
||||
}
|
||||
},
|
||||
RecommendedSettingItem
|
||||
{
|
||||
settingName: catalog.i18nc("@action:label", "Placement")
|
||||
tooltipText: catalog.i18nc("support_type description", "Adjusts the placement of the support structures. The placement can be set to touching build plate or everywhere. When set to everywhere the support structures will also be printed on the model.")
|
||||
isCompressed: enableSupportRow.isCompressed
|
||||
|
||||
settingControl: Cura.SingleSettingComboBox
|
||||
{
|
||||
width: parent.width
|
||||
settingName: "support_type"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ UM.PointingRectangle
|
|||
id: base
|
||||
property real sourceWidth: 0
|
||||
width: UM.Theme.getSize("tooltip").width
|
||||
height: textScroll.height + UM.Theme.getSize("tooltip_margins").height * 2
|
||||
height: textScroll.height + UM.Theme.getSize("tooltip_margins").height
|
||||
color: UM.Theme.getColor("tooltip")
|
||||
|
||||
arrowSize: UM.Theme.getSize("default_arrow").width
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import UM 1.5 as UM
|
||||
import UM 1.7 as UM
|
||||
|
||||
SettingItem
|
||||
{
|
||||
|
@ -14,6 +14,11 @@ SettingItem
|
|||
property string textBeforeEdit
|
||||
property bool textHasChanged
|
||||
property bool focusGainedByClick: false
|
||||
|
||||
readonly property UM.IntValidator intValidator: UM.IntValidator {}
|
||||
readonly property UM.FloatValidator floatValidator: UM.FloatValidator {}
|
||||
readonly property UM.IntListValidator intListValidator: UM.IntListValidator {}
|
||||
|
||||
onFocusReceived:
|
||||
{
|
||||
textHasChanged = false;
|
||||
|
@ -159,7 +164,23 @@ SettingItem
|
|||
// should be done as little as possible)
|
||||
clip: definition.type == "str" || definition.type == "[int]"
|
||||
|
||||
validator: RegularExpressionValidator { regularExpression: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,11}\s*,)*(\s*-?[0-9]{0,11})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,12}$/ : (definition.type == "float") ? /^-?[0-9]{0,11}[.,]?[0-9]{0,3}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
|
||||
validator: RegularExpressionValidator
|
||||
{
|
||||
regularExpression:
|
||||
{
|
||||
switch (definition.type)
|
||||
{
|
||||
case "[int]":
|
||||
return new RegExp(intListValidator.regexString)
|
||||
case "int":
|
||||
return new RegExp(intValidator.regexString)
|
||||
case "float":
|
||||
return new RegExp(floatValidator.regexString)
|
||||
default:
|
||||
return new RegExp("^.*$")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ import QtQuick 2.2
|
|||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
Item
|
||||
{
|
||||
|
@ -29,13 +29,13 @@ Item
|
|||
anchors
|
||||
{
|
||||
fill: toolButtons
|
||||
leftMargin: -radius - border.width
|
||||
rightMargin: -border.width
|
||||
topMargin: -border.width
|
||||
bottomMargin: -border.width
|
||||
leftMargin: -radius - border.width // Removes border on left side
|
||||
}
|
||||
radius: UM.Theme.getSize("default_radius").width
|
||||
color: UM.Theme.getColor("lining")
|
||||
color: UM.Theme.getColor("toolbar_background")
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
|
||||
}
|
||||
|
||||
Column
|
||||
|
@ -111,13 +111,12 @@ Item
|
|||
anchors
|
||||
{
|
||||
fill: extruderButtons
|
||||
leftMargin: -radius - border.width
|
||||
rightMargin: -border.width
|
||||
topMargin: -border.width
|
||||
bottomMargin: -border.width
|
||||
leftMargin: -radius - border.width // Removes border on left side
|
||||
}
|
||||
radius: UM.Theme.getSize("default_radius").width
|
||||
color: UM.Theme.getColor("lining")
|
||||
color: UM.Theme.getColor("toolbar_background")
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
visible: extrudersModel.items.length > 1
|
||||
}
|
||||
|
||||
|
@ -135,11 +134,21 @@ Item
|
|||
height: childrenRect.height
|
||||
model: extrudersModel.items.length > 1 ? extrudersModel : 0
|
||||
|
||||
delegate: ExtruderButton
|
||||
delegate: Cura.ExtruderButton
|
||||
{
|
||||
extruder: model
|
||||
isTopElement: extrudersModel.getItem(0).id == model.id
|
||||
isBottomElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).id == model.id
|
||||
isTopElement: extrudersModel.getItem(0).id === model.id
|
||||
isBottomElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).id === model.id
|
||||
text: catalog.i18ncp("@label %1 is filled in with the name of an extruder", "Print Selected Model with %1", "Print Selected Models with %1", UM.Selection.selectionCount).arg(extruder.name)
|
||||
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) !== -1
|
||||
enabled: UM.Selection.hasSelection && extruder.stack.isEnabled
|
||||
font: UM.Theme.getFont("small_emphasis")
|
||||
|
||||
onClicked:
|
||||
{
|
||||
forceActiveFocus() //First grab focus, so all the text fields are updated
|
||||
CuraActions.setExtruderForSelection(extruder.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ ComboBox
|
|||
|
||||
enabled: delegateModel.count > 0
|
||||
|
||||
height: UM.Theme.getSize("combobox").height
|
||||
|
||||
onVisibleChanged: { popup.close() }
|
||||
|
||||
states: [
|
||||
|
|
102
resources/qml/Widgets/SingleSettingComboBox.qml
Normal file
102
resources/qml/Widgets/SingleSettingComboBox.qml
Normal file
|
@ -0,0 +1,102 @@
|
|||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
// This ComboBox allows changing of a single setting. Only the setting name has to be passed in to "settingName".
|
||||
// All of the setting updating logic is handled by this component.
|
||||
// This uses the "options" value of a setting to populate the drop down. This will only work for settings with "options"
|
||||
// If the setting is limited to a single extruder or is settable with different values per extruder use "updateAllExtruders: true"
|
||||
Cura.ComboBox {
|
||||
textRole: "text"
|
||||
property alias settingName: propertyProvider.key
|
||||
|
||||
// If true, all extruders will have "settingName" property updated.
|
||||
// The displayed value will be read from the extruder with index "defaultExtruderIndex" instead of the machine.
|
||||
property bool updateAllExtruders: false
|
||||
// This is only used if updateAllExtruders == true
|
||||
property int defaultExtruderIndex: 0
|
||||
|
||||
model: ListModel
|
||||
{
|
||||
id: comboboxModel
|
||||
|
||||
// The propertyProvider has not loaded the setting when this components onComplete triggers. Populating the model
|
||||
// is defered until propertyProvider signals "onIsValueUsedChanged". The defered upate is triggered with this function.
|
||||
function updateModel()
|
||||
{
|
||||
clear()
|
||||
|
||||
if(!propertyProvider.properties.options) // No options have been loaded yet to populate combobox
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
for (var i = 0; i < propertyProvider.properties["options"].keys().length; i++)
|
||||
{
|
||||
var key = propertyProvider.properties["options"].keys()[i]
|
||||
var value = propertyProvider.properties["options"][key]
|
||||
comboboxModel.append({ text: value, code: key})
|
||||
|
||||
if (propertyProvider.properties.value === key)
|
||||
{
|
||||
// The combobox is cleared after each value change so the currentIndex must be set each time.
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updates to the setting are delayed by interval. The signal onIsValueUsedChanged() is emitted early for some reason.
|
||||
// This causes the selected value in the combobox to be updated to the previous value. (This issue is present with infill_pattern setting)
|
||||
// This is a hack. If you see this in the future, try removing it and see if the combobox still works.
|
||||
Timer
|
||||
{
|
||||
id: updateTimer
|
||||
interval: 100
|
||||
repeat: false
|
||||
onTriggered: comboboxModel.updateModel(false)
|
||||
}
|
||||
|
||||
property UM.SettingPropertyProvider propertyProvider: UM.SettingPropertyProvider
|
||||
{
|
||||
id: propertyProvider
|
||||
containerStackId: updateAllExtruders ? Cura.ExtruderManager.extruderIds[defaultExtruderIndex] : Cura.MachineManager.activeMachine.id
|
||||
watchedProperties: ["value" , "options"]
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: propertyProvider
|
||||
function onContainerStackChanged() { updateTimer.restart() }
|
||||
function onIsValueUsedChanged() { updateTimer.restart() }
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: parseValueAndUpdateSetting()
|
||||
|
||||
function parseValueAndUpdateSetting()
|
||||
{
|
||||
if (comboboxModel.get(currentIndex) && comboboxModel.get(currentIndex).code !== propertyProvider.properties.value)
|
||||
{
|
||||
updateSetting(comboboxModel.get(currentIndex).code)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateSetting(value)
|
||||
{
|
||||
if (updateAllExtruders)
|
||||
{
|
||||
Cura.MachineManager.setSettingForAllExtruders(propertyProvider.key, "value", value)
|
||||
}
|
||||
else
|
||||
{
|
||||
propertyProvider.setPropertyValue("value", value)
|
||||
}
|
||||
}
|
||||
}
|
70
resources/qml/Widgets/SingleSettingExtruderSelectorBar.qml
Normal file
70
resources/qml/Widgets/SingleSettingExtruderSelectorBar.qml
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.5 as Cura
|
||||
|
||||
// This component displays a row of extruder icons, clicking on the extruder will update the setting passed to "settingName"
|
||||
// with the index of that extruder.
|
||||
// This will only work for settings that take an extruder index.
|
||||
Row
|
||||
{
|
||||
id: extruderSelectionBar
|
||||
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
spacing: 0
|
||||
|
||||
property int selectedIndex: extruderSettingProvider.properties.value !== undefined ? extruderSettingProvider.properties.value : 0
|
||||
property alias model: extruderButtonRepeater.model
|
||||
property alias extruderSettingName: extruderSettingProvider.key
|
||||
property alias containerStack: extruderSettingProvider.containerStack
|
||||
|
||||
property UM.SettingPropertyProvider extruderSettingProvider: UM.SettingPropertyProvider
|
||||
{
|
||||
id: extruderSettingProvider
|
||||
containerStack: Cura.MachineManager.activeMachine
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 0
|
||||
}
|
||||
|
||||
function onClickExtruder(index)
|
||||
{
|
||||
forceActiveFocus();
|
||||
extruderSettingProvider.setPropertyValue("value", index);
|
||||
}
|
||||
|
||||
|
||||
Repeater
|
||||
{
|
||||
id: extruderButtonRepeater
|
||||
|
||||
model: CuraApplication.getExtrudersModel()
|
||||
|
||||
delegate: Item
|
||||
{
|
||||
width: {
|
||||
// This will "squish" the extruder buttons together when the fill up the horizontal space
|
||||
const maximum_width = Math.floor(extruderSelectionBar.width / extruderButtonRepeater.count);
|
||||
return Math.min(UM.Theme.getSize("large_button").width, maximum_width);
|
||||
}
|
||||
height: childrenRect.height
|
||||
|
||||
Cura.ExtruderButton
|
||||
{
|
||||
anchors.margins: 0
|
||||
padding: 0
|
||||
extruder: model
|
||||
checked: extruder.index === selectedIndex
|
||||
iconScale: 0.8
|
||||
font: UM.Theme.getFont("tiny_emphasis")
|
||||
buttonSize: UM.Theme.getSize("small_button").width
|
||||
onClicked: extruder.enabled && onClickExtruder(extruder.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
105
resources/qml/Widgets/SingleSettingSlider.qml
Normal file
105
resources/qml/Widgets/SingleSettingSlider.qml
Normal file
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import UM 1.7 as UM
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
// This silder allows changing of a single setting. Only the setting name has to be passed in to "settingName".
|
||||
// All of the setting updating logic is handled by this component.
|
||||
// This component allows you to choose values between minValue -> maxValue and rounds them to the nearest 10.
|
||||
// If the setting is limited to a single extruder or is settable with different values per extruder use "updateAllExtruders: true"
|
||||
UM.Slider
|
||||
{
|
||||
id: settingSlider
|
||||
|
||||
property alias settingName: propertyProvider.key
|
||||
|
||||
// If true, all extruders will have "settingName" property updated.
|
||||
// The displayed value will be read from the extruder with index "defaultExtruderIndex" instead of the machine.
|
||||
property bool updateAllExtruders: false
|
||||
// This is only used if updateAllExtruders == true
|
||||
property int defaultExtruderIndex: 0
|
||||
property int previousValue: -1
|
||||
|
||||
// set range from 0 to 100
|
||||
from: 0; to: 100
|
||||
// set stepSize to 10 and set snapMode to snap on release snapMode is needed
|
||||
// otherwise the used percentage and slider handle show different values
|
||||
stepSize: 10; snapMode: Slider.SnapOnRelease
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: propertyProvider
|
||||
containerStackId: updateAllExtruders ? Cura.ExtruderManager.extruderIds[defaultExtruderIndex] : Cura.MachineManager.activeMachine.id
|
||||
watchedProperties: ["value"]
|
||||
storeIndex: 0
|
||||
}
|
||||
|
||||
// set initial value from stack
|
||||
value: parseInt(propertyProvider.properties.value)
|
||||
|
||||
// When the slider is released trigger an update immediately. This forces the slider to snap to the rounded value.
|
||||
onPressedChanged: function(pressed)
|
||||
{
|
||||
if(!pressed)
|
||||
{
|
||||
updateSetting(settingSlider.value);
|
||||
}
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: propertyProvider
|
||||
function onContainerStackChanged()
|
||||
{
|
||||
updateTimer.restart()
|
||||
}
|
||||
function onIsValueUsedChanged()
|
||||
{
|
||||
updateTimer.restart()
|
||||
}
|
||||
}
|
||||
|
||||
// Updates to the setting are delayed by interval. This reduces lag by waiting a bit after a setting change to update the slider contents.
|
||||
Timer
|
||||
{
|
||||
id: updateTimer
|
||||
interval: 100
|
||||
repeat: false
|
||||
onTriggered: parseValueUpdateSetting(false)
|
||||
}
|
||||
|
||||
function updateSlider(value)
|
||||
{
|
||||
settingSlider.value = value
|
||||
}
|
||||
|
||||
function parseValueUpdateSetting(triggerUpdate)
|
||||
{
|
||||
// Only run when the setting value is updated by something other than the slider.
|
||||
// This sets the slider value based on the setting value, it does not update the setting value.
|
||||
|
||||
if (parseInt(propertyProvider.properties.value) == settingSlider.value)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
settingSlider.value = propertyProvider.properties.value
|
||||
}
|
||||
|
||||
// Override this function to update a setting differently
|
||||
function updateSetting(value)
|
||||
{
|
||||
if (updateAllExtruders)
|
||||
{
|
||||
Cura.MachineManager.setSettingForAllExtruders(propertyProvider.key, "value", value)
|
||||
}
|
||||
else
|
||||
{
|
||||
propertyProvider.setPropertyValue("value", value)
|
||||
}
|
||||
}
|
||||
}
|
190
resources/qml/Widgets/SingleSettingTextField.qml
Normal file
190
resources/qml/Widgets/SingleSettingTextField.qml
Normal file
|
@ -0,0 +1,190 @@
|
|||
// Copyright (c) 2022 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.7 as UM
|
||||
import Cura 1.7 as Cura
|
||||
|
||||
// This text field allows you to edit a single setting. The setting can be passed by "settingName".
|
||||
// You must specify a validator with Validator. We store our default setting validators in qml/Validators
|
||||
// If the setting is limited to a single extruder or is settable with different values per extruder use "updateAllExtruders: true"
|
||||
UM.TextField
|
||||
{
|
||||
id: control
|
||||
property alias settingName: propertyProvider.key
|
||||
|
||||
// If true, all extruders will have "settingName" property updated.
|
||||
// The displayed value will be read from the extruder with index "defaultExtruderIndex" instead of the machine.
|
||||
property bool updateAllExtruders: false
|
||||
// This is only used if updateAllExtruders == true
|
||||
property int defaultExtruderIndex: 0
|
||||
|
||||
// Resolving the value in the textField.
|
||||
Binding
|
||||
{
|
||||
target: control
|
||||
property: "text"
|
||||
|
||||
value:
|
||||
{
|
||||
if (control.activeFocus)
|
||||
{
|
||||
// This stops the text being reformatted as you edit. For example "10.1" -Edit-> "10." -Auto Format-> "10.0".
|
||||
return control.text
|
||||
}
|
||||
|
||||
if (( propertyProvider.properties.resolve != "None" && propertyProvider.properties.resolve) && ( propertyProvider.properties.stackLevels[0] != 0) && ( propertyProvider.properties.stackLevels[0] != 1))
|
||||
{
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
return base.resolve
|
||||
}
|
||||
|
||||
return propertyProvider.properties.value
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
property UM.SettingPropertyProvider propertyProvider: UM.SettingPropertyProvider
|
||||
{
|
||||
id: propertyProvider
|
||||
watchedProperties: ["value", "validationState", "resolve"]
|
||||
containerStackId: updateAllExtruders ? Cura.ExtruderManager.extruderIds[defaultExtruderIndex] : Cura.MachineManager.activeMachine.id
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: propertyProvider
|
||||
function onContainerStackChanged()
|
||||
{
|
||||
updateTimer.restart()
|
||||
}
|
||||
function onIsValueUsedChanged()
|
||||
{
|
||||
updateTimer.restart()
|
||||
}
|
||||
}
|
||||
|
||||
// Restart update timer right after releasing a key. This stops lag while typing, but you still get warning and error
|
||||
// textfield styling while typing.
|
||||
Keys.onReleased: updateTimer.restart()
|
||||
// Forces formatting when you finish editing "10.1" -Edit-> "10." -Focus Change-> "10"
|
||||
onActiveFocusChanged: updateTimer.restart()
|
||||
|
||||
// Updates to the setting are delayed by interval. This stops lag caused by calling the
|
||||
// parseValueUpdateSetting() function being called repeatedly while changing the text value.
|
||||
Timer
|
||||
{
|
||||
id: updateTimer
|
||||
interval: 50
|
||||
repeat: false
|
||||
onTriggered: parseValueUpdateSetting()
|
||||
}
|
||||
|
||||
function parseValueUpdateSetting()
|
||||
{
|
||||
// User convenience. We use dots for decimal values
|
||||
const modified_text = text.replace(",", ".");
|
||||
if (propertyProvider.properties.value === modified_text || (parseFloat(propertyProvider.properties.value) === parseFloat(modified_text)))
|
||||
{
|
||||
// Don't set the property value from the control. It already has the same value
|
||||
return
|
||||
}
|
||||
|
||||
if (propertyProvider && modified_text !== propertyProvider.properties.value)
|
||||
{
|
||||
updateSetting(modified_text);
|
||||
}
|
||||
}
|
||||
|
||||
function updateSetting(value)
|
||||
{
|
||||
if (updateAllExtruders)
|
||||
{
|
||||
Cura.MachineManager.setSettingForAllExtruders(propertyProvider.key, "value", value)
|
||||
}
|
||||
else
|
||||
{
|
||||
propertyProvider.setPropertyValue("value", text)
|
||||
}
|
||||
}
|
||||
|
||||
// Forced to override parent states using overrideState. Otherwise hover in TextField.qml would override the validation states.
|
||||
// The first state to evaluate true applies styling. States in inheriting components get appended to the state list of their parent.
|
||||
overrideState: true
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "validationError"
|
||||
when: propertyProvider.properties.validationState === "ValidatorState.Exception" || propertyProvider.properties.validationState === "ValidatorState.MinimumError" || propertyProvider.properties.validationState === "ValidatorState.MaximumError"
|
||||
PropertyChanges
|
||||
{
|
||||
target: background
|
||||
liningColor: UM.Theme.getColor("setting_validation_error")
|
||||
color: UM.Theme.getColor("setting_validation_error_background")
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "validationWarning"
|
||||
when: propertyProvider.properties.validationState === "ValidatorState.MinimumWarning" || propertyProvider.properties.validationState === "ValidatorState.MaximumWarning"
|
||||
PropertyChanges
|
||||
{
|
||||
target: background
|
||||
liningColor: UM.Theme.getColor("setting_validation_warning")
|
||||
color: UM.Theme.getColor("setting_validation_warning_background")
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "disabled"
|
||||
when: !control.enabled
|
||||
PropertyChanges
|
||||
{
|
||||
target: control
|
||||
color: UM.Theme.getColor("text_field_text_disabled")
|
||||
}
|
||||
PropertyChanges
|
||||
{
|
||||
target: background
|
||||
liningColor: UM.Theme.getColor("text_field_border_disabled")
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "invalid"
|
||||
when: !control.acceptableInput
|
||||
PropertyChanges
|
||||
{
|
||||
target: background
|
||||
color: UM.Theme.getColor("setting_validation_error_background")
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "active"
|
||||
when: control.activeFocus
|
||||
PropertyChanges
|
||||
{
|
||||
target: background
|
||||
liningColor: UM.Theme.getColor("text_field_border_active")
|
||||
borderColor: UM.Theme.getColor("text_field_border_active")
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "hovered"
|
||||
when: control.hovered && !control.activeFocus
|
||||
PropertyChanges
|
||||
{
|
||||
target: background
|
||||
liningColor: UM.Theme.getColor("text_field_border_hovered")
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -4,87 +4,12 @@
|
|||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.5 as UM
|
||||
import UM 1.7 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
|
||||
//
|
||||
// Cura-style TextField
|
||||
//
|
||||
TextField
|
||||
UM.TextField
|
||||
{
|
||||
id: control
|
||||
|
||||
property alias leftIcon: iconLeft.source
|
||||
|
||||
height: UM.Theme.getSize("setting_control").height
|
||||
|
||||
hoverEnabled: true
|
||||
selectByMouse: true
|
||||
font: UM.Theme.getFont("default")
|
||||
color: UM.Theme.getColor("text_field_text")
|
||||
selectedTextColor: UM.Theme.getColor("text_field_text")
|
||||
placeholderTextColor: UM.Theme.getColor("text_field_text_disabled")
|
||||
renderType: Text.NativeRendering
|
||||
selectionColor: UM.Theme.getColor("text_selection")
|
||||
leftPadding: iconLeft.visible ? iconLeft.width + UM.Theme.getSize("default_margin").width * 2 : UM.Theme.getSize("thin_margin").width
|
||||
|
||||
states: [
|
||||
State
|
||||
{
|
||||
name: "disabled"
|
||||
when: !control.enabled
|
||||
PropertyChanges { target: control; color: UM.Theme.getColor("text_field_text_disabled")}
|
||||
PropertyChanges { target: backgroundRectangle; liningColor: UM.Theme.getColor("text_field_border_disabled")}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "invalid"
|
||||
when: !control.acceptableInput
|
||||
PropertyChanges { target: backgroundRectangle; color: UM.Theme.getColor("setting_validation_error_background")}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "active"
|
||||
when: control.activeFocus
|
||||
PropertyChanges
|
||||
{
|
||||
target: backgroundRectangle
|
||||
liningColor: UM.Theme.getColor("text_field_border_active")
|
||||
borderColor: UM.Theme.getColor("text_field_border_active")
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "hovered"
|
||||
when: control.hovered && !control.activeFocus
|
||||
PropertyChanges
|
||||
{
|
||||
target: backgroundRectangle
|
||||
liningColor: UM.Theme.getColor("text_field_border_hovered")
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
background: UM.UnderlineBackground
|
||||
{
|
||||
id: backgroundRectangle
|
||||
//Optional icon added on the left hand side.
|
||||
UM.ColorImage
|
||||
{
|
||||
id: iconLeft
|
||||
|
||||
anchors
|
||||
{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
|
||||
visible: source != ""
|
||||
height: UM.Theme.getSize("small_button_icon").height
|
||||
width: visible ? height : 0
|
||||
color: control.color
|
||||
}
|
||||
}
|
||||
leftPadding: UM.Theme.getSize("thin_margin").width
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ SettingView 1.0 SettingView.qml
|
|||
ProfileMenu 1.0 ProfileMenu.qml
|
||||
PrintSelectorCard 1.0 PrintSelectorCard.qml
|
||||
|
||||
|
||||
# Cura/WelcomePages
|
||||
|
||||
WizardPanel 1.0 WizardPanel.qml
|
||||
|
@ -38,6 +37,11 @@ ScrollView 1.0 ScrollView.qml
|
|||
Menu 1.0 Menu.qml
|
||||
MenuItem 1.0 MenuItem.qml
|
||||
MenuSeparator 1.0 MenuSeparator.qml
|
||||
SingleSettingExtruderSelectorBar 1.7 SingleSettingExtruderSelectorBar.qml
|
||||
ExtruderButton 1.7 ExtruderButton.qml
|
||||
SingleSettingComboBox 1.7 SingleSettingComboBox.qml
|
||||
SingleSettingSlider 1.7 SingleSettingSlider.qml
|
||||
SingleSettingTextField 1.7 SingleSettingTextField.qml
|
||||
|
||||
|
||||
# Cura/MachineSettings
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue