Cura/resources/qml/ExpandableComponent.qml
Diego Prado Gesto bc8bf87809 Align the buttons at the bottom of the panel
Contributes to CURA-5941.
2018-11-29 15:54:02 +01:00

204 lines
6.4 KiB
QML

import QtQuick 2.7
import QtQuick.Controls 2.3
import UM 1.2 as UM
import Cura 1.0 as Cura
import QtGraphicalEffects 1.0 // For the dropshadow
// The expandable component has 3 major sub components:
// * The headerItem; Always visible and should hold some info about what happens if the component is expanded
// * The popupItem; The content that needs to be shown if the component is expanded.
// * The icon; An icon that is displayed on the right of the drawer.
Item
{
id: base
// Enumeration with the different possible alignments of the popup with respect of the headerItem
enum PopupAlignment
{
AlignLeft,
AlignRight
}
// The headerItem holds the QML item that is always displayed.
property alias headerItem: headerItemLoader.sourceComponent
// The popupItem holds the QML item that is shown when the "open" button is pressed
property var popupItem
property color popupBackgroundColor: UM.Theme.getColor("action_button")
property color headerBackgroundColor: UM.Theme.getColor("action_button")
property color headerHoverColor: UM.Theme.getColor("action_button_hovered")
// Defines the alignment of the popup with respect of the headerItem, by default to the right
property int popupAlignment: ExpandableComponent.PopupAlignment.AlignRight
// How much spacing is needed around the popupItem
property alias popupPadding: popup.padding
// How much spacing is needed for the popupItem by Y coordinate
property var popupSpacingY: 0
// How much padding is needed around the header & button
property alias headerPadding: background.padding
// What icon should be displayed on the right.
property alias iconSource: collapseButton.source
property alias iconColor: collapseButton.color
// The icon size (it's always drawn as a square)
property alias iconSize: collapseButton.height
// Is the "drawer" open?
readonly property alias expanded: popup.visible
property alias expandedHighlightColor: expandedHighlight.color
// What should the radius of the header be. This is also influenced by the headerCornerSide
property alias headerRadius: background.radius
// On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right.
property alias headerCornerSide: background.cornerSide
// Change the popupItem close behaviour
property alias popupClosePolicy : popup.closePolicy
property alias headerShadowColor: shadow.color
property alias enableHeaderShadow: shadow.visible
property int shadowOffset: 2
function togglePopup()
{
if (popup.visible)
{
popup.close()
}
else
{
popup.open()
}
}
onPopupItemChanged:
{
// Since we want the size of the popup to be set by the size of the content,
// we need to do it like this.
popup.width = popupItem.width + 2 * popup.padding
popup.height = popupItem.height + 2 * popup.padding
popup.contentItem = popupItem
}
Connections
{
// Since it could be that the popup is dynamically populated, we should also take these changes into account.
target: popupItem
onWidthChanged: popup.width = popupItem.width + 2 * popup.padding
onHeightChanged: popup.height = popupItem.height + 2 * popup.padding
}
implicitHeight: 100 * screenScaleFactor
implicitWidth: 400 * screenScaleFactor
RoundedRectangle
{
id: background
property real padding: UM.Theme.getSize("default_margin").width
color: headerBackgroundColor
anchors.fill: parent
Loader
{
id: headerItemLoader
anchors
{
left: parent.left
right: collapseButton.visible ? collapseButton.left : parent.right
top: parent.top
bottom: parent.bottom
margins: background.padding
}
}
// A highlight that is shown when the popup is expanded
Rectangle
{
id: expandedHighlight
width: parent.width
height: UM.Theme.getSize("thick_lining").height
color: UM.Theme.getColor("primary")
visible: expanded
anchors.bottom: parent.bottom
}
UM.RecolorImage
{
id: collapseButton
anchors
{
right: parent.right
verticalCenter: parent.verticalCenter
margins: background.padding
}
sourceSize.width: width
sourceSize.height: height
visible: source != ""
width: height
height: Math.round(0.2 * base.height)
color: UM.Theme.getColor("text")
}
MouseArea
{
id: mouseArea
anchors.fill: parent
onClicked: togglePopup()
hoverEnabled: true
onEntered: background.color = headerHoverColor
onExited: background.color = headerBackgroundColor
}
}
DropShadow
{
id: shadow
// Don't blur the shadow
radius: 0
anchors.fill: background
source: background
verticalOffset: base.shadowOffset
visible: true
color: UM.Theme.getColor("action_button_shadow")
// Should always be drawn behind the background.
z: background.z - 1
}
Popup
{
id: popup
// Ensure that the popup is located directly below the headerItem
y: background.height + base.shadowOffset + popupSpacingY
// Make the popup aligned with the rest, using the property popupAlignment to decide whether is right or left.
// In case of right alignment, the 3x padding is due to left, right and padding between the button & text.
x: popupAlignment == ExpandableComponent.PopupAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0
padding: UM.Theme.getSize("default_margin").width
closePolicy: Popup.CloseOnPressOutsideParent
background: Cura.RoundedRectangle
{
cornerSide: Cura.RoundedRectangle.Direction.Down
color: popupBackgroundColor
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
radius: UM.Theme.getSize("default_radius").width
}
}
}