diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2012-11-09 17:08:46 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2013-02-27 23:55:42 +0100 |
commit | e123056c47e33759e740ea2e25771e0cc1899c13 (patch) | |
tree | 7c7973fc60b919ea2daadc51c8ca37861ed69835 /src/plugins | |
parent | 3d81b43aa462c66e11f772398550e76ce4cee6de (diff) |
iOS: Implement QIOSWindow::setGeometry() and pick up UIView geometry changes
The best way to pick up geometry changes of the UIView seems to be to override
layoutSubviews(), but that will only be called if the size of the UIView
changes, not when the position (center) changes. This means that the position
reflected by the QWindow will not always be in sync with the position of the
native UIView. Fortunately the position of a QWindow is not used for anything
critical in Qt itself.
Another issue is that the frame property of a UIView is only valid if the
transform of the UIView is set to the identity transform. We try to catch
cases where this is not the case, and warn the user about this. We could
in theory react to changes in the UIView geometry by only updating the
size, since this is also reflected through the bounds property of the
UIView. This is left for when we know more about how these things
interact in practice.
Change-Id: I079162c059d377a77569fe3974e261d2e0671fd5
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 43 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index c2bf1bb6f0..d16e17124d 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,6 +83,7 @@ public: ~QIOSWindow(); void setGeometry(const QRect &rect); + void updateGeometry(const QRect &rect); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index ce0ea6e0e1..feabaeb47a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -56,6 +56,11 @@ static CGRect toCGRect(const QRect &rect) return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); } +static QRect fromCGRect(const CGRect &rect) +{ + return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + @implementation EAGLView + (Class)layerClass @@ -94,6 +99,24 @@ static CGRect toCGRect(const QRect &rect) return self; } +- (void)layoutSubviews +{ + // This method is the de facto way to know that view has been resized, + // or otherwise needs invalidation of its buffers. Note though that we + // do not get this callback when the view just changes its position, so + // the position of our QWindow (and platform window) will only get updated + // when the size is also changed. + + if (CGAffineTransformIsIdentity(self.transform)) { + // Reflect the new size (and possibly also position) in the QWindow + m_qioswindow->updateGeometry(fromCGRect(self.frame)); + } else { + qWarning() << "QIOSPlatformWindow's UIView has transform set, ignoring geometry updates"; + } + + [super layoutSubviews]; +} + - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { UITouch *touch = [touches anyObject]; @@ -189,9 +212,27 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setGeometry(const QRect &rect) { + if (!CGAffineTransformIsIdentity(m_view.transform)) { + qWarning() << "Setting the geometry of a QWindow with a transform set on the UIView is not supported"; + return; + } + + // Since we don't support transformations on the UIView, we can set the frame + // directly and let UIKit deal with translating that into bounds and center. + m_view.frame = toCGRect(rect); + + updateGeometry(rect); +} + +void QIOSWindow::updateGeometry(const QRect &rect) +{ + // The baseclass implementation will store the geometry, and allows use to + // re-use the baseclass geometry() implementation, which just returns rect. QPlatformWindow::setGeometry(rect); - qDebug() << __FUNCTION__ << "not implemented"; + // We inform Qt about new geometry, which will trigger resize and + // expose events for the application. + QWindowSystemInterface::handleGeometryChange(window(), rect); } GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const |