Kirigami2

GlobalDrawerActionItem.qml
1/*
2 * SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7pragma ComponentBehavior: Bound
8
9import QtQuick
10import QtQuick.Controls as QQC2
11import QtQuick.Controls.impl as QQC2Impl
12import QtQuick.Layouts
13import QtQuick.Templates as T
14import org.kde.kirigami as Kirigami
15
16QQC2.ItemDelegate {
17 id: listItem
18
19 required property T.Action tAction
20 // `as` case operator is still buggy
21 readonly property Kirigami.Action kAction: tAction instanceof Kirigami.Action ? tAction : null
22
23 readonly property bool actionVisible: kAction?.visible ?? true
24 readonly property bool isSeparator: kAction?.separator ?? false
25 readonly property bool isExpandable: kAction?.expandible ?? false
26 readonly property bool hasChildren: kAction ? kAction.children.length > 0 : false
27 readonly property bool hasVisibleMenu: actionsMenu?.visible ?? false
28 readonly property bool hasToolTip: kAction ? kAction.tooltip !== "" : false
29
30 checked: checkedBinding()
31 highlighted: checked
32 activeFocusOnTab: true
33
34 width: parent.width
35
36 contentItem: RowLayout {
37 spacing: Kirigami.Units.largeSpacing
38
39 Kirigami.Icon {
40 id: iconItem
41 color: listItem.tAction.icon.color
42 source: listItem.tAction.icon.name || listItem.tAction.icon.source
43
44 readonly property int size: Kirigami.Units.iconSizes.smallMedium
45 Layout.minimumHeight: size
46 Layout.maximumHeight: size
47 Layout.minimumWidth: size
48 Layout.maximumWidth: size
49
50 selected: (listItem.highlighted || listItem.checked || listItem.down)
51 visible: source !== undefined && !listItem.isSeparator
52 }
53
54 QQC2Impl.MnemonicLabel {
55 id: labelItem
56 visible: !listItem.isSeparator
57 text: width > height * 2 ? listItem.Kirigami.MnemonicData.mnemonicLabel : ""
58 Accessible.name: listItem.Kirigami.MnemonicData.plainTextLabel
59
60 // Work around Qt bug where left aligned text is not right aligned
61 // in RTL mode unless horizontalAlignment is explicitly set.
62 // https://bugreports.qt.io/browse/QTBUG-95873
63 horizontalAlignment: Text.AlignLeft
64
65 Layout.fillWidth: true
66 mnemonicVisible: listItem.Kirigami.MnemonicData.active
67 color: (listItem.highlighted || listItem.checked || listItem.down) ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor
68 elide: Text.ElideRight
69 font: listItem.font
70 opacity: {
71 if (root.collapsed) {
72 return 0;
73 } else if (!listItem.enabled) {
74 return 0.6;
75 } else {
76 return 1.0;
77 }
78 }
79 Behavior on opacity {
80 NumberAnimation {
81 duration: Kirigami.Units.longDuration/2
82 easing.type: Easing.InOutQuad
83 }
84 }
85 }
86
87 Kirigami.Separator {
88 id: separatorAction
89
90 visible: listItem.isSeparator
91 Layout.fillWidth: true
92 }
93
94 Kirigami.Icon {
95 isMask: true
96 Layout.alignment: Qt.AlignVCenter
97 Layout.leftMargin: !root.collapsed ? 0 : -width
98 Layout.preferredHeight: !root.collapsed ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.small/2
99 opacity: 0.7
100 selected: listItem.checked || listItem.down
101 Layout.preferredWidth: Layout.preferredHeight
102 source: listItem.mirrored ? "go-next-symbolic-rtl" : "go-next-symbolic"
103 visible: (!listItem.isExpandable || root.collapsed) && !listItem.isSeparator && listItem.hasChildren
104 }
105 }
106
107 Accessible.name: Kirigami.MnemonicData.plainTextLabel
108 Kirigami.MnemonicData.enabled: enabled && visible
109 Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
110 Kirigami.MnemonicData.label: tAction?.text ?? ""
111
112 Shortcut {
113 sequence: listItem.Kirigami.MnemonicData.sequence
114 onActivated: listItem.clicked()
115 }
116
117 property ActionsMenu actionsMenu: ActionsMenu {
118 x: Qt.application.layoutDirection === Qt.RightToLeft ? -width : listItem.width
119 actions: listItem.kAction?.children ?? []
120 submenuComponent: ActionsMenu {}
121
122 onVisibleChanged: {
123 if (visible) {
124 stackView.openSubMenu = listItem.actionsMenu;
125 } else if (stackView.openSubMenu === listItem.actionsMenu) {
126 stackView.openSubMenu = null;
127 }
128 }
129 }
130
131 // TODO: animate the hide by collapse
132 visible: actionVisible && opacity > 0
133 opacity: !root.collapsed || iconItem.source.toString().length > 0
134
135 Behavior on opacity {
136 NumberAnimation {
137 duration: Kirigami.Units.longDuration / 2
138 easing.type: Easing.InOutQuad
139 }
140 }
141
142 enabled: tAction?.enabled ?? false
143
144 hoverEnabled: (!isExpandable || root.collapsed) && !Kirigami.Settings.tabletMode && !isSeparator
145 font.pointSize: isExpandable ? Kirigami.Theme.defaultFont.pointSize * 1.30 : Kirigami.Theme.defaultFont.pointSize
146 height: implicitHeight * opacity
147
148 QQC2.ToolTip {
149 visible: !listItem.isSeparator
150 && (listItem.hasToolTip || root.collapsed)
151 && !listItem.hasVisibleMenu
152 && listItem.hovered
153 && text.length > 0
154
155 text: (listItem.kAction?.tooltip || listItem.tAction?.text) ?? ""
156 delay: Kirigami.Units.toolTipDelay
157 y: (listItem.height - height) / 2
158 x: Qt.application.layoutDirection === Qt.RightToLeft ? -width : listItem.width
159 }
160
161 onHoveredChanged: {
162 if (!hovered) {
163 return;
164 }
165 if (stackView.openSubMenu) {
166 stackView.openSubMenu.visible = false;
167
168 if (actionsMenu.count > 0) {
169 actionsMenu.popup(this, width, 0);
170 }
171 }
172 }
173
174 onClicked: trigger()
175 Accessible.onPressAction: trigger()
176 Keys.onEnterPressed: event => trigger()
177 Keys.onReturnPressed: event => trigger()
178
179 function trigger() {
180 tAction?.trigger();
181
182 if (hasChildren) {
183 if (root.collapsed) {
184 if (actionsMenu.count > 0 && !actionsMenu.visible) {
185 stackView.openSubMenu = actionsMenu;
186 actionsMenu.popup(this, width, 0);
187 }
188 } else {
189 stackView.push(menuComponent, {
190 model: kAction?.children ?? [],
191 level: level + 1,
192 current: tAction,
193 });
194 }
195 } else if (root.resetMenuOnTriggered) {
196 root.resetMenu();
197 }
198 checked = Qt.binding(() => checkedBinding());
199 }
200
201 function checkedBinding(): bool {
202 return (tAction?.checked || actionsMenu?.visible) ?? false;
203 }
204
205 Keys.onDownPressed: event => nextItemInFocusChain().focus = true
206 Keys.onUpPressed: event => nextItemInFocusChain(false).focus = true
207}
QStringView level(QStringView ifopt)
RightToLeft
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 21 2025 11:47:53 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.