Add another expandable component

Use one of them if the drop-panel has to act as a Popup and the other if it has to act as a standard component.

Contributes to CURA-5941.
This commit is contained in:
Diego Prado Gesto 2018-12-05 09:39:04 +01:00
parent 47ff95b1f3
commit cdb8020029
7 changed files with 227 additions and 62 deletions

View file

@ -16,7 +16,6 @@ Cura.ExpandableComponent
id: base id: base
width: UM.Theme.getSize("layerview_menu_size").width width: UM.Theme.getSize("layerview_menu_size").width
contentType: Cura.ExpandableComponent.ContentType.Fixed
Connections Connections
{ {

View file

@ -20,20 +20,11 @@ Item
AlignRight AlignRight
} }
enum ContentType
{
Floating,
Fixed
}
// The headerItem holds the QML item that is always displayed. // The headerItem holds the QML item that is always displayed.
property alias headerItem: headerItemLoader.sourceComponent property alias headerItem: headerItemLoader.sourceComponent
// The contentItem holds the QML item that is shown when the "open" button is pressed // The contentItem holds the QML item that is shown when the "open" button is pressed
property var contentItem: content.contentItem property alias contentItem: content.contentItem
// Defines the type of the contents
property int contentType: ExpandableComponent.ContentType.Floating
property color contentBackgroundColor: UM.Theme.getColor("action_button") property color contentBackgroundColor: UM.Theme.getColor("action_button")
@ -48,7 +39,7 @@ Item
property alias contentPadding: content.padding property alias contentPadding: content.padding
// How much spacing is needed for the contentItem by Y coordinate // How much spacing is needed for the contentItem by Y coordinate
property var contentSpacingY: 0 property var contentSpacingY: UM.Theme.getSize("narrow_margin").width
// How much padding is needed around the header & button // How much padding is needed around the header & button
property alias headerPadding: background.padding property alias headerPadding: background.padding
@ -64,17 +55,12 @@ Item
// Is the "drawer" open? // Is the "drawer" open?
readonly property alias expanded: content.visible readonly property alias expanded: content.visible
property alias expandedHighlightColor: expandedHighlight.color
// What should the radius of the header be. This is also influenced by the headerCornerSide // What should the radius of the header be. This is also influenced by the headerCornerSide
property alias headerRadius: background.radius 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. // 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 property alias headerCornerSide: background.cornerSide
// Change the contentItem close behaviour
property alias contentClosePolicy : content.closePolicy
property alias headerShadowColor: shadow.color property alias headerShadowColor: shadow.color
property alias enableHeaderShadow: shadow.visible property alias enableHeaderShadow: shadow.visible
@ -83,14 +69,7 @@ Item
function toggleContent() function toggleContent()
{ {
if (content.visible) content.visible = !content.visible
{
content.close()
}
else
{
content.open()
}
} }
implicitHeight: 100 * screenScaleFactor implicitHeight: 100 * screenScaleFactor
@ -117,17 +96,6 @@ Item
} }
} }
// A highlight that is shown when the content is expanded
Rectangle
{
id: expandedHighlight
width: parent.width
height: UM.Theme.getSize("thick_lining").height
color: UM.Theme.getColor("primary")
visible: contentType == ExpandableComponent.ContentType.Floating && expanded
anchors.bottom: parent.bottom
}
UM.RecolorImage UM.RecolorImage
{ {
id: collapseButton id: collapseButton
@ -139,9 +107,7 @@ Item
} }
sourceSize.width: width sourceSize.width: width
sourceSize.height: height sourceSize.height: height
source: contentType == ExpandableComponent.ContentType.Floating ? source: UM.Theme.getIcon("pencil")
(expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")) :
UM.Theme.getIcon("pencil")
visible: source != "" visible: source != ""
width: UM.Theme.getSize("standard_arrow").width width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height height: UM.Theme.getSize("standard_arrow").height
@ -155,8 +121,7 @@ Item
onClicked: toggleContent() onClicked: toggleContent()
hoverEnabled: true hoverEnabled: true
onEntered: background.color = headerHoverColor onEntered: background.color = headerHoverColor
onExited: background.color = (contentType == ExpandableComponent.ContentType.Fixed && expanded) ? onExited: background.color = expanded ? headerActiveColor : headerBackgroundColor
headerActiveColor : headerBackgroundColor
} }
} }
@ -174,9 +139,10 @@ Item
z: background.z - 1 z: background.z - 1
} }
Popup Control
{ {
id: content id: content
visible: false
// Ensure that the content is located directly below the headerItem // Ensure that the content is located directly below the headerItem
y: background.height + base.shadowOffset + base.contentSpacingY y: background.height + base.shadowOffset + base.contentSpacingY
@ -185,7 +151,6 @@ Item
// In case of right alignment, the 3x padding is due to left, right and padding between the button & text. // In case of right alignment, the 3x padding is due to left, right and padding between the button & text.
x: contentAlignment == ExpandableComponent.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 x: contentAlignment == ExpandableComponent.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0
padding: UM.Theme.getSize("default_margin").width padding: UM.Theme.getSize("default_margin").width
closePolicy: Popup.CloseOnPressOutsideParent
background: Cura.RoundedRectangle background: Cura.RoundedRectangle
{ {
@ -195,15 +160,16 @@ Item
border.color: UM.Theme.getColor("lining") border.color: UM.Theme.getColor("lining")
radius: UM.Theme.getSize("default_radius").width radius: UM.Theme.getSize("default_radius").width
} }
}
onContentItemChanged: contentItem: Item {}
{
// Since we want the size of the content to be set by the size of the content, onContentItemChanged:
// we need to do it like this. {
content.width = contentItem.width + 2 * content.padding // Since we want the size of the content to be set by the size of the content,
content.height = contentItem.height + 2 * content.padding // we need to do it like this.
content.contentItem = contentItem content.width = contentItem.width + 2 * content.padding
content.height = contentItem.height + 2 * content.padding
}
} }
// DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item. // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item.

View file

@ -0,0 +1,204 @@
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 2 major sub components:
// * The headerItem; Always visible and should hold some info about what happens if the component is expanded
// * The contentItem; The content that needs to be shown if the component is expanded.
Item
{
id: base
// Enumeration with the different possible alignments of the content with respect of the headerItem
enum ContentAlignment
{
AlignLeft,
AlignRight
}
// The headerItem holds the QML item that is always displayed.
property alias headerItem: headerItemLoader.sourceComponent
// The contentItem holds the QML item that is shown when the "open" button is pressed
property alias contentItem: content.contentItem
property color contentBackgroundColor: UM.Theme.getColor("action_button")
property color headerBackgroundColor: UM.Theme.getColor("action_button")
property color headerActiveColor: UM.Theme.getColor("secondary")
property color headerHoverColor: UM.Theme.getColor("action_button_hovered")
// Defines the alignment of the content with respect of the headerItem, by default to the right
property int contentAlignment: ExpandablePopup.ContentAlignment.AlignRight
// How much spacing is needed around the contentItem
property alias contentPadding: content.padding
// 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: content.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 contentItem close behaviour
property alias contentClosePolicy : content.closePolicy
property alias headerShadowColor: shadow.color
property alias enableHeaderShadow: shadow.visible
property int shadowOffset: 2
function toggleContent()
{
if (content.visible)
{
content.close()
}
else
{
content.open()
}
}
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 content 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
source: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
visible: source != ""
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
color: UM.Theme.getColor("text")
}
MouseArea
{
id: mouseArea
anchors.fill: parent
onClicked: toggleContent()
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: content
// Ensure that the content is located directly below the headerItem
y: background.height + base.shadowOffset
// Make the content aligned with the rest, using the property contentAlignment 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: contentAlignment == ExpandablePopup.ContentAlignment.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: contentBackgroundColor
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
radius: UM.Theme.getSize("default_radius").width
}
contentItem: Item {}
onContentItemChanged:
{
// Since we want the size of the content to be set by the size of the content,
// we need to do it like this.
content.width = contentItem.width + 2 * content.padding
content.height = contentItem.height + 2 * content.padding
}
}
// DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item.
// Apparently the order in which these are handled matters and so the height is correctly updated if this is here.
Connections
{
// Since it could be that the content is dynamically populated, we should also take these changes into account.
target: content.contentItem
onWidthChanged: content.width = content.contentItem.width + 2 * content.padding
onHeightChanged: content.height = content.contentItem.height + 2 * content.padding
}
}

View file

@ -12,7 +12,7 @@ import UM 1.2 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
Cura.ExpandableComponent Cura.ExpandablePopup
{ {
id: base id: base

View file

@ -14,11 +14,7 @@ Cura.ExpandableComponent
property string enabledText: catalog.i18nc("@label:Should be short", "On") property string enabledText: catalog.i18nc("@label:Should be short", "On")
property string disabledText: catalog.i18nc("@label:Should be short", "Off") property string disabledText: catalog.i18nc("@label:Should be short", "Off")
contentType: Cura.ExpandableComponent.ContentType.Fixed
contentPadding: UM.Theme.getSize("default_lining").width contentPadding: UM.Theme.getSize("default_lining").width
contentSpacingY: UM.Theme.getSize("narrow_margin").width
contentClosePolicy: Popup.CloseOnEscape
UM.I18nCatalog UM.I18nCatalog
{ {

View file

@ -7,7 +7,7 @@ import QtQuick.Controls 2.3
import UM 1.2 as UM import UM 1.2 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
Cura.ExpandableComponent Cura.ExpandablePopup
{ {
id: machineSelector id: machineSelector
@ -16,7 +16,7 @@ Cura.ExpandableComponent
property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
contentPadding: UM.Theme.getSize("default_lining").width contentPadding: UM.Theme.getSize("default_lining").width
contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft
UM.I18nCatalog UM.I18nCatalog
{ {

View file

@ -7,12 +7,12 @@ import QtQuick.Controls 2.3
import UM 1.2 as UM import UM 1.2 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
Cura.ExpandableComponent Cura.ExpandablePopup
{ {
id: viewSelector id: viewSelector
contentPadding: UM.Theme.getSize("default_lining").width contentPadding: UM.Theme.getSize("default_lining").width
contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft
property var viewModel: UM.ViewModel { } property var viewModel: UM.ViewModel { }
@ -72,13 +72,13 @@ Cura.ExpandableComponent
contentItem: Column contentItem: Column
{ {
id: viewSelectorPopup id: viewSelectorPopup
width: viewSelector.width - 2 * viewSelector.popupPadding width: viewSelector.width - 2 * viewSelector.contentPadding
// For some reason the height/width of the column gets set to 0 if this is not set... // For some reason the height/width of the column gets set to 0 if this is not set...
Component.onCompleted: Component.onCompleted:
{ {
height = implicitHeight height = implicitHeight
width = viewSelector.width - 2 * viewSelector.popupPadding width = viewSelector.width - 2 * viewSelector.contentPadding
} }
Repeater Repeater