diff --git a/src/controls/Card.qml b/src/controls/Card.qml index 056123c6..fec92d01 100644 --- a/src/controls/Card.qml +++ b/src/controls/Card.qml @@ -1,105 +1,106 @@ /* * SPDX-FileCopyrightText: 2018 Marco Martin * * SPDX-License-Identifier: LGPL-2.0-or-later */ import QtQuick 2.6 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.0 as Controls import org.kde.kirigami 2.12 as Kirigami import "private" /** * This is the standard layout of a Card. * It is recommended to use this class when the concept of Cards is needed * in the application. * This Card has default items as header and footer. The header is an * image that can contain an optional title and icon, accessible via the * banner grouped property. * The footer will show a series of toolbuttons (and eventual overflow menu) * representing the actions list accessible with the list property actions. * It is possible even tough is discouraged to override the footer: * in this case the actions property shouldn't be used. * * @inherits AbstractCard * @since 2.4 */ Kirigami.AbstractCard { id: root /** * actions: list * if the card should provide clickable actions, put them in this property, * they will be put in the footer as a list of ToolButtons plus an optional * overflow menu, when not all of them will fit in the available Card width. */ property list actions /** * actions: hiddenActions * This list of actions is for those you always want in the menu, even if there * is enough space. * @since 2.6 */ property list hiddenActions /** * banner: Image * Gropuped property to control the banner image present in the header, it * has the following sub properties: * * url source: the source for the image, it understands any url * valid for an Image component * * string title: the title for the banner, shown as contrasting * text over the image * * Qt.Alignment titleAlignment: the alignment of the title inside the image, * a combination of flags is supported * (default: Qt.AlignTop | Qt.AlignLeft) * * string titleIcon: the optional icon to put in the banner: * it can be either a freedesktop-compatible icon name (recommended) * or any url supported by Image * * titleLevel: The Kirigami Heading level for the title, it controls the font size, default 1 * * wrapMode: if the header should be able to do wrapping * * It also has the full set of properties a QML Image has, such as sourceSize and fillMode */ readonly property alias banner: bannerImage header: BannerImage { id: bannerImage anchors.leftMargin: -root.leftPadding + root.background.border.width anchors.topMargin: -root.topPadding + root.background.border.width anchors.rightMargin: root.headerOrientation == Qt.Vertical ? -root.rightPadding + root.background.border.width : 0 anchors.bottomMargin: root.headerOrientation == Qt.Horizontal ? -root.bottomPadding + root.background.border.width : 0 //height: Layout.preferredHeight implicitWidth: root.headerOrientation == Qt.Horizontal ? sourceSize.width : Layout.preferredWidth + Layout.preferredHeight: (source != "" ? width / (sourceSize.width / sourceSize.height) : Layout.minimumHeight) + anchors.topMargin + anchors.bottomMargin readonly property real widthWithBorder: width + root.background.border.width * 2 readonly property real heightWithBorder: height + root.background.border.width * 2 readonly property real radiusFromBackground: root.background.radius - root.background.border.width corners.topLeftRadius: radiusFromBackground corners.topRightRadius: (root.headerOrientation == Qt.Horizontal && widthWithBorder < root.width) ? 0 : radiusFromBackground corners.bottomLeftRadius: (root.headerOrientation != Qt.Horizontal && heightWithBorder < root.height) ? 0 : radiusFromBackground corners.bottomRightRadius: heightWithBorder < root.height ? 0 : radiusFromBackground } onHeaderChanged: { if (!header) { return; } header.anchors.leftMargin = Qt.binding(function() {return -root.leftPadding}); header.anchors.topMargin = Qt.binding(function() {return -root.topPadding}); header.anchors.rightMargin = Qt.binding(function() {return root.headerOrientation == Qt.Vertical ? -root.rightPadding : 0}); header.anchors.bottomMargin = Qt.binding(function() {return root.headerOrientation == Qt.Horizontal ? -root.bottomPadding : 0}); } footer: Kirigami.ActionToolBar { id: actionsToolBar actions: root.actions position: Controls.ToolBar.Footer hiddenActions: root.hiddenActions visible: root.footer == actionsToolBar } } diff --git a/src/controls/templates/AbstractCard.qml b/src/controls/templates/AbstractCard.qml index deaa301f..f524a494 100644 --- a/src/controls/templates/AbstractCard.qml +++ b/src/controls/templates/AbstractCard.qml @@ -1,159 +1,159 @@ /* * SPDX-FileCopyrightText: 2018 Marco Martin * * SPDX-License-Identifier: LGPL-2.0-or-later */ import QtQuick 2.6 import QtQuick.Layouts 1.2 import QtQuick.Templates 2.0 as T import org.kde.kirigami 2.4 as Kirigami /** * A AbstractCard is the base for cards. A Card is a visual object that serves * as an entry point for more detailed information. An abstractCard is empty, * providing just the look and the base properties and signals for an ItemDelegate. * It can be filled with any custom layout of items, its content is organized * in 3 properties: header, contentItem and footer. * Use this only when you need particular custom contents, for a standard layout * for cards, use the Card component. * * @see Card * @inherits QtQuick.Templates.ItemDelegate * @since 2.4 */ T.ItemDelegate { id: root /** * header: Item * This item serves as header, it will be put either on top if headerOrientation * is Qt.Vertical(default) or on the left if it's Qt.Horizontal */ property Item header /** * headerOrientation: Qt.Orientation * If Qt.Vertical the header will be positioned on top(default), * if Qt.Horizontal will be positioned on the left (or right if an RTL layout is used) */ property int headerOrientation: Qt.Vertical /** * footer: Item * This item serves as footer, and it will be positioned at the bottom of the card. */ property Item footer /** * showClickFeedback: bool * if true, when clicking or tapping on the card area, the card will be colored * to show a visual click feedback. * Use this if you want to do an action in the onClicked signal handler of the card. */ property bool showClickFeedback: false Layout.fillWidth: true implicitWidth: Math.max(background.implicitWidth, mainLayout.implicitWidth) + leftPadding + rightPadding implicitHeight: mainLayout.implicitHeight + topPadding + bottomPadding hoverEnabled: !Kirigami.Settings.tabletMode && showClickFeedback //if it's in a CardLayout, try to expand horizontal cards to both columns Layout.columnSpan: headerOrientation == Qt.Horizontal && parent.hasOwnProperty("columns") ? parent.columns : 1 Kirigami.Theme.inherit: false Kirigami.Theme.colorSet: Kirigami.Theme.View - topPadding: Kirigami.Units.largeSpacing + topPadding: contentItemParent.children.length > 0 ? Kirigami.Units.largeSpacing : 0 leftPadding: Kirigami.Units.largeSpacing - bottomPadding: Kirigami.Units.largeSpacing + bottomPadding: contentItemParent.children.length > 0 ? Kirigami.Units.largeSpacing : 0 rightPadding: Kirigami.Units.largeSpacing GridLayout { id: mainLayout rowSpacing: root.topPadding columnSpacing: root.leftPadding anchors { top: parent.top left: parent.left right: parent.right leftMargin: root.leftPadding topMargin: root.topPadding rightMargin: root.rightPadding bottom:parent.bottom bottomMargin: root.bottomPadding } columns: headerOrientation == Qt.Vertical ? 1 : 2 function preferredHeight(item) { if (!item) { return 0; } if (item.Layout.preferredHeight > 0) { return item.Layout.preferredHeight; } return item.implicitHeight } Item { id: headerParent Layout.fillWidth: true Layout.fillHeight: root.headerOrientation == Qt.Horizontal Layout.rowSpan: root.headerOrientation == Qt.Vertical ? 1 : 2 Layout.preferredWidth: header ? header.implicitWidth : 0 Layout.preferredHeight: root.headerOrientation == Qt.Vertical ? mainLayout.preferredHeight(header) : -1 visible: children.length > 0 } Item { id: contentItemParent Layout.fillWidth: true Layout.fillHeight: true Layout.topMargin: root.topPadding Layout.bottomMargin: root.bottomPadding Layout.preferredWidth: contentItem ? contentItem.implicitWidth : 0 Layout.preferredHeight: mainLayout.preferredHeight(contentItem) visible: children.length > 0 } Item { id: footerParent Layout.fillWidth: true Layout.preferredWidth: footer ? footer.implicitWidth : 0 Layout.preferredHeight: mainLayout.preferredHeight(footer) visible: children.length > 0 } } //BEGIN signal handlers onContentItemChanged: { if (!contentItem) { return; } contentItem.parent = contentItemParent; contentItem.anchors.fill = contentItemParent; } onHeaderChanged: { if (!header) { return; } header.parent = headerParent; header.anchors.fill = headerParent; } onFooterChanged: { if (!footer) { return; } //make the footer always looking it's at the bottom of the card footer.parent = footerParent; footer.anchors.left = footerParent.left; footer.anchors.top = footerParent.top; footer.anchors.right = footerParent.right; footer.anchors.topMargin = Qt.binding(function() {return (root.height - root.bottomPadding - root.topPadding) - (footerParent.y + footerParent.height)}); } Component.onCompleted: { contentItemChanged(); } //END signal handlers }