diff --git a/resources.qrc b/resources.qrc
index f26f90192acfe..c43621f8847f1 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -1,5 +1,8 @@
+ src/gui/nmcgui/qmldir
+ src/gui/nmcgui/NMCHeaderButton.qml
+ src/gui/nmcgui/NMCMenuItem.qml
src/gui/UserStatusMessageView.qml
src/gui/UserStatusSelectorPage.qml
src/gui/EmojiPicker.qml
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 736d8bc3cc622..7233e45df8f81 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -23,6 +23,9 @@ endif()
configure_file(${CMAKE_SOURCE_DIR}/theme.qrc.in ${CMAKE_SOURCE_DIR}/theme.qrc)
set(theme_dir ${CMAKE_SOURCE_DIR}/theme)
+#NMC customization: needed to find the ui file in a different location than the header file
+set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_SOURCE_DIR}/src/gui")
+
set(client_UI_SRCS
accountsettings.ui
conflictdialog.ui
@@ -259,6 +262,10 @@ set(client_SRCS
integration/fileactionsmodel.cpp
)
+file(GLOB NMC_FILES "nmcgui/*")
+set(NMC_SRCS ${NMC_FILES})
+list(APPEND client_SRCS ${NMC_SRCS})
+
if (NOT DISABLE_ACCOUNT_MIGRATION)
list(APPEND client_SRCS
legacyaccountselectiondialog.h
diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp
index fe7c66e315bbc..d7d00b72ebe66 100644
--- a/src/gui/accountsettings.cpp
+++ b/src/gui/accountsettings.cpp
@@ -216,17 +216,8 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
const auto fpSettingsWidget = fpSettingsController->settingsViewWidget(fpAccountUserIdAtHost, fileProviderPanelContents,
QQuickWidget::SizeRootObjectToView);
fpSettingsLayout->setContentsMargins(0, 0, 0, 0);
- fpSettingsLayout->setSpacing(0);
-
- fpSettingsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- if (const auto fpSettingsWidgetLayout = fpSettingsWidget->layout()) {
- fpSettingsWidgetLayout->setContentsMargins(0, 0, 0, 0);
- }
- fpSettingsLayout->addWidget(fpSettingsWidget, 1);
- fileProviderPanelContents->setLayout(fpSettingsLayout);
+ fpSettingsLayout->addWidget(fpSettingsWidget);
} else {
- // macOS 13 Ventura: the file provider feature is unsupported there.
- // This branch can be removed once Ventura is no longer supported.
_ui->fileProviderPanel->setVisible(false);
}
#else
@@ -240,10 +231,8 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
networkSettingsLayout->setContentsMargins(0, 0, 0, 0);
}
connectionSettingsLayout->setContentsMargins(0, 0, 0, 0);
- connectionSettingsLayout->setSpacing(0);
- connectionSettingsLayout->addWidget(networkSettings, 1);
- connectionSettingsPanelContents->setLayout(connectionSettingsLayout);
-
+ connectionSettingsLayout->addWidget(networkSettings);
+
const auto mouseCursorChanger = new MouseCursorChanger(this);
mouseCursorChanger->folderList = _ui->_folderList;
mouseCursorChanger->model = _model;
diff --git a/src/gui/nmcgui/NMCHeaderButton.qml b/src/gui/nmcgui/NMCHeaderButton.qml
new file mode 100644
index 0000000000000..560019eb014a2
--- /dev/null
+++ b/src/gui/nmcgui/NMCHeaderButton.qml
@@ -0,0 +1,65 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import Style
+import com.nextcloud.desktopclient
+
+Item {
+ id: rec
+
+ width: 92
+ height: Style.nmcTrayWindowHeaderHeight
+
+ signal clickedButton
+
+ property string iconText: ""
+ property string iconSource: ""
+ property bool iconHovered: false
+
+ ColumnLayout {
+ spacing: 0
+ anchors.centerIn: parent
+
+ Button {
+ id: button
+ flat: true
+ focusPolicy: Qt.NoFocus
+ Layout.alignment: Qt.AlignHCenter
+
+ contentItem: Image {
+ source: rec.iconSource
+ width: Style.nmcTrayWindowIconWidth
+ height: Style.nmcTrayWindowIconWidth
+ fillMode: Image.PreserveAspectFit
+ anchors.centerIn: parent
+ }
+
+ background: Rectangle {
+ color: rec.iconHovered || button.visualFocus ? "black" : "transparent"
+ opacity: 0.05
+ radius: 4
+ }
+
+ MouseArea {
+ id: buttonArea
+ anchors.fill: parent
+ onClicked: rec.clickedButton() // Trigger the button click signal
+ }
+
+ // Optional: Handle hover on icon to change its state
+ onClicked: rec.clickedButton()
+ }
+
+ Text {
+ width: rec.width
+ text: rec.iconText
+ elide: Text.ElideRight
+ color: Style.nmcTrayWindowHeaderTextColor
+ font.pixelSize: Style.nmcFontSizeIconText
+ horizontalAlignment: Text.AlignHCenter
+ leftPadding: 8
+ rightPadding: 8
+ }
+ }
+}
diff --git a/src/gui/nmcgui/NMCMenuItem.qml b/src/gui/nmcgui/NMCMenuItem.qml
new file mode 100644
index 0000000000000..76c18dbb53992
--- /dev/null
+++ b/src/gui/nmcgui/NMCMenuItem.qml
@@ -0,0 +1,37 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import Style
+
+MenuItem {
+ id: root
+
+ contentItem: RowLayout {
+ spacing: 8
+ anchors.fill: parent
+ anchors.leftMargin: 12
+
+ Image {
+ source: root.icon.source
+ visible: root.icon.source !== ""
+ width: Style.nmcTrayWindowIconWidth
+ height: Style.nmcTrayWindowIconWidth
+ fillMode: Image.PreserveAspectFit
+ }
+
+ Text {
+ text: root.text
+ color: hovered ? Style.nmcTrayWindowHeaderTextColor : Style.nmcTrayWindowHeaderTextColor
+ font.pixelSize: Style.topLinePixelSize
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignLeft
+ elide: Text.ElideRight
+ Layout.fillWidth: true
+ }
+ }
+
+ background: Rectangle {
+ color: root.hovered ? Style.nmcTrayWindowHeaderHighlightColor : "transparent"
+ }
+}
diff --git a/src/gui/nmcgui/qmldir b/src/gui/nmcgui/qmldir
new file mode 100644
index 0000000000000..9bc50ef6383cc
--- /dev/null
+++ b/src/gui/nmcgui/qmldir
@@ -0,0 +1,3 @@
+module NMCGui
+NMCHeaderButton 1.0 NMCHeaderButton.qml
+NMCMenuItem 1.0 NMCMenuItem.qml
\ No newline at end of file
diff --git a/src/gui/tray/ActivityItem.qml b/src/gui/tray/ActivityItem.qml
index 6af9ec3c16522..d406dc30d0ecd 100644
--- a/src/gui/tray/ActivityItem.qml
+++ b/src/gui/tray/ActivityItem.qml
@@ -7,6 +7,7 @@ import QtQml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
+
import Style
import com.nextcloud.desktopclient
@@ -24,25 +25,31 @@ ItemDelegate {
property bool isTalkReplyOptionVisible: model.messageSent !== ""
padding: Style.standardSpacing
+ hoverEnabled: true
Accessible.role: Accessible.ListItem
Accessible.name: (model.path !== "" && model.displayPath !== "") ? qsTr("Open %1 locally").arg(model.displayPath) : model.message
Accessible.onPressAction: root.clicked()
+ background: Rectangle {
+ color: root.hovered || root.activeFocus ? palette.highlight : "transparent"
+ radius: Style.mediumRoundedButtonRadius
+ border.width: 0
+ }
+
ToolTip {
popupType: Qt.platform.os === "windows" ? Popup.Item : Popup.Native
visible: root.hovered && !activityContent.childHovered && model.displayLocation !== ""
text: qsTr("In %1").arg(model.displayLocation)
}
- // TODO: the current style does not support customization of this control
contentItem: ColumnLayout {
spacing: Style.smallSpacing
ActivityItemContent {
id: activityContent
- adaptiveTextColor: root.activeFocus ? palette.highlightedText : palette.text
+ adaptiveTextColor: root.hovered || root.activeFocus ? palette.highlightedText : palette.text
Layout.fillWidth: true
Layout.minimumHeight: Style.minActivityHeight
@@ -60,6 +67,7 @@ ItemDelegate {
Loader {
id: talkReplyTextFieldLoader
+
active: root.isChatActivity && root.isTalkReplyPossible && model.messageSent === ""
visible: root.isTalkReplyOptionVisible
@@ -69,8 +77,8 @@ ItemDelegate {
sourceComponent: TalkReplyTextField {
onSendReply: {
- UserModel.currentUser.sendReplyMessage(model.activityIndex, model.conversationToken, reply, model.messageId);
- talkReplyTextFieldLoader.visible = false;
+ UserModel.currentUser.sendReplyMessage(model.activityIndex, model.conversationToken, reply, model.messageId)
+ talkReplyTextFieldLoader.visible = false
}
}
}
diff --git a/src/gui/tray/ActivityItemActions.qml b/src/gui/tray/ActivityItemActions.qml
index 3997f9250f6e8..7ddaad27e2ee1 100644
--- a/src/gui/tray/ActivityItemActions.qml
+++ b/src/gui/tray/ActivityItemActions.qml
@@ -50,5 +50,25 @@ Repeater {
onClicked: isTalkReplyButton ? root.showReplyField() : root.triggerAction(model.index)
visible: verb !== "REPLY" || (verb === "REPLY" && root.talkReplyButtonVisible)
+
+ HoverHandler {
+ id: mouse
+ acceptedDevices: PointerDevice.AllPointerTypes
+ }
+
+ background: Rectangle {
+ color: mouse.hovered ? Style.nmcConflictHoverColor : Style.nmcConflictColor
+ radius: Style.nmcStandardRadius
+ height: Style.nmcTraySyncButtonHeight
+ }
+
+ contentItem: Text {
+ text: activityActionButton.text
+ color: mouse.hovered ? Style.nmcTextInButtonColor : Style.nmcTextInButtonColor
+ font.pixelSize: Style.fontSizeSmall
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
}
}
diff --git a/src/gui/tray/ActivityItemContent.qml b/src/gui/tray/ActivityItemContent.qml
index f1b09c765e0ef..b22f457684b50 100644
--- a/src/gui/tray/ActivityItemContent.qml
+++ b/src/gui/tray/ActivityItemContent.qml
@@ -33,8 +33,8 @@ RowLayout {
Item {
id: thumbnailItem
- readonly property int imageWidth: width * (1 - Style.thumbnailImageSizeReduction)
- readonly property int imageHeight: height * (1 - Style.thumbnailImageSizeReduction)
+ readonly property int imageWidth: width
+ readonly property int imageHeight: height
readonly property int thumbnailRadius: model.thumbnail && model.thumbnail.isUserAvatar ? width / 2 : 3
implicitWidth: root.iconSize
@@ -184,30 +184,8 @@ RowLayout {
}
display: Button.IconOnly
- visible: model.showFileDetails
- onClicked: fileMoreButtonMenu.visible ? fileMoreButtonMenu.close() : fileMoreButtonMenu.popup()
-
- AutoSizingMenu {
- id: fileMoreButtonMenu
- closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape
-
- MenuItem {
- height: visible ? implicitHeight : 0
- text: qsTr("File details")
- font.pixelSize: Style.topLinePixelSize
- hoverEnabled: true
- onClicked: Systray.presentShareViewInTray(model.openablePath)
- }
-
- MenuItem {
- visible: model.serverHasIntegration
- height: visible ? implicitHeight : 0
- text: qsTr("File actions")
- font.pixelSize: Style.topLinePixelSize
- hoverEnabled: true
- onClicked: Systray.presentFileActionsViewInSystray(model.openablePath)
- }
- }
+ visible: false
+ onClicked: Systray.presentShareViewInTray(model.openablePath)
}
Button {
diff --git a/src/gui/tray/ActivityList.qml b/src/gui/tray/ActivityList.qml
index e2e43c3492707..404a39c3f7854 100644
--- a/src/gui/tray/ActivityList.qml
+++ b/src/gui/tray/ActivityList.qml
@@ -11,9 +11,10 @@ import com.nextcloud.desktopclient as NC
ScrollView {
id: controlRoot
+
property alias model: sortedActivityList.sourceModel
property alias count: activityList.count
- property alias atYBeginning : activityList.atYBeginning
+ property alias atYBeginning: activityList.atYBeginning
property bool isFileActivityList: false
property int iconSize: Style.trayListItemIconSize
property int delegateHorizontalPadding: 0
@@ -21,7 +22,6 @@ ScrollView {
property bool scrollingToTop: false
function scrollToTop() {
- // Triggers activation of repeating upward flick timer
scrollingToTop = true
}
@@ -33,7 +33,7 @@ ScrollView {
topPadding: 0
bottomPadding: 0
rightPadding: ScrollBar.vertical.width
-
+
focus: false
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
@@ -60,6 +60,9 @@ ScrollView {
currentIndex: -1
interactive: true
+ highlight: null
+ highlightFollowsCurrentItem: false
+
Timer {
id: repeatUpFlickTimer
interval: Style.activityListScrollToTopTimerInterval
@@ -74,52 +77,34 @@ ScrollView {
}
}
- highlight: Rectangle {
- id: activityHover
- anchors.fill: activityList.currentItem
- color: palette.highlight
- radius: Style.mediumRoundedButtonRadius
- visible: activityList.activeFocus
- }
-
- highlightFollowsCurrentItem: true
- highlightMoveDuration: 0
- highlightResizeDuration: 0
- highlightRangeMode: ListView.ApplyRange
- preferredHighlightBegin: 0
- preferredHighlightEnd: controlRoot.height
-
model: NC.SortedActivityListModel {
id: sortedActivityList
}
delegate: ActivityItem {
- background: null
width: activityList.contentItem.width
isFileActivityList: controlRoot.isFileActivityList
- iconSize: controlRoot.iconSize
+ iconSize: Style.nmcListViewIconSize
+ leftPadding: Style.nmcListViewLeftPadding
flickable: activityList
+
onHoveredChanged: if (hovered) {
- // When we set the currentIndex the list view will scroll...
- // unless we tamper with the preferred highlight points to stop this.
- const savedPreferredHighlightBegin = activityList.preferredHighlightBegin;
- const savedPreferredHighlightEnd = activityList.preferredHighlightEnd;
- // Set overkill values to make sure no scroll happens when we hover with mouse
- activityList.preferredHighlightBegin = -controlRoot.height;
- activityList.preferredHighlightEnd = controlRoot.height * 2;
+ const savedPreferredHighlightBegin = activityList.preferredHighlightBegin
+ const savedPreferredHighlightEnd = activityList.preferredHighlightEnd
- activityList.currentIndex = index
+ activityList.preferredHighlightBegin = -controlRoot.height
+ activityList.preferredHighlightEnd = controlRoot.height * 2
- // Reset original values so keyboard navigation makes list view scroll
- activityList.preferredHighlightBegin = savedPreferredHighlightBegin;
- activityList.preferredHighlightEnd = savedPreferredHighlightEnd;
+ activityList.currentIndex = index
- forceActiveFocus();
+ activityList.preferredHighlightBegin = savedPreferredHighlightBegin
+ activityList.preferredHighlightEnd = savedPreferredHighlightEnd
}
+
onClicked: {
if (model.isCurrentUserFileActivity && model.openablePath) {
- openFile("file://" + model.openablePath);
+ openFile("file://" + model.openablePath)
} else {
activityItemClicked(model.activityIndex)
}
@@ -150,7 +135,8 @@ ScrollView {
Column {
id: placeholderColumn
- width: parent.width * 0.8
+
+ width: parent.width * 0.75
anchors.centerIn: parent
visible: activityList.count === 0
spacing: Style.standardSpacing
@@ -164,12 +150,12 @@ ScrollView {
}
EnforcedPlainTextLabel {
- width: parent.width
- text: qsTr("No activities yet")
- font.bold: true
- wrapMode: Text.Wrap
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
+ width: parent.width
+ text: qsTr("No activities yet")
+ font.bold: true
+ wrapMode: Text.Wrap
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
}
}
}
diff --git a/src/gui/tray/CurrentAccountHeaderButton.qml b/src/gui/tray/CurrentAccountHeaderButton.qml
index c296c8fbab0d4..f278a2432a039 100644
--- a/src/gui/tray/CurrentAccountHeaderButton.qml
+++ b/src/gui/tray/CurrentAccountHeaderButton.qml
@@ -9,6 +9,7 @@ import QtQuick.Layouts
import "../"
import "../filedetails/"
+import "qrc:/qml/NMCGui"
import Style
import com.nextcloud.desktopclient
@@ -23,18 +24,20 @@ Button {
display: AbstractButton.IconOnly
flat: true
+ hoverEnabled: true
+
+ background: Rectangle {
+ color: root.hovered ? Style.nmcTrayWindowHeaderHighlightColor : "transparent"
+ radius: 4
+ }
+
+ Layout.preferredWidth: Style.nmcCurrentAccountButtonWidth
+ Layout.preferredHeight: Style.nmcTrayWindowHeaderHeight
Accessible.role: Accessible.ButtonMenu
Accessible.name: qsTr("Current account")
Accessible.onPressAction: root.clicked()
- palette {
- text: Style.currentUserHeaderTextColor
- windowText: Style.currentUserHeaderTextColor
- buttonText: Style.currentUserHeaderTextColor
- button: Style.adjustedCurrentUserHeaderColor
- }
-
// We call open() instead of popup() because we want to position it
// exactly below the dropdown button, not the mouse
onClicked: {
@@ -51,18 +54,15 @@ Button {
// x coordinate grows towards the right
// y coordinate grows towards the bottom
- x: (root.x + 2)
- y: (root.y + Style.trayWindowHeaderHeight + 2)
+ x: (0 - Style.nmcTrayWindowLogoWidth)
+ y: (root.y + Style.nmcTrayWindowHeaderHeight - Style.nmcTrayWindowMenuOverlayMargin)
- property real widestMenuItemWidth: 0
- property real maximumWidthAllowed: trayWindowHeader.width - (root.x + 4)
- property real extraMenuWidth: Style.userLineSpacing
- width: Math.min(widestMenuItemWidth + leftPadding + rightPadding + extraMenuWidth, maximumWidthAllowed)
+ width: (Style.nmcCurrentAccountButtonWidth + Style.nmcTrayWindowLogoWidth + 64)
height: Math.min(implicitHeight, maxMenuHeight)
closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape
onClosed: {
- // HACK: reload account Instantiator immediately by resetting it - could be done better I guess
+ // HACK: reload account Instantiator immediately by restting it - could be done better I guess
// see also onVisibleChanged above
userLineInstantiator.active = false;
userLineInstantiator.active = true;
@@ -75,175 +75,106 @@ Button {
implicitHeight: instantiatedUserLine.height
UserLine {
id: instantiatedUserLine
- width: Math.min(accountMenu.widestMenuItemWidth, accountMenu.maximumWidthAllowed)
- parentBackgroundColor: Style.colorWithoutTransparency(accountMenu.palette.window)
-
- Component.onCompleted: {
- instantiatedUserLine.updateMenuWidth()
- }
-
- onImplicitWidthChanged: {
- instantiatedUserLine.updateMenuWidth()
- }
-
- Connections {
- target: model
- function onNameChanged() {
- instantiatedUserLine.updateMenuWidth()
- }
-
- function onStatusChanged() {
- instantiatedUserLine.updateMenuWidth()
- }
- }
-
+ width: parent.width
onShowUserStatusSelector: {
userStatusDrawer.openUserStatusDrawer(model.index);
accountMenu.close();
}
- onShowUserStatusMessageSelector: {
- userStatusDrawer.openUserStatusMessageDrawer(model.index);
- accountMenu.close();
- }
onClicked: UserModel.currentUserId = model.index;
-
- function updateMenuWidth()
- {
- accountMenu.widestMenuItemWidth = Math.max( instantiatedUserLine.implicitWidth, accountMenu.widestMenuItemWidth )
- }
}
}
- onObjectAdded: function(index, object) {
- accountMenu.insertItem(index, object)
- }
- onObjectRemoved: function(index, object) {
- accountMenu.removeItem(object)
- }
+ onObjectAdded: accountMenu.insertItem(index, object)
+ onObjectRemoved: accountMenu.removeItem(object)
}
- MenuItem {
- id: addAccountButton
- hoverEnabled: true
- visible: Systray.enableAddAccount
- implicitHeight: Style.trayWindowHeaderHeight
-
- readonly property real addAccountIconSize: Style.accountAvatarSize * Style.smallIconScaleFactor
- readonly property real addAccountHorizontalOffset: ( (Style.accountAvatarSize - addAccountIconSize) / 2 ) + Style.accountIconsMenuMargin
- property var iconColor: !addAccountButton.enabled
- ? addAccountButton.palette.mid
- : ((addAccountButton.highlighted || addAccountButton.down) && Qt.platform.os !== "windows"
- ? addAccountButton.palette.highlightedText
- : addAccountButton.palette.text)
-
- icon.source: "image://svgimage-custom-color/add.svg/" + iconColor
- icon.width: addAccountIconSize
- icon.height: addAccountIconSize
- leftPadding: addAccountHorizontalOffset
- spacing: Style.userLineSpacing
- text: qsTr("Add account")
- onClicked: UserModel.addAccount()
-
- Accessible.role: Accessible.MenuItem
- Accessible.name: qsTr("Add new account")
- Accessible.onPressAction: addAccountButton.clicked()
+ MenuSeparator {
+ padding: 0
+ topPadding: 6
+ bottomPadding: 6
+ contentItem: Rectangle {
+ implicitHeight: 1
+ color: Style.nmcTrayWindowHeaderSeparatorColor
+ }
}
- MenuSeparator {}
-
- MenuItem {
+ NMCMenuItem {
id: syncPauseButton
- height: Systray.anySyncFolders ? implicitHeight : 0
- font.pixelSize: Style.topLinePixelSize
- hoverEnabled: true
+
+ icon.source: Style.nmcPauseIcon
+ icon.height: Style.nmcTrayWindowIconWidth
+ icon.width: Style.nmcTrayWindowIconWidth
+ leftPadding: Style.nmcMenuSubItemLeftPadding
+ height: Style.nmcMenuSubItemHeight
+
enabled: Systray.anySyncFolders
visible: Systray.anySyncFolders
onClicked: Systray.syncIsPaused = !Systray.syncIsPaused
Accessible.role: Accessible.MenuItem
Accessible.name: Systray.syncIsPaused ? qsTr("Resume sync for all") : qsTr("Pause sync for all")
Accessible.onPressAction: syncPauseButton.clicked()
-
- contentItem: Text {
- text: parent.text
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
- leftPadding: Style.userLineSpacing
- elide: Text.ElideRight
- color: !parent.enabled
- ? parent.palette.mid
- : ((parent.highlighted || parent.down) && Qt.platform.os !== "windows"
- ? parent.palette.highlightedText
- : parent.palette.text)
- }
}
- MenuItem {
+ NMCMenuItem {
id: settingsButton
text: qsTr("Settings")
- font.pixelSize: Style.topLinePixelSize
- hoverEnabled: true
+
+ icon.source: Style.nmcSettingsIcon
+ icon.height: Style.nmcTrayWindowIconWidth
+ icon.width: Style.nmcTrayWindowIconWidth
+ leftPadding: Style.nmcMenuSubItemLeftPadding
+ height: Style.nmcMenuSubItemHeight
+
onClicked: Systray.openSettings()
Accessible.role: Accessible.MenuItem
Accessible.name: text
Accessible.onPressAction: settingsButton.clicked()
-
- contentItem: Text {
- text: parent.text
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
- leftPadding: Style.userLineSpacing
- elide: Text.ElideRight
- color: !parent.enabled
- ? parent.palette.mid
- : ((parent.highlighted || parent.down) && Qt.platform.os !== "windows"
- ? parent.palette.highlightedText
- : parent.palette.text)
- }
}
- MenuItem {
+ NMCMenuItem {
id: exitButton
text: qsTr("Exit");
- font.pixelSize: Style.topLinePixelSize
- hoverEnabled: true
+
+ icon.source: Style.nmcCloseIcon
+ icon.height: Style.nmcTrayWindowIconWidth
+ icon.width: Style.nmcTrayWindowIconWidth
+ leftPadding: Style.nmcMenuSubItemLeftPadding
+ height: Style.nmcMenuSubItemHeight
+
onClicked: Systray.shutdown()
Accessible.role: Accessible.MenuItem
Accessible.name: text
- Accessible.onPressAction: exitButton.clicked()
-
- contentItem: Text {
- text: parent.text
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
- leftPadding: Style.userLineSpacing
- elide: Text.ElideRight
- color: !parent.enabled
- ? parent.palette.mid
- : ((parent.highlighted || parent.down) && Qt.platform.os !== "windows"
- ? parent.palette.highlightedText
- : parent.palette.text)
- }
+ Accessible.onPressAction: exitButton.clicked()
+ }
+
+ // NMC customization: spacer at the bottom of the menu
+ Rectangle {
+ width: parent.width
+ height: 8
+ color: "transparent"
+ anchors.horizontalCenter: parent.horizontalCenter
}
}
- RowLayout {
- id: accountControlRowLayout
+ Item {
+ anchors.fill: parent
- height: Style.trayWindowHeaderHeight
- width: Style.rootWidth
- spacing: 0
+ RowLayout {
+ id: accountControlRowLayout
- Image {
- id: currentAccountAvatar
+ anchors.verticalCenter: parent.verticalCenter
+ width: Style.nmcCurrentAccountButtonWidth
+ spacing: 0
- Layout.leftMargin: Style.trayHorizontalMargin
- verticalAlignment: Qt.AlignCenter
- cache: false
- source: (UserModel.currentUser && UserModel.currentUser.avatar !== "") ? UserModel.currentUser.avatar : "image://avatars/fallbackWhite"
- Layout.preferredHeight: Style.accountAvatarSize
- Layout.preferredWidth: Style.accountAvatarSize
+ Image {
+ id: currentAccountAvatar
- Accessible.role: Accessible.Graphic
- Accessible.name: qsTr("Current account avatar")
+ Layout.leftMargin: Style.trayHorizontalMargin
+ verticalAlignment: Qt.AlignCenter
+ cache: false
+ source: Style.nmcAccountAvatarIcon
+
+ Accessible.role: Accessible.Graphic
+ Accessible.name: qsTr("Current account avatar")
Rectangle {
id: currentAccountStatusIndicatorBackground
@@ -253,7 +184,7 @@ Button {
&& UserModel.currentUser.status !== NC.userStatus.Offline
width: Style.accountAvatarStateIndicatorSize + Style.trayFolderStatusIndicatorSizeOffset
height: width
- color: "white"
+ color: root.parentBackgroundColor
anchors.bottom: currentAccountAvatar.bottom
anchors.right: currentAccountAvatar.right
radius: width * Style.trayFolderStatusIndicatorRadiusFactor
@@ -271,84 +202,88 @@ Button {
sourceSize.width: Style.accountAvatarStateIndicatorSize
sourceSize.height: Style.accountAvatarStateIndicatorSize
- Accessible.role: Accessible.Indicator
- Accessible.name: UserModel.desktopNotificationsAllowed ? qsTr("Current account status is online") : qsTr("Current account status is do not disturb")
- }
- }
-
- Column {
- id: accountLabels
- spacing: Style.extraExtraSmallSpacing
- Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
- Layout.leftMargin: Style.userStatusSpacing
- Layout.fillWidth: true
- Layout.maximumWidth: parent.width
-
- EnforcedPlainTextLabel {
- id: currentAccountUser
- Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
- width: Style.currentAccountLabelWidth
- color: Style.currentUserHeaderTextColor
- text: UserModel.currentUser ? UserModel.currentUser.name : ""
- elide: Text.ElideRight
-
- font.pixelSize: Style.topLinePixelSize
- font.bold: true
- }
-
- EnforcedPlainTextLabel {
- id: currentAccountServer
- Layout.alignment: Qt.AlignLeft | Qt.AlignTop
- width: Style.currentAccountLabelWidth
- color: Style.currentUserHeaderTextColor
- text: UserModel.currentUser ? UserModel.currentUser.server : ""
- font.pixelSize: Style.subLinePixelSize
- elide: Text.ElideRight
- visible: UserModel.numUsers() > 1
+ Accessible.role: Accessible.Indicator
+ Accessible.name: UserModel.desktopNotificationsAllowed ? qsTr("Current account status is online") : qsTr("Current account status is do not disturb")
+ }
}
- RowLayout {
- id: currentUserStatus
- visible: UserModel.currentUser && UserModel.currentUser.isConnected &&
- UserModel.currentUser.serverHasUserStatus
- width: parent.width
+ Column {
+ id: accountLabels
+ spacing: 0
+ Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+ Layout.leftMargin: Style.userStatusSpacing
+ Layout.fillWidth: true
EnforcedPlainTextLabel {
- id: emoji
- Layout.alignment: Qt.AlignLeft | Qt.AlignTop
- visible: UserModel.currentUser && UserModel.currentUser.statusEmoji !== ""
- color: Style.currentUserHeaderTextColor
- text: UserModel.currentUser ? UserModel.currentUser.statusEmoji : ""
- font.pixelSize: Style.subLinePixelSize
+ id: currentAccountUser
+ Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+ Layout.fillWidth: true
+ width: Style.currentAccountLabelWidth
+ color: Style.nmcTrayWindowHeaderTextColor
+ text: UserModel.currentUser ? UserModel.currentUser.name : ""
+ elide: Text.ElideRight
+
+ font.pixelSize: Style.topLinePixelSize
+ font.bold: false
+ palette.windowText: Style.nmcTrayWindowHeaderTextColor
}
+
EnforcedPlainTextLabel {
- id: message
- Layout.alignment: Qt.AlignLeft | Qt.AlignTop
- Layout.fillWidth: true
- visible: UserModel.currentUser && UserModel.currentUser.statusMessage !== ""
+ id: currentAccountServer
+ visible: false
+ Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+ width: Style.currentAccountLabelWidth
color: Style.currentUserHeaderTextColor
- text: UserModel.currentUser && UserModel.currentUser.statusMessage !== ""
- ? UserModel.currentUser.statusMessage
- : UserModel.currentUser ? UserModel.currentUser.server : ""
- font.pixelSize: Style.subLinePixelSize
+ text: UserModel.currentUser ? UserModel.currentUser.server : ""
elide: Text.ElideRight
}
- }
- }
- Loader {
- active: root.indicator === null
- sourceComponent: Image {
- Layout.alignment: Qt.AlignRight
- verticalAlignment: Qt.AlignCenter
- horizontalAlignment: Qt.AlignRight
- Layout.leftMargin: Style.accountDropDownCaretMargin
- source: "image://svgimage-custom-color/caret-down.svg/" + palette.windowText
- sourceSize.width: Style.accountDropDownCaretSize
- sourceSize.height: Style.accountDropDownCaretSize
- Accessible.role: Accessible.PopupMenu
- Accessible.name: qsTr("Account switcher and settings menu")
+ RowLayout {
+ id: currentUserStatus
+ visible: UserModel.currentUser && UserModel.currentUser.isConnected &&
+ UserModel.currentUser.serverHasUserStatus
+ spacing: Style.accountLabelsSpacing
+ width: parent.width
+
+ EnforcedPlainTextLabel {
+ id: emoji
+ visible: UserModel.currentUser && UserModel.currentUser.statusEmoji !== ""
+ width: Style.userStatusEmojiSize
+ color: Style.currentUserHeaderTextColor
+ text: UserModel.currentUser ? UserModel.currentUser.statusEmoji : ""
+ }
+ EnforcedPlainTextLabel {
+ id: message
+ Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+ Layout.fillWidth: true
+ visible: UserModel.currentUser && UserModel.currentUser.statusMessage !== ""
+ width: Style.currentAccountLabelWidth
+ color: Style.currentUserHeaderTextColor
+ text: UserModel.currentUser && UserModel.currentUser.statusMessage !== ""
+ ? UserModel.currentUser.statusMessage
+ : UserModel.currentUser ? UserModel.currentUser.server : ""
+ elide: Text.ElideRight
+ font.pixelSize: Style.subLinePixelSize
+ }
+ }
}
}
}
-}
+
+ Loader {
+ id: caretLoader
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: root.right
+ anchors.rightMargin: 12
+ active: root.indicator === null
+
+ sourceComponent: Image {
+ source: "image://svgimage-custom-color/caret-down.svg/" + Style.nmcTrayWindowHeaderTextColor
+ sourceSize.width: Style.accountDropDownCaretSize
+ sourceSize.height: Style.accountDropDownCaretSize
+
+ Accessible.role: Accessible.PopupMenu
+ Accessible.name: qsTr("Account switcher and settings menu")
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/gui/tray/MainWindow.qml b/src/gui/tray/MainWindow.qml
index e0c70e93c7a23..b6a80c13e8b28 100644
--- a/src/gui/tray/MainWindow.qml
+++ b/src/gui/tray/MainWindow.qml
@@ -13,6 +13,7 @@ import Qt.labs.platform as NativeDialogs
import "../"
import "../filedetails/"
+import "qrc:/qml/NMCGui"
// Custom qml modules are in /theme (and included by resources.qrc)
import Style
@@ -27,12 +28,12 @@ ApplicationWindow {
title: Systray.windowTitle
// If the main dialog is displayed as a regular window we want it to be quadratic
- width: Systray.useNormalWindow ? Style.trayWindowHeight : Style.trayWindowWidth
- height: Style.trayWindowHeight
+ width: Systray.useNormalWindow ? Style.nmcTrayWindowHeight : Style.nmcTrayWindowWidth
+ height: Style.nmcTrayWindowHeight
flags: Systray.useNormalWindow ? Qt.Window : Qt.Dialog | Qt.FramelessWindowHint
color: "transparent"
- readonly property int maxMenuHeight: Style.trayWindowHeight - Style.trayWindowHeaderHeight - 2 * Style.trayWindowBorderWidth
+ readonly property int maxMenuHeight: Style.nmcTrayWindowHeight - Style.trayWindowHeaderHeight - 2 * Style.trayWindowBorderWidth
Component.onCompleted: Systray.forceWindowInit(trayWindow)
@@ -48,9 +49,9 @@ ApplicationWindow {
onVisibleChanged: {
// HACK: reload account Instantiator immediately by restting it - could be done better I guess
- // see also id:trayWindowHeader.currentAccountHeaderButton.accountMenu below
- trayWindowHeader.currentAccountHeaderButton.userLineInstantiator.active = false;
- trayWindowHeader.currentAccountHeaderButton.userLineInstantiator.active = true;
+ // see also id:trayWindowHeader.accountHeaderButton.accountMenu below
+ trayWindowHeader.accountHeaderButton.userLineInstantiator.active = false;
+ trayWindowHeader.accountHeaderButton.userLineInstantiator.active = true;
syncStatus.model.load();
}
@@ -64,7 +65,7 @@ ApplicationWindow {
Connections {
target: UserModel
function onCurrentUserChanged() {
- trayWindowHeader.currentAccountHeaderButton.accountMenu.close();
+ trayWindowHeader.accountHeaderButton.accountMenu.close();
syncStatus.model.load();
}
}
@@ -90,10 +91,8 @@ ApplicationWindow {
fileDetailsDrawer.close();
if (Systray.isOpen) {
- trayWindowHeader.currentAccountHeaderButton.accountMenu.close();
- trayWindowHeader.appsMenu.close();
- trayWindowHeader.openLocalFolderButton.closeMenu()
- UserModel.refreshSyncErrorUsers()
+ trayWindowHeader.accountHeaderButton.accountMenu.close();
+ UserModel.refreshSyncErrorUsers();
}
}
@@ -258,18 +257,7 @@ ApplicationWindow {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
- height: Style.trayWindowHeaderHeight
-
- onFeaturedAppButtonClicked: {
- if (UserModel.currentUser.isAssistantEnabled) {
- trayWindowMainItem.showAssistantPanel = !trayWindowMainItem.showAssistantPanel
- if (trayWindowMainItem.showAssistantPanel) {
- assistantQuestionInput.forceActiveFocus()
- }
- } else {
- UserModel.openCurrentAccountFeaturedApp()
- }
- }
+ height: Style.nmcTrayWindowHeaderHeight
}
Button {
@@ -287,7 +275,6 @@ ApplicationWindow {
visible: UserModel.hasSyncErrors
&& !(UserModel.syncErrorUserCount === 1
&& UserModel.firstSyncErrorUserId === UserModel.currentUserId)
- && !trayWindowMainItem.isAssistantActive
padding: 0
background: Rectangle {
radius: Style.slightlyRoundedButtonRadius
@@ -342,10 +329,21 @@ ApplicationWindow {
}
}
+ Rectangle {
+ id: separator
+ height: 1
+ color: Style.nmcTrayWindowHeaderSeparatorColor
+
+ anchors {
+ top: trayWindowHeader.bottom
+ left: trayWindowMainItem.left
+ right: trayWindowMainItem.right
+ }
+ }
+
UnifiedSearchInputContainer {
id: trayWindowUnifiedSearchInputContainer
- visible: !trayWindowMainItem.showAssistantPanel
-
+ visible: false
property bool activateSearchFocus: activeFocus
anchors.top: trayWindowSyncWarning.visible
@@ -677,7 +675,7 @@ ApplicationWindow {
Rectangle {
id: bottomUnifiedSearchInputSeparator
- anchors.top: trayWindowMainItem.showAssistantPanel ? assistantInputContainer.bottom : trayWindowUnifiedSearchInputContainer.bottom
+ anchors.top: trayWindowUnifiedSearchInputContainer.visible ? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: Style.trayHorizontalMargin
@@ -691,7 +689,7 @@ ApplicationWindow {
id: unifiedSearchResultsErrorLabel
visible: UserModel.currentUser.unifiedSearchResultsListModel.errorString && !unifiedSearchResultsListView.visible && ! UserModel.currentUser.unifiedSearchResultsListModel.isSearchInProgress && ! UserModel.currentUser.unifiedSearchResultsListModel.currentFetchMoreInProgressProviderId
text: UserModel.currentUser.unifiedSearchResultsListModel.errorString
- anchors.top: bottomUnifiedSearchInputSeparator.bottom
+ anchors.top: trayWindowUnifiedSearchInputContainer.visible ? bottomUnifiedSearchInputSeparator.bottom : separator.bottom
anchors.left: trayWindowMainItem.left
anchors.right: trayWindowMainItem.right
anchors.margins: Style.trayHorizontalMargin
@@ -700,7 +698,7 @@ ApplicationWindow {
UnifiedSearchPlaceholderView {
id: unifiedSearchPlaceholderView
- anchors.top: bottomUnifiedSearchInputSeparator.bottom
+ anchors.top: trayWindowUnifiedSearchInputContainer.visible ? bottomUnifiedSearchInputSeparator.bottom : separator.bottom
anchors.left: trayWindowMainItem.left
anchors.right: trayWindowMainItem.right
anchors.bottom: trayWindowMainItem.bottom
@@ -712,7 +710,7 @@ ApplicationWindow {
UnifiedSearchResultNothingFound {
id: unifiedSearchResultNothingFound
- anchors.top: bottomUnifiedSearchInputSeparator.bottom
+ anchors.top: trayWindowUnifiedSearchInputContainer.visible ? bottomUnifiedSearchInputSeparator.bottom : separator.bottom
anchors.left: trayWindowMainItem.left
anchors.right: trayWindowMainItem.right
anchors.topMargin: Style.trayHorizontalMargin
@@ -730,7 +728,7 @@ ApplicationWindow {
Loader {
id: unifiedSearchResultsListViewSkeletonLoader
- anchors.top: bottomUnifiedSearchInputSeparator.bottom
+ anchors.top: trayWindowUnifiedSearchInputContainer.visible ? bottomUnifiedSearchInputSeparator.bottom : separator.bottom
anchors.left: trayWindowMainItem.left
anchors.right: trayWindowMainItem.right
anchors.bottom: trayWindowMainItem.bottom
@@ -759,7 +757,7 @@ ApplicationWindow {
}
visible: unifiedSearchResultsListView.count > 0
- anchors.top: bottomUnifiedSearchInputSeparator.bottom
+ anchors.top: trayWindowUnifiedSearchInputContainer.visible ? bottomUnifiedSearchInputSeparator.bottom : separator.bottom
anchors.left: trayWindowMainItem.left
anchors.right: trayWindowMainItem.right
anchors.bottom: trayWindowMainItem.bottom
@@ -802,7 +800,7 @@ ApplicationWindow {
accentColor: Style.accentColor
visible: !trayWindowMainItem.isUnifiedSearchActive && !trayWindowMainItem.showAssistantPanel
- anchors.top: trayWindowMainItem.showAssistantPanel ? assistantInputContainer.bottom : trayWindowUnifiedSearchInputContainer.bottom
+ anchors.top: trayWindowUnifiedSearchInputContainer.visible ? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom
anchors.left: trayWindowMainItem.left
anchors.right: trayWindowMainItem.right
}
@@ -894,4 +892,4 @@ ApplicationWindow {
}
}
} // Item trayWindowMainItem
-}
+}
\ No newline at end of file
diff --git a/src/gui/tray/NCProgressBar.qml b/src/gui/tray/NCProgressBar.qml
index 839073da4b084..21cd9a7dffdc6 100644
--- a/src/gui/tray/NCProgressBar.qml
+++ b/src/gui/tray/NCProgressBar.qml
@@ -16,10 +16,10 @@ BasicControls.ProgressBar {
background: Rectangle {
implicitWidth: Style.progressBarWidth
implicitHeight: Style.progressBarBackgroundHeight
- radius: Style.progressBarRadius
- color: palette.base
+ radius: Style.nmcStandardRadius
+ color: Style.nmcTrayWindowHeaderHighlightColor
border.color: palette.dark
- border.width: Style.progressBarBackgroundBorderWidth
+ border.width: 0
}
contentItem: Item {
@@ -30,9 +30,9 @@ BasicControls.ProgressBar {
width: control.visualPosition * parent.width
height: parent.height
radius: Style.progressBarRadius
- color: control.fillColor
+ color: Style.nmcTelekomMagentaColor
border.color: palette.dark
- border.width: Style.progressBarContentBorderWidth
+ border.width: 0
}
}
}
diff --git a/src/gui/tray/SyncStatus.qml b/src/gui/tray/SyncStatus.qml
index 8827d8a842991..486dc27523045 100644
--- a/src/gui/tray/SyncStatus.qml
+++ b/src/gui/tray/SyncStatus.qml
@@ -18,6 +18,8 @@ RowLayout {
property color accentColor: Style.ncBlue
spacing: Style.trayHorizontalMargin
+ Layout.alignment: Qt.AlignVCenter
+ Layout.preferredHeight: Style.nmcTraySyncButtonHeight + 8
NC.SyncStatusSummary {
id: syncStatus
@@ -31,11 +33,11 @@ RowLayout {
Layout.preferredWidth: size
Layout.preferredHeight: size
- Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.alignment: Qt.AlignVCenter
Layout.topMargin: Style.trayHorizontalMargin
Layout.rightMargin: whiteSpace * (0.5 + Style.thumbnailImageSizeReduction)
Layout.bottomMargin: Style.trayHorizontalMargin
- Layout.leftMargin: Style.trayHorizontalMargin + (whiteSpace * (0.5 - Style.thumbnailImageSizeReduction))
+ Layout.leftMargin: Style.nmcListViewLeftPadding
padding: 0
@@ -50,6 +52,7 @@ RowLayout {
Layout.topMargin: 8
Layout.rightMargin: Style.trayHorizontalMargin
Layout.bottomMargin: 8
+ Layout.leftMargin: Style.nmcProgressFieldTextOffset
Layout.fillWidth: true
Layout.fillHeight: true
@@ -60,7 +63,7 @@ RowLayout {
text: syncStatus.syncStatusString
verticalAlignment: Text.AlignVCenter
- font.pixelSize: Style.topLinePixelSize
+ font.pixelSize: Style.nmcFontSizeSyncText
font.bold: true
wrapMode: Text.Wrap
}
@@ -85,7 +88,7 @@ RowLayout {
Layout.fillWidth: true
text: syncStatus.syncStatusDetailString
- visible: syncStatus.syncStatusDetailString !== ""
+ visible: false
font.pixelSize: Style.subLinePixelSize
wrapMode: Text.Wrap
}
@@ -94,6 +97,7 @@ RowLayout {
Button {
id: syncNowButton
+ Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: Style.trayHorizontalMargin
text: qsTr("Sync now")
@@ -107,6 +111,27 @@ RowLayout {
(Qt.platform.os === "osx" && NC.UserModel.currentUser.hasFileProvider)) &&
NC.UserModel.currentUser.isConnected
enabled: visible
+
+ HoverHandler {
+ id: mouseSync
+ acceptedDevices: PointerDevice.AllPointerTypes
+ }
+
+ background: Rectangle {
+ color: mouseSync.hovered ? Style.nmcSyncHoverColor : Style.nmcTelekomMagentaColor
+ radius: Style.nmcStandardRadius
+ height: Style.nmcTraySyncButtonHeight
+ }
+
+ contentItem: Text {
+ text: syncNowButton.text
+ color: "white"
+ font.pixelSize: Style.nmcFontSizeAccountName
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
onClicked: {
if(!syncStatus.syncing) {
NC.UserModel.currentUser.forceSyncNow();
@@ -115,8 +140,11 @@ RowLayout {
}
Button {
+ Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: Style.trayHorizontalMargin
+ padding: Style.smallSpacing
+
text: qsTr("Resolve conflicts")
visible: activityModel.hasSyncConflicts &&
@@ -124,10 +152,34 @@ RowLayout {
NC.UserModel.currentUser.hasLocalFolder &&
NC.UserModel.currentUser.isConnected
enabled: visible
+
+ HoverHandler {
+ id: mouseConflict
+ acceptedDevices: PointerDevice.Mouse
+ }
+
+ contentItem: Text {
+ text: parent.text
+ color: Style.nmcTextInButtonColor
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent
+ }
+
+ background: Rectangle {
+ color: mouseConflict.hovered
+ ? Style.nmcConflictHoverColor
+ : Style.nmcConflictColor
+ radius: Style.nmcStandardRadius
+ height: Style.nmcTraySyncButtonHeight
+ width: parent.width
+ }
+
onClicked: NC.Systray.createResolveConflictsDialog(activityModel.allConflicts);
}
Button {
+ Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: Style.trayHorizontalMargin
text: qsTr("Open browser")
diff --git a/src/gui/tray/TrayWindowHeader.qml b/src/gui/tray/TrayWindowHeader.qml
index a7a6aad89cbc3..45c811c789c8e 100644
--- a/src/gui/tray/TrayWindowHeader.qml
+++ b/src/gui/tray/TrayWindowHeader.qml
@@ -9,6 +9,7 @@ import QtQuick.Layouts
import "../"
import "../filedetails/"
+import "qrc:/qml/NMCGui"
import Style
import com.nextcloud.desktopclient
@@ -18,11 +19,10 @@ Rectangle {
signal featuredAppButtonClicked
- readonly property alias currentAccountHeaderButton: currentAccountHeaderButton
- readonly property alias openLocalFolderButton: openLocalFolderButton
- readonly property alias appsMenu: appsMenu
+ readonly property alias accountHeaderButton: currentAccountHeaderButton
- color: Style.currentUserHeaderColor
+ color: Style.nmcTrayWindowHeaderBackgroundColor
+ height: Style.nmcTrayWindowHeaderHeight
palette {
text: Style.currentUserHeaderTextColor
@@ -31,11 +31,54 @@ Rectangle {
button: Style.adjustedCurrentUserHeaderColor
}
+ Rectangle {
+ id: whiteMargin
+ width: 10
+ height: Style.nmcTrayWindowHeaderHeight
+ color: Style.nmcTrayWindowHeaderBackgroundColor
+
+ anchors {
+ top: parent.top
+ left: parent.left
+ }
+ }
+
+ Rectangle {
+ id: tLogo
+ width: Style.nmcTrayWindowLogoWidth
+ height: Style.nmcTrayWindowHeaderHeight
+
+ anchors {
+ top: parent.top
+ left: whiteMargin.right
+ }
+
+ Image {
+ anchors.fill: parent
+ source: Style.nmcTLogoPath
+ fillMode: Image.Stretch
+ cache: false
+ }
+ }
+
RowLayout {
id: trayWindowHeaderLayout
spacing: 0
- anchors.fill: parent
+ height: Style.nmcTrayWindowHeaderHeight
+
+ anchors {
+ top: parent.top
+ left: tLogo.right
+ right: parent.right
+ }
+
+ Rectangle {
+ id: whiteMarginLeft1
+ Layout.preferredWidth: 10
+ Layout.fillHeight: true
+ color: Style.nmcTrayWindowHeaderBackgroundColor
+ }
CurrentAccountHeaderButton {
id: currentAccountHeaderButton
@@ -49,101 +92,69 @@ Rectangle {
Layout.fillWidth: true
}
- TrayFoldersMenuButton {
- id: openLocalFolderButton
-
- Layout.alignment: Qt.AlignRight
- Layout.preferredWidth: Style.trayWindowHeaderHeight
+ Rectangle {
+ id: trayWindowWebsiteButtonContainer
+ Layout.preferredWidth: 92
Layout.fillHeight: true
-
- visible: currentUser.hasLocalFolder || (Qt.platform.os === "osx" && currentUser.hasFileProvider)
- currentUser: UserModel.currentUser
- parentBackgroundColor: root.color
-
- onClicked: {
- if (openLocalFolderButton.userHasGroupFolders) {
- openLocalFolderButton.toggleMenuOpen()
- } else if (currentUser.hasLocalFolder) {
- UserModel.openCurrentAccountLocalFolder()
- } else if (Qt.platform.os === "osx") {
- UserModel.openCurrentAccountFileProviderDomain()
+ color: websiteHover.hovered ? Style.nmcTrayWindowHeaderHighlightColor : "transparent"
+
+ NMCHeaderButton {
+ id: trayWindowWebsiteButton
+ iconSource: Style.darkMode
+ ? "qrc:///client/theme/NMCIcons/website-white.svg"
+ : "qrc:///client/theme/NMCIcons/website.svg"
+ iconText: qsTranslate("", "OPEN_WEBSITE")
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: UserModel.openCurrentAccountServer()
}
}
- onFolderEntryTriggered: isGroupFolder ? UserModel.openCurrentAccountFolderFromTrayInfo(fullFolderPath) : UserModel.openCurrentAccountLocalFolder()
-
- Accessible.role: Accessible.Graphic
- Accessible.name: qsTr("Open local or team folders")
- Accessible.onPressAction: {
- if (openLocalFolderButton.userHasGroupFolders) {
- openLocalFolderButton.toggleMenuOpen()
- } else if (currentUser.hasLocalFolder) {
- UserModel.openCurrentAccountLocalFolder()
- } else if (Qt.platform.os === "osx") {
- UserModel.openCurrentAccountFileProviderDomain()
- }
+ HoverHandler {
+ id: websiteHover
+ acceptedDevices: PointerDevice.Mouse
}
}
- HeaderButton {
- id: trayWindowFeaturedAppButton
-
- Layout.alignment: Qt.AlignRight
- Layout.preferredWidth: Style.trayWindowHeaderHeight
+ Rectangle {
+ id: whiteMarginRight1
+ Layout.preferredWidth: 10
Layout.fillHeight: true
- visible: UserModel.currentUser.isAssistantEnabled
- icon.source: UserModel.currentUser.featuredAppIcon + "/" + palette.windowText
- onClicked: root.featuredAppButtonClicked()
-
- Accessible.role: Accessible.Button
- Accessible.name: UserModel.currentUser.featuredAppAccessibleName
- Accessible.onPressAction: trayWindowFeaturedAppButton.clicked()
+ color: Style.nmcTrayWindowHeaderBackgroundColor
}
- HeaderButton {
- id: trayWindowAppsButton
- icon.source: "image://svgimage-custom-color/more-apps.svg/" + palette.windowText
-
- onClicked: {
- if(appsMenu.count <= 0) {
- UserModel.openCurrentAccountServer()
- } else if (appsMenu.visible) {
- appsMenu.close()
- } else {
- appsMenu.open()
+ Rectangle {
+ id: trayWindowLocalButtonContainer
+ Layout.preferredWidth: 92
+ Layout.fillHeight: true
+ color: localHover.hovered ? Style.nmcTrayWindowHeaderHighlightColor : "transparent"
+
+ NMCHeaderButton {
+ id: trayWindowLocalButton
+ iconSource: Style.darkMode
+ ? "qrc:///client/theme/white/folder.svg"
+ : "qrc:///client/theme/black/folder.svg"
+ iconText: qsTranslate("", "LOCAL_FOLDER")
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: UserModel.openCurrentAccountLocalFolder()
}
}
- Accessible.role: Accessible.ButtonMenu
- Accessible.name: qsTr("More apps")
- Accessible.onPressAction: trayWindowAppsButton.clicked()
-
- Menu {
- id: appsMenu
- x: Style.trayWindowMenuOffsetX
- y: (trayWindowAppsButton.y + trayWindowAppsButton.height + Style.trayWindowMenuOffsetY)
- width: Style.trayWindowWidth * Style.trayWindowMenuWidthFactor
- height: implicitHeight + y > Style.trayWindowHeight ? Style.trayWindowHeight - y : implicitHeight
- closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape
-
- Repeater {
- model: UserAppsModel
- delegate: MenuItem {
- id: appEntry
- // HACK: Without creating our own component (and killing native styling)
- // HACK: we do not have a way to adjust the text and icon spacing.
- text: " " + model.appName
- font.pixelSize: Style.topLinePixelSize
- icon.source: "image://tray-image-provider/" + model.appIconUrl
- icon.color: palette.windowText
- onTriggered: UserAppsModel.openAppUrl(appUrl)
- Accessible.role: Accessible.MenuItem
- Accessible.name: qsTr("Open %1 in browser").arg(model.appName)
- Accessible.onPressAction: appEntry.triggered()
- }
- }
+ HoverHandler {
+ id: localHover
+ acceptedDevices: PointerDevice.Mouse
}
}
+
+ Rectangle {
+ id: whiteMarginRight2
+ Layout.preferredWidth: 10
+ Layout.fillHeight: true
+ color: Style.nmcTrayWindowHeaderBackgroundColor
+ }
}
}
diff --git a/src/gui/tray/UnifiedSearchInputContainer.qml b/src/gui/tray/UnifiedSearchInputContainer.qml
index 4fd6ac4f1d927..535026ca9daeb 100644
--- a/src/gui/tray/UnifiedSearchInputContainer.qml
+++ b/src/gui/tray/UnifiedSearchInputContainer.qml
@@ -28,7 +28,7 @@ TextField {
topPadding: topInset
bottomPadding: bottomInset
leftPadding: iconInset + leadingControlWidth + Style.smallSpacing
- rightPadding: iconInset + trailingControlWidth + Style.smallSpacing
+ rightPadding: clearTextButton.width + iconInset + Style.smallSpacing
verticalAlignment: Qt.AlignVCenter
placeholderText: qsTr("Search files, messages, events …")
diff --git a/src/gui/tray/UserLine.qml b/src/gui/tray/UserLine.qml
index 2491fd3c5be79..b643b96fda956 100644
--- a/src/gui/tray/UserLine.qml
+++ b/src/gui/tray/UserLine.qml
@@ -7,6 +7,7 @@ import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
+import "qrc:/qml/NMCGui"
// Custom qml modules are in /theme (and included by resources.qrc)
import Style
@@ -23,14 +24,15 @@ AbstractButton {
Accessible.role: Accessible.MenuItem
Accessible.name: qsTr("Switch to account") + " " + model.name
- height: Style.trayWindowHeaderHeight
+ height: Style.nmcMenuSubItemHeight
contentItem: RowLayout {
id: userLineLayout
- spacing: Style.userLineSpacing
+ spacing: 8
Image {
id: accountAvatar
+ visible: false
Layout.leftMargin: Style.accountIconsMenuMargin
verticalAlignment: Qt.AlignCenter
cache: false
@@ -68,21 +70,34 @@ AbstractButton {
}
}
- ColumnLayout {
+ RowLayout {
id: accountLabels
Layout.fillWidth: true
Layout.fillHeight: true
- spacing: Style.extraExtraSmallSpacing
+ Layout.alignment: Qt.AlignVCenter
+ spacing: 8
+
+ Item { width: Style.nmcMenuSubItemLeftPadding }
+
+ Image {
+ id: accountIcon
+ source: Style.nmcAccountAvatarIcon
+ visible: true
+ width: Style.nmcTrayWindowIconWidth
+ height: Style.nmcTrayWindowIconWidth
+ fillMode: Image.PreserveAspectFit
+ Layout.alignment: Qt.AlignVCenter
+ }
EnforcedPlainTextLabel {
id: accountUser
Layout.fillWidth: true
- Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
- verticalAlignment: Text.AlignBottom
+ Layout.alignment: Qt.AlignVCenter
+ verticalAlignment: Text.AlignVCenter
text: name
elide: Text.ElideRight
font.pixelSize: Style.topLinePixelSize
- font.bold: true
+ font.bold: false
color: !userLine.parent.enabled
? userLine.parent.palette.mid
@@ -99,6 +114,7 @@ AbstractButton {
text: server
elide: Text.ElideRight
font.pixelSize: Style.subLinePixelSize
+ visible: false
color: !userLine.parent.enabled
? userLine.parent.palette.mid
@@ -110,7 +126,7 @@ AbstractButton {
RowLayout {
id: statusLayout
Layout.fillWidth: true
- height: visible ? implicitHeight : 0
+ Layout.preferredHeight: visible ? implicitHeight : 0
visible: model.isConnected &&
model.serverHasUserStatus &&
(model.statusEmoji !== "" || model.statusMessage !== "")
@@ -169,9 +185,12 @@ AbstractButton {
Button {
id: userMoreButton
- Layout.preferredWidth: Style.headerButtonIconSize
+ Layout.preferredWidth: Style.iconButtonWidth
Layout.fillHeight: true
+ Layout.rightMargin: Style.accountIconsMenuMargin
flat: true
+ visible: true
+ opacity: 1
Accessible.role: Accessible.ButtonMenu
Accessible.name: qsTr("Account actions")
@@ -179,12 +198,9 @@ AbstractButton {
onClicked: userMoreButtonMenu.visible ? userMoreButtonMenu.close() : userMoreButtonMenu.popup()
- property var iconColor: !userLine.parent.enabled
- ? userLine.parent.palette.mid
- : (!hovered && ((userLine.parent.highlighted || userLine.parent.down) && Qt.platform.os !== "windows")
- ? userLine.parent.palette.highlightedText
- : userLine.parent.palette.text)
- icon.source: "image://svgimage-custom-color/more.svg/" + iconColor
+ icon.source: Style.darkMode
+ ? "qrc:///client/theme/more-white.svg"
+ : "qrc:///client/theme/more.svg"
AutoSizingMenu {
id: userMoreButtonMenu
@@ -193,10 +209,12 @@ AbstractButton {
MenuItem {
id: setStatusButton
+ visible: false
enabled: model.isConnected && model.serverHasUserStatus
text: qsTr("Set status")
font.pixelSize: Style.topLinePixelSize
hoverEnabled: true
+ height: visible ? implicitHeight : 0
onClicked: showUserStatusSelector(index)
@@ -207,10 +225,12 @@ AbstractButton {
MenuItem {
id: statusMessageButton
+ visible: false
enabled: model.isConnected && model.serverHasUserStatus
text: qsTr("Status message")
font.pixelSize: Style.topLinePixelSize
hoverEnabled: true
+ height: visible ? implicitHeight : 0
onClicked: showUserStatusMessageSelector(index)
@@ -219,13 +239,15 @@ AbstractButton {
Accessible.onPressAction: statusMessageButton.clicked()
}
- MenuItem {
+ NMCMenuItem {
id: logInOutButton
enabled: model.canLogout
text: model.isConnected ? qsTr("Log out") : qsTr("Log in")
- width: parent.width
- font.pixelSize: Style.topLinePixelSize
- hoverEnabled: true
+ height: Style.nmcMenuSubItemHeight
+ icon.source: Style.nmcLogOutIcon
+ icon.height: Style.nmcTrayWindowIconWidth
+ icon.width: Style.nmcTrayWindowIconWidth
+ leftPadding: Style.nmcMenuSubItemLeftPadding
onClicked: {
if (model.isConnected) {
@@ -238,14 +260,18 @@ AbstractButton {
Accessible.role: Accessible.Button
Accessible.name: text
- Accessible.onPressAction: logInOutButton.clicked()
+ Accessible.onPressAction: clicked()
}
- MenuItem {
+ NMCMenuItem {
id: removeAccountButton
text: model.removeAccountText
- font.pixelSize: Style.topLinePixelSize
- hoverEnabled: true
+ height: Style.nmcMenuSubItemHeight
+ icon.source: Style.nmcRemoveIcon
+ icon.height: Style.nmcTrayWindowIconWidth
+ icon.width: Style.nmcTrayWindowIconWidth
+ leftPadding: Style.nmcMenuSubItemLeftPadding
+
onClicked: {
UserModel.removeAccount(index)
accountMenu.close()
@@ -253,7 +279,7 @@ AbstractButton {
Accessible.role: Accessible.Button
Accessible.name: text
- Accessible.onPressAction: removeAccountButton.clicked()
+ Accessible.onPressAction: clicked()
}
}
}
diff --git a/src/gui/tray/asyncimageresponse.cpp b/src/gui/tray/asyncimageresponse.cpp
index 875a2d16eb755..d6603173676b2 100644
--- a/src/gui/tray/asyncimageresponse.cpp
+++ b/src/gui/tray/asyncimageresponse.cpp
@@ -137,6 +137,7 @@ void AsyncImageResponse::processNetworkReply(QNetworkReply *reply)
scaledSvg.fill("transparent");
QPainter painterForSvg(&scaledSvg);
svgRenderer.render(&painterForSvg);
+ painterForSvg.end();
if (!_svgRecolor.isValid()) {
setImageAndEmitFinished(scaledSvg);
@@ -145,9 +146,12 @@ void AsyncImageResponse::processNetworkReply(QNetworkReply *reply)
QImage image(_requestedImageSize, QImage::Format_ARGB32);
image.fill(_svgRecolor);
+
QPainter imagePainter(&image);
imagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
imagePainter.drawImage(0, 0, scaledSvg);
+ imagePainter.end();
+
setImageAndEmitFinished(image);
}
diff --git a/theme.qrc.in b/theme.qrc.in
index 8ebb6e3d7b590..8f88cfc526498 100644
--- a/theme.qrc.in
+++ b/theme.qrc.in
@@ -295,5 +295,13 @@
theme/file-open.svg
theme/backup.svg
theme/convert_to_text.svg
+ theme/NMCIcons/accountAvatarIcon-white.svg
+ theme/NMCIcons/logout-white.svg
+ theme/NMCIcons/pause-white.svg
+ theme/NMCIcons/remove-white.svg
+ theme/NMCIcons/website-white.svg
+ theme/close-white.svg
+ theme/more-white.svg
+ theme/settings-white.svg
diff --git a/theme/NMCIcons/accountAvatarIcon-white.svg b/theme/NMCIcons/accountAvatarIcon-white.svg
new file mode 100644
index 0000000000000..1071c83ea6ef8
--- /dev/null
+++ b/theme/NMCIcons/accountAvatarIcon-white.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/theme/NMCIcons/logout-white.svg b/theme/NMCIcons/logout-white.svg
new file mode 100644
index 0000000000000..f449764e1a279
--- /dev/null
+++ b/theme/NMCIcons/logout-white.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/theme/NMCIcons/pause-white.svg b/theme/NMCIcons/pause-white.svg
new file mode 100644
index 0000000000000..41fd92da98393
--- /dev/null
+++ b/theme/NMCIcons/pause-white.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/theme/NMCIcons/remove-white.svg b/theme/NMCIcons/remove-white.svg
new file mode 100644
index 0000000000000..9a71790bcff30
--- /dev/null
+++ b/theme/NMCIcons/remove-white.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/theme/NMCIcons/website-white.svg b/theme/NMCIcons/website-white.svg
new file mode 100644
index 0000000000000..4db891a1afe17
--- /dev/null
+++ b/theme/NMCIcons/website-white.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml
index 07d80f19e53f7..26398df3c1b32 100644
--- a/theme/Style/Style.qml
+++ b/theme/Style/Style.qml
@@ -7,6 +7,52 @@ import QtQuick
import com.nextcloud.desktopclient
QtObject {
+ // NMC customization
+ readonly property int nmcFontSizeAccountName: 13
+ readonly property int nmcFontSizeIconText: 10
+ readonly property int nmcFontSizeSyncText: 15
+
+ // NMC icons
+ readonly property url nmcTLogoPath: "qrc:///client/theme/NMCIcons/tlogocarrier.svg"
+ readonly property url nmcAccountAvatarIcon: Theme.darkMode ? "qrc:///client/theme/NMCIcons/accountAvatarIcon-white.svg" : "qrc:///client/theme/NMCIcons/accountAvatarIcon.svg"
+ readonly property url nmcSettingsIcon: Theme.darkMode ? "qrc:///client/theme/settings-white.svg" : "qrc:///client/theme/settings.svg"
+ readonly property url nmcCloseIcon: Theme.darkMode ? "qrc:///client/theme/close-white.svg" : "qrc:///client/theme/close.svg"
+ readonly property url nmcPauseIcon: Theme.darkMode ? "qrc:///client/theme/NMCIcons/pause-white.svg" : "qrc:///client/theme/NMCIcons/pause.svg"
+ readonly property url nmcLogOutIcon: Theme.darkMode ? "qrc:///client/theme/NMCIcons/logout-white.svg" : "qrc:///client/theme/NMCIcons/logout.svg"
+ readonly property url nmcRemoveIcon: Theme.darkMode ? "qrc:///client/theme/NMCIcons/remove-white.svg" : "qrc:///client/theme/NMCIcons/remove.svg"
+
+ // NMC colors
+ readonly property color nmcTelekomMagentaColor: "#E20074"
+ readonly property color nmcConflictColor: Theme.darkMode ? "#FFA14A" : "#F97012"
+ readonly property color nmcConflictHoverColor: Theme.darkMode ? "#f0802e" : "#de6310"
+ readonly property color nmcSyncHoverColor: Theme.darkMode ? "#ff4d94" : "#c00063"
+ readonly property color nmcSyncRefreshColor: Theme.darkMode ? "#6677ff" : "#2238df"
+ readonly property color nmcTrayWindowHeaderBackgroundColor: Theme.darkMode ? "#2b2b2b" : "white"
+ readonly property color nmcTrayWindowHeaderTextColor: Theme.darkMode ? "white" : "black"
+ readonly property color nmcTrayWindowHeaderSeparatorColor: Theme.darkMode ? "#3c3c3c" : "#ededed"
+ readonly property color nmcTrayWindowHeaderHighlightColor: Theme.darkMode ? "#444444" : "#ededed"
+ readonly property color nmcMenuMoreItemsColor: Theme.darkMode ? "#3a3a3a" : "#E5E5E5"
+ readonly property color nmcTextInButtonColor: Theme.darkMode ? "black" : "white"
+
+ // NMC measurements
+ readonly property int nmcTrayWindowWidth: variableSize(480)
+ readonly property int nmcTrayWindowHeight: variableSize(520)
+ readonly property int nmcTrayWindowAddAccountButtonHeight: 56
+ readonly property int nmcTrayWindowHeaderHeight: 64
+ readonly property int nmcTrayWindowItemsHeight: 48
+ readonly property int nmcTrayWindowIconWidth: 20
+ readonly property int nmcTrayWindowLogoWidth: 64
+ readonly property int nmcTrayWindowStandardMargin: 16
+ readonly property int nmcTrayWindowMenuOverlayMargin: 8
+ readonly property int nmcTraySyncButtonHeight: 28
+ readonly property int nmcCurrentAccountButtonWidth: 180
+ readonly property int nmcMenuSubItemHeight: 42
+ readonly property int nmcMenuSubItemLeftPadding: 16
+ readonly property int nmcStandardRadius: 4
+ readonly property int nmcListViewLeftPadding: 22
+ readonly property int nmcListViewIconSize: 32
+ readonly property int nmcProgressFieldTextOffset: -12
+
readonly property int pixelSize: fontMetrics.font.pixelSize
readonly property bool darkMode: Theme.darkMode
@@ -93,7 +139,7 @@ QtObject {
property int folderStateIndicatorSize: 16
property int accountLabelWidth: 128
- property int accountDropDownCaretSize: 10
+ property int accountDropDownCaretSize: 18
property int accountDropDownCaretMargin: 8
property int trayFoldersMenuButtonStateIndicatorBottomOffset: 5
@@ -106,7 +152,7 @@ QtObject {
property int headerButtonIconSize: 48
property int minimumActivityItemHeight: 24
- property int accountIconsMenuMargin: 7
+ property int accountIconsMenuMargin: 4
property int activityLabelBaseWidth: 240
@@ -129,7 +175,7 @@ QtObject {
property int accountServerAnchorsMargin: 10
property int accountLabelsSpacing: 4
property int accountsServerMargin: 6
- property int accountLabelsAnchorsMargin: 5
+ property int accountLabelsAnchorsMargin: 4
property int accountLabelsLayoutMargin: 12
property int accountLabelsLayoutTopMargin: 10
diff --git a/theme/black/folder.svg b/theme/black/folder.svg
index 265162634208a..b4ca23cca78ac 100644
--- a/theme/black/folder.svg
+++ b/theme/black/folder.svg
@@ -1,7 +1,13 @@
-
-
-