Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickmenubaritem.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
8#include "qquickmenu_p.h"
9
11
12/*!
13 \qmltype MenuBarItem
14 \inherits AbstractButton
15//! \nativetype QQuickMenuBarItem
16 \inqmlmodule QtQuick.Controls
17 \since 5.10
18 \ingroup qtquickcontrols-menus
19 \brief Presents a drop-down menu within a MenuBar.
20
21 MenuBarItem presents a Menu within a MenuBar. The respective drop-down menu
22 is shown when a MenuBarItem is \l triggered via keyboard, mouse, or touch.
23
24 \image qtquickcontrols-menubar.png
25 {Menu bar with File, Edit, and View menus}
26
27 MenuBarItem is used as a default \l {MenuBar::}{delegate} type for MenuBar.
28 Notice that it is not necessary to declare MenuBarItem instances by hand when
29 using MenuBar. It is sufficient to declare Menu instances as children of the
30 MenuBar and the respective items are created automatically.
31
32 \sa {Customizing MenuBar}, MenuBar, {Menu Controls}
33*/
34
35/*!
36 \qmlsignal void QtQuick.Controls::MenuBarItem::triggered()
37
38 This signal is emitted when the menu bar item is triggered by the user.
39*/
40
41void QQuickMenuBarItemPrivate::setMenuBar(QQuickMenuBar *newMenuBar)
42{
43 Q_Q(QQuickMenuBarItem);
44 if (menuBar == newMenuBar)
45 return;
46
47 menuBar = newMenuBar;
48 emit q->menuBarChanged();
49}
50
52{
53 // This is inspired by the code in keyReleaseEvent
54
55 Q_Q(QQuickMenuBarItem);
56
57 // We override these event functions so that we can emit triggered here.
58 // We can't just connect clicked to triggered, because that would cause mouse clicks
59 // to open the menu, when only presses should.
60 emit q->triggered();
61}
62
63bool QQuickMenuBarItemPrivate::handlePress(const QPointF &point, ulong timestamp)
64{
65 Q_Q(QQuickMenuBarItem);
66 const bool handled = QQuickAbstractButtonPrivate::handlePress(point, timestamp);
67 if (!handled)
68 return false;
69
70 const bool wasTouchPress = touchId != -1;
71 if (!wasTouchPress) {
72 // Open the menu when it's a mouse press.
73 emit q->triggered();
74 }
75
76 return true;
77}
78
79bool QQuickMenuBarItemPrivate::handleRelease(const QPointF &point, ulong timestamp)
80{
81 Q_Q(QQuickMenuBarItem);
82 const bool wasTouchPress = touchId != -1;
83 const bool handled = QQuickAbstractButtonPrivate::handleRelease(point, timestamp);
84 if (!handled)
85 return false;
86
87 if (wasDoubleClick || !wasTouchPress) {
88 // Don't open the menu on mouse release, as it should be done on press.
89 return handled;
90 }
91
92 if (wasTouchPress) {
93 // Open the menu.
94 emit q->triggered();
95 }
96
97 return true;
98}
99
101{
102 return QQuickTheme::palette(QQuickTheme::MenuBar);
103}
104
105QQuickMenuBarItem::QQuickMenuBarItem(QQuickItem *parent)
106 : QQuickAbstractButton(*(new QQuickMenuBarItemPrivate), parent)
107{
108 setFocusPolicy(Qt::NoFocus);
109 d_func()->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Fixed);
110}
111
112/*!
113 \qmlproperty Menu QtQuick.Controls::MenuBarItem::menuBar
114 \readonly
115
116 This property holds the menu bar that contains this item,
117 or \c null if the item is not in a menu bar.
118*/
119QQuickMenuBar *QQuickMenuBarItem::menuBar() const
120{
121 Q_D(const QQuickMenuBarItem);
122 return d->menuBar;
123}
124
125/*!
126 \qmlproperty Menu QtQuick.Controls::MenuBarItem::menu
127
128 This property holds the menu that this item presents in a
129 menu bar, or \c null if this item does not have a menu.
130*/
131QQuickMenu *QQuickMenuBarItem::menu() const
132{
133 Q_D(const QQuickMenuBarItem);
134 return d->menu;
135}
136
137void QQuickMenuBarItem::setMenu(QQuickMenu *menu)
138{
139 Q_D(QQuickMenuBarItem);
140 if (d->menu == menu)
141 return;
142
143 if (d->menu)
144 disconnect(d->menu, &QQuickMenu::titleChanged, this, &QQuickAbstractButton::setText);
145
146 if (menu) {
147 setText(menu->title());
148 menu->setY(height());
149 menu->setParentItem(this);
150 menu->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent | QQuickPopup::CloseOnReleaseOutsideParent);
151 connect(menu, &QQuickMenu::titleChanged, this, &QQuickAbstractButton::setText);
152 }
153
154 d->menu = menu;
155 emit menuChanged();
156}
157
158/*!
159 \qmlproperty bool QtQuick.Controls::MenuBarItem::highlighted
160
161 This property holds whether the menu bar item is highlighted by the user.
162
163 A menu bar item can be highlighted by mouse hover or keyboard navigation.
164
165 The default value is \c false.
166*/
167bool QQuickMenuBarItem::isHighlighted() const
168{
169 Q_D(const QQuickMenuBarItem);
170 return d->highlighted;
171}
172
173void QQuickMenuBarItem::setHighlighted(bool highlighted)
174{
175 Q_D(QQuickMenuBarItem);
176 if (highlighted == d->highlighted)
177 return;
178
179 d->highlighted = highlighted;
180 emit highlightedChanged();
181}
182
183bool QQuickMenuBarItem::event(QEvent *event)
184{
185#if QT_CONFIG(shortcut)
186 Q_D(QQuickMenuBarItem);
187 if (event->type() == QEvent::Shortcut) {
188 auto *shortcutEvent = static_cast<QShortcutEvent *>(event);
189 if (shortcutEvent->shortcutId() == d->shortcutId) {
190 d->trigger();
191 emit triggered();
192 return true;
193 }
194 }
195#endif
196 return QQuickControl::event(event);
197}
198
199void QQuickMenuBarItem::keyPressEvent(QKeyEvent *event)
200{
201 Q_D(QQuickMenuBarItem);
202 QQuickControl::keyPressEvent(event);
203 if (d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) {
204 d->setPressPoint(d->centerPressPoint());
205 setPressed(true);
206 emit pressed();
207 event->accept();
208 }
209}
210
211void QQuickMenuBarItem::keyReleaseEvent(QKeyEvent *event)
212{
213 Q_D(QQuickMenuBarItem);
214 QQuickControl::keyReleaseEvent(event);
215 if (d->pressed && d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) {
216 setPressed(false);
217 emit released();
218 d->trigger();
219 // We override these event functions so that we can emit triggered here.
220 // We can't just connect clicked to triggered, because that would cause mouse clicks
221 // to open the menu, when only presses should.
222 emit triggered();
223 event->accept();
224 }
225}
226
227void QQuickMenuBarItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
228{
229 Q_D(QQuickMenuBarItem);
230 QQuickAbstractButton::geometryChange(newGeometry, oldGeometry);
231 if (d->menu)
232 d->menu->setY(newGeometry.height());
233}
234
235QFont QQuickMenuBarItem::defaultFont() const
236{
237 return QQuickTheme::font(QQuickTheme::MenuBar);
238}
239
240#if QT_CONFIG(accessibility)
241QAccessible::Role QQuickMenuBarItem::accessibleRole() const
242{
243 return QAccessible::MenuBar;
244}
245#endif
246
247QT_END_NAMESPACE
248
249#include "moc_qquickmenubaritem_p.cpp"
bool handleRelease(const QPointF &point, ulong timestamp) override
QPalette defaultPalette() const override
void accessiblePressAction() override
bool handlePress(const QPointF &point, ulong timestamp) override
Combined button and popup list for selecting options.