1 | // Copyright (C) 2020 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 "qquicklabsplatformmenubar_p.h" |
5 | #include "qquicklabsplatformmenu_p.h" |
6 | |
7 | #include <QtCore/qloggingcategory.h> |
8 | #include <QtGui/qpa/qplatformmenu.h> |
9 | #include <QtGui/qpa/qplatformtheme.h> |
10 | #include <QtGui/private/qguiapplication_p.h> |
11 | #include <QtQuick/qquickwindow.h> |
12 | #include <QtQuick/qquickitem.h> |
13 | |
14 | QT_BEGIN_NAMESPACE |
15 | |
16 | /*! |
17 | \qmltype MenuBar |
18 | \inherits QtObject |
19 | //! \instantiates QQuickLabsPlatformMenuBar |
20 | \inqmlmodule Qt.labs.platform |
21 | \since 5.8 |
22 | \brief A native menubar. |
23 | |
24 | The MenuBar type provides a QML API for native platform menubars. |
25 | |
26 | \image qtlabsplatform-menubar.png |
27 | |
28 | A menubar consists of a list of drop-down menus. |
29 | |
30 | \code |
31 | MenuBar { |
32 | id: menuBar |
33 | |
34 | Menu { |
35 | id: fileMenu |
36 | title: qsTr("File") |
37 | // ... |
38 | } |
39 | |
40 | Menu { |
41 | id: editMenu |
42 | title: qsTr("&Edit") |
43 | // ... |
44 | } |
45 | |
46 | Menu { |
47 | id: viewMenu |
48 | title: qsTr("&View") |
49 | // ... |
50 | } |
51 | |
52 | Menu { |
53 | id: helpMenu |
54 | title: qsTr("&Help") |
55 | // ... |
56 | } |
57 | } |
58 | \endcode |
59 | |
60 | MenuBar is currently available on the following platforms: |
61 | |
62 | \list |
63 | \li macOS |
64 | \li Android |
65 | \li Linux (only available on desktop environments that provide a global D-Bus menu bar) |
66 | \li Windows |
67 | \endlist |
68 | |
69 | \labs |
70 | |
71 | \sa Menu |
72 | */ |
73 | |
74 | Q_DECLARE_LOGGING_CATEGORY() |
75 | |
76 | QQuickLabsPlatformMenuBar::(QObject *parent) |
77 | : QObject(parent), |
78 | m_complete(false), |
79 | m_window(nullptr), |
80 | m_handle(nullptr) |
81 | { |
82 | m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); |
83 | qCDebug(qtLabsPlatformMenus) << "MenuBar ->" << m_handle; |
84 | } |
85 | |
86 | QQuickLabsPlatformMenuBar::() |
87 | { |
88 | for (QQuickLabsPlatformMenu * : std::as_const(t&: m_menus)) |
89 | menu->setMenuBar(nullptr); |
90 | delete m_handle; |
91 | m_handle = nullptr; |
92 | } |
93 | |
94 | QPlatformMenuBar *QQuickLabsPlatformMenuBar::handle() const |
95 | { |
96 | return m_handle; |
97 | } |
98 | |
99 | /*! |
100 | \qmldefault |
101 | \qmlproperty list<QtObject> Qt.labs.platform::MenuBar::data |
102 | |
103 | This default property holds the list of all objects declared as children of |
104 | the menubar. The data property includes objects that are not \l Menu instances, |
105 | such as \l Timer and \l QtObject. |
106 | |
107 | \sa menus |
108 | */ |
109 | QQmlListProperty<QObject> QQuickLabsPlatformMenuBar::() |
110 | { |
111 | return QQmlListProperty<QObject>(this, nullptr, data_append, data_count, data_at, data_clear); |
112 | } |
113 | |
114 | /*! |
115 | \qmlproperty list<Menu> Qt.labs.platform::MenuBar::menus |
116 | |
117 | This property holds the list of menus in the menubar. |
118 | */ |
119 | QQmlListProperty<QQuickLabsPlatformMenu> QQuickLabsPlatformMenuBar::() |
120 | { |
121 | return QQmlListProperty<QQuickLabsPlatformMenu>(this, nullptr, menus_append, menus_count, menus_at, menus_clear); |
122 | } |
123 | |
124 | /*! |
125 | \qmlproperty Window Qt.labs.platform::MenuBar::window |
126 | |
127 | This property holds the menubar's window. |
128 | |
129 | Unless explicitly set, the window is automatically resolved by iterating |
130 | the QML parent objects until a \l Window or an \l Item that has a window |
131 | is found. |
132 | */ |
133 | QWindow *QQuickLabsPlatformMenuBar::() const |
134 | { |
135 | return m_window; |
136 | } |
137 | |
138 | void QQuickLabsPlatformMenuBar::(QWindow *window) |
139 | { |
140 | if (m_window == window) |
141 | return; |
142 | |
143 | if (m_handle) |
144 | m_handle->handleReparent(newParentWindow: window); |
145 | |
146 | m_window = window; |
147 | emit windowChanged(); |
148 | } |
149 | |
150 | /*! |
151 | \qmlmethod void Qt.labs.platform::MenuBar::addMenu(Menu menu) |
152 | |
153 | Adds a \a menu to end of the menubar. |
154 | */ |
155 | void QQuickLabsPlatformMenuBar::(QQuickLabsPlatformMenu *) |
156 | { |
157 | insertMenu(index: m_menus.size(), menu); |
158 | } |
159 | |
160 | /*! |
161 | \qmlmethod void Qt.labs.platform::MenuBar::insertMenu(int index, Menu menu) |
162 | |
163 | Inserts a \a menu at the specified \a index in the menubar. |
164 | */ |
165 | void QQuickLabsPlatformMenuBar::(int index, QQuickLabsPlatformMenu *) |
166 | { |
167 | if (!menu || m_menus.contains(t: menu)) |
168 | return; |
169 | |
170 | QQuickLabsPlatformMenu *before = m_menus.value(i: index); |
171 | m_menus.insert(i: index, t: menu); |
172 | m_data.append(t: menu); |
173 | menu->setMenuBar(this); |
174 | if (m_handle) |
175 | m_handle->insertMenu(menu: menu->create(), before: before ? before->handle() : nullptr); |
176 | menu->sync(); |
177 | emit menusChanged(); |
178 | } |
179 | |
180 | /*! |
181 | \qmlmethod void Qt.labs.platform::MenuBar::removeMenu(Menu menu) |
182 | |
183 | Removes a \a menu from the menubar. |
184 | */ |
185 | void QQuickLabsPlatformMenuBar::(QQuickLabsPlatformMenu *) |
186 | { |
187 | if (!menu || !m_menus.removeOne(t: menu)) |
188 | return; |
189 | |
190 | m_data.removeOne(t: menu); |
191 | if (m_handle) |
192 | m_handle->removeMenu(menu: menu->handle()); |
193 | menu->setMenuBar(nullptr); |
194 | emit menusChanged(); |
195 | } |
196 | |
197 | /*! |
198 | \qmlmethod void Qt.labs.platform::MenuBar::clear() |
199 | |
200 | Removes all menus from the menubar. |
201 | */ |
202 | void QQuickLabsPlatformMenuBar::() |
203 | { |
204 | if (m_menus.isEmpty()) |
205 | return; |
206 | |
207 | for (QQuickLabsPlatformMenu * : std::as_const(t&: m_menus)) { |
208 | m_data.removeOne(t: menu); |
209 | if (m_handle) |
210 | m_handle->removeMenu(menu: menu->handle()); |
211 | menu->setMenuBar(nullptr); |
212 | delete menu; |
213 | } |
214 | |
215 | m_menus.clear(); |
216 | emit menusChanged(); |
217 | } |
218 | |
219 | void QQuickLabsPlatformMenuBar::() |
220 | { |
221 | } |
222 | |
223 | void QQuickLabsPlatformMenuBar::() |
224 | { |
225 | m_complete = true; |
226 | for (QQuickLabsPlatformMenu * : std::as_const(t&: m_menus)) |
227 | menu->sync(); |
228 | if (!m_window) |
229 | setWindow(findWindow()); |
230 | } |
231 | |
232 | QWindow *QQuickLabsPlatformMenuBar::() const |
233 | { |
234 | QObject *obj = parent(); |
235 | while (obj) { |
236 | QWindow *window = qobject_cast<QWindow *>(o: obj); |
237 | if (window) |
238 | return window; |
239 | QQuickItem *item = qobject_cast<QQuickItem *>(o: obj); |
240 | if (item && item->window()) |
241 | return item->window(); |
242 | obj = obj->parent(); |
243 | } |
244 | return nullptr; |
245 | } |
246 | |
247 | void QQuickLabsPlatformMenuBar::(QQmlListProperty<QObject> *property, QObject *object) |
248 | { |
249 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
250 | QQuickLabsPlatformMenu * = qobject_cast<QQuickLabsPlatformMenu *>(object); |
251 | if (menu) |
252 | menuBar->addMenu(menu); |
253 | else |
254 | menuBar->m_data.append(t: object); |
255 | } |
256 | |
257 | qsizetype QQuickLabsPlatformMenuBar::(QQmlListProperty<QObject> *property) |
258 | { |
259 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
260 | return menuBar->m_data.size(); |
261 | } |
262 | |
263 | QObject *QQuickLabsPlatformMenuBar::(QQmlListProperty<QObject> *property, qsizetype index) |
264 | { |
265 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
266 | return menuBar->m_data.value(i: index); |
267 | } |
268 | |
269 | void QQuickLabsPlatformMenuBar::(QQmlListProperty<QObject> *property) |
270 | { |
271 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
272 | menuBar->m_data.clear(); |
273 | } |
274 | |
275 | void QQuickLabsPlatformMenuBar::(QQmlListProperty<QQuickLabsPlatformMenu> *property, QQuickLabsPlatformMenu *) |
276 | { |
277 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
278 | menuBar->addMenu(menu); |
279 | } |
280 | |
281 | qsizetype QQuickLabsPlatformMenuBar::(QQmlListProperty<QQuickLabsPlatformMenu> *property) |
282 | { |
283 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
284 | return menuBar->m_menus.size(); |
285 | } |
286 | |
287 | QQuickLabsPlatformMenu *QQuickLabsPlatformMenuBar::(QQmlListProperty<QQuickLabsPlatformMenu> *property, qsizetype index) |
288 | { |
289 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
290 | return menuBar->m_menus.value(i: index); |
291 | } |
292 | |
293 | void QQuickLabsPlatformMenuBar::(QQmlListProperty<QQuickLabsPlatformMenu> *property) |
294 | { |
295 | QQuickLabsPlatformMenuBar * = static_cast<QQuickLabsPlatformMenuBar *>(property->object); |
296 | menuBar->clear(); |
297 | } |
298 | |
299 | QT_END_NAMESPACE |
300 | |
301 | #include "moc_qquicklabsplatformmenubar_p.cpp" |
302 | |