Warning, /frameworks/kirigami/src/controls/BasicListItem.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  *  SPDX-FileCopyrightText: 2010 Marco Martin <notmart@gmail.com>
0003  *  SPDX-FileCopyrightText: 2022 ivan tkachenko <me@ratijas.tk>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 import QtQuick 2.15
0009 import QtQuick.Layouts 1.15
0010 import QtQuick.Controls 2.15 as QQC2
0011 import org.kde.kirigami 2.12 as Kirigami
0012 
0013 //TODO KF6: this needs to become a layout inside a Delegate rather than its own listItem
0014 /**
0015  * @brief A BasicListItem provides a simple list item design that can handle the
0016  * most common list item usecases.
0017  *
0018  * @image html BasicListItemTypes.svg "The styles of the BasicListItem. From left to right top to bottom: light icon + title + subtitle, dark icon + title + subtitle, light icon + label, dark icon + label, light label, dark label." width=50%
0019  * @warning This will be reworked into a layout to be used inside a delegate.
0020  * @see <a href="https://develop.kde.org/hig/components/editing/list">KDE Human Interface Guidelines on List Views and List Items</a>
0021  */
0022 Kirigami.AbstractListItem {
0023     id: listItem
0024 
0025 //BEGIN properties
0026     /**
0027      * @brief This property holds the text of this list item's label.
0028      *
0029      * If a subtitle is provided, the label will behave as a title and will be styled
0030      * accordingly. Every list item should have a label.
0031      *
0032      * @property string label
0033      */
0034     property alias label: listItem.text
0035 
0036     /**
0037      * @brief This property holds an optional subtitle that can appear under the label.
0038      * @since KDE Frameworks 5.70
0039      * @since org.kde.kirigami 2.12
0040      */
0041     property alias subtitle: subtitleItem.text
0042 
0043     /**
0044      * @brief This property holds an item that will be displayed before the title and subtitle.
0045      * @note The leading item is allowed to expand infinitely horizontally, and should be bounded by the user.
0046      * @since org.kde.kirigami 2.15
0047      */
0048     property Item leading
0049 
0050     /**
0051      * @brief This property holds the padding after the leading item.
0052      * @since org.kde.kirigami 2.15
0053      */
0054     property real leadingPadding: Kirigami.Units.largeSpacing
0055 
0056     // TODO KF6: remove this property and instead implement leading and trailing
0057     // item positioning in such a way that they fill vertically, but a fixed
0058     // height can be manually specified without needing to wrap it in an Item
0059     /**
0060      * @brief This property sets whether or not to stretch the leading item to fit all available vertical space.
0061      *
0062      * If false, you will be responsible for setting a height for the
0063      * item or ensuring that its default height works.
0064      *
0065      * default: ``true``
0066      *
0067      * @warning This property will likely be removed in KF6
0068      * @since KDE Frameworks 5.83
0069      * @since org.kde.kirigami 2.15
0070      */
0071     property bool leadingFillVertically: true
0072 
0073     /**
0074      * @brief This property holds an item that will be displayed after the title and subtitle
0075      * @note The trailing item is allowed to expand infinitely horizontally, and should be bounded by the user.
0076      * @since org.kde.kirigami 2.15
0077      */
0078     property Item trailing
0079 
0080     /**
0081      * @brief This property holds the padding before the trailing item.
0082      * @since org.kde.kirigami 2.15
0083      */
0084     property real trailingPadding: Kirigami.Units.largeSpacing
0085 
0086     // TODO KF6: remove this property and instead implement leading and trailing
0087     // item positioning in such a way that they fill vertically, but a fixed
0088     // height can be manually specified without needing to wrap it in an Item
0089     /**
0090      * @brief This propery sets whether or not to stretch the trailing item to fit all available vertical space.
0091      *
0092      * If false, you will be responsible for setting a height for the
0093      * item or ensuring that its default height works.
0094      *
0095      * default: ``true``
0096      *
0097      * @warning This property will likely be removed in KF6
0098      * @since KDE Frameworks 5.83
0099      * @since org.kde.kirigami 2.15
0100      */
0101     property bool trailingFillVertically: true
0102 
0103     /**
0104      * @brief This property sets whether list item's text should render in bold.
0105      *
0106      * default: ``false``
0107      *
0108      * @since KDE Frameworks 5.71
0109      * @since org.kde.kirigami 2.13
0110      */
0111     property bool bold: false
0112 
0113     /**
0114      * @code ts
0115      * interface IconGroup {
0116      *     name:   string,
0117      *     source: string,
0118      *     width:  int,
0119      *     height: int,
0120      *     color:  color,
0121      * }
0122      *
0123      * type Icon = string | IconGroup | URL
0124      * @endcode
0125      *
0126      * The icon that will render on this list item.
0127      *
0128      * This can either be an icon name, a URL, or an object with the following properties:
0129      *
0130      * If the type of the icon is a string containing an icon name, the icon will be looked up from the
0131      * platform icon theme.
0132      *
0133      * Using an icon object allows you to specify more granular attributes of the icon,
0134      * such as its color and dimensions.
0135      *
0136      * If the icon is a URL, the icon will be attempted to be loaded from the
0137      * given URL.
0138      */
0139     property var icon
0140 
0141     /**
0142      * @brief This property sets the size at which the icon will render.
0143      *
0144      * This will not affect icon lookup, unlike the icon group's width and height properties, which will.
0145      *
0146      * @since org.kde.kirigami 2.5
0147      * @property int iconSize
0148      */
0149     property alias iconSize: iconItem.size
0150 
0151     /**
0152      * @brief This property holds the color of the icon.
0153      *
0154      * If the icon's original colors should be left intact, set this to the default value, "transparent".
0155      * Note that this colour will only be applied if the icon can be recoloured, (e.g. you can use Kirigami.Theme.foregroundColor to change the icon's colour.)
0156      *
0157      * @since org.kde.kirigami 2.7
0158      * @property color iconColor
0159      */
0160     property alias iconColor: iconItem.color
0161 
0162     /**
0163      * @brief This property sets whether or not the icon has a "selected" appearance.
0164      *
0165      * Can be used to override the icon coloration if the list item's background and
0166      * text are also being overridden, to ensure that the icon never becomes invisible.
0167      *
0168      * @since KDE Frameworks 5.91
0169      * @since org.kde.kirigami 2.19
0170      * @property bool iconSelected
0171      */
0172     property alias iconSelected: iconItem.selected
0173 
0174     /**
0175      * @brief This property sets whether or not to reserve space for the icon, even if there is no icon.
0176      * @image html BasicListItemReserve.svg "Left: reserveSpaceForIcon: false. Right: reserveSpaceForIcon: true" width=50%
0177      * @property bool reserveSpaceForIcon
0178      */
0179     property alias reserveSpaceForIcon: iconItem.visible
0180 
0181     /**
0182      * @brief This property sets whether or not the label of the list item should fill width.
0183      *
0184      * Setting this to @c false is useful if you have other items in the list item
0185      * that should fill width instead of the label.
0186      *
0187      * @property bool reserveSpaceForLabel
0188      */
0189     property alias reserveSpaceForLabel: labelItem.visible
0190 
0191     /**
0192      * @brief This property holds whether the list item's height should account for
0193      * the presence of a subtitle.
0194      *
0195      * default: ``false``
0196      *
0197      * @since KDE Frameworks 5.77
0198      * @since org.kde.kirigami 2.15
0199      */
0200     property bool reserveSpaceForSubtitle: false
0201 
0202     /**
0203      * @brief This property holds the spacing between the label row and subtitle row.
0204      * @since KDE Frameworks 5.83
0205      * @since org.kde.kirigami 2.15
0206      * @property real textSpacing
0207      */
0208     property alias textSpacing: labelColumn.spacing
0209 
0210     /**
0211      * @brief This property holds sets whether to make the icon and labels have a disabled look.
0212      *
0213      * This can be used to tweak whether the content elements are visually active
0214      * while preserving an active appearance for any leading or trailing items.
0215      *
0216      * default: ``false``
0217      *
0218      * @since KDE Frameworks 5.83
0219      * @since org.kde.kirigami 2.15
0220      */
0221     property bool fadeContent: false
0222 
0223     /**
0224      * @brief This property holds the label item, for accessing the usual QtQuick.Text properties.
0225      * @since KDE Frameworks 5.84
0226      * @since org.kde.kirigami 2.16
0227      * @property QtQuick.Controls.Label labelItem
0228      */
0229     property alias labelItem: labelItem
0230 
0231     /**
0232      * @brief This property holds the subtitle item, for accessing the usual QtQuick.Text properties.
0233      * @since KDE Frameworks 5.84
0234      * @since org.kde.kirigami 2.16
0235      * @property QtQuick.Controls.Label subtitleItem
0236      */
0237     property alias subtitleItem: subtitleItem
0238 
0239     /**
0240      * @brief This property holds whether the tooltip of the subtitle should be visible
0241      * @since 5.107
0242      */
0243     property bool toolTipVisible: false
0244 
0245     /** @internal */
0246     default property alias _basicDefault: layout.data
0247 //END properties
0248 
0249 //BEGIN signal handlers
0250     onLeadingChanged: {
0251         const item = leading;
0252         if (!!item) {
0253             item.parent = contItem
0254             item.anchors.left = item.parent.left
0255             item.anchors.top = leadingFillVertically ? item.parent.top : undefined
0256             item.anchors.bottom = leadingFillVertically ? item.parent.bottom : undefined
0257             item.anchors.verticalCenter = leadingFillVertically ? undefined : item.parent.verticalCenter
0258             layout.anchors.left = item.right
0259             layout.anchors.leftMargin = Qt.binding(() => leadingPadding)
0260         } else {
0261             layout.anchors.left = contentItem.left
0262             layout.anchors.leftMargin = 0
0263         }
0264     }
0265 
0266     onTrailingChanged: {
0267         const item = trailing;
0268         if (!!item) {
0269             item.parent = contItem
0270             item.anchors.right = item.parent.right
0271             item.anchors.top = trailingFillVertically ? item.parent.top : undefined
0272             item.anchors.bottom = trailingFillVertically ? item.parent.bottom : undefined
0273             item.anchors.verticalCenter = trailingFillVertically ? undefined : item.parent.verticalCenter
0274             layout.anchors.right = item.left
0275             layout.anchors.rightMargin = Qt.binding(() => trailingPadding)
0276         } else {
0277             layout.anchors.right = contentItem.right
0278             layout.anchors.rightMargin = 0
0279         }
0280     }
0281 
0282     Keys.onEnterPressed: event => action ? action.trigger() : clicked()
0283     Keys.onReturnPressed: event => action ? action.trigger() : clicked()
0284 //END signal handlers
0285 
0286     icon: action ? action.icon.name || action.icon.source : undefined
0287 
0288     contentItem: Item {
0289         id: contItem
0290 
0291         implicitWidth: layout.implicitWidth
0292             + (listItem.leading !== null ? listItem.leading.implicitWidth : 0)
0293             + (listItem.trailing !== null ? listItem.trailing.implicitWidth : 0)
0294 
0295         Binding on implicitHeight {
0296             value: Math.max(iconItem.size, (!subtitleItem.visible && listItem.reserveSpaceForSubtitle ? (labelItem.implicitHeight + labelColumn.spacing + subtitleItem.implicitHeight): labelColumn.implicitHeight) )
0297             delayed: true
0298         }
0299 
0300         RowLayout {
0301             id: layout
0302             spacing: LayoutMirroring.enabled ? listItem.rightPadding : listItem.leftPadding
0303             anchors.left: contItem.left
0304             anchors.leftMargin: listItem.leading ? listItem.leadingPadding : 0
0305             anchors.right: contItem.right
0306             anchors.rightMargin: listItem.trailing ? listItem.trailingPadding : 0
0307             anchors.verticalCenter: parent.verticalCenter
0308 
0309             Kirigami.Icon {
0310                 id: iconItem
0311                 source: {
0312                     if (!listItem.icon) {
0313                         return undefined
0314                     }
0315                     if (listItem.icon.hasOwnProperty) {
0316                         if (listItem.icon.hasOwnProperty("name") && listItem.icon.name !== "")
0317                             return listItem.icon.name;
0318                         if (listItem.icon.hasOwnProperty("source"))
0319                             return listItem.icon.source;
0320                     }
0321                     return listItem.icon;
0322                 }
0323                 property int size: subtitleItem.visible || reserveSpaceForSubtitle ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.smallMedium
0324                 Layout.minimumHeight: size
0325                 Layout.maximumHeight: size
0326                 Layout.minimumWidth: size
0327                 Layout.maximumWidth: size
0328                 selected: (listItem.highlighted || listItem.checked || listItem.down)
0329                 opacity: listItem.fadeContent ? 0.6 : 1.0
0330                 visible: source !== undefined
0331             }
0332             ColumnLayout {
0333                 id: labelColumn
0334                 spacing: 0
0335                 Layout.fillWidth: true
0336                 Layout.alignment: Qt.AlignVCenter
0337                 QQC2.Label {
0338                     id: labelItem
0339                     text: listItem.text
0340                     Layout.fillWidth: true
0341                     Layout.alignment: subtitleItem.visible ? Qt.AlignLeft | Qt.AlignBottom : Qt.AlignLeft | Qt.AlignVCenter
0342                     color: (listItem.highlighted || listItem.checked || listItem.down) ? listItem.activeTextColor : listItem.textColor
0343                     elide: Text.ElideRight
0344                     font.weight: listItem.bold ? Font.Bold : Font.Normal
0345                     opacity: listItem.fadeContent ? 0.6 : 1.0
0346                 }
0347                 QQC2.Label {
0348                     id: subtitleItem
0349                     Layout.fillWidth: true
0350                     Layout.alignment: subtitleItem.visible ? Qt.AlignLeft | Qt.AlignTop : Qt.AlignLeft | Qt.AlignVCenter
0351                     color: (listItem.highlighted || listItem.checked || listItem.down) ? listItem.activeTextColor : listItem.textColor
0352                     elide: Text.ElideRight
0353                     font: Kirigami.Theme.smallFont
0354                     opacity: listItem.fadeContent ? 0.6 : (listItem.bold ? 0.9 : 0.7)
0355                     visible: text.length > 0
0356                 }
0357                 QQC2.ToolTip.text: {
0358                     let txt = "";
0359                     if (labelItem.truncated) {
0360                         txt += labelItem.text;
0361                     }
0362                     if (subtitleItem.truncated) {
0363                         if (txt.length > 0) {
0364                             txt += "<br/><br/>";
0365                         }
0366                         txt += subtitleItem.text;
0367                     }
0368                     return txt;
0369                 }
0370                 QQC2.ToolTip.visible: toolTipVisible && QQC2.ToolTip.text.length > 0 && (Kirigami.Settings.tabletMode ? listItem.pressed : listItem.hovered)
0371                 QQC2.ToolTip.delay: Kirigami.Settings.tabletMode ? Qt.styleHints.mousePressAndHoldInterval : Kirigami.Units.toolTipDelay
0372             }
0373         }
0374     }
0375 }