Marketplace.qml 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // Copyright (c) 2021 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.15
  4. import QtQuick.Controls 2.15
  5. import QtQuick.Layouts 1.15
  6. import QtQuick.Window 2.2
  7. import UM 1.2 as UM
  8. import Cura 1.6 as Cura
  9. Window
  10. {
  11. id: marketplaceDialog
  12. property variant catalog: UM.I18nCatalog { name: "cura" }
  13. signal searchStringChanged(string new_search)
  14. minimumWidth: UM.Theme.getSize("modal_window_minimum").width
  15. minimumHeight: UM.Theme.getSize("modal_window_minimum").height
  16. width: minimumWidth
  17. height: minimumHeight
  18. onVisibleChanged:
  19. {
  20. while(contextStack.depth > 1)
  21. {
  22. contextStack.pop(); //Do NOT use the StackView.Immediate transition here, since it causes the window to stay empty. Seemingly a Qt bug: https://bugreports.qt.io/browse/QTBUG-60670?
  23. }
  24. }
  25. Connections
  26. {
  27. target: Cura.API.account
  28. function onLoginStateChanged()
  29. {
  30. close();
  31. }
  32. }
  33. title: "Marketplace" //Seen by Ultimaker as a brand name, so this doesn't get translated.
  34. modality: Qt.NonModal
  35. // Background color
  36. Rectangle
  37. {
  38. anchors.fill: parent
  39. color: UM.Theme.getColor("main_background")
  40. }
  41. //The Marketplace can have a page in front of everything with package details. The stack view controls its visibility.
  42. StackView
  43. {
  44. id: contextStack
  45. anchors.fill: parent
  46. initialItem: packageBrowse
  47. ColumnLayout
  48. {
  49. id: packageBrowse
  50. spacing: UM.Theme.getSize("narrow_margin").height
  51. // Page title.
  52. Item
  53. {
  54. Layout.preferredWidth: parent.width
  55. Layout.preferredHeight: childrenRect.height + UM.Theme.getSize("default_margin").height
  56. Label
  57. {
  58. id: pageTitle
  59. anchors
  60. {
  61. left: parent.left
  62. leftMargin: UM.Theme.getSize("default_margin").width
  63. right: parent.right
  64. rightMargin: UM.Theme.getSize("default_margin").width
  65. bottom: parent.bottom
  66. }
  67. font: UM.Theme.getFont("large")
  68. color: UM.Theme.getColor("text")
  69. text: content.item ? content.item.pageTitle: catalog.i18nc("@title", "Loading...")
  70. }
  71. }
  72. OnboardBanner
  73. {
  74. visible: content.item && content.item.bannerVisible
  75. text: content.item && content.item.bannerText
  76. icon: content.item && content.item.bannerIcon
  77. onRemove: content.item && content.item.onRemoveBanner
  78. readMoreUrl: content.item && content.item.bannerReadMoreUrl
  79. Layout.fillWidth: true
  80. Layout.leftMargin: UM.Theme.getSize("default_margin").width
  81. Layout.rightMargin: UM.Theme.getSize("default_margin").width
  82. }
  83. // Search & Top-Level Tabs
  84. Item
  85. {
  86. implicitHeight: childrenRect.height
  87. implicitWidth: parent.width - 2 * UM.Theme.getSize("default_margin").width
  88. Layout.alignment: Qt.AlignHCenter
  89. RowLayout
  90. {
  91. width: parent.width
  92. height: UM.Theme.getSize("button_icon").height + UM.Theme.getSize("default_margin").height
  93. spacing: UM.Theme.getSize("thin_margin").width
  94. Cura.SearchBar
  95. {
  96. id: searchBar
  97. implicitHeight: UM.Theme.getSize("button_icon").height
  98. Layout.fillWidth: true
  99. onTextEdited: searchStringChanged(text)
  100. }
  101. // Page selection.
  102. TabBar
  103. {
  104. id: pageSelectionTabBar
  105. Layout.alignment: Qt.AlignRight
  106. height: UM.Theme.getSize("button_icon").height
  107. spacing: 0
  108. background: Rectangle { color: "transparent" }
  109. currentIndex: manager.tabShown
  110. onCurrentIndexChanged:
  111. {
  112. manager.tabShown = currentIndex
  113. searchBar.text = "";
  114. searchBar.visible = currentItem.hasSearch;
  115. content.source = currentItem.sourcePage;
  116. }
  117. PackageTypeTab
  118. {
  119. id: pluginTabText
  120. width: implicitWidth
  121. text: catalog.i18nc("@button", "Plugins")
  122. property string sourcePage: "Plugins.qml"
  123. property bool hasSearch: true
  124. }
  125. PackageTypeTab
  126. {
  127. id: materialsTabText
  128. width: implicitWidth
  129. text: catalog.i18nc("@button", "Materials")
  130. property string sourcePage: "Materials.qml"
  131. property bool hasSearch: true
  132. }
  133. ManagePackagesButton
  134. {
  135. property string sourcePage: "ManagedPackages.qml"
  136. property bool hasSearch: false
  137. Cura.NotificationIcon
  138. {
  139. anchors
  140. {
  141. horizontalCenter: parent.right
  142. verticalCenter: parent.top
  143. }
  144. visible: CuraApplication.getPackageManager().packagesWithUpdate.length > 0
  145. labelText:
  146. {
  147. const itemCount = CuraApplication.getPackageManager().packagesWithUpdate.length
  148. return itemCount > 9 ? "9+" : itemCount
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. FontMetrics
  156. {
  157. id: fontMetrics
  158. font: UM.Theme.getFont("default")
  159. }
  160. Cura.TertiaryButton
  161. {
  162. text: catalog.i18nc("@info", "Search in the browser")
  163. iconSource: UM.Theme.getIcon("LinkExternal")
  164. visible: pageSelectionTabBar.currentItem.hasSearch
  165. isIconOnRightSide: true
  166. height: fontMetrics.height
  167. textFont: fontMetrics.font
  168. textColor: UM.Theme.getColor("text")
  169. onClicked: content.item && Qt.openUrlExternally(content.item.searchInBrowserUrl)
  170. }
  171. // Page contents.
  172. Rectangle
  173. {
  174. Layout.preferredWidth: parent.width
  175. Layout.fillHeight: true
  176. color: UM.Theme.getColor("detail_background")
  177. // Page contents.
  178. Loader
  179. {
  180. id: content
  181. anchors.fill: parent
  182. anchors.margins: UM.Theme.getSize("default_margin").width
  183. source: "Plugins.qml"
  184. Connections
  185. {
  186. target: content
  187. function onLoaded()
  188. {
  189. pageTitle.text = content.item.pageTitle
  190. searchStringChanged.connect(handleSearchStringChanged)
  191. }
  192. function handleSearchStringChanged(new_search)
  193. {
  194. content.item.model.searchString = new_search
  195. }
  196. }
  197. }
  198. }
  199. }
  200. }
  201. Rectangle
  202. {
  203. height: quitButton.height + 2 * UM.Theme.getSize("default_margin").width
  204. color: UM.Theme.getColor("primary")
  205. visible: manager.showRestartNotification
  206. anchors
  207. {
  208. left: parent.left
  209. right: parent.right
  210. bottom: parent.bottom
  211. }
  212. RowLayout
  213. {
  214. anchors
  215. {
  216. left: parent.left
  217. right: parent.right
  218. verticalCenter: parent.verticalCenter
  219. margins: UM.Theme.getSize("default_margin").width
  220. }
  221. spacing: UM.Theme.getSize("default_margin").width
  222. UM.ColorImage
  223. {
  224. id: bannerIcon
  225. source: UM.Theme.getIcon("Plugin")
  226. color: UM.Theme.getColor("primary_button_text")
  227. implicitWidth: UM.Theme.getSize("banner_icon_size").width
  228. implicitHeight: UM.Theme.getSize("banner_icon_size").height
  229. }
  230. Text
  231. {
  232. color: UM.Theme.getColor("primary_button_text")
  233. text: catalog.i18nc("@button", "In order to use the package you will need to restart Cura")
  234. font: UM.Theme.getFont("default")
  235. renderType: Text.NativeRendering
  236. Layout.fillWidth: true
  237. }
  238. Cura.SecondaryButton
  239. {
  240. id: quitButton
  241. text: catalog.i18nc("@info:button, %1 is the application name", "Quit %1").arg(CuraApplication.applicationDisplayName)
  242. onClicked:
  243. {
  244. marketplaceDialog.hide();
  245. CuraApplication.closeApplication();
  246. }
  247. }
  248. }
  249. }
  250. }