diff options
Diffstat (limited to 'src/SFML/Window/OSX/SFOpenGLView+keyboard.mm')
-rw-r--r-- | src/SFML/Window/OSX/SFOpenGLView+keyboard.mm | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/SFML/Window/OSX/SFOpenGLView+keyboard.mm b/src/SFML/Window/OSX/SFOpenGLView+keyboard.mm new file mode 100644 index 0000000..4fbef01 --- /dev/null +++ b/src/SFML/Window/OSX/SFOpenGLView+keyboard.mm @@ -0,0 +1,220 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 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 + |