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
/// 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
/// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm).
@ -56,6 +54,7 @@ namespace sf {
BOOL m_useKeyRepeat; ///< Key repeat setting
BOOL m_mouseIsIn; ///< Mouse positional state
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.
// We use a silent responder to prevent sound alerts.
@ -66,24 +65,16 @@ namespace sf {
////////////////////////////////////////////////////////////
/// \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 isFullscreen fullscreen flag
///
/// \return an initialized view
///
////////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect;
////////////////////////////////////////////////////////////
/// \brief Handle going in fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)enterFullscreen;
////////////////////////////////////////////////////////////
/// \brief Handle exiting fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)exitFullscreen;
-(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen;
////////////////////////////////////////////////////////////
/// \brief Apply the given requester to the view

View File

@ -77,6 +77,30 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////////
-(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
///
@ -108,6 +132,12 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect
{
return [self initWithFrame:frameRect fullscreen:NO];
}
////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen
{
if ((self = [super initWithFrame:frameRect]))
{
@ -123,6 +153,22 @@ BOOL isValidTextUnicode(NSEvent* event);
userInfo:nil];
[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
m_silentResponder = [[SFSilentResponder alloc] init];
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
{
@ -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 Subclassing methods
@ -283,6 +355,9 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
-(void)dealloc
{
// Unregister for window focus events
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Unregister
[self removeTrackingArea:m_trackingArea];

View File

@ -44,21 +44,17 @@ namespace sf {
////////////////////////////////////////////////////////////
/// \brief Implementation of WindowImplDelegateProtocol for window management
///
/// Key and mouse events are delegated to its view.
/// Window events are managed by this class.
/// Key, mouse and Window focus events are delegated to its view, SFOpenGLView.
///
/// Used when SFML handle everything and when a NSWindow* is given
/// 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>
{
NSWindow* m_window; ///< Underlying Cocoa window to be controlled
SFOpenGLView* m_oglView; ///< OpenGL view for rendering
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_oglView = nil;
m_requester = 0;
m_fullscreen = NO;
// Retain the window for our own use.
m_window = [window retain];
@ -106,7 +105,8 @@
}
// 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)
{
@ -144,9 +144,8 @@
m_window = nil;
m_oglView = nil;
m_requester = 0;
m_fullscreen = style & sf::Style::Fullscreen;
if (m_fullscreen)
if (style & sf::Style::Fullscreen)
[self setupFullscreenViewWithMode:mode];
else
[self setupWindowWithMode:mode andStyle:style];
@ -204,7 +203,8 @@
CGFloat y = (desktop.height - mode.height) / 2.0;
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)
{
@ -217,9 +217,6 @@
// Populate the window and views
[masterView addSubview:m_oglView];
[m_window setContentView:masterView];
// Finalize setup
[m_oglView enterFullscreen];
}
@ -265,7 +262,8 @@
}
// 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)
{
@ -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 Other methods