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

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 pragma ComponentBehavior: Bound
0008 
0009 import QtQuick
0010 import QtQuick.Controls as QQC2
0011 import QtQuick.Controls.impl as QQC2Impl
0012 import QtQuick.Layouts
0013 import QtQuick.Templates as T
0014 import org.kde.kirigami as Kirigami
0015 
0016 QQC2.ItemDelegate {
0017     id: listItem
0018 
0019     required property T.Action tAction
0020     // `as` case operator is still buggy
0021     readonly property Kirigami.Action kAction: tAction instanceof Kirigami.Action ? tAction : null
0022 
0023     readonly property bool actionVisible: kAction?.visible ?? true
0024     readonly property bool isSeparator: kAction?.separator ?? false
0025     readonly property bool isExpandable: kAction?.expandible ?? false
0026     readonly property bool hasChildren: kAction ? kAction.children.length > 0 : false
0027     readonly property bool hasVisibleMenu: actionsMenu?.visible ?? false
0028     readonly property bool hasToolTip: kAction ? kAction.tooltip !== "" : false
0029 
0030     checked: checkedBinding()
0031     highlighted: checked
0032 
0033     width: parent.width
0034 
0035     contentItem: RowLayout {
0036         spacing: Kirigami.Units.largeSpacing
0037 
0038         Kirigami.Icon {
0039             id: iconItem
0040             color: listItem.tAction.icon.color
0041             source: listItem.tAction.icon.name || listItem.tAction.icon.source
0042 
0043             readonly property int size: Kirigami.Units.iconSizes.smallMedium
0044             Layout.minimumHeight: size
0045             Layout.maximumHeight: size
0046             Layout.minimumWidth: size
0047             Layout.maximumWidth: size
0048 
0049             selected: (listItem.highlighted || listItem.checked || listItem.down)
0050             visible: source !== undefined && !listItem.isSeparator
0051         }
0052 
0053         QQC2Impl.MnemonicLabel {
0054             id: labelItem
0055             visible: !listItem.isSeparator
0056             text: width > height * 2 ? listItem.Kirigami.MnemonicData.mnemonicLabel : ""
0057 
0058             // Work around Qt bug where left aligned text is not right aligned
0059             // in RTL mode unless horizontalAlignment is explicitly set.
0060             // https://bugreports.qt.io/browse/QTBUG-95873
0061             horizontalAlignment: Text.AlignLeft
0062 
0063             Layout.fillWidth: true
0064             mnemonicVisible: listItem.Kirigami.MnemonicData.active
0065             color: (listItem.highlighted || listItem.checked || listItem.down) ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor
0066             elide: Text.ElideRight
0067             font: listItem.font
0068             opacity: {
0069                 if (root.collapsed) {
0070                     return 0;
0071                 } else if (!listItem.enabled) {
0072                     return 0.6;
0073                 } else {
0074                     return 1.0;
0075                 }
0076             }
0077             Behavior on opacity {
0078                 NumberAnimation {
0079                     duration: Kirigami.Units.longDuration/2
0080                     easing.type: Easing.InOutQuad
0081                 }
0082             }
0083         }
0084 
0085         Kirigami.Separator {
0086             id: separatorAction
0087 
0088             visible: listItem.isSeparator
0089             Layout.fillWidth: true
0090         }
0091 
0092         Kirigami.Icon {
0093             isMask: true
0094             Layout.alignment: Qt.AlignVCenter
0095             Layout.leftMargin: !root.collapsed ? 0 : -width
0096             Layout.preferredHeight: !root.collapsed ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.small/2
0097             opacity: 0.7
0098             selected: listItem.checked || listItem.down
0099             Layout.preferredWidth: Layout.preferredHeight
0100             source: listItem.mirrored ? "go-next-symbolic-rtl" : "go-next-symbolic"
0101             visible: (!listItem.isExpandable || root.collapsed) && !listItem.isSeparator && listItem.hasChildren
0102         }
0103     }
0104 
0105     Accessible.name: listItem.tAction?.text ?? ""
0106     Kirigami.MnemonicData.enabled: enabled && visible
0107     Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
0108     Kirigami.MnemonicData.label: tAction?.text ?? ""
0109 
0110     Shortcut {
0111         sequence: listItem.Kirigami.MnemonicData.sequence
0112         onActivated: listItem.clicked()
0113     }
0114 
0115     property ActionsMenu actionsMenu: ActionsMenu {
0116         x: Qt.application.layoutDirection === Qt.RightToLeft ? -width : listItem.width
0117         actions: listItem.kAction?.children ?? []
0118         submenuComponent: ActionsMenu {}
0119 
0120         onVisibleChanged: {
0121             if (visible) {
0122                 stackView.openSubMenu = listItem.actionsMenu;
0123             } else if (stackView.openSubMenu === listItem.actionsMenu) {
0124                 stackView.openSubMenu = null;
0125             }
0126         }
0127     }
0128 
0129     // TODO: animate the hide by collapse
0130     visible: actionVisible && opacity > 0
0131     opacity: !root.collapsed || iconItem.source.toString().length > 0
0132 
0133     Behavior on opacity {
0134         NumberAnimation {
0135             duration: Kirigami.Units.longDuration / 2
0136             easing.type: Easing.InOutQuad
0137         }
0138     }
0139 
0140     enabled: tAction?.enabled ?? false
0141 
0142     hoverEnabled: (!isExpandable || root.collapsed) && !Kirigami.Settings.tabletMode && !isSeparator
0143     font.pointSize: isExpandable ? Kirigami.Theme.defaultFont.pointSize * 1.30 : Kirigami.Theme.defaultFont.pointSize
0144     height: implicitHeight * opacity
0145 
0146     QQC2.ToolTip {
0147         visible: !listItem.isSeparator
0148             && (listItem.hasToolTip || root.collapsed)
0149             && !listItem.hasVisibleMenu
0150             && listItem.hovered
0151             && text.length > 0
0152 
0153         text: listItem.kAction?.tooltip ?? listItem.tAction?.text ?? ""
0154         delay: Kirigami.Units.toolTipDelay
0155         y: (listItem.height - height) / 2
0156         x: Qt.application.layoutDirection === Qt.RightToLeft ? -width : listItem.width
0157     }
0158 
0159     onHoveredChanged: {
0160         if (!hovered) {
0161             return;
0162         }
0163         if (stackView.openSubMenu) {
0164             stackView.openSubMenu.visible = false;
0165 
0166             if (actionsMenu.count > 0) {
0167                 actionsMenu.popup(this, width, 0);
0168             }
0169         }
0170     }
0171 
0172     onClicked: trigger()
0173     Accessible.onPressAction: trigger()
0174     Keys.onEnterPressed: event => trigger()
0175     Keys.onReturnPressed: event => trigger()
0176 
0177     function trigger() {
0178         tAction?.trigger();
0179 
0180         if (hasChildren) {
0181             if (root.collapsed) {
0182                 if (actionsMenu.count > 0 && !actionsMenu.visible) {
0183                     stackView.openSubMenu = actionsMenu;
0184                     actionsMenu.popup(this, width, 0);
0185                 }
0186             } else {
0187                 stackView.push(menuComponent, {
0188                     model: kAction?.children ?? [],
0189                     level: level + 1,
0190                     current: tAction,
0191                 });
0192             }
0193         } else if (root.resetMenuOnTriggered) {
0194             root.resetMenu();
0195         }
0196         checked = Qt.binding(() => checkedBinding());
0197     }
0198 
0199     function checkedBinding(): bool {
0200         return (tAction?.checked || actionsMenu?.visible) ?? false;
0201     }
0202 
0203     Keys.onDownPressed: event => nextItemInFocusChain().focus = true
0204     Keys.onUpPressed: event => nextItemInFocusChain(false).focus = true
0205 }