SelectProjectPage.qml 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // Copyright (C) 2021 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.10
  4. import QtQuick.Window 2.2
  5. import QtQuick.Controls 1.4 as OldControls // TableView doesn't exist in the QtQuick Controls 2.x in 5.10, so use the old one
  6. import QtQuick.Controls 2.3
  7. import QtQuick.Controls.Styles 1.4
  8. import QtQuick.Layouts 1.1
  9. import UM 1.2 as UM
  10. import Cura 1.6 as Cura
  11. import DigitalFactory 1.0 as DF
  12. Item
  13. {
  14. id: base
  15. width: parent.width
  16. height: parent.height
  17. property bool createNewProjectButtonVisible: true
  18. anchors
  19. {
  20. top: parent.top
  21. bottom: parent.bottom
  22. left: parent.left
  23. right: parent.right
  24. margins: UM.Theme.getSize("default_margin").width
  25. }
  26. RowLayout
  27. {
  28. id: headerRow
  29. anchors
  30. {
  31. top: parent.top
  32. left: parent.left
  33. right: parent.right
  34. }
  35. height: childrenRect.height
  36. spacing: UM.Theme.getSize("default_margin").width
  37. Cura.TextField
  38. {
  39. id: searchBar
  40. Layout.fillWidth: true
  41. implicitHeight: createNewProjectButton.height
  42. leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2
  43. focus: true
  44. onTextEdited: manager.projectFilter = text //Update the search filter when editing this text field.
  45. placeholderText: "Search"
  46. UM.RecolorImage
  47. {
  48. id: searchIcon
  49. anchors
  50. {
  51. verticalCenter: parent.verticalCenter
  52. left: parent.left
  53. leftMargin: UM.Theme.getSize("default_margin").width
  54. }
  55. source: UM.Theme.getIcon("search")
  56. height: UM.Theme.getSize("small_button_icon").height
  57. width: height
  58. color: UM.Theme.getColor("text")
  59. }
  60. }
  61. Cura.SecondaryButton
  62. {
  63. id: createNewProjectButton
  64. text: "New Library project"
  65. visible: createNewProjectButtonVisible && manager.userAccountCanCreateNewLibraryProject && (manager.retrievingProjectsStatus == DF.RetrievalStatus.Success || manager.retrievingProjectsStatus == DF.RetrievalStatus.Failed)
  66. onClicked:
  67. {
  68. createNewProjectPopup.open()
  69. }
  70. busy: manager.creatingNewProjectStatus == DF.RetrievalStatus.InProgress
  71. }
  72. Cura.SecondaryButton
  73. {
  74. id: upgradePlanButton
  75. text: "Upgrade plan"
  76. iconSource: UM.Theme.getIcon("external_link")
  77. visible: createNewProjectButtonVisible && !manager.userAccountCanCreateNewLibraryProject && (manager.retrievingProjectsStatus == DF.RetrievalStatus.Success || manager.retrievingProjectsStatus == DF.RetrievalStatus.Failed)
  78. tooltip: "Maximum number of projects reached. Please upgrade your subscription to create more projects."
  79. onClicked: Qt.openUrlExternally("https://ultimaker.com/software/enterprise-software?utm_source=cura&utm_medium=software&utm_campaign=MaxProjLink")
  80. }
  81. }
  82. Item
  83. {
  84. id: noLibraryProjectsContainer
  85. anchors
  86. {
  87. top: parent.top
  88. bottom: parent.bottom
  89. left: parent.left
  90. right: parent.right
  91. }
  92. visible: manager.digitalFactoryProjectModel.count == 0 && (manager.retrievingProjectsStatus == DF.RetrievalStatus.Success || manager.retrievingProjectsStatus == DF.RetrievalStatus.Failed)
  93. Column
  94. {
  95. anchors.centerIn: parent
  96. spacing: UM.Theme.getSize("thin_margin").height
  97. Image
  98. {
  99. id: digitalFactoryImage
  100. anchors.horizontalCenter: parent.horizontalCenter
  101. source: searchBar.text === "" ? "../images/digital_factory.svg" : "../images/projects_not_found.svg"
  102. fillMode: Image.PreserveAspectFit
  103. width: parent.width - 2 * UM.Theme.getSize("thick_margin").width
  104. }
  105. Label
  106. {
  107. id: noLibraryProjectsLabel
  108. anchors.horizontalCenter: parent.horizontalCenter
  109. text: searchBar.text === "" ? "It appears that you don't have any projects in the Library yet." : "No projects found that match the search query."
  110. font: UM.Theme.getFont("medium")
  111. color: UM.Theme.getColor("text")
  112. }
  113. Cura.TertiaryButton
  114. {
  115. id: visitDigitalLibraryButton
  116. anchors.horizontalCenter: parent.horizontalCenter
  117. text: "Visit Digital Library"
  118. onClicked: Qt.openUrlExternally(CuraApplication.ultimakerDigitalFactoryUrl + "/app/library?utm_source=cura&utm_medium=software&utm_campaign=empty-library")
  119. visible: searchBar.text === "" //Show the link to Digital Library when there are no projects in the user's Library.
  120. }
  121. }
  122. }
  123. Item
  124. {
  125. id: projectListContainer
  126. anchors
  127. {
  128. top: headerRow.bottom
  129. topMargin: UM.Theme.getSize("default_margin").height
  130. bottom: parent.bottom
  131. left: parent.left
  132. right: parent.right
  133. }
  134. visible: manager.digitalFactoryProjectModel.count > 0
  135. // Use a flickable and a column with a repeater instead of a ListView in a ScrollView, because the ScrollView cannot
  136. // have additional children (aside from the view inside it), which wouldn't allow us to add the LoadMoreProjectsCard
  137. // in it.
  138. Flickable
  139. {
  140. id: flickableView
  141. clip: true
  142. contentWidth: parent.width
  143. contentHeight: projectsListView.implicitHeight
  144. anchors.fill: parent
  145. ScrollBar.vertical: ScrollBar
  146. {
  147. // Vertical ScrollBar, styled similarly to the scrollBar in the settings panel
  148. id: verticalScrollBar
  149. visible: flickableView.contentHeight > flickableView.height
  150. background: Rectangle
  151. {
  152. implicitWidth: UM.Theme.getSize("scrollbar").width
  153. radius: Math.round(implicitWidth / 2)
  154. color: UM.Theme.getColor("scrollbar_background")
  155. }
  156. contentItem: Rectangle
  157. {
  158. id: scrollViewHandle
  159. implicitWidth: UM.Theme.getSize("scrollbar").width
  160. radius: Math.round(implicitWidth / 2)
  161. color: verticalScrollBar.pressed ? UM.Theme.getColor("scrollbar_handle_down") : verticalScrollBar.hovered ? UM.Theme.getColor("scrollbar_handle_hover") : UM.Theme.getColor("scrollbar_handle")
  162. Behavior on color { ColorAnimation { duration: 50; } }
  163. }
  164. }
  165. Column
  166. {
  167. id: projectsListView
  168. width: verticalScrollBar.visible ? parent.width - verticalScrollBar.width - UM.Theme.getSize("default_margin").width : parent.width
  169. anchors.top: parent.top
  170. spacing: UM.Theme.getSize("narrow_margin").width
  171. Repeater
  172. {
  173. model: manager.digitalFactoryProjectModel
  174. delegate: ProjectSummaryCard
  175. {
  176. id: projectSummaryCard
  177. imageSource: model.thumbnailUrl || "../images/placeholder.svg"
  178. projectNameText: model.displayName
  179. projectUsernameText: model.username
  180. projectLastUpdatedText: "Last updated: " + model.lastUpdated
  181. onClicked:
  182. {
  183. manager.selectedProjectIndex = index
  184. }
  185. }
  186. }
  187. LoadMoreProjectsCard
  188. {
  189. id: loadMoreProjectsCard
  190. height: UM.Theme.getSize("toolbox_thumbnail_small").height
  191. width: parent.width
  192. visible: manager.digitalFactoryProjectModel.count > 0
  193. hasMoreProjectsToLoad: manager.hasMoreProjectsToLoad
  194. onClicked:
  195. {
  196. manager.loadMoreProjects()
  197. }
  198. }
  199. }
  200. }
  201. }
  202. CreateNewProjectPopup
  203. {
  204. id: createNewProjectPopup
  205. width: 400 * screenScaleFactor
  206. height: 220 * screenScaleFactor
  207. x: Math.round((parent.width - width) / 2)
  208. y: Math.round((parent.height - height) / 2)
  209. }
  210. }