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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtdeclarative/src/quicktemplates/qquickmenubaritem.cpp