TrayFoldersMenuButton.qml 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright (C) 2023 by Oleksandr Zolotov <alex@nextcloud.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. * for more details.
  13. */
  14. import QtQuick 2.15
  15. import QtQuick.Controls 2.15
  16. import QtQuick.Layouts 1.15
  17. import QtGraphicalEffects 1.0
  18. import Style 1.0
  19. HeaderButton {
  20. id: root
  21. signal folderEntryTriggered(string fullFolderPath, bool isGroupFolder)
  22. required property var currentUser
  23. property bool userHasGroupFolders: currentUser.groupFolders.length > 0
  24. function openMenu() {
  25. foldersMenuLoader.openMenu()
  26. }
  27. function closeMenu() {
  28. foldersMenuLoader.closeMenu()
  29. }
  30. function toggleMenuOpen() {
  31. if (foldersMenuLoader.isMenuVisible) {
  32. closeMenu()
  33. } else {
  34. openMenu()
  35. }
  36. }
  37. visible: currentUser.hasLocalFolder
  38. display: AbstractButton.IconOnly
  39. flat: true
  40. palette: Style.systemPalette
  41. Accessible.role: root.userHasGroupFolders ? Accessible.ButtonMenu : Accessible.Button
  42. Accessible.name: tooltip.text
  43. Accessible.onPressAction: root.clicked()
  44. NCToolTip {
  45. id: tooltip
  46. visible: root.hovered && !foldersMenuLoader.isMenuVisible
  47. text: root.userHasGroupFolders ? qsTr("Open local or group folders") : qsTr("Open local folder")
  48. }
  49. Image {
  50. id: folderStateIndicator
  51. visible: root.currentUser.hasLocalFolder
  52. source: root.currentUser.isConnected ? Style.stateOnlineImageSource : Style.stateOfflineImageSource
  53. cache: false
  54. anchors.top: root.verticalCenter
  55. anchors.left: root.horizontalCenter
  56. sourceSize.width: Style.folderStateIndicatorSize
  57. sourceSize.height: Style.folderStateIndicatorSize
  58. Accessible.role: Accessible.Indicator
  59. Accessible.name: root.currentUser.isConnected ? qsTr("Connected") : qsTr("Disconnected")
  60. z: 1
  61. Rectangle {
  62. id: folderStateIndicatorBackground
  63. width: Style.folderStateIndicatorSize + Style.trayFolderStatusIndicatorSizeOffset
  64. height: width
  65. anchors.centerIn: parent
  66. color: Style.currentUserHeaderColor
  67. radius: width * Style.trayFolderStatusIndicatorRadiusFactor
  68. z: -2
  69. }
  70. Rectangle {
  71. id: folderStateIndicatorBackgroundMouseHover
  72. width: Style.folderStateIndicatorSize + Style.trayFolderStatusIndicatorSizeOffset
  73. height: width
  74. anchors.centerIn: parent
  75. color: root.hovered ? Style.currentUserHeaderTextColor : "transparent"
  76. opacity: Style.trayFolderStatusIndicatorMouseHoverOpacityFactor
  77. radius: width * Style.trayFolderStatusIndicatorRadiusFactor
  78. z: -1
  79. }
  80. }
  81. RowLayout {
  82. id: openLocalFolderButtonRowLayout
  83. anchors.fill: parent
  84. spacing: 0
  85. Image {
  86. id: openLocalFolderButtonIcon
  87. cache: false
  88. source: "qrc:///client/theme/white/folder.svg"
  89. verticalAlignment: Qt.AlignCenter
  90. Accessible.role: Accessible.Graphic
  91. Accessible.name: qsTr("Group folder button")
  92. Layout.leftMargin: Style.trayHorizontalMargin
  93. }
  94. Loader {
  95. id: openLocalFolderButtonCaretIconLoader
  96. active: root.userHasGroupFolders
  97. visible: active
  98. sourceComponent: ColorOverlay {
  99. width: source.width
  100. height: source.height
  101. cached: true
  102. color: Style.currentUserHeaderTextColor
  103. source: Image {
  104. source: "qrc:///client/theme/white/caret-down.svg"
  105. sourceSize.width: Style.accountDropDownCaretSize
  106. sourceSize.height: Style.accountDropDownCaretSize
  107. verticalAlignment: Qt.AlignCenter
  108. Layout.alignment: Qt.AlignRight
  109. Layout.margins: Style.accountDropDownCaretMargin
  110. }
  111. }
  112. }
  113. }
  114. Loader {
  115. id: foldersMenuLoader
  116. property var openMenu: function(){}
  117. property var closeMenu: function(){}
  118. property bool isMenuVisible: false
  119. anchors.fill: parent
  120. active: root.userHasGroupFolders
  121. visible: active
  122. sourceComponent: AutoSizingMenu {
  123. id: foldersMenu
  124. x: Style.trayWindowMenuOffsetX
  125. y: (root.y + root.height + Style.trayWindowMenuOffsetY)
  126. width: Style.trayWindowWidth * Style.trayWindowMenuWidthFactor
  127. height: implicitHeight + y > Style.trayWindowHeight ? Style.trayWindowHeight - y : implicitHeight
  128. closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape
  129. contentItem: ScrollView {
  130. id: foldersMenuScrollView
  131. ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
  132. data: WheelHandler {
  133. target: foldersMenuScrollView.contentItem
  134. }
  135. ListView {
  136. id: foldersMenuListView
  137. implicitHeight: contentHeight
  138. model: root.currentUser.groupFolders
  139. interactive: true
  140. clip: true
  141. currentIndex: foldersMenu.currentIndex
  142. anchors.left: parent.left
  143. anchors.right: parent.right
  144. delegate: TrayFolderListItem {
  145. id: groupFoldersEntry
  146. property bool isGroupFolder: model.modelData.isGroupFolder
  147. text: model.modelData.name
  148. toolTipText: !isGroupFolder ? qsTr("Open local folder \"%1\"").arg(model.modelData.fullPath) : qsTr("Open groupfolder \"%1\"").arg(model.modelData.fullPath)
  149. subline: model.modelData.parentPath
  150. width: foldersMenuListView.width
  151. height: Style.standardPrimaryButtonHeight
  152. iconSource: !isGroupFolder ? "image://svgimage-custom-color/folder.svg/" + Style.ncTextColor : "image://svgimage-custom-color/folder-group.svg/" + Style.ncTextColor
  153. onTriggered: {
  154. foldersMenu.close();
  155. root.folderEntryTriggered(model.modelData.fullPath, isGroupFolder);
  156. }
  157. Accessible.role: Accessible.MenuItem
  158. Accessible.name: qsTr("Open %1 in file explorer").arg(title)
  159. Accessible.onPressAction: groupFoldersEntry.triggered()
  160. }
  161. Accessible.role: Accessible.PopupMenu
  162. Accessible.name: qsTr("User group and local folders menu")
  163. }
  164. }
  165. Component.onCompleted: {
  166. foldersMenuLoader.openMenu = open
  167. foldersMenuLoader.closeMenu = close
  168. }
  169. Connections {
  170. onVisibleChanged: foldersMenuLoader.isMenuVisible = visible
  171. }
  172. }
  173. }
  174. }