Kirigami2

PrivateActionToolButton.qml
1/*
2 * SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7import QtQuick
8import QtQml
9import QtQuick.Controls as QQC2
10import QtQuick.Templates as T
11
12import org.kde.kirigami as Kirigami
13
14QQC2.ToolButton {
15 id: control
16
17 signal menuAboutToShow()
18
19 hoverEnabled: true
20
21 display: QQC2.ToolButton.TextBesideIcon
22
23 property bool showMenuArrow: !Kirigami.DisplayHint.displayHintSet(action, Kirigami.DisplayHint.HideChildIndicator)
24
25 property list<T.Action> menuActions: {
26 if (action instanceof Kirigami.Action) {
27 return action.children;
28 }
29 return []
30 }
31
32 property Component menuComponent: ActionsMenu {
33 submenuComponent: ActionsMenu { }
34 }
35
36 property T.Menu menu: null
37
38 // We create the menu instance only when there are any actual menu items.
39 // This also happens in the background, avoiding slowdowns due to menu item
40 // creation on the main thread.
41 onMenuActionsChanged: {
42 if (menuComponent && menuActions.length > 0) {
43 if (!menu) {
44 const setupIncubatedMenu = incubatedMenu => {
45 menu = incubatedMenu
46 // Important: We handle the press on parent in the parent, so ignore it here.
47 menu.closePolicy = QQC2.Popup.CloseOnEscape | QQC2.Popup.CloseOnPressOutsideParent
48 menu.closed.connect(() => control.checked = false)
49 menu.actions = control.menuActions
50 }
51 const incubator = menuComponent.incubateObject(control, { actions: menuActions })
52 if (incubator.status !== Component.Ready) {
53 incubator.onStatusChanged = status => {
54 if (status === Component.Ready) {
55 setupIncubatedMenu(incubator.object)
56 }
57 }
58 } else {
59 setupIncubatedMenu(incubator.object);
60 }
61 } else {
62 menu.actions = menuActions
63 }
64 }
65 }
66
67 visible: action instanceof Kirigami.Action ? action.visible : true
68 autoExclusive: action instanceof Kirigami.Action ? action.autoExclusive : false
69
70 // Workaround for QTBUG-85941
71 Binding {
72 target: control
73 property: "checkable"
74 value: (control.action?.checkable ?? false) || (control.menuActions.length > 0)
75 restoreMode: Binding.RestoreBinding
76 }
77
78 // Important: This cannot be a direct onVisibleChanged handler in the button
79 // because it breaks action assignment if we do that. However, this slightly
80 // more indirect Connections object does not have that effect.
81 Connections {
82 target: control
83 function onVisibleChanged() {
84 if (!control.visible && control.menu && control.menu.visible) {
85 control.menu.dismiss()
86 }
87 }
88 }
89
90 onToggled: {
91 if (menuActions.length > 0 && menu) {
92 if (checked) {
93 control.menuAboutToShow();
94 menu.popup(control, 0, control.height)
95 } else {
96 menu.dismiss()
97 }
98 }
99 }
100
101 QQC2.ToolTip {
102 visible: control.hovered && text.length > 0 && !(control.menu && control.menu.visible) && !control.pressed
103 text: {
104 const a = control.action;
105 if (a) {
106 if (a.tooltip) {
107 return a.tooltip;
108 } else if (control.display === QQC2.Button.IconOnly) {
109 return a.text;
110 }
111 }
112 return "";
113 }
114 }
115
116 // This will set showMenuArrow when using qqc2-desktop-style.
117 Accessible.role: (control.showMenuArrow && control.menuActions.length > 0) ? Accessible.ButtonMenu : Accessible.Button
118 Accessible.ignored: !visible
119 Accessible.onPressAction: {
120 if (control.checkable) {
121 control.toggle();
122 } else {
123 control.action.trigger();
124 }
125 }
126}
Q_SCRIPTABLE CaptureState status()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 3 2025 11:48:03 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.