mirror of
https://github.com/SFML/SFML.git
synced 2024-12-01 15:51:04 +08:00
Refactored OS X implementation regarding SFOpenGLView
This commit is contained in:
parent
7b20093650
commit
2f53489f2a
@ -133,6 +133,10 @@ elseif(SFML_OS_MACOSX)
|
|||||||
${SRCROOT}/OSX/SFKeyboardModifiersHelper.mm
|
${SRCROOT}/OSX/SFKeyboardModifiersHelper.mm
|
||||||
${SRCROOT}/OSX/SFOpenGLView.h
|
${SRCROOT}/OSX/SFOpenGLView.h
|
||||||
${SRCROOT}/OSX/SFOpenGLView.mm
|
${SRCROOT}/OSX/SFOpenGLView.mm
|
||||||
|
${SRCROOT}/OSX/SFOpenGLView+keyboard.mm
|
||||||
|
${SRCROOT}/OSX/SFOpenGLView+keyboard_priv.h
|
||||||
|
${SRCROOT}/OSX/SFOpenGLView+mouse.mm
|
||||||
|
${SRCROOT}/OSX/SFOpenGLView+mouse_priv.h
|
||||||
${SRCROOT}/OSX/SFSilentResponder.h
|
${SRCROOT}/OSX/SFSilentResponder.h
|
||||||
${SRCROOT}/OSX/SFSilentResponder.m
|
${SRCROOT}/OSX/SFSilentResponder.m
|
||||||
${SRCROOT}/OSX/SFWindow.h
|
${SRCROOT}/OSX/SFWindow.h
|
||||||
|
220
src/SFML/Window/OSX/SFOpenGLView+keyboard.mm
Normal file
220
src/SFML/Window/OSX/SFOpenGLView+keyboard.mm
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||||
|
#include <SFML/Window/OSX/HIDInputManager.hpp> // For localizedKeys and nonLocalizedKeys
|
||||||
|
|
||||||
|
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
|
||||||
|
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||||
|
#import <SFML/Window/OSX/SFOpenGLView+keyboard_priv.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// In this file, we implement keyboard handling for SFOpenGLView
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@implementation SFOpenGLView (keyboard)
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(BOOL)acceptsFirstResponder
|
||||||
|
{
|
||||||
|
// Accepts key event.
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(BOOL)canBecomeKeyView
|
||||||
|
{
|
||||||
|
// Accepts key event.
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)enableKeyRepeat
|
||||||
|
{
|
||||||
|
m_useKeyRepeat = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)disableKeyRepeat
|
||||||
|
{
|
||||||
|
m_useKeyRepeat = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)keyDown:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] keyDown:theEvent];
|
||||||
|
|
||||||
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Handle key down event
|
||||||
|
if (m_useKeyRepeat || ![theEvent isARepeat])
|
||||||
|
{
|
||||||
|
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
||||||
|
|
||||||
|
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
|
||||||
|
m_requester->keyDown(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Handle text entered event:
|
||||||
|
// Ignore event if we don't want repeated keystrokes
|
||||||
|
if (m_useKeyRepeat || ![theEvent isARepeat])
|
||||||
|
{
|
||||||
|
// Ignore escape key and other non text keycode (See NSEvent.h)
|
||||||
|
// because they produce a sound alert.
|
||||||
|
if ([SFOpenGLView isValidTextUnicode:theEvent])
|
||||||
|
{
|
||||||
|
// Send the event to the hidden text view for processing
|
||||||
|
[m_hiddenTextView interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carefully handle backspace and delete..
|
||||||
|
// Note: the event is intentionally sent to the hidden view
|
||||||
|
// even if we do something more specific below. This way
|
||||||
|
// key combination are correctly interpreted.
|
||||||
|
|
||||||
|
unsigned short keycode = [theEvent keyCode];
|
||||||
|
|
||||||
|
// Backspace
|
||||||
|
if (keycode == 0x33)
|
||||||
|
{
|
||||||
|
// Send the correct Unicode value (i.e. 8) instead of 127 (which is 'delete')
|
||||||
|
m_requester->textEntered(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
else if ((keycode == 0x75) || (keycode == NSDeleteFunctionKey))
|
||||||
|
{
|
||||||
|
// Instead of the value 63272 we send 127.
|
||||||
|
m_requester->textEntered(127);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, let's see what our hidden field has computed
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSString* string = [m_hiddenTextView string];
|
||||||
|
|
||||||
|
// Send each character to SFML event requester
|
||||||
|
for (NSUInteger index = 0; index < [string length]; ++index)
|
||||||
|
m_requester->textEntered([string characterAtIndex:index]);
|
||||||
|
|
||||||
|
// Empty our hidden cache
|
||||||
|
[m_hiddenTextView setString:@""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)sfKeyUp:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
// For some mystic reasons, key released events don't work the same way
|
||||||
|
// as key pressed events... We somewhat hijack the event chain of response
|
||||||
|
// in -[SFApplication sendEvent:] and resume this chain with the next
|
||||||
|
// responder.
|
||||||
|
// This is workaround to make sure key released events are fired in
|
||||||
|
// fullscreen window too.
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] keyUp:theEvent];
|
||||||
|
|
||||||
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
||||||
|
|
||||||
|
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
|
||||||
|
m_requester->keyUp(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)flagsChanged:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] flagsChanged:theEvent];
|
||||||
|
|
||||||
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NSUInteger modifiers = [theEvent modifierFlags];
|
||||||
|
handleModifiersChanged(modifiers, *m_requester);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
|
||||||
|
{
|
||||||
|
// Key code
|
||||||
|
sf::Keyboard::Key key = sf::Keyboard::Unknown;
|
||||||
|
|
||||||
|
// First we look if the key down is from a list of characters
|
||||||
|
// that depend on keyboard localization.
|
||||||
|
NSString* string = [event charactersIgnoringModifiers];
|
||||||
|
if ([string length] > 0)
|
||||||
|
key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
|
||||||
|
|
||||||
|
// If the key is not a localized one, we try to find a corresponding code
|
||||||
|
// through virtual key code.
|
||||||
|
if (key == sf::Keyboard::Unknown)
|
||||||
|
key = sf::priv::HIDInputManager::nonLocalizedKeys([event keyCode]);
|
||||||
|
|
||||||
|
return keyEventWithModifiers([event modifierFlags], key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
+(BOOL)isValidTextUnicode:(NSEvent*)event
|
||||||
|
{
|
||||||
|
if ([event keyCode] == 0x35) // Escape
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ([[event characters] length] > 0)
|
||||||
|
{
|
||||||
|
unichar code = [[event characters] characterAtIndex:0];
|
||||||
|
return ((code < 0xF700) || (code > 0xF8FF));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
68
src/SFML/Window/OSX/SFOpenGLView+keyboard_priv.h
Normal file
68
src/SFML/Window/OSX/SFOpenGLView+keyboard_priv.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/Window/Mouse.hpp>
|
||||||
|
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Here are defined a few private messages for keyboard
|
||||||
|
/// handling in SFOpenGLView.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@interface SFOpenGLView (keyboard_priv)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Convert a key down/up NSEvent into an SFML key event
|
||||||
|
///
|
||||||
|
/// The conversion is based on localizedKeys and nonLocalizedKeys functions.
|
||||||
|
///
|
||||||
|
/// \param event a key event
|
||||||
|
///
|
||||||
|
/// \return sf::Keyboard::Unknown as Code if the key is unknown
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check if the event represent some Unicode text
|
||||||
|
///
|
||||||
|
/// The event is assumed to be a key down event.
|
||||||
|
/// False is returned if the event is either escape or a non text Unicode.
|
||||||
|
///
|
||||||
|
/// \param event a key down event
|
||||||
|
///
|
||||||
|
/// \return true if event represents a Unicode character, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
+(BOOL)isValidTextUnicode:(NSEvent*)event;
|
||||||
|
|
||||||
|
@end
|
285
src/SFML/Window/OSX/SFOpenGLView+mouse.mm
Normal file
285
src/SFML/Window/OSX/SFOpenGLView+mouse.mm
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||||
|
|
||||||
|
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||||
|
#import <SFML/Window/OSX/SFOpenGLView+mouse_priv.h>
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// In this file, we implement mouse handling for SFOpenGLView
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@implementation SFOpenGLView (mouse)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(BOOL)isMouseInside
|
||||||
|
{
|
||||||
|
NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
|
||||||
|
NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
|
||||||
|
|
||||||
|
return NSPointInRect(relativeToView, [self bounds]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)updateMouseState
|
||||||
|
{
|
||||||
|
BOOL mouseWasIn = m_mouseIsIn;
|
||||||
|
m_mouseIsIn = [self isMouseInside];
|
||||||
|
|
||||||
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Send event if needed.
|
||||||
|
if (mouseWasIn && !m_mouseIsIn)
|
||||||
|
m_requester->mouseMovedOut();
|
||||||
|
else if (!mouseWasIn && m_mouseIsIn)
|
||||||
|
m_requester->mouseMovedIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)mouseDown:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseDown:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] mouseDown:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)rightMouseDown:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseDown:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] rightMouseDown:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)otherMouseDown:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseDown:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] otherMouseDown:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)handleMouseDown:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
sf::Mouse::Button button = [SFOpenGLView mouseButtonFromEvent:theEvent];
|
||||||
|
|
||||||
|
if (m_requester != 0)
|
||||||
|
{
|
||||||
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
|
||||||
|
if (button != sf::Mouse::ButtonCount)
|
||||||
|
m_requester->mouseDownAt(button, loc.x, loc.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)mouseUp:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseUp:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] mouseUp:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)rightMouseUp:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseUp:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] rightMouseUp:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)otherMouseUp:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseUp:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] otherMouseUp:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(void)handleMouseUp:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
sf::Mouse::Button button = [SFOpenGLView mouseButtonFromEvent:theEvent];
|
||||||
|
|
||||||
|
if (m_requester != 0)
|
||||||
|
{
|
||||||
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
|
||||||
|
if (button != sf::Mouse::ButtonCount)
|
||||||
|
m_requester->mouseUpAt(button, loc.x, loc.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)mouseMoved:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseMove:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] mouseMoved:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)rightMouseDragged:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseMove:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] rightMouseDragged:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)mouseDragged:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseMove:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] mouseDragged:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)otherMouseDragged:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
[self handleMouseMove:theEvent];
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] otherMouseUp:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)handleMouseMove:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
if (m_requester != 0)
|
||||||
|
{
|
||||||
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
|
||||||
|
// Make sure the point is inside the view.
|
||||||
|
// (mouseEntered: and mouseExited: are not immediately called
|
||||||
|
// when the mouse is dragged. That would be too easy!)
|
||||||
|
[self updateMouseState];
|
||||||
|
if (m_mouseIsIn)
|
||||||
|
m_requester->mouseMovedAt(loc.x, loc.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)scrollWheel:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
if (m_requester != 0)
|
||||||
|
{
|
||||||
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
m_requester->mouseWheelScrolledAt([theEvent deltaX], [theEvent deltaY], loc.x, loc.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transmit to non-SFML responder
|
||||||
|
[[self nextResponder] scrollWheel:theEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)mouseEntered:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
(void)theEvent;
|
||||||
|
[self updateMouseState];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)mouseExited:(NSEvent*)theEvent
|
||||||
|
{
|
||||||
|
(void)theEvent;
|
||||||
|
[self updateMouseState];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil
|
||||||
|
{
|
||||||
|
NSPoint loc;
|
||||||
|
// If no event given then get current mouse pos.
|
||||||
|
if (eventOrNil == nil)
|
||||||
|
{
|
||||||
|
NSPoint rawPos = [[self window] mouseLocationOutsideOfEventStream];
|
||||||
|
loc = [self convertPoint:rawPos fromView:nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loc = [self convertPoint:[eventOrNil locationInWindow] fromView:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't forget to change to SFML coord system.
|
||||||
|
float h = [self frame].size.height;
|
||||||
|
loc.y = h - loc.y;
|
||||||
|
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
+(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event
|
||||||
|
{
|
||||||
|
switch ([event buttonNumber])
|
||||||
|
{
|
||||||
|
case 0: return sf::Mouse::Left;
|
||||||
|
case 1: return sf::Mouse::Right;
|
||||||
|
case 2: return sf::Mouse::Middle;
|
||||||
|
case 3: return sf::Mouse::XButton1;
|
||||||
|
case 4: return sf::Mouse::XButton2;
|
||||||
|
default: return sf::Mouse::ButtonCount; // Never happens! (hopefully)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
79
src/SFML/Window/OSX/SFOpenGLView+mouse_priv.h
Normal file
79
src/SFML/Window/OSX/SFOpenGLView+mouse_priv.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/Window/Mouse.hpp>
|
||||||
|
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Here are defined a few private messages for mouse
|
||||||
|
/// handling in SFOpenGLView.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@interface SFOpenGLView (mouse_priv)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Update the mouse state (in or out)
|
||||||
|
///
|
||||||
|
/// Fire an event if its state has changed.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(void)updateMouseState;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief handle mouse down event
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(void)handleMouseDown:(NSEvent*)theEvent;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief handle mouse up event
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(void)handleMouseUp:(NSEvent*)theEvent;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief handle mouse move event
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(void)handleMouseMove:(NSEvent*)theEvent;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Convert the NSEvent mouse button type to SFML type
|
||||||
|
///
|
||||||
|
/// \param event a mouse button event
|
||||||
|
///
|
||||||
|
/// \return Left, Right, ..., or ButtonCount if the button is unknown
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
+(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event;
|
||||||
|
|
||||||
|
@end
|
@ -47,6 +47,11 @@ namespace sf {
|
|||||||
/// 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).
|
||||||
///
|
///
|
||||||
|
/// The interface is subdivided into several categories in order
|
||||||
|
/// to have multiple implementation files to divide this monolithic
|
||||||
|
/// implementation. However, all attributes are defined in the main
|
||||||
|
/// interface declaration right below.
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@interface SFOpenGLView : NSOpenGLView
|
@interface SFOpenGLView : NSOpenGLView
|
||||||
{
|
{
|
||||||
@ -105,6 +110,18 @@ namespace sf {
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point;
|
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Get the display scale factor
|
||||||
|
///
|
||||||
|
/// \return e.g. 1.0 for classic display, 2.0 for retina display
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(CGFloat)displayScaleFactor;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface SFOpenGLView (keyboard)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Enable key repeat
|
/// \brief Enable key repeat
|
||||||
///
|
///
|
||||||
@ -117,13 +134,9 @@ namespace sf {
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)disableKeyRepeat;
|
-(void)disableKeyRepeat;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
@end
|
||||||
/// \brief Get the display scale factor
|
|
||||||
///
|
@interface SFOpenGLView (mouse)
|
||||||
/// \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
|
||||||
|
@ -27,28 +27,13 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||||
#include <SFML/Window/OSX/HIDInputManager.hpp> // For localizedKeys and nonLocalizedKeys
|
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
|
||||||
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
|
|
||||||
#import <SFML/Window/OSX/SFOpenGLView.h>
|
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||||
|
#import <SFML/Window/OSX/SFOpenGLView+mouse_priv.h>
|
||||||
#import <SFML/Window/OSX/SFSilentResponder.h>
|
#import <SFML/Window/OSX/SFSilentResponder.h>
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Check if the event represent some Unicode text
|
|
||||||
///
|
|
||||||
/// The event is assumed to be a key down event.
|
|
||||||
/// False is returned if the event is either escape or a non text Unicode.
|
|
||||||
///
|
|
||||||
/// \param event a key down event
|
|
||||||
///
|
|
||||||
/// \return true if event represents a Unicode character, false otherwise
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
BOOL isValidTextUnicode(NSEvent* event);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// SFOpenGLView class: Privates Methods Declaration
|
/// SFOpenGLView class: Privates Methods Declaration
|
||||||
///
|
///
|
||||||
@ -67,14 +52,6 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)viewDidEndLiveResize;
|
-(void)viewDidEndLiveResize;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Update the mouse state (in or out)
|
|
||||||
///
|
|
||||||
/// Fire an event if its state has changed.
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
-(void)updateMouseState;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Callback for focus event
|
/// \brief Callback for focus event
|
||||||
///
|
///
|
||||||
@ -99,28 +76,6 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)exitFullscreen;
|
-(void)exitFullscreen;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Convert the NSEvent mouse button type to SFML type
|
|
||||||
///
|
|
||||||
/// \param event a mouse button event
|
|
||||||
///
|
|
||||||
/// \return Left, Right, ..., or ButtonCount if the button is unknown
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Convert a key down/up NSEvent into an SFML key event
|
|
||||||
///
|
|
||||||
/// The conversion is based on localizedKeys and nonLocalizedKeys functions.
|
|
||||||
///
|
|
||||||
/// \param event a key event
|
|
||||||
///
|
|
||||||
/// \return sf::Keyboard::Unknown as Code if the key is unknown
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation SFOpenGLView
|
@implementation SFOpenGLView
|
||||||
@ -251,20 +206,6 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)enableKeyRepeat
|
|
||||||
{
|
|
||||||
m_useKeyRepeat = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)disableKeyRepeat
|
|
||||||
{
|
|
||||||
m_useKeyRepeat = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(CGFloat)displayScaleFactor
|
-(CGFloat)displayScaleFactor
|
||||||
{
|
{
|
||||||
@ -317,34 +258,6 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
m_requester->windowResized(newSize.width, newSize.height);
|
m_requester->windowResized(newSize.width, newSize.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(BOOL)isMouseInside
|
|
||||||
{
|
|
||||||
NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
|
|
||||||
NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
|
|
||||||
|
|
||||||
return NSPointInRect(relativeToView, [self bounds]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)updateMouseState
|
|
||||||
{
|
|
||||||
BOOL mouseWasIn = m_mouseIsIn;
|
|
||||||
m_mouseIsIn = [self isMouseInside];
|
|
||||||
|
|
||||||
if (m_requester == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Send event if needed.
|
|
||||||
if (mouseWasIn && !m_mouseIsIn)
|
|
||||||
m_requester->mouseMovedOut();
|
|
||||||
else if (!mouseWasIn && m_mouseIsIn)
|
|
||||||
m_requester->mouseMovedIn();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)windowDidBecomeKey:(NSNotification*)notification
|
-(void)windowDidBecomeKey:(NSNotification*)notification
|
||||||
{
|
{
|
||||||
@ -426,398 +339,4 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(BOOL)acceptsFirstResponder
|
|
||||||
{
|
|
||||||
// Accepts key event.
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(BOOL)canBecomeKeyView
|
|
||||||
{
|
|
||||||
// Accepts key event.
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark
|
|
||||||
#pragma mark Mouse-event methods
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)mouseDown:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Forward to...
|
|
||||||
[self otherMouseDown:theEvent];
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] mouseDown:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)mouseUp:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Forward to...
|
|
||||||
[self otherMouseUp:theEvent];
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] mouseUp:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)mouseMoved:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Forward to...
|
|
||||||
[self otherMouseDragged:theEvent];
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] mouseMoved:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)scrollWheel:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
if (m_requester != 0)
|
|
||||||
{
|
|
||||||
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
|
||||||
m_requester->mouseWheelScrolledAt([theEvent deltaX], [theEvent deltaY], loc.x, loc.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] scrollWheel:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)mouseEntered:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
(void)theEvent;
|
|
||||||
[self updateMouseState];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)mouseExited:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
(void)theEvent;
|
|
||||||
[self updateMouseState];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)rightMouseDown:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Forward to...
|
|
||||||
[self otherMouseDown:theEvent];
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] rightMouseDown:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)rightMouseUp:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Forward to...
|
|
||||||
[self otherMouseUp:theEvent];
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] rightMouseUp:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)otherMouseDown:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
|
||||||
|
|
||||||
if (m_requester != 0)
|
|
||||||
{
|
|
||||||
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
|
||||||
|
|
||||||
if (button != sf::Mouse::ButtonCount)
|
|
||||||
m_requester->mouseDownAt(button, loc.x, loc.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the event is not forwarded by mouseDown or rightMouseDown...
|
|
||||||
if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
|
|
||||||
{
|
|
||||||
// ... transmit to non-SFML responder
|
|
||||||
[[self nextResponder] otherMouseDown:theEvent];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)otherMouseUp:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
|
||||||
|
|
||||||
if (m_requester != 0)
|
|
||||||
{
|
|
||||||
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
|
||||||
|
|
||||||
if (button != sf::Mouse::ButtonCount)
|
|
||||||
m_requester->mouseUpAt(button, loc.x, loc.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the event is not forwarded by mouseUp or rightMouseUp...
|
|
||||||
if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
|
|
||||||
{
|
|
||||||
// ... transmit to non-SFML responder
|
|
||||||
[[self nextResponder] otherMouseUp:theEvent];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)rightMouseDragged:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Forward to...
|
|
||||||
[self otherMouseDragged:theEvent];
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] rightMouseDragged:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)mouseDragged:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Forward to...
|
|
||||||
[self otherMouseDragged:theEvent];
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] mouseDragged:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)otherMouseDragged:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
if (m_requester != 0)
|
|
||||||
{
|
|
||||||
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
|
||||||
|
|
||||||
// Make sure the point is inside the view.
|
|
||||||
// (mouseEntered: and mouseExited: are not immediately called
|
|
||||||
// when the mouse is dragged. That would be too easy!)
|
|
||||||
[self updateMouseState];
|
|
||||||
if (m_mouseIsIn)
|
|
||||||
m_requester->mouseMovedAt(loc.x, loc.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the event is not forwarded by mouseDragged or rightMouseDragged...
|
|
||||||
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
|
||||||
if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
|
|
||||||
{
|
|
||||||
// ... transmit to non-SFML responder
|
|
||||||
[[self nextResponder] otherMouseUp:theEvent];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil
|
|
||||||
{
|
|
||||||
NSPoint loc;
|
|
||||||
// If no event given then get current mouse pos.
|
|
||||||
if (eventOrNil == nil)
|
|
||||||
{
|
|
||||||
NSPoint rawPos = [[self window] mouseLocationOutsideOfEventStream];
|
|
||||||
loc = [self convertPoint:rawPos fromView:nil];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
loc = [self convertPoint:[eventOrNil locationInWindow] fromView:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't forget to change to SFML coord system.
|
|
||||||
float h = [self frame].size.height;
|
|
||||||
loc.y = h - loc.y;
|
|
||||||
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event
|
|
||||||
{
|
|
||||||
switch ([event buttonNumber])
|
|
||||||
{
|
|
||||||
case 0: return sf::Mouse::Left;
|
|
||||||
case 1: return sf::Mouse::Right;
|
|
||||||
case 2: return sf::Mouse::Middle;
|
|
||||||
case 3: return sf::Mouse::XButton1;
|
|
||||||
case 4: return sf::Mouse::XButton2;
|
|
||||||
default: return sf::Mouse::ButtonCount; // Never happens! (hopefully)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark
|
|
||||||
#pragma mark Key-event methods
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)keyDown:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] keyDown:theEvent];
|
|
||||||
|
|
||||||
if (m_requester == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Handle key down event
|
|
||||||
if (m_useKeyRepeat || ![theEvent isARepeat])
|
|
||||||
{
|
|
||||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
|
||||||
|
|
||||||
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
|
|
||||||
m_requester->keyDown(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Handle text entered event:
|
|
||||||
// Ignore event if we don't want repeated keystrokes
|
|
||||||
if (m_useKeyRepeat || ![theEvent isARepeat])
|
|
||||||
{
|
|
||||||
// Ignore escape key and other non text keycode (See NSEvent.h)
|
|
||||||
// because they produce a sound alert.
|
|
||||||
if (isValidTextUnicode(theEvent))
|
|
||||||
{
|
|
||||||
// Send the event to the hidden text view for processing
|
|
||||||
[m_hiddenTextView interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Carefully handle backspace and delete..
|
|
||||||
// Note: the event is intentionally sent to the hidden view
|
|
||||||
// even if we do something more specific below. This way
|
|
||||||
// key combination are correctly interpreted.
|
|
||||||
|
|
||||||
unsigned short keycode = [theEvent keyCode];
|
|
||||||
|
|
||||||
// Backspace
|
|
||||||
if (keycode == 0x33)
|
|
||||||
{
|
|
||||||
// Send the correct Unicode value (i.e. 8) instead of 127 (which is 'delete')
|
|
||||||
m_requester->textEntered(8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete
|
|
||||||
else if ((keycode == 0x75) || (keycode == NSDeleteFunctionKey))
|
|
||||||
{
|
|
||||||
// Instead of the value 63272 we send 127.
|
|
||||||
m_requester->textEntered(127);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, let's see what our hidden field has computed
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NSString* string = [m_hiddenTextView string];
|
|
||||||
|
|
||||||
// Send each character to SFML event requester
|
|
||||||
for (NSUInteger index = 0; index < [string length]; ++index)
|
|
||||||
m_requester->textEntered([string characterAtIndex:index]);
|
|
||||||
|
|
||||||
// Empty our hidden cache
|
|
||||||
[m_hiddenTextView setString:@""];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)sfKeyUp:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// For some mystic reasons, key released events don't work the same way
|
|
||||||
// as key pressed events... We somewhat hijack the event chain of response
|
|
||||||
// in -[SFApplication sendEvent:] and resume this chain with the next
|
|
||||||
// responder.
|
|
||||||
// This is workaround to make sure key released events are fired in
|
|
||||||
// fullscreen window too.
|
|
||||||
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] keyUp:theEvent];
|
|
||||||
|
|
||||||
if (m_requester == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
|
||||||
|
|
||||||
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
|
|
||||||
m_requester->keyUp(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(void)flagsChanged:(NSEvent*)theEvent
|
|
||||||
{
|
|
||||||
// Transmit to non-SFML responder
|
|
||||||
[[self nextResponder] flagsChanged:theEvent];
|
|
||||||
|
|
||||||
if (m_requester == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
NSUInteger modifiers = [theEvent modifierFlags];
|
|
||||||
handleModifiersChanged(modifiers, *m_requester);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
|
|
||||||
{
|
|
||||||
// Key code
|
|
||||||
sf::Keyboard::Key key = sf::Keyboard::Unknown;
|
|
||||||
|
|
||||||
// First we look if the key down is from a list of characters
|
|
||||||
// that depend on keyboard localization.
|
|
||||||
NSString* string = [event charactersIgnoringModifiers];
|
|
||||||
if ([string length] > 0)
|
|
||||||
key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
|
|
||||||
|
|
||||||
// If the key is not a localized one, we try to find a corresponding code
|
|
||||||
// through virtual key code.
|
|
||||||
if (key == sf::Keyboard::Unknown)
|
|
||||||
key = sf::priv::HIDInputManager::nonLocalizedKeys([event keyCode]);
|
|
||||||
|
|
||||||
//#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages.
|
|
||||||
// if (key.code == sf::Keyboard::Unknown) { // The key is unknown.
|
|
||||||
// sf::err() << "This is an unknown key. Virtual key code is 0x"
|
|
||||||
// << std::hex
|
|
||||||
// << [event keyCode]
|
|
||||||
// << "."
|
|
||||||
// << std::endl;
|
|
||||||
// }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
return keyEventWithModifiers([event modifierFlags], key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - C-like functions
|
|
||||||
|
|
||||||
BOOL isValidTextUnicode(NSEvent* event)
|
|
||||||
{
|
|
||||||
if ([event keyCode] == 0x35) // Escape
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if ([[event characters] length] > 0)
|
|
||||||
{
|
|
||||||
unichar code = [[event characters] characterAtIndex:0];
|
|
||||||
return ((code < 0xF700) || (code > 0xF8FF));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user