diff --git a/CMakeLists.txt b/CMakeLists.txt index 27102a6f0e7cd..2434776e7b040 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) set(QT_VERSION_MAJOR "6") @@ -341,6 +344,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 0000000000000..1e673f886e4f5 Binary files /dev/null and b/nmctheme_v1.rcc differ diff --git a/resources.qrc b/resources.qrc index 630251749749c..30d89f4e986b5 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 9660bfb7ee7f2..0402a9c1a26c2 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -3,6 +3,9 @@ find_package(Qt${QT_MAJOR_VERSION} REQUIRED COMPONENTS Widgets Svg Qml Quick Qui find_package(KF6Archive REQUIRED) find_package(KF6GuiAddons) +#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 (NOT TARGET Qt::GuiPrivate) message(FATAL_ERROR "Could not find GuiPrivate component of Qt. It might be shipped as a separate package, please check that.") endif() @@ -251,6 +254,10 @@ set(client_SRCS wizard/linklabel.cpp ) +file(GLOB NMC_FILES "nmcgui/*") +set(NMC_SRCS ${NMC_FILES}) +list(APPEND client_SRCS ${NMC_SRCS}) + if (WITH_WEBENGINE) list(APPEND client_SRCS wizard/webviewpage.h @@ -618,6 +625,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 e91fb3be9a1f4..f9a92fda2d1be 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -57,6 +57,14 @@ int main(int argc, char **argv) qputenv("QML_IMPORT_PATH", (QDir::currentPath() + QStringLiteral("/qml")).toLatin1()); #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 0000000000000..38b88dada0915 --- /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 0000000000000..f0a23f140b680 --- /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 0795ef3b83b6c..259e8f8750037 100644 --- a/src/gui/tray/ActivityItemActions.qml +++ b/src/gui/tray/ActivityItemActions.qml @@ -44,6 +44,20 @@ Repeater { onClicked: isTalkReplyButton ? root.showReplyField() : root.triggerAction(model.index) + textColor: Style.nmcTextInButtonColor + textColorHovered: Style.nmcTextInButtonColor + 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 48f5b901f6418..511aef9a1d35c 100644 --- a/src/gui/tray/ActivityItemContent.qml +++ b/src/gui/tray/ActivityItemContent.qml @@ -26,8 +26,10 @@ 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 imageWidth: width + readonly property int imageHeight: height readonly property int thumbnailRadius: model.thumbnail && model.thumbnail.isUserAvatar ? width / 2 : 3 implicitWidth: root.iconSize @@ -174,7 +176,7 @@ RowLayout { display: Button.IconOnly - 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 0e57289f8644a..af82758728b27 100644 --- a/src/gui/tray/ActivityList.qml +++ b/src/gui/tray/ActivityList.qml @@ -86,7 +86,9 @@ ScrollView { width: activityList.contentItem.width isFileActivityList: controlRoot.isFileActivityList - iconSize: controlRoot.iconSize + // iconSize: controlRoot.iconSize + iconSize: Style.nmcListViewIconSize + leftPadding: Style.nmcListViewLeftPadding flickable: activityList onHoveredChanged: if (hovered) { // When we set the currentIndex the list view will scroll... diff --git a/src/gui/tray/MainWindow.qml b/src/gui/tray/MainWindow.qml index be7ede737d5c5..cd36e1e5a3b8f 100644 --- a/src/gui/tray/MainWindow.qml +++ b/src/gui/tray/MainWindow.qml @@ -22,6 +22,7 @@ import Qt.labs.platform as NativeDialogs import "../" import "../filedetails/" +import "../nmcgui" // Custom qml modules are in /theme (and included by resources.qrc) import Style @@ -243,22 +244,58 @@ ApplicationWindow { anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.top: trayWindowMainItem.top - height: Style.trayWindowHeaderHeight - color: palette.window + // height: Style.trayWindowHeaderHeight + // color: palette.window + 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 + // anchors.fill: parent + + anchors { + left: tLogo.right + top: trayWindowHeaderBackground.top + right: trayWindowHeaderBackground.right + } Button { id: currentAccountButton - Layout.preferredWidth: Style.currentAccountButtonWidth - Layout.preferredHeight: Style.trayWindowHeaderHeight + // 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") @@ -280,17 +317,47 @@ ApplicationWindow { // x coordinate grows towards the right // y coordinate grows towards the bottom - x: (currentAccountButton.x + 2) - y: (currentAccountButton.y + Style.trayWindowHeaderHeight + 2) + // 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.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.window - radius: Style.halfTrayWindowRadius + // radius: Style.halfTrayWindowRadius + radius: Style.nmcStandardRadius + layer.enabled: true + layer.effect: DropShadow { + transparentBorder: true + horizontalOffset: 0 + verticalOffset: 0 + radius: 6 + color: "#40000000" + } + } + + contentItem: ScrollView { + id: accMenuScrollView + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + data: WheelHandler { + target: accMenuScrollView.contentItem + } + + ListView { + implicitHeight: contentHeight + model: accountMenu.contentModel + interactive: true + clip: true + currentIndex: accountMenu.currentIndex + } } onClosed: { @@ -316,9 +383,11 @@ ApplicationWindow { MenuItem { id: addAccountButton - height: Systray.enableAddAccount ? Style.addAccountButtonHeight : 0 + // height: Systray.enableAddAccount ? Style.addAccountButtonHeight : 0 + height: Systray.enableAddAccount ? Style.nmcTrayWindowAddAccountButtonHeight : 0 hoverEnabled: true visible: Systray.enableAddAccount + icon.color: Style.ncTextColor RowLayout { anchors.fill: parent @@ -363,15 +432,26 @@ ApplicationWindow { color: palette.dark } - MenuItem { + NMCMenuItem { id: syncPauseButton - font.pixelSize: Style.topLinePixelSize - hoverEnabled: true + // font.pixelSize: Style.topLinePixelSize + // hoverEnabled: true 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() + height: Style.nmcMenuSubItemHeight + icon.source: Style.nmcPauseIcon + icon.height: Style.nmcTrayWindowIconWidth + icon.width: Style.nmcTrayWindowIconWidth + icon.color: Style.ncTextColor + leftPadding: Style.nmcMenuSubItemLeftPadding + + Text { + color: Style.nmcTrayWindowHeaderTextColor + } + background: Rectangle { radius: Style.halfTrayWindowRadius color: palette.highlight @@ -379,16 +459,27 @@ ApplicationWindow { } } - MenuItem { + NMCMenuItem { id: settingsButton text: qsTr("Settings") - font.pixelSize: Style.topLinePixelSize - hoverEnabled: true + // font.pixelSize: Style.topLinePixelSize + // hoverEnabled: true onClicked: Systray.openSettings() Accessible.role: Accessible.MenuItem Accessible.name: text Accessible.onPressAction: settingsButton.clicked() + height: Style.nmcMenuSubItemHeight + icon.source: Style.nmcSettingsIcon + icon.height: Style.nmcTrayWindowIconWidth + icon.width: Style.nmcTrayWindowIconWidth + icon.color: Style.ncTextColor + leftPadding: Style.nmcMenuSubItemLeftPadding + + Text { + color: Style.nmcTrayWindowHeaderTextColor + } + background: Rectangle { radius: Style.halfTrayWindowRadius color: palette.highlight @@ -396,29 +487,48 @@ ApplicationWindow { } } - MenuItem { + NMCMenuItem { id: exitButton text: qsTr("Exit"); - font.pixelSize: Style.topLinePixelSize - hoverEnabled: true + // font.pixelSize: Style.topLinePixelSize + // hoverEnabled: true onClicked: Systray.shutdown() Accessible.role: Accessible.MenuItem Accessible.name: text Accessible.onPressAction: exitButton.clicked() + height: Style.nmcMenuSubItemHeight + icon.source: Style.nmcCloseIcon + icon.height: Style.nmcTrayWindowIconWidth + icon.width: Style.nmcTrayWindowIconWidth + icon.color: Style.ncTextColor + leftPadding: Style.nmcMenuSubItemLeftPadding + + Text { + color: Style.nmcTrayWindowHeaderTextColor + } + background: Rectangle { radius: Style.halfTrayWindowRadius color: palette.highlight visible: exitButton.hovered } } + + //NMC customization: spacer at the bottom of the menu + Rectangle { + height: 8 + color: "white" + radius: Style.nmcStandardRadius + } } RowLayout { id: accountControlRowLayout height: Style.trayWindowHeaderHeight - width: Style.currentAccountButtonWidth + // width: Style.currentAccountButtonWidth + width: Style.nmcCurrentAccountButtonWidth spacing: 0 Image { @@ -427,9 +537,12 @@ ApplicationWindow { 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 + // source: (UserModel.currentUser && 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") @@ -490,8 +603,11 @@ ApplicationWindow { text: UserModel.currentUser ? UserModel.currentUser.name : "" elide: Text.ElideRight - font.pixelSize: Style.topLinePixelSize - font.bold: true + // font.pixelSize: Style.topLinePixelSize + // font.bold: true + font.pixelSize: Style.nmcFontSizeAccountName + font.bold: false + color: Style.nmcTrayWindowHeaderTextColor } EnforcedPlainTextLabel { @@ -550,124 +666,82 @@ ApplicationWindow { Layout.fillWidth: true } - TrayFoldersMenuButton { - id: openLocalFolderButton - - visible: currentUser.hasLocalFolder - currentUser: UserModel.currentUser + Rectangle { + id: trayWindowWebsiteButtonContainer + width: 92 + height: Style.nmcTrayWindowHeaderHeight - 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: trayWindowFeaturedAppButton - visible: UserModel.currentUser.isFeaturedAppEnabled - icon.source: UserModel.currentUser.featuredAppIcon + "/" - onClicked: UserModel.openCurrentAccountFeaturedApp() - - Accessible.role: Accessible.Button - Accessible.name: UserModel.currentUser.featuredAppAccessibleName - Accessible.onPressAction: trayWindowFeaturedAppButton.clicked() - - Layout.alignment: Qt.AlignRight - Layout.preferredWidth: Style.trayWindowHeaderHeight - Layout.preferredHeight: Style.trayWindowHeaderHeight - } - - HeaderButton { - id: trayWindowAppsButton - icon.source: "image://svgimage-custom-color/more-apps.svg/" + palette.windowText + 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 - radius: Style.halfTrayWindowRadius - color: palette.window + 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.windowText - onTriggered: UserAppsModel.openAppUrl(appUrl) - hoverEnabled: true - Accessible.role: Accessible.MenuItem - Accessible.name: qsTr("Open %1 in browser").arg(model.appName) - Accessible.onPressAction: appEntry.triggered() - - background: Rectangle { - anchors.fill: parent - anchors.margins: 1 - color: appEntry.hovered ? palette.highlight : palette.window - radius: Style.halfTrayWindowRadius - } - } - } + 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: Math.max(Style.talkReplyTextFieldPreferredHeight, contentHeight) + visible: false anchors { top: trayWindowHeaderBackground.bottom left: trayWindowMainItem.left right: trayWindowMainItem.right - topMargin: Style.trayHorizontalMargin + controlRoot.padding + // topMargin: Style.trayHorizontalMargin + controlRoot.padding + topMargin: Style.nmcTrayWindowStandardMargin leftMargin: Style.trayHorizontalMargin + controlRoot.padding rightMargin: Style.trayHorizontalMargin + controlRoot.padding } @@ -696,7 +770,8 @@ 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.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible ? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.margins: Style.trayHorizontalMargin @@ -705,7 +780,8 @@ ApplicationWindow { UnifiedSearchResultNothingFound { id: unifiedSearchResultNothingFound - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + // anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible ? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.topMargin: Style.trayHorizontalMargin @@ -723,7 +799,8 @@ ApplicationWindow { Loader { id: unifiedSearchResultsListViewSkeletonLoader - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + // anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible ? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.bottom: trayWindowMainItem.bottom @@ -752,7 +829,8 @@ ApplicationWindow { } visible: unifiedSearchResultsListView.count > 0 - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + // anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible ? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right anchors.bottom: trayWindowMainItem.bottom @@ -794,7 +872,8 @@ ApplicationWindow { visible: !trayWindowMainItem.isUnifiedSearchActive - anchors.top: trayWindowUnifiedSearchInputContainer.bottom + // anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.top: trayWindowUnifiedSearchInputContainer.visible ? trayWindowUnifiedSearchInputContainer.bottom : separator.bottom anchors.left: trayWindowMainItem.left anchors.right: trayWindowMainItem.right @@ -864,6 +943,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 diff --git a/src/gui/tray/NCProgressBar.qml b/src/gui/tray/NCProgressBar.qml index c620f149a2ff5..5452dc5319a27 100644 --- a/src/gui/tray/NCProgressBar.qml +++ b/src/gui/tray/NCProgressBar.qml @@ -22,10 +22,13 @@ ProgressBar { background: Rectangle { implicitWidth: Style.progressBarWidth implicitHeight: Style.progressBarBackgroundHeight - radius: Style.progressBarRadius - color: Style.progressBarBackgroundColor + // radius: Style.progressBarRadius + // color: Style.progressBarBackgroundColor + radius: Style.nmcStandardRadius + color: Style.nmcTrayWindowHeaderHighlightColor border.color: Style.progressBarBackgroundBorderColor - border.width: Style.progressBarBackgroundBorderWidth + // border.width: Style.progressBarBackgroundBorderWidth + border.width: 0 } contentItem: Item { @@ -36,9 +39,11 @@ ProgressBar { width: control.visualPosition * parent.width height: parent.height radius: Style.progressBarRadius - color: Style.progressBarContentColor + // color: Style.progressBarContentColor + color: Style.nmcTelekomMagentaColor border.color: Style.progressBarContentBorderColor - border.width: Style.progressBarContentBorderWidth + // border.width: Style.progressBarContentBorderWidth + border.width: 0 } } } diff --git a/src/gui/tray/SyncStatus.qml b/src/gui/tray/SyncStatus.qml index e8bb975189663..5762e90e5c4b8 100644 --- a/src/gui/tray/SyncStatus.qml +++ b/src/gui/tray/SyncStatus.qml @@ -29,7 +29,8 @@ 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.trayHorizontalMargin + (whiteSpace * (0.5 - Style.thumbnailImageSizeReduction)) + Layout.leftMargin: Style.nmcListViewLeftPadding padding: 0 @@ -43,6 +44,7 @@ RowLayout { Layout.alignment: Qt.AlignVCenter Layout.topMargin: 8 Layout.rightMargin: Style.trayHorizontalMargin + Layout.leftMargin: Style.nmcProgressFieldTextOffset Layout.bottomMargin: 8 Layout.fillWidth: true Layout.fillHeight: true @@ -54,7 +56,8 @@ RowLayout { text: syncStatus.syncStatusString verticalAlignment: Text.AlignVCenter - font.pixelSize: Style.topLinePixelSize + // font.pixelSize: Style.topLinePixelSize + font.pixelSize: Style.nmcFontSizeSyncText font.bold: true wrapMode: Text.Wrap } @@ -78,7 +81,8 @@ RowLayout { Layout.fillWidth: true text: syncStatus.syncStatusDetailString - visible: syncStatus.syncStatusDetailString !== "" + // visible: syncStatus.syncStatusDetailString !== "" + visible: false font.pixelSize: Style.subLinePixelSize wrapMode: Text.Wrap } @@ -87,15 +91,17 @@ RowLayout { CustomButton { id: syncNowButton - FontMetrics { - id: syncNowFm - } + // FontMetrics { + // id: syncNowFm + // } Layout.rightMargin: Style.trayHorizontalMargin text: qsTr("Sync now") padding: Style.smallSpacing + textColor: Style.nmcTextInButtonColor + textColorHovered: Style.nmcTextInButtonColor visible: !activityModel.hasSyncConflicts && !syncStatus.syncing && @@ -107,6 +113,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 { @@ -118,11 +135,26 @@ RowLayout { text: qsTr("Resolve conflicts") + padding: Style.smallSpacing + textColor: Style.nmcTextInButtonColor + textColorHovered: Style.nmcTextInButtonColor + visible: activityModel.hasSyncConflicts && !syncStatus.syncing && NC.UserModel.currentUser.hasLocalFolder && 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 e6f5ef800c218..ed431c8229eb1 100644 --- a/src/gui/tray/UserLine.qml +++ b/src/gui/tray/UserLine.qml @@ -16,6 +16,9 @@ import QtQuick import QtQuick.Window import QtQuick.Controls import QtQuick.Layouts +import QtGraphicalEffects 1.0 + +import "../nmcgui/" // Custom qml modules are in /theme (and included by resources.qrc) import Style @@ -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.window radius: Style.halfTrayWindowRadius } @@ -52,9 +54,13 @@ AbstractButton { Layout.leftMargin: Style.accountIconsMenuMargin 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 + // 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 @@ -95,7 +101,8 @@ AbstractButton { text: name elide: Text.ElideRight font.pixelSize: Style.topLinePixelSize - font.bold: true + // font.bold: true + font.bold: false } RowLayout { @@ -132,6 +139,7 @@ AbstractButton { text: server elide: Text.ElideRight font.pixelSize: Style.subLinePixelSize + visible: false } } @@ -141,27 +149,42 @@ AbstractButton { Layout.fillHeight: true flat: true + icon.source: "qrc:///client/theme/more.svg" + icon.color: Style.ncTextColor + Accessible.role: Accessible.ButtonMenu Accessible.name: qsTr("Account actions") Accessible.onPressAction: userMoreButtonMouseArea.clicked() onClicked: userMoreButtonMenu.visible ? userMoreButtonMenu.close() : userMoreButtonMenu.popup() - Image { - anchors.fill: parent - source: "image://svgimage-custom-color/more.svg/" + palette.windowText - fillMode: Image.PreserveAspectFit - anchors.rightMargin: Style.accountLabelsAnchorsMargin - } + // Image { + // anchors.fill: parent + // source: "image://svgimage-custom-color/more.svg/" + palette.windowText + // fillMode: Image.PreserveAspectFit + // anchors.rightMargin: Style.accountLabelsAnchorsMargin + // } AutoSizingMenu { id: userMoreButtonMenu closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape + height: Math.min(implicitHeight, maxMenuHeight) + width: 170 background: Rectangle { border.color: palette.dark - radius: Style.halfTrayWindowRadius - color: palette.window + // radius: Style.halfTrayWindowRadius + // color: palette.window + radius: Style.nmcStandardRadius + color: palette.base + layer.enabled: true + layer.effect: DropShadow { + transparentBorder: true + horizontalOffset: 0 + verticalOffset: 0 + radius: 6 + color: "#40000000" + } } MenuItem { @@ -178,10 +201,16 @@ AbstractButton { } } - MenuItem { + NMCMenuItem { text: model.isConnected ? qsTr("Log out") : qsTr("Log in") - font.pixelSize: Style.topLinePixelSize - hoverEnabled: true + // font.pixelSize: Style.topLinePixelSize + // 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() @@ -205,11 +234,17 @@ AbstractButton { } } - MenuItem { + NMCMenuItem { id: removeAccountButton text: qsTr("Remove account") - font.pixelSize: Style.topLinePixelSize - hoverEnabled: true + // font.pixelSize: Style.topLinePixelSize + // 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() @@ -224,6 +259,13 @@ AbstractButton { color: parent.hovered ? palette.highlight : palette.window } } + + //NMC Customization: spacer at the bottom of the menu + Rectangle { + height: 8 + color: "white" + radius: Style.nmcStandardRadius + } } } } diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml index 912aa10b8167b..1fb1b3ef859e8 100644 --- a/theme/Style/Style.qml +++ b/theme/Style/Style.qml @@ -5,6 +5,45 @@ import QtQuick import com.nextcloud.desktopclient QtObject { + + // 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" + readonly property int pixelSize: fontMetrics.font.pixelSize readonly property bool darkMode: Theme.darkMode diff --git a/theme/black/folder.svg b/theme/black/folder.svg index bc31144b67784..0007cf46b16aa 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 d4102db766da4..7cea12292d9dc 100644 --- a/theme/close.svg +++ b/theme/close.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + icon/action/circle-close/default@svg + + + + \ No newline at end of file diff --git a/theme/more.svg b/theme/more.svg index 164a1b70345f8..e2f50c80c7483 100644 --- a/theme/more.svg +++ b/theme/more.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + /svg/icon/action/more/default + + + + \ No newline at end of file diff --git a/theme/settings.svg b/theme/settings.svg index 85597a0c0d835..434caf275d458 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