summaryrefslogtreecommitdiff
path: root/src/SFML/Window/OSX/SFOpenGLView+keyboard.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Window/OSX/SFOpenGLView+keyboard.mm')
-rw-r--r--src/SFML/Window/OSX/SFOpenGLView+keyboard.mm220
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
+