ExpandableComponent.qml 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import QtQuick 2.7
  2. import QtQuick.Controls 2.3
  3. import UM 1.2 as UM
  4. // The expandable component has 3 major sub components:
  5. // * The headerItem; Always visible and should hold some info about what happens if the component is expanded
  6. // * The popupItem; The content that needs to be shown if the component is expanded.
  7. // * The Icon; An icon that is displayed on the right of the drawer.
  8. Item
  9. {
  10. // The headerItem holds the QML item that is always displayed.
  11. property alias headerItem: headerItemLoader.sourceComponent
  12. // The popupItem holds the QML item that is shown when the "open" button is pressed
  13. property var popupItem
  14. // The background color of the popup
  15. property color popupBackgroundColor: "white"
  16. property alias headerBackgroundColor: background.color
  17. // How much spacing is needed around the popupItem
  18. property alias popupPadding: popup.padding
  19. // How much padding is needed around the header & button
  20. property alias headerPadding: background.padding
  21. // What icon should be displayed on the right.
  22. property alias iconSource: collapseButton.source
  23. // What is the color of the icon?
  24. property alias iconColor: collapseButton.color
  25. // The icon size (it's always drawn as a square)
  26. property alias iconSize: collapseButton.width
  27. // Is the "drawer" open?
  28. readonly property alias expanded: popup.visible
  29. onPopupItemChanged:
  30. {
  31. // Since we want the size of the popup to be set by the size of the content,
  32. // we need to do it like this.
  33. popup.width = popupItem.width + 2 * popup.padding
  34. popup.height = popupItem.height + 2 * popup.padding
  35. popup.contentItem = popupItem
  36. }
  37. Connections
  38. {
  39. // Since it could be that the popup is dynamically populated, we should also take these changes into account.
  40. target: popupItem
  41. onWidthChanged: popup.width = popupItem.width + 2 * popup.padding
  42. onHeightChanged: popup.height = popupItem.height + 2 * popup.padding
  43. }
  44. implicitHeight: 100
  45. implicitWidth: 400
  46. Rectangle
  47. {
  48. id: background
  49. property real padding: UM.Theme.getSize("default_margin").width
  50. color: "white"
  51. anchors.fill: parent
  52. Loader
  53. {
  54. id: headerItemLoader
  55. anchors
  56. {
  57. left: parent.left
  58. right: collapseButton.left
  59. top: parent.top
  60. bottom: parent.bottom
  61. margins: background.padding
  62. }
  63. }
  64. UM.RecolorImage
  65. {
  66. id: collapseButton
  67. anchors
  68. {
  69. right: parent.right
  70. verticalCenter: parent.verticalCenter
  71. margins: background.padding
  72. }
  73. sourceSize.width: width
  74. sourceSize.height: height
  75. visible: source != ""
  76. width: UM.Theme.getSize("section_icon").width
  77. height: width
  78. color: "black"
  79. }
  80. MouseArea
  81. {
  82. anchors.fill: parent
  83. onClicked: popup.visible ? popup.close() : popup.open()
  84. }
  85. }
  86. Popup
  87. {
  88. id: popup
  89. // Ensure that the popup is located directly below the headerItem
  90. y: headerItemLoader.height + 2 * background.padding
  91. // Make the popup right aligned with the rest. The 3x padding is due to left, right and padding between
  92. //the button & text.
  93. x: -width + collapseButton.width + headerItemLoader.width + 3 * background.padding
  94. padding: UM.Theme.getSize("default_margin").width
  95. closePolicy: Popup.CloseOnPressOutsideParent
  96. background: Rectangle
  97. {
  98. color: popupBackgroundColor
  99. }
  100. }
  101. }