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];
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.
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)
{
// 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.
CGEventRef event = CGEventCreateMouseEvent(NULL,
@ -180,9 +183,10 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ
return;
// 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];
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
NSTrackingArea* m_trackingArea; ///< Mouse tracking area
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.
// 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
/// 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 isFullscreen fullscreen flag
///
@ -76,6 +79,14 @@ namespace sf {
////////////////////////////////////////////////////////////
-(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
///
@ -106,6 +117,14 @@ namespace sf {
////////////////////////////////////////////////////////////
-(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
///

View File

@ -55,6 +55,12 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////////
@interface SFOpenGLView ()
////////////////////////////////////////////////////////////
/// \brief Handle screen changed event
///
////////////////////////////////////////////////////////////
-(void)updateScaleFactor;
////////////////////////////////////////////////////////////
/// \brief Handle view resized event
///
@ -154,7 +160,27 @@ BOOL isValidTextUnicode(NSEvent* event);
[self addTrackingArea:m_trackingArea];
m_fullscreen = isFullscreen;
m_scaleFactor = 1.0; // Default value; it will be updated in finishInit
// Create a hidden text view for parsing key down event properly
m_silentResponder = [[SFSilentResponder alloc] init];
m_hiddenTextView = [[NSTextView alloc] initWithFrame:NSZeroRect];
[m_hiddenTextView setNextResponder:m_silentResponder];
// Request high resolution on high DPI displays
[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;
}
////////////////////////////////////////////////////////
-(void)finishInit
{
// Register for window focus events
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidBecomeKey:)
@ -169,16 +195,18 @@ BOOL isValidTextUnicode(NSEvent* event);
name:NSWindowWillCloseNotification
object:[self window]];
// Create a hidden text view for parsing key down event properly
m_silentResponder = [[SFSilentResponder alloc] init];
m_hiddenTextView = [[NSTextView alloc] initWithFrame:NSZeroRect];
[m_hiddenTextView setNextResponder:m_silentResponder];
// 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]];
// Request high resolution on high DPI displays
[self setWantsBestResolutionOpenGLSurface:YES];
}
return self;
// Now that we have a window, set up correctly the scale factor
[self updateScaleFactor];
}
@ -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
{

View File

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

View File

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

View File

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

View File

@ -66,6 +66,14 @@ namespace sf {
////////////////////////////////////////////////////////////
@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
///