Port QMacCocoaViewContainer to Qt 5.

Includes example.

Change-Id: Ifdda5c535d0ec41694712405d921b2c32cb8dfc8
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
This commit is contained in:
Morten Johan Sørvig 2013-09-02 13:49:24 +02:00 committed by The Qt Project
parent f370f77e48
commit 68b42cd595
6 changed files with 130 additions and 31 deletions

View File

@ -1,5 +1,7 @@
TEMPLATE = subdirs
macx {
SUBDIRS = \
qmacnativewidget
}
qmacnativewidget \
qmacnativewidget
}

View File

@ -0,0 +1,67 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtMacExtras module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtWidgets>
#include <Cocoa/Cocoa.h>
#include <QMacCocoaViewContainer>
class WindowWidget : public QWidget
{
public:
WindowWidget()
{
QMacCocoaViewContainer *cocoaViewContainer = new QMacCocoaViewContainer(0, this);
cocoaViewContainer->move(100, 100);
cocoaViewContainer->resize(300, 300);
NSTextView *text = [[NSTextView alloc] initWithFrame : NSMakeRect(0, 0, 300, 300)];
cocoaViewContainer->setCocoaView(text);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
WindowWidget widget;
widget.show();
return app.exec();
}

View File

@ -0,0 +1,7 @@
TEMPLATE = app
OBJECTIVE_SOURCES += main.mm
LIBS += -framework Cocoa
QT += widgets

View File

@ -44,20 +44,20 @@
#include <QtWidgets/QWidget>
Q_FORWARD_DECLARE_OBJC_CLASS(NSView);
QT_BEGIN_NAMESPACE
class QMacCocoaViewContainerPrivate;
class Q_WIDGETS_EXPORT QMacCocoaViewContainer : public QWidget
{
Q_OBJECT
public:
QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent = 0);
QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent = 0);
virtual ~QMacCocoaViewContainer();
void setCocoaView(void *cocoaViewToWrap);
void *cocoaView() const;
void setCocoaView(NSView *view);
NSView *cocoaView() const;
private:
Q_DECLARE_PRIVATE(QMacCocoaViewContainer)

View File

@ -40,9 +40,12 @@
****************************************************************************/
#import <Cocoa/Cocoa.h>
#include <private/qwidget_p.h>
#include "qmaccocoaviewcontainer_mac.h"
#include <private/qt_mac_p.h>
#include <QtCore/QDebug>
#include <QtGui/QWindow>
#include <qpa/qplatformnativeinterface.h>
#include <private/qwidget_p.h>
/*!
\class QMacCocoaViewContainer
@ -91,6 +94,20 @@
QT_BEGIN_NAMESPACE
namespace {
// TODO use QtMacExtras copy of this function when available.
inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePlatformFunction(const QByteArray &functionName)
{
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
nativeInterface->nativeResourceFunctionForIntegration(functionName);
if (!function)
qWarning() << "Qt could not resolve function" << functionName
<< "from QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()";
return function;
}
} //namespsace
class QMacCocoaViewContainerPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QMacCocoaViewContainer)
@ -111,20 +128,22 @@ QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate()
}
/*!
\fn QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent)
\fn QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent)
Create a new QMacCocoaViewContainer using the NSView pointer in \a
cocoaViewToWrap with parent, \a parent. QMacCocoaViewContainer will
retain \a cocoaViewToWrap.
\a cocoaViewToWrap is a void pointer that allows the header to be included
with C++ source.
*/
QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent)
QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *view, QWidget *parent)
: QWidget(*new QMacCocoaViewContainerPrivate, parent, 0)
{
if (cocoaViewToWrap)
setCocoaView(cocoaViewToWrap);
if (view)
setCocoaView(view);
// QMacCocoaViewContainer requires a native window handle.
setAttribute(Qt::WA_NativeWindow);
}
/*!
@ -132,33 +151,37 @@ QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *p
*/
QMacCocoaViewContainer::~QMacCocoaViewContainer()
{
}
/*!
Returns the NSView that has been set on this container. The returned view
has been autoreleased, so you will need to retain it if you want to make
use of it.
Returns the NSView that has been set on this container.
*/
void *QMacCocoaViewContainer::cocoaView() const
NSView *QMacCocoaViewContainer::cocoaView() const
{
Q_D(const QMacCocoaViewContainer);
return [[d->nsview retain] autorelease];
return d->nsview;
}
/*!
Sets the NSView to contain to be \a cocoaViewToWrap and retains it. If this
container already had a view set, it will release the previously set view.
*/
void QMacCocoaViewContainer::setCocoaView(void *cocoaViewToWrap)
void QMacCocoaViewContainer::setCocoaView(NSView *view)
{
Q_D(QMacCocoaViewContainer);
QMacCocoaAutoReleasePool pool;
NSView *view = static_cast<NSView *>(cocoaViewToWrap);
NSView *oldView = d->nsview;
destroy(true, true);
[view retain];
d->nsview = view;
create(WId(d->nsview), false, true);
// Create window and platformwindow
winId();
QPlatformWindow *platformWindow = this->windowHandle()->handle();
// Set the new view as the content view for the window.
typedef void (*SetWindowContentViewFunction)(QPlatformWindow *window, NSView *nsview);
reinterpret_cast<SetWindowContentViewFunction>(resolvePlatformFunction("setwindowcontentview"))(platformWindow, view);
[oldView release];
}

View File

@ -143,21 +143,21 @@ SOURCES += \
macx {
HEADERS += \
widgets/qmacnativewidget_mac.h
widgets/qmacnativewidget_mac.h \
widgets/qmaccocoaviewcontainer_mac.h
OBJECTIVE_SOURCES += \
widgets/qmenu_mac.mm \
widgets/qmacnativewidget_mac.mm
widgets/qmacnativewidget_mac.mm \
widgets/qmaccocoaviewcontainer_mac.mm
}
# TODO
false:mac {
HEADERS += widgets/qmaccocoaviewcontainer_mac.h
OBJECTIVE_HEADERS += widgets/qcocoatoolbardelegate_mac_p.h \
widgets/qcocoamenu_mac_p.h
OBJECTIVE_SOURCES += widgets/qmaccocoaviewcontainer_mac.mm \
widgets/qcocoatoolbardelegate_mac.mm \
widgets/qmainwindowlayout_mac.mm \
OBJECTIVE_SOURCES += widgets/qcocoatoolbardelegate_mac.mm \
widgets/qmainwindowlayout_mac.mm
}