From 9fa5191b6eca7fc96b4720d9b892b0e2a8ff1469 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 4 Jan 2013 14:55:36 +0100 Subject: [PATCH] QPA, Cocoa: Add platform popup menus Also, allow to set menu-wide font (instead of per menu item), and minimum width. Change-Id: I5f83f260602f55b9409ad69abf670afb59b2d33a Reviewed-by: Paul Olav Tvete --- src/gui/kernel/qplatformmenu.h | 10 ++++++ src/plugins/platforms/cocoa/qcocoamenu.h | 6 +++- src/plugins/platforms/cocoa/qcocoamenu.mm | 37 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index 7e7ccdb294..785adedce3 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -103,6 +103,16 @@ public: virtual void setText(const QString &text) = 0; virtual void setEnabled(bool enabled) = 0; virtual void setVisible(bool visible) = 0; + virtual void setMinimumWidth(int width) { Q_UNUSED(width); } + virtual void setFont(const QFont &font) { Q_UNUSED(font); } + + virtual void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) + { + Q_UNUSED(parentWindow); + Q_UNUSED(pos); + Q_UNUSED(item); + setVisible(true); + } virtual QPlatformMenuItem *menuItemAt(int position) const = 0; virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0; diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 3afe089225..7407916cfc 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -71,11 +71,15 @@ public: void syncMenuItem(QPlatformMenuItem *menuItem); void setEnabled(bool enabled); void setVisible(bool visible); + void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item); + void syncSeparatorsCollapsible(bool enable); void syncModalState(bool modal); - virtual void setText(const QString &text); + void setText(const QString &text); + void setMinimumWidth(int width); + void setFont(const QFont &font); void setParentItem(QCocoaMenuItem* item); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 676f0683fa..afd007b36a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -47,6 +47,7 @@ #include #include "qcocoaapplication.h" #include "qcocoamenuloader.h" +#include "qcocoawindow.h" static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader() { @@ -133,6 +134,20 @@ void QCocoaMenu::setText(const QString &text) [m_nativeItem setTitle:QCFString::toNSString(stripped)]; } +void QCocoaMenu::setMinimumWidth(int width) +{ + m_nativeMenu.minimumWidth = width; +} + +void QCocoaMenu::setFont(const QFont &font) +{ + if (font.resolve()) { + NSFont *customMenuFont = [NSFont fontWithName:QCFString::toNSString(font.family()) + size:font.pointSize()]; + m_nativeMenu.font = customMenuFont; + } +} + void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) { QCocoaAutoReleasePool pool; @@ -290,6 +305,28 @@ void QCocoaMenu::setVisible(bool visible) [m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)]; } +void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) +{ + QCocoaWindow *cocoaWindow = static_cast(parentWindow->handle()); + NSView *view = cocoaWindow->contentView(); + NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil; + NSPoint nsPos = NSMakePoint(pos.x(), pos.y()); + [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:view]; + + // The call above blocks and swallows the mouse release event, so we send a + // synthetic one to bring back any QQuickMouseArea back to a more normal state. + NSEvent *releaseEvent = [NSEvent mouseEventWithType:NSLeftMouseUp + location:nsPos + modifierFlags:0 + timestamp:0 + windowNumber:view.window.windowNumber + context:[NSGraphicsContext currentContext] + eventNumber:0 + clickCount:0 + pressure:1.0]; + [view.window sendEvent:releaseEvent]; +} + QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const { return m_menuItems.at(position);