Merge branch 'master' of github.com:Ultimaker/Cura

This commit is contained in:
Jaime van Kessel 2020-06-17 16:03:39 +02:00
commit d8ac7fdf2a
No known key found for this signature in database
GPG Key ID: 3710727397403C91
14 changed files with 203 additions and 107 deletions

View File

@ -103,6 +103,11 @@ class Account(QObject):
self._authorization_service.accessTokenChanged.connect(self._onAccessTokenChanged) self._authorization_service.accessTokenChanged.connect(self._onAccessTokenChanged)
self._authorization_service.loadAuthDataFromPreferences() self._authorization_service.loadAuthDataFromPreferences()
@pyqtProperty(int, notify=syncStateChanged)
def syncState(self):
return self._sync_state
def setSyncState(self, service_name: str, state: int) -> None: def setSyncState(self, service_name: str, state: int) -> None:
""" Can be used to register sync services and update account sync states """ Can be used to register sync services and update account sync states

View File

@ -262,6 +262,10 @@ class CuraApplication(QtApplication):
def ultimakerCloudAccountRootUrl(self) -> str: def ultimakerCloudAccountRootUrl(self) -> str:
return UltimakerCloudConstants.CuraCloudAccountAPIRoot return UltimakerCloudConstants.CuraCloudAccountAPIRoot
@pyqtProperty(str, constant=True)
def ultimakerDigitalFactoryUrl(self) -> str:
return UltimakerCloudConstants.CuraDigitalFactoryURL
def addCommandLineOptions(self): def addCommandLineOptions(self):
"""Adds command line options to the command line parser. """Adds command line options to the command line parser.

View File

@ -7,6 +7,7 @@
DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str
DEFAULT_CLOUD_API_VERSION = "1" # type: str DEFAULT_CLOUD_API_VERSION = "1" # type: str
DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str
DEFAULT_DIGITAL_FACTORY_URL = "https://digitalfactory.ultimaker.com" # type: str
# Container Metadata keys # Container Metadata keys
META_UM_LINKED_TO_ACCOUNT = "um_linked_to_account" META_UM_LINKED_TO_ACCOUNT = "um_linked_to_account"
@ -32,3 +33,10 @@ try:
CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT
except ImportError: except ImportError:
CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT
try:
from cura.CuraVersion import CuraDigitalFactoryURL # type: ignore
if CuraDigitalFactoryURL == "":
CuraDigitalFactoryURL = DEFAULT_DIGITAL_FACTORY_URL
except ImportError:
CuraDigitalFactoryURL = DEFAULT_DIGITAL_FACTORY_URL

View File

@ -5702,7 +5702,7 @@
"minimum_value": "0", "minimum_value": "0",
"maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)", "maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)",
"minimum_value_warning": "max(extruderValues('prime_tower_line_width')) * 2", "minimum_value_warning": "max(extruderValues('prime_tower_line_width')) * 2",
"maximum_value_warning": "20", "maximum_value_warning": "42",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false "settable_per_extruder": false
}, },

View File

@ -1,4 +1,4 @@
// Copyright (c) 2018 Ultimaker B.V. // Copyright (c) 2020 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10 import QtQuick 2.10
@ -7,19 +7,16 @@ import QtQuick.Controls 2.3
import UM 1.4 as UM import UM 1.4 as UM
import Cura 1.1 as Cura import Cura 1.1 as Cura
Column Item
{ {
property var profile: null property var profile: Cura.API.account.userProfile
property var loggedIn: false property bool loggedIn: Cura.API.account.isLoggedIn
property var profileImage: "" property var profileImage: Cura.API.account.profileImageUrl
padding: UM.Theme.getSize("wide_margin").height
spacing: UM.Theme.getSize("wide_margin").height
Loader Loader
{ {
id: accountOperations id: accountOperations
anchors.horizontalCenter: parent.horizontalCenter anchors.centerIn: parent
sourceComponent: loggedIn ? userOperations : generalOperations sourceComponent: loggedIn ? userOperations : generalOperations
} }

View File

@ -131,14 +131,9 @@ Item
opacity: opened ? 1 : 0 opacity: opened ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } } Behavior on opacity { NumberAnimation { duration: 100 } }
padding: 0
contentItem: AccountDetails contentItem: AccountDetails
{ {}
id: panel
profile: Cura.API.account.userProfile
loggedIn: Cura.API.account.isLoggedIn
profileImage: Cura.API.account.profileImageUrl
}
background: UM.PointingRectangle background: UM.PointingRectangle
{ {

View File

@ -54,6 +54,6 @@ Item
visible: hasAvatar visible: hasAvatar
source: UM.Theme.getIcon("circle_outline") source: UM.Theme.getIcon("circle_outline")
sourceSize: Qt.size(parent.width, parent.height) sourceSize: Qt.size(parent.width, parent.height)
color: UM.Theme.getColor("account_widget_ouline_active") color: UM.Theme.getColor("account_widget_outline_active")
} }
} }

View File

@ -10,7 +10,7 @@ import Cura 1.1 as Cura
Column Column
{ {
spacing: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width
padding: UM.Theme.getSize("default_margin").width
Image Image
{ {
id: machinesImage id: machinesImage

View File

@ -4,15 +4,45 @@ import QtQuick.Controls 2.3
import UM 1.4 as UM import UM 1.4 as UM
import Cura 1.1 as Cura import Cura 1.1 as Cura
Row // sync state icon + message Row // Sync state icon + message
{ {
property var syncState: Cura.API.account.syncState
id: syncRow id: syncRow
width: childrenRect.width width: childrenRect.width
height: childrenRect.height height: childrenRect.height
anchors.horizontalCenter: parent.horizontalCenter
spacing: UM.Theme.getSize("narrow_margin").height spacing: UM.Theme.getSize("narrow_margin").height
states: [
State
{
name: "idle"
when: syncState == Cura.AccountSyncState.IDLE
PropertyChanges { target: icon; source: UM.Theme.getIcon("update")}
},
State
{
name: "syncing"
when: syncState == Cura.AccountSyncState.SYNCING
PropertyChanges { target: icon; source: UM.Theme.getIcon("update") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Checking...")}
},
State
{
name: "up_to_date"
when: syncState == Cura.AccountSyncState.SUCCESS
PropertyChanges { target: icon; source: UM.Theme.getIcon("checked") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Account synced")}
},
State
{
name: "error"
when: syncState == Cura.AccountSyncState.ERROR
PropertyChanges { target: icon; source: UM.Theme.getIcon("warning_light") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Something went wrong...")}
}
]
UM.RecolorImage UM.RecolorImage
{ {
id: icon id: icon
@ -20,7 +50,7 @@ Row // sync state icon + message
height: width height: width
source: Cura.API.account.manualSyncEnabled ? UM.Theme.getIcon("update") : UM.Theme.getIcon("checked") source: Cura.API.account.manualSyncEnabled ? UM.Theme.getIcon("update") : UM.Theme.getIcon("checked")
color: palette.text color: UM.Theme.getColor("account_sync_state_icon")
RotationAnimator RotationAnimator
{ {
@ -30,7 +60,7 @@ Row // sync state icon + message
to: 360 to: 360
duration: 1000 duration: 1000
loops: Animation.Infinite loops: Animation.Infinite
running: true running: syncState == Cura.AccountSyncState.SYNCING
// reset rotation when stopped // reset rotation when stopped
onRunningChanged: { onRunningChanged: {
@ -50,10 +80,13 @@ Row // sync state icon + message
Label Label
{ {
id: stateLabel id: stateLabel
text: catalog.i18nc("@state", catalog.i18nc("@label", "You are in sync with your account")) text: catalog.i18nc("@state", catalog.i18nc("@label", "Account synced"))
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
font: UM.Theme.getFont("medium") font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering renderType: Text.NativeRendering
width: contentWidth + UM.Theme.getSize("default_margin").height
height: contentHeight
verticalAlignment: Text.AlignVCenter
visible: !Cura.API.account.manualSyncEnabled visible: !Cura.API.account.manualSyncEnabled
} }
@ -64,8 +97,10 @@ Row // sync state icon + message
color: UM.Theme.getColor("secondary_button_text") color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium") font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
height: contentHeight
width: contentWidth + UM.Theme.getSize("default_margin").height
visible: Cura.API.account.manualSyncEnabled visible: Cura.API.account.manualSyncEnabled
height: visible ? accountSyncButton.intrinsicHeight : 0
MouseArea MouseArea
{ {
@ -77,33 +112,4 @@ Row // sync state icon + message
} }
} }
} }
}
signal syncStateChanged(string newState)
onSyncStateChanged: {
if(newState == Cura.AccountSyncState.IDLE){
icon.source = UM.Theme.getIcon("update")
} else if(newState == Cura.AccountSyncState.SYNCING){
icon.source = UM.Theme.getIcon("update")
stateLabel.text = catalog.i18nc("@label", "Checking...")
} else if (newState == Cura.AccountSyncState.SUCCESS) {
icon.source = UM.Theme.getIcon("checked")
stateLabel.text = catalog.i18nc("@label", "You are in sync with your account")
} else if (newState == Cura.AccountSyncState.ERROR) {
icon.source = UM.Theme.getIcon("warning_light")
stateLabel.text = catalog.i18nc("@label", "Something went wrong...")
} else {
print("Error: unexpected sync state: " + newState)
}
if(newState == Cura.AccountSyncState.SYNCING){
updateAnimator.running = true
} else {
updateAnimator.running = false
}
}
Component.onCompleted: Cura.API.account.syncStateChanged.connect(syncStateChanged)
}

View File

@ -9,72 +9,119 @@ import Cura 1.1 as Cura
Column Column
{ {
width: Math.max( spacing: UM.Theme.getSize("narrow_margin").height
Math.max(title.width, accountButton.width) + 2 * UM.Theme.getSize("default_margin").width, topPadding: UM.Theme.getSize("default_margin").height
syncRow.width bottomPadding: UM.Theme.getSize("default_margin").height
) width: childrenRect.width
spacing: UM.Theme.getSize("default_margin").height Item
SystemPalette
{ {
id: palette id: accountInfo
width: childrenRect.width
height: childrenRect.height
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
AvatarImage
{
id: avatar
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("main_window_header").height
height: UM.Theme.getSize("main_window_header").height
source: profile["profile_image_url"] ? profile["profile_image_url"] : ""
outlineColor: UM.Theme.getColor("main_background")
}
Rectangle
{
id: initialCircle
width: avatar.width
height: avatar.height
radius: width
anchors.verticalCenter: parent.verticalCenter
color: UM.Theme.getColor("action_button_disabled")
visible: !avatar.hasAvatar
Label
{
id: initialLabel
anchors.centerIn: parent
text: profile["username"].charAt(0).toUpperCase()
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
}
}
Column
{
anchors.left: avatar.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("narrow_margin").height
width: childrenRect.width
height: childrenRect.height
Label
{
id: username
renderType: Text.NativeRendering
text: profile.username
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
}
SyncState
{
id: syncRow
}
Label
{
id: lastSyncLabel
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a timestamp", "Last update: %1").arg(Cura.API.account.lastSyncDateTime)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
}
}
} }
Label Rectangle
{ {
id: title width: parent.width
anchors.horizontalCenter: parent.horizontalCenter color: UM.Theme.getColor("lining")
horizontalAlignment: Text.AlignHCenter height: UM.Theme.getSize("default_lining").height
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a username.", "Hi %1").arg(profile.username)
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
} }
Cura.TertiaryButton
SyncState {
id: syncRow
}
Label
{ {
id: lastSyncLabel id: cloudButton
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a timestamp", "Last update: %1").arg(Cura.API.account.lastSyncDateTime)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
}
Cura.SecondaryButton
{
id: accountButton
anchors.horizontalCenter: parent.horizontalCenter
width: UM.Theme.getSize("account_button").width width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Ultimaker account") text: catalog.i18nc("@button", "Ultimaker Digital Factory")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerDigitalFactoryUrl)
fixedWidthMode: false
}
Cura.TertiaryButton
{
id: accountButton
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Ultimaker Account")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl) onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl)
fixedWidthMode: false fixedWidthMode: false
} }
Label Rectangle
{ {
id: signOutButton width: parent.width
anchors.horizontalCenter: parent.horizontalCenter color: UM.Theme.getColor("lining")
text: catalog.i18nc("@button", "Sign out") height: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
MouseArea
{
anchors.fill: parent
onClicked: Cura.API.account.logout()
hoverEnabled: true
onEntered: signOutButton.font.underline = true
onExited: signOutButton.font.underline = false
}
} }
Cura.TertiaryButton
{
id: signOutButton
onClicked: Cura.API.account.logout()
text: catalog.i18nc("@button", "Sign Out")
}
} }

View File

@ -33,6 +33,8 @@ Button
property alias shadowEnabled: shadow.visible property alias shadowEnabled: shadow.visible
property alias busy: busyIndicator.visible property alias busy: busyIndicator.visible
property bool underlineTextOnHover: false
property alias toolTipContentAlignment: tooltip.contentAlignment property alias toolTipContentAlignment: tooltip.contentAlignment
// This property is used to indicate whether the button has a fixed width or the width would depend on the contents // This property is used to indicate whether the button has a fixed width or the width would depend on the contents
@ -49,6 +51,14 @@ Button
height: UM.Theme.getSize("action_button").height height: UM.Theme.getSize("action_button").height
hoverEnabled: true hoverEnabled: true
onHoveredChanged:
{
if(underlineTextOnHover)
{
buttonText.font.underline = hovered
}
}
contentItem: Row contentItem: Row
{ {
spacing: UM.Theme.getSize("narrow_margin").width spacing: UM.Theme.getSize("narrow_margin").width

View File

@ -0,0 +1,21 @@
// Copyright (c) 2020 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: "transparent"
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: "transparent"
underlineTextOnHover: true
}

View File

@ -24,6 +24,8 @@
"main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_inactive": [128, 128, 128, 255],
"account_sync_state_icon": [255, 255, 255, 204],
"machine_selector_bar": [39, 44, 48, 255], "machine_selector_bar": [39, 44, 48, 255],
"machine_selector_active": [39, 44, 48, 255], "machine_selector_active": [39, 44, 48, 255],
"machine_selector_printer_icon": [204, 204, 204, 255], "machine_selector_printer_icon": [204, 204, 204, 255],

View File

@ -183,6 +183,7 @@
"main_window_header_button_background_hovered": [117, 114, 159, 255], "main_window_header_button_background_hovered": [117, 114, 159, 255],
"account_widget_outline_active": [70, 66, 126, 255], "account_widget_outline_active": [70, 66, 126, 255],
"account_sync_state_icon": [25, 25, 25, 255],
"machine_selector_bar": [31, 36, 39, 255], "machine_selector_bar": [31, 36, 39, 255],
"machine_selector_active": [68, 72, 75, 255], "machine_selector_active": [68, 72, 75, 255],