diff --git a/.gitignore b/.gitignore index 85a87ed91464..ceea196245ae 100644 --- a/.gitignore +++ b/.gitignore @@ -190,3 +190,6 @@ convert.exe *-w10startmenu.png *state-*.png theme.qrc + +# Ignore specific folders +shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 687733588813..8c291b9c4594 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,9 @@ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES) set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +set(NMC_RCC_FILE "nmctheme_v1.rcc") +configure_file(${CMAKE_SOURCE_DIR}/${NMC_RCC_FILE} "${BIN_OUTPUT_DIRECTORY}/${NMC_RCC_FILE}" COPYONLY) + include(${CMAKE_SOURCE_DIR}/NEXTCLOUD.cmake) # CfAPI Shell Extensions @@ -303,6 +306,7 @@ configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h) if(BUILD_OWNCLOUD_OSX_BUNDLE) install(FILES sync-exclude.lst DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/) configure_file(sync-exclude.lst bin/${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/sync-exclude.lst COPYONLY) + install(FILES nmctheme_v1.rcc DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/) elseif(BUILD_CLIENT) install( FILES sync-exclude.lst DESTINATION ${SYSCONFDIR}/${APPLICATION_SHORTNAME} ) configure_file(sync-exclude.lst bin/sync-exclude.lst COPYONLY) diff --git a/nmctheme_v1.rcc b/nmctheme_v1.rcc new file mode 100644 index 000000000000..1e673f886e4f Binary files /dev/null and b/nmctheme_v1.rcc differ diff --git a/resources.qrc b/resources.qrc index 7222e8c9ff0e..4f7a17ee7b12 100644 --- a/resources.qrc +++ b/resources.qrc @@ -1,5 +1,7 @@ + src/gui/nmcgui/NMCHeaderButton.qml + src/gui/nmcgui/NMCMenuItem.qml src/gui/UserStatusSelector.qml src/gui/UserStatusSelectorPage.qml src/gui/EmojiPicker.qml diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 6e4acf203d19..43e6550abf67 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -3,6 +3,9 @@ find_package(Qt5 REQUIRED COMPONENTS Widgets Svg Qml Quick QuickControls2 QuickW find_package(KF5Archive REQUIRED) find_package(KF5GuiAddons) +#NMC change, its needed to find the ui file in a different location than the header file +set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_SOURCE_DIR}/src/gui") + if(QUICK_COMPILER) find_package(Qt5QuickCompiler) set_package_properties(Qt5QuickCompiler PROPERTIES @@ -261,6 +264,10 @@ set(client_SRCS wizard/linklabel.cpp ) +file(GLOB NMC_FILES "nmcgui/*") +set(NMC_SRCS ${NMC_FILES}) +list(APPEND client_SRCS ${NMC_SRCS}) + if (Qt5WebEngine_FOUND AND Qt5WebEngineWidgets_FOUND) list(APPEND client_SRCS wizard/webviewpage.h @@ -623,6 +630,7 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) install(FILES ${VISUAL_ELEMENTS} DESTINATION bin/visualelements) install(FILES "${theme_dir}/${APPLICATION_EXECUTABLE}.VisualElementsManifest.xml" DESTINATION bin) install(FILES ${client_I18N} DESTINATION i18n) + install(FILES ${CMAKE_SOURCE_DIR}/nmctheme_v1.rcc DESTINATION bin) endif() # we may not add MACOSX_BUNDLE here, if not building one diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 6742a8b1a0e5..6bf132bd1225 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -58,6 +58,18 @@ int main(int argc, char **argv) #ifdef Q_OS_WIN SetDllDirectory(L""); #endif + + bool resourceLoaded = false; + const QString currentPath = QDir::currentPath(); + if(Utility::isMac()) + { + resourceLoaded = QResource::registerResource(QDir::toNativeSeparators("/Applications/MagentaCLOUD.app/Contents/Resources/nmctheme_v1.rcc")); + } + else if(Utility::isWindows() || !resourceLoaded) + { + resourceLoaded = QResource::registerResource(QDir::toNativeSeparators(currentPath + "/nmctheme_v1.rcc")); + } + Q_INIT_RESOURCE(resources); Q_INIT_RESOURCE(theme); diff --git a/src/gui/nmcgui/NMCHeaderButton.qml b/src/gui/nmcgui/NMCHeaderButton.qml new file mode 100644 index 000000000000..38b88dada091 --- /dev/null +++ b/src/gui/nmcgui/NMCHeaderButton.qml @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 by Eugen Fischer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +import QtQml 2.15 +import QtQml.Models 2.15 +import QtQuick 2.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtGraphicalEffects 1.15 + +// Custom qml modules are in /theme (and included by resources.qrc) +import Style 1.0 +import com.nextcloud.desktopclient 1.0 + +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 + icon.source: rec.iconSource + icon.width: Style.nmcTrayWindowIconWidth + icon.height: Style.nmcTrayWindowIconWidth + + onClicked: { + rec.clickedButton() + } + + background: Rectangle { + color: iconHovered || button.visualFocus ? "black" : "transparent" + opacity: 0.05 + } + Layout.alignment: Qt.AlignHCenter + } + + Text { + width: rec.width + text: rec.iconText + elide: Text.ElideRight + color: Style.nmcTrayWindowHeaderTextColor + font.pixelSize: Style.nmcFontSizeIconText + font.bold: false + leftPadding: 8 + rightPadding: 8 + } + } +} + diff --git a/src/gui/nmcgui/NMCMenuItem.qml b/src/gui/nmcgui/NMCMenuItem.qml new file mode 100644 index 000000000000..f0a23f140b68 --- /dev/null +++ b/src/gui/nmcgui/NMCMenuItem.qml @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 by Eugen Fischer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +import Style 1.0 + +MenuItem { + icon.color: hovered ? Style.ncBlue : Style.ncTextColor + palette.windowText: hovered ? Style.nmcTrayWindowHeaderTextColor : Style.nmcTrayWindowHeaderTextColor + hoverEnabled: true + font.pixelSize: Style.topLinePixelSize +} diff --git a/src/gui/tray/ActivityItemActions.qml b/src/gui/tray/ActivityItemActions.qml index a44fc9880ee1..1aaf7a7942cb 100644 --- a/src/gui/tray/ActivityItemActions.qml +++ b/src/gui/tray/ActivityItemActions.qml @@ -44,11 +44,22 @@ Repeater { onClicked: isTalkReplyButton ? root.showReplyField() : root.triggerAction(model.index) - textColor: Style.adjustedCurrentUserHeaderColor - textColorHovered: Style.currentUserHeaderTextColor + textColor: Style.nmcTextInButtonColor + textColorHovered: Style.nmcTextInButtonColor contentsFont.bold: true bgColor: Style.currentUserHeaderColor visible: verb !== "REPLY" || (verb === "REPLY" && root.talkReplyButtonVisible) + + HoverHandler { + id: mouse + acceptedDevices: PointerDevice.Mouse + } + + background: Rectangle { + color: mouse.hovered? Style.nmcConflictHoverColor : Style.nmcConflictColor + radius: Style.nmcStandardRadius + height: Style.nmcTraySyncButtonHeight + } } } diff --git a/src/gui/tray/ActivityItemContent.qml b/src/gui/tray/ActivityItemContent.qml index 795a490d916e..319dfe9f1dcd 100644 --- a/src/gui/tray/ActivityItemContent.qml +++ b/src/gui/tray/ActivityItemContent.qml @@ -26,8 +26,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 //* (1 - Style.thumbnailImageSizeReduction) + readonly property int imageHeight: height //* (1 - Style.thumbnailImageSizeReduction) readonly property int thumbnailRadius: model.thumbnail && model.thumbnail.isUserAvatar ? width / 2 : 3 implicitWidth: root.iconSize @@ -177,7 +177,7 @@ RowLayout { bgColor: palette.mid bgNormalOpacity: 0 - visible: model.showFileDetails + visible: false onClicked: Systray.presentShareViewInTray(model.openablePath) } diff --git a/src/gui/tray/ActivityList.qml b/src/gui/tray/ActivityList.qml index 150e6483b3c4..939fc0a28392 100644 --- a/src/gui/tray/ActivityList.qml +++ b/src/gui/tray/ActivityList.qml @@ -85,8 +85,9 @@ ScrollView { background: null width: activityList.contentItem.width + leftPadding: Style.nmcListViewLeftPadding isFileActivityList: controlRoot.isFileActivityList - iconSize: controlRoot.iconSize + iconSize: Style.nmcListViewIconSize flickable: activityList onHoveredChanged: if (hovered) { // When we set the currentIndex the list view will scroll... diff --git a/src/gui/tray/NCProgressBar.qml b/src/gui/tray/NCProgressBar.qml index da154d430a95..09f098cb4b84 100644 --- a/src/gui/tray/NCProgressBar.qml +++ b/src/gui/tray/NCProgressBar.qml @@ -22,10 +22,10 @@ ProgressBar { background: Rectangle { implicitWidth: Style.progressBarWidth implicitHeight: Style.progressBarBackgroundHeight - radius: Style.progressBarRadius - color: Style.progressBarBackgroundColor + radius: Style.nmcStandardRadius + color: Style.nmcTrayWindowHeaderHighlightColor border.color: Style.progressBarBackgroundBorderColor - border.width: Style.progressBarBackgroundBorderWidth + border.width: 0 //Style.progressBarBackgroundBorderWidth } contentItem: Item { @@ -36,9 +36,9 @@ ProgressBar { width: control.visualPosition * parent.width height: parent.height radius: Style.progressBarRadius - color: Style.progressBarContentColor + color: Style.nmcTelekomMagentaColor border.color: Style.progressBarContentBorderColor - border.width: Style.progressBarContentBorderWidth + border.width: 0 } } } diff --git a/src/gui/tray/SyncStatus.qml b/src/gui/tray/SyncStatus.qml index 25d4f69115a3..521b3b4904e8 100644 --- a/src/gui/tray/SyncStatus.qml +++ b/src/gui/tray/SyncStatus.qml @@ -29,7 +29,7 @@ RowLayout { Layout.topMargin: 16 Layout.rightMargin: whiteSpace * (0.5 + Style.thumbnailImageSizeReduction) Layout.bottomMargin: 16 - Layout.leftMargin: Style.trayHorizontalMargin + (whiteSpace * (0.5 - Style.thumbnailImageSizeReduction)) + Layout.leftMargin: Style.nmcListViewLeftPadding padding: 0 @@ -47,6 +47,8 @@ RowLayout { Layout.fillWidth: true Layout.fillHeight: true + Layout.leftMargin: Style.nmcProgressFieldTextOffset + EnforcedPlainTextLabel { id: syncProgressText @@ -54,7 +56,7 @@ RowLayout { text: syncStatus.syncStatusString verticalAlignment: Text.AlignVCenter - font.pixelSize: Style.topLinePixelSize + font.pixelSize: Style.nmcFontSizeSyncText font.bold: true wrapMode: Text.Wrap } @@ -78,7 +80,7 @@ RowLayout { Layout.fillWidth: true text: syncStatus.syncStatusDetailString - visible: syncStatus.syncStatusDetailString !== "" + visible: false color: palette.midlight font.pixelSize: Style.subLinePixelSize wrapMode: Text.Wrap @@ -88,17 +90,17 @@ RowLayout { CustomButton { id: syncNowButton - FontMetrics { - id: syncNowFm - font: syncNowButton.contentsFont - } + // FontMetrics { + // id: syncNowFm + // font: syncNowButton.contentsFont + // } Layout.rightMargin: Style.trayHorizontalMargin text: qsTr("Sync now") padding: Style.smallSpacing - textColor: Style.adjustedCurrentUserHeaderColor + textColor: Style.nmcTextInButtonColor textColorHovered: Style.currentUserHeaderTextColor contentsFont.bold: true bgColor: Style.currentUserHeaderColor @@ -113,6 +115,17 @@ RowLayout { NC.UserModel.currentUser.forceSyncNow(); } } + + HoverHandler { + id: mouseSync + acceptedDevices: PointerDevice.Mouse + } + + background: Rectangle { + color: mouseSync.hovered? Style.nmcSyncHoverColor : Style.nmcTelekomMagentaColor + radius: Style.nmcStandardRadius + height: Style.nmcTraySyncButtonHeight + } } CustomButton { @@ -123,8 +136,9 @@ RowLayout { Layout.rightMargin: Style.trayHorizontalMargin text: qsTr("Resolve conflicts") - textColor: Style.adjustedCurrentUserHeaderColor - textColorHovered: Style.currentUserHeaderTextColor + padding: Style.smallSpacing + textColor: Style.nmcTextInButtonColor + textColorHovered: Style.nmcTextInButtonColor contentsFont.bold: true bgColor: Style.currentUserHeaderColor @@ -134,5 +148,16 @@ RowLayout { NC.UserModel.currentUser.isConnected enabled: visible onClicked: NC.Systray.createResolveConflictsDialog(activityModel.allConflicts); + + HoverHandler { + id: mouseConflict + acceptedDevices: PointerDevice.Mouse + } + + background: Rectangle { + color: mouseConflict.hovered? Style.nmcConflictHoverColor : Style.nmcConflictColor + radius: Style.nmcStandardRadius + height: Style.nmcTraySyncButtonHeight + } } } diff --git a/src/gui/tray/UserLine.qml b/src/gui/tray/UserLine.qml index 8b5ebcebe19d..8cdd147002d7 100644 --- a/src/gui/tray/UserLine.qml +++ b/src/gui/tray/UserLine.qml @@ -16,6 +16,9 @@ import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 +import QtGraphicalEffects 1.0 + +import "../nmcgui/" // Custom qml modules are in /theme (and included by resources.qrc) import Style 1.0 @@ -37,8 +40,7 @@ AbstractButton { background: Rectangle { anchors.fill: parent anchors.margins: 1 - color: (userLine.hovered || userLine.visualFocus) && - !(userMoreButton.hovered || userMoreButton.visualFocus) ? + color: (userLine.hovered || userLine.visualFocus) ? palette.highlight : palette.base } @@ -51,9 +53,10 @@ AbstractButton { Layout.leftMargin: 7 verticalAlignment: Qt.AlignCenter cache: false - source: model.avatar !== "" ? model.avatar : Theme.darkMode ? "image://avatars/fallbackWhite" : "image://avatars/fallbackBlack" - Layout.preferredHeight: Style.accountAvatarSize - Layout.preferredWidth: Style.accountAvatarSize + visible:false + source: Style.nmcAccountAvatarIcon + sourceSize.width: Style.nmcTrayWindowIconWidth // NMC Customization: These changes sharpen the image + sourceSize.height: Style.nmcTrayWindowIconWidth Rectangle { id: accountStatusIndicatorBackground @@ -81,6 +84,17 @@ AbstractButton { } } + //NMC Customization: This section adds hover effect to account avatar image + ColorOverlay { + cached: true + color: Style.ncTextColor + width: source.width + height: source.height + source: accountAvatar + anchors.leftMargin: 16 + Layout.leftMargin: 16 + } + ColumnLayout { id: accountLabels Layout.leftMargin: Style.accountLabelsSpacing @@ -95,7 +109,8 @@ AbstractButton { text: name elide: Text.ElideRight font.pixelSize: Style.topLinePixelSize - font.bold: true + font.bold: false + palette.windowText: Style.ncTextColor } RowLayout { @@ -132,6 +147,7 @@ AbstractButton { text: server elide: Text.ElideRight font.pixelSize: Style.subLinePixelSize + visible: false } } @@ -142,7 +158,7 @@ AbstractButton { flat: true icon.source: "qrc:///client/theme/more.svg" - icon.color: palette.buttonText + icon.color: Style.ncTextColor Accessible.role: Accessible.ButtonMenu Accessible.name: qsTr("Account actions") @@ -152,12 +168,29 @@ AbstractButton { background: Rectangle { anchors.fill: parent anchors.margins: 1 - color: userMoreButton.hovered || userMoreButton.visualFocus ? palette.highlight : "transparent" + color: userMoreButton.hovered || userMoreButton.visualFocus ? Style.nmcMenuMoreItemsColor : "transparent" } AutoSizingMenu { id: userMoreButtonMenu closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape + width: 170 + height: Math.min(implicitHeight, maxMenuHeight) + + background: Rectangle { + id:menuBackground + border.color: palette.dark + color: palette.base + radius: Style.nmcStandardRadius + layer.enabled: true + layer.effect: DropShadow { + transparentBorder: true + horizontalOffset: 0 + verticalOffset: 0 + radius: 6 + color: "#40000000" + } + } MenuItem { visible: model.isConnected && model.serverHasUserStatus @@ -169,11 +202,14 @@ AbstractButton { onClicked: showUserStatusSelector(index) } - MenuItem { + NMCMenuItem { text: model.isConnected ? qsTr("Log out") : qsTr("Log in") - font.pixelSize: Style.topLinePixelSize - palette.windowText: Style.ncTextColor - hoverEnabled: true + height: Style.nmcMenuSubItemHeight + icon.source: Style.nmcLogOutIcon + icon.color: Style.ncTextColor + icon.height: Style.nmcTrayWindowIconWidth + icon.width: Style.nmcTrayWindowIconWidth + leftPadding: Style.nmcMenuSubItemLeftPadding onClicked: { model.isConnected ? UserModel.logout(index) : UserModel.login(index) accountMenu.close() @@ -202,12 +238,15 @@ AbstractButton { } } - MenuItem { + NMCMenuItem { id: removeAccountButton text: qsTr("Remove account") - font.pixelSize: Style.topLinePixelSize - palette.windowText: Style.ncTextColor - hoverEnabled: true + height: Style.nmcMenuSubItemHeight + icon.source: Style.nmcRemoveIcon + icon.color: Style.ncTextColor + icon.height: Style.nmcTrayWindowIconWidth + icon.width: Style.nmcTrayWindowIconWidth + leftPadding: Style.nmcMenuSubItemLeftPadding onClicked: { UserModel.removeAccount(index) accountMenu.close() @@ -227,6 +266,13 @@ AbstractButton { Accessible.name: text Accessible.onPressAction: removeAccountButton.clicked() } + + //NMC Customization: spacer at the bottom of the menu + Rectangle { + height: 8 + color: "white" + radius: Style.nmcStandardRadius + } } } } diff --git a/src/gui/tray/Window.qml b/src/gui/tray/Window.qml index 75380d5fddff..e7560cb3b238 100644 --- a/src/gui/tray/Window.qml +++ b/src/gui/tray/Window.qml @@ -21,6 +21,7 @@ import Qt.labs.platform 1.1 as NativeDialogs import "../" import "../filedetails/" +import "../nmcgui" // Custom qml modules are in /theme (and included by resources.qrc) import Style 1.0 @@ -40,21 +41,21 @@ ApplicationWindow { // TODO: Rather than setting all these palette colours manually, // create a custom style and do it for all components globally palette { - text: Style.ncTextColor - windowText: Style.ncTextColor - buttonText: Style.ncTextColor - brightText: Style.ncTextBrightColor + text: Style.nmcTrayWindowHeaderTextColor + windowText: Style.nmcTrayWindowHeaderTextColor + buttonText: Style.nmcTrayWindowHeaderTextColor + brightText: Style.nmcTrayWindowHeaderTextColor highlight: Style.lightHover - highlightedText: Style.ncTextColor + highlightedText: Style.nmcTrayWindowHeaderTextColor light: Style.lightHover - midlight: Style.ncSecondaryTextColor + midlight: Style.nmcTrayWindowHeaderTextColor mid: Style.darkerHover dark: Style.menuBorder button: Style.buttonBackgroundColor window: Style.backgroundColor base: Style.backgroundColor toolTipBase: Style.backgroundColor - toolTipText: Style.ncTextColor + toolTipText: Style.nmcTrayWindowHeaderTextColor } readonly property int maxMenuHeight: Style.trayWindowHeight - Style.trayWindowHeaderHeight - 2 * Style.trayWindowBorderWidth @@ -262,22 +263,51 @@ ApplicationWindow { anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.top: trayWindowMainItem.top - height: Style.trayWindowHeaderHeight - color: Style.currentUserHeaderColor + height: Style.nmcTrayWindowHeaderHeight + color: Style.nmcTrayWindowHeaderBackgroundColor + + Rectangle { + id: whiteMargin + anchors.top: trayWindowHeaderBackground.top + anchors.left: trayWindowHeaderBackground.left + width: 10 + height: 64 + color: Style.nmcTrayWindowHeaderBackgroundColor + } + + Rectangle { + id: tLogo + anchors.top: trayWindowHeaderBackground.top + anchors.left: whiteMargin.right + width: Style.nmcTrayWindowLogoWidth + height: Style.nmcTrayWindowLogoWidth + + Image { + anchors.fill: parent + cache: false + source: Style.nmcTLogoPath + sourceSize: Qt.size(width, height) + fillMode: Image.Stretch + } + } RowLayout { id: trayWindowHeaderLayout - - spacing: 0 - anchors.fill: parent + spacing: 0 + anchors { + left: tLogo.right + top: trayWindowHeaderBackground.top + right: trayWindowHeaderBackground.right + } Button { id: currentAccountButton - Layout.preferredWidth: Style.currentAccountButtonWidth - Layout.preferredHeight: Style.trayWindowHeaderHeight + Layout.preferredWidth: Style.nmcCurrentAccountButtonWidth + Layout.preferredHeight: trayWindowHeaderBackground.height display: AbstractButton.IconOnly flat: true + hoverEnabled: true Accessible.role: Accessible.ButtonMenu Accessible.name: qsTr("Current account") @@ -299,17 +329,26 @@ ApplicationWindow { // x coordinate grows towards the right // y coordinate grows towards the bottom - x: (currentAccountButton.x + 2) - y: (currentAccountButton.y + Style.trayWindowHeaderHeight + 2) + x: (0 - tLogo.width) + y: (currentAccountButton.y + Style.nmcTrayWindowHeaderHeight - Style.nmcTrayWindowMenuOverlayMargin) - width: (Style.currentAccountButtonWidth - 2) + width: (Style.nmcCurrentAccountButtonWidth + tLogo.width + 30) height: Math.min(implicitHeight, maxMenuHeight) closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape background: Rectangle { + id: menuBackground border.color: palette.dark color: palette.base - radius: Style.currentAccountButtonRadius + radius: Style.nmcStandardRadius + layer.enabled: true + layer.effect: DropShadow { + transparentBorder: true + horizontalOffset: 0 + verticalOffset: 0 + radius: 6 + color: "#40000000" + } } contentItem: ScrollView { @@ -351,9 +390,10 @@ ApplicationWindow { MenuItem { id: addAccountButton - height: Systray.enableAddAccount ? Style.addAccountButtonHeight : 0 + height: Systray.enableAddAccount ? Style.nmcTrayWindowAddAccountButtonHeight : 0 hoverEnabled: true visible: Systray.enableAddAccount + icon.color: Style.ncTextColor background: Item { height: parent.height @@ -401,11 +441,19 @@ ApplicationWindow { color: palette.dark } - MenuItem { + NMCMenuItem { id: syncPauseButton - font.pixelSize: Style.topLinePixelSize - hoverEnabled: true onClicked: Systray.syncIsPaused = !Systray.syncIsPaused + icon.source: Style.nmcPauseIcon + icon.height: Style.nmcTrayWindowIconWidth + icon.width: Style.nmcTrayWindowIconWidth + icon.color: Style.ncTextColor + leftPadding: Style.nmcMenuSubItemLeftPadding + height: Style.nmcMenuSubItemHeight + + Text { + color: Style.nmcTrayWindowHeaderTextColor + } background: Item { height: parent.height @@ -422,11 +470,20 @@ ApplicationWindow { Accessible.onPressAction: syncPauseButton.clicked() } - 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 + icon.color: Style.ncTextColor + leftPadding: Style.nmcMenuSubItemLeftPadding + height: Style.nmcMenuSubItemHeight + + Text { + color: Style.nmcTrayWindowHeaderTextColor + } + onClicked: Systray.openSettings() background: Item { @@ -444,11 +501,20 @@ ApplicationWindow { Accessible.onPressAction: settingsButton.clicked() } - 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 + icon.color: Style.ncTextColor + leftPadding: Style.nmcMenuSubItemLeftPadding + height: Style.nmcMenuSubItemHeight + + Text { + color: Style.nmcTrayWindowHeaderTextColor + } + onClicked: Systray.shutdown() background: Item { @@ -465,18 +531,25 @@ ApplicationWindow { Accessible.name: text Accessible.onPressAction: exitButton.clicked() } + + //NMC customization: spacer at the bottom of the menu + Rectangle{ + height: 8 + color: "white" + radius: Style.nmcStandardRadius + } } background: Rectangle { - color: parent.hovered || parent.visualFocus ? Style.currentUserHeaderTextColor : "transparent" - opacity: 0.2 + color: parent.hovered || parent.visualFocus ? "black" : "transparent" + opacity: 0.05 } RowLayout { id: accountControlRowLayout height: Style.trayWindowHeaderHeight - width: Style.currentAccountButtonWidth + width: Style.nmcCurrentAccountButtonWidth spacing: 0 Image { @@ -485,9 +558,9 @@ ApplicationWindow { Layout.leftMargin: Style.trayHorizontalMargin verticalAlignment: Qt.AlignCenter cache: false - source: UserModel.currentUser.avatar != "" ? UserModel.currentUser.avatar : "image://avatars/fallbackWhite" - Layout.preferredHeight: Style.accountAvatarSize - Layout.preferredWidth: Style.accountAvatarSize + source: Style.nmcAccountAvatarIcon + sourceSize.width: Style.nmcTrayWindowIconWidth + sourceSize.height: Style.nmcTrayWindowIconWidth Accessible.role: Accessible.Graphic Accessible.name: qsTr("Current account avatar") @@ -547,10 +620,10 @@ ApplicationWindow { width: Style.currentAccountLabelWidth text: UserModel.currentUser.name elide: Text.ElideRight - color: Style.currentUserHeaderTextColor + color: Style.nmcTrayWindowHeaderTextColor - font.pixelSize: Style.topLinePixelSize - font.bold: true + font.pixelSize: Style.nmcFontSizeAccountName + font.bold: false } EnforcedPlainTextLabel { @@ -594,14 +667,14 @@ ApplicationWindow { ColorOverlay { cached: true - color: Style.currentUserHeaderTextColor + color: Style.nmcTrayWindowHeaderTextColor width: source.width height: source.height source: Image { Layout.alignment: Qt.AlignRight verticalAlignment: Qt.AlignCenter Layout.margins: Style.accountDropDownCaretMargin - source: "qrc:///client/theme/white/caret-down.svg" + source: "qrc:///client/theme/black/caret-down.svg" sourceSize.width: Style.accountDropDownCaretSize sourceSize.height: Style.accountDropDownCaretSize Accessible.role: Accessible.PopupMenu @@ -616,134 +689,82 @@ ApplicationWindow { Layout.fillWidth: true } - TrayFoldersMenuButton { - id: openLocalFolderButton - - visible: currentUser.hasLocalFolder - currentUser: UserModel.currentUser - - - onClicked: openLocalFolderButton.userHasGroupFolders ? openLocalFolderButton.toggleMenuOpen() : UserModel.openCurrentAccountLocalFolder() - - onFolderEntryTriggered: isGroupFolder ? UserModel.openCurrentAccountFolderFromTrayInfo(fullFolderPath) : UserModel.openCurrentAccountLocalFolder() - - Accessible.role: Accessible.Graphic - Accessible.name: qsTr("Open local or group folders") - Accessible.onPressAction: openLocalFolderButton.userHasGroupFolders ? openLocalFolderButton.toggleMenuOpen() : UserModel.openCurrentAccountLocalFolder() - - Layout.alignment: Qt.AlignRight - Layout.preferredWidth: Style.trayWindowHeaderHeight - Layout.preferredHeight: Style.trayWindowHeaderHeight - } - - HeaderButton { - id: trayWindowTalkButton - - visible: UserModel.currentUser.serverHasTalk - icon.source: "qrc:///client/theme/white/talk-app.svg" - icon.color: Style.currentUserHeaderTextColor - onClicked: UserModel.openCurrentAccountTalk() - - Accessible.role: Accessible.Button - Accessible.name: qsTr("Open Nextcloud Talk in browser") - Accessible.onPressAction: trayWindowTalkButton.clicked() - - Layout.alignment: Qt.AlignRight - Layout.preferredWidth: Style.trayWindowHeaderHeight - Layout.preferredHeight: Style.trayWindowHeaderHeight - - } + Rectangle { + id: trayWindowWebsiteButtonContainer + width: 92 + height: Style.nmcTrayWindowHeaderHeight - HeaderButton { - id: trayWindowAppsButton - icon.source: "qrc:///client/theme/white/more-apps.svg" - icon.color: Style.currentUserHeaderTextColor + NMCHeaderButton { + id: trayWindowWebsiteButton + iconSource: "qrc:///client/theme/NMCIcons/website.svg" + iconText: qsTranslate("", "OPEN_WEBSITE") + } - onClicked: { - if(appsMenuListView.count <= 0) { - UserModel.openCurrentAccountServer() - } else if (appsMenu.visible) { - appsMenu.close() - } else { - appsMenu.open() + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: UserModel.openCurrentAccountServer() + onEntered: { + trayWindowWebsiteButtonContainer.color = Style.nmcTrayWindowHeaderHighlightColor + } + onExited: { + trayWindowWebsiteButtonContainer.color = "transparent" } } + } - Accessible.role: Accessible.ButtonMenu - Accessible.name: qsTr("More apps") - Accessible.onPressAction: trayWindowAppsButton.clicked() + Rectangle { + id: trayWindowLocalButtonContainer + width: 92 + height: Style.nmcTrayWindowHeaderHeight - 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 + NMCHeaderButton { + id: trayWindowLocalButton + iconSource: "qrc:///client/theme/black/folder.svg" + iconText: qsTranslate("", "LOCAL_FOLDER") + } - background: Rectangle { - border.color: palette.dark - color: palette.base - radius: 2 + MouseArea{ + anchors.fill: parent + hoverEnabled: true + onClicked: UserModel.openCurrentAccountLocalFolder() + onEntered: { + trayWindowLocalButtonContainer.color = Style.nmcTrayWindowHeaderHighlightColor } - - contentItem: ScrollView { - id: appsMenuScrollView - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - - data: WheelHandler { - target: appsMenuScrollView.contentItem - } - ListView { - id: appsMenuListView - implicitHeight: contentHeight - model: UserAppsModel - interactive: true - clip: true - currentIndex: appsMenu.currentIndex - delegate: MenuItem { - id: appEntry - anchors.left: parent.left - anchors.right: parent.right - - text: model.appName - font.pixelSize: Style.topLinePixelSize - icon.source: model.appIconUrl - icon.color: palette.buttonText - onTriggered: UserAppsModel.openAppUrl(appUrl) - hoverEnabled: true - - background: Item { - height: parent.height - width: parent.width - Rectangle { - anchors.fill: parent - anchors.margins: 1 - color: parent.parent.hovered || parent.parent.visualFocus ? palette.highlight : "transparent" - } - } - - Accessible.role: Accessible.MenuItem - Accessible.name: qsTr("Open %1 in browser").arg(model.appName) - Accessible.onPressAction: appEntry.triggered() - } - } + onExited:{ + trayWindowLocalButtonContainer.color = "transparent" } } } + + Rectangle { + width: 10 + color: Style.nmcTrayWindowHeaderBackgroundColor + } } } // Rectangle trayWindowHeaderBackground + Rectangle{ + id: separator + color: Style.nmcTrayWindowHeaderSeparatorColor + anchors.top: trayWindowHeaderBackground.bottom + anchors.left: trayWindowMainItem.left + anchors.right: trayWindowMainItem.right + height: 1 + } + UnifiedSearchInputContainer { id: trayWindowUnifiedSearchInputContainer height: Style.trayWindowHeaderHeight * 0.65 + visible: false + anchors { - top: trayWindowHeaderBackground.bottom + top: separator.bottom left: trayWindowMainItem.left right: trayWindowMainItem.right - topMargin: Style.trayHorizontalMargin + controlRoot.padding + topMargin: Style.nmcTrayWindowStandardMargin leftMargin: Style.trayHorizontalMargin + controlRoot.padding rightMargin: Style.trayHorizontalMargin + controlRoot.padding } @@ -759,7 +780,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: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.margins: Style.trayHorizontalMargin @@ -768,7 +789,7 @@ ApplicationWindow { UnifiedSearchResultNothingFound { id: unifiedSearchResultNothingFound - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.topMargin: Style.trayHorizontalMargin @@ -786,7 +807,7 @@ ApplicationWindow { Loader { id: unifiedSearchResultsListViewSkeletonLoader - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.bottom: trayWindowMainItem.bottom @@ -815,7 +836,7 @@ ApplicationWindow { } visible: unifiedSearchResultsListView.count > 0 - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.bottom: trayWindowMainItem.bottom @@ -857,7 +878,7 @@ ApplicationWindow { visible: !trayWindowMainItem.isUnifiedSearchActive - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right } @@ -925,6 +946,7 @@ ApplicationWindow { ActivityList { id: activityList + ScrollBar.vertical.policy: contentHeight > activityList.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff visible: !trayWindowMainItem.isUnifiedSearchActive anchors.top: syncStatus.bottom anchors.left: trayWindowMainItem.left @@ -947,4 +969,4 @@ ApplicationWindow { } } } // Item trayWindowMainItem -} +} \ No newline at end of file diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml index 8fd90e0a0f6e..696b6d0c4d2c 100644 --- a/theme/Style/Style.qml +++ b/theme/Style/Style.qml @@ -202,4 +202,42 @@ QtObject { function variableSize(size) { return size * (1 + Math.min(pixelSize / 100, 1)); } + + //NMC Customization + readonly property int nmcFontSizeAccountName: 13 + readonly property int nmcFontSizeIconText: 10 + readonly property int nmcFontSizeSyncText: 15 + readonly property string nmcTLogoPath: "qrc:///client/theme/NMCIcons/tlogocarrier.svg" + readonly property string nmcAccountAvatarIcon: "qrc:///client/theme/NMCIcons/accountAvatarIcon.svg" + readonly property string nmcSettingsIcon: "qrc:///client/theme/settings.svg" + readonly property string nmcCloseIcon: "qrc:///client/theme/close.svg" + readonly property string nmcPauseIcon: "qrc:///client/theme/NMCIcons/pause.svg" + readonly property string nmcLogOutIcon: "qrc:///client/theme/NMCIcons/logout.svg" + readonly property string nmcRemoveIcon: "qrc:///client/theme/NMCIcons/remove.svg" + readonly property color nmcTelekomMagentaColor: "#E20074" + readonly property color nmcConflictColor: "#F97012" + readonly property color nmcConflictHoverColor: "#de6310" + readonly property color nmcSyncHoverColor: "#c00063" + readonly property color nmcSyncRefreshColor: "#2238df" + readonly property int nmcTrayWindowAddAccountButtonHeight: 56 + readonly property int nmcTrayWindowHeaderHeight: 64 + readonly property int nmcTrayWindowItemsHeight: 48 + readonly property int nmcTrayWindowIconWidth: 24 + 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: 40 + 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 color nmcMenuMoreItemsColor: "#E5E5E5" + readonly property color nmcTrayWindowHeaderBackgroundColor: "white" + readonly property color nmcTrayWindowHeaderTextColor: "black" + readonly property color nmcTrayWindowHeaderSeparatorColor: "#ededed" + readonly property color nmcTrayWindowHeaderHighlightColor: "#ededed" + readonly property color nmcTextInButtonColor: "white" } diff --git a/theme/black/folder.svg b/theme/black/folder.svg index bc31144b6778..0007cf46b16a 100644 --- a/theme/black/folder.svg +++ b/theme/black/folder.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + icon/content/folder/default@svg + + + + + + + + + + \ No newline at end of file diff --git a/theme/close.svg b/theme/close.svg index 30de70b7c809..7cea12292d9d 100644 --- a/theme/close.svg +++ b/theme/close.svg @@ -1 +1,7 @@ - + + + icon/action/circle-close/default@svg + + + + \ No newline at end of file diff --git a/theme/more.svg b/theme/more.svg index 8bbdaca10680..e2f50c80c748 100644 --- a/theme/more.svg +++ b/theme/more.svg @@ -1 +1,7 @@ - + + + /svg/icon/action/more/default + + + + \ No newline at end of file diff --git a/theme/settings.svg b/theme/settings.svg index f53024e88404..434caf275d45 100644 --- a/theme/settings.svg +++ b/theme/settings.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + /svg/icon/service/settings/default + + + + \ No newline at end of file