Moved more responsibilities to SFOpenGLView

These changes will ease the implementation of mouse grab (#394)
This commit is contained in:
Marco Antognini 2014-05-21 22:45:04 +02:00
parent aa47dd5d33
commit 2215f55ef9
4 changed files with 120 additions and 92 deletions

View File

@ -43,8 +43,6 @@ namespace sf {
/// ///
/// NSTrackingArea is used to keep track of mouse events. We also /// NSTrackingArea is used to keep track of mouse events. We also
/// need to be able to ignore mouse event when exiting fullscreen. /// need to be able to ignore mouse event when exiting fullscreen.
/// The SFWindowController should call -[SFOpenGLView exitFullscreen]
/// and -[SFOpenGLView enterFullscreen] when appropriate.
/// ///
/// Modifiers keys (cmd, ctrl, alt, shift) are handled by this class /// Modifiers keys (cmd, ctrl, alt, shift) are handled by this class
/// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm). /// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm).
@ -56,6 +54,7 @@ namespace sf {
BOOL m_useKeyRepeat; ///< Key repeat setting BOOL m_useKeyRepeat; ///< Key repeat setting
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
// 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.
@ -66,24 +65,16 @@ namespace sf {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create the SFML OpenGL view /// \brief Create the SFML OpenGL view
/// ///
/// NB: -initWithFrame: is also implemented to default isFullscreen to NO
/// in case SFOpenGLView is created with the standard message.
///
/// \param frameRect dimension of the view /// \param frameRect dimension of the view
/// \param isFullscreen fullscreen flag
/// ///
/// \return an initialized view /// \return an initialized view
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect; -(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen;
////////////////////////////////////////////////////////////
/// \brief Handle going in fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)enterFullscreen;
////////////////////////////////////////////////////////////
/// \brief Handle exiting fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)exitFullscreen;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Apply the given requester to the view /// \brief Apply the given requester to the view

View File

@ -77,6 +77,30 @@ BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
-(void)updateMouseState; -(void)updateMouseState;
////////////////////////////////////////////////////////////
/// \brief Callback for focus event
///
////////////////////////////////////////////////////////////
-(void)windowDidBecomeKey:(NSNotification*)notification;
////////////////////////////////////////////////////////////
/// \brief Callback for unfocus event
///
////////////////////////////////////////////////////////////
-(void)windowDidResignKey:(NSNotification*)notification;
////////////////////////////////////////////////////////////
/// \brief Handle going in fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)enterFullscreen;
////////////////////////////////////////////////////////////
/// \brief Handle exiting fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)exitFullscreen;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert the NSEvent mouse button type to SFML type /// \brief Convert the NSEvent mouse button type to SFML type
/// ///
@ -108,6 +132,12 @@ BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect -(id)initWithFrame:(NSRect)frameRect
{
return [self initWithFrame:frameRect fullscreen:NO];
}
////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen
{ {
if ((self = [super initWithFrame:frameRect])) if ((self = [super initWithFrame:frameRect]))
{ {
@ -123,6 +153,22 @@ BOOL isValidTextUnicode(NSEvent* event);
userInfo:nil]; userInfo:nil];
[self addTrackingArea:m_trackingArea]; [self addTrackingArea:m_trackingArea];
m_fullscreen = isFullscreen;
// 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];
m_hiddenTextView = [[NSTextView alloc] initWithFrame:NSZeroRect]; m_hiddenTextView = [[NSTextView alloc] initWithFrame:NSZeroRect];
@ -136,37 +182,6 @@ BOOL isValidTextUnicode(NSEvent* event);
} }
////////////////////////////////////////////////////////
-(void)enterFullscreen
{
// Remove the tracking area first,
// just to be sure we don't add it twice!
[self removeTrackingArea:m_trackingArea];
[self addTrackingArea:m_trackingArea];
// Fire an mouse entered event if needed
if (!m_mouseIsIn && (m_requester != 0))
m_requester->mouseMovedIn();
// Update status
m_mouseIsIn = YES;
}
////////////////////////////////////////////////////////
-(void)exitFullscreen
{
[self removeTrackingArea:m_trackingArea];
// Fire an mouse left event if needed
if (m_mouseIsIn && (m_requester != 0))
m_requester->mouseMovedOut();
// Update status
m_mouseIsIn = NO;
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester -(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
{ {
@ -276,6 +291,63 @@ BOOL isValidTextUnicode(NSEvent* event);
} }
////////////////////////////////////////////////////////
-(void)windowDidBecomeKey:(NSNotification*)notification
{
(void)notification;
if (m_requester)
m_requester->windowGainedFocus();
if (m_fullscreen)
[self enterFullscreen];
}
////////////////////////////////////////////////////////
-(void)windowDidResignKey:(NSNotification*)notification
{
(void)notification;
if (m_requester)
m_requester->windowLostFocus();
if (m_fullscreen)
[self exitFullscreen];
}
////////////////////////////////////////////////////////
-(void)enterFullscreen
{
// Remove the tracking area first,
// just to be sure we don't add it twice!
[self removeTrackingArea:m_trackingArea];
[self addTrackingArea:m_trackingArea];
// Fire an mouse entered event if needed
if (!m_mouseIsIn && (m_requester != 0))
m_requester->mouseMovedIn();
// Update status
m_mouseIsIn = YES;
}
////////////////////////////////////////////////////////
-(void)exitFullscreen
{
[self removeTrackingArea:m_trackingArea];
// Fire an mouse left event if needed
if (m_mouseIsIn && (m_requester != 0))
m_requester->mouseMovedOut();
// Update status
m_mouseIsIn = NO;
}
#pragma mark #pragma mark
#pragma mark Subclassing methods #pragma mark Subclassing methods
@ -283,6 +355,9 @@ BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)dealloc -(void)dealloc
{ {
// Unregister for window focus events
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Unregister // Unregister
[self removeTrackingArea:m_trackingArea]; [self removeTrackingArea:m_trackingArea];

View File

@ -44,21 +44,17 @@ namespace sf {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Implementation of WindowImplDelegateProtocol for window management /// \brief Implementation of WindowImplDelegateProtocol for window management
/// ///
/// Key and mouse events are delegated to its view. /// Key, mouse and Window focus events are delegated to its view, SFOpenGLView.
/// Window events are managed by this class.
/// ///
/// Used when SFML handle everything and when a NSWindow* is given /// Used when SFML handle everything and when a NSWindow* is given
/// as handle to WindowImpl. /// as handle to WindowImpl.
/// ///
/// m_fullscreenMode is bind to default video mode if we don't need to change screen size.
///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate> @interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate>
{ {
NSWindow* m_window; ///< Underlying Cocoa window to be controlled NSWindow* m_window; ///< Underlying Cocoa window to be controlled
SFOpenGLView* m_oglView; ///< OpenGL view for rendering SFOpenGLView* m_oglView; ///< OpenGL view for rendering
sf::priv::WindowImplCocoa* m_requester; ///< Requester sf::priv::WindowImplCocoa* m_requester; ///< Requester
BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -94,7 +94,6 @@
m_window = nil; m_window = nil;
m_oglView = nil; m_oglView = nil;
m_requester = 0; m_requester = 0;
m_fullscreen = NO;
// Retain the window for our own use. // Retain the window for our own use.
m_window = [window retain]; m_window = [window retain];
@ -106,7 +105,8 @@
} }
// Create the view. // Create the view.
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]]; m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]
fullscreen:NO];
if (m_oglView == nil) if (m_oglView == nil)
{ {
@ -144,9 +144,8 @@
m_window = nil; m_window = nil;
m_oglView = nil; m_oglView = nil;
m_requester = 0; m_requester = 0;
m_fullscreen = style & sf::Style::Fullscreen;
if (m_fullscreen) if (style & sf::Style::Fullscreen)
[self setupFullscreenViewWithMode:mode]; [self setupFullscreenViewWithMode:mode];
else else
[self setupWindowWithMode:mode andStyle:style]; [self setupWindowWithMode:mode andStyle:style];
@ -204,7 +203,8 @@
CGFloat y = (desktop.height - mode.height) / 2.0; CGFloat y = (desktop.height - mode.height) / 2.0;
NSRect oglRect = NSMakeRect(x, y, mode.width, mode.height); NSRect oglRect = NSMakeRect(x, y, mode.width, mode.height);
m_oglView = [[SFOpenGLView alloc] initWithFrame:oglRect]; m_oglView = [[SFOpenGLView alloc] initWithFrame:oglRect
fullscreen:YES];
if (m_oglView == nil) if (m_oglView == nil)
{ {
@ -217,9 +217,6 @@
// Populate the window and views // Populate the window and views
[masterView addSubview:m_oglView]; [masterView addSubview:m_oglView];
[m_window setContentView:masterView]; [m_window setContentView:masterView];
// Finalize setup
[m_oglView enterFullscreen];
} }
@ -265,7 +262,8 @@
} }
// Create the view. // Create the view.
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]]; m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]
fullscreen:NO];
if (m_oglView == nil) if (m_oglView == nil)
{ {
@ -553,38 +551,6 @@
} }
////////////////////////////////////////////////////////
-(void)windowDidBecomeKey:(NSNotification*)notification
{
(void)notification;
// Send event.
if (m_requester == 0)
return;
m_requester->windowGainedFocus();
if (m_fullscreen)
[m_oglView enterFullscreen];
}
////////////////////////////////////////////////////////
-(void)windowDidResignKey:(NSNotification*)notification
{
(void)notification;
// Send event.
if (m_requester == 0)
return;
m_requester->windowLostFocus();
if (m_fullscreen)
[m_oglView exitFullscreen];
}
#pragma mark #pragma mark
#pragma mark Other methods #pragma mark Other methods