Merge branch 'bugfix/osx-implementation'

This commit is contained in:
Lukas Dürrenberger 2014-06-04 11:48:31 +02:00
commit 265c411c39
7 changed files with 149 additions and 47 deletions

View File

@ -133,7 +133,8 @@ Vector2i InputImpl::getMousePosition()
NSPoint pos = [NSEvent mouseLocation]; NSPoint pos = [NSEvent mouseLocation];
pos.y = sf::VideoMode::getDesktopMode().height - pos.y; pos.y = sf::VideoMode::getDesktopMode().height - pos.y;
return Vector2i(pos.x, pos.y); int scale = [[NSScreen mainScreen] backingScaleFactor];
return Vector2i(pos.x, pos.y) * scale;
} }
@ -149,7 +150,8 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
// Use -cursorPositionFromEvent: with nil. // Use -cursorPositionFromEvent: with nil.
NSPoint pos = [view cursorPositionFromEvent:nil]; NSPoint pos = [view cursorPositionFromEvent:nil];
return Vector2i(pos.x, pos.y); int scale = [view displayScaleFactor];
return Vector2i(pos.x, pos.y) * scale;
} }
@ -157,7 +159,8 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
void InputImpl::setMousePosition(const Vector2i& position) void InputImpl::setMousePosition(const Vector2i& position)
{ {
// Here we don't need to reverse the coordinates. // Here we don't need to reverse the coordinates.
CGPoint pos = CGPointMake(position.x, position.y); int scale = [[NSScreen mainScreen] backingScaleFactor];
CGPoint pos = CGPointMake(position.x / scale, position.y / scale);
// Place the cursor. // Place the cursor.
CGEventRef event = CGEventCreateMouseEvent(NULL, CGEventRef event = CGEventCreateMouseEvent(NULL,
@ -180,9 +183,10 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ
return; return;
// Let SFOpenGLView compute the position in global coordinate // Let SFOpenGLView compute the position in global coordinate
NSPoint p = NSMakePoint(position.x, position.y); int scale = [view displayScaleFactor];
NSPoint p = NSMakePoint(position.x / scale, position.y / scale);
p = [view computeGlobalPositionOfRelativePoint:p]; p = [view computeGlobalPositionOfRelativePoint:p];
setMousePosition(sf::Vector2i(p.x, p.y)); setMousePosition(sf::Vector2i(p.x, p.y) * scale);
} }

View File

@ -55,6 +55,7 @@ namespace sf {
BOOL m_mouseIsIn; ///< Mouse positional state BOOL m_mouseIsIn; ///< Mouse positional state
NSTrackingArea* m_trackingArea; ///< Mouse tracking area NSTrackingArea* m_trackingArea; ///< Mouse tracking area
BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not
CGFloat m_scaleFactor; ///< Display scale factor (e.g. 1x for classic display, 2x for retina)
// Hidden text view used to convert key event to actual chars. // Hidden text view used to convert key event to actual chars.
// We use a silent responder to prevent sound alerts. // We use a silent responder to prevent sound alerts.
@ -68,6 +69,8 @@ namespace sf {
/// NB: -initWithFrame: is also implemented to default isFullscreen to NO /// NB: -initWithFrame: is also implemented to default isFullscreen to NO
/// in case SFOpenGLView is created with the standard message. /// in case SFOpenGLView is created with the standard message.
/// ///
/// To finish the initialization -finishInit should be called too.
///
/// \param frameRect dimension of the view /// \param frameRect dimension of the view
/// \param isFullscreen fullscreen flag /// \param isFullscreen fullscreen flag
/// ///
@ -76,6 +79,14 @@ namespace sf {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen; -(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen;
////////////////////////////////////////////////////////////
/// \brief Finish the creation of the SFML OpenGL view
///
/// This method should be called after the view was added to a window
///
////////////////////////////////////////////////////////////
-(void)finishInit;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Apply the given requester to the view /// \brief Apply the given requester to the view
/// ///
@ -106,6 +117,14 @@ namespace sf {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
-(void)disableKeyRepeat; -(void)disableKeyRepeat;
////////////////////////////////////////////////////////////
/// \brief Get the display scale factor
///
/// \return e.g. 1.0 for classic display, 2.0 for retina display
///
////////////////////////////////////////////////////////////
-(CGFloat)displayScaleFactor;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Compute the position of the cursor /// \brief Compute the position of the cursor
/// ///

View File

@ -55,6 +55,12 @@ BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@interface SFOpenGLView () @interface SFOpenGLView ()
////////////////////////////////////////////////////////////
/// \brief Handle screen changed event
///
////////////////////////////////////////////////////////////
-(void)updateScaleFactor;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Handle view resized event /// \brief Handle view resized event
/// ///
@ -154,20 +160,7 @@ BOOL isValidTextUnicode(NSEvent* event);
[self addTrackingArea:m_trackingArea]; [self addTrackingArea:m_trackingArea];
m_fullscreen = isFullscreen; m_fullscreen = isFullscreen;
m_scaleFactor = 1.0; // Default value; it will be updated in finishInit
// Register for window focus events
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidBecomeKey:)
name:NSWindowDidBecomeKeyNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidResignKey:)
name:NSWindowDidResignKeyNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidResignKey:)
name:NSWindowWillCloseNotification
object:[self window]];
// Create a hidden text view for parsing key down event properly // Create a hidden text view for parsing key down event properly
m_silentResponder = [[SFSilentResponder alloc] init]; m_silentResponder = [[SFSilentResponder alloc] init];
@ -176,12 +169,47 @@ BOOL isValidTextUnicode(NSEvent* event);
// Request high resolution on high DPI displays // Request high resolution on high DPI displays
[self setWantsBestResolutionOpenGLSurface:YES]; [self setWantsBestResolutionOpenGLSurface:YES];
// At that point, the view isn't attached to a window. We defer the rest of
// the initialization process to later.
} }
return self; return self;
} }
////////////////////////////////////////////////////////
-(void)finishInit
{
// Register for window focus events
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidBecomeKey:)
name:NSWindowDidBecomeKeyNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidResignKey:)
name:NSWindowDidResignKeyNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidResignKey:)
name:NSWindowWillCloseNotification
object:[self window]];
// Register for changed screen and changed screen's profile events
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateScaleFactor)
name:NSWindowDidChangeScreenNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateScaleFactor)
name:NSWindowDidChangeScreenProfileNotification
object:[self window]];
// Now that we have a window, set up correctly the scale factor
[self updateScaleFactor];
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester -(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
{ {
@ -234,6 +262,22 @@ BOOL isValidTextUnicode(NSEvent* event);
} }
////////////////////////////////////////////////////////
-(CGFloat)displayScaleFactor
{
return m_scaleFactor;
}
////////////////////////////////////////////////////////
-(void)updateScaleFactor
{
NSWindow* window = [self window];
NSScreen* screen = window ? [window screen] : [NSScreen mainScreen];
m_scaleFactor = [screen backingScaleFactor];
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)viewDidEndLiveResize -(void)viewDidEndLiveResize
{ {

View File

@ -71,6 +71,8 @@
[m_view addSubview:m_oglView]; [m_view addSubview:m_oglView];
[m_oglView setAutoresizingMask:[m_view autoresizingMask]]; [m_oglView setAutoresizingMask:[m_view autoresizingMask]];
[m_oglView finishInit];
} }
return self; return self;
@ -89,6 +91,13 @@
} }
////////////////////////////////////////////////////////
-(CGFloat)displayScaleFactor
{
return [m_oglView displayScaleFactor];
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester -(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
{ {

View File

@ -149,6 +149,8 @@
[self setupFullscreenViewWithMode:mode]; [self setupFullscreenViewWithMode:mode];
else else
[self setupWindowWithMode:mode andStyle:style]; [self setupWindowWithMode:mode andStyle:style];
[m_oglView finishInit];
} }
return self; return self;
} }
@ -306,6 +308,13 @@
#pragma mark WindowImplDelegateProtocol's methods #pragma mark WindowImplDelegateProtocol's methods
////////////////////////////////////////////////////////
-(CGFloat)displayScaleFactor
{
return [m_oglView displayScaleFactor];
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester -(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
{ {

View File

@ -43,6 +43,15 @@ namespace sf
namespace priv namespace priv
{ {
////////////////////////////////////////////////////////////
/// \brief Get the scale factor of the main screen
///
////////////////////////////////////////////////////////////
CGFloat getDefaultScaleFactor()
{
return [[NSScreen mainScreen] backingScaleFactor];
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Scale SFML coordinates to backing coordinates /// \brief Scale SFML coordinates to backing coordinates
/// ///
@ -50,27 +59,27 @@ namespace priv
/// has a retina display or not. /// has a retina display or not.
/// ///
/// \param in SFML coordinates to be converted /// \param in SFML coordinates to be converted
/// \param delegate a object implementing WindowImplDelegateProtocol, or nil for default scale
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <class T> template <class T>
void scaleIn(T& in) void scaleIn(T& in, id<WindowImplDelegateProtocol> delegate)
{ {
CGFloat scale = [[NSScreen mainScreen] backingScaleFactor]; in /= delegate ? [delegate displayScaleFactor] : getDefaultScaleFactor();
in /= scale;
} }
template <class T> template <class T>
void scaleInWidthHeight(T& in) void scaleInWidthHeight(T& in, id<WindowImplDelegateProtocol> delegate)
{ {
scaleIn(in.width); scaleIn(in.width, delegate);
scaleIn(in.height); scaleIn(in.height, delegate);
} }
template <class T> template <class T>
void scaleInXY(T& in) void scaleInXY(T& in, id<WindowImplDelegateProtocol> delegate)
{ {
scaleIn(in.x); scaleIn(in.x, delegate);
scaleIn(in.y); scaleIn(in.y, delegate);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -80,27 +89,27 @@ void scaleInXY(T& in)
/// has a retina display or not. /// has a retina display or not.
/// ///
/// \param out backing coordinates to be converted /// \param out backing coordinates to be converted
/// \param delegate a object implementing WindowImplDelegateProtocol, or nil for default scale
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <class T> template <class T>
void scaleOut(T& out) void scaleOut(T& out, id<WindowImplDelegateProtocol> delegate)
{ {
CGFloat scale = [[NSScreen mainScreen] backingScaleFactor]; out *= delegate ? [delegate displayScaleFactor] : getDefaultScaleFactor();
out *= scale;
} }
template <class T> template <class T>
void scaleOutWidthHeight(T& out) void scaleOutWidthHeight(T& out, id<WindowImplDelegateProtocol> delegate)
{ {
scaleOut(out.width); scaleOut(out.width, delegate);
scaleOut(out.height); scaleOut(out.height, delegate);
} }
template <class T> template <class T>
void scaleOutXY(T& out) void scaleOutXY(T& out, id<WindowImplDelegateProtocol> delegate)
{ {
scaleOut(out.x); scaleOut(out.x, delegate);
scaleOut(out.y); scaleOut(out.y, delegate);
} }
#pragma mark #pragma mark
@ -159,7 +168,7 @@ m_showCursor(true)
retainPool(); retainPool();
// Use backing size // Use backing size
scaleInWidthHeight(mode); scaleInWidthHeight(mode, nil);
m_delegate = [[SFWindowController alloc] initWithMode:mode andStyle:style]; m_delegate = [[SFWindowController alloc] initWithMode:mode andStyle:style];
[m_delegate changeTitle:sfStringToNSString(title)]; [m_delegate changeTitle:sfStringToNSString(title)];
@ -250,7 +259,7 @@ void WindowImplCocoa::windowResized(unsigned int width, unsigned int height)
event.type = Event::Resized; event.type = Event::Resized;
event.size.width = width; event.size.width = width;
event.size.height = height; event.size.height = height;
scaleOutWidthHeight(event.size); scaleOutWidthHeight(event.size, m_delegate);
pushEvent(event); pushEvent(event);
} }
@ -293,7 +302,7 @@ void WindowImplCocoa::mouseDownAt(Mouse::Button button, int x, int y)
event.mouseButton.button = button; event.mouseButton.button = button;
event.mouseButton.x = x; event.mouseButton.x = x;
event.mouseButton.y = y; event.mouseButton.y = y;
scaleOutXY(event.mouseButton); scaleOutXY(event.mouseButton, m_delegate);
pushEvent(event); pushEvent(event);
} }
@ -307,7 +316,7 @@ void WindowImplCocoa::mouseUpAt(Mouse::Button button, int x, int y)
event.mouseButton.button = button; event.mouseButton.button = button;
event.mouseButton.x = x; event.mouseButton.x = x;
event.mouseButton.y = y; event.mouseButton.y = y;
scaleOutXY(event.mouseButton); scaleOutXY(event.mouseButton, m_delegate);
pushEvent(event); pushEvent(event);
} }
@ -320,7 +329,7 @@ void WindowImplCocoa::mouseMovedAt(int x, int y)
event.type = Event::MouseMoved; event.type = Event::MouseMoved;
event.mouseMove.x = x; event.mouseMove.x = x;
event.mouseMove.y = y; event.mouseMove.y = y;
scaleOutXY(event.mouseMove); scaleOutXY(event.mouseMove, m_delegate);
pushEvent(event); pushEvent(event);
} }
@ -333,7 +342,7 @@ void WindowImplCocoa::mouseWheelScrolledAt(float delta, int x, int y)
event.mouseWheel.delta = delta; event.mouseWheel.delta = delta;
event.mouseWheel.x = x; event.mouseWheel.x = x;
event.mouseWheel.y = y; event.mouseWheel.y = y;
scaleOutXY(event.mouseWheel); scaleOutXY(event.mouseWheel, m_delegate);
pushEvent(event); pushEvent(event);
} }
@ -424,7 +433,7 @@ Vector2i WindowImplCocoa::getPosition() const
{ {
NSPoint pos = [m_delegate position]; NSPoint pos = [m_delegate position];
sf::Vector2i ret(pos.x, pos.y); sf::Vector2i ret(pos.x, pos.y);
scaleOutXY(ret); scaleOutXY(ret, m_delegate);
return ret; return ret;
} }
@ -433,7 +442,7 @@ Vector2i WindowImplCocoa::getPosition() const
void WindowImplCocoa::setPosition(const Vector2i& position) void WindowImplCocoa::setPosition(const Vector2i& position)
{ {
sf::Vector2i backingPosition = position; sf::Vector2i backingPosition = position;
scaleInXY(backingPosition); scaleInXY(backingPosition, m_delegate);
[m_delegate setWindowPositionToX:backingPosition.x Y:backingPosition.y]; [m_delegate setWindowPositionToX:backingPosition.x Y:backingPosition.y];
} }
@ -443,7 +452,7 @@ Vector2u WindowImplCocoa::getSize() const
{ {
NSSize size = [m_delegate size]; NSSize size = [m_delegate size];
Vector2u ret(size.width, size.height); Vector2u ret(size.width, size.height);
scaleOutXY(ret); scaleOutXY(ret, m_delegate);
return ret; return ret;
} }
@ -452,7 +461,7 @@ Vector2u WindowImplCocoa::getSize() const
void WindowImplCocoa::setSize(const Vector2u& size) void WindowImplCocoa::setSize(const Vector2u& size)
{ {
sf::Vector2u backingSize = size; sf::Vector2u backingSize = size;
scaleInXY(backingSize); scaleInXY(backingSize, m_delegate);
[m_delegate resizeTo:backingSize.x by:backingSize.y]; [m_delegate resizeTo:backingSize.x by:backingSize.y];
} }

View File

@ -66,6 +66,14 @@ namespace sf {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@protocol WindowImplDelegateProtocol @protocol WindowImplDelegateProtocol
////////////////////////////////////////////////////////////
/// \brief Get the display scale factor
///
/// \return e.g. 1.0 for classic display, 2.0 for retina display
///
////////////////////////////////////////////////////////////
-(CGFloat)displayScaleFactor;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Set the WindowImpl who requested this delegate /// \brief Set the WindowImpl who requested this delegate
/// ///