darwin: Add Foundation conversion functions for QRect/QRectF

The fromCGRect function was left out for QRect, as the foundation type is
using CGFloats internally. Clients should use an explicit QRectF::toRect()
when potentially throwing away precision.

Change-Id: I0d4c5c5a4e6a45ea3287e3f37a00b69b0bfdefcf
Reviewed-by: Jake Petroules <jake.petroules@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
This commit is contained in:
Tor Arne Vestbø 2016-05-13 13:30:46 +02:00
parent cbe62a0e6d
commit ebee64645a
15 changed files with 80 additions and 47 deletions

View File

@ -44,9 +44,14 @@
#include <QtCore/qdatetime.h>
#include <QtCore/quuid.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qrect.h>
#import <Foundation/Foundation.h>
#if defined(QT_PLATFORM_UIKIT)
#import <CoreGraphics/CoreGraphics.h>
#endif
QT_BEGIN_NAMESPACE
/*!
@ -415,4 +420,43 @@ NSDate *QDateTime::toNSDate() const
dateWithTimeIntervalSince1970:static_cast<NSTimeInterval>(toMSecsSinceEpoch()) / 1000];
}
// ----------------------------------------------------------------------------
/*!
\since 5.8
Creates a CGRect from a QRect.
\sa fromCGRect()
*/
CGRect QRect::toCGRect() const Q_DECL_NOTHROW
{
return CGRectMake(x(), y(), width(), height());
}
/*!
\since 5.8
Creates a CGRect from a QRectF.
\sa fromCGRect()
*/
CGRect QRectF::toCGRect() const Q_DECL_NOTHROW
{
return CGRectMake(x(), y(), width(), height());
}
/*!
\since 5.8
Creates a QRectF from a CGRect.
\sa toCGRect()
*/
QRectF QRectF::fromCGRect(CGRect rect) Q_DECL_NOTHROW
{
return QRectF(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
}
QT_END_NAMESPACE

View File

@ -48,6 +48,10 @@
#error qrect.h must be included before any header file that defines topLeft
#endif
#if defined(Q_OS_DARWIN)
struct CGRect;
#endif
QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QRect
@ -149,6 +153,10 @@ public:
friend Q_DECL_CONSTEXPR inline bool operator==(const QRect &, const QRect &) Q_DECL_NOTHROW;
friend Q_DECL_CONSTEXPR inline bool operator!=(const QRect &, const QRect &) Q_DECL_NOTHROW;
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
CGRect toCGRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT;
#endif
private:
int x1;
int y1;
@ -604,6 +612,11 @@ public:
Q_DECL_CONSTEXPR inline QRect toRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT;
QRect toAlignedRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT;
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
static QRectF fromCGRect(CGRect rect) Q_DECL_NOTHROW Q_REQUIRED_RESULT;
CGRect toCGRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT;
#endif
private:
qreal xp;
qreal yp;

View File

@ -78,8 +78,6 @@ QImage qt_mac_toQImage(CGImageRef image);
QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size);
NSSize qt_mac_toNSSize(const QSize &qtSize);
NSRect qt_mac_toNSRect(const QRect &rect);
QRect qt_mac_toQRect(const NSRect &rect);
QColor qt_mac_toQColor(const NSColor *color);
QColor qt_mac_toQColor(CGColorRef color);

View File

@ -214,16 +214,6 @@ NSSize qt_mac_toNSSize(const QSize &qtSize)
return NSMakeSize(qtSize.width(), qtSize.height());
}
NSRect qt_mac_toNSRect(const QRect &rect)
{
return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
}
QRect qt_mac_toQRect(const NSRect &rect)
{
return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
}
QColor qt_mac_toQColor(const NSColor *color)
{
QColor qtColor;

View File

@ -505,7 +505,7 @@ QRect QCocoaWindow::geometry() const
NSRect screenRect = [[m_contentView window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
NSPoint screenPoint = screenRect.origin;
QPoint position = qt_mac_flipPoint(screenPoint).toPoint();
QSize size = qt_mac_toQRect([m_contentView bounds]).size();
QSize size = QRectF::fromCGRect([m_contentView bounds]).toRect().size();
return QRect(position, size);
}

View File

@ -322,9 +322,9 @@ static bool _q_dontOverrideCtrlLMB = false;
if (m_platformWindow->m_isNSWindowChild) {
return;
#if 0
//geometry = qt_mac_toQRect([self frame]);
//geometry = QRectF::fromCGRect([self frame]).toRect();
qDebug() << "nsview updateGeometry" << m_platformWindow->window();
QRect screenRect = qt_mac_toQRect([m_platformWindow->m_nsWindow convertRectToScreen:[self frame]]);
QRect screenRect = QRectF::fromCGRect([m_platformWindow->m_nsWindow convertRectToScreen:[self frame]]).toRect();
qDebug() << "screenRect" << screenRect;
screenRect.moveTop(qt_mac_flipYCoordinate(screenRect.y() + screenRect.height()));
@ -339,10 +339,10 @@ static bool _q_dontOverrideCtrlLMB = false;
geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height);
} else if (m_platformWindow->m_contentViewIsToBeEmbedded) {
// embedded child window, use the frame rect ### merge with case below
geometry = qt_mac_toQRect([self bounds]);
geometry = QRectF::fromCGRect([self bounds]).toRect();
} else {
// child window, use the frame rect
geometry = qt_mac_toQRect([self frame]);
geometry = QRectF::fromCGRect([self frame]).toRect();
}
if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry())
@ -555,7 +555,7 @@ static bool _q_dontOverrideCtrlLMB = false;
- (void) drawRect:(NSRect)dirtyRect
{
qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_window << qt_mac_toQRect(dirtyRect);
qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_window << QRectF::fromCGRect(dirtyRect);
#ifndef QT_NO_OPENGL
if (m_glContext && m_shouldSetGLContextinDrawRect) {

View File

@ -61,8 +61,6 @@ class QPlatformScreen;
bool isQtApplication();
CGRect toCGRect(const QRectF &rect);
QRectF fromCGRect(const CGRect &rect);
CGPoint toCGPoint(const QPointF &point);
QPointF fromCGPoint(const CGPoint &point);

View File

@ -58,16 +58,6 @@ bool isQtApplication()
return isQt;
}
CGRect toCGRect(const QRectF &rect)
{
return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
}
QRectF fromCGRect(const CGRect &rect)
{
return QRectF(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
}
CGPoint toCGPoint(const QPointF &point)
{
return CGPointMake(point.x(), point.y());

View File

@ -382,7 +382,7 @@ void QIOSInputContext::updateKeyboardState(NSNotification *notification)
m_keyboardState.animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
m_keyboardState.keyboardAnimating = m_keyboardState.animationDuration > 0 && !atEndOfKeyboardTransition;
qImDebug() << qPrintable(QString::fromNSString(notification.name)) << "from" << fromCGRect(frameBegin) << "to" << fromCGRect(frameEnd)
qImDebug() << qPrintable(QString::fromNSString(notification.name)) << "from" << QRectF::fromCGRect(frameBegin) << "to" << QRectF::fromCGRect(frameEnd)
<< "(curve =" << m_keyboardState.animationCurve << "duration =" << m_keyboardState.animationDuration << "s)";
} else {
qImDebug("No notification to update keyboard state based on, just updating keyboard rect");
@ -391,7 +391,7 @@ void QIOSInputContext::updateKeyboardState(NSNotification *notification)
if (!focusView() || CGRectIsEmpty(currentKeyboardRect))
m_keyboardState.keyboardRect = QRectF();
else // QInputmethod::keyboardRectangle() is documented to be in window coordinates.
m_keyboardState.keyboardRect = fromCGRect([focusView() convertRect:currentKeyboardRect fromView:nil]);
m_keyboardState.keyboardRect = QRectF::fromCGRect([focusView() convertRect:currentKeyboardRect fromView:nil]);
// Emit for all changed properties
if (m_keyboardState.keyboardVisible != previousState.keyboardVisible)

View File

@ -570,7 +570,7 @@ void QIOSMenu::repositionMenu()
switch (m_effectiveMenuType) {
case EditMenu: {
UIView *view = reinterpret_cast<UIView *>(m_parentWindow->winId());
[[UIMenuController sharedMenuController] setTargetRect:toCGRect(m_targetRect) inView:view];
[[UIMenuController sharedMenuController] setTargetRect:m_targetRect.toCGRect() inView:view];
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
break; }
default:

View File

@ -231,11 +231,11 @@ void QIOSScreen::updateProperties()
QRect previousGeometry = m_geometry;
QRect previousAvailableGeometry = m_availableGeometry;
m_geometry = fromCGRect(m_uiScreen.bounds).toRect();
m_geometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect();
#ifndef Q_OS_TVOS
m_availableGeometry = fromCGRect(m_uiScreen.applicationFrame).toRect();
m_availableGeometry = QRectF::fromCGRect(m_uiScreen.applicationFrame).toRect();
#else
m_availableGeometry = fromCGRect(m_uiScreen.bounds).toRect();
m_availableGeometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect();
#endif
#ifndef Q_OS_TVOS
@ -279,7 +279,7 @@ void QIOSScreen::updateProperties()
// before being output on the physical display. We have to take this into account when
// computing the physical size. Note that unlike the native bounds, the physical size
// follows the primary orientation of the screen.
physicalGeometry = mapBetween(nativeOrientation(), primaryOrientation, fromCGRect(m_uiScreen.nativeBounds).toRect());
physicalGeometry = mapBetween(nativeOrientation(), primaryOrientation, QRectF::fromCGRect(m_uiScreen.nativeBounds).toRect());
} else {
physicalGeometry = QRectF(0, 0, m_geometry.width() * devicePixelRatio(), m_geometry.height() * devicePixelRatio());
}

View File

@ -135,7 +135,7 @@ static void executeBlockWithoutAnimation(void (^block)(void))
// first responder, which is normally QIOSTextResponder.
QRectF cr = qApp->inputMethod()->cursorRectangle();
QRectF ar = qApp->inputMethod()->anchorRectangle();
CGRect targetRect = toCGRect(cr.united(ar));
CGRect targetRect = cr.united(ar).toCGRect();
UIView *focusView = reinterpret_cast<UIView *>(qApp->focusWindow()->winId());
[[UIMenuController sharedMenuController] setTargetRect:targetRect inView:focusView];
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
@ -826,8 +826,8 @@ static void executeBlockWithoutAnimation(void (^block)(void))
// Adjust handles and input rect to match the new selection
QRectF inputRect = QGuiApplication::inputMethod()->inputItemClipRectangle();
CGRect cursorRect = toCGRect(QGuiApplication::inputMethod()->cursorRectangle());
CGRect anchorRect = toCGRect(QGuiApplication::inputMethod()->anchorRectangle());
CGRect cursorRect = QGuiApplication::inputMethod()->cursorRectangle().toCGRect();
CGRect anchorRect = QGuiApplication::inputMethod()->anchorRectangle().toCGRect();
if (!_multiLine) {
// Resize the layer a bit bigger to ensure that the handles are
@ -836,7 +836,7 @@ static void executeBlockWithoutAnimation(void (^block)(void))
inputRect.adjust(-margin / 2, -margin, margin / 2, margin);
}
executeBlockWithoutAnimation(^{ _clipRectLayer.frame = toCGRect(inputRect); });
executeBlockWithoutAnimation(^{ _clipRectLayer.frame = inputRect.toCGRect(); });
_cursorLayer.cursorRectangle = [self.focusView.layer convertRect:cursorRect toLayer:_clipRectLayer];
_anchorLayer.cursorRectangle = [self.focusView.layer convertRect:anchorRect toLayer:_clipRectLayer];
_cursorLayer.visible = YES;

View File

@ -807,7 +807,7 @@
[self sendEventToFocusObject:e];
}
return toCGRect(startRect.united(endRect));
return startRect.united(endRect).toCGRect();
}
- (NSArray *)selectionRectsForRange:(UITextRange *)range
@ -825,7 +825,7 @@
// Assume for now that position is always the same as
// cursor index until a better API is in place:
QRectF cursorRect = qApp->inputMethod()->cursorRectangle();
return toCGRect(cursorRect);
return cursorRect.toCGRect();
}
- (void)replaceRange:(UITextRange *)range withText:(NSString *)text

View File

@ -211,7 +211,7 @@ void QIOSWindow::applyGeometry(const QRect &rect)
// The baseclass takes care of persisting this for us.
QPlatformWindow::setGeometry(rect);
m_view.frame = toCGRect(rect);
m_view.frame = rect.toCGRect();
// iOS will automatically trigger -[layoutSubviews:] for resize,
// but not for move, so we force it just in case.

View File

@ -60,7 +60,7 @@
- (id)initWithQIOSWindow:(QIOSWindow *)window
{
if (self = [self initWithFrame:toCGRect(window->geometry())])
if (self = [self initWithFrame:window->geometry().toCGRect()])
m_qioswindow = window;
m_accessibleElements = [[NSMutableArray alloc] init];
@ -153,7 +153,7 @@
// from what we end up with after applying window constraints.
QRect requestedGeometry = m_qioswindow->geometry();
QRect actualGeometry = fromCGRect(self.frame).toRect();
QRect actualGeometry = QRectF::fromCGRect(self.frame).toRect();
// Persist the actual/new geometry so that QWindow::geometry() can
// be queried on the resize event.
@ -188,7 +188,7 @@
QRegion region;
if (m_qioswindow->isExposed()) {
QSize bounds = fromCGRect(self.layer.bounds).toRect().size();
QSize bounds = QRectF::fromCGRect(self.layer.bounds).toRect().size();
Q_ASSERT(m_qioswindow->geometry().size() == bounds);
Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible());