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

0001 /* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
0002  * SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  */
0005 
0006 import QtQuick
0007 import QtQuick.Layouts
0008 import QtQuick.Controls as QQC2
0009 import QtQuick.Templates as T
0010 import org.kde.kirigami as Kirigami
0011 
0012 /**
0013  * @brief Navigation buttons to be used for the NavigationTabBar component.
0014  *
0015  * It supplies its own padding, and also supports using the QQC2 AbstractButton ``display`` property to be used in column lists.
0016  *
0017  * Alternative way to the "actions" property on NavigationTabBar, as it can be used
0018  * with Repeater to generate buttons from models.
0019  *
0020  * Example usage:
0021  * @code{.qml}
0022  * Kirigami.NavigationTabBar {
0023  *      id: navTabBar
0024  *      Kirigami.NavigationTabButton {
0025  *          visible: true
0026  *          icon.name: "document-save"
0027  *          text: `test ${tabIndex + 1}`
0028  *          QQC2.ButtonGroup.group: navTabBar.tabGroup
0029  *      }
0030  *      Kirigami.NavigationTabButton {
0031  *          visible: false
0032  *          icon.name: "document-send"
0033  *          text: `test ${tabIndex + 1}`
0034  *          QQC2.ButtonGroup.group: navTabBar.tabGroup
0035  *      }
0036  *      actions: [
0037  *          Kirigami.Action {
0038  *              visible: true
0039  *              icon.name: "edit-copy"
0040  *              icon.height: 32
0041  *              icon.width: 32
0042  *              text: `test 3`
0043  *              checked: true
0044  *          },
0045  *          Kirigami.Action {
0046  *              visible: true
0047  *              icon.name: "edit-cut"
0048  *              text: `test 4`
0049  *              checkable: true
0050  *          },
0051  *          Kirigami.Action {
0052  *              visible: false
0053  *              icon.name: "edit-paste"
0054  *              text: `test 5`
0055  *          },
0056  *          Kirigami.Action {
0057  *              visible: true
0058  *              icon.source: "../logo.png"
0059  *              text: `test 6`
0060  *              checkable: true
0061  *          }
0062  *      ]
0063  *  }
0064  * @endcode
0065  *
0066  * @since 5.87
0067  * @since org.kde.kirigami 2.19
0068  * @inherit QtQuick.Templates.TabButton
0069  */
0070 T.TabButton {
0071     id: control
0072 
0073     /**
0074      * @brief This property tells the index of this tab within the tab bar.
0075      */
0076     readonly property int tabIndex: {
0077         let tabIdx = 0
0078         for (const child of parent.children) {
0079             if (child === this) {
0080                 return tabIdx
0081             }
0082             // Checking for AbstractButtons because any AbstractButton can act as a tab
0083             if (child instanceof T.AbstractButton) {
0084                 ++tabIdx
0085             }
0086         }
0087         return -1
0088     }
0089 
0090     // FIXME: all those internal properties should go, and the button should style itself in a more standard way
0091     // probably similar to view items
0092     readonly property color __foregroundColor: Qt.alpha(Kirigami.Theme.textColor, 0.85)
0093     readonly property color __highlightForegroundColor: Qt.alpha(Kirigami.Theme.textColor, 0.85)
0094 
0095     readonly property color __pressedColor: Qt.alpha(Kirigami.Theme.highlightColor, 0.3)
0096     readonly property color __hoverSelectColor: Qt.alpha(Kirigami.Theme.highlightColor, 0.2)
0097     readonly property color __checkedBorderColor: Qt.alpha(Kirigami.Theme.highlightColor, 0.7)
0098     readonly property color __pressedBorderColor: Qt.alpha(Kirigami.Theme.highlightColor, 0.9)
0099 
0100     readonly property real __verticalMargins: (display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.largeSpacing : 0
0101 
0102     implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
0103                             implicitContentWidth + leftPadding + rightPadding)
0104     implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
0105                              implicitContentHeight + topPadding + bottomPadding)
0106 
0107     display: T.AbstractButton.TextUnderIcon
0108 
0109     Kirigami.Theme.colorSet: Kirigami.Theme.Window
0110     Kirigami.Theme.inherit: false
0111 
0112     hoverEnabled: true
0113 
0114     padding: Kirigami.Units.smallSpacing
0115     spacing: Kirigami.Units.smallSpacing
0116 
0117     icon.height: display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
0118     icon.width: display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
0119     icon.color: checked ? __highlightForegroundColor : __foregroundColor
0120 
0121     Kirigami.MnemonicData.enabled: enabled && visible
0122     Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
0123     Kirigami.MnemonicData.label: text
0124 
0125     Accessible.onPressAction: control.action.trigger()
0126 
0127     background: Rectangle {
0128         Kirigami.Theme.colorSet: Kirigami.Theme.Button
0129         Kirigami.Theme.inherit: false
0130 
0131         implicitHeight: (control.display === T.AbstractButton.TextBesideIcon) ? 0 : (Kirigami.Units.gridUnit * 3 + Kirigami.Units.smallSpacing * 2)
0132 
0133         color: "transparent"
0134 
0135         Rectangle {
0136             width: parent.width - Kirigami.Units.largeSpacing
0137             height: parent.height - Kirigami.Units.largeSpacing
0138             anchors.centerIn: parent
0139 
0140             radius: Kirigami.Units.smallSpacing
0141             color: control.down ? control.__pressedColor : (control.checked || control.hovered ? control.__hoverSelectColor : "transparent")
0142 
0143             border.color: control.checked ? control.__checkedBorderColor : (control.down ? control.__pressedBorderColor : color)
0144             border.width: 1
0145 
0146             Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
0147             Behavior on border.color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
0148         }
0149     }
0150 
0151     contentItem: GridLayout {
0152         columnSpacing: 0
0153         rowSpacing: (label.visible && label.lineCount > 1) ? 0 : control.spacing
0154 
0155         // if this is a row or a column
0156         columns: control.display !== T.AbstractButton.TextBesideIcon ? 1 : 2
0157 
0158         Kirigami.Icon {
0159             id: icon
0160             source: control.icon.name || control.icon.source
0161             visible: (control.icon.name.length > 0 || control.icon.source.toString().length > 0) && control.display !== T.AbstractButton.TextOnly
0162             color: control.icon.color
0163 
0164             Layout.topMargin: control.__verticalMargins
0165             Layout.bottomMargin: control.__verticalMargins
0166             Layout.leftMargin: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.gridUnit : 0
0167             Layout.rightMargin: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.gridUnit : 0
0168 
0169             Layout.alignment: {
0170                 if (control.display === T.AbstractButton.TextBesideIcon) {
0171                     // row layout
0172                     return Qt.AlignVCenter | Qt.AlignRight;
0173                 } else {
0174                     // column layout
0175                     return Qt.AlignHCenter | ((!label.visible || label.lineCount > 1) ? Qt.AlignVCenter : Qt.AlignBottom);
0176                 }
0177             }
0178             implicitHeight: source ? control.icon.height : 0
0179             implicitWidth: source ? control.icon.width : 0
0180 
0181             Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
0182         }
0183         QQC2.Label {
0184             id: label
0185 
0186             text: control.Kirigami.MnemonicData.richTextLabel
0187             horizontalAlignment: (control.display === T.AbstractButton.TextBesideIcon) ? Text.AlignLeft : Text.AlignHCenter
0188 
0189             visible: control.display !== T.AbstractButton.IconOnly
0190             wrapMode: Text.Wrap
0191             elide: Text.ElideMiddle
0192             color: control.checked ? control.__highlightForegroundColor : control.__foregroundColor
0193 
0194             font.bold: control.checked
0195             font.family: Kirigami.Theme.smallFont.family
0196             font.pointSize: {
0197                 if (control.display === T.AbstractButton.TextBesideIcon) {
0198                     // row layout
0199                     return Kirigami.Theme.defaultFont.pointSize;
0200                 } else {
0201                     // column layout
0202                     return icon.visible ? Kirigami.Theme.smallFont.pointSize : Kirigami.Theme.defaultFont.pointSize * 1.20; // 1.20 is equivalent to level 2 heading
0203                 }
0204             }
0205 
0206             Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
0207 
0208             Layout.topMargin: control.__verticalMargins
0209             Layout.bottomMargin: control.__verticalMargins
0210 
0211             Layout.alignment: {
0212                 if (control.display === T.AbstractButton.TextBesideIcon) {
0213                     // row layout
0214                     return Qt.AlignVCenter | Qt.AlignLeft;
0215                 } else {
0216                     // column layout
0217                     return icon.visible ? Qt.AlignHCenter | Qt.AlignTop : Qt.AlignCenter;
0218                 }
0219             }
0220 
0221             // Work around bold text changing implicit size
0222             Layout.preferredWidth: boldMetrics.implicitWidth
0223             Layout.preferredHeight: boldMetrics.implicitHeight * label.lineCount
0224             Layout.fillWidth: true
0225 
0226             Accessible.ignored: true
0227 
0228             QQC2.Label {
0229                 id: boldMetrics
0230                 visible: false
0231                 text: label.text
0232                 font.bold: true
0233                 font.family: Kirigami.Theme.smallFont.family
0234                 font.pointSize: Kirigami.Theme.smallFont.pointSize
0235                 horizontalAlignment: Text.AlignHCenter
0236                 wrapMode: Text.Wrap
0237                 elide: Text.ElideMiddle
0238 
0239                 Accessible.ignored: true
0240             }
0241         }
0242     }
0243 }