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
59 // Work around Qt bug where left aligned text is not right aligned
60 // in RTL mode unless horizontalAlignment is explicitly set.
61 // https://bugreports.qt.io/browse/QTBUG-95873
62 horizontalAlignment: Text.AlignLeft
63
64 Layout.fillWidth: true
65 mnemonicVisible: listItem.Kirigami.MnemonicData.active
66 color: (listItem.highlighted || listItem.checked || listItem.down) ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor
67 elide: Text.ElideRight
68 font: listItem.font
69 opacity: {
70 if (root.collapsed) {
71 return 0;
72 } else if (!listItem.enabled) {
73 return 0.6;
74 } else {
75 return 1.0;
76 }
77 }
78 Behavior on opacity {
79 NumberAnimation {
80 duration: Kirigami.Units.longDuration/2
81 easing.type: Easing.InOutQuad
82 }
83 }
84 }
85
86 Kirigami.Separator {
87 id: separatorAction
88
89 visible: listItem.isSeparator
90 Layout.fillWidth: true
91 }
92
93 Kirigami.Icon {
94 isMask: true
95 Layout.alignment: Qt.AlignVCenter
96 Layout.leftMargin: !root.collapsed ? 0 : -width
97 Layout.preferredHeight: !root.collapsed ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.small/2
98 opacity: 0.7
99 selected: listItem.checked || listItem.down
100 Layout.preferredWidth: Layout.preferredHeight
101 source: listItem.mirrored ? "go-next-symbolic-rtl" : "go-next-symbolic"
102 visible: (!listItem.isExpandable || root.collapsed) && !listItem.isSeparator && listItem.hasChildren
103 }
104 }
105
106 Accessible.name: listItem.tAction?.text ?? ""
107 Kirigami.MnemonicData.enabled: enabled && visible
108 Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
109 Kirigami.MnemonicData.label: tAction?.text ?? ""
110
111 Shortcut {
112 sequence: listItem.Kirigami.MnemonicData.sequence
113 onActivated: listItem.clicked()
114 }
115
116 property ActionsMenu actionsMenu: ActionsMenu {
117 x: Qt.application.layoutDirection === Qt.RightToLeft ? -width : listItem.width
118 actions: listItem.kAction?.children ?? []
119 submenuComponent: ActionsMenu {}
120
121 onVisibleChanged: {
122 if (visible) {
123 stackView.openSubMenu = listItem.actionsMenu;
124 } else if (stackView.openSubMenu === listItem.actionsMenu) {
125 stackView.openSubMenu = null;
126 }
127 }
128 }
129
130 // TODO: animate the hide by collapse
131 visible: actionVisible && opacity > 0
132 opacity: !root.collapsed || iconItem.source.toString().length > 0
133
134 Behavior on opacity {
135 NumberAnimation {
136 duration: Kirigami.Units.longDuration / 2
137 easing.type: Easing.InOutQuad
138 }
139 }
140
141 enabled: tAction?.enabled ?? false
142
143 hoverEnabled: (!isExpandable || root.collapsed) && !Kirigami.Settings.tabletMode && !isSeparator
144 font.pointSize: isExpandable ? Kirigami.Theme.defaultFont.pointSize * 1.30 : Kirigami.Theme.defaultFont.pointSize
145 height: implicitHeight * opacity
146
147 QQC2.ToolTip {
148 visible: !listItem.isSeparator
149 && (listItem.hasToolTip || root.collapsed)
150 && !listItem.hasVisibleMenu
151 && listItem.hovered
152 && text.length > 0
153
154 text: listItem.kAction?.tooltip ?? listItem.tAction?.text ?? ""
155 delay: Kirigami.Units.toolTipDelay
156 y: (listItem.height - height) / 2
157 x: Qt.application.layoutDirection === Qt.RightToLeft ? -width : listItem.width
158 }
159
160 onHoveredChanged: {
161 if (!hovered) {
162 return;
163 }
164 if (stackView.openSubMenu) {
165 stackView.openSubMenu.visible = false;
166
167 if (actionsMenu.count > 0) {
168 actionsMenu.popup(this, width, 0);
169 }
170 }
171 }
172
173 onClicked: trigger()
174 Accessible.onPressAction: trigger()
175 Keys.onEnterPressed: event => trigger()
176 Keys.onReturnPressed: event => trigger()
177
178 function trigger() {
179 tAction?.trigger();
180
181 if (hasChildren) {
182 if (root.collapsed) {
183 if (actionsMenu.count > 0 && !actionsMenu.visible) {
184 stackView.openSubMenu = actionsMenu;
185 actionsMenu.popup(this, width, 0);
186 }
187 } else {
188 stackView.push(menuComponent, {
189 model: kAction?.children ?? [],
190 level: level + 1,
191 current: tAction,
192 });
193 }
194 } else if (root.resetMenuOnTriggered) {
195 root.resetMenu();
196 }
197 checked = Qt.binding(() => checkedBinding());
198 }
199
200 function checkedBinding(): bool {
201 return (tAction?.checked || actionsMenu?.visible) ?? false;
202 }
203
204 Keys.onDownPressed: event => nextItemInFocusChain().focus = true
205 Keys.onUpPressed: event => nextItemInFocusChain(false).focus = true
206}
QStringView level(QStringView ifopt)
RightToLeft
ElideRight
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Apr 27 2024 22:13:10 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.