Fix merge conflicts

This commit is contained in:
Lipu Fei 2018-12-12 13:25:57 +01:00
commit b6ea61612e
265 changed files with 11829 additions and 9342 deletions

View file

@ -373,6 +373,23 @@
}
}
},
"PreviewStage": {
"package_info": {
"package_id": "PreviewStage",
"package_type": "plugin",
"display_name": "Preview Stage",
"description": "Provides a preview stage in Cura.",
"package_version": "1.0.0",
"sdk_version": 5,
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
"display_name": "Ultimaker B.V.",
"email": "plugins@ultimaker.com",
"website": "https://ultimaker.com"
}
}
},
"RemovableDriveOutputDevice": {
"package_info": {
"package_id": "RemovableDriveOutputDevice",

View file

@ -1,170 +0,0 @@
// Copyright (c) 2015 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.1
import UM 1.1 as UM
UM.Dialog
{
id: base
//: About dialog title
title: catalog.i18nc("@title:window","About Cura")
minimumWidth: 500 * screenScaleFactor
minimumHeight: 650 * screenScaleFactor
width: minimumWidth
height: minimumHeight
Rectangle
{
width: parent.width + 2 * margin // margin from Dialog.qml
height: version.y + version.height + margin
anchors.top: parent.top
anchors.topMargin: - margin
anchors.horizontalCenter: parent.horizontalCenter
color: UM.Theme.getColor("viewport_background")
}
Image
{
id: logo
width: (base.minimumWidth * 0.85) | 0
height: (width * (1/4.25)) | 0
source: UM.Theme.getImage("logo")
sourceSize.width: width
sourceSize.height: height
anchors.top: parent.top
anchors.topMargin: ((base.minimumWidth - width) / 2) | 0
anchors.horizontalCenter: parent.horizontalCenter
UM.I18nCatalog{id: catalog; name:"cura"}
}
Label
{
id: version
text: catalog.i18nc("@label","version: %1").arg(UM.Application.version)
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
anchors.right : logo.right
anchors.top: logo.bottom
anchors.topMargin: (UM.Theme.getSize("default_margin").height / 2) | 0
}
Label
{
id: description
width: parent.width
//: About dialog application description
text: catalog.i18nc("@label","End-to-end solution for fused filament 3D printing.")
font: UM.Theme.getFont("system")
wrapMode: Text.WordWrap
anchors.top: version.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
}
Label
{
id: creditsNotes
width: parent.width
//: About dialog application author note
text: catalog.i18nc("@info:credit","Cura is developed by Ultimaker B.V. in cooperation with the community.\nCura proudly uses the following open source projects:")
font: UM.Theme.getFont("system")
wrapMode: Text.WordWrap
anchors.top: description.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
}
ScrollView
{
id: credits
anchors.top: creditsNotes.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
height: base.height - y - (2 * UM.Theme.getSize("default_margin").height + closeButton.height)
ListView
{
id: projectsList
width: parent.width
delegate: Row
{
Label
{
text: "<a href='%1' title='%2'>%2</a>".arg(model.url).arg(model.name)
width: (projectsList.width * 0.25) | 0
elide: Text.ElideRight
onLinkActivated: Qt.openUrlExternally(link)
}
Label
{
text: model.description
elide: Text.ElideRight
width: (projectsList.width * 0.6) | 0
}
Label
{
text: model.license
elide: Text.ElideRight
width: (projectsList.width * 0.15) | 0
}
}
model: ListModel
{
id: projectsModel
}
Component.onCompleted:
{
projectsModel.append({ name:"Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" });
projectsModel.append({ name:"Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" });
projectsModel.append({ name:"CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
projectsModel.append({ name:"libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" });
projectsModel.append({ name:"Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" });
projectsModel.append({ name:"Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" });
projectsModel.append({ name:"PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" });
projectsModel.append({ name:"SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" });
projectsModel.append({ name:"Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
projectsModel.append({ name:"SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" });
projectsModel.append({ name:"NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
projectsModel.append({ name:"NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" });
projectsModel.append({ name:"Shapely", description: catalog.i18nc("@label", "Support library for handling planar objects"), license: "BSD", url: "https://github.com/Toblerity/Shapely" });
projectsModel.append({ name:"Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" });
projectsModel.append({ name:"NetworkX", description: catalog.i18nc("@label", "Support library for analysis of complex networks"), license: "3-clause BSD", url: "https://networkx.github.io/" });
projectsModel.append({ name:"libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" });
projectsModel.append({ name:"libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" });
projectsModel.append({ name:"PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" });
projectsModel.append({ name:"python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" });
projectsModel.append({ name:"Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" });
projectsModel.append({ name:"Requests", description: catalog.i18nc("@Label", "Python HTTP library"), license: "GPL", url: "http://docs.python-requests.org" });
projectsModel.append({ name:"Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" });
projectsModel.append({ name:"Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" });
projectsModel.append({ name:"AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" });
}
}
}
rightButtons: Button
{
//: Close about dialog button
id: closeButton
text: catalog.i18nc("@action:button","Close");
onClicked: base.visible = false;
}
}

View file

@ -0,0 +1,69 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import UM 1.4 as UM
import Cura 1.1 as Cura
Column
{
property var profile: null
property var loggedIn: false
property var profileImage: ""
padding: UM.Theme.getSize("wide_margin").height
spacing: UM.Theme.getSize("wide_margin").height
AvatarImage
{
id: avatar
width: UM.Theme.getSize("avatar_image").width
height: UM.Theme.getSize("avatar_image").height
anchors.horizontalCenter: parent.horizontalCenter
source:
{
if(loggedIn)
{
if(profileImage)
{
return profileImage
}
return UM.Theme.getImage("avatar_no_user")
}
return UM.Theme.getImage("avatar_no_user")
}
outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("lining")
}
Label
{
id: information
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
text: loggedIn ? profile["username"] : catalog.i18nc("@label", "Please log in or create an account to\nenjoy all features of Ultimaker Cura.")
font: loggedIn ? UM.Theme.getFont("large") : UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
Loader
{
id: accountOperations
anchors.horizontalCenter: parent.horizontalCenter
sourceComponent: loggedIn ? userOperations : generalOperations
}
Component
{
id: userOperations
UserOperations { }
}
Component
{
id: generalOperations
GeneralOperations { }
}
}

View file

@ -0,0 +1,76 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import UM 1.4 as UM
import Cura 1.1 as Cura
Button
{
id: accountWidget
property var profile: Cura.API.account.userProfile
property var loggedIn: Cura.API.account.isLoggedIn
implicitHeight: UM.Theme.getSize("main_window_header").height
implicitWidth: UM.Theme.getSize("main_window_header").height
background: AvatarImage
{
id: avatar
width: Math.round(0.8 * accountWidget.width)
height: Math.round(0.8 * accountWidget.height)
anchors.verticalCenter: accountWidget.verticalCenter
anchors.horizontalCenter: accountWidget.horizontalCenter
source:
{
if(loggedIn)
{
if(profile["profile_image_url"])
{
return profile["profile_image_url"]
}
return UM.Theme.getImage("avatar_no_user")
}
return UM.Theme.getImage("avatar_no_user")
}
outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("lining")
}
onClicked: popup.opened ? popup.close() : popup.open()
Popup
{
id: popup
y: parent.height + UM.Theme.getSize("default_arrow").height
x: parent.width - width
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
opacity: opened ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
contentItem: AccountDetails
{
id: panel
profile: Cura.API.account.userProfile
loggedIn: Cura.API.account.isLoggedIn
profileImage: Cura.API.account.profileImageUrl
}
background: UM.PointingRectangle
{
color: UM.Theme.getColor("tool_panel_background")
borderColor: UM.Theme.getColor("lining")
borderWidth: UM.Theme.getSize("default_lining").width
target: Qt.point(width - (accountWidget.width / 2), -10)
arrowSize: UM.Theme.getSize("default_arrow").width
}
}
}

View file

@ -0,0 +1,56 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtGraphicalEffects 1.0
import UM 1.4 as UM
Item
{
// This item shows the provided image while applying a round mask to it.
// It also shows a round border around it. The color is defined by the outlineColor property.
id: avatar
property alias source: profileImage.source
property alias outlineColor: profileImageOutline.color
Image
{
id: profileImage
anchors.fill: parent
source: UM.Theme.getImage("avatar_default")
fillMode: Image.PreserveAspectCrop
visible: false
mipmap: true
}
Rectangle
{
id: profileImageMask
anchors.fill: parent
radius: width
}
OpacityMask
{
anchors.fill: parent
source: profileImage
maskSource: profileImageMask
cached: true
}
UM.RecolorImage
{
id: profileImageOutline
anchors.centerIn: parent
// Make it a bit bigger than it has to, otherwise it sometimes shows a white border.
width: parent.width + 2
height: parent.height + 2
source: UM.Theme.getIcon("circle_outline")
sourceSize: Qt.size(parent.width, parent.height)
color: UM.Theme.getColor("account_widget_ouline_active")
}
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import UM 1.4 as UM
import Cura 1.1 as Cura
Row
{
spacing: UM.Theme.getSize("default_margin").width
Cura.SecondaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Create account")
onClicked: Qt.openUrlExternally("https://account.ultimaker.com/app/create")
fixedWidthMode: true
}
Cura.PrimaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Login")
onClicked: Cura.API.account.login()
fixedWidthMode: true
}
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import UM 1.4 as UM
import Cura 1.1 as Cura
Row
{
spacing: UM.Theme.getSize("default_margin").width
Cura.SecondaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Manage account")
onClicked: Qt.openUrlExternally("https://account.ultimaker.com")
fixedWidthMode: true
}
Cura.PrimaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Logout")
onClicked: Cura.API.account.logout()
fixedWidthMode: true
}
}

View file

@ -0,0 +1,119 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtGraphicalEffects 1.0 // For the dropshadow
import UM 1.1 as UM
import Cura 1.0 as Cura
Button
{
id: button
property bool isIconOnRightSide: false
property alias iconSource: buttonIconLeft.source
property alias textFont: buttonText.font
property alias cornerRadius: backgroundRect.radius
property alias tooltip: tooltip.text
property alias cornerSide: backgroundRect.cornerSide
property color color: UM.Theme.getColor("primary")
property color hoverColor: UM.Theme.getColor("primary_hover")
property color disabledColor: color
property color textColor: UM.Theme.getColor("button_text")
property color textHoverColor: textColor
property color textDisabledColor: textColor
property color outlineColor: color
property color outlineHoverColor: hoverColor
property color outlineDisabledColor: outlineColor
property alias shadowColor: shadow.color
property alias shadowEnabled: shadow.visible
// This property is used to indicate whether the button has a fixed width or the width would depend on the contents
// Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case,
// we elide the text to the right so the text will be cut off with the three dots at the end.
property var fixedWidthMode: false
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("action_button").height
hoverEnabled: true
contentItem: Row
{
//Left side icon. Only displayed if !isIconOnRightSide.
UM.RecolorImage
{
id: buttonIconLeft
source: ""
height: buttonText.height
width: visible ? height : 0
sourceSize.width: width
sourceSize.height: height
color: button.hovered ? button.textHoverColor : button.textColor
visible: source != "" && !button.isIconOnRightSide
anchors.verticalCenter: parent.verticalCenter
}
Label
{
id: buttonText
text: button.text
color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor
font: UM.Theme.getFont("action_button")
visible: text != ""
renderType: Text.NativeRendering
anchors.verticalCenter: parent.verticalCenter
width: fixedWidthMode ? button.width - button.leftPadding - button.rightPadding : undefined
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
}
//Right side icon. Only displayed if isIconOnRightSide.
UM.RecolorImage
{
id: buttonIconRight
source: buttonIconLeft.source
height: buttonText.height
width: visible ? height : 0
sourceSize.width: width
sourceSize.height: height
color: buttonIconLeft.color
visible: source != "" && button.isIconOnRightSide
anchors.verticalCenter: buttonIconLeft.verticalCenter
}
}
background: Cura.RoundedRectangle
{
id: backgroundRect
cornerSide: Cura.RoundedRectangle.Direction.All
color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor
radius: UM.Theme.getSize("action_button_radius").width
border.width: UM.Theme.getSize("default_lining").width
border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor
}
DropShadow
{
id: shadow
// Don't blur the shadow
radius: 0
anchors.fill: backgroundRect
source: backgroundRect
verticalOffset: 2
visible: false
// Should always be drawn behind the background.
z: backgroundRect.z - 1
}
ToolTip
{
id: tooltip
text: ""
delay: 500
visible: text != "" && button.hovered
}
}

View file

@ -0,0 +1,55 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import UM 1.2 as UM
import Cura 1.0 as Cura
// This element hold all the elements needed for the user to trigger the slicing process, and later
// to get information about the printing times, material consumption and the output process (such as
// saving to a file, printing over network, ...
Rectangle
{
id: actionPanelWidget
width: UM.Theme.getSize("action_panel_widget").width
height: childrenRect.height + 2 * UM.Theme.getSize("thick_margin").height
color: UM.Theme.getColor("main_background")
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
radius: UM.Theme.getSize("default_radius").width
property bool outputAvailable: UM.Backend.state == UM.Backend.Done || UM.Backend.state == UM.Backend.Disabled
Loader
{
id: loader
anchors
{
top: parent.top
topMargin: UM.Theme.getSize("thick_margin").height
left: parent.left
leftMargin: UM.Theme.getSize("thick_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("thick_margin").width
}
sourceComponent: outputAvailable ? outputProcessWidget : sliceProcessWidget
}
Component
{
id: sliceProcessWidget
SliceProcessWidget { }
}
Component
{
id: outputProcessWidget
OutputProcessWidget { }
}
}

View file

@ -0,0 +1,107 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import UM 1.1 as UM
import Cura 1.0 as Cura
Item
{
id: widget
Cura.PrimaryButton
{
id: saveToButton
height: parent.height
fixedWidthMode: true
cornerSide: deviceSelectionMenu.visible ? Cura.RoundedRectangle.Direction.Left : Cura.RoundedRectangle.Direction.All
anchors
{
top: parent.top
left: parent.left
right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right
}
tooltip: UM.OutputDeviceManager.activeDeviceDescription
text: UM.OutputDeviceManager.activeDeviceShortDescription
onClicked:
{
forceActiveFocus();
UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName,
{ "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats });
}
}
Cura.ActionButton
{
id: deviceSelectionMenu
height: parent.height
shadowEnabled: true
shadowColor: UM.Theme.getColor("primary_shadow")
cornerSide: Cura.RoundedRectangle.Direction.Right
anchors
{
top: parent.top
right: parent.right
}
leftPadding: UM.Theme.getSize("narrow_margin").width //Need more space than usual here for wide text.
rightPadding: UM.Theme.getSize("narrow_margin").width
tooltip: popup.opened ? "" : catalog.i18nc("@info:tooltip", "Select the active output device")
iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom")
color: UM.Theme.getColor("action_panel_secondary")
visible: (devicesModel.deviceCount > 1)
onClicked: popup.opened ? popup.close() : popup.open()
Popup
{
id: popup
padding: 0
y: -height
x: parent.width - width
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
contentItem: ColumnLayout
{
Repeater
{
model: devicesModel
delegate: Cura.ActionButton
{
text: model.description
color: "transparent"
cornerRadius: 0
hoverColor: UM.Theme.getColor("primary")
Layout.fillWidth: true
onClicked:
{
UM.OutputDeviceManager.setActiveDevice(model.id)
popup.close()
}
}
}
}
background: Rectangle
{
opacity: visible ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
color: UM.Theme.getColor("action_panel_secondary")
}
}
}
UM.OutputDevicesModel { id: devicesModel }
}

View file

@ -0,0 +1,142 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import UM 1.1 as UM
import Cura 1.0 as Cura
// This element contains all the elements the user needs to visualize the data
// that is gather after the slicing process, such as printint time, material usage, ...
// There are also two buttons: one to previsualize the output layers, and the other to
// select what to do with it (such as print over network, save to file, ...)
Column
{
id: widget
spacing: UM.Theme.getSize("thin_margin").height
property bool preSlicedData: PrintInformation.preSliced
UM.I18nCatalog
{
id: catalog
name: "cura"
}
Item
{
id: information
width: parent.width
height: childrenRect.height
Column
{
id: timeAndCostsInformation
spacing: UM.Theme.getSize("thin_margin").height
anchors
{
left: parent.left
right: printInformationPanel.left
rightMargin: UM.Theme.getSize("thin_margin").height
}
Cura.IconWithText
{
id: estimatedTime
width: parent.width
text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long)
source: UM.Theme.getIcon("clock")
font: UM.Theme.getFont("default_bold")
}
Cura.IconWithText
{
id: estimatedCosts
width: parent.width
property var printMaterialLengths: PrintInformation.materialLengths
property var printMaterialWeights: PrintInformation.materialWeights
text:
{
if (preSlicedData)
{
return catalog.i18nc("@label", "No cost estimation available")
}
var totalLengths = 0
var totalWeights = 0
if (printMaterialLengths)
{
for(var index = 0; index < printMaterialLengths.length; index++)
{
if(printMaterialLengths[index] > 0)
{
totalLengths += printMaterialLengths[index]
totalWeights += Math.round(printMaterialWeights[index])
}
}
}
return totalWeights + "g · " + totalLengths.toFixed(2) + "m"
}
source: UM.Theme.getIcon("spool")
}
}
PrintInformationWidget
{
id: printInformationPanel
visible: !preSlicedData
anchors
{
right: parent.right
verticalCenter: timeAndCostsInformation.verticalCenter
}
}
}
Item
{
id: buttonRow
anchors.right: parent.right
anchors.left: parent.left
height: UM.Theme.getSize("action_button").height
Cura.SecondaryButton
{
id: previewStageShortcut
anchors
{
left: parent.left
right: outputDevicesButton.left
rightMargin: UM.Theme.getSize("default_margin").width
}
height: UM.Theme.getSize("action_button").height
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@button", "Preview")
onClicked: UM.Controller.setActiveStage("PreviewStage")
visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage"
shadowEnabled: true
shadowColor: UM.Theme.getColor("action_button_disabled_shadow")
}
Cura.OutputDevicesActionButton
{
id: outputDevicesButton
anchors.right: parent.right
width: previewStageShortcut.visible ? UM.Theme.getSize("action_button").width : parent.width
height: UM.Theme.getSize("action_button").height
}
}
}

View file

@ -0,0 +1,58 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import UM 1.1 as UM
import Cura 1.0 as Cura
UM.RecolorImage
{
id: widget
source: UM.Theme.getIcon("info")
width: UM.Theme.getSize("section_icon").width
height: UM.Theme.getSize("section_icon").height
color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium")
MouseArea
{
anchors.fill: parent
hoverEnabled: true
onEntered: popup.open()
onExited: popup.close()
}
Popup
{
id: popup
y: -(height + UM.Theme.getSize("default_arrow").height + UM.Theme.getSize("thin_margin").height)
x: parent.width - width + UM.Theme.getSize("thin_margin").width
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
opacity: opened ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
contentItem: PrintJobInformation
{
id: printJobInformation
width: UM.Theme.getSize("action_panel_information_widget").width
}
background: UM.PointingRectangle
{
color: UM.Theme.getColor("tool_panel_background")
borderColor: UM.Theme.getColor("lining")
borderWidth: UM.Theme.getSize("default_lining").width
target: Qt.point(width - (widget.width / 2) - UM.Theme.getSize("thin_margin").width,
height + UM.Theme.getSize("default_arrow").height - UM.Theme.getSize("thin_margin").height)
arrowSize: UM.Theme.getSize("default_arrow").width
}
}
}

View file

@ -0,0 +1,159 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import UM 1.1 as UM
import Cura 1.0 as Cura
Column
{
id: base
spacing: UM.Theme.getSize("default_margin").width
UM.I18nCatalog
{
id: catalog
name: "cura"
}
Column
{
id: timeSpecification
width: parent.width
topPadding: UM.Theme.getSize("default_margin").height
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
Label
{
text: catalog.i18nc("@label", "Time specification").toUpperCase()
color: UM.Theme.getColor("primary")
font: UM.Theme.getFont("default_bold")
renderType: Text.NativeRendering
}
Label
{
property var printDuration: PrintInformation.currentPrintTime
text:
{
// All the time information for the different features is achieved
var printTime = PrintInformation.getFeaturePrintTimes()
var totalSeconds = parseInt(printDuration.getDisplayString(UM.DurationFormat.Seconds))
// A message is created and displayed when the user hover the time label
var text = "<table width=\"100%\">"
for(var feature in printTime)
{
if(!printTime[feature].isTotalDurationZero)
{
text += "<tr><td>" + feature + ":</td>" +
"<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(printTime[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) +
"<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1%</td>".arg(Math.round(100 * parseInt(printTime[feature].getDisplayString(UM.DurationFormat.Seconds)) / totalSeconds)) +
"</tr>"
}
}
text += "</table>"
return text
}
width: parent.width - 2 * UM.Theme.getSize("default_margin").width
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
textFormat: Text.RichText
}
}
Column
{
id: materialSpecification
width: parent.width
bottomPadding: UM.Theme.getSize("default_margin").height
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
Label
{
text: catalog.i18nc("@label", "Material specification").toUpperCase()
color: UM.Theme.getColor("primary")
font: UM.Theme.getFont("default_bold")
renderType: Text.NativeRendering
}
Label
{
property var printMaterialLengths: PrintInformation.materialLengths
property var printMaterialWeights: PrintInformation.materialWeights
property var printMaterialCosts: PrintInformation.materialCosts
property var printMaterialNames: PrintInformation.materialNames
function formatRow(items)
{
var rowHTML = "<tr>"
for(var item = 0; item < items.length; item++)
{
if (item == 0)
{
rowHTML += "<td valign=\"bottom\">%1</td>".arg(items[item])
}
else
{
rowHTML += "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(items[item])
}
}
rowHTML += "</tr>"
return rowHTML
}
text:
{
var lengths = []
var weights = []
var costs = []
var names = []
if(printMaterialLengths)
{
for(var index = 0; index < printMaterialLengths.length; index++)
{
if(printMaterialLengths[index] > 0)
{
names.push(printMaterialNames[index])
lengths.push(printMaterialLengths[index].toFixed(2))
weights.push(String(Math.round(printMaterialWeights[index])))
var cost = printMaterialCosts[index] == undefined ? 0 : printMaterialCosts[index].toFixed(2)
costs.push(cost)
}
}
}
if(lengths.length == 0)
{
lengths = ["0.00"]
weights = ["0"]
costs = ["0.00"]
}
var text = "<table width=\"100%\">"
for(var index = 0; index < lengths.length; index++)
{
text += formatRow([
"%1:".arg(names[index]),
catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]),
catalog.i18nc("@label g for grams", "%1g").arg(weights[index]),
"%1&nbsp;%2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]),
])
}
text += "</table>"
return text
}
width: parent.width - 2 * UM.Theme.getSize("default_margin").width
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
textFormat: Text.RichText
}
}
}

View file

@ -0,0 +1,157 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import QtQuick.Controls 1.4 as Controls1
import UM 1.1 as UM
import Cura 1.0 as Cura
// This element contains all the elements the user needs to create a printjob from the
// model(s) that is(are) on the buildplate. Mainly the button to start/stop the slicing
// process and a progress bar to see the progress of the process.
Column
{
id: widget
spacing: UM.Theme.getSize("thin_margin").height
UM.I18nCatalog
{
id: catalog
name: "cura"
}
property real progress: UM.Backend.progress
property int backendState: UM.Backend.state
function sliceOrStopSlicing()
{
if (widget.backendState == UM.Backend.NotStarted)
{
CuraApplication.backend.forceSlice()
}
else
{
CuraApplication.backend.stopSlicing()
}
}
Label
{
id: autoSlicingLabel
width: parent.width
visible: prepareButtons.autoSlice && (widget.backendState == UM.Backend.Processing || widget.backendState == UM.Backend.NotStarted)
text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...")
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
}
Cura.IconWithText
{
id: unableToSliceMessage
width: parent.width
visible: widget.backendState == UM.Backend.Error
text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice")
source: UM.Theme.getIcon("warning")
color: UM.Theme.getColor("warning")
}
// Progress bar, only visible when the backend is in the process of slice the printjob
ProgressBar
{
id: progressBar
width: parent.width
height: UM.Theme.getSize("progressbar").height
value: progress
indeterminate: widget.backendState == UM.Backend.NotStarted
visible: (widget.backendState == UM.Backend.Processing || (prepareButtons.autoSlice && widget.backendState == UM.Backend.NotStarted))
background: Rectangle
{
anchors.fill: parent
radius: UM.Theme.getSize("progressbar_radius").width
color: UM.Theme.getColor("progressbar_background")
}
contentItem: Item
{
anchors.fill: parent
Rectangle
{
width: progressBar.visualPosition * parent.width
height: parent.height
radius: UM.Theme.getSize("progressbar_radius").width
color: UM.Theme.getColor("progressbar_control")
}
}
}
Item
{
id: prepareButtons
// Get the current value from the preferences
property bool autoSlice: UM.Preferences.getValue("general/auto_slice")
// Disable the slice process when
width: parent.width
height: UM.Theme.getSize("action_button").height
visible: !autoSlice
Cura.PrimaryButton
{
id: sliceButton
fixedWidthMode: true
anchors.fill: parent
text: catalog.i18nc("@button", "Slice")
enabled: widget.backendState != UM.Backend.Error
visible: widget.backendState == UM.Backend.NotStarted || widget.backendState == UM.Backend.Error
onClicked: sliceOrStopSlicing()
}
Cura.SecondaryButton
{
id: cancelButton
fixedWidthMode: true
anchors.fill: parent
text: catalog.i18nc("@button", "Cancel")
enabled: sliceButton.enabled
visible: !sliceButton.visible
onClicked: sliceOrStopSlicing()
}
}
// React when the user changes the preference of having the auto slice enabled
Connections
{
target: UM.Preferences
onPreferenceChanged:
{
var autoSlice = UM.Preferences.getValue("general/auto_slice")
prepareButtons.autoSlice = autoSlice
if(autoSlice)
{
CuraApplication.backend.forceSlice()
}
}
}
// Shortcut for "slice/stop"
Controls1.Action
{
shortcut: "Ctrl+P"
onTriggered:
{
if (prepareButton.enabled)
{
sliceOrStopSlicing()
}
}
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2015 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
pragma Singleton
@ -23,8 +23,6 @@ Item
property alias viewLeftSideCamera: viewLeftSideCameraAction;
property alias viewRightSideCamera: viewRightSideCameraAction;
property alias expandSidebar: expandSidebarAction;
property alias deleteSelection: deleteSelectionAction;
property alias centerSelection: centerSelectionAction;
property alias multiplySelection: multiplySelectionAction;
@ -58,7 +56,6 @@ Item
property alias preferences: preferencesAction;
property alias showEngineLog: showEngineLogAction;
property alias showProfileFolder: showProfileFolderAction;
property alias documentation: documentationAction;
property alias reportBug: reportBugAction;
@ -70,7 +67,7 @@ Item
property alias browsePackages: browsePackagesAction
UM.I18nCatalog{id: catalog; name:"cura"}
UM.I18nCatalog{id: catalog; name: "cura"}
Action
{
@ -398,14 +395,6 @@ Item
shortcut: StandardKey.New
}
Action
{
id: showEngineLogAction;
text: catalog.i18nc("@action:inmenu menubar:help","Show Engine &Log...");
iconName: "view-list-text";
shortcut: StandardKey.WhatsThis;
}
Action
{
id: showProfileFolderAction;
@ -426,11 +415,4 @@ Item
text: catalog.i18nc("@action:menu", "&Marketplace")
iconName: "plugins_browse"
}
Action
{
id: expandSidebarAction;
text: catalog.i18nc("@action:inmenu menubar:view","Expand/Collapse Sidebar");
shortcut: "Ctrl+E";
}
}

View file

@ -0,0 +1,10 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.0
QtObject
{
property real width: 0
property color color: "black"
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
@ -6,53 +6,42 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import QtGraphicalEffects 1.0
import UM 1.3 as UM
import Cura 1.1 as Cura
import "Dialogs"
import "Menus"
import "MainWindow"
UM.MainWindow
{
id: base
//: Cura application window title
title: catalog.i18nc("@title:window","Ultimaker Cura");
viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
property bool showPrintMonitor: false
// Cura application window title
title: catalog.i18nc("@title:window", "Ultimaker Cura")
backgroundColor: UM.Theme.getColor("viewport_background")
// This connection is here to support legacy printer output devices that use the showPrintMonitor signal on Application to switch to the monitor stage
// It should be phased out in newer plugin versions.
Connections
UM.I18nCatalog
{
target: CuraApplication
onShowPrintMonitor: {
if (show) {
UM.Controller.setActiveStage("MonitorStage")
} else {
UM.Controller.setActiveStage("PrepareStage")
}
}
id: catalog
name: "cura"
}
onWidthChanged:
function showTooltip(item, position, text)
{
// If slidebar is collapsed then it should be invisible
// otherwise after the main_window resize the sidebar will be fully re-drawn
if (sidebar.collapsed){
if (sidebar.visible == true){
sidebar.visible = false
sidebar.initialWidth = 0
}
}
else{
if (sidebar.visible == false){
sidebar.visible = true
sidebar.initialWidth = UM.Theme.getSize("sidebar").width
}
}
tooltip.text = text;
position = item.mapToItem(backgroundItem, position.x - UM.Theme.getSize("default_arrow").width, position.y);
tooltip.show(position);
}
function hideTooltip()
{
tooltip.hide();
}
Component.onCompleted:
{
CuraApplication.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size"))
@ -72,12 +61,12 @@ UM.MainWindow
Item
{
id: backgroundItem;
anchors.fill: parent;
UM.I18nCatalog{id: catalog; name:"cura"}
id: backgroundItem
anchors.fill: parent
signal hasMesh(string name) //this signal sends the filebase name so it can be used for the JobSpecs.qml
function getMeshName(path){
function getMeshName(path)
{
//takes the path the complete path of the meshname and returns only the filebase
var fileName = path.slice(path.lastIndexOf("/") + 1)
var fileBase = fileName.slice(0, fileName.indexOf("."))
@ -85,253 +74,86 @@ UM.MainWindow
}
//DeleteSelection on the keypress backspace event
Keys.onPressed: {
Keys.onPressed:
{
if (event.key == Qt.Key_Backspace)
{
Cura.Actions.deleteSelection.trigger()
}
}
UM.ApplicationMenu
ApplicationMenu
{
id: menu
id: applicationMenu
window: base
Menu
{
id: fileMenu
title: catalog.i18nc("@title:menu menubar:toplevel","&File");
MenuItem
{
id: newProjectMenu
action: Cura.Actions.newProject;
}
MenuItem
{
id: openMenu
action: Cura.Actions.open;
}
RecentFilesMenu { }
MenuItem
{
id: saveWorkspaceMenu
text: catalog.i18nc("@title:menu menubar:file","&Save...")
onTriggered:
{
var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" };
if(UM.Preferences.getValue("cura/dialog_on_project_save"))
{
saveWorkspaceDialog.args = args;
saveWorkspaceDialog.open()
}
else
{
UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args)
}
}
}
MenuSeparator { }
MenuItem
{
id: saveAsMenu
text: catalog.i18nc("@title:menu menubar:file", "&Export...")
onTriggered:
{
var localDeviceId = "local_file";
UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"});
}
}
MenuItem
{
id: exportSelectionMenu
text: catalog.i18nc("@action:inmenu menubar:file", "Export Selection...");
enabled: UM.Selection.hasSelection;
iconName: "document-save-as";
onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"});
}
MenuSeparator { }
MenuItem
{
id: reloadAllMenu
action: Cura.Actions.reloadAll;
}
MenuSeparator { }
MenuItem { action: Cura.Actions.quit; }
}
Menu
{
title: catalog.i18nc("@title:menu menubar:toplevel","&Edit");
MenuItem { action: Cura.Actions.undo; }
MenuItem { action: Cura.Actions.redo; }
MenuSeparator { }
MenuItem { action: Cura.Actions.selectAll; }
MenuItem { action: Cura.Actions.arrangeAll; }
MenuItem { action: Cura.Actions.deleteSelection; }
MenuItem { action: Cura.Actions.deleteAll; }
MenuItem { action: Cura.Actions.resetAllTranslation; }
MenuItem { action: Cura.Actions.resetAll; }
MenuSeparator { }
MenuItem { action: Cura.Actions.groupObjects;}
MenuItem { action: Cura.Actions.mergeObjects;}
MenuItem { action: Cura.Actions.unGroupObjects;}
}
ViewMenu { title: catalog.i18nc("@title:menu", "&View") }
Menu
{
id: settingsMenu
title: catalog.i18nc("@title:menu", "&Settings")
PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") }
Instantiator
{
model: Cura.ExtrudersModel { simpleNames: true }
Menu {
title: model.name
NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index }
MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index }
MenuSeparator
{
visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials
}
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Set as Active Extruder")
onTriggered: Cura.MachineManager.setExtruderIndex(model.index)
}
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Enable Extruder")
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true)
visible: !Cura.MachineManager.getExtruder(model.index).isEnabled
}
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Disable Extruder")
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
visible: Cura.MachineManager.getExtruder(model.index).isEnabled
enabled: Cura.MachineManager.numberExtrudersEnabled > 1
}
}
onObjectAdded: settingsMenu.insertItem(index, object)
onObjectRemoved: settingsMenu.removeItem(object)
}
// TODO Only show in dev mode. Remove check when feature ready
BuildplateMenu { title: catalog.i18nc("@title:menu", "&Build plate"); visible: CuraSDKVersion == "dev" ? Cura.MachineManager.hasVariantBuildplates : false }
ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile"); }
MenuSeparator { }
MenuItem { action: Cura.Actions.configureSettingVisibility }
}
Menu
{
id: extension_menu
title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions");
Instantiator
{
id: extensions
model: UM.ExtensionModel { }
Menu
{
id: sub_menu
title: model.name;
visible: actions != null
enabled: actions != null
Instantiator
{
model: actions
MenuItem
{
text: model.text
onTriggered: extensions.model.subMenuTriggered(name, model.text)
}
onObjectAdded: sub_menu.insertItem(index, object)
onObjectRemoved: sub_menu.removeItem(object)
}
}
onObjectAdded: extension_menu.insertItem(index, object)
onObjectRemoved: extension_menu.removeItem(object)
}
}
Menu
{
id: plugin_menu
title: catalog.i18nc("@title:menu menubar:toplevel", "&Marketplace")
MenuItem { action: Cura.Actions.browsePackages }
}
Menu
{
id: preferencesMenu
title: catalog.i18nc("@title:menu menubar:toplevel","P&references");
MenuItem { action: Cura.Actions.preferences; }
}
Menu
{
id: helpMenu
title: catalog.i18nc("@title:menu menubar:toplevel","&Help");
MenuItem { action: Cura.Actions.showProfileFolder; }
MenuItem { action: Cura.Actions.documentation; }
MenuItem { action: Cura.Actions.reportBug; }
MenuSeparator { }
MenuItem { action: Cura.Actions.about; }
}
}
UM.SettingPropertyProvider
{
id: machineExtruderCount
containerStack: Cura.MachineManager.activeMachine
key: "machine_extruder_count"
watchedProperties: [ "value" ]
storeIndex: 0
}
Item
{
id: contentItem;
id: headerBackground
anchors
{
top: applicationMenu.bottom
left: parent.left
right: parent.right
}
height: stageMenu.source != "" ? Math.round(mainWindowHeader.height + stageMenu.height / 2) : mainWindowHeader.height
y: menu.height
width: parent.width;
height: parent.height - menu.height;
LinearGradient
{
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(parent.width, 0)
gradient: Gradient
{
GradientStop
{
position: 0.0
color: UM.Theme.getColor("main_window_header_background")
}
GradientStop
{
position: 0.5
color: UM.Theme.getColor("main_window_header_background_gradient")
}
GradientStop
{
position: 1.0
color: UM.Theme.getColor("main_window_header_background")
}
}
}
}
Keys.forwardTo: menu
MainWindowHeader
{
id: mainWindowHeader
anchors
{
left: parent.left
right: parent.right
top: applicationMenu.bottom
}
}
Item
{
id: contentItem
anchors
{
top: mainWindowHeader.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
}
Keys.forwardTo: applicationMenu
DropArea
{
anchors.fill: parent;
// The drop area is here to handle files being dropped onto Cura.
anchors.fill: parent
onDropped:
{
if (drop.urls.length > 0)
@ -359,156 +181,110 @@ UM.MainWindow
}
}
JobSpecs
{
id: jobSpecs
anchors
{
bottom: parent.bottom;
right: sidebar.left;
bottomMargin: UM.Theme.getSize("default_margin").height;
rightMargin: UM.Theme.getSize("default_margin").width;
}
}
Button
{
id: openFileButton;
text: catalog.i18nc("@action:button","Open File");
iconSource: UM.Theme.getIcon("load")
style: UM.Theme.styles.tool_button
tooltip: ""
anchors
{
top: topbar.bottom;
topMargin: UM.Theme.getSize("default_margin").height;
left: parent.left;
}
action: Cura.Actions.open;
}
Toolbar
{
id: toolbar;
// The toolbar is the left bar that is populated by all the tools (which are dynamicly populated by
// plugins)
id: toolbar
property int mouseX: base.mouseX
property int mouseY: base.mouseY
anchors {
top: openFileButton.bottom;
topMargin: UM.Theme.getSize("window_margin").height;
left: parent.left;
anchors
{
verticalCenter: parent.verticalCenter
left: parent.left
}
visible: CuraApplication.platformActivity && !PrintInformation.preSliced
}
ObjectsList
{
id: objectsList;
visible: UM.Preferences.getValue("cura/use_multi_build_plate");
id: objectsList
visible: UM.Preferences.getValue("cura/use_multi_build_plate")
anchors
{
bottom: parent.bottom;
left: parent.left;
bottom: viewOrientationControls.top
left: toolbar.right
margins: UM.Theme.getSize("default_margin").width
}
}
Topbar
JobSpecs
{
id: jobSpecs
visible: CuraApplication.platformActivity
anchors
{
left: parent.left
bottom: viewOrientationControls.top
margins: UM.Theme.getSize("default_margin").width
bottomMargin: UM.Theme.getSize("thin_margin").width
}
}
ViewOrientationControls
{
id: viewOrientationControls
anchors
{
left: parent.left
bottom: parent.bottom
margins: UM.Theme.getSize("default_margin").width
}
}
Cura.ActionPanelWidget
{
id: topbar
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.rightMargin: UM.Theme.getSize("thick_margin").width
anchors.bottomMargin: UM.Theme.getSize("thick_margin").height
visible: CuraApplication.platformActivity
}
Loader
{
// A stage can control this area. If nothing is set, it will therefore show the 3D view.
id: main
anchors
{
top: topbar.bottom
bottom: parent.bottom
// Align to the top of the stageMenu since the stageMenu may not exist
top: parent.top
left: parent.left
right: sidebar.left
right: parent.right
bottom: parent.bottom
}
MouseArea
{
visible: UM.Controller.activeStage.mainComponent != ""
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onWheel: wheel.accepted = true
}
source: UM.Controller.activeStage.mainComponent
source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : ""
}
Loader
{
id: sidebar
property bool collapsed: false;
property var initialWidth: UM.Theme.getSize("sidebar").width;
function callExpandOrCollapse() {
if (collapsed) {
sidebar.visible = true;
sidebar.initialWidth = UM.Theme.getSize("sidebar").width;
viewportRect = Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0);
expandSidebarAnimation.start();
} else {
viewportRect = Qt.rect(0, 0, 1, 1.0);
collapseSidebarAnimation.start();
}
collapsed = !collapsed;
UM.Preferences.setValue("cura/sidebar_collapsed", collapsed);
}
// The stage menu is, as the name implies, a menu that is defined by the active stage.
// Note that this menu does not need to be set at all! It's perfectly acceptable to have a stage
// without this menu!
id: stageMenu
anchors
{
top: topbar.top
bottom: parent.bottom
left: parent.left
right: parent.right
top: parent.top
}
width: initialWidth
x: base.width - sidebar.width
source: UM.Controller.activeStage.sidebarComponent
height: UM.Theme.getSize("stage_menu").height
source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : ""
NumberAnimation {
id: collapseSidebarAnimation
target: sidebar
properties: "x"
to: base.width
duration: 100
}
NumberAnimation {
id: expandSidebarAnimation
target: sidebar
properties: "x"
to: base.width - sidebar.width
duration: 100
}
Component.onCompleted:
// The printSetupSelector is defined here so that the setting list doesn't need to get re-instantiated
// Every time the stage is changed.
property var printSetupSelector: Cura.PrintSetupSelector
{
var sidebar_collapsed = UM.Preferences.getValue("cura/sidebar_collapsed");
if (sidebar_collapsed)
{
sidebar.collapsed = true;
viewportRect = Qt.rect(0, 0, 1, 1.0)
collapseSidebarAnimation.start();
}
}
MouseArea
{
visible: UM.Controller.activeStage.sidebarComponent != ""
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onWheel: wheel.accepted = true
width: UM.Theme.getSize("print_setup_widget").width
height: UM.Theme.getSize("stage_menu").height
headerCornerSide: RoundedRectangle.Direction.Right
}
}
@ -517,20 +293,17 @@ UM.MainWindow
anchors
{
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: -(Math.round(UM.Theme.getSize("sidebar").width / 2))
top: parent.verticalCenter;
bottom: parent.bottom;
top: parent.verticalCenter
bottom: parent.bottom
bottomMargin: UM.Theme.getSize("default_margin").height
}
}
}
}
// Expand or collapse sidebar
Connections
{
target: Cura.Actions.expandSidebar
onTriggered: sidebar.callExpandOrCollapse()
PrintSetupTooltip
{
id: tooltip
}
}
UM.PreferencesDialog
@ -567,13 +340,6 @@ UM.MainWindow
}
}
WorkspaceSummaryDialog
{
id: saveWorkspaceDialog
property var args
onYes: UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args)
}
Connections
{
target: Cura.Actions.preferences
@ -586,33 +352,6 @@ UM.MainWindow
onShowPreferencesWindow: preferences.visible = true
}
MessageDialog
{
id: newProjectDialog
modality: Qt.ApplicationModal
title: catalog.i18nc("@title:window", "New project")
text: catalog.i18nc("@info:question", "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings.")
standardButtons: StandardButton.Yes | StandardButton.No
icon: StandardIcon.Question
onYes:
{
CuraApplication.deleteAll();
Cura.Actions.resetProfile.trigger();
}
}
Connections
{
target: Cura.Actions.newProject
onTriggered:
{
if(Printer.platformActivity || Cura.MachineManager.hasUserSettings)
{
newProjectDialog.visible = true
}
}
}
Connections
{
target: Cura.Actions.addProfile
@ -670,19 +409,6 @@ UM.MainWindow
}
}
UM.ExtensionModel {
id: curaExtensions
}
// show the plugin browser dialog
Connections
{
target: Cura.Actions.browsePackages
onTriggered: {
curaExtensions.callExtensionMethod("Toolbox", "browsePackages")
}
}
Timer
{
id: createProfileTimer
@ -703,7 +429,8 @@ UM.MainWindow
}
}
ContextMenu {
ContextMenu
{
id: contextMenu
}
@ -870,7 +597,8 @@ UM.MainWindow
modality: Qt.ApplicationModal
}
MessageDialog {
MessageDialog
{
id: infoMultipleFilesWithGcodeDialog
title: catalog.i18nc("@title:window", "Open File(s)")
icon: StandardIcon.Information
@ -914,11 +642,6 @@ UM.MainWindow
}
}
EngineLog
{
id: engineLog;
}
Connections
{
target: Cura.Actions.showProfileFolder

View file

@ -0,0 +1,168 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.1
import UM 1.1 as UM
UM.Dialog
{
id: base
//: About dialog title
title: catalog.i18nc("@title:window","About Cura")
minimumWidth: 500 * screenScaleFactor
minimumHeight: 650 * screenScaleFactor
width: minimumWidth
height: minimumHeight
Rectangle
{
width: parent.width + 2 * margin // margin from Dialog.qml
height: version.y + version.height + margin
anchors.top: parent.top
anchors.topMargin: - margin
anchors.horizontalCenter: parent.horizontalCenter
color: UM.Theme.getColor("viewport_background")
}
Image
{
id: logo
width: (base.minimumWidth * 0.85) | 0
height: (width * (UM.Theme.getSize("logo").height / UM.Theme.getSize("logo").width)) | 0
source: UM.Theme.getImage("logo_about")
anchors.top: parent.top
anchors.topMargin: ((base.minimumWidth - width) / 2) | 0
anchors.horizontalCenter: parent.horizontalCenter
UM.I18nCatalog{id: catalog; name: "cura"}
}
Label
{
id: version
text: catalog.i18nc("@label","version: %1").arg(UM.Application.version)
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
anchors.right : logo.right
anchors.top: logo.bottom
anchors.topMargin: (UM.Theme.getSize("default_margin").height / 2) | 0
}
Label
{
id: description
width: parent.width
//: About dialog application description
text: catalog.i18nc("@label","End-to-end solution for fused filament 3D printing.")
font: UM.Theme.getFont("system")
wrapMode: Text.WordWrap
anchors.top: version.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
}
Label
{
id: creditsNotes
width: parent.width
//: About dialog application author note
text: catalog.i18nc("@info:credit","Cura is developed by Ultimaker B.V. in cooperation with the community.\nCura proudly uses the following open source projects:")
font: UM.Theme.getFont("system")
wrapMode: Text.WordWrap
anchors.top: description.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
}
ScrollView
{
id: credits
anchors.top: creditsNotes.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
height: base.height - y - (2 * UM.Theme.getSize("default_margin").height + closeButton.height)
ListView
{
id: projectsList
width: parent.width
delegate: Row
{
Label
{
text: "<a href='%1' title='%2'>%2</a>".arg(model.url).arg(model.name)
width: (projectsList.width * 0.25) | 0
elide: Text.ElideRight
onLinkActivated: Qt.openUrlExternally(link)
}
Label
{
text: model.description
elide: Text.ElideRight
width: (projectsList.width * 0.6) | 0
}
Label
{
text: model.license
elide: Text.ElideRight
width: (projectsList.width * 0.15) | 0
}
}
model: ListModel
{
id: projectsModel
}
Component.onCompleted:
{
projectsModel.append({ name: "Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" });
projectsModel.append({ name: "Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" });
projectsModel.append({ name: "CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
projectsModel.append({ name: "libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" });
projectsModel.append({ name: "Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" });
projectsModel.append({ name: "Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" });
projectsModel.append({ name: "PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" });
projectsModel.append({ name: "SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" });
projectsModel.append({ name: "Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
projectsModel.append({ name: "SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" });
projectsModel.append({ name: "NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
projectsModel.append({ name: "NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" });
projectsModel.append({ name: "Shapely", description: catalog.i18nc("@label", "Support library for handling planar objects"), license: "BSD", url: "https://github.com/Toblerity/Shapely" });
projectsModel.append({ name: "Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" });
projectsModel.append({ name: "NetworkX", description: catalog.i18nc("@label", "Support library for analysis of complex networks"), license: "3-clause BSD", url: "https://networkx.github.io/" });
projectsModel.append({ name: "libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" });
projectsModel.append({ name: "libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" });
projectsModel.append({ name: "PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" });
projectsModel.append({ name: "python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" });
projectsModel.append({ name: "Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" });
projectsModel.append({ name: "Requests", description: catalog.i18nc("@Label", "Python HTTP library"), license: "GPL", url: "http://docs.python-requests.org" });
projectsModel.append({ name: "Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" });
projectsModel.append({ name: "Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" });
projectsModel.append({ name: "AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" });
}
}
}
rightButtons: Button
{
//: Close about dialog button
id: closeButton
text: catalog.i18nc("@action:button","Close");
onClicked: base.visible = false;
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@ -156,7 +156,6 @@ UM.Dialog
anchors.rightMargin: UM.Theme.getSize("default_margin").width
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: width
color: palette.windowText
source: base.activeCategory == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right")
@ -170,7 +169,7 @@ UM.Dialog
if (machineList.model.getItem(machineList.currentIndex).section != section)
{
// Find the first machine from this section
for(var i = 0; i < machineList.model.rowCount(); i++)
for(var i = 0; i < machineList.model.count; i++)
{
var item = machineList.model.getItem(i);
if (item.section == section)
@ -276,7 +275,6 @@ UM.Dialog
id: machineName
text: getMachineName()
width: Math.floor(parent.width * 0.75)
implicitWidth: UM.Theme.getSize("standard_list_input").width
maximumLength: 40
//validator: Cura.MachineNameValidator { } //TODO: Gives a segfault in PyQt5.6. For now, we must use a signal on text changed.
validator: RegExpValidator

View file

@ -11,6 +11,7 @@ import Cura 1.0 as Cura
UM.Dialog
{
id: base
title: catalog.i18nc("@title:window", "Save Project")
minimumWidth: 500 * screenScaleFactor
@ -49,7 +50,7 @@ UM.Dialog
UM.SettingDefinitionsModel
{
id: definitionsModel
containerId: Cura.MachineManager.activeDefinitionId
containerId: base.visible ? Cura.MachineManager.activeDefinitionId: ""
showAll: true
exclude: ["command_line_settings"]
showAncestors: true

View file

@ -1,53 +0,0 @@
// Copyright (c) 2015 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import UM 1.1 as UM
UM.Dialog
{
id: dialog;
//: Engine Log dialog title
title: catalog.i18nc("@title:window","Engine Log");
modality: Qt.NonModal;
TextArea
{
id: textArea
anchors.fill: parent;
Timer
{
id: updateTimer;
interval: 1000;
running: false;
repeat: true;
onTriggered: textArea.text = CuraApplication.getEngineLog();
}
UM.I18nCatalog{id: catalog; name:"cura"}
}
rightButtons: Button
{
//: Close engine log button
text: catalog.i18nc("@action:button","Close");
onClicked: dialog.visible = false;
}
onVisibleChanged:
{
if(visible)
{
textArea.text = CuraApplication.getEngineLog();
updateTimer.start();
} else
{
updateTimer.stop();
}
}
}

View file

@ -0,0 +1,262 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
import QtGraphicalEffects 1.0 // For the dropshadow
// The expandable component has 2 major sub components:
// * The headerItem; Always visible and should hold some info about what happens if the component is expanded
// * The contentItem; The content that needs to be shown if the component is expanded.
Item
{
id: base
// Enumeration with the different possible alignments of the content with respect of the headerItem
enum ContentAlignment
{
AlignLeft,
AlignRight
}
// The headerItem holds the QML item that is always displayed.
property alias headerItem: headerItemLoader.sourceComponent
// The contentItem holds the QML item that is shown when the "open" button is pressed
property alias contentItem: content.contentItem
property color contentBackgroundColor: UM.Theme.getColor("action_button")
property color headerBackgroundColor: UM.Theme.getColor("action_button")
property color headerActiveColor: UM.Theme.getColor("secondary")
property color headerHoverColor: UM.Theme.getColor("action_button_hovered")
property alias enabled: mouseArea.enabled
// Text to show when this component is disabled
property alias disabledText: disabledLabel.text
// Defines the alignment of the content with respect of the headerItem, by default to the right
property int contentAlignment: ExpandableComponent.ContentAlignment.AlignRight
// How much spacing is needed around the contentItem
property alias contentPadding: content.padding
// Adds a title to the content item
property alias contentHeaderTitle: contentHeader.headerTitle
// How much spacing is needed for the contentItem by Y coordinate
property var contentSpacingY: UM.Theme.getSize("narrow_margin").width
// How much padding is needed around the header & button
property alias headerPadding: background.padding
// What icon should be displayed on the right.
property alias iconSource: collapseButton.source
property alias iconColor: collapseButton.color
// The icon size (it's always drawn as a square)
property alias iconSize: collapseButton.height
// Is the "drawer" open?
readonly property alias expanded: contentContainer.visible
// What should the radius of the header be. This is also influenced by the headerCornerSide
property alias headerRadius: background.radius
// On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right.
property alias headerCornerSide: background.cornerSide
property alias headerShadowColor: shadow.color
property alias enableHeaderShadow: shadow.visible
property int shadowOffset: 2
function toggleContent()
{
contentContainer.visible = !expanded
}
// Add this binding since the background color is not updated otherwise
Binding
{
target: background
property: "color"
value:
{
return base.enabled ? (expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled")
}
}
// The panel needs to close when it becomes disabled
Connections
{
target: base
onEnabledChanged:
{
if (!base.enabled && expanded)
{
toggleContent()
}
}
}
implicitHeight: 100 * screenScaleFactor
implicitWidth: 400 * screenScaleFactor
RoundedRectangle
{
id: background
property real padding: UM.Theme.getSize("default_margin").width
color: base.enabled ? (base.expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled")
anchors.fill: parent
Label
{
id: disabledLabel
visible: !base.enabled
anchors.fill: parent
leftPadding: background.padding
rightPadding: background.padding
text: ""
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
color: UM.Theme.getColor("text")
wrapMode: Text.WordWrap
}
Item
{
anchors.fill: parent
visible: base.enabled
Loader
{
id: headerItemLoader
anchors
{
left: parent.left
right: collapseButton.visible ? collapseButton.left : parent.right
top: parent.top
bottom: parent.bottom
margins: background.padding
}
}
UM.RecolorImage
{
id: collapseButton
anchors
{
right: parent.right
verticalCenter: parent.verticalCenter
margins: background.padding
}
source: UM.Theme.getIcon("pencil")
visible: source != ""
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
color: UM.Theme.getColor("small_button_text")
}
}
MouseArea
{
id: mouseArea
anchors.fill: parent
onClicked: toggleContent()
hoverEnabled: true
onEntered: background.color = headerHoverColor
onExited: background.color = base.enabled ? (base.expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled")
}
}
DropShadow
{
id: shadow
// Don't blur the shadow
radius: 0
anchors.fill: background
source: background
verticalOffset: base.shadowOffset
visible: true
color: UM.Theme.getColor("action_button_shadow")
// Should always be drawn behind the background.
z: background.z - 1
}
Cura.RoundedRectangle
{
id: contentContainer
visible: false
width: childrenRect.width
height: childrenRect.height
// Ensure that the content is located directly below the headerItem
y: background.height + base.shadowOffset + base.contentSpacingY
// Make the content aligned with the rest, using the property contentAlignment to decide whether is right or left.
// In case of right alignment, the 3x padding is due to left, right and padding between the button & text.
x: contentAlignment == ExpandableComponent.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0
cornerSide: Cura.RoundedRectangle.Direction.All
color: contentBackgroundColor
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
radius: UM.Theme.getSize("default_radius").width
ExpandableComponentHeader
{
id: contentHeader
headerTitle: ""
anchors
{
top: parent.top
right: parent.right
left: parent.left
}
}
Control
{
id: content
anchors.top: contentHeader.bottom
padding: UM.Theme.getSize("default_margin").width
contentItem: Item {}
onContentItemChanged:
{
// Since we want the size of the content to be set by the size of the content,
// we need to do it like this.
content.width = contentItem.width + 2 * content.padding
content.height = contentItem.height + 2 * content.padding
}
}
}
// DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item.
// Apparently the order in which these are handled matters and so the height is correctly updated if this is here.
Connections
{
// Since it could be that the content is dynamically populated, we should also take these changes into account.
target: content.contentItem
onWidthChanged: content.width = content.contentItem.width + 2 * content.padding
onHeightChanged:
{
content.height = content.contentItem.height + 2 * content.padding
contentContainer.height = contentHeader.height + content.height
}
}
}

View file

@ -0,0 +1,68 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
// Header of the popup
Cura.RoundedRectangle
{
id: header
property alias headerTitle: headerLabel.text
height: UM.Theme.getSize("expandable_component_content_header").height
color: UM.Theme.getColor("secondary")
cornerSide: Cura.RoundedRectangle.Direction.Up
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
radius: UM.Theme.getSize("default_radius").width
Label
{
id: headerLabel
text: ""
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
color: UM.Theme.getColor("small_button_text")
height: parent.height
anchors
{
topMargin: UM.Theme.getSize("default_margin").height
left: parent.left
leftMargin: UM.Theme.getSize("default_margin").height
}
}
Button
{
id: closeButton
width: UM.Theme.getSize("message_close").width
height: UM.Theme.getSize("message_close").height
hoverEnabled: true
anchors
{
right: parent.right
rightMargin: UM.Theme.getSize("default_margin").width
verticalCenter: parent.verticalCenter
}
contentItem: UM.RecolorImage
{
anchors.fill: parent
sourceSize.width: width
color: closeButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text")
source: UM.Theme.getIcon("cross1")
}
background: Item {}
onClicked: toggleContent() // Will hide the popup item
}
}

View file

@ -0,0 +1,250 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
import QtGraphicalEffects 1.0 // For the dropshadow
// The expandable component has 2 major sub components:
// * The headerItem; Always visible and should hold some info about what happens if the component is expanded
// * The contentItem; The content that needs to be shown if the component is expanded.
Item
{
id: base
// Enumeration with the different possible alignments of the content with respect of the headerItem
enum ContentAlignment
{
AlignLeft,
AlignRight
}
// The headerItem holds the QML item that is always displayed.
property alias headerItem: headerItemLoader.sourceComponent
// The contentItem holds the QML item that is shown when the "open" button is pressed
property alias contentItem: content.contentItem
property color contentBackgroundColor: UM.Theme.getColor("action_button")
property color headerBackgroundColor: UM.Theme.getColor("action_button")
property color headerActiveColor: UM.Theme.getColor("secondary")
property color headerHoverColor: UM.Theme.getColor("action_button_hovered")
property alias enabled: mouseArea.enabled
// Text to show when this component is disabled
property alias disabledText: disabledLabel.text
// Defines the alignment of the content with respect of the headerItem, by default to the right
property int contentAlignment: ExpandablePopup.ContentAlignment.AlignRight
// How much spacing is needed around the contentItem
property alias contentPadding: content.padding
// How much padding is needed around the header & button
property alias headerPadding: background.padding
// What icon should be displayed on the right.
property alias iconSource: collapseButton.source
property alias iconColor: collapseButton.color
// The icon size (it's always drawn as a square)
property alias iconSize: collapseButton.height
// Is the "drawer" open?
readonly property alias expanded: content.visible
property alias expandedHighlightColor: expandedHighlight.color
// What should the radius of the header be. This is also influenced by the headerCornerSide
property alias headerRadius: background.radius
// On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right.
property alias headerCornerSide: background.cornerSide
// Change the contentItem close behaviour
property alias contentClosePolicy : content.closePolicy
property alias headerShadowColor: shadow.color
property alias enableHeaderShadow: shadow.visible
property int shadowOffset: 2
function toggleContent()
{
if (content.visible)
{
content.close()
}
else
{
content.open()
}
}
// Add this binding since the background color is not updated otherwise
Binding
{
target: background
property: "color"
value: base.enabled ? headerBackgroundColor : UM.Theme.getColor("disabled")
}
// The panel needs to close when it becomes disabled
Connections
{
target: base
onEnabledChanged:
{
if (!base.enabled && expanded)
{
toggleContent()
}
}
}
implicitHeight: 100 * screenScaleFactor
implicitWidth: 400 * screenScaleFactor
RoundedRectangle
{
id: background
property real padding: UM.Theme.getSize("default_margin").width
color: base.enabled ? headerBackgroundColor : UM.Theme.getColor("disabled")
anchors.fill: parent
Label
{
id: disabledLabel
visible: !base.enabled
leftPadding: background.padding
text: ""
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
color: UM.Theme.getColor("text")
height: parent.height
}
Item
{
anchors.fill: parent
visible: base.enabled
Loader
{
id: headerItemLoader
anchors
{
left: parent.left
right: collapseButton.visible ? collapseButton.left : parent.right
top: parent.top
bottom: parent.bottom
margins: background.padding
}
}
// A highlight that is shown when the content is expanded
Rectangle
{
id: expandedHighlight
width: parent.width
height: UM.Theme.getSize("thick_lining").height
color: UM.Theme.getColor("primary")
visible: expanded
anchors.bottom: parent.bottom
}
UM.RecolorImage
{
id: collapseButton
anchors
{
right: parent.right
verticalCenter: parent.verticalCenter
margins: background.padding
}
source: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
visible: source != ""
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
color: UM.Theme.getColor("small_button_text")
}
}
MouseArea
{
id: mouseArea
anchors.fill: parent
onClicked: toggleContent()
hoverEnabled: true
onEntered: background.color = headerHoverColor
onExited: background.color = base.enabled ? headerBackgroundColor : UM.Theme.getColor("disabled")
}
}
DropShadow
{
id: shadow
// Don't blur the shadow
radius: 0
anchors.fill: background
source: background
verticalOffset: base.shadowOffset
visible: true
color: UM.Theme.getColor("action_button_shadow")
// Should always be drawn behind the background.
z: background.z - 1
}
Popup
{
id: content
// Ensure that the content is located directly below the headerItem
y: background.height + base.shadowOffset
// Make the content aligned with the rest, using the property contentAlignment to decide whether is right or left.
// In case of right alignment, the 3x padding is due to left, right and padding between the button & text.
x: contentAlignment == ExpandablePopup.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0
padding: UM.Theme.getSize("default_margin").width
closePolicy: Popup.CloseOnPressOutsideParent
background: Cura.RoundedRectangle
{
cornerSide: Cura.RoundedRectangle.Direction.Down
color: contentBackgroundColor
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
radius: UM.Theme.getSize("default_radius").width
}
contentItem: Item {}
onContentItemChanged:
{
// Since we want the size of the content to be set by the size of the content,
// we need to do it like this.
content.width = contentItem.width + 2 * content.padding
content.height = contentItem.height + 2 * content.padding
}
}
// DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item.
// Apparently the order in which these are handled matters and so the height is correctly updated if this is here.
Connections
{
// Since it could be that the content is dynamically populated, we should also take these changes into account.
target: content.contentItem
onWidthChanged: content.width = content.contentItem.width + 2 * content.padding
onHeightChanged: content.height = content.contentItem.height + 2 * content.padding
}
}

View file

@ -2,80 +2,32 @@
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls 2.0
import UM 1.2 as UM
import Cura 1.0 as Cura
Button
Cura.ToolbarButton
{
id: base
property var extruder;
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)
style: UM.Theme.styles.tool_button;
iconSource: UM.Theme.getIcon("extruder_button")
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1
enabled: UM.Selection.hasSelection && extruder.stack.isEnabled
property color customColor: base.hovered ? UM.Theme.getColor("button_hover") : UM.Theme.getColor("button");
Rectangle
toolItem: ExtruderIcon
{
anchors.fill: parent
anchors.margins: UM.Theme.getSize("default_lining").width;
color: "transparent"
border.width: base.checked ? UM.Theme.getSize("default_lining").width : 0;
border.color: UM.Theme.getColor("button_text")
}
Item
{
anchors.centerIn: parent
width: UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("default_margin").height
Label
{
anchors.centerIn: parent;
text: index + 1;
color: parent.enabled ? UM.Theme.getColor("button_text") : UM.Theme.getColor("button_disabled_text")
font: UM.Theme.getFont("default_bold");
}
}
// Material colour circle
// Only draw the filling colour of the material inside the SVG border.
Rectangle
{
anchors
{
right: parent.right
top: parent.top
rightMargin: UM.Theme.getSize("extruder_button_material_margin").width
topMargin: UM.Theme.getSize("extruder_button_material_margin").height
}
color: model.color
width: UM.Theme.getSize("extruder_button_material").width
height: UM.Theme.getSize("extruder_button_material").height
radius: Math.round(width / 2)
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("extruder_button_material_border")
opacity: !base.enabled ? 0.2 : 1.0
materialColor: extruder.color
extruderEnabled: extruder.stack.isEnabled
property int index: extruder.index
}
onClicked:
{
forceActiveFocus() //First grab focus, so all the text fields are updated
CuraActions.setExtruderForSelection(extruder.id);
CuraActions.setExtruderForSelection(extruder.id)
}
}

View file

@ -0,0 +1,71 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.1
import UM 1.2 as UM
Item
{
id: extruderIconItem
implicitWidth: UM.Theme.getSize("extruder_icon").width
implicitHeight: UM.Theme.getSize("extruder_icon").height
property bool checked: true
property color materialColor
property alias textColor: extruderNumberText.color
property bool extruderEnabled: true
UM.RecolorImage
{
id: mainIcon
anchors.fill: parent
source: UM.Theme.getIcon("extruder_button")
color: extruderEnabled ? materialColor: UM.Theme.getColor("disabled")
}
Rectangle
{
id: extruderNumberCircle
width: height
height: Math.round(parent.height / 2)
radius: Math.round(width / 2)
color: UM.Theme.getColor("toolbar_background")
anchors
{
horizontalCenter: parent.horizontalCenter
top: parent.top
// The circle needs to be slightly off center (so it sits in the middle of the square bit of the icon)
topMargin: (parent.height - height) / 2 - 0.1 * parent.height
}
Label
{
id: extruderNumberText
anchors.centerIn: parent
text: index + 1
font: UM.Theme.getFont("very_small")
width: contentWidth
height: contentHeight
visible: extruderEnabled
renderType: Text.NativeRendering
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
UM.RecolorImage
{
id: disabledIcon
anchors.fill: parent
anchors.margins: UM.Theme.getSize("thick_lining").width
sourceSize.height: width
source: UM.Theme.getIcon("cross1")
visible: !extruderEnabled
color: "black"
}
}
}

View file

@ -0,0 +1,70 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import UM 1.2 as UM
import Cura 1.0 as Cura
// Reusable component that holds an (re-colorable) icon on the left with some text on the right.
// This component is also designed to be used with layouts. It will use the width of the text + icon as preferred width
// It sets the icon size + half of the content as its minium width (in which case it will elide the text)
Item
{
property alias source: icon.source
property alias iconSize: icon.width
property alias color: label.color
property alias text: label.text
property alias font: label.font
property real margin: UM.Theme.getSize("narrow_margin").width
// These properties can be used in combination with layouts.
readonly property real contentWidth: icon.width + margin + label.contentWidth
readonly property real minContentWidth: Math.round(icon.width + margin + 0.5 * label.contentWidth)
Layout.minimumWidth: minContentWidth
Layout.preferredWidth: contentWidth
Layout.fillHeight: true
Layout.fillWidth: true
implicitWidth: icon.width + 100
implicitHeight: icon.height
UM.RecolorImage
{
id: icon
width: UM.Theme.getSize("section_icon").width
height: UM.Theme.getSize("section_icon").height
color: label.color
anchors
{
left: parent.left
verticalCenter: parent.verticalCenter
}
}
Label
{
id: label
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
anchors
{
left: icon.right
right: parent.right
top: parent.top
bottom: parent.bottom
rightMargin: 0
margins: margin
}
}
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@ -9,141 +9,145 @@ import QtQuick.Layouts 1.1
import UM 1.1 as UM
import Cura 1.0 as Cura
Item {
Item
{
id: base
property bool activity: CuraApplication.platformActivity
property string fileBaseName: PrintInformation.baseName
UM.I18nCatalog { id: catalog; name:"cura"}
UM.I18nCatalog
{
id: catalog
name: "cura"
}
width: childrenRect.width
height: childrenRect.height
onActivityChanged: {
if (activity == false) {
onActivityChanged:
{
if (!activity)
{
//When there is no mesh in the buildplate; the printJobTextField is set to an empty string so it doesn't set an empty string as a jobName (which is later used for saving the file)
PrintInformation.baseName = ''
PrintInformation.baseName = ""
}
}
Rectangle
Item
{
id: jobNameRow
anchors.top: parent.top
anchors.right: parent.right
anchors.left: parent.left
height: UM.Theme.getSize("jobspecs_line").height
visible: base.activity
Item
Button
{
width: parent.width
height: parent.height
id: printJobPencilIcon
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("save_button_specs_icons").width
height: UM.Theme.getSize("save_button_specs_icons").height
Button
onClicked:
{
id: printJobPencilIcon
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("save_button_specs_icons").width
height: UM.Theme.getSize("save_button_specs_icons").height
onClicked:
{
printJobTextfield.selectAll();
printJobTextfield.focus = true;
}
style: ButtonStyle
{
background: Item
{
UM.RecolorImage
{
width: UM.Theme.getSize("save_button_specs_icons").width;
height: UM.Theme.getSize("save_button_specs_icons").height;
sourceSize.width: width;
sourceSize.height: width;
color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene");
source: UM.Theme.getIcon("pencil");
}
}
}
printJobTextfield.selectAll()
printJobTextfield.focus = true
}
TextField
style: ButtonStyle
{
id: printJobTextfield
anchors.right: printJobPencilIcon.left
anchors.rightMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
height: UM.Theme.getSize("jobspecs_line").height
width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50)
maximumLength: 120
property int unremovableSpacing: 5
text: PrintInformation.jobName
horizontalAlignment: TextInput.AlignRight
onEditingFinished: {
var new_name = text == "" ? catalog.i18nc("@text Print job name", "Untitled") : text;
PrintInformation.setJobName(new_name, true);
printJobTextfield.focus = false;
}
validator: RegExpValidator {
regExp: /^[^\\\/\*\?\|\[\]]*$/
}
style: TextFieldStyle{
textColor: UM.Theme.getColor("text_scene");
font: UM.Theme.getFont("default_bold");
background: Rectangle {
opacity: 0
border.width: 0
background: Item
{
UM.RecolorImage
{
width: UM.Theme.getSize("save_button_specs_icons").width
height: UM.Theme.getSize("save_button_specs_icons").height
sourceSize.width: width
sourceSize.height: width
color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene")
source: UM.Theme.getIcon("pencil")
}
}
}
}
}
Row {
id: additionalComponentsRow
anchors.top: jobNameRow.bottom
anchors.right: parent.right
TextField
{
id: printJobTextfield
anchors.left: printJobPencilIcon.right
anchors.leftMargin: UM.Theme.getSize("narrow_margin").width
height: UM.Theme.getSize("jobspecs_line").height
width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50)
maximumLength: 120
text: PrintInformation.jobName
horizontalAlignment: TextInput.AlignLeft
onEditingFinished:
{
var new_name = text == "" ? catalog.i18nc("@text Print job name", "Untitled") : text
PrintInformation.setJobName(new_name, true)
printJobTextfield.focus = false
}
validator: RegExpValidator {
regExp: /^[^\\\/\*\?\|\[\]]*$/
}
style: TextFieldStyle
{
textColor: UM.Theme.getColor("text_scene")
font: UM.Theme.getFont("default_bold")
background: Rectangle
{
opacity: 0
border.width: 0
}
}
}
}
Label
{
id: boundingSpec
anchors.top: jobNameRow.bottom
anchors.right: additionalComponentsRow.left
anchors.rightMargin:
{
if (additionalComponentsRow.width > 0)
{
return UM.Theme.getSize("default_margin").width
}
else
{
return 0;
}
}
anchors.left: parent.left
height: UM.Theme.getSize("jobspecs_line").height
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("small")
font: UM.Theme.getFont("default_bold")
color: UM.Theme.getColor("text_scene")
text: CuraApplication.getSceneBoundingBoxString
}
Component.onCompleted: {
Row
{
id: additionalComponentsRow
anchors.top: boundingSpec.top
anchors.bottom: boundingSpec.bottom
anchors.left: boundingSpec.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
}
Component.onCompleted:
{
base.addAdditionalComponents("jobSpecsButton")
}
Connections {
Connections
{
target: CuraApplication
onAdditionalComponentsChanged: base.addAdditionalComponents("jobSpecsButton")
}
function addAdditionalComponents (areaId) {
if(areaId == "jobSpecsButton") {
for (var component in CuraApplication.additionalComponents["jobSpecsButton"]) {
function addAdditionalComponents(areaId)
{
if (areaId == "jobSpecsButton")
{
for (var component in CuraApplication.additionalComponents["jobSpecsButton"])
{
CuraApplication.additionalComponents["jobSpecsButton"][component].parent = additionalComponentsRow
}
}
}
}

View file

@ -1,86 +0,0 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import UM 1.2 as UM
import Cura 1.0 as Cura
import "Menus"
ToolButton
{
id: base
property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != ""
property bool printerConnected: Cura.MachineManager.printerConnected
property var printerStatus: Cura.MachineManager.printerConnected ? "connected" : "disconnected"
text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName
tooltip: Cura.MachineManager.activeMachineName
style: ButtonStyle
{
background: Rectangle
{
color:
{
if (control.pressed) {
return UM.Theme.getColor("sidebar_header_active");
}
else if (control.hovered) {
return UM.Theme.getColor("sidebar_header_hover");
}
else {
return UM.Theme.getColor("sidebar_header_bar");
}
}
Behavior on color { ColorAnimation { duration: 50; } }
UM.RecolorImage
{
id: downArrow
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: width
color: UM.Theme.getColor("text_emphasis")
source: UM.Theme.getIcon("arrow_bottom")
}
PrinterStatusIcon
{
id: printerStatusIcon
visible: printerConnected || isNetworkPrinter
status: printerStatus
anchors
{
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: UM.Theme.getSize("sidebar_margin").width
}
}
Label
{
id: sidebarComboBoxLabel
color: UM.Theme.getColor("sidebar_header_text_active")
text: control.text;
elide: Text.ElideRight;
anchors.left: printerStatusIcon.visible ? printerStatusIcon.right : parent.left;
anchors.leftMargin: printerStatusIcon.visible ? UM.Theme.getSize("sidebar_lining").width : UM.Theme.getSize("sidebar_margin").width
anchors.right: downArrow.left;
anchors.rightMargin: control.rightMargin;
anchors.verticalCenter: parent.verticalCenter;
font: UM.Theme.getFont("medium_bold")
}
}
label: Label {}
}
menu: PrinterMenu { }
}

View file

@ -0,0 +1,171 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import UM 1.3 as UM
import Cura 1.1 as Cura
import "../Menus"
import "../Dialogs"
Item
{
id: menu
width: applicationMenu.width
height: applicationMenu.height
property alias window: applicationMenu.window
UM.ApplicationMenu
{
id: applicationMenu
FileMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&File") }
Menu
{
title: catalog.i18nc("@title:menu menubar:toplevel", "&Edit")
MenuItem { action: Cura.Actions.undo }
MenuItem { action: Cura.Actions.redo }
MenuSeparator { }
MenuItem { action: Cura.Actions.selectAll }
MenuItem { action: Cura.Actions.arrangeAll }
MenuItem { action: Cura.Actions.deleteSelection }
MenuItem { action: Cura.Actions.deleteAll }
MenuItem { action: Cura.Actions.resetAllTranslation }
MenuItem { action: Cura.Actions.resetAll }
MenuSeparator { }
MenuItem { action: Cura.Actions.groupObjects }
MenuItem { action: Cura.Actions.mergeObjects }
MenuItem { action: Cura.Actions.unGroupObjects }
}
ViewMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&View") }
SettingsMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&Settings") }
Menu
{
id: extensionMenu
title: catalog.i18nc("@title:menu menubar:toplevel", "E&xtensions")
Instantiator
{
id: extensions
model: UM.ExtensionModel { }
Menu
{
id: sub_menu
title: model.name;
visible: actions != null
enabled: actions != null
Instantiator
{
model: actions
MenuItem
{
text: model.text
onTriggered: extensions.model.subMenuTriggered(name, model.text)
}
onObjectAdded: sub_menu.insertItem(index, object)
onObjectRemoved: sub_menu.removeItem(object)
}
}
onObjectAdded: extensionMenu.insertItem(index, object)
onObjectRemoved: extensionMenu.removeItem(object)
}
}
Menu
{
id: plugin_menu
title: catalog.i18nc("@title:menu menubar:toplevel", "&Marketplace")
MenuItem { action: Cura.Actions.browsePackages }
}
Menu
{
id: preferencesMenu
title: catalog.i18nc("@title:menu menubar:toplevel", "P&references")
MenuItem { action: Cura.Actions.preferences }
}
Menu
{
id: helpMenu
title: catalog.i18nc("@title:menu menubar:toplevel", "&Help")
MenuItem { action: Cura.Actions.showProfileFolder }
MenuItem { action: Cura.Actions.documentation }
MenuItem { action: Cura.Actions.reportBug }
MenuSeparator { }
MenuItem { action: Cura.Actions.about }
}
}
// ###############################################################################################
// Definition of other components that are linked to the menus
// ###############################################################################################
WorkspaceSummaryDialog
{
id: saveWorkspaceDialog
property var args
onYes: UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args)
}
MessageDialog
{
id: newProjectDialog
modality: Qt.ApplicationModal
title: catalog.i18nc("@title:window", "New project")
text: catalog.i18nc("@info:question", "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings.")
standardButtons: StandardButton.Yes | StandardButton.No
icon: StandardIcon.Question
onYes:
{
CuraApplication.deleteAll();
Cura.Actions.resetProfile.trigger();
}
}
UM.ExtensionModel
{
id: curaExtensions
}
// ###############################################################################################
// Definition of all the connections
// ###############################################################################################
Connections
{
target: Cura.Actions.newProject
onTriggered:
{
if(Printer.platformActivity || Cura.MachineManager.hasUserSettings)
{
newProjectDialog.visible = true
}
}
}
// show the plugin browser dialog
Connections
{
target: Cura.Actions.browsePackages
onTriggered:
{
curaExtensions.callExtensionMethod("Toolbox", "browsePackages")
}
}
}

View file

@ -0,0 +1,118 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0 as Controls2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.1
import UM 1.4 as UM
import Cura 1.0 as Cura
import QtGraphicalEffects 1.0
import "../Account"
Item
{
id: base
implicitHeight: UM.Theme.getSize("main_window_header").height
implicitWidth: UM.Theme.getSize("main_window_header").width
Image
{
id: logo
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
source: UM.Theme.getImage("logo")
width: UM.Theme.getSize("logo").width
height: UM.Theme.getSize("logo").height
}
Row
{
id: stagesListContainer
spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
anchors
{
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
leftMargin: UM.Theme.getSize("default_margin").width
}
// The main window header is dynamically filled with all available stages
Repeater
{
id: stagesHeader
model: UM.StageModel { }
delegate: Button
{
text: model.name.toUpperCase()
checkable: true
checked: model.active
anchors.verticalCenter: parent.verticalCenter
exclusiveGroup: mainWindowHeaderMenuGroup
style: UM.Theme.styles.main_window_header_tab
height: UM.Theme.getSize("main_window_header_button").height
onClicked: UM.Controller.setActiveStage(model.id)
iconSource: model.stage.iconSource
property color overlayColor: "transparent"
property string overlayIconSource: ""
}
}
ExclusiveGroup { id: mainWindowHeaderMenuGroup }
}
// Shortcut button to quick access the Toolbox
Controls2.Button
{
id: marketplaceButton
text: catalog.i18nc("@action:button", "Marketplace")
height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height)
onClicked: Cura.Actions.browsePackages.trigger()
hoverEnabled: true
background: Rectangle
{
radius: UM.Theme.getSize("action_button_radius").width
color: marketplaceButton.hovered ? UM.Theme.getColor("primary_text") : UM.Theme.getColor("main_window_header_background")
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("primary_text")
}
contentItem: Label
{
id: label
text: marketplaceButton.text
color: marketplaceButton.hovered ? UM.Theme.getColor("main_window_header_background") : UM.Theme.getColor("primary_text")
width: contentWidth
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
}
anchors
{
right: accountWidget.left
rightMargin: UM.Theme.getSize("default_margin").width
verticalCenter: parent.verticalCenter
}
}
AccountWidget
{
id: accountWidget
anchors
{
right: parent.right
rightMargin: UM.Theme.getSize("default_margin").width
}
}
}

View file

@ -0,0 +1,39 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import UM 1.3 as UM
import Cura 1.0 as Cura
Item
{
width: parent.width
height: childrenRect.height
Label
{
id: header
text: catalog.i18nc("@header", "Configurations")
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
height: contentHeight
renderType: Text.NativeRendering
anchors
{
left: parent.left
right: parent.right
}
}
ConfigurationListView
{
anchors.top: header.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").width
width: parent.width
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
}
}

View file

@ -7,143 +7,129 @@ import QtQuick.Controls 2.0
import UM 1.2 as UM
import Cura 1.0 as Cura
Rectangle
Button
{
id: configurationItem
property var configuration: null
property var selected: false
signal activateConfiguration()
hoverEnabled: true
height: childrenRect.height
border.width: UM.Theme.getSize("default_lining").width
border.color: updateBorderColor()
color: selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item")
property var textColor: selected ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text")
height: background.height
function updateBorderColor()
background: Rectangle
{
border.color = selected ? UM.Theme.getColor("configuration_item_border_active") : UM.Theme.getColor("configuration_item_border")
}
height: childrenRect.height
color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining")
border.width: parent.checked ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width
radius: UM.Theme.getSize("default_radius").width
Column
{
id: contentColumn
width: parent.width
padding: UM.Theme.getSize("default_margin").width
spacing: Math.round(UM.Theme.getSize("default_margin").height / 2)
Row
Column
{
id: extruderRow
id: contentColumn
width: parent.width
padding: UM.Theme.getSize("wide_margin").width
spacing: UM.Theme.getSize("narrow_margin").height
width: parent.width - 2 * parent.padding
height: childrenRect.height
spacing: UM.Theme.getSize("default_margin").width
Repeater
Row
{
id: repeater
height: childrenRect.height
model: configuration.extruderConfigurations
delegate: PrintCoreConfiguration
id: extruderRow
anchors
{
width: Math.round(parent.width / 2)
printCoreConfiguration: modelData
mainColor: textColor
left: parent.left
leftMargin: parent.padding
right: parent.right
rightMargin: parent.padding
}
height: childrenRect.height
spacing: UM.Theme.getSize("default_margin").width
Repeater
{
id: repeater
height: childrenRect.height
model: configuration.extruderConfigurations
delegate: PrintCoreConfiguration
{
width: Math.round(parent.width / 2)
printCoreConfiguration: modelData
}
}
}
//Buildplate row separator
Rectangle
{
id: separator
visible: buildplateInformation.visible
anchors
{
left: parent.left
leftMargin: parent.padding
right: parent.right
rightMargin: parent.padding
}
height: visible ? Math.round(UM.Theme.getSize("default_lining").height / 2) : 0
color: UM.Theme.getColor("lining")
}
Item
{
id: buildplateInformation
anchors
{
left: parent.left
leftMargin: parent.padding
right: parent.right
rightMargin: parent.padding
}
height: childrenRect.height
visible: configuration.buildplateConfiguration != ""
UM.RecolorImage
{
id: buildplateIcon
anchors.left: parent.left
width: UM.Theme.getSize("main_window_header_button_icon").width
height: UM.Theme.getSize("main_window_header_button_icon").height
source: UM.Theme.getIcon("buildplate")
color: UM.Theme.getColor("text")
}
Label
{
id: buildplateLabel
anchors.left: buildplateIcon.right
anchors.verticalCenter: buildplateIcon.verticalCenter
anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2)
text: configuration.buildplateConfiguration
renderType: Text.NativeRendering
color: UM.Theme.getColor("text")
}
}
}
//Buildplate row separator
Rectangle
Connections
{
id: separator
visible: buildplateInformation.visible
width: parent.width - 2 * parent.padding
height: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0
color: textColor
}
Item
{
id: buildplateInformation
width: parent.width - 2 * parent.padding
height: childrenRect.height
visible: configuration.buildplateConfiguration != ""
UM.RecolorImage {
id: buildplateIcon
anchors.left: parent.left
width: UM.Theme.getSize("topbar_button_icon").width
height: UM.Theme.getSize("topbar_button_icon").height
sourceSize.width: width
sourceSize.height: height
source: UM.Theme.getIcon("buildplate")
color: textColor
}
Label
target: Cura.MachineManager
onCurrentConfigurationChanged:
{
id: buildplateLabel
anchors.left: buildplateIcon.right
anchors.verticalCenter: buildplateIcon.verticalCenter
anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2)
text: configuration.buildplateConfiguration
renderType: Text.NativeRendering
color: textColor
configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration)
}
}
}
MouseArea
{
id: mouse
anchors.fill: parent
onClicked: activateConfiguration()
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered:
Component.onCompleted:
{
parent.border.color = UM.Theme.getColor("configuration_item_border_hover")
if (configurationItem.selected == false)
{
configurationItem.color = UM.Theme.getColor("sidebar_lining")
}
}
onExited:
{
updateBorderColor()
if (configurationItem.selected == false)
{
configurationItem.color = UM.Theme.getColor("configuration_item")
}
configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration)
}
}
Connections
onClicked:
{
target: Cura.MachineManager
onCurrentConfigurationChanged: {
configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration)
updateBorderColor()
}
}
Component.onCompleted:
{
configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration)
updateBorderColor()
}
onVisibleChanged:
{
if(visible)
{
// I cannot trigger function updateBorderColor() after visibility change
color = selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item")
}
Cura.MachineManager.applyRemoteConfiguration(configuration)
}
}

View file

@ -2,8 +2,7 @@
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
@ -12,75 +11,74 @@ Column
{
id: base
property var outputDevice: null
property var computedHeight: container.height + configurationListHeading.height + 3 * padding
height: childrenRect.height + 2 * padding
padding: UM.Theme.getSize("default_margin").width
spacing: Math.round(UM.Theme.getSize("default_margin").height / 2)
spacing: UM.Theme.getSize("narrow_margin").height
function forceModelUpdate()
{
// FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI
configurationList.model = []
if(outputDevice)
if (outputDevice)
{
configurationList.model = outputDevice.uniqueConfigurations
}
}
Label
{
id: configurationListHeading
text: catalog.i18nc("@label:header configurations", "Available configurations")
font: UM.Theme.getFont("large")
width: parent.width - 2 * parent.padding
color: UM.Theme.getColor("configuration_item_text")
}
Component
{
id: sectionHeading
Rectangle
{
height: childrenRect.height + UM.Theme.getSize("default_margin").height
Label
{
text: section
font: UM.Theme.getFont("default_bold")
color: UM.Theme.getColor("configuration_item_text")
}
}
}
ScrollView
{
id: container
width: parent.width - parent.padding
height: Math.min(configurationList.contentHeight, 350 * screenScaleFactor)
width: parent.width
readonly property int maximumHeight: 350 * screenScaleFactor
height: Math.round(Math.min(configurationList.height, maximumHeight))
contentHeight: configurationList.height
clip: true
style: UM.Theme.styles.scrollview
__wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event
ScrollBar.vertical.policy: (configurationList.height > maximumHeight) ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff //The AsNeeded policy also hides it when the cursor is away, and we don't want that.
ScrollBar.vertical.background: Rectangle
{
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: width / 2
color: UM.Theme.getColor("scrollbar_background")
}
ScrollBar.vertical.contentItem: Rectangle
{
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: width / 2
color: UM.Theme.getColor(parent.pressed ? "scrollbar_handle_down" : parent.hovered ? "scrollbar_handle_hover" : "scrollbar_handle")
}
ButtonGroup
{
buttons: configurationList.children
}
ListView
{
id: configurationList
spacing: Math.round(UM.Theme.getSize("default_margin").height / 2)
width: container.width
spacing: UM.Theme.getSize("narrow_margin").height
width: container.width - ((height > container.maximumHeight) ? container.ScrollBar.vertical.background.width : 0) //Make room for scroll bar if there is any.
contentHeight: childrenRect.height
height: childrenRect.height
section.property: "modelData.printerType"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
section.delegate: Item
{
height: printerTypeLabel.height + UM.Theme.getSize("wide_margin").height //Causes a default margin above the label and a default margin below the label.
Cura.PrinterTypeLabel
{
id: printerTypeLabel
text: Cura.MachineManager.getAbbreviatedMachineName(section)
anchors.verticalCenter: parent.verticalCenter //One default margin above and one below.
}
}
model: (outputDevice != null) ? outputDevice.uniqueConfigurations : []
delegate: ConfigurationItem
{
width: parent.width - UM.Theme.getSize("default_margin").width
width: parent.width
configuration: modelData
onActivateConfiguration:
{
switchPopupState()
Cura.MachineManager.applyRemoteConfiguration(configuration)
}
}
}
}

View file

@ -0,0 +1,218 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
/**
* Menu that allows you to select the configuration of the current printer, such
* as the nozzle sizes and materials in each extruder.
*/
Cura.ExpandablePopup
{
id: base
Cura.ExtrudersModel
{
id: extrudersModel
}
UM.I18nCatalog
{
id: catalog
name: "cura"
}
enum ConfigurationMethod
{
Auto,
Custom
}
enabled: Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants || Cura.MachineManager.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change.
headerItem: Item
{
// Horizontal list that shows the extruders and their materials
ListView
{
id: extrudersList
orientation: ListView.Horizontal
anchors.fill: parent
model: extrudersModel
visible: Cura.MachineManager.hasMaterials
delegate: Item
{
height: parent.height
width: Math.round(ListView.view.width / extrudersModel.count)
// Extruder icon. Shows extruder index and has the same color as the active material.
Cura.ExtruderIcon
{
id: extruderIcon
materialColor: model.color
extruderEnabled: model.enabled
height: parent.height
width: height
}
// Label for the brand of the material
Label
{
id: brandNameLabel
text: model.material_brand
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_inactive")
renderType: Text.NativeRendering
anchors
{
left: extruderIcon.right
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("default_margin").width
}
}
// Label that shows the name of the material
Label
{
text: model.material
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
anchors
{
left: extruderIcon.right
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("default_margin").width
top: brandNameLabel.bottom
}
}
}
}
//Placeholder text if there is a configuration to select but no materials (so we can't show the materials per extruder).
Label
{
text: catalog.i18nc("@label", "Select configuration")
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
visible: !Cura.MachineManager.hasMaterials && (Cura.MachineManager.hasVariants || Cura.MachineManager.hasVariantBuildplates)
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("default_margin").width
verticalCenter: parent.verticalCenter
}
}
}
contentItem: Column
{
id: popupItem
width: base.width - 2 * UM.Theme.getSize("default_margin").width
height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up.
spacing: UM.Theme.getSize("default_margin").height
property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible.
onVisibleChanged:
{
is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate.
}
property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.Auto : ConfigurationMenu.ConfigurationMethod.Custom //Auto if connected to a printer at start-up, or Custom if not.
Item
{
width: parent.width
height:
{
var height = 0;
if(autoConfiguration.visible)
{
height += autoConfiguration.height;
}
if(customConfiguration.visible)
{
height += customConfiguration.height;
}
return height;
}
AutoConfiguration
{
id: autoConfiguration
visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto
}
CustomConfiguration
{
id: customConfiguration
visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom
}
}
Rectangle
{
id: separator
visible: buttonBar.visible
x: -contentPadding
width: base.width
height: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining")
}
//Allow switching between custom and auto.
Item
{
id: buttonBar
visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible.
width: parent.width
height: childrenRect.height
Cura.SecondaryButton
{
id: goToCustom
visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto
text: catalog.i18nc("@label", "Custom")
anchors.right: parent.right
iconSource: UM.Theme.getIcon("arrow_right")
isIconOnRightSide: true
onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom
}
Cura.SecondaryButton
{
id: goToAuto
visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom
text: catalog.i18nc("@label", "Configurations")
iconSource: UM.Theme.getIcon("arrow_left")
onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto
}
}
}
}

View file

@ -1,65 +0,0 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Item
{
id: configurationSelector
property var connectedDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
property var panelWidth: control.width
function switchPopupState()
{
popup.visible ? popup.close() : popup.open()
}
SyncButton
{
id: syncButton
onClicked: switchPopupState()
outputDevice: connectedDevice
}
Popup
{
// TODO Change once updating to Qt5.10 - The 'opened' property is in 5.10 but the behavior is now implemented with the visible property
id: popup
clip: true
closePolicy: Popup.CloseOnPressOutsideParent
y: configurationSelector.height - UM.Theme.getSize("default_lining").height
x: configurationSelector.width - width
width: panelWidth
visible: false
padding: UM.Theme.getSize("default_lining").width
transformOrigin: Popup.Top
contentItem: ConfigurationListView
{
id: configList
width: panelWidth - 2 * popup.padding
outputDevice: connectedDevice
}
background: Rectangle
{
color: UM.Theme.getColor("setting_control")
border.color: UM.Theme.getColor("setting_control_border")
}
exit: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
}
enter: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
}
onClosed: visible = false
onOpened: visible = true
}
}

View file

@ -0,0 +1,295 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.6
import QtQuick.Controls 2.0
import QtQuick.Controls 1.1 as OldControls
import Cura 1.0 as Cura
import UM 1.3 as UM
Item
{
UM.I18nCatalog
{
id: catalog
name: "cura"
}
width: parent.width
height: childrenRect.height
Label
{
id: header
text: catalog.i18nc("@header", "Custom")
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
height: contentHeight
renderType: Text.NativeRendering
anchors
{
top: parent.top
left: parent.left
right: parent.right
}
}
//Printer type selector.
Item
{
id: printerTypeSelectorRow
visible:
{
return Cura.MachineManager.printerOutputDevices.length >= 1 //If connected...
&& Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount != null //...and we have configuration information...
&& Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount.length > 1; //...and there is more than one type of printer in the configuration list.
}
height: visible ? childrenRect.height : 0
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("default_margin").width
top: header.bottom
topMargin: visible ? UM.Theme.getSize("default_margin").height : 0
}
Label
{
text: catalog.i18nc("@label", "Printer")
width: Math.round(parent.width * 0.3) - UM.Theme.getSize("default_margin").width
height: contentHeight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
anchors.verticalCenter: printerTypeSelector.verticalCenter
anchors.left: parent.left
}
OldControls.ToolButton
{
id: printerTypeSelector
text: Cura.MachineManager.activeMachineDefinitionName
tooltip: Cura.MachineManager.activeMachineDefinitionName
height: UM.Theme.getSize("setting_control").height
width: Math.round(parent.width * 0.7) + UM.Theme.getSize("default_margin").width
anchors.right: parent.right
style: UM.Theme.styles.print_setup_header_button
menu: Cura.PrinterTypeMenu { }
}
}
UM.TabRow
{
id: tabBar
anchors.top: printerTypeSelectorRow.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
visible: extrudersModel.count > 1
Repeater
{
id: repeater
model: extrudersModel
delegate: UM.TabRowButton
{
contentItem: Item
{
Cura.ExtruderIcon
{
anchors.horizontalCenter: parent.horizontalCenter
materialColor: model.color
extruderEnabled: model.enabled
width: parent.height
height: parent.height
}
}
onClicked:
{
Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex)
}
}
}
//When active extruder changes for some other reason, switch tabs.
//Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex!
//This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead.
Connections
{
target: Cura.ExtruderManager
onActiveExtruderChanged:
{
tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex);
}
}
//When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt.
//This causes the currentIndex of the tab to be in an invalid position which resets it to 0.
//Therefore we need to change it back to what it was: The active extruder index.
Connections
{
target: repeater.model
onModelChanged:
{
tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex)
}
}
}
Rectangle
{
width: parent.width
height: childrenRect.height
anchors.top: tabBar.bottom
radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0
border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0
border.color: UM.Theme.getColor("lining")
color: UM.Theme.getColor("main_background")
//Remove rounding and lining at the top.
Rectangle
{
width: parent.width
height: parent.radius
anchors.top: parent.top
color: UM.Theme.getColor("lining")
visible: tabBar.visible
Rectangle
{
anchors
{
left: parent.left
leftMargin: parent.parent.border.width
right: parent.right
rightMargin: parent.parent.border.width
top: parent.top
}
height: parent.parent.radius
color: parent.parent.color
}
}
Column
{
id: selectors
padding: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").height
property var model: extrudersModel.items[tabBar.currentIndex]
readonly property real paddedWidth: parent.width - padding * 2
property real textWidth: Math.round(paddedWidth * 0.3)
property real controlWidth: paddedWidth - textWidth
Row
{
height: UM.Theme.getSize("print_setup_item").height
visible: extrudersModel.count > 1 // If there is only one extruder, there is no point to enable/disable that.
Label
{
text: catalog.i18nc("@label", "Enabled")
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
height: parent.height
width: selectors.textWidth
renderType: Text.NativeRendering
}
OldControls.CheckBox
{
checked: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.isEnabled : false
enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder.
height: UM.Theme.getSize("setting_control").height
style: UM.Theme.styles.checkbox
/* Use a MouseArea to process the click on this checkbox.
This is necessary because actually clicking the checkbox
causes the "checked" property to be overwritten. After
it's been overwritten, the original link that made it
depend on the active extruder stack is broken. */
MouseArea
{
anchors.fill: parent
onClicked: Cura.MachineManager.setExtruderEnabled(Cura.ExtruderManager.activeExtruderIndex, !parent.checked)
enabled: parent.enabled
}
}
}
Row
{
height: UM.Theme.getSize("print_setup_item").height
visible: Cura.MachineManager.hasMaterials
Label
{
text: catalog.i18nc("@label", "Material")
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
height: parent.height
width: selectors.textWidth
renderType: Text.NativeRendering
}
OldControls.ToolButton
{
id: materialSelection
property bool valueError: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") != "True" : true
property bool valueWarning: !Cura.MachineManager.isActiveQualitySupported
text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : ""
tooltip: text
height: UM.Theme.getSize("setting_control").height
width: selectors.controlWidth
style: UM.Theme.styles.print_setup_header_button
activeFocusOnPress: true
menu: Cura.MaterialMenu
{
extruderIndex: Cura.ExtruderManager.activeExtruderIndex
}
}
}
Row
{
height: UM.Theme.getSize("print_setup_item").height
visible: Cura.MachineManager.hasVariants
Label
{
text: Cura.MachineManager.activeDefinitionVariantsName
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
height: parent.height
width: selectors.textWidth
renderType: Text.NativeRendering
}
OldControls.ToolButton
{
id: variantSelection
text: Cura.MachineManager.activeVariantName
tooltip: Cura.MachineManager.activeVariantName
height: UM.Theme.getSize("setting_control").height
width: selectors.controlWidth
style: UM.Theme.styles.print_setup_header_button
activeFocusOnPress: true;
menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex }
}
}
}
}
}

View file

@ -5,87 +5,50 @@ import QtQuick 2.7
import QtQuick.Controls 2.0
import UM 1.2 as UM
import Cura 1.0 as Cura
Column
Row
{
id: extruderInfo
property var printCoreConfiguration
property var mainColor: "black"
spacing: Math.round(UM.Theme.getSize("default_margin").height / 2)
height: childrenRect.height
height: information.height
spacing: UM.Theme.getSize("default_margin").width
Item
//Extruder icon.
Cura.ExtruderIcon
{
id: extruder
width: parent.width
height: childrenRect.height
materialColor: printCoreConfiguration.material.color
anchors.verticalCenter: parent.verticalCenter
extruderEnabled: printCoreConfiguration.material.brand !== "" && printCoreConfiguration.hotendID !== ""
}
Column
{
id: information
Label
{
id: extruderLabel
text: catalog.i18nc("@label:extruder label", "Extruder")
text: printCoreConfiguration.material.brand ? printCoreConfiguration.material.brand : " " //Use space so that the height is still correct.
renderType: Text.NativeRendering
elide: Text.ElideRight
anchors.left: parent.left
font: UM.Theme.getFont("default")
color: mainColor
color: UM.Theme.getColor("text_inactive")
}
// Rounded item to show the extruder number
Item
Label
{
id: extruderIconItem
anchors.verticalCenter: extruderLabel.verticalCenter
anchors.left: extruderLabel.right
anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
width: UM.Theme.getSize("section_icon").width
height: UM.Theme.getSize("section_icon").height
UM.RecolorImage {
id: mainCircle
anchors.fill: parent
anchors.centerIn: parent
sourceSize.width: parent.width
sourceSize.height: parent.height
source: UM.Theme.getIcon("extruder_button")
color: mainColor
}
Label
{
id: extruderNumberText
anchors.centerIn: parent
text: printCoreConfiguration.position + 1
renderType: Text.NativeRendering
font: UM.Theme.getFont("default")
color: mainColor
}
text: printCoreConfiguration.material.brand ? printCoreConfiguration.material.name : " " //Use space so that the height is still correct.
renderType: Text.NativeRendering
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
Label
{
text: printCoreConfiguration.hotendID ? printCoreConfiguration.hotendID : " " //Use space so that the height is still correct.
renderType: Text.NativeRendering
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_inactive")
}
}
Label
{
id: materialLabel
text: printCoreConfiguration.material.name
renderType: Text.NativeRendering
elide: Text.ElideRight
width: parent.width
font: UM.Theme.getFont("default_bold")
color: mainColor
}
Label
{
id: printCoreTypeLabel
text: printCoreConfiguration.hotendID
renderType: Text.NativeRendering
elide: Text.ElideRight
width: parent.width
font: UM.Theme.getFont("default")
color: mainColor
}
}

View file

@ -1,102 +0,0 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Button
{
id: base
property var outputDevice: null
property var matched: updateOnSync()
text: matched == true ? catalog.i18nc("@label:extruder label", "Yes") : catalog.i18nc("@label:extruder label", "No")
width: parent.width
height: parent.height
function updateOnSync()
{
if (outputDevice != undefined)
{
for (var index in outputDevice.uniqueConfigurations)
{
var configuration = outputDevice.uniqueConfigurations[index]
if (Cura.MachineManager.matchesConfiguration(configuration))
{
base.matched = true;
return;
}
}
}
base.matched = false;
}
style: ButtonStyle
{
background: Rectangle
{
color:
{
if(control.pressed)
{
return UM.Theme.getColor("sidebar_header_active");
}
else if(control.hovered)
{
return UM.Theme.getColor("sidebar_header_hover");
}
else
{
return UM.Theme.getColor("sidebar_header_bar");
}
}
Behavior on color { ColorAnimation { duration: 50; } }
UM.RecolorImage
{
id: downArrow
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: UM.Theme.getColor("text_emphasis")
source: UM.Theme.getIcon("arrow_bottom")
}
UM.RecolorImage
{
id: sidebarComboBoxLabel
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter;
width: UM.Theme.getSize("printer_sync_icon").width
height: UM.Theme.getSize("printer_sync_icon").height
color: control.matched ? UM.Theme.getColor("printer_config_matched") : UM.Theme.getColor("printer_config_mismatch")
source: UM.Theme.getIcon("tab_status_connected")
sourceSize.width: width
sourceSize.height: height
}
}
label: Label {}
}
Connections
{
target: outputDevice
onUniqueConfigurationsChanged: updateOnSync()
}
Connections
{
target: Cura.MachineManager
onCurrentConfigurationChanged: updateOnSync()
onOutputDevicesChanged: updateOnSync()
}
}

View file

@ -0,0 +1,81 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import UM 1.2 as UM
import Cura 1.0 as Cura
Menu
{
id: base
title: catalog.i18nc("@title:menu menubar:toplevel", "&File")
MenuItem
{
id: newProjectMenu
action: Cura.Actions.newProject
}
MenuItem
{
id: openMenu
action: Cura.Actions.open
}
RecentFilesMenu { }
MenuItem
{
id: saveWorkspaceMenu
text: catalog.i18nc("@title:menu menubar:file", "&Save...")
onTriggered:
{
var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" };
if(UM.Preferences.getValue("cura/dialog_on_project_save"))
{
saveWorkspaceDialog.args = args
saveWorkspaceDialog.open()
}
else
{
UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args)
}
}
}
MenuSeparator { }
MenuItem
{
id: saveAsMenu
text: catalog.i18nc("@title:menu menubar:file", "&Export...")
onTriggered:
{
var localDeviceId = "local_file"
UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"})
}
}
MenuItem
{
id: exportSelectionMenu
text: catalog.i18nc("@action:inmenu menubar:file", "Export Selection...")
enabled: UM.Selection.hasSelection
iconName: "document-save-as"
onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"})
}
MenuSeparator { }
MenuItem
{
id: reloadAllMenu
action: Cura.Actions.reloadAll
}
MenuSeparator { }
MenuItem { action: Cura.Actions.quit }
}

View file

@ -1,27 +0,0 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import UM 1.2 as UM
import Cura 1.0 as Cura
Item
{
property var status: "disconnected"
width: childrenRect.width
height: childrenRect.height
UM.RecolorImage
{
id: statusIcon
width: UM.Theme.getSize("printer_status_icon").width
height: UM.Theme.getSize("printer_status_icon").height
sourceSize.width: width
sourceSize.height: width
color: UM.Theme.getColor("tab_status_" + parent.status)
source: UM.Theme.getIcon(parent.status)
}
}

View file

@ -37,7 +37,7 @@ Menu
MenuSeparator
{
id: customSeparator
visible: Cura.CustomQualityProfilesDropDownMenuModel.rowCount > 0
visible: Cura.CustomQualityProfilesDropDownMenuModel.count > 0
}
Instantiator
@ -48,7 +48,7 @@ Menu
Connections
{
target: Cura.CustomQualityProfilesDropDownMenuModel
onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.rowCount() > 0
onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.count > 0
}
MenuItem
@ -62,12 +62,12 @@ Menu
onObjectAdded:
{
customSeparator.visible = model.rowCount() > 0;
customSeparator.visible = model.count > 0;
menu.insertItem(index, object);
}
onObjectRemoved:
{
customSeparator.visible = model.rowCount() > 0;
customSeparator.visible = model.count > 0;
menu.removeItem(object);
}
}

View file

@ -7,6 +7,8 @@ import QtQuick.Controls 1.1
import UM 1.3 as UM
import Cura 1.0 as Cura
import "../Dialogs"
Menu
{
id: menu

View file

@ -0,0 +1,70 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import UM 1.2 as UM
import Cura 1.0 as Cura
Menu
{
id: base
title: catalog.i18nc("@title:menu menubar:toplevel", "&Settings")
PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") }
Instantiator
{
model: Cura.MachineManager.activeMachine.extruderList
Menu
{
title: modelData.name
NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index }
MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index }
MenuSeparator
{
visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials
}
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Set as Active Extruder")
onTriggered: Cura.MachineManager.setExtruderIndex(model.index)
}
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Enable Extruder")
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true)
visible: !Cura.MachineManager.getExtruder(model.index).isEnabled
}
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Disable Extruder")
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
visible: Cura.MachineManager.getExtruder(model.index).isEnabled
enabled: Cura.MachineManager.numberExtrudersEnabled > 1
}
}
onObjectAdded: base.insertItem(index, object)
onObjectRemoved: base.removeItem(object)
}
// TODO Only show in dev mode. Remove check when feature ready
BuildplateMenu
{
title: catalog.i18nc("@title:menu", "&Build plate")
visible: CuraSDKVersion == "dev" && Cura.MachineManager.hasVariantBuildplates
}
ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile") }
MenuSeparator { }
MenuItem { action: Cura.Actions.configureSettingVisibility }
}

View file

@ -11,32 +11,10 @@ Menu
{
title: catalog.i18nc("@title:menu menubar:toplevel", "&View")
id: base
enabled: !PrintInformation.preSliced
property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
// main views
Instantiator
{
model: UM.ViewModel{}
MenuItem
{
text: model.name
checkable: true
checked: model.active
exclusiveGroup: group
onTriggered: UM.Controller.setActiveView(model.id)
enabled: !PrintInformation.preSliced
}
onObjectAdded: base.insertItem(index, object)
onObjectRemoved: base.removeItem(object)
}
ExclusiveGroup
{
id: group
}
MenuSeparator {}
Menu
{
title: catalog.i18nc("@action:inmenu menubar:view","&Camera position");
@ -80,12 +58,6 @@ Menu
MenuSeparator {}
MenuItem
{
action: Cura.Actions.expandSidebar
}
MenuSeparator {}
MenuItem
{
action: Cura.Actions.toggleFullScreen

View file

@ -13,9 +13,9 @@ import Cura 1.0 as Cura
Item
{
id: base;
UM.I18nCatalog { id: catalog; name:"cura"}
UM.I18nCatalog { id: catalog; name: "cura"}
height: childrenRect.height + UM.Theme.getSize("sidebar_margin").height
height: childrenRect.height + UM.Theme.getSize("thick_margin").height
property bool printerConnected: Cura.MachineManager.printerConnected
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
@ -162,10 +162,10 @@ Item
Label
{
id: statusLabel
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
width: parent.width - 2 * UM.Theme.getSize("thick_margin").width
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.leftMargin: UM.Theme.getSize("thick_margin").width
color: base.statusColor
font: UM.Theme.getFont("large")
@ -224,12 +224,12 @@ Item
property string backgroundColor: UM.Theme.getColor("progressbar_background");
property string controlColor: base.statusColor;
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width;
width: parent.width - 2 * UM.Theme.getSize("thick_margin").width;
height: UM.Theme.getSize("progressbar").height;
anchors.top: statusLabel.bottom;
anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 4);
anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 4);
anchors.left: parent.left;
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width;
anchors.leftMargin: UM.Theme.getSize("thick_margin").width;
}
Row
@ -237,9 +237,9 @@ Item
id: buttonsRow
height: abortButton.height
anchors.top: progressBar.bottom
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
anchors.topMargin: UM.Theme.getSize("thick_margin").height
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
anchors.rightMargin: UM.Theme.getSize("thick_margin").width
spacing: UM.Theme.getSize("default_margin").width
Row
@ -309,7 +309,7 @@ Item
}
}
style: UM.Theme.styles.sidebar_action_button
style: UM.Theme.styles.print_setup_action_button
}
Button
@ -325,7 +325,7 @@ Item
text: catalog.i18nc("@label", "Abort Print")
onClicked: confirmationDialog.visible = true
style: UM.Theme.styles.sidebar_action_button
style: UM.Theme.styles.print_setup_action_button
}
MessageDialog

View file

@ -1,15 +1,17 @@
// Copyright (c) 2017 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick 2.10
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import UM 1.2 as UM
import Cura 1.0 as Cura
import "Menus"
import "Menus/ConfigurationMenu"
Rectangle
{
id: base
@ -30,8 +32,8 @@ Rectangle
property variant printMaterialCosts: PrintInformation.materialCosts
property variant printMaterialNames: PrintInformation.materialNames
color: UM.Theme.getColor("sidebar")
UM.I18nCatalog { id: catalog; name:"cura"}
color: UM.Theme.getColor("main_background")
UM.I18nCatalog { id: catalog; name: "cura"}
Timer {
id: tooltipDelayTimer
@ -70,7 +72,7 @@ Rectangle
time -= minutes * 60
var seconds = Math.floor(time);
var finalTime = strPadLeft(hours, "0", 2) + ':' + strPadLeft(minutes,'0',2)+ ':' + strPadLeft(seconds,'0',2);
var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2);
return finalTime;
}
@ -85,11 +87,11 @@ Rectangle
}
}
MachineSelection
MachineSelector
{
id: machineSelection
width: base.width - configSelection.width - separator.width
height: UM.Theme.getSize("sidebar_header").height
height: UM.Theme.getSize("stage_menu").height
anchors.top: base.top
anchors.left: parent.left
}
@ -98,21 +100,20 @@ Rectangle
{
id: separator
visible: configSelection.visible
width: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0
height: UM.Theme.getSize("sidebar_header").height
color: UM.Theme.getColor("sidebar_lining_thin")
width: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0
height: UM.Theme.getSize("stage_menu").height
color: UM.Theme.getColor("thick_lining")
anchors.left: machineSelection.right
}
ConfigurationSelection
CustomConfigurationSelector
{
id: configSelection
visible: isNetworkPrinter && printerConnected
width: visible ? Math.round(base.width * 0.15) : 0
height: UM.Theme.getSize("sidebar_header").height
height: UM.Theme.getSize("stage_menu").height
anchors.top: base.top
anchors.right: parent.right
panelWidth: base.width
}
Loader
@ -158,10 +159,10 @@ Rectangle
{
id: footerSeparator
width: parent.width
height: UM.Theme.getSize("sidebar_lining").height
color: UM.Theme.getColor("sidebar_lining")
height: UM.Theme.getSize("wide_lining").height
color: UM.Theme.getColor("wide_lining")
anchors.bottom: monitorButton.top
anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
anchors.bottomMargin: UM.Theme.getSize("thick_margin").height
}
// MonitorButton is actually the bottom footer panel.
@ -172,7 +173,7 @@ Rectangle
anchors.bottom: parent.bottom
}
SidebarTooltip
PrintSetupTooltip
{
id: tooltip
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@ -55,7 +55,6 @@ Rectangle
{
width: control.width
height: control.height
sourceSize.width: width
sourceSize.height: width
color: UM.Theme.getColor("setting_control_text")
source: collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom")
@ -225,7 +224,7 @@ Rectangle
{
id: arrangeAllBuildPlatesButton;
text: catalog.i18nc("@action:button","Arrange to all build plates");
style: UM.Theme.styles.sidebar_action_button
style: UM.Theme.styles.print_setup_action_button
height: UM.Theme.getSize("objects_menu_button").height;
tooltip: '';
anchors
@ -245,7 +244,7 @@ Rectangle
{
id: arrangeBuildPlateButton;
text: catalog.i18nc("@action:button","Arrange current build plate");
style: UM.Theme.styles.sidebar_action_button
style: UM.Theme.styles.print_setup_action_button
height: UM.Theme.getSize("objects_menu_button").height;
tooltip: '';
anchors

View file

@ -1,4 +1,4 @@
// Copyright (c) 2017 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.1
@ -134,7 +134,7 @@ UM.PreferencesPage
UM.PluginsModel { id: plugins }
//: Language selection label
UM.I18nCatalog{id: catalog; name:"cura"}
UM.I18nCatalog{id: catalog; name: "cura"}
Label
{

View file

@ -21,8 +21,10 @@ UM.ManagementPage
function activeMachineIndex()
{
for(var i = 0; i < model.rowCount(); i++) {
if (model.getItem(i).id == Cura.MachineManager.activeMachineId) {
for(var i = 0; i < model.count; i++)
{
if (model.getItem(i).id == Cura.MachineManager.activeMachineId)
{
return i;
}
}
@ -47,7 +49,7 @@ UM.ManagementPage
{
text: catalog.i18nc("@action:button", "Remove");
iconName: "list-remove";
enabled: base.currentItem != null && model.rowCount() > 1
enabled: base.currentItem != null && model.count > 1
onClicked: confirmDialog.open();
},
Button

View file

@ -55,7 +55,8 @@ Rectangle
text: ""
implicitWidth: UM.Theme.getSize("favorites_button").width
implicitHeight: UM.Theme.getSize("favorites_button").height
UM.RecolorImage {
UM.RecolorImage
{
anchors
{
verticalCenter: parent.verticalCenter
@ -63,8 +64,6 @@ Rectangle
}
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: "black"
source: brand_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
}

View file

@ -57,7 +57,7 @@ Item
var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id
search_root_id = currentItemId
}
for (var material_idx = 0; material_idx < genericMaterialsModel.rowCount(); material_idx++)
for (var material_idx = 0; material_idx < genericMaterialsModel.count; material_idx++)
{
var material = genericMaterialsModel.getItem(material_idx)
if (material.root_material_id == search_root_id)
@ -72,15 +72,15 @@ Item
return true
}
}
for (var brand_idx = 0; brand_idx < materialsModel.rowCount(); brand_idx++)
for (var brand_idx = 0; brand_idx < materialsModel.count; brand_idx++)
{
var brand = materialsModel.getItem(brand_idx)
var types_model = brand.material_types
for (var type_idx = 0; type_idx < types_model.rowCount(); type_idx++)
for (var type_idx = 0; type_idx < types_model.count; type_idx++)
{
var type = types_model.getItem(type_idx)
var colors_model = type.colors
for (var material_idx = 0; material_idx < colors_model.rowCount(); material_idx++)
for (var material_idx = 0; material_idx < colors_model.count; material_idx++)
{
var material = colors_model.getItem(material_idx)
if (material.root_material_id == search_root_id)

View file

@ -95,8 +95,6 @@ Rectangle
}
width: UM.Theme.getSize("favorites_button_icon").width
height: UM.Theme.getSize("favorites_button_icon").height
sourceSize.width: width
sourceSize.height: height
color:
{
if (favorite_button.hovered)

View file

@ -74,8 +74,6 @@ Rectangle
}
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: "black"
source: material_type_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
}

View file

@ -188,21 +188,27 @@ Item
Connections
{
target: qualitiesModel
onItemsChanged: {
onItemsChanged:
{
var toSelectItemName = base.currentItem == null ? "" : base.currentItem.name;
if (newQualityNameToSelect != "") {
if (newQualityNameToSelect != "")
{
toSelectItemName = newQualityNameToSelect;
}
var newIdx = -1; // Default to nothing if nothing can be found
if (toSelectItemName != "") {
if (toSelectItemName != "")
{
// Select the required quality name if given
for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) {
for (var idx = 0; idx < qualitiesModel.count; ++idx)
{
var item = qualitiesModel.getItem(idx);
if (item.name == toSelectItemName) {
if (item.name == toSelectItemName)
{
// Switch to the newly created profile if needed
newIdx = idx;
if (base.toActivateNewQuality) {
if (base.toActivateNewQuality)
{
// Activate this custom quality if required
Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group);
}
@ -382,9 +388,11 @@ Item
var selectedItemName = Cura.MachineManager.activeQualityOrQualityChangesName;
// Select the required quality name if given
for (var idx = 0; idx < qualitiesModel.rowCount(); idx++) {
for (var idx = 0; idx < qualitiesModel.count; idx++)
{
var item = qualitiesModel.getItem(idx);
if (item.name == selectedItemName) {
if (item.name == selectedItemName)
{
currentIndex = idx;
break;
}

View file

@ -50,7 +50,7 @@ UM.PreferencesPage
{
return Qt.Unchecked
}
else if(definitionsModel.visibleCount == definitionsModel.rowCount(null))
else if(definitionsModel.visibleCount == definitionsModel.count)
{
return Qt.Checked
}

View file

@ -1,616 +0,0 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import UM 1.2 as UM
import Cura 1.0 as Cura
import "Menus"
import "Menus/ConfigurationMenu"
Rectangle
{
id: base
property int currentModeIndex: -1
property bool hideSettings: PrintInformation.preSliced
property bool hideView: Cura.MachineManager.activeMachineName == ""
// Is there an output device for this printer?
property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != ""
property bool printerConnected: Cura.MachineManager.printerConnected
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
property variant printDuration: PrintInformation.currentPrintTime
property variant printMaterialLengths: PrintInformation.materialLengths
property variant printMaterialWeights: PrintInformation.materialWeights
property variant printMaterialCosts: PrintInformation.materialCosts
property variant printMaterialNames: PrintInformation.materialNames
color: UM.Theme.getColor("sidebar")
UM.I18nCatalog { id: catalog; name:"cura"}
Timer {
id: tooltipDelayTimer
interval: 500
repeat: false
property var item
property string text
onTriggered:
{
base.showTooltip(base, {x: 0, y: item.y}, text);
}
}
function showTooltip(item, position, text)
{
tooltip.text = text;
position = item.mapToItem(base, position.x - UM.Theme.getSize("default_arrow").width, position.y);
tooltip.show(position);
}
function hideTooltip()
{
tooltip.hide();
}
function strPadLeft(string, pad, length) {
return (new Array(length + 1).join(pad) + string).slice(-length);
}
function getPrettyTime(time)
{
var hours = Math.floor(time / 3600)
time -= hours * 3600
var minutes = Math.floor(time / 60);
time -= minutes * 60
var seconds = Math.floor(time);
var finalTime = strPadLeft(hours, "0", 2) + ':' + strPadLeft(minutes,'0',2)+ ':' + strPadLeft(seconds,'0',2);
return finalTime;
}
MouseArea
{
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onWheel:
{
wheel.accepted = true;
}
}
MachineSelection
{
id: machineSelection
width: base.width - configSelection.width - separator.width
height: UM.Theme.getSize("sidebar_header").height
anchors.top: base.top
anchors.left: parent.left
}
Rectangle
{
id: separator
visible: configSelection.visible
width: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0
height: UM.Theme.getSize("sidebar_header").height
color: UM.Theme.getColor("sidebar_lining_thin")
anchors.left: machineSelection.right
}
ConfigurationSelection
{
id: configSelection
visible: isNetworkPrinter && printerConnected
width: visible ? Math.round(base.width * 0.15) : 0
height: UM.Theme.getSize("sidebar_header").height
anchors.top: base.top
anchors.right: parent.right
panelWidth: base.width
}
SidebarHeader {
id: header
width: parent.width
visible: !hideSettings && (machineExtruderCount.properties.value > 1 || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants)
anchors.top: machineSelection.bottom
onShowTooltip: base.showTooltip(item, location, text)
onHideTooltip: base.hideTooltip()
}
Rectangle {
id: headerSeparator
width: parent.width
visible: settingsModeSelection.visible && header.visible
height: visible ? UM.Theme.getSize("sidebar_lining").height : 0
color: UM.Theme.getColor("sidebar_lining")
anchors.top: header.bottom
anchors.topMargin: visible ? UM.Theme.getSize("sidebar_margin").height : 0
}
onCurrentModeIndexChanged:
{
UM.Preferences.setValue("cura/active_mode", currentModeIndex);
if(modesListModel.count > base.currentModeIndex)
{
sidebarContents.replace(modesListModel.get(base.currentModeIndex).item, { "replace": true })
}
}
Label
{
id: settingsModeLabel
text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified")
renderType: Text.NativeRendering
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.top: hideSettings ? machineSelection.bottom : headerSeparator.bottom
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
width: Math.round(parent.width * 0.45)
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
visible: !hideView
}
// Settings mode selection toggle
Rectangle
{
id: settingsModeSelection
color: "transparent"
width: Math.round(parent.width * 0.55)
height: UM.Theme.getSize("sidebar_header_mode_toggle").height
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
anchors.top:
{
if (settingsModeLabel.contentWidth >= parent.width - width - UM.Theme.getSize("sidebar_margin").width * 2)
{
return settingsModeLabel.bottom;
}
else
{
return headerSeparator.bottom;
}
}
visible: !hideSettings && !hideView
Component
{
id: wizardDelegate
Button
{
id: control
height: settingsModeSelection.height
width: Math.round(parent.width / 2)
anchors.left: parent.left
anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2)
anchors.verticalCenter: parent.verticalCenter
ButtonGroup.group: modeMenuGroup
checkable: true
checked: base.currentModeIndex == index
onClicked: base.currentModeIndex = index
onHoveredChanged:
{
if (hovered)
{
tooltipDelayTimer.item = settingsModeSelection
tooltipDelayTimer.text = model.tooltipText
tooltipDelayTimer.start()
}
else
{
tooltipDelayTimer.stop()
base.hideTooltip()
}
}
background: Rectangle
{
border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width
border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border"): UM.Theme.getColor("action_button_border")
// for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is
color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
}
contentItem: Label
{
text: model.text
font: UM.Theme.getFont("default")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
elide: Text.ElideRight
color:
{
if(control.pressed)
{
return UM.Theme.getColor("action_button_active_text");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_text");
}
return UM.Theme.getColor("action_button_text");
}
}
}
}
ButtonGroup
{
id: modeMenuGroup
}
ListView
{
id: modesList
model: modesListModel
delegate: wizardDelegate
anchors.top: parent.top
anchors.left: parent.left
width: parent.width
}
}
StackView
{
id: sidebarContents
anchors.bottom: footerSeparator.top
anchors.top: settingsModeSelection.bottom
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
anchors.left: base.left
anchors.right: base.right
visible: !hideSettings
replaceEnter: Transition {
PropertyAnimation {
property: "opacity"
from: 0
to:1
duration: 100
}
}
replaceExit: Transition {
PropertyAnimation {
property: "opacity"
from: 1
to:0
duration: 100
}
}
}
Loader
{
anchors.bottom: footerSeparator.top
anchors.top: headerSeparator.bottom
anchors.left: base.left
anchors.right: base.right
source: "SidebarContents.qml"
}
Rectangle
{
id: footerSeparator
width: parent.width
height: UM.Theme.getSize("sidebar_lining").height
color: UM.Theme.getColor("sidebar_lining")
anchors.bottom: printSpecs.top
anchors.bottomMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2 + UM.Theme.getSize("progressbar").height + UM.Theme.getFont("default_bold").pixelSize)
}
Item
{
id: printSpecs
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
height: timeDetails.height + costSpec.height
width: base.width - (saveButton.buttonRowWidth + UM.Theme.getSize("sidebar_margin").width)
clip: true
Label
{
id: timeDetails
anchors.left: parent.left
anchors.bottom: costSpec.top
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text_subtext")
text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label Hours and minutes", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
renderType: Text.NativeRendering
MouseArea
{
id: timeDetailsMouseArea
anchors.fill: parent
hoverEnabled: true
onEntered:
{
if(base.printDuration.valid && !base.printDuration.isTotalDurationZero)
{
// All the time information for the different features is achieved
var print_time = PrintInformation.getFeaturePrintTimes();
var total_seconds = parseInt(base.printDuration.getDisplayString(UM.DurationFormat.Seconds))
// A message is created and displayed when the user hover the time label
var tooltip_html = "<b>%1</b><br/><table width=\"100%\">".arg(catalog.i18nc("@tooltip", "Time specification"));
for(var feature in print_time)
{
if(!print_time[feature].isTotalDurationZero)
{
tooltip_html += "<tr><td>" + feature + ":</td>" +
"<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(print_time[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) +
"<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1%</td>".arg(Math.round(100 * parseInt(print_time[feature].getDisplayString(UM.DurationFormat.Seconds)) / total_seconds)) +
"</td></tr>";
}
}
tooltip_html += "</table>";
base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), tooltip_html);
}
}
onExited:
{
base.hideTooltip();
}
}
}
Label
{
function formatRow(items)
{
var row_html = "<tr>";
for(var item = 0; item < items.length; item++)
{
if (item == 0)
{
row_html += "<td valign=\"bottom\">%1</td>".arg(items[item]);
}
else
{
row_html += "<td align=\"right\" valign=\"bottom\">&nbsp;&nbsp;%1</td>".arg(items[item]);
}
}
row_html += "</tr>";
return row_html;
}
function getSpecsData()
{
var lengths = [];
var total_length = 0;
var weights = [];
var total_weight = 0;
var costs = [];
var total_cost = 0;
var some_costs_known = false;
var names = [];
if(base.printMaterialLengths)
{
for(var index = 0; index < base.printMaterialLengths.length; index++)
{
if(base.printMaterialLengths[index] > 0)
{
names.push(base.printMaterialNames[index]);
lengths.push(base.printMaterialLengths[index].toFixed(2));
weights.push(String(Math.round(base.printMaterialWeights[index])));
var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2);
costs.push(cost);
if(cost > 0)
{
some_costs_known = true;
}
total_length += base.printMaterialLengths[index];
total_weight += base.printMaterialWeights[index];
total_cost += base.printMaterialCosts[index];
}
}
}
if(lengths.length == 0)
{
lengths = ["0.00"];
weights = ["0"];
costs = ["0.00"];
}
var tooltip_html = "<b>%1</b><br/><table width=\"100%\">".arg(catalog.i18nc("@label", "Cost specification"));
for(var index = 0; index < lengths.length; index++)
{
tooltip_html += formatRow([
"%1:".arg(names[index]),
catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]),
catalog.i18nc("@label g for grams", "%1g").arg(weights[index]),
"%1&nbsp;%2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]),
]);
}
if(lengths.length > 1)
{
tooltip_html += formatRow([
catalog.i18nc("@label", "Total:"),
catalog.i18nc("@label m for meter", "%1m").arg(total_length.toFixed(2)),
catalog.i18nc("@label g for grams", "%1g").arg(Math.round(total_weight)),
"%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(total_cost.toFixed(2)),
]);
}
tooltip_html += "</table>";
tooltipText = tooltip_html;
return tooltipText
}
id: costSpec
anchors.left: parent.left
anchors.bottom: parent.bottom
font: UM.Theme.getFont("very_small")
renderType: Text.NativeRendering
color: UM.Theme.getColor("text_subtext")
elide: Text.ElideMiddle
width: parent.width
property string tooltipText
text:
{
var lengths = [];
var weights = [];
var costs = [];
var someCostsKnown = false;
if(base.printMaterialLengths) {
for(var index = 0; index < base.printMaterialLengths.length; index++)
{
if(base.printMaterialLengths[index] > 0)
{
lengths.push(base.printMaterialLengths[index].toFixed(2));
weights.push(String(Math.round(base.printMaterialWeights[index])));
var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2);
costs.push(cost);
if(cost > 0)
{
someCostsKnown = true;
}
}
}
}
if(lengths.length == 0)
{
lengths = ["0.00"];
weights = ["0"];
costs = ["0.00"];
}
var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g";
if(someCostsKnown)
{
result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency");
}
return result;
}
MouseArea
{
id: costSpecMouseArea
anchors.fill: parent
hoverEnabled: true
onEntered:
{
if(base.printDuration.valid && !base.printDuration.isTotalDurationZero)
{
var show_data = costSpec.getSpecsData()
base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), show_data);
}
}
onExited:
{
base.hideTooltip();
}
}
}
}
// SaveButton is actually the bottom footer panel.
SaveButton
{
id: saveButton
implicitWidth: base.width
anchors.top: footerSeparator.bottom
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
anchors.bottom: parent.bottom
}
SidebarTooltip
{
id: tooltip
}
// Setting mode: Recommended or Custom
ListModel
{
id: modesListModel
}
SidebarSimple
{
id: sidebarSimple
visible: false
onShowTooltip: base.showTooltip(item, location, text)
onHideTooltip: base.hideTooltip()
}
SidebarAdvanced
{
id: sidebarAdvanced
visible: false
onShowTooltip: base.showTooltip(item, location, text)
onHideTooltip: base.hideTooltip()
}
Component.onCompleted:
{
modesListModel.append({
text: catalog.i18nc("@title:tab", "Recommended"),
tooltipText: catalog.i18nc("@tooltip", "<b>Recommended Print Setup</b><br/><br/>Print with the recommended settings for the selected printer, material and quality."),
item: sidebarSimple
})
modesListModel.append({
text: catalog.i18nc("@title:tab", "Custom"),
tooltipText: catalog.i18nc("@tooltip", "<b>Custom Print Setup</b><br/><br/>Print with finegrained control over every last bit of the slicing process."),
item: sidebarAdvanced
})
var index = Math.round(UM.Preferences.getValue("cura/active_mode"))
if(index != null && !isNaN(index))
{
currentModeIndex = index;
}
else
{
currentModeIndex = 0;
}
}
UM.SettingPropertyProvider
{
id: machineExtruderCount
containerStack: Cura.MachineManager.activeMachine
key: "machine_extruder_count"
watchedProperties: [ "value" ]
storeIndex: 0
}
UM.SettingPropertyProvider
{
id: machineHeatedBed
containerStack: Cura.MachineManager.activeMachine
key: "machine_heated_bed"
watchedProperties: [ "value" ]
storeIndex: 0
}
}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import UM 1.4 as UM
import Cura 1.1 as Cura
Cura.ActionButton
{
shadowEnabled: true
shadowColor: enabled ? UM.Theme.getColor("primary_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow")
color: UM.Theme.getColor("primary_button")
textColor: UM.Theme.getColor("primary_button_text")
outlineColor: "transparent"
disabledColor: UM.Theme.getColor("action_button_disabled")
textDisabledColor: UM.Theme.getColor("action_button_disabled_text")
hoverColor: UM.Theme.getColor("primary_button_hover")
}

View file

@ -11,136 +11,180 @@ import Cura 1.0 as Cura
import "PrinterOutput"
Column
Rectangle
{
id: printMonitor
id: base
UM.I18nCatalog { id: catalog; name: "cura"}
function showTooltip(item, position, text)
{
tooltip.text = text;
position = item.mapToItem(base, position.x - UM.Theme.getSize("default_arrow").width, position.y);
tooltip.show(position);
}
function hideTooltip()
{
tooltip.hide();
}
function strPadLeft(string, pad, length) {
return (new Array(length + 1).join(pad) + string).slice(-length);
}
function getPrettyTime(time)
{
var hours = Math.floor(time / 3600)
time -= hours * 3600
var minutes = Math.floor(time / 60);
time -= minutes * 60
var seconds = Math.floor(time);
var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2);
return finalTime;
}
property var connectedDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
property var activePrinter: connectedDevice != null ? connectedDevice.activePrinter : null
property var activePrintJob: activePrinter != null ? activePrinter.activePrintJob: null
Cura.ExtrudersModel
PrintSetupTooltip
{
id: extrudersModel
simpleNames: true
id: tooltip
}
OutputDeviceHeader
Column
{
outputDevice: connectedDevice
}
id: printMonitor
Rectangle
{
color: UM.Theme.getColor("sidebar_lining")
width: parent.width
height: childrenRect.height
anchors.fill: parent
Flow
Cura.ExtrudersModel
{
id: extrudersGrid
spacing: UM.Theme.getSize("sidebar_lining_thin").width
id: extrudersModel
simpleNames: true
}
OutputDeviceHeader
{
outputDevice: connectedDevice
}
Rectangle
{
color: UM.Theme.getColor("wide_lining")
width: parent.width
height: childrenRect.height
Repeater
Flow
{
id: extrudersRepeater
model: activePrinter != null ? activePrinter.extruders : null
id: extrudersGrid
spacing: UM.Theme.getSize("thick_lining").width
width: parent.width
ExtruderBox
Repeater
{
color: UM.Theme.getColor("sidebar")
width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.round(extrudersGrid.width / 2 - UM.Theme.getSize("sidebar_lining_thin").width / 2)
extruderModel: modelData
id: extrudersRepeater
model: activePrinter != null ? activePrinter.extruders : null
ExtruderBox
{
color: UM.Theme.getColor("main_background")
width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.round(extrudersGrid.width / 2 - UM.Theme.getSize("thick_lining").width / 2)
extruderModel: modelData
}
}
}
}
}
Rectangle
{
color: UM.Theme.getColor("sidebar_lining")
width: parent.width
height: UM.Theme.getSize("sidebar_lining_thin").width
}
HeatedBedBox
{
visible: {
if(activePrinter != null && activePrinter.bedTemperature != -1)
{
return true
}
return false
}
printerModel: activePrinter
}
UM.SettingPropertyProvider
{
id: bedTemperature
containerStack: Cura.MachineManager.activeMachine
key: "material_bed_temperature"
watchedProperties: ["value", "minimum_value", "maximum_value", "resolve"]
storeIndex: 0
property var resolve: Cura.MachineManager.activeStack != Cura.MachineManager.activeMachine ? properties.resolve : "None"
}
UM.SettingPropertyProvider
{
id: machineExtruderCount
containerStack: Cura.MachineManager.activeMachine
key: "machine_extruder_count"
watchedProperties: ["value"]
}
ManualPrinterControl
{
printerModel: activePrinter
visible: activePrinter != null ? activePrinter.canControlManually : false
}
MonitorSection
{
label: catalog.i18nc("@label", "Active print")
width: base.width
visible: activePrinter != null
}
MonitorItem
{
label: catalog.i18nc("@label", "Job Name")
value: activePrintJob != null ? activePrintJob.name : ""
width: base.width
visible: activePrinter != null
}
MonitorItem
{
label: catalog.i18nc("@label", "Printing Time")
value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal) : ""
width: base.width
visible: activePrinter != null
}
MonitorItem
{
label: catalog.i18nc("@label", "Estimated time left")
value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal - activePrintJob.timeElapsed) : ""
visible:
Rectangle
{
if(activePrintJob == null)
color: UM.Theme.getColor("wide_lining")
width: parent.width
height: UM.Theme.getSize("thick_lining").width
}
HeatedBedBox
{
visible:
{
if(activePrinter != null && activePrinter.bedTemperature != -1)
{
return true
}
return false
}
return (activePrintJob.state == "printing" ||
activePrintJob.state == "resuming" ||
activePrintJob.state == "pausing" ||
activePrintJob.state == "paused")
printerModel: activePrinter
}
UM.SettingPropertyProvider
{
id: bedTemperature
containerStack: Cura.MachineManager.activeMachine
key: "material_bed_temperature"
watchedProperties: ["value", "minimum_value", "maximum_value", "resolve"]
storeIndex: 0
property var resolve: Cura.MachineManager.activeStack != Cura.MachineManager.activeMachine ? properties.resolve : "None"
}
UM.SettingPropertyProvider
{
id: machineExtruderCount
containerStack: Cura.MachineManager.activeMachine
key: "machine_extruder_count"
watchedProperties: ["value"]
}
ManualPrinterControl
{
printerModel: activePrinter
visible: activePrinter != null ? activePrinter.canControlManually : false
}
MonitorSection
{
label: catalog.i18nc("@label", "Active print")
width: base.width
visible: activePrinter != null
}
MonitorItem
{
label: catalog.i18nc("@label", "Job Name")
value: activePrintJob != null ? activePrintJob.name : ""
width: base.width
visible: activePrinter != null
}
MonitorItem
{
label: catalog.i18nc("@label", "Printing Time")
value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal) : ""
width: base.width
visible: activePrinter != null
}
MonitorItem
{
label: catalog.i18nc("@label", "Estimated time left")
value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal - activePrintJob.timeElapsed) : ""
visible:
{
if(activePrintJob == null)
{
return false
}
return (activePrintJob.state == "printing" ||
activePrintJob.state == "resuming" ||
activePrintJob.state == "pausing" ||
activePrintJob.state == "paused")
}
width: base.width
}
width: base.width
}
}
}

View file

@ -0,0 +1,133 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import UM 1.3 as UM
import Cura 1.0 as Cura
Item
{
id: customPrintSetup
height: childrenRect.height + padding
property real padding: UM.Theme.getSize("default_margin").width
property bool multipleExtruders: extrudersModel.count > 1
Cura.ExtrudersModel
{
id: extrudersModel
}
// Profile selector row
GlobalProfileSelector
{
id: globalProfileRow
anchors
{
top: parent.top
topMargin: parent.padding
left: parent.left
leftMargin: parent.padding
right: parent.right
rightMargin: parent.padding
}
}
UM.TabRow
{
id: tabBar
visible: multipleExtruders // The tab row is only visible when there are more than 1 extruder
anchors
{
top: globalProfileRow.bottom
topMargin: UM.Theme.getSize("default_margin").height
left: parent.left
leftMargin: parent.padding
right: parent.right
rightMargin: parent.padding
}
Repeater
{
id: repeater
model: extrudersModel
delegate: UM.TabRowButton
{
contentItem: Item
{
Cura.ExtruderIcon
{
anchors.horizontalCenter: parent.horizontalCenter
materialColor: model.color
extruderEnabled: model.enabled
}
}
onClicked:
{
Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex)
}
}
}
//When active extruder changes for some other reason, switch tabs.
//Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex!
//This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead.
Connections
{
target: Cura.ExtruderManager
onActiveExtruderChanged:
{
tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex);
}
}
//When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt.
//This causes the currentIndex of the tab to be in an invalid position which resets it to 0.
//Therefore we need to change it back to what it was: The active extruder index.
Connections
{
target: repeater.model
onModelChanged:
{
tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex)
}
}
}
Rectangle
{
height: UM.Theme.getSize("print_setup_widget").height
anchors
{
top: tabBar.visible ? tabBar.bottom : globalProfileRow.bottom
left: parent.left
leftMargin: parent.padding
right: parent.right
rightMargin: parent.padding
topMargin: -UM.Theme.getSize("default_lining").width
}
z: tabBar.z - 1
// Don't show the border when only one extruder
border.color: tabBar.visible ? UM.Theme.getColor("lining") : "transparent"
border.width: UM.Theme.getSize("default_lining").width
Cura.SettingView
{
anchors
{
fill: parent
topMargin: UM.Theme.getSize("default_margin").height
leftMargin: UM.Theme.getSize("default_margin").width
// Small space for the scrollbar
rightMargin: UM.Theme.getSize("narrow_margin").width
// Compensate for the negative margin in the parent
bottomMargin: UM.Theme.getSize("default_lining").width
}
}
}
}

View file

@ -0,0 +1,100 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.2
import UM 1.2 as UM
import Cura 1.0 as Cura
Item
{
id: globalProfileRow
height: childrenRect.height
Label
{
id: globalProfileLabel
anchors
{
top: parent.top
bottom: parent.bottom
left: parent.left
right: globalProfileSelection.left
}
text: catalog.i18nc("@label", "Profile")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignVCenter
}
ToolButton
{
id: globalProfileSelection
text: generateActiveQualityText()
width: UM.Theme.getSize("print_setup_big_item").width
height: UM.Theme.getSize("print_setup_big_item").height
anchors
{
top: parent.top
right: parent.right
}
tooltip: Cura.MachineManager.activeQualityOrQualityChangesName
style: UM.Theme.styles.print_setup_header_button
activeFocusOnPress: true
menu: Cura.ProfileMenu { }
function generateActiveQualityText()
{
var result = Cura.MachineManager.activeQualityOrQualityChangesName
if (Cura.MachineManager.isActiveQualityExperimental)
{
result += " (Experimental)"
}
if (Cura.MachineManager.isActiveQualitySupported)
{
if (Cura.MachineManager.activeQualityLayerHeight > 0)
{
result += " <font color=\"" + UM.Theme.getColor("text_detail") + "\">"
result += " - "
result += Cura.MachineManager.activeQualityLayerHeight + "mm"
result += "</font>"
}
}
return result
}
UM.SimpleButton
{
id: customisedSettings
visible: Cura.MachineManager.hasUserSettings
width: UM.Theme.getSize("print_setup_icon").width
height: UM.Theme.getSize("print_setup_icon").height
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("thick_margin").width)
color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button");
iconSource: UM.Theme.getIcon("star")
onClicked:
{
forceActiveFocus();
Cura.Actions.manageProfiles.trigger()
}
onEntered:
{
var content = catalog.i18nc("@tooltip","Some setting/override values are different from the values stored in the profile.\n\nClick to open the profile manager.")
base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("default_margin").width, 0), content)
}
onExited: base.hideTooltip()
}
}
}

View file

@ -0,0 +1,35 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import UM 1.3 as UM
import Cura 1.0 as Cura
Cura.ExpandableComponent
{
id: printSetupSelector
property bool preSlicedData: PrintInformation.preSliced
contentPadding: UM.Theme.getSize("default_lining").width
contentHeaderTitle: catalog.i18nc("@label", "Print settings")
enabled: !preSlicedData
disabledText: catalog.i18nc("@label shown when we load a Gcode file", "Print setup disabled. G code file can not be modified.")
UM.I18nCatalog
{
id: catalog
name: "cura"
}
headerItem: PrintSetupSelectorHeader {}
Cura.ExtrudersModel
{
id: extrudersModel
}
contentItem: PrintSetupSelectorContents {}
}

View file

@ -0,0 +1,129 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.3 as UM
import Cura 1.0 as Cura
import "Recommended"
import "Custom"
Item
{
id: content
width: UM.Theme.getSize("print_setup_widget").width - 2 * UM.Theme.getSize("default_margin").width
height: childrenRect.height
enum Mode
{
Recommended = 0,
Custom = 1
}
// Set the current mode index to the value that is stored in the preferences or Recommended mode otherwise.
property int currentModeIndex:
{
var index = Math.round(UM.Preferences.getValue("cura/active_mode"))
if (index != null && !isNaN(index))
{
return index
}
return PrintSetupSelectorContents.Mode.Recommended
}
onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex)
Item
{
id: contents
// Use the visible property instead of checking the currentModeIndex. That creates a binding that
// evaluates the new height every time the visible property changes.
height: recommendedPrintSetup.visible ? recommendedPrintSetup.height : customPrintSetup.height
anchors
{
top: parent.top
left: parent.left
right: parent.right
}
RecommendedPrintSetup
{
id: recommendedPrintSetup
anchors
{
left: parent.left
right: parent.right
top: parent.top
}
visible: currentModeIndex == PrintSetupSelectorContents.Mode.Recommended
}
CustomPrintSetup
{
id: customPrintSetup
anchors
{
left: parent.left
right: parent.right
top: parent.top
}
visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom
}
}
Rectangle
{
id: buttonsSeparator
// The buttonsSeparator is inside the contents. This is to avoid a double line in the bottom
anchors.bottom: contents.bottom
width: parent.width
height: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining")
}
Item
{
id: buttonRow
property real padding: UM.Theme.getSize("default_margin").width
height: childrenRect.height + 2 * padding
anchors
{
top: buttonsSeparator.bottom
left: parent.left
right: parent.right
}
Cura.SecondaryButton
{
anchors.top: parent.top
anchors.left: parent.left
anchors.margins: parent.padding
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@button", "Recommended")
iconSource: UM.Theme.getIcon("arrow_left")
visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom
onClicked: currentModeIndex = PrintSetupSelectorContents.Mode.Recommended
}
Cura.SecondaryButton
{
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("arrow_right")
isIconOnRightSide: true
visible: currentModeIndex == PrintSetupSelectorContents.Mode.Recommended
onClicked: currentModeIndex = PrintSetupSelectorContents.Mode.Custom
}
}
}

View file

@ -0,0 +1,83 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import UM 1.3 as UM
import Cura 1.0 as Cura
RowLayout
{
property string enabledText: catalog.i18nc("@label:Should be short", "On")
property string disabledText: catalog.i18nc("@label:Should be short", "Off")
Cura.IconWithText
{
source: UM.Theme.getIcon("category_layer_height")
text:
{
if (Cura.MachineManager.activeStack)
{
var text = Cura.MachineManager.activeQualityOrQualityChangesName
if (!Cura.MachineManager.hasNotSupportedQuality)
{
text += " " + layerHeight.properties.value + "mm"
}
return text
}
return ""
}
UM.SettingPropertyProvider
{
id: layerHeight
containerStack: Cura.MachineManager.activeStack
key: "layer_height"
watchedProperties: ["value"]
}
}
Cura.IconWithText
{
source: UM.Theme.getIcon("category_infill")
text: Cura.MachineManager.activeStack ? parseInt(infillDensity.properties.value) + "%" : "0%"
UM.SettingPropertyProvider
{
id: infillDensity
containerStack: Cura.MachineManager.activeStack
key: "infill_sparse_density"
watchedProperties: ["value"]
}
}
Cura.IconWithText
{
source: UM.Theme.getIcon("category_support")
text: supportEnabled.properties.value == "True" ? enabledText : disabledText
UM.SettingPropertyProvider
{
id: supportEnabled
containerStack: Cura.MachineManager.activeMachine
key: "support_enable"
watchedProperties: ["value"]
}
}
Cura.IconWithText
{
source: UM.Theme.getIcon("category_adhesion")
text: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" ? enabledText : disabledText
UM.SettingPropertyProvider
{
id: platformAdhesionType
containerStack: Cura.MachineManager.activeMachine
key: "adhesion_type"
watchedProperties: [ "value"]
}
}
}

View file

@ -0,0 +1,100 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
//
// Adhesion
//
Item
{
id: enableAdhesionRow
height: childrenRect.height
property real labelColumnWidth: Math.round(width / 3)
Cura.IconWithText
{
id: enableAdhesionRowTitle
anchors.top: parent.top
anchors.left: parent.left
source: UM.Theme.getIcon("category_adhesion")
text: catalog.i18nc("@label", "Adhesion")
width: labelColumnWidth
}
Item
{
id: enableAdhesionContainer
height: enableAdhesionCheckBox.height
anchors
{
left: enableAdhesionRowTitle.right
right: parent.right
verticalCenter: enableAdhesionRowTitle.verticalCenter
}
CheckBox
{
id: enableAdhesionCheckBox
anchors.verticalCenter: parent.verticalCenter
property alias _hovered: adhesionMouseArea.containsMouse
//: Setting enable printing build-plate adhesion helper checkbox
style: UM.Theme.styles.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
onClicked:
{
var adhesionType = "skirt"
if (!parent.checked)
{
// Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft
platformAdhesionType.removeFromContainer(0)
adhesionType = platformAdhesionType.properties.value
if(adhesionType == "skirt" || adhesionType == "none")
{
// If the rest of the stack doesn't prescribe an adhesion-type, default to a brim
adhesionType = "brim"
}
}
platformAdhesionType.setPropertyValue("value", adhesionType)
}
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", "enabled" ]
storeIndex: 0
}
}

View file

@ -0,0 +1,252 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.2 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("gradual")
}
if (density <= 0)
{
return UM.Theme.getIcon("hollow")
}
if (density < 40)
{
return UM.Theme.getIcon("sparse")
}
if (density < 90)
{
return UM.Theme.getIcon("dense")
}
return UM.Theme.getIcon("solid")
}
}
// 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: parseInt(infillDensity.properties.value)
}
// 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("category_infill")
text: catalog.i18nc("@label", "Infill") + " (%)"
width: labelColumnWidth
}
Item
{
id: infillSliderContainer
height: childrenRect.height
anchors
{
left: infillRowTitle.right
right: parent.right
verticalCenter: infillRowTitle.verticalCenter
}
Slider
{
id: infillSlider
width: parent.width
height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider
minimumValue: 0
maximumValue: 100
stepSize: 1
tickmarksEnabled: true
// disable slider when gradual support is enabled
enabled: parseInt(infillSteps.properties.value) == 0
// set initial value from stack
value: parseInt(infillDensity.properties.value)
style: SliderStyle
{
//Draw line
groove: Item
{
Rectangle
{
height: UM.Theme.getSize("print_setup_slider_groove").height
width: control.width - UM.Theme.getSize("print_setup_slider_handle").width
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
}
}
handle: Rectangle
{
id: handleButton
color: control.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)
}
tickmarks: Repeater
{
id: repeater
model: control.maximumValue / control.stepSize + 1
Rectangle
{
color: control.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
x: ((styleData.handleWidth / 2) - (implicitWidth / 2) + (index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))))
radius: Math.round(implicitWidth / 2)
visible: (index % 10) == 0 // Only show steps of 10%
Label
{
text: index
visible: (index % 20) == 0 // Only show steps of 20%
anchors.horizontalCenter: parent.horizontalCenter
y: UM.Theme.getSize("thin_margin").height
renderType: Text.NativeRendering
}
}
}
}
onValueChanged:
{
// Don't round the value if it's already the same
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 Recomended mode is Active,
// Otherwise if I change the value in the Custom mode the Recomended view will try to repeat
// same operation
var active_mode = UM.Preferences.getValue("cura/active_mode")
if (active_mode == 0 || active_mode == "simple")
{
Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue)
Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance")
}
}
}
}
// Gradual Support Infill Checkbox
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")
style: UM.Theme.styles.checkbox
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
}
}

View file

@ -0,0 +1,81 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Item
{
id: recommendedPrintSetup
height: childrenRect.height + 2 * padding
property Action configureSettings
property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1
property real padding: UM.Theme.getSize("thick_margin").width
UM.I18nCatalog
{
id: catalog
name: "cura"
}
Column
{
width: parent.width - 2 * parent.padding
spacing: UM.Theme.getSize("wide_margin").height
anchors
{
left: parent.left
right: parent.right
top: parent.top
margins: parent.padding
}
// TODO
property real firstColumnWidth: Math.round(width / 3)
RecommendedQualityProfileSelector
{
width: parent.width
// TODO Create a reusable component with these properties to not define them separately for each component
labelColumnWidth: parent.firstColumnWidth
}
RecommendedInfillDensitySelector
{
width: parent.width
// TODO Create a reusable component with these properties to not define them separately for each component
labelColumnWidth: parent.firstColumnWidth
}
RecommendedSupportSelector
{
width: parent.width
// TODO Create a reusable component with these properties to not define them separately for each component
labelColumnWidth: parent.firstColumnWidth
}
RecommendedAdhesionSelector
{
width: parent.width
// TODO Create a reusable component with these properties to not define them separately for each component
labelColumnWidth: parent.firstColumnWidth
}
}
UM.SettingPropertyProvider
{
id: extrudersEnabledCount
containerStack: Cura.MachineManager.activeMachine
key: "extruders_enabled_count"
watchedProperties: [ "value" ]
storeIndex: 0
}
}

View file

@ -0,0 +1,453 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
//
// Quality profile
//
Item
{
id: qualityRow
height: childrenRect.height
property real labelColumnWidth: Math.round(width / 3)
property real settingsColumnWidth: width - labelColumnWidth
Timer
{
id: qualitySliderChangeTimer
interval: 50
running: false
repeat: false
onTriggered:
{
var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value);
Cura.MachineManager.activeQualityGroup = item.quality_group;
}
}
Component.onCompleted: qualityModel.update()
Connections
{
target: Cura.QualityProfilesDropDownMenuModel
onItemsChanged: qualityModel.update()
}
Connections {
target: base
onVisibleChanged:
{
// update needs to be called when the widgets are visible, otherwise the step width calculation
// will fail because the width of an invisible item is 0.
if (visible)
{
qualityModel.update();
}
}
}
ListModel
{
id: qualityModel
property var totalTicks: 0
property var availableTotalTicks: 0
property var existingQualityProfile: 0
property var qualitySliderActiveIndex: 0
property var qualitySliderStepWidth: 0
property var qualitySliderAvailableMin: 0
property var qualitySliderAvailableMax: 0
property var qualitySliderMarginRight: 0
function update ()
{
reset()
var availableMin = -1
var availableMax = -1
for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++)
{
var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i)
// Add each quality item to the UI quality model
qualityModel.append(qualityItem)
// Set selected value
if (Cura.MachineManager.activeQualityType == qualityItem.quality_type)
{
// set to -1 when switching to user created profile so all ticks are clickable
if (Cura.SimpleModeSettingsManager.isProfileUserCreated)
{
qualityModel.qualitySliderActiveIndex = -1
}
else
{
qualityModel.qualitySliderActiveIndex = i
}
qualityModel.existingQualityProfile = 1
}
// Set min available
if (qualityItem.available && availableMin == -1)
{
availableMin = i
}
// Set max available
if (qualityItem.available)
{
availableMax = i
}
}
// Set total available ticks for active slider part
if (availableMin != -1)
{
qualityModel.availableTotalTicks = availableMax - availableMin + 1
}
// Calculate slider values
calculateSliderStepWidth(qualityModel.totalTicks)
calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks)
qualityModel.qualitySliderAvailableMin = availableMin
qualityModel.qualitySliderAvailableMax = availableMax
}
function calculateSliderStepWidth (totalTicks)
{
// Do not use Math.round otherwise the tickmarks won't be aligned
qualityModel.qualitySliderStepWidth = totalTicks != 0 ?
((settingsColumnWidth - UM.Theme.getSize("print_setup_slider_handle").width) / (totalTicks)) : 0
}
function calculateSliderMargins (availableMin, availableMax, totalTicks)
{
if (availableMin == -1 || (availableMin == 0 && availableMax == 0))
{
// Do not use Math.round otherwise the tickmarks won't be aligned
qualityModel.qualitySliderMarginRight = settingsColumnWidth
}
else if (availableMin == availableMax)
{
// Do not use Math.round otherwise the tickmarks won't be aligned
qualityModel.qualitySliderMarginRight = (totalTicks - availableMin) * qualitySliderStepWidth
}
else
{
// Do not use Math.round otherwise the tickmarks won't be aligned
qualityModel.qualitySliderMarginRight = (totalTicks - availableMax) * qualitySliderStepWidth
}
}
function reset () {
qualityModel.clear()
qualityModel.availableTotalTicks = 0
qualityModel.existingQualityProfile = 0
// check, the ticks count cannot be less than zero
qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1)
}
}
// Here are the elements that are shown in the left column
Item
{
id: titleRow
width: labelColumnWidth
height: childrenRect.height
Cura.IconWithText
{
id: qualityRowTitle
source: UM.Theme.getIcon("category_layer_height")
text: catalog.i18nc("@label", "Layer Height")
anchors.left: parent.left
anchors.right: customisedSettings.left
}
UM.SimpleButton
{
id: customisedSettings
visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated
height: visible ? UM.Theme.getSize("print_setup_icon").height : 0
width: height
anchors
{
right: parent.right
rightMargin: UM.Theme.getSize("default_margin").width
leftMargin: UM.Theme.getSize("default_margin").width
verticalCenter: parent.verticalCenter
}
color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
iconSource: UM.Theme.getIcon("reset")
onClicked:
{
// if the current profile is user-created, switch to a built-in quality
Cura.MachineManager.resetToUseDefaultQuality()
}
onEntered:
{
var tooltipContent = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.")
base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltipContent)
}
onExited: base.hideTooltip()
}
}
// Show titles for the each quality slider ticks
Item
{
anchors.left: speedSlider.left
anchors.top: speedSlider.bottom
height: childrenRect.height
Repeater
{
model: qualityModel
Label
{
anchors.verticalCenter: parent.verticalCenter
anchors.top: parent.top
// The height has to be set manually, otherwise it's not automatically calculated in the repeater
height: UM.Theme.getSize("default_margin").height
color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
text:
{
var result = ""
if(Cura.MachineManager.activeMachine != null)
{
result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height
if(result == undefined)
{
result = "";
}
else
{
result = Number(Math.round(result + "e+2") + "e-2"); //Round to 2 decimals. Javascript makes this difficult...
if (result == undefined || result != result) //Parse failure.
{
result = "";
}
}
}
return result
}
x:
{
// Make sure the text aligns correctly with each tick
if (qualityModel.totalTicks == 0)
{
// If there is only one tick, align it centrally
return Math.round(((settingsColumnWidth) - width) / 2)
}
else if (index == 0)
{
return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index
}
else if (index == qualityModel.totalTicks)
{
return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index - width
}
else
{
return Math.round((settingsColumnWidth / qualityModel.totalTicks) * index - (width / 2))
}
}
}
}
}
// Print speed slider
// Two sliders are created, one at the bottom with the unavailable qualities
// and the other at the top with the available quality profiles and so the handle to select them.
Item
{
id: speedSlider
height: childrenRect.height
anchors
{
left: titleRow.right
right: parent.right
verticalCenter: titleRow.verticalCenter
}
// Draw unavailable slider
Slider
{
id: unavailableSlider
width: parent.width
height: qualitySlider.height // Same height as the slider that is on top
updateValueWhileDragging : false
tickmarksEnabled: true
minimumValue: 0
// maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly
// speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available)
maximumValue: qualityModel.totalTicks
stepSize: 1
style: SliderStyle
{
//Draw Unvailable line
groove: Item
{
Rectangle
{
height: UM.Theme.getSize("print_setup_slider_groove").height
width: control.width - UM.Theme.getSize("print_setup_slider_handle").width
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: UM.Theme.getColor("quality_slider_unavailable")
}
}
handle: Item {}
tickmarks: Repeater
{
id: qualityRepeater
model: qualityModel.totalTicks > 0 ? qualityModel : 0
Rectangle
{
color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? 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
x: ((UM.Theme.getSize("print_setup_slider_handle").width / 2) - (implicitWidth / 2) + (qualityModel.qualitySliderStepWidth * index))
radius: Math.round(implicitWidth / 2)
}
}
}
// Create a mouse area on top of the unavailable profiles to show a specific tooltip
MouseArea
{
anchors.fill: parent
hoverEnabled: true
enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated
onEntered:
{
var tooltipContent = catalog.i18nc("@tooltip", "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile")
base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent)
}
onExited: base.hideTooltip()
}
}
// Draw available slider
Slider
{
id: qualitySlider
width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) + UM.Theme.getSize("print_setup_slider_handle").width
height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider
enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized
visible: qualityModel.availableTotalTicks > 0
updateValueWhileDragging : false
anchors
{
right: parent.right
rightMargin: qualityModel.qualitySliderMarginRight
}
minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0
// maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly
// speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available)
maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1
stepSize: 1
value: qualityModel.qualitySliderActiveIndex
style: SliderStyle
{
// Draw Available line
groove: Item
{
Rectangle
{
height: UM.Theme.getSize("print_setup_slider_groove").height
width: control.width - UM.Theme.getSize("print_setup_slider_handle").width
anchors.verticalCenter: parent.verticalCenter
// Do not use Math.round otherwise the tickmarks won't be aligned
x: UM.Theme.getSize("print_setup_slider_handle").width / 2
color: UM.Theme.getColor("quality_slider_available")
}
}
handle: Rectangle
{
id: qualityhandleButton
color: UM.Theme.getColor("primary")
implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width
implicitHeight: implicitWidth
radius: Math.round(implicitWidth / 2)
visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile
}
}
onValueChanged:
{
// only change if an active machine is set and the slider is visible at all.
if (Cura.MachineManager.activeMachine != null && visible)
{
// prevent updating during view initializing. Trigger only if the value changed by user
if (qualitySlider.value != qualityModel.qualitySliderActiveIndex && qualityModel.qualitySliderActiveIndex != -1)
{
// start updating with short delay
qualitySliderChangeTimer.start()
}
}
}
// This mouse area is only used to capture the onHover state and don't propagate it to the unavailable mouse area
MouseArea
{
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated
}
}
// This mouse area will only take the mouse events and show a tooltip when the profile in use is
// a user created profile
MouseArea
{
anchors.fill: parent
hoverEnabled: true
visible: Cura.SimpleModeSettingsManager.isProfileUserCreated
onEntered:
{
var tooltipContent = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab")
base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent)
}
onExited: base.hideTooltip()
}
}
}

View file

@ -0,0 +1,204 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
//
// Enable support
//
Item
{
id: enableSupportRow
height: childrenRect.height
property real labelColumnWidth: Math.round(width / 3)
Cura.IconWithText
{
id: enableSupportRowTitle
anchors.top: parent.top
anchors.left: parent.left
visible: enableSupportCheckBox.visible
source: UM.Theme.getIcon("category_support")
text: catalog.i18nc("@label", "Support")
width: labelColumnWidth
}
Item
{
id: enableSupportContainer
height: enableSupportCheckBox.height
anchors
{
left: enableSupportRowTitle.right
right: parent.right
verticalCenter: enableSupportRowTitle.verticalCenter
}
CheckBox
{
id: enableSupportCheckBox
anchors.verticalCenter: parent.verticalCenter
property alias _hovered: enableSupportMouseArea.containsMouse
style: UM.Theme.styles.checkbox
enabled: recommendedPrintSetup.settingsEnabled
visible: supportEnabled.properties.enabled == "True"
checked: supportEnabled.properties.value == "True"
MouseArea
{
id: enableSupportMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True")
onEntered:
{
base.showTooltip(enableSupportCheckBox, 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()
}
}
ComboBox
{
id: supportExtruderCombobox
height: UM.Theme.getSize("print_setup_big_item").height
anchors
{
left: enableSupportCheckBox.right
right: parent.right
leftMargin: UM.Theme.getSize("thick_margin").width
rightMargin: UM.Theme.getSize("thick_margin").width
verticalCenter: parent.verticalCenter
}
style: UM.Theme.styles.combobox_color
enabled: recommendedPrintSetup.settingsEnabled
visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1)
textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started
model: extruderModel
property alias _hovered: supportExtruderMouseArea.containsMouse
property string color_override: "" // for manually setting values
property string color: // is evaluated automatically, but the first time is before extruderModel being filled
{
var current_extruder = extruderModel.get(currentIndex)
color_override = ""
if (current_extruder === undefined) return ""
return (current_extruder.color) ? current_extruder.color : ""
}
currentIndex:
{
if (supportExtruderNr.properties == null)
{
return Cura.MachineManager.defaultExtruderPosition
}
else
{
var extruder = parseInt(supportExtruderNr.properties.value)
if ( extruder === -1)
{
return Cura.MachineManager.defaultExtruderPosition
}
return extruder;
}
}
onActivated: supportExtruderNr.setPropertyValue("value", String(index))
MouseArea
{
id: supportExtruderMouseArea
anchors.fill: parent
hoverEnabled: true
enabled: recommendedPrintSetup.settingsEnabled
acceptedButtons: Qt.NoButton
onEntered:
{
base.showTooltip(supportExtruderCombobox, Qt.point(-enableSupportContainer.x - supportExtruderCombobox.x - UM.Theme.getSize("thick_margin").width, 0),
catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."));
}
onExited: base.hideTooltip()
}
function updateCurrentColor()
{
var current_extruder = extruderModel.get(currentIndex)
if (current_extruder !== undefined)
{
supportExtruderCombobox.color_override = current_extruder.color
}
}
}
}
ListModel
{
id: extruderModel
Component.onCompleted: populateExtruderModel()
}
//: Model used to populate the extrudelModel
Cura.ExtrudersModel
{
id: extruders
onModelChanged: populateExtruderModel()
}
UM.SettingPropertyProvider
{
id: supportEnabled
containerStack: Cura.MachineManager.activeMachine
key: "support_enable"
watchedProperties: [ "value", "enabled", "description" ]
storeIndex: 0
}
UM.SettingPropertyProvider
{
id: supportExtruderNr
containerStack: Cura.MachineManager.activeMachine
key: "support_extruder_nr"
watchedProperties: [ "value" ]
storeIndex: 0
}
UM.SettingPropertyProvider
{
id: machineExtruderCount
containerStack: Cura.MachineManager.activeMachine
key: "machine_extruder_count"
watchedProperties: ["value"]
storeIndex: 0
}
function populateExtruderModel()
{
extruderModel.clear()
for (var extruderNumber = 0; extruderNumber < extruders.rowCount(); extruderNumber++)
{
extruderModel.append({
text: extruders.getItem(extruderNumber).name,
color: extruders.getItem(extruderNumber).color
})
}
supportExtruderCombobox.updateCurrentColor()
}
}

View file

@ -36,7 +36,7 @@ UM.PointingRectangle {
}
}
base.opacity = 1;
target = Qt.point(40 , position.y + Math.round(UM.Theme.getSize("tooltip_arrow_margins").height / 2))
target = Qt.point(position.x + 1, position.y + Math.round(UM.Theme.getSize("tooltip_arrow_margins").height / 2))
}
function hide() {

View file

@ -12,8 +12,10 @@ Item
property alias color: background.color
property var extruderModel
property var position: index
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
implicitWidth: parent.width
implicitHeight: UM.Theme.getSize("sidebar_extruder_box").height
implicitHeight: UM.Theme.getSize("print_setup_extruder_box").height
UM.SettingPropertyProvider
{
@ -45,7 +47,7 @@ Item
{
id: extruderTargetTemperature
text: Math.round(extruderModel.targetHotendTemperature) + "°C"
font: UM.Theme.getFont("small")
font: UM.Theme.getFont("default_bold")
color: UM.Theme.getColor("text_inactive")
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width

View file

@ -1,10 +1,10 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import QtQuick 2.10
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3
import UM 1.2 as UM
import Cura 1.0 as Cura
@ -12,12 +12,13 @@ import Cura 1.0 as Cura
Item
{
implicitWidth: parent.width
height: visible ? UM.Theme.getSize("sidebar_extruder_box").height : 0
height: visible ? UM.Theme.getSize("print_setup_extruder_box").height : 0
property var printerModel
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
Rectangle
{
color: UM.Theme.getColor("sidebar")
color: UM.Theme.getColor("main_background")
anchors.fill: parent
Label //Build plate label.
@ -34,7 +35,7 @@ Item
{
id: bedTargetTemperature
text: printerModel != null ? printerModel.targetBedTemperature + "°C" : ""
font: UM.Theme.getFont("small")
font: UM.Theme.getFont("default_bold")
color: UM.Theme.getColor("text_inactive")
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
@ -114,7 +115,7 @@ Item
{
return false; //Can't preheat if not connected.
}
if (!connectedPrinter.acceptsCommands)
if (connectedPrinter == null || !connectedPrinter.acceptsCommands)
{
return false; //Not allowed to do anything.
}

View file

@ -1,103 +1,26 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import QtQuick 2.10
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3
import UM 1.2 as UM
import UM 1.3 as UM
import Cura 1.0 as Cura
import "."
Item
{
property var printerModel
property var printerModel: null
property var activePrintJob: printerModel != null ? printerModel.activePrintJob : null
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
implicitWidth: parent.width
implicitHeight: childrenRect.height
Component
{
id: monitorButtonStyle
ButtonStyle
{
background: Rectangle
{
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_border");
}
else if(control.pressed)
{
return UM.Theme.getColor("action_button_active_border");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_border");
}
return UM.Theme.getColor("action_button_border");
}
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled");
}
else if(control.pressed)
{
return UM.Theme.getColor("action_button_active");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered");
}
return UM.Theme.getColor("action_button");
}
Behavior on color
{
ColorAnimation
{
duration: 50
}
}
}
label: Item
{
UM.RecolorImage
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: Math.floor(control.width / 2)
height: Math.floor(control.height / 2)
sourceSize.width: width
sourceSize.height: width
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_text");
}
else if(control.pressed)
{
return UM.Theme.getColor("action_button_active_text");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_text");
}
return UM.Theme.getColor("action_button_text");
}
source: control.iconSource
}
}
}
}
Column
{
enabled:
@ -180,7 +103,7 @@ Item
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_top");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -197,7 +120,7 @@ Item
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_left");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -214,7 +137,7 @@ Item
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_right");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -231,7 +154,7 @@ Item
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_bottom");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -248,7 +171,7 @@ Item
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("home");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -278,7 +201,7 @@ Item
Button
{
iconSource: UM.Theme.getIcon("arrow_top");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -291,7 +214,7 @@ Item
Button
{
iconSource: UM.Theme.getIcon("home");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -304,7 +227,7 @@ Item
Button
{
iconSource: UM.Theme.getIcon("arrow_bottom");
style: monitorButtonStyle
style: UM.Theme.styles.monitor_button_style
width: height
height: UM.Theme.getSize("setting_control").height
@ -356,72 +279,7 @@ Item
checked: distancesRow.currentDistance == model.value
onClicked: distancesRow.currentDistance = model.value
style: ButtonStyle {
background: Rectangle {
border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width
border.color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_border");
}
else if (control.checked || control.pressed)
{
return UM.Theme.getColor("action_button_active_border");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_border");
}
return UM.Theme.getColor("action_button_border");
}
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled");
}
else if (control.checked || control.pressed)
{
return UM.Theme.getColor("action_button_active");
}
else if (control.hovered)
{
return UM.Theme.getColor("action_button_hovered");
}
return UM.Theme.getColor("action_button");
}
Behavior on color { ColorAnimation { duration: 50; } }
Label {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2
anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_text");
}
else if (control.checked || control.pressed)
{
return UM.Theme.getColor("action_button_active_text");
}
else if (control.hovered)
{
return UM.Theme.getColor("action_button_hovered_text");
}
return UM.Theme.getColor("action_button_text");
}
font: UM.Theme.getFont("default")
text: control.text
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideMiddle
}
}
label: Item { }
}
style: UM.Theme.styles.monitor_checkable_button_style
}
}
}
@ -462,7 +320,7 @@ Item
if (printerModel == null) {
return false // Can't send custom commands if not connected.
}
if (!connectedPrinter.acceptsCommands) {
if (connectedPrinter == null || !connectedPrinter.acceptsCommands) {
return false // Not allowed to do anything
}
if (connectedPrinter.jobState == "printing" || connectedPrinter.jobState == "pre_print" || connectedPrinter.jobState == "resuming" || connectedPrinter.jobState == "pausing" || connectedPrinter.jobState == "paused" || connectedPrinter.jobState == "error" || connectedPrinter.jobState == "offline") {
@ -551,4 +409,4 @@ Item
}
ExclusiveGroup { id: distanceGroup }
}
}
}

View file

@ -15,6 +15,8 @@ Item
property string value: ""
height: childrenRect.height;
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
Row
{
height: UM.Theme.getSize("setting_control").height

View file

@ -1,10 +1,10 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import QtQuick 2.10
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3
import UM 1.2 as UM
import Cura 1.0 as Cura
@ -13,7 +13,8 @@ Item
{
id: base
property string label
height: childrenRect.height;
height: childrenRect.height
Rectangle
{
color: UM.Theme.getColor("setting_category")
@ -30,4 +31,4 @@ Item
color: UM.Theme.getColor("setting_category_text")
}
}
}
}

View file

@ -43,10 +43,10 @@ Item
{
id: outputDeviceAddressLabel
text: (outputDevice != null && outputDevice.address != null) ? outputDevice.address : ""
font: UM.Theme.getFont("small")
font: UM.Theme.getFont("default_bold")
color: UM.Theme.getColor("text_inactive")
anchors.top: parent.top
anchors.right: parent.right
anchors.top: outputDeviceNameLabel.bottom
anchors.left: parent.left
anchors.margins: UM.Theme.getSize("default_margin").width
}
@ -54,7 +54,7 @@ Item
{
text: outputDevice != null ? "" : catalog.i18nc("@info:status", "The printer is not connected.")
color: outputDevice != null && outputDevice.acceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
font: UM.Theme.getFont("very_small")
font: UM.Theme.getFont("default")
wrapMode: Text.WordWrap
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width

View file

@ -0,0 +1,174 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
Cura.ExpandablePopup
{
id: machineSelector
property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != ""
property bool isPrinterConnected: Cura.MachineManager.printerConnected
property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
contentPadding: UM.Theme.getSize("default_lining").width
contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft
UM.I18nCatalog
{
id: catalog
name: "cura"
}
headerItem: Item
{
implicitHeight: icon.height
UM.RecolorImage
{
id: icon
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
source:
{
if (isNetworkPrinter)
{
if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1)
{
return UM.Theme.getIcon("printer_group")
}
return UM.Theme.getIcon("printer_single")
}
return ""
}
width: UM.Theme.getSize("machine_selector_icon").width
height: width
color: UM.Theme.getColor("machine_selector_printer_icon")
visible: source != ""
}
Label
{
id: label
anchors.left: icon.visible ? icon.right : parent.left
anchors.right: parent.right
anchors.leftMargin: UM.Theme.getSize("thin_margin").width
anchors.verticalCenter: icon.verticalCenter
text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName
elide: Text.ElideRight
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
}
UM.RecolorImage
{
anchors
{
bottom: parent.bottom
left: parent.left
leftMargin: UM.Theme.getSize("thick_margin").width
}
source: UM.Theme.getIcon("printer_connected")
width: UM.Theme.getSize("printer_status_icon").width
height: UM.Theme.getSize("printer_status_icon").height
color: UM.Theme.getColor("primary")
visible: isNetworkPrinter && isPrinterConnected
// Make a themable circle in the background so we can change it in other themes
Rectangle
{
id: iconBackground
anchors.centerIn: parent
// Make it a bit bigger so there is an outline
width: parent.width + 2 * UM.Theme.getSize("default_lining").width
height: parent.height + 2 * UM.Theme.getSize("default_lining").height
radius: Math.round(width / 2)
color: UM.Theme.getColor("main_background")
z: parent.z - 1
}
}
}
contentItem: Item
{
id: popup
width: UM.Theme.getSize("machine_selector_widget_content").width
ScrollView
{
id: scroll
width: parent.width
clip: true
leftPadding: UM.Theme.getSize("default_lining").width
rightPadding: UM.Theme.getSize("default_lining").width
MachineSelectorList
{
// Can't use parent.width since the parent is the flickable component and not the ScrollView
width: scroll.width - scroll.leftPadding - scroll.rightPadding
property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height
onHeightChanged:
{
scroll.height = Math.min(height, maximumHeight)
popup.height = scroll.height + buttonRow.height
}
}
}
Rectangle
{
id: separator
anchors.top: scroll.bottom
width: parent.width
height: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining")
}
Row
{
id: buttonRow
// The separator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar.
anchors.top: separator.top
anchors.horizontalCenter: parent.horizontalCenter
padding: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width
Cura.SecondaryButton
{
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@button", "Add printer")
onClicked:
{
toggleContent()
Cura.Actions.addMachine.trigger()
}
}
Cura.SecondaryButton
{
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@button", "Manage printers")
onClicked:
{
toggleContent()
Cura.Actions.configureMachines.trigger()
}
}
}
}
}

View file

@ -0,0 +1,103 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import UM 1.1 as UM
import Cura 1.0 as Cura
Button
{
id: machineSelectorButton
width: parent.width
height: UM.Theme.getSize("action_button").height
leftPadding: UM.Theme.getSize("thick_margin").width
rightPadding: UM.Theme.getSize("thick_margin").width
checkable: true
hoverEnabled: true
property var outputDevice: null
property var printerTypesList: []
function updatePrinterTypesList()
{
printerTypesList = (checked && (outputDevice != null)) ? outputDevice.uniquePrinterTypes : []
}
contentItem: Item
{
width: machineSelectorButton.width - machineSelectorButton.leftPadding
height: UM.Theme.getSize("action_button").height
Label
{
id: buttonText
anchors
{
left: parent.left
right: printerTypes.left
verticalCenter: parent.verticalCenter
}
text: machineSelectorButton.text
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("action_button")
visible: text != ""
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
Row
{
id: printerTypes
width: childrenRect.width
anchors
{
right: parent.right
verticalCenter: parent.verticalCenter
}
spacing: UM.Theme.getSize("narrow_margin").width
Repeater
{
model: printerTypesList
delegate: Cura.PrinterTypeLabel
{
text: Cura.MachineManager.getAbbreviatedMachineName(modelData)
}
}
}
}
background: Rectangle
{
id: backgroundRect
color: machineSelectorButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent"
radius: UM.Theme.getSize("action_button_radius").width
border.width: UM.Theme.getSize("default_lining").width
border.color: machineSelectorButton.checked ? UM.Theme.getColor("primary") : "transparent"
}
onClicked:
{
toggleContent()
Cura.MachineManager.setActiveMachine(model.id)
}
Connections
{
target: outputDevice
onUniqueConfigurationsChanged: updatePrinterTypesList()
}
Connections
{
target: Cura.MachineManager
onOutputDevicesChanged: updatePrinterTypesList()
}
Component.onCompleted: updatePrinterTypesList()
}

View file

@ -0,0 +1,84 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
Column
{
id: machineSelectorList
Label
{
text: catalog.i18nc("@label", "Connected printers")
visible: networkedPrintersModel.items.length > 0
leftPadding: UM.Theme.getSize("default_margin").width
height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0
renderType: Text.NativeRendering
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text_medium")
verticalAlignment: Text.AlignVCenter
}
Repeater
{
id: networkedPrinters
model: UM.ContainerStacksModel
{
id: networkedPrintersModel
filter:
{
"type": "machine", "um_network_key": "*", "hidden": "False"
}
}
delegate: MachineSelectorButton
{
text: model.metadata["connect_group_name"]
checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"]
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
Connections
{
target: Cura.MachineManager
onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"]
}
}
}
Label
{
text: catalog.i18nc("@label", "Preset printers")
visible: virtualPrintersModel.items.length > 0
leftPadding: UM.Theme.getSize("default_margin").width
height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0
renderType: Text.NativeRendering
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text_medium")
verticalAlignment: Text.AlignVCenter
}
Repeater
{
id: virtualPrinters
model: UM.ContainerStacksModel
{
id: virtualPrintersModel
filter:
{
"type": "machine", "um_network_key": null
}
}
delegate: MachineSelectorButton
{
text: model.name
checked: Cura.MachineManager.activeMachineId == model.id
}
}
}

View file

@ -0,0 +1,34 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.1
import UM 1.1 as UM
// This component creates a label with the abbreviated name of a printer, with a rectangle surrounding the label.
// It is created in a separated place in order to be reused whenever needed.
Item
{
property alias text: printerTypeLabel.text
width: UM.Theme.getSize("printer_type_label").width
height: UM.Theme.getSize("printer_type_label").height
Rectangle
{
anchors.fill: parent
color: UM.Theme.getColor("printer_type_label_background")
}
Label
{
id: printerTypeLabel
text: "CFFFP" // As an abbreviated name of the Custom FFF Printer
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
renderType: Text.NativeRendering
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
}
}

View file

@ -0,0 +1,72 @@
import QtQuick 2.7
import UM 1.2 as UM
// The rounded rectangle works mostly like a regular rectangle, but provides the option to have rounded corners on only one side of the rectangle.
Item
{
id: roundedRectangle
// As per the regular rectangle
property color color: "transparent"
// As per regular rectangle
property int radius: UM.Theme.getSize("default_radius").width
// On what side should the corners be shown 5 can be used if no radius is needed.
// 1 is down, 2 is left, 3 is up and 4 is right.
property int cornerSide: RoundedRectangle.Direction.None
// Simple object to ensure that border.width and border.color work
property BorderGroup border: BorderGroup {}
enum Direction
{
None = 0,
Down = 1,
Left = 2,
Up = 3,
Right = 4,
All = 5
}
Rectangle
{
id: background
anchors.fill: parent
radius: cornerSide != RoundedRectangle.Direction.None ? parent.radius : 0
color: parent.color
border.width: parent.border.width
border.color: parent.border.color
}
// The item that covers 2 of the corners to make them not rounded.
Rectangle
{
visible: cornerSide != RoundedRectangle.Direction.None && cornerSide != RoundedRectangle.Direction.All
height: cornerSide % 2 ? parent.radius: parent.height
width: cornerSide % 2 ? parent.width : parent.radius
color: parent.color
anchors
{
right: cornerSide == RoundedRectangle.Direction.Left ? parent.right: undefined
bottom: cornerSide == RoundedRectangle.Direction.Up ? parent.bottom: undefined
}
border.width: parent.border.width
border.color: parent.border.color
Rectangle
{
color: roundedRectangle.color
height: cornerSide % 2 ? roundedRectangle.border.width: roundedRectangle.height - 2 * roundedRectangle.border.width
width: cornerSide % 2 ? roundedRectangle.width - 2 * roundedRectangle.border.width: roundedRectangle.border.width
anchors
{
right: cornerSide == RoundedRectangle.Direction.Right ? parent.right : undefined
bottom: cornerSide == RoundedRectangle.Direction.Down ? parent.bottom: undefined
horizontalCenter: cornerSide % 2 ? parent.horizontalCenter: undefined
verticalCenter: cornerSide % 2 ? undefined: parent.verticalCenter
}
}
}
}

View file

@ -1,409 +0,0 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import UM 1.1 as UM
import Cura 1.0 as Cura
Item {
id: base;
UM.I18nCatalog { id: catalog; name:"cura"}
property real progress: UM.Backend.progress
property int backendState: UM.Backend.state
property bool activity: CuraApplication.platformActivity
property alias buttonRowWidth: saveRow.width
property string fileBaseName
property string statusText:
{
if(!activity)
{
return catalog.i18nc("@label:PrintjobStatus", "Please load a 3D model");
}
if (base.backendState == "undefined") {
return ""
}
switch(base.backendState)
{
case 1:
return catalog.i18nc("@label:PrintjobStatus", "Ready to slice");
case 2:
return catalog.i18nc("@label:PrintjobStatus", "Slicing...");
case 3:
return catalog.i18nc("@label:PrintjobStatus %1 is target operation","Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription);
case 4:
return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice");
case 5:
return catalog.i18nc("@label:PrintjobStatus", "Slicing unavailable");
default:
return "";
}
}
function sliceOrStopSlicing() {
try {
if ([1, 5].indexOf(base.backendState) != -1) {
CuraApplication.backend.forceSlice();
} else {
CuraApplication.backend.stopSlicing();
}
} catch (e) {
console.log('Could not start or stop slicing', e)
}
}
Label {
id: statusLabel
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("default_bold")
text: statusText;
}
Rectangle {
id: progressBar
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
height: UM.Theme.getSize("progressbar").height
anchors.top: statusLabel.bottom
anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 4)
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
radius: UM.Theme.getSize("progressbar_radius").width
color: UM.Theme.getColor("progressbar_background")
Rectangle {
width: Math.max(parent.width * base.progress)
height: parent.height
color: UM.Theme.getColor("progressbar_control")
radius: UM.Theme.getSize("progressbar_radius").width
visible: (base.backendState != "undefined" && base.backendState == 2) ? true : false
}
}
// Shortcut for "save as/print/..."
Action {
shortcut: "Ctrl+P"
onTriggered:
{
// only work when the button is enabled
if (saveToButton.enabled) {
saveToButton.clicked();
}
// prepare button
if (prepareButton.enabled) {
sliceOrStopSlicing();
}
}
}
Item {
id: saveRow
width: {
// using childrenRect.width directly causes a binding loop, because setting the width affects the childrenRect
var children_width = UM.Theme.getSize("default_margin").width;
for (var index in children)
{
var child = children[index];
if(child.visible)
{
children_width += child.width + child.anchors.rightMargin;
}
}
return Math.min(children_width, base.width - UM.Theme.getSize("sidebar_margin").width);
}
height: saveToButton.height
anchors.bottom: parent.bottom
anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
anchors.right: parent.right
clip: true
Row {
id: additionalComponentsRow
anchors.top: parent.top
anchors.right: saveToButton.visible ? saveToButton.left : (prepareButton.visible ? prepareButton.left : parent.right)
anchors.rightMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width
}
Component.onCompleted: {
saveRow.addAdditionalComponents("saveButton")
}
Connections {
target: CuraApplication
onAdditionalComponentsChanged: saveRow.addAdditionalComponents("saveButton")
}
function addAdditionalComponents (areaId) {
if(areaId == "saveButton") {
for (var component in CuraApplication.additionalComponents["saveButton"]) {
CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow
}
}
}
Connections {
target: UM.Preferences
onPreferenceChanged:
{
var autoSlice = UM.Preferences.getValue("general/auto_slice");
prepareButton.autoSlice = autoSlice;
saveToButton.autoSlice = autoSlice;
}
}
// Prepare button, only shows if auto_slice is off
Button {
id: prepareButton
tooltip: [1, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@info:tooltip","Slice current printjob") : catalog.i18nc("@info:tooltip","Cancel slicing process")
// 1 = not started, 2 = Processing
enabled: base.backendState != "undefined" && ([1, 2].indexOf(base.backendState) != -1) && base.activity
visible: base.backendState != "undefined" && !autoSlice && ([1, 2, 4].indexOf(base.backendState) != -1) && base.activity
property bool autoSlice
height: UM.Theme.getSize("save_button_save_to_button").height
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
// 1 = not started, 4 = error, 5 = disabled
text: [1, 4, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@label:Printjob", "Prepare") : catalog.i18nc("@label:Printjob", "Cancel")
onClicked:
{
sliceOrStopSlicing();
}
style: ButtonStyle {
background: Rectangle
{
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_border");
else if(control.pressed)
return UM.Theme.getColor("action_button_active_border");
else if(control.hovered)
return UM.Theme.getColor("action_button_hovered_border");
else
return UM.Theme.getColor("action_button_border");
}
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled");
else if(control.pressed)
return UM.Theme.getColor("action_button_active");
else if(control.hovered)
return UM.Theme.getColor("action_button_hovered");
else
return UM.Theme.getColor("action_button");
}
Behavior on color { ColorAnimation { duration: 50; } }
implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2)
Label {
id: actualLabel
anchors.centerIn: parent
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_text");
else if(control.pressed)
return UM.Theme.getColor("action_button_active_text");
else if(control.hovered)
return UM.Theme.getColor("action_button_hovered_text");
else
return UM.Theme.getColor("action_button_text");
}
font: UM.Theme.getFont("action_button")
text: control.text;
}
}
label: Item { }
}
}
Button {
id: saveToButton
tooltip: UM.OutputDeviceManager.activeDeviceDescription;
// 3 = done, 5 = disabled
enabled: base.backendState != "undefined" && (base.backendState == 3 || base.backendState == 5) && base.activity == true
visible: base.backendState != "undefined" && autoSlice || ((base.backendState == 3 || base.backendState == 5) && base.activity == true)
property bool autoSlice
height: UM.Theme.getSize("save_button_save_to_button").height
anchors.top: parent.top
anchors.right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right
anchors.rightMargin: deviceSelectionMenu.visible ? -3 * UM.Theme.getSize("default_lining").width : UM.Theme.getSize("sidebar_margin").width
text: UM.OutputDeviceManager.activeDeviceShortDescription
onClicked:
{
forceActiveFocus();
UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName,
{ "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats });
}
style: ButtonStyle {
background: Rectangle
{
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_border");
else if(control.pressed)
return UM.Theme.getColor("print_button_ready_pressed_border");
else if(control.hovered)
return UM.Theme.getColor("print_button_ready_hovered_border");
else
return UM.Theme.getColor("print_button_ready_border");
}
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled");
else if(control.pressed)
return UM.Theme.getColor("print_button_ready_pressed");
else if(control.hovered)
return UM.Theme.getColor("print_button_ready_hovered");
else
return UM.Theme.getColor("print_button_ready");
}
Behavior on color { ColorAnimation { duration: 50; } }
implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2)
Label {
id: actualLabel
anchors.centerIn: parent
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_text");
else if(control.pressed)
return UM.Theme.getColor("print_button_ready_text");
else if(control.hovered)
return UM.Theme.getColor("print_button_ready_text");
else
return UM.Theme.getColor("print_button_ready_text");
}
font: UM.Theme.getFont("action_button")
text: control.text;
}
}
label: Item { }
}
}
Button {
id: deviceSelectionMenu
tooltip: catalog.i18nc("@info:tooltip","Select the active output device");
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
width: UM.Theme.getSize("save_button_save_to_button").height
height: UM.Theme.getSize("save_button_save_to_button").height
// 3 = Done, 5 = Disabled
enabled: base.backendState != "undefined" && (base.backendState == 3 || base.backendState == 5) && base.activity == true
visible: base.backendState != "undefined" && (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true
style: ButtonStyle {
background: Rectangle {
id: deviceSelectionIcon
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_border");
else if(control.pressed)
return UM.Theme.getColor("print_button_ready_pressed_border");
else if(control.hovered)
return UM.Theme.getColor("print_button_ready_hovered_border");
else
return UM.Theme.getColor("print_button_ready_border");
}
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled");
else if(control.pressed)
return UM.Theme.getColor("print_button_ready_pressed");
else if(control.hovered)
return UM.Theme.getColor("print_button_ready_hovered");
else
return UM.Theme.getColor("print_button_ready");
}
Behavior on color { ColorAnimation { duration: 50; } }
anchors.left: parent.left
anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2);
width: parent.height
height: parent.height
UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_text");
else if(control.pressed)
return UM.Theme.getColor("print_button_ready_text");
else if(control.hovered)
return UM.Theme.getColor("print_button_ready_text");
else
return UM.Theme.getColor("print_button_ready_text");
}
source: UM.Theme.getIcon("arrow_bottom");
}
}
label: Label{ }
}
menu: Menu {
id: devicesMenu;
Instantiator {
model: devicesModel;
MenuItem {
text: model.description
checkable: true;
checked: model.id == UM.OutputDeviceManager.activeDevice;
exclusiveGroup: devicesMenuGroup;
onTriggered: {
UM.OutputDeviceManager.setActiveDevice(model.id);
}
}
onObjectAdded: devicesMenu.insertItem(index, object)
onObjectRemoved: devicesMenu.removeItem(object)
}
ExclusiveGroup { id: devicesMenuGroup; }
}
}
UM.OutputDevicesModel { id: devicesModel; }
}
}

View file

@ -0,0 +1,20 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import UM 1.4 as UM
import Cura 1.1 as Cura
Cura.ActionButton
{
shadowEnabled: true
shadowColor: enabled ? UM.Theme.getColor("secondary_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow")
color: UM.Theme.getColor("secondary_button")
textColor: UM.Theme.getColor("secondary_button_text")
outlineColor: "transparent"
disabledColor: UM.Theme.getColor("action_button_disabled")
textDisabledColor: UM.Theme.getColor("action_button_disabled_text")
hoverColor: UM.Theme.getColor("secondary_button_hover")
}

View file

@ -12,48 +12,39 @@ Button
id: base
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
// To avoid overlaping with the scrollBars
anchors.rightMargin: 2 * UM.Theme.getSize("thin_margin").width
hoverEnabled: true
background: Rectangle
{
id: backgroundRectangle
implicitHeight: UM.Theme.getSize("section").height
color: {
if (base.color) {
return base.color;
} else if (!base.enabled) {
return UM.Theme.getColor("setting_category_disabled");
} else if (base.hovered && base.checkable && base.checked) {
return UM.Theme.getColor("setting_category_active_hover");
} else if (base.pressed || (base.checkable && base.checked)) {
return UM.Theme.getColor("setting_category_active");
} else if (base.hovered) {
return UM.Theme.getColor("setting_category_hover");
} else {
return UM.Theme.getColor("setting_category");
color:
{
if (base.color)
{
return base.color
}
else if (!base.enabled)
{
return UM.Theme.getColor("setting_category_disabled")
}
else if (base.hovered && base.checkable && base.checked)
{
return UM.Theme.getColor("setting_category_active_hover")
}
else if (base.pressed || (base.checkable && base.checked))
{
return UM.Theme.getColor("setting_category_active")
}
else if (base.hovered)
{
return UM.Theme.getColor("setting_category_hover")
}
return UM.Theme.getColor("setting_category")
}
Behavior on color { ColorAnimation { duration: 50; } }
Rectangle
{
id: backgroundLiningRectangle
height: UM.Theme.getSize("default_lining").height
width: parent.width
anchors.bottom: parent.bottom
color: {
if (!base.enabled) {
return UM.Theme.getColor("setting_category_disabled_border");
} else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) {
return UM.Theme.getColor("setting_category_active_hover_border");
} else if (base.pressed || (base.checkable && base.checked)) {
return UM.Theme.getColor("setting_category_active_border");
} else if (base.hovered || base.activeFocus) {
return UM.Theme.getColor("setting_category_hover_border");
} else {
return UM.Theme.getColor("setting_category_border");
}
}
}
}
signal showTooltip(string text)
@ -65,18 +56,19 @@ Button
property var focusItem: base
contentItem: Item {
contentItem: Item
{
anchors.fill: parent
anchors.left: parent.left
Label {
Label
{
id: settingNameLabel
anchors
{
left: parent.left
leftMargin: 2 * UM.Theme.getSize("default_margin").width + UM.Theme.getSize("section_icon").width
right: parent.right;
verticalCenter: parent.verticalCenter;
right: parent.right
verticalCenter: parent.verticalCenter
}
text: definition.label
textFormat: Text.PlainText
@ -84,21 +76,27 @@ Button
font: UM.Theme.getFont("setting_category")
color:
{
if (!base.enabled) {
return UM.Theme.getColor("setting_category_disabled_text");
} else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) {
return UM.Theme.getColor("setting_category_active_hover_text");
} else if (base.pressed || (base.checkable && base.checked)) {
return UM.Theme.getColor("setting_category_active_text");
} else if (base.hovered || base.activeFocus) {
return UM.Theme.getColor("setting_category_hover_text");
} else {
return UM.Theme.getColor("setting_category_text");
if (!base.enabled)
{
return UM.Theme.getColor("setting_category_disabled_text")
} else if ((base.hovered || base.activeFocus) && base.checkable && base.checked)
{
return UM.Theme.getColor("setting_category_active_hover_text")
} else if (base.pressed || (base.checkable && base.checked))
{
return UM.Theme.getColor("setting_category_active_text")
} else if (base.hovered || base.activeFocus)
{
return UM.Theme.getColor("setting_category_hover_text")
} else
{
return UM.Theme.getColor("setting_category_text")
}
}
fontSizeMode: Text.HorizontalFit
minimumPointSize: 8
}
UM.RecolorImage
{
id: category_arrow
@ -107,21 +105,26 @@ Button
anchors.rightMargin: UM.Theme.getSize("default_margin").width
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: width
color:
{
if (!base.enabled) {
return UM.Theme.getColor("setting_category_disabled_text");
} else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) {
return UM.Theme.getColor("setting_category_active_hover_text");
} else if (base.pressed || (base.checkable && base.checked)) {
return UM.Theme.getColor("setting_category_active_text");
} else if (base.hovered || base.activeFocus) {
return UM.Theme.getColor("setting_category_hover_text");
} else {
return UM.Theme.getColor("setting_category_text");
if (!base.enabled)
{
return UM.Theme.getColor("setting_category_disabled_text")
}
else if ((base.hovered || base.activeFocus) && base.checkable && base.checked)
{
return UM.Theme.getColor("setting_category_active_hover_text")
}
else if (base.pressed || (base.checkable && base.checked))
{
return UM.Theme.getColor("setting_category_active_text")
}
else if (base.hovered || base.activeFocus)
{
return UM.Theme.getColor("setting_category_hover_text")
}
return UM.Theme.getColor("setting_category_text")
}
source: base.checked ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
}
@ -132,24 +135,30 @@ Button
id: icon
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.leftMargin: UM.Theme.getSize("thin_margin").width
color:
{
if (!base.enabled) {
return UM.Theme.getColor("setting_category_disabled_text");
} else if((base.hovered || base.activeFocus) && base.checkable && base.checked) {
return UM.Theme.getColor("setting_category_active_hover_text");
} else if(base.pressed || (base.checkable && base.checked)) {
return UM.Theme.getColor("setting_category_active_text");
} else if(base.hovered || base.activeFocus) {
return UM.Theme.getColor("setting_category_hover_text");
} else {
return UM.Theme.getColor("setting_category_text");
if (!base.enabled)
{
return UM.Theme.getColor("setting_category_disabled_text")
}
else if((base.hovered || base.activeFocus) && base.checkable && base.checked)
{
return UM.Theme.getColor("setting_category_active_hover_text")
}
else if(base.pressed || (base.checkable && base.checked))
{
return UM.Theme.getColor("setting_category_active_text")
}
else if(base.hovered || base.activeFocus)
{
return UM.Theme.getColor("setting_category_hover_text")
}
return UM.Theme.getColor("setting_category_text")
}
source: UM.Theme.getIcon(definition.icon)
width: UM.Theme.getSize("section_icon").width;
height: UM.Theme.getSize("section_icon").height;
width: UM.Theme.getSize("section_icon").width
height: UM.Theme.getSize("section_icon").height
sourceSize.width: width + 15 * screenScaleFactor
sourceSize.height: width + 15 * screenScaleFactor
}
@ -159,31 +168,28 @@ Button
onClicked:
{
if (definition.expanded) {
settingDefinitionsModel.collapse(definition.key);
} else {
settingDefinitionsModel.expandRecursive(definition.key);
if (definition.expanded)
{
settingDefinitionsModel.collapse(definition.key)
}
else
{
settingDefinitionsModel.expandRecursive(definition.key)
}
//Set focus so that tab navigation continues from this point on.
//NB: This must be set AFTER collapsing/expanding the category so that the scroll position is correct.
forceActiveFocus();
forceActiveFocus()
}
onActiveFocusChanged:
{
if(activeFocus)
if (activeFocus)
{
base.focusReceived();
base.focusReceived()
}
}
Keys.onTabPressed:
{
base.setActiveFocusToNextSetting(true)
}
Keys.onBacktabPressed:
{
base.setActiveFocusToNextSetting(false)
}
Keys.onTabPressed: base.setActiveFocusToNextSetting(true)
Keys.onBacktabPressed: base.setActiveFocusToNextSetting(false)
UM.SimpleButton
{
@ -193,9 +199,10 @@ Button
height: Math.round(base.height * 0.6)
width: Math.round(base.height * 0.6)
anchors {
anchors
{
right: inheritButton.visible ? inheritButton.left : parent.right
// use 1.9 as the factor because there is a 0.1 difference between the settings and inheritance warning icons
// Use 1.9 as the factor because there is a 0.1 difference between the settings and inheritance warning icons
rightMargin: inheritButton.visible ? Math.round(UM.Theme.getSize("default_margin").width / 2) : category_arrow.width + Math.round(UM.Theme.getSize("default_margin").width * 1.9)
verticalCenter: parent.verticalCenter
}
@ -204,9 +211,7 @@ Button
hoverColor: UM.Theme.getColor("setting_control_button_hover")
iconSource: UM.Theme.getIcon("settings")
onClicked: {
Cura.Actions.configureSettingVisibility.trigger(definition)
}
onClicked: Cura.Actions.configureSettingVisibility.trigger(definition)
}
UM.SimpleButton
@ -239,24 +244,18 @@ Button
onClicked:
{
settingDefinitionsModel.expandRecursive(definition.key);
base.checked = true;
base.showAllHiddenInheritedSettings(definition.key);
settingDefinitionsModel.expandRecursive(definition.key)
base.checked = true
base.showAllHiddenInheritedSettings(definition.key)
}
color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button_hover")
iconSource: UM.Theme.getIcon("notice")
onEntered:
{
base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible."))
}
onEntered: base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible."))
onExited:
{
base.hideTooltip();
}
onExited: base.hideTooltip()
UM.I18nCatalog { id: catalog; name: "cura" }
}

View file

@ -28,37 +28,40 @@ SettingItem
// 3: material -> user changed material in materials page
// 4: variant
// 5: machine
var value;
if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) {
var value
if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 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).
value = base.resolve;
} else {
value = propertyProvider.properties.value;
value = base.resolve
}
else
{
value = propertyProvider.properties.value
}
switch(value)
{
case "True":
return true;
return true
case "False":
return false;
return false
default:
return value;
return value
}
}
Keys.onSpacePressed:
{
forceActiveFocus();
propertyProvider.setPropertyValue("value", !checked);
forceActiveFocus()
propertyProvider.setPropertyValue("value", !checked)
}
onClicked:
{
forceActiveFocus();
propertyProvider.setPropertyValue("value", !checked);
forceActiveFocus()
propertyProvider.setPropertyValue("value", !checked)
}
Keys.onTabPressed:
@ -72,9 +75,9 @@ SettingItem
onActiveFocusChanged:
{
if(activeFocus)
if (activeFocus)
{
base.focusReceived();
base.focusReceived()
}
}
@ -90,37 +93,38 @@ SettingItem
color:
{
if(!enabled)
if (!enabled)
{
return UM.Theme.getColor("setting_control_disabled")
}
if(control.containsMouse || control.activeFocus)
if (control.containsMouse || control.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)
if (!enabled)
{
return UM.Theme.getColor("setting_control_disabled_border")
}
if(control.containsMouse || control.activeFocus)
if (control.containsMouse || control.activeFocus)
{
return UM.Theme.getColor("setting_control_border_highlight")
}
return UM.Theme.getColor("setting_control_border")
}
UM.RecolorImage {
UM.RecolorImage
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: Math.round(parent.width / 2.5)
height: Math.round(parent.height / 2.5)
sourceSize.width: width
sourceSize.height: width
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text");
source: UM.Theme.getIcon("check")

View file

@ -35,6 +35,7 @@ SettingItem
return UM.Theme.getColor("setting_control")
}
radius: UM.Theme.getSize("setting_control_radius").width
border.width: UM.Theme.getSize("default_lining").width
border.color:
{

View file

@ -19,8 +19,9 @@ SettingItem
model: Cura.ExtrudersModel
{
onModelChanged: {
control.color = getItem(control.currentIndex).color;
onModelChanged:
{
control.color = getItem(control.currentIndex).color
}
}
@ -113,14 +114,15 @@ SettingItem
{
if (!enabled)
{
return UM.Theme.getColor("setting_control_disabled");
return UM.Theme.getColor("setting_control_disabled")
}
if (control.hovered || base.activeFocus)
{
return UM.Theme.getColor("setting_control_highlight");
return UM.Theme.getColor("setting_control_highlight")
}
return UM.Theme.getColor("setting_control");
return UM.Theme.getColor("setting_control")
}
radius: UM.Theme.getSize("setting_control_radius").width
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
@ -153,20 +155,18 @@ SettingItem
elide: Text.ElideLeft
verticalAlignment: Text.AlignVCenter
background: Rectangle
background: UM.RecolorImage
{
id: swatch
height: Math.round(UM.Theme.getSize("setting_control").height / 2)
height: Math.round(parent.height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
radius: Math.round(width / 2)
anchors.rightMargin: UM.Theme.getSize("thin_margin").width
sourceSize.width: width
sourceSize.height: height
source: UM.Theme.getIcon("extruder_button")
color: control.color
}
}
@ -219,20 +219,18 @@ SettingItem
verticalAlignment: Text.AlignVCenter
rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
background: Rectangle
background: UM.RecolorImage
{
id: swatch
height: Math.round(UM.Theme.getSize("setting_control").height / 2)
height: Math.round(parent.height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
radius: Math.round(width / 2)
anchors.rightMargin: UM.Theme.getSize("thin_margin").width
sourceSize.width: width
sourceSize.height: height
source: UM.Theme.getIcon("extruder_button")
color: control.model.getItem(index).color
}
}

View file

@ -10,10 +10,15 @@ import Cura 1.0 as Cura
import "."
Item {
id: base;
Item
{
id: base
height: UM.Theme.getSize("section").height
anchors.left: parent.left
anchors.right: parent.right
// To avoid overlaping with the scrollBars
anchors.rightMargin: 2 * UM.Theme.getSize("thin_margin").width
property alias contents: controlContainer.children
property alias hovered: mouse.containsMouse
@ -43,25 +48,25 @@ Item {
var affected_by = settingDefinitionsModel.getRequires(definition.key, "value")
var affected_by_list = ""
for(var i in affected_by)
for (var i in affected_by)
{
affected_by_list += "<li>%1</li>\n".arg(affected_by[i].label)
}
var affects_list = ""
for(var i in affects)
for (var i in affects)
{
affects_list += "<li>%1</li>\n".arg(affects[i].label)
}
var tooltip = "<b>%1</b>\n<p>%2</p>".arg(definition.label).arg(definition.description)
if(affects_list != "")
if (affects_list != "")
{
tooltip += "<br/><b>%1</b>\n<ul>\n%2</ul>".arg(catalog.i18nc("@label Header for list of settings.", "Affects")).arg(affects_list)
}
if(affected_by_list != "")
if (affected_by_list != "")
{
tooltip += "<br/><b>%1</b>\n<ul>\n%2</ul>".arg(catalog.i18nc("@label Header for list of settings.", "Affected By")).arg(affected_by_list)
}
@ -71,53 +76,57 @@ Item {
MouseArea
{
id: mouse;
id: mouse
anchors.fill: parent;
anchors.fill: parent
acceptedButtons: Qt.RightButton;
acceptedButtons: Qt.RightButton
hoverEnabled: true;
onClicked: base.contextMenuRequested();
onClicked: base.contextMenuRequested()
onEntered: {
hoverTimer.start();
onEntered:
{
hoverTimer.start()
}
onExited: {
if(controlContainer.item && controlContainer.item.hovered) {
return;
onExited:
{
if (controlContainer.item && controlContainer.item.hovered)
{
return
}
hoverTimer.stop();
base.hideTooltip();
hoverTimer.stop()
base.hideTooltip()
}
Timer {
id: hoverTimer;
interval: 500;
repeat: false;
Timer
{
id: hoverTimer
interval: 500
repeat: false
onTriggered:
{
base.showTooltip(base.tooltipText);
base.showTooltip(base.tooltipText)
}
}
Label
{
id: label;
id: label
anchors.left: parent.left;
anchors.leftMargin: doDepthIndentation ? Math.round((UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0
anchors.right: settingControls.left;
anchors.left: parent.left
anchors.leftMargin: doDepthIndentation ? Math.round(UM.Theme.getSize("thin_margin").width + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0
anchors.right: settingControls.left
anchors.verticalCenter: parent.verticalCenter
text: definition.label
elide: Text.ElideMiddle;
elide: Text.ElideMiddle
renderType: Text.NativeRendering
textFormat: Text.PlainText
color: UM.Theme.getColor("setting_control_text");
color: UM.Theme.getColor("setting_control_text")
opacity: (definition.visible) ? 1 : 0.5
// emphasize the setting if it has a value in the user or quality profile
font: base.doQualityUserSettingEmphasis && base.stackLevel != undefined && base.stackLevel <= 1 ? UM.Theme.getFont("default_italic") : UM.Theme.getFont("default")
@ -128,11 +137,12 @@ Item {
id: settingControls
height: Math.round(parent.height / 2)
spacing: Math.round(UM.Theme.getSize("sidebar_margin").height / 2)
spacing: Math.round(UM.Theme.getSize("thick_margin").height / 2)
anchors {
anchors
{
right: controlContainer.left
rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2)
rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2)
verticalCenter: parent.verticalCenter
}
@ -150,112 +160,123 @@ Item {
iconSource: UM.Theme.getIcon("link")
onEntered: {
hoverTimer.stop();
var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders.");
if ((resolve != "None") && (stackLevel != 0)) {
onEntered:
{
hoverTimer.stop()
var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders.")
if ((resolve != "None") && (stackLevel != 0))
{
// We come here if a setting has a resolve and the setting is not manually edited.
tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + Cura.ExtruderManager.getInstanceExtruderValues(definition.key) + "].";
tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + Cura.ExtruderManager.getInstanceExtruderValues(definition.key) + "]."
}
base.showTooltip(tooltipText);
base.showTooltip(tooltipText)
}
onExited: base.showTooltip(base.tooltipText);
onExited: base.showTooltip(base.tooltipText)
}
UM.SimpleButton
{
id: revertButton;
id: revertButton
visible: base.stackLevel == 0 && base.showRevertButton
height: parent.height;
width: height;
height: parent.height
width: height
color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button_hover")
iconSource: UM.Theme.getIcon("reset")
onClicked: {
onClicked:
{
revertButton.focus = true
if (externalResetHandler) {
if (externalResetHandler)
{
externalResetHandler(propertyProvider.key)
} else {
}
else
{
Cura.MachineManager.clearUserSettingAllCurrentStacks(propertyProvider.key)
}
}
onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) }
onExited: base.showTooltip(base.tooltipText);
onEntered:
{
hoverTimer.stop()
base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile."))
}
onExited: base.showTooltip(base.tooltipText)
}
UM.SimpleButton
{
// This button shows when the setting has an inherited function, but is overriden by profile.
id: inheritButton;
id: inheritButton
// Inherit button needs to be visible if;
// - User made changes that override any loaded settings
// - This setting item uses inherit button at all
// - The type of the value of any deeper container is an "object" (eg; is a function)
visible:
{
if(!base.showInheritButton)
if (!base.showInheritButton)
{
return false;
return false
}
if(!propertyProvider.properties.enabled)
if (!propertyProvider.properties.enabled)
{
// Note: This is not strictly necessary since a disabled setting is hidden anyway.
// But this will cause the binding to be re-evaluated when the enabled property changes.
return false;
return false
}
// There are no settings with any warning.
if(Cura.SettingInheritanceManager.settingsWithInheritanceWarning.length == 0)
if (Cura.SettingInheritanceManager.settingsWithInheritanceWarning.length == 0)
{
return false;
return false
}
// This setting has a resolve value, so an inheritance warning doesn't do anything.
if(resolve != "None")
if (resolve != "None")
{
return false
}
// If the setting does not have a limit_to_extruder property (or is -1), use the active stack.
if(globalPropertyProvider.properties.limit_to_extruder == null || String(globalPropertyProvider.properties.limit_to_extruder) == "-1")
if (globalPropertyProvider.properties.limit_to_extruder == null || String(globalPropertyProvider.properties.limit_to_extruder) == "-1")
{
return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0;
return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0
}
// Setting does have a limit_to_extruder property, so use that one instead.
if (definition.key === undefined) {
// Observed when loading workspace, probably when SettingItems are removed.
return false;
return false
}
return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, String(globalPropertyProvider.properties.limit_to_extruder)).indexOf(definition.key) >= 0;
return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, String(globalPropertyProvider.properties.limit_to_extruder)).indexOf(definition.key) >= 0
}
height: parent.height;
width: height;
height: parent.height
width: height
onClicked: {
focus = true;
onClicked:
{
focus = true
// Get the most shallow function value (eg not a number) that we can find.
var last_entry = propertyProvider.stackLevels[propertyProvider.stackLevels.length - 1]
for (var i = 1; i < base.stackLevels.length; i++)
{
var has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object";
var has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object"
if(has_setting_function)
{
last_entry = propertyProvider.stackLevels[i]
break;
break
}
}
if((last_entry == 4 || last_entry == 11) && base.stackLevel == 0 && base.stackLevels.length == 2)
if ((last_entry == 4 || last_entry == 11) && base.stackLevel == 0 && base.stackLevels.length == 2)
{
// Special case of the inherit reset. If only the definition (4th or 11th) container) and the first
// entry (user container) are set, we can simply remove the container.
@ -276,23 +297,22 @@ Item {
color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button_hover")
iconSource: UM.Theme.getIcon("formula");
iconSource: UM.Theme.getIcon("formula")
onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) }
onExited: base.showTooltip(base.tooltipText);
onExited: base.showTooltip(base.tooltipText)
}
}
Item
{
id: controlContainer;
id: controlContainer
enabled: propertyProvider.isValueUsed
anchors.right: parent.right;
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
anchors.verticalCenter: parent.verticalCenter;
width: UM.Theme.getSize("setting_control").width;
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("setting_control").width
height: UM.Theme.getSize("setting_control").height
}
}

View file

@ -1,5 +1,5 @@
// Copyright (c) 2016 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
@ -31,12 +31,15 @@ SettingItem
{
forceActiveFocus();
propertyProvider.setPropertyValue("value", model.getItem(index).index);
} else
}
else
{
if (propertyProvider.properties.value == -1)
{
control.currentIndex = model.rowCount() - 1; // we know the last item is "Not overriden"
} else {
control.currentIndex = model.count - 1; // we know the last item is "Not overriden"
}
else
{
control.currentIndex = propertyProvider.properties.value; // revert to the old value
}
}
@ -116,6 +119,7 @@ SettingItem
}
return UM.Theme.getColor("setting_control");
}
radius: UM.Theme.getSize("setting_control_radius").width
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
@ -148,20 +152,18 @@ SettingItem
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
background: Rectangle
background: UM.RecolorImage
{
id: swatch
height: Math.round(UM.Theme.getSize("setting_control").height / 2)
height: Math.round(parent.height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
radius: Math.round(width / 2)
anchors.rightMargin: UM.Theme.getSize("thin_margin").width
sourceSize.width: width
sourceSize.height: height
source: UM.Theme.getIcon("extruder_button")
color: control.color
}
}
@ -215,20 +217,18 @@ SettingItem
verticalAlignment: Text.AlignVCenter
rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
background: Rectangle
background: UM.RecolorImage
{
id: swatch
height: Math.round(UM.Theme.getSize("setting_control").height / 2)
height: Math.round(parent.height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
radius: Math.round(width / 2)
anchors.rightMargin: UM.Theme.getSize("thin_margin").width
sourceSize.width: width
sourceSize.height: height
source: UM.Theme.getIcon("extruder_button")
color: control.model.getItem(index).color
}
}

View file

@ -32,6 +32,7 @@ SettingItem
anchors.fill: parent
radius: UM.Theme.getSize("setting_control_radius").width
border.width: Math.round(UM.Theme.getSize("default_lining").width)
border.color:
{
@ -81,10 +82,10 @@ SettingItem
Rectangle
{
anchors.fill: parent;
anchors.margins: Math.round(UM.Theme.getSize("default_lining").width);
anchors.fill: parent
anchors.margins: Math.round(UM.Theme.getSize("default_lining").width)
color: UM.Theme.getColor("setting_control_highlight")
opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35;
opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35
}
Label
@ -145,11 +146,11 @@ SettingItem
}
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default");
font: UM.Theme.getFont("default")
selectByMouse: true;
selectByMouse: true
maximumLength: (definition.type == "str" || definition.type == "[int]") ? -1 : 10;
maximumLength: (definition.type == "str" || definition.type == "[int]") ? -1 : 10
clip: true; //Hide any text that exceeds the width of the text box.
validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,3}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
@ -158,7 +159,8 @@ SettingItem
{
target: input
property: "text"
value: {
value:
{
// Stacklevels
// 0: user -> unsaved change
// 1: quality changes -> saved change
@ -167,13 +169,15 @@ SettingItem
// 4: variant
// 5: machine_changes
// 6: machine
if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 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;
} else {
return propertyProvider.properties.value;
return base.resolve
}
else {
return propertyProvider.properties.value
}
}
when: !input.activeFocus
@ -182,16 +186,17 @@ SettingItem
MouseArea
{
id: mouseArea
anchors.fill: parent;
anchors.fill: parent
cursorShape: Qt.IBeamCursor
onPressed: {
if(!input.activeFocus) {
base.focusGainedByClick = true;
input.forceActiveFocus();
if (!input.activeFocus)
{
base.focusGainedByClick = true
input.forceActiveFocus()
}
mouse.accepted = false;
mouse.accepted = false
}
}
}

View file

@ -1,5 +1,5 @@
// Copyright (c) 2017 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.1
@ -13,163 +13,28 @@ import "../Menus"
Item
{
id: base;
id: settingsView
property QtObject settingVisibilityPresetsModel: CuraApplication.getSettingVisibilityPresetsModel()
property Action configureSettings
property bool findingSettings
signal showTooltip(Item item, point location, string text)
signal hideTooltip()
Item
{
id: globalProfileRow
height: UM.Theme.getSize("sidebar_setup").height
visible: !sidebar.hideSettings
anchors
{
top: parent.top
left: parent.left
leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
right: parent.right
rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
}
Label
{
id: globalProfileLabel
text: catalog.i18nc("@label","Profile:")
textFormat: Text.PlainText
width: Math.round(parent.width * 0.45 - UM.Theme.getSize("sidebar_margin").width - 2)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignVCenter
anchors.top: parent.top
anchors.bottom: parent.bottom
}
ToolButton
{
id: globalProfileSelection
text: generateActiveQualityText()
enabled: !header.currentExtruderVisible || header.currentExtruderIndex > -1
width: Math.round(parent.width * 0.55)
height: UM.Theme.getSize("setting_control").height
anchors.left: globalProfileLabel.right
anchors.right: parent.right
tooltip: Cura.MachineManager.activeQualityOrQualityChangesName
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true
menu: ProfileMenu { }
function generateActiveQualityText ()
{
var result = Cura.MachineManager.activeQualityOrQualityChangesName
if (Cura.MachineManager.isActiveQualityExperimental)
{
result += " (Experimental)"
}
if (Cura.MachineManager.isActiveQualitySupported)
{
if (Cura.MachineManager.activeQualityLayerHeight > 0)
{
result += " <font color=\"" + UM.Theme.getColor("text_detail") + "\">"
result += " - "
result += Cura.MachineManager.activeQualityLayerHeight + "mm"
result += "</font>"
}
}
return result
}
UM.SimpleButton
{
id: customisedSettings
visible: Cura.MachineManager.hasUserSettings
height: Math.round(parent.height * 0.6)
width: Math.round(parent.height * 0.6)
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("sidebar_margin").width)
color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button");
iconSource: UM.Theme.getIcon("star");
onClicked:
{
forceActiveFocus();
Cura.Actions.manageProfiles.trigger()
}
onEntered:
{
var content = catalog.i18nc("@tooltip","Some setting/override values are different from the values stored in the profile.\n\nClick to open the profile manager.")
base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), content)
}
onExited: base.hideTooltip()
}
}
}
ToolButton
{
id: settingVisibilityMenu
width: height
height: UM.Theme.getSize("setting_control").height
anchors
{
top: globalProfileRow.bottom
topMargin: UM.Theme.getSize("sidebar_margin").height
right: parent.right
rightMargin: UM.Theme.getSize("sidebar_margin").width
}
style: ButtonStyle
{
background: Item {
UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: width
color: control.enabled ? UM.Theme.getColor("setting_category_text") : UM.Theme.getColor("setting_category_disabled_text")
source: UM.Theme.getIcon("menu")
}
}
label: Label{}
}
menu: SettingVisibilityPresetsMenu
{
onShowAllSettings:
{
definitionsModel.setAllVisible(true);
filter.updateDefinitionModel();
}
}
}
Rectangle
{
id: filterContainer
visible: true
radius: UM.Theme.getSize("setting_control_radius").width
border.width: Math.round(UM.Theme.getSize("default_lining").width)
border.color:
{
if(hoverMouseArea.containsMouse || clearFilterButton.containsMouse)
if (hoverMouseArea.containsMouse || clearFilterButton.containsMouse)
{
return UM.Theme.getColor("setting_control_border_highlight");
return UM.Theme.getColor("setting_control_border_highlight")
}
else
{
return UM.Theme.getColor("setting_control_border");
return UM.Theme.getColor("setting_control_border")
}
}
@ -177,16 +42,12 @@ Item
anchors
{
top: globalProfileRow.bottom
topMargin: UM.Theme.getSize("sidebar_margin").height
top: parent.top
left: parent.left
leftMargin: UM.Theme.getSize("sidebar_margin").width
right: settingVisibilityMenu.left
rightMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2)
rightMargin: UM.Theme.getSize("default_margin").width
}
height: visible ? UM.Theme.getSize("setting_control").height : 0
Behavior on height { NumberAnimation { duration: 100 } }
height: UM.Theme.getSize("print_setup_big_item").height
Timer
{
id: settingsSearchTimer
@ -198,19 +59,19 @@ Item
TextField
{
id: filter;
id: filter
height: parent.height
anchors.left: parent.left
anchors.right: clearFilterButton.left
anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width)
placeholderText: catalog.i18nc("@label:textbox", "Search...")
placeholderText: "<img align='middle' src='"+ UM.Theme.getIcon("search") +"'>" + "<div vertical-align=bottom>" + catalog.i18nc("@label:textbox", "search settings")
style: TextFieldStyle
{
textColor: UM.Theme.getColor("setting_control_text");
placeholderTextColor: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default");
textColor: UM.Theme.getColor("setting_control_text")
placeholderTextColor: UM.Theme.getColor("setting_filter_field")
font: UM.Theme.getFont("default_italic")
background: Item {}
}
@ -224,38 +85,38 @@ Item
onEditingFinished:
{
definitionsModel.filter = {"i18n_label": "*" + text};
findingSettings = (text.length > 0);
if(findingSettings != lastFindingSettings)
definitionsModel.filter = {"i18n_label": "*" + text}
findingSettings = (text.length > 0)
if (findingSettings != lastFindingSettings)
{
updateDefinitionModel();
lastFindingSettings = findingSettings;
updateDefinitionModel()
lastFindingSettings = findingSettings
}
}
Keys.onEscapePressed:
{
filter.text = "";
filter.text = ""
}
function updateDefinitionModel()
{
if(findingSettings)
if (findingSettings)
{
expandedCategories = definitionsModel.expanded.slice();
definitionsModel.expanded = [""]; // keep categories closed while to prevent render while making settings visible one by one
definitionsModel.showAncestors = true;
definitionsModel.showAll = true;
definitionsModel.expanded = ["*"];
expandedCategories = definitionsModel.expanded.slice()
definitionsModel.expanded = [""] // keep categories closed while to prevent render while making settings visible one by one
definitionsModel.showAncestors = true
definitionsModel.showAll = true
definitionsModel.expanded = ["*"]
}
else
{
if(expandedCategories)
if (expandedCategories)
{
definitionsModel.expanded = expandedCategories;
definitionsModel.expanded = expandedCategories
}
definitionsModel.showAncestors = false;
definitionsModel.showAll = false;
definitionsModel.showAncestors = false
definitionsModel.showAll = false
}
}
}
@ -287,41 +148,93 @@ Item
onClicked:
{
filter.text = "";
filter.forceActiveFocus();
filter.text = ""
filter.forceActiveFocus()
}
}
}
ToolButton
{
id: settingVisibilityMenu
anchors
{
top: filterContainer.top
bottom: filterContainer.bottom
right: parent.right
rightMargin: UM.Theme.getSize("wide_margin").width
}
style: ButtonStyle
{
background: Item
{
UM.RecolorImage
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: control.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text")
source: UM.Theme.getIcon("menu")
}
}
label: Label {}
}
menu: SettingVisibilityPresetsMenu
{
onShowAllSettings:
{
definitionsModel.setAllVisible(true)
filter.updateDefinitionModel()
}
}
}
// Mouse area that gathers the scroll events to not propagate it to the main view.
MouseArea
{
anchors.fill: scrollView
acceptedButtons: Qt.AllButtons
onWheel: wheel.accepted = true
}
ScrollView
{
anchors.top: filterContainer.bottom;
anchors.bottom: parent.bottom;
anchors.right: parent.right;
anchors.left: parent.left;
anchors.topMargin: filterContainer.visible ? UM.Theme.getSize("sidebar_margin").height : 0
Behavior on anchors.topMargin { NumberAnimation { duration: 100 } }
id: scrollView
anchors
{
top: filterContainer.bottom
topMargin: UM.Theme.getSize("default_margin").height
bottom: parent.bottom
right: parent.right
left: parent.left
}
style: UM.Theme.styles.scrollview;
flickableItem.flickableDirection: Flickable.VerticalFlick;
__wheelAreaScrollSpeed: 75; // Scroll three lines in one scroll event
style: UM.Theme.styles.scrollview
flickableItem.flickableDirection: Flickable.VerticalFlick
__wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event
ListView
{
id: contents
spacing: Math.round(UM.Theme.getSize("default_lining").height);
cacheBuffer: 1000000; // Set a large cache to effectively just cache every list item.
spacing: UM.Theme.getSize("default_lining").height
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
model: UM.SettingDefinitionsModel
{
id: definitionsModel;
id: definitionsModel
containerId: Cura.MachineManager.activeDefinitionId
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order", "cutting_mesh", "support_mesh", "anti_overhang_mesh"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
expanded: CuraApplication.expandedCategories
onExpandedChanged:
{
if(!findingSettings)
if (!findingSettings)
{
// Do not change expandedCategories preference while filtering settings
// because all categories are expanded while filtering
@ -337,7 +250,7 @@ Item
{
id: delegate
width: Math.round(UM.Theme.getSize("sidebar").width);
width: scrollView.width
height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing
Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled == "True" ? 1 : 0
@ -407,17 +320,17 @@ Item
// machine gets changed.
var activeMachineId = Cura.MachineManager.activeMachineId;
if(!model.settable_per_extruder)
if (!model.settable_per_extruder)
{
//Not settable per extruder or there only is global, so we must pick global.
return activeMachineId;
}
if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
if (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
{
//We have limit_to_extruder, so pick that stack.
return Cura.ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)];
}
if(Cura.ExtruderManager.activeExtruderStackId)
if (Cura.ExtruderManager.activeExtruderStackId)
{
//We're on an extruder tab. Pick the current extruder.
return Cura.ExtruderManager.activeExtruderStackId;
@ -458,7 +371,7 @@ Item
contextMenu.provider = provider
contextMenu.popup();
}
onShowTooltip: base.showTooltip(delegate, { x: -UM.Theme.getSize("default_arrow").width, y: Math.round(delegate.height / 2) }, text)
onShowTooltip: base.showTooltip(delegate, Qt.point(- settingsView.x - UM.Theme.getSize("default_margin").width, 0), text)
onHideTooltip: base.hideTooltip()
onShowAllHiddenInheritedSettings:
{
@ -479,14 +392,14 @@ Item
}
onSetActiveFocusToNextSetting:
{
if(forward == undefined || forward)
if (forward == undefined || forward)
{
contents.currentIndex = contents.indexWithFocus + 1;
while(contents.currentItem && contents.currentItem.height <= 0)
{
contents.currentIndex++;
}
if(contents.currentItem)
if (contents.currentItem)
{
contents.currentItem.item.focusItem.forceActiveFocus();
}
@ -498,7 +411,7 @@ Item
{
contents.currentIndex--;
}
if(contents.currentItem)
if (contents.currentItem)
{
contents.currentItem.item.focusItem.forceActiveFocus();
}

View file

@ -1,10 +0,0 @@
// Copyright (c) 2015 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.0
import "Settings"
SettingView {
}

View file

@ -1,43 +0,0 @@
// Copyright (c) 2016 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import UM 1.2 as UM
import Cura 1.0 as Cura
StackView
{
id: sidebarContents
delegate: StackViewDelegate
{
function transitionFinished(properties)
{
properties.exitItem.opacity = 1
}
pushTransition: StackViewTransition
{
PropertyAnimation
{
target: enterItem
property: "opacity"
from: 0
to: 1
duration: 100
}
PropertyAnimation
{
target: exitItem
property: "opacity"
from: 1
to: 0
duration: 100
}
}
}
}

View file

@ -1,617 +0,0 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import UM 1.2 as UM
import Cura 1.0 as Cura
import "Menus"
Column
{
id: base;
property int currentExtruderIndex: Cura.ExtruderManager.activeExtruderIndex;
property bool currentExtruderVisible: extrudersList.visible;
property bool printerConnected: Cura.MachineManager.printerConnected
property bool hasManyPrinterTypes:
{
if (printerConnected)
{
if (Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount != null)
{
return Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount.length > 1;
}
}
return false;
}
property bool buildplateCompatibilityError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable
property bool buildplateCompatibilityWarning: Cura.MachineManager.variantBuildplateUsable
spacing: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.9)
signal showTooltip(Item item, point location, string text)
signal hideTooltip()
Item
{
id: initialSeparator
anchors
{
left: parent.left
right: parent.right
}
visible: printerTypeSelectionRow.visible || buildplateRow.visible || extruderSelectionRow.visible
height: UM.Theme.getSize("default_lining").height
width: height
}
// Printer Type Row
Item
{
id: printerTypeSelectionRow
height: UM.Theme.getSize("sidebar_setup").height
visible: printerConnected && hasManyPrinterTypes && !sidebar.hideSettings
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("sidebar_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("sidebar_margin").width
}
Label
{
id: configurationLabel
text: catalog.i18nc("@label", "Printer type");
width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width)
height: parent.height
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
}
ToolButton
{
id: printerTypeSelection
text: Cura.MachineManager.activeMachineDefinitionName
tooltip: Cura.MachineManager.activeMachineDefinitionName
height: UM.Theme.getSize("setting_control").height
width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width
anchors.right: parent.right
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true;
menu: PrinterTypeMenu { }
}
}
Rectangle {
id: headerSeparator
width: parent.width
visible: printerTypeSelectionRow.visible
height: visible ? UM.Theme.getSize("sidebar_lining").height : 0
color: UM.Theme.getColor("sidebar_lining")
}
// Extruder Row
Item
{
id: extruderSelectionRow
width: parent.width
height: Math.round(UM.Theme.getSize("sidebar_tabs").height * 2 / 3)
visible: machineExtruderCount.properties.value > 1
anchors
{
left: parent.left
leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7)
right: parent.right
rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7)
topMargin: UM.Theme.getSize("sidebar_margin").height
}
ListView
{
id: extrudersList
property var index: 0
height: UM.Theme.getSize("sidebar_header_mode_tabs").height
width: Math.round(parent.width)
boundsBehavior: Flickable.StopAtBounds
anchors
{
left: parent.left
leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
right: parent.right
rightMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
verticalCenter: parent.verticalCenter
}
ExclusiveGroup { id: extruderMenuGroup; }
orientation: ListView.Horizontal
model: Cura.ExtrudersModel { id: extrudersModel; }
Connections
{
target: Cura.MachineManager
onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
}
delegate: Button
{
height: ListView.view.height
width: Math.round(ListView.view.width / extrudersModel.rowCount())
text: model.name
tooltip: model.name
exclusiveGroup: extruderMenuGroup
checked: base.currentExtruderIndex == index
property bool extruder_enabled: true
MouseArea
{
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
switch (mouse.button) {
case Qt.LeftButton:
extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled
if (extruder_enabled)
{
forceActiveFocus(); // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
Cura.ExtruderManager.setActiveExtruderIndex(index);
}
break;
case Qt.RightButton:
extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled
extruderMenu.popup();
break;
}
}
}
Menu
{
id: extruderMenu
MenuItem {
text: catalog.i18nc("@action:inmenu", "Enable Extruder")
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true)
visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then
}
MenuItem {
text: catalog.i18nc("@action:inmenu", "Disable Extruder")
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
visible: extruder_enabled
enabled: Cura.MachineManager.numberExtrudersEnabled > 1
}
}
style: ButtonStyle
{
background: Item
{
function buttonBackgroundColor(index)
{
var extruder = Cura.MachineManager.getExtruder(index)
if (extruder.isEnabled) {
return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") :
control.hovered ? UM.Theme.getColor("action_button_hovered") :
UM.Theme.getColor("action_button")
} else {
return UM.Theme.getColor("action_button_disabled")
}
}
function buttonBorderColor(index)
{
var extruder = Cura.MachineManager.getExtruder(index)
if (extruder.isEnabled) {
return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") :
control.hovered ? UM.Theme.getColor("action_button_hovered_border") :
UM.Theme.getColor("action_button_border")
} else {
return UM.Theme.getColor("action_button_disabled_border")
}
}
function buttonColor(index) {
var extruder = Cura.MachineManager.getExtruder(index);
if (extruder.isEnabled)
{
return (
control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
UM.Theme.getColor("action_button_text");
} else {
return UM.Theme.getColor("action_button_disabled_text");
}
}
Rectangle
{
anchors.fill: parent
border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width
border.color: buttonBorderColor(index)
color: buttonBackgroundColor(index)
Behavior on color { ColorAnimation { duration: 50; } }
}
Item
{
id: extruderButtonFace
anchors.centerIn: parent
width: {
var extruderTextWidth = extruderStaticText.visible ? extruderStaticText.width : 0;
var iconWidth = extruderIconItem.width;
return Math.round(extruderTextWidth + iconWidth + UM.Theme.getSize("default_margin").width / 2);
}
// Static text "Extruder"
Label
{
id: extruderStaticText
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
color: buttonColor(index)
font: UM.Theme.getFont("large_nonbold")
text: catalog.i18nc("@label", "Extruder")
visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width)
elide: Text.ElideRight
}
// Everything for the extruder icon
Item
{
id: extruderIconItem
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
property var sizeToUse:
{
var minimumWidth = control.width < UM.Theme.getSize("button").width ? control.width : UM.Theme.getSize("button").width;
var minimumHeight = control.height < UM.Theme.getSize("button").height ? control.height : UM.Theme.getSize("button").height;
var minimumSize = minimumWidth < minimumHeight ? minimumWidth : minimumHeight;
minimumSize -= Math.round(UM.Theme.getSize("default_margin").width / 2);
return minimumSize;
}
width: sizeToUse
height: sizeToUse
UM.RecolorImage {
id: mainCircle
anchors.fill: parent
sourceSize.width: parent.width
sourceSize.height: parent.width
source: UM.Theme.getIcon("extruder_button")
color: extruderNumberText.color
}
Label
{
id: extruderNumberText
anchors.centerIn: parent
text: index + 1;
color: buttonColor(index)
font: UM.Theme.getFont("default_bold")
}
// Material colour circle
// Only draw the filling colour of the material inside the SVG border.
Rectangle
{
id: materialColorCircle
anchors
{
right: parent.right
top: parent.top
rightMargin: Math.round(parent.sizeToUse * 0.01)
topMargin: Math.round(parent.sizeToUse * 0.05)
}
color: model.color
width: Math.round(parent.width * 0.35)
height: Math.round(parent.height * 0.35)
radius: Math.round(width / 2)
border.width: 1
border.color: UM.Theme.getColor("extruder_button_material_border")
opacity: !control.checked ? 0.6 : 1.0
}
}
}
}
label: Item {}
}
}
}
}
Item
{
id: variantRowSpacer
height: Math.round(UM.Theme.getSize("sidebar_margin").height / 4)
width: height
visible: !extruderSelectionRow.visible && !initialSeparator.visible
}
// Material Row
Item
{
id: materialRow
height: UM.Theme.getSize("sidebar_setup").height
visible: Cura.MachineManager.hasMaterials && !sidebar.hideSettings
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("sidebar_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("sidebar_margin").width
}
Label
{
id: materialLabel
text: catalog.i18nc("@label", "Material");
width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
height: parent.height
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
}
ToolButton
{
id: materialSelection
property var activeExtruder: Cura.MachineManager.activeStack
property var hasActiveExtruder: activeExtruder != null
property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : ""
text: currentRootMaterialName
tooltip: currentRootMaterialName
visible: Cura.MachineManager.hasMaterials
enabled: !extrudersList.visible || base.currentExtruderIndex > -1
height: UM.Theme.getSize("setting_control").height
width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width
anchors.right: parent.right
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true;
menu: MaterialMenu
{
extruderIndex: base.currentExtruderIndex
}
property var valueError: !isMaterialSupported()
property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported
function isMaterialSupported ()
{
if (!hasActiveExtruder)
{
return false;
}
return Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") == "True"
}
}
}
//Variant row
Item
{
id: variantRow
height: UM.Theme.getSize("sidebar_setup").height
visible: Cura.MachineManager.hasVariants && !sidebar.hideSettings
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("sidebar_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("sidebar_margin").width
}
Label
{
id: variantLabel
text: Cura.MachineManager.activeDefinitionVariantsName;
width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
height: parent.height
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
}
ToolButton
{
id: variantSelection
text: Cura.MachineManager.activeVariantName
tooltip: Cura.MachineManager.activeVariantName;
visible: Cura.MachineManager.hasVariants
height: UM.Theme.getSize("setting_control").height
width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
anchors.right: parent.right
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true;
menu: NozzleMenu { extruderIndex: base.currentExtruderIndex }
}
}
Rectangle
{
id: buildplateSeparator
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
visible: buildplateRow.visible
height: visible ? UM.Theme.getSize("sidebar_lining_thin").height : 0
color: UM.Theme.getColor("sidebar_lining")
}
//Buildplate row
Item
{
id: buildplateRow
height: UM.Theme.getSize("sidebar_setup").height
// TODO Only show in dev mode. Remove check when feature ready
visible: CuraSDKVersion == "dev" ? Cura.MachineManager.hasVariantBuildplates && !sidebar.hideSettings : false
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("sidebar_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("sidebar_margin").width
}
Label
{
id: buildplateLabel
text: catalog.i18nc("@label", "Build plate");
width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
height: parent.height
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
}
ToolButton
{
id: buildplateSelection
text: Cura.MachineManager.activeVariantBuildplateName
tooltip: Cura.MachineManager.activeVariantBuildplateName
visible: Cura.MachineManager.hasVariantBuildplates
height: UM.Theme.getSize("setting_control").height
width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
anchors.right: parent.right
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true;
menu: BuildplateMenu {}
property var valueError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable
property var valueWarning: Cura.MachineManager.variantBuildplateUsable
}
}
// Material info row
Item
{
id: materialInfoRow
height: Math.round(UM.Theme.getSize("sidebar_setup").height / 2)
visible: (Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariantBuildplates) && !sidebar.hideSettings
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("sidebar_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("sidebar_margin").width
}
// TODO This was added to replace the buildplate selector. Remove this component when the feature is ready
Label
{
id: materialCompatibilityLabel
y: -Math.round(UM.Theme.getSize("sidebar_margin").height / 3)
anchors.left: parent.left
width: parent.width - materialCompatibilityLink.width
text: catalog.i18nc("@label", "Use glue with this material combination")
font: UM.Theme.getFont("very_small")
color: UM.Theme.getColor("text")
visible: CuraSDKVersion == "dev" ? false : buildplateCompatibilityError || buildplateCompatibilityWarning
wrapMode: Text.WordWrap
opacity: 0.5
}
Item
{
id: materialCompatibilityLink
height: UM.Theme.getSize("sidebar_setup").height
anchors.right: parent.right
width: childrenRect.width + UM.Theme.getSize("default_margin").width
UM.RecolorImage {
id: warningImage
anchors.right: materialInfoLabel.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.Bottom
source: UM.Theme.getIcon("warning")
width: UM.Theme.getSize("section_icon").width
height: UM.Theme.getSize("section_icon").height
sourceSize.width: width
sourceSize.height: height
color: UM.Theme.getColor("material_compatibility_warning")
visible: !Cura.MachineManager.isCurrentSetupSupported || buildplateCompatibilityError || buildplateCompatibilityWarning
}
Label {
id: materialInfoLabel
wrapMode: Text.WordWrap
text: "<a href='%1'>" + catalog.i18nc("@label", "Check compatibility") + "</a>"
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
linkColor: UM.Theme.getColor("text_link")
verticalAlignment: Text.AlignTop
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
// open the material URL with web browser
var url = "https://ultimaker.com/incoming-links/cura/material-compatibilty"
Qt.openUrlExternally(url);
}
onEntered: {
var content = catalog.i18nc("@tooltip", "Click to check the material compatibility on Ultimaker.com.");
base.showTooltip(
materialInfoRow,
Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0),
catalog.i18nc("@tooltip", content)
);
}
onExited: base.hideTooltip();
}
}
}
}
UM.SettingPropertyProvider
{
id: machineExtruderCount
containerStack: Cura.MachineManager.activeMachine
key: "machine_extruder_count"
watchedProperties: [ "value" ]
storeIndex: 0
}
UM.I18nCatalog { id: catalog; name:"cura" }
}

File diff suppressed because it is too large Load diff

View file

@ -2,96 +2,162 @@
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
Item
{
id: base;
id: base
width: buttons.width;
width: buttons.width
height: buttons.height
property int activeY
Column
Item
{
id: buttons;
id: buttons
width: parent.visible ? toolButtons.width : 0
height: childrenRect.height
anchors.bottom: parent.bottom
anchors.left: parent.left
spacing: UM.Theme.getSize("button_lining").width
Behavior on width { NumberAnimation { duration: 100 } }
Repeater
// Used to create a rounded rectangle behind the toolButtons
Rectangle
{
id: repeat
model: UM.ToolModel { }
width: childrenRect.width
height: childrenRect.height
Button
anchors
{
text: model.name + (model.shortcut ? (" (" + model.shortcut + ")") : "")
iconSource: (UM.Theme.getIcon(model.icon) != "") ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon
checkable: true
checked: model.active
enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled
style: UM.Theme.styles.tool_button
fill: toolButtons
leftMargin: -radius - border.width
rightMargin: -border.width
topMargin: -border.width
bottomMargin: -border.width
}
radius: UM.Theme.getSize("default_radius").width
color: UM.Theme.getColor("lining")
}
onCheckedChanged:
Column
{
id: toolButtons
anchors.top: parent.top
anchors.right: parent.right
spacing: UM.Theme.getSize("default_lining").height
Repeater
{
id: repeat
model: UM.ToolModel { id: toolsModel }
width: childrenRect.width
height: childrenRect.height
delegate: ToolbarButton
{
if (checked)
text: model.name + (model.shortcut ? (" (" + model.shortcut + ")") : "")
checkable: true
checked: model.active
enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled
isTopElement: toolsModel.getItem(0).id == model.id
isBottomElement: toolsModel.getItem(toolsModel.count - 1).id == model.id
toolItem: UM.RecolorImage
{
base.activeY = y;
source: UM.Theme.getIcon(model.icon) != "" ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon
color: UM.Theme.getColor("toolbar_button_text")
sourceSize: UM.Theme.getSize("button_icon")
}
}
//Workaround since using ToolButton's onClicked would break the binding of the checked property, instead
//just catch the click so we do not trigger that behaviour.
MouseArea
{
anchors.fill: parent;
onClicked:
onCheckedChanged:
{
forceActiveFocus() //First grab focus, so all the text fields are updated
if(parent.checked)
if (checked)
{
UM.Controller.setActiveTool(null);
base.activeY = y;
}
else
}
//Workaround since using ToolButton's onClicked would break the binding of the checked property, instead
//just catch the click so we do not trigger that behaviour.
MouseArea
{
anchors.fill: parent;
onClicked:
{
UM.Controller.setActiveTool(model.id);
forceActiveFocus() //First grab focus, so all the text fields are updated
if(parent.checked)
{
UM.Controller.setActiveTool(null);
}
else
{
UM.Controller.setActiveTool(model.id);
}
}
}
}
}
}
Item { height: UM.Theme.getSize("default_margin").height; width: UM.Theme.getSize("default_lining").width; visible: extruders.count > 0 }
Repeater
// Used to create a rounded rectangle behind the extruderButtons
Rectangle
{
id: extruders
width: childrenRect.width
height: childrenRect.height
property var _model: Cura.ExtrudersModel { id: extrudersModel }
model: _model.items.length > 1 ? _model : 0
ExtruderButton { extruder: model }
anchors
{
fill: extruderButtons
leftMargin: -radius - border.width
rightMargin: -border.width
topMargin: -border.width
bottomMargin: -border.width
}
radius: UM.Theme.getSize("default_radius").width
color: UM.Theme.getColor("lining")
visible: extrudersModel.items.length > 1
}
Column
{
id: extruderButtons
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.top: toolButtons.bottom
anchors.right: parent.right
spacing: UM.Theme.getSize("default_lining").height
Repeater
{
id: extruders
width: childrenRect.width
height: childrenRect.height
model: extrudersModel.items.length > 1 ? extrudersModel : 0
delegate: ExtruderButton
{
extruder: model
isTopElement: extrudersModel.getItem(0).id == model.id
isBottomElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).id == model.id
}
}
}
}
Cura.ExtrudersModel
{
id: extrudersModel
}
UM.PointingRectangle
{
id: panelBorder;
id: panelBorder
anchors.left: parent.right;
anchors.leftMargin: UM.Theme.getSize("default_margin").width;
anchors.top: base.top;
anchors.left: parent.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.top: base.top
anchors.topMargin: base.activeY
z: buttons.z -1
z: buttons.z - 1
target: Qt.point(parent.right, base.activeY + Math.round(UM.Theme.getSize("button").height/2))
arrowSize: UM.Theme.getSize("default_arrow").width
@ -100,14 +166,14 @@ Item
{
if (panel.item && panel.width > 0)
{
return Math.max(panel.width + 2 * UM.Theme.getSize("default_margin").width);
return Math.max(panel.width + 2 * UM.Theme.getSize("default_margin").width)
}
else
{
return 0;
}
}
height: panel.item ? panel.height + 2 * UM.Theme.getSize("default_margin").height : 0;
height: panel.item ? panel.height + 2 * UM.Theme.getSize("default_margin").height : 0
opacity: panel.item && panel.width > 0 ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
@ -125,11 +191,11 @@ Item
{
id: panel
x: UM.Theme.getSize("default_margin").width;
y: UM.Theme.getSize("default_margin").height;
x: UM.Theme.getSize("default_margin").width
y: UM.Theme.getSize("default_margin").height
source: UM.ActiveTool.valid ? UM.ActiveTool.activeToolPanel : ""
enabled: UM.Controller.toolsEnabled;
enabled: UM.Controller.toolsEnabled
}
}

View file

@ -0,0 +1,99 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
Button
{
id: base
property alias toolItem: contentItemLoader.sourceComponent
// These two properties indicate whether the toolbar button is at the top of the toolbar column or at the bottom.
// If it is somewhere in the middle, then both has to be false. If there is only one element in the column, then
// both properties have to be set to true. This is used to create a rounded corner.
property bool isTopElement: false
property bool isBottomElement: false
hoverEnabled: true
background: Rectangle
{
implicitWidth: UM.Theme.getSize("button").width
implicitHeight: UM.Theme.getSize("button").height
color:
{
if (base.checked && base.hovered)
{
return UM.Theme.getColor("toolbar_button_active_hover")
}
else if (base.checked)
{
return UM.Theme.getColor("toolbar_button_active")
}
else if(base.hovered)
{
return UM.Theme.getColor("toolbar_button_hover")
}
return UM.Theme.getColor("toolbar_background")
}
radius: UM.Theme.getSize("default_radius").width
Rectangle
{
id: topSquare
anchors
{
left: parent.left
right: parent.right
top: parent.top
}
height: parent.radius
color: parent.color
visible: !base.isTopElement
}
Rectangle
{
id: bottomSquare
anchors
{
left: parent.left
right: parent.right
bottom: parent.bottom
}
height: parent.radius
color: parent.color
visible: !base.isBottomElement
}
Rectangle
{
id: leftSquare
anchors
{
left: parent.left
top: parent.top
bottom: parent.bottom
}
width: parent.radius
color: parent.color
}
}
contentItem: Item
{
opacity: parent.enabled ? 1.0 : 0.2
Loader
{
id: contentItemLoader
anchors.centerIn: parent
width: UM.Theme.getSize("button_icon").width
height: UM.Theme.getSize("button_icon").height
}
}
}

Some files were not shown because too many files have changed in this diff Show more