1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2017 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the plugins of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QWINDOWSMENU_H 41 #define QWINDOWSMENU_H 42 43 #include "qtwindowsglobal.h" 44 45 #include <qpa/qplatformmenu.h> 46 47 #include <QtCore/qvector.h> 48 #include <QtCore/qpair.h> 49 50 QT_BEGIN_NAMESPACE 51 52 class QDebug; 53 54 class QWindowsMenu; 55 class QWindowsMenuBar; 56 class QWindowsWindow; 57 58 class QWindowsMenuItem : public QPlatformMenuItem 59 { 60 Q_OBJECT 61 public: 62 explicit QWindowsMenuItem(QWindowsMenu *parentMenu = nullptr); 63 ~QWindowsMenuItem() override; 64 65 void setText(const QString &text) override; 66 void setIcon(const QIcon &icon) override; 67 void setMenu(QPlatformMenu *menu) override; 68 void setVisible(bool isVisible) override; 69 void setIsSeparator(bool isSeparator) override; setFont(const QFont &)70 void setFont(const QFont &) override {} setRole(MenuRole)71 void setRole(MenuRole) override {} 72 void setCheckable(bool checkable) override; 73 void setChecked(bool isChecked) override; 74 #ifndef QT_NO_SHORTCUT 75 void setShortcut(const QKeySequence& shortcut) override; 76 #endif 77 void setEnabled(bool enabled) override; 78 void setIconSize(int size) override; 79 parentMenu()80 const QWindowsMenu *parentMenu() const { return m_parentMenu; } parentMenu()81 QWindowsMenu *parentMenu() { return m_parentMenu; } 82 HMENU parentMenuHandle() const; subMenu()83 QWindowsMenu *subMenu() const { return m_subMenu; } id()84 UINT_PTR id() const { return m_id; } setId(uint id)85 void setId(uint id) { m_id = id; } 86 UINT state() const; text()87 QString text() const { return m_text; } 88 QString nativeText() const; isVisible()89 bool isVisible() const { return m_visible; } 90 91 void insertIntoMenu(QWindowsMenu *menuItem, bool append, int index); 92 bool removeFromMenu(); 93 94 #ifndef QT_NO_DEBUG_STREAM 95 void formatDebug(QDebug &d) const; 96 #endif 97 98 private: 99 void updateBitmap(); 100 void freeBitmap(); 101 void updateText(); 102 void insertIntoMenuHelper(QWindowsMenu *menu, bool append, int index); 103 104 QWindowsMenu *m_parentMenu = nullptr; 105 QWindowsMenu *m_subMenu = nullptr; 106 UINT_PTR m_id; // Windows Id sent as wParam with WM_COMMAND or submenu handle. 107 QString m_text; 108 QIcon m_icon; 109 HBITMAP m_hbitmap = nullptr; 110 int m_iconSize = 0; 111 bool m_separator = false; 112 bool m_visible = true; 113 bool m_checkable = false; 114 bool m_checked = false; 115 bool m_enabled = true; 116 QKeySequence m_shortcut; 117 }; 118 119 class QWindowsMenu : public QPlatformMenu 120 { 121 Q_OBJECT 122 public: 123 using MenuItems = QVector<QWindowsMenuItem *>; 124 125 QWindowsMenu(); 126 ~QWindowsMenu(); 127 128 void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) override; 129 void removeMenuItem(QPlatformMenuItem *menuItem) override; syncMenuItem(QPlatformMenuItem *)130 void syncMenuItem(QPlatformMenuItem *) override {} syncSeparatorsCollapsible(bool)131 void syncSeparatorsCollapsible(bool) override {} 132 133 void setText(const QString &text) override; 134 void setIcon(const QIcon &icon) override; 135 void setEnabled(bool enabled) override; isEnabled()136 bool isEnabled() const override { return m_enabled; } 137 void setVisible(bool visible) override; 138 139 QPlatformMenuItem *menuItemAt(int position) const override; 140 QPlatformMenuItem *menuItemForTag(quintptr tag) const override; 141 142 QPlatformMenuItem *createMenuItem() const override; 143 QPlatformMenu *createSubMenu() const override; 144 menuHandle()145 HMENU menuHandle() const { return m_hMenu; } id()146 UINT_PTR id() const { return reinterpret_cast<UINT_PTR>(m_hMenu); } text()147 QString text() const { return m_text; } menuItems()148 const MenuItems &menuItems() const { return m_menuItems; } 149 QWindowsMenuItem *itemForSubMenu(const QWindowsMenu *subMenu) const; 150 parentMenuBar()151 const QWindowsMenuBar *parentMenuBar() const { return m_parentMenuBar; } 152 HMENU parentMenuBarHandle() const; parentMenu()153 const QWindowsMenu *parentMenu() const { return m_parentMenu; } 154 void setAsItemSubMenu(QWindowsMenuItem *item); notifyRemoved(QWindowsMenuItem * item)155 void notifyRemoved(QWindowsMenuItem *item) { m_menuItems.removeOne(item); } 156 HMENU parentMenuHandle() const; 157 HMENU parentHandle() const; isVisible()158 bool isVisible() const { return m_visible; } 159 void insertIntoMenuBar(QWindowsMenuBar *bar, bool append, int index); 160 bool removeFromParent(); 161 162 #ifndef QT_NO_DEBUG_STREAM 163 void formatDebug(QDebug &d) const; 164 #endif 165 166 protected: 167 explicit QWindowsMenu(QWindowsMenu *parentMenu, HMENU menu); 168 169 private: 170 QWindowsMenuBar *m_parentMenuBar = nullptr; 171 QWindowsMenu *m_parentMenu = nullptr; 172 MenuItems m_menuItems; 173 HMENU m_hMenu = nullptr; 174 QString m_text; 175 QIcon m_icon; 176 bool m_visible = true; 177 bool m_enabled = true; 178 }; 179 180 class QWindowsPopupMenu : public QWindowsMenu 181 { 182 Q_OBJECT 183 public: 184 QWindowsPopupMenu(); 185 186 static bool notifyTriggered(uint id); 187 static bool notifyAboutToShow(HMENU hmenu); 188 189 void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) override; dismiss()190 void dismiss() override {} 191 192 bool trackPopupMenu(HWND windowHandle, int x, int y); 193 }; 194 195 class QWindowsMenuBar : public QPlatformMenuBar 196 { 197 Q_OBJECT 198 public: 199 using Menus = QVector<QWindowsMenu *>; 200 201 QWindowsMenuBar(); 202 ~QWindowsMenuBar() override; 203 204 void insertMenu(QPlatformMenu *menu, QPlatformMenu *before) override; 205 void removeMenu(QPlatformMenu *menu) override; syncMenu(QPlatformMenu *)206 void syncMenu(QPlatformMenu *) override {} 207 void handleReparent(QWindow *newParentWindow) override; 208 209 QPlatformMenu *menuForTag(quintptr tag) const override; 210 QPlatformMenu *createMenu() const override; 211 menuBarHandle()212 HMENU menuBarHandle() const { return m_hMenuBar; } menus()213 const Menus &menus() const { return m_menus; } 214 bool notifyTriggered(uint id); 215 bool notifyAboutToShow(HMENU hmenu); notifyRemoved(QWindowsMenu * menu)216 void notifyRemoved(QWindowsMenu *menu) { m_menus.removeOne(menu); } 217 void redraw() const; 218 219 void install(QWindowsWindow *window); 220 221 static QWindowsMenuBar *menuBarOf(const QWindow *notYetCreatedWindow); 222 223 #ifndef QT_NO_DEBUG_STREAM 224 void formatDebug(QDebug &d) const; 225 #endif 226 227 private: 228 QWindowsWindow *platformWindow() const; 229 void removeFromWindow(); 230 231 Menus m_menus; 232 HMENU m_hMenuBar = nullptr; 233 }; 234 235 #ifndef QT_NO_DEBUG_STREAM 236 QDebug operator<<(QDebug d, const QPlatformMenuItem *); 237 QDebug operator<<(QDebug d, const QPlatformMenu *); 238 QDebug operator<<(QDebug d, const QPlatformMenuBar *); 239 #endif // !QT_NO_DEBUG_STREAM 240 241 QT_END_NAMESPACE 242 243 #endif // QWINDOWSMENU_H 244