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
26 MenuBarItem is used as a default \l {MenuBar::}{delegate} type for MenuBar.
27 Notice that it is not necessary to declare MenuBarItem instances by hand when
28 using MenuBar. It is sufficient to declare Menu instances as children of the
29 MenuBar and the respective items are created automatically.
30
31 \sa {Customizing MenuBar}, MenuBar, {Menu Controls}
32*/
33
34/*!
35 \qmlsignal void QtQuick.Controls::MenuBarItem::triggered()
36
37 This signal is emitted when the menu bar item is triggered by the user.
38*/
39
40void QQuickMenuBarItemPrivate::setMenuBar(QQuickMenuBar *newMenuBar)
41{
42 Q_Q(QQuickMenuBarItem);
43 if (menuBar == newMenuBar)
44 return;
45
46 menuBar = newMenuBar;
47 emit q->menuBarChanged();
48}
49
51{
52 // This is inspired by the code in keyReleaseEvent
53
54 Q_Q(QQuickMenuBarItem);
55
56 // We override these event functions so that we can emit triggered here.
57 // We can't just connect clicked to triggered, because that would cause mouse clicks
58 // to open the menu, when only presses should.
59 emit q->triggered();
60}
61
62bool QQuickMenuBarItemPrivate::handlePress(const QPointF &point, ulong timestamp)
63{
64 Q_Q(QQuickMenuBarItem);
65 const bool handled = QQuickAbstractButtonPrivate::handlePress(point, timestamp);
66 if (!handled)
67 return false;
68
69 const bool wasTouchPress = touchId != -1;
70 if (!wasTouchPress) {
71 // Open the menu when it's a mouse press.
72 emit q->triggered();
73 }
74
75 return true;
76}
77
78bool QQuickMenuBarItemPrivate::handleRelease(const QPointF &point, ulong timestamp)
79{
80 Q_Q(QQuickMenuBarItem);
81 const bool wasTouchPress = touchId != -1;
82 const bool handled = QQuickAbstractButtonPrivate::handleRelease(point, timestamp);
83 if (!handled)
84 return false;
85
86 if (wasDoubleClick || !wasTouchPress) {
87 // Don't open the menu on mouse release, as it should be done on press.
88 return handled;
89 }
90
91 if (wasTouchPress) {
92 // Open the menu.
93 emit q->triggered();
94 }
95
96 return true;
97}
98
100{
101 return QQuickTheme::palette(QQuickTheme::MenuBar);
102}
103
104QQuickMenuBarItem::QQuickMenuBarItem(QQuickItem *parent)
105 : QQuickAbstractButton(*(new QQuickMenuBarItemPrivate), parent)
106{
107 setFocusPolicy(Qt::NoFocus);
108 d_func()->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Fixed);
109}
110
111/*!
112 \qmlproperty Menu QtQuick.Controls::MenuBarItem::menuBar
113 \readonly
114
115 This property holds the menu bar that contains this item,
116 or \c null if the item is not in a menu bar.
117*/
118QQuickMenuBar *QQuickMenuBarItem::menuBar() const
119{
120 Q_D(const QQuickMenuBarItem);
121 return d->menuBar;
122}
123
124/*!
125 \qmlproperty Menu QtQuick.Controls::MenuBarItem::menu
126
127 This property holds the menu that this item presents in a
128 menu bar, or \c null if this item does not have a menu.
129*/
130QQuickMenu *QQuickMenuBarItem::menu() const
131{
132 Q_D(const QQuickMenuBarItem);
133 return d->menu;
134}
135
136void QQuickMenuBarItem::setMenu(QQuickMenu *menu)
137{
138 Q_D(QQuickMenuBarItem);
139 if (d->menu == menu)
140 return;
141
142 if (d->menu)
143 disconnect(d->menu, &QQuickMenu::titleChanged, this, &QQuickAbstractButton::setText);
144
145 if (menu) {
146 setText(menu->title());
147 menu->setY(height());
148 menu->setParentItem(this);
149 menu->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent | QQuickPopup::CloseOnReleaseOutsideParent);
150 connect(menu, &QQuickMenu::titleChanged, this, &QQuickAbstractButton::setText);
151 }
152
153 d->menu = menu;
154 emit menuChanged();
155}
156
157/*!
158 \qmlproperty bool QtQuick.Controls::MenuBarItem::highlighted
159
160 This property holds whether the menu bar item is highlighted by the user.
161
162 A menu bar item can be highlighted by mouse hover or keyboard navigation.
163
164 The default value is \c false.
165*/
166bool QQuickMenuBarItem::isHighlighted() const
167{
168 Q_D(const QQuickMenuBarItem);
169 return d->highlighted;
170}
171
172void QQuickMenuBarItem::setHighlighted(bool highlighted)
173{
174 Q_D(QQuickMenuBarItem);
175 if (highlighted == d->highlighted)
176 return;
177
178 d->highlighted = highlighted;
179 emit highlightedChanged();
180}
181
182bool QQuickMenuBarItem::event(QEvent *event)
183{
184#if QT_CONFIG(shortcut)
185 Q_D(QQuickMenuBarItem);
186 if (event->type() == QEvent::Shortcut) {
187 auto *shortcutEvent = static_cast<QShortcutEvent *>(event);
188 if (shortcutEvent->shortcutId() == d->shortcutId) {
189 d->trigger();
190 emit triggered();
191 return true;
192 }
193 }
194#endif
195 return QQuickControl::event(event);
196}
197
198void QQuickMenuBarItem::keyPressEvent(QKeyEvent *event)
199{
200 Q_D(QQuickMenuBarItem);
201 QQuickControl::keyPressEvent(event);
202 if (d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) {
203 d->setPressPoint(d->centerPressPoint());
204 setPressed(true);
205 emit pressed();
206 event->accept();
207 }
208}
209
210void QQuickMenuBarItem::keyReleaseEvent(QKeyEvent *event)
211{
212 Q_D(QQuickMenuBarItem);
213 QQuickControl::keyReleaseEvent(event);
214 if (d->pressed && d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) {
215 setPressed(false);
216 emit released();
217 d->trigger();
218 // We override these event functions so that we can emit triggered here.
219 // We can't just connect clicked to triggered, because that would cause mouse clicks
220 // to open the menu, when only presses should.
221 emit triggered();
222 event->accept();
223 }
224}
225
226void QQuickMenuBarItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
227{
228 Q_D(QQuickMenuBarItem);
229 QQuickAbstractButton::geometryChange(newGeometry, oldGeometry);
230 if (d->menu)
231 d->menu->setY(newGeometry.height());
232}
233
234QFont QQuickMenuBarItem::defaultFont() const
235{
236 return QQuickTheme::font(QQuickTheme::MenuBar);
237}
238
239#if QT_CONFIG(accessibility)
240QAccessible::Role QQuickMenuBarItem::accessibleRole() const
241{
242 return QAccessible::MenuBar;
243}
244#endif
245
246QT_END_NAMESPACE
247
248#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