From f85a1794bc46fab68ebd752280caeee372edf505 Mon Sep 17 00:00:00 2001 From: mantognini Date: Fri, 11 Feb 2011 00:17:19 +0000 Subject: [PATCH] Improved TextEntered event. Improved KeyPressed/Released event. Add support for 'modifier' keys (System, Alt, Control, Shift). git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1795 4e206d99-4929-0410-ac5d-dfc041789085 --- src/SFML/Window/OSX/SFOpenGLView.h | 12 + src/SFML/Window/OSX/SFOpenGLView.mm | 824 +++++++++++++++++++++- src/SFML/Window/OSX/SFWindowController.mm | 4 +- src/SFML/Window/OSX/WindowImplCocoa.hpp | 18 +- src/SFML/Window/OSX/WindowImplCocoa.mm | 142 +--- 5 files changed, 833 insertions(+), 167 deletions(-) diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h index a27d7e652..be2903efe 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.h +++ b/src/SFML/Window/OSX/SFOpenGLView.h @@ -45,6 +45,9 @@ namespace sf { /// bound to its default value we don't recompute the mouse position /// and assume it's correct. /// +/// As I don't have the right control keycode I cannot implement left-right +/// recognition for this key. (See SFOpenGLView.mm for more info.) +/// //////////////////////////////////////////////////////////// @interface SFOpenGLView : NSOpenGLView { sf::priv::WindowImplCocoa* myRequester; @@ -52,6 +55,15 @@ namespace sf { NSTrackingRectTag myTrackingTag; BOOL myMouseIsIn; NSSize myRealSize; + + /// 'modifiers' state + BOOL myRightShiftWasDown; + BOOL myLeftShiftWasDown; + BOOL myRightCommandWasDown; + BOOL myLeftCommandWasDown; + BOOL myRightAlternateWasDown; + BOOL myLeftAlternateWasDown; + BOOL myControlWasDown; } //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm index 90995ae34..a358c2961 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.mm +++ b/src/SFML/Window/OSX/SFOpenGLView.mm @@ -27,9 +27,58 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #import +//////////////////////////////////////////////////////////// +/// Here are define the mask value for the 'modifiers' keys (cmd, ctrl, alt, shift) +/// +/// As I don't have the right control keycode I cannot implement left-right +/// recognition for this key. +#warning Missing keycode for right control key. +/// #define NSRightControlKeyMask 0x... +/// #define NSLeftControlKeyMask 0x40101 +/// +//////////////////////////////////////////////////////////// +#define NSRightShiftKeyMask 0x020004 +#define NSLeftShiftKeyMask 0x020002 +#define NSRightCommandKeyMask 0x100010 +#define NSLeftCommandKeyMask 0x100008 +#define NSRightAlternateKeyMask 0x080040 +#define NSLeftAlternateKeyMask 0x080020 + +//////////////////////////////////////////////////////////// +/// Erase (replace with 0) the given bits mask from the given data bits. +/// +//////////////////////////////////////////////////////////// +NSUInteger EraseMaskFromData(NSUInteger data, NSUInteger mask); + +//////////////////////////////////////////////////////////// +/// Erase (replace with 0) everything execept the given bits mask from the given data bits. +/// +//////////////////////////////////////////////////////////// +NSUInteger KeepOnlyMaskFromData(NSUInteger data, NSUInteger mask); + +//////////////////////////////////////////////////////////// +/// Try to convert a character into a SFML key code. +/// Return sf::Key::Count if it doesn't match any 'localized' keys. +/// +/// By 'localized' I mean keys that depend on the keyboard layout +/// and might not be the same as the US keycode in some country +/// (e.g. the keys 'Y' and 'Z' are switched on QWERTZ keyboard and +/// US keyboard layouts.) +/// +//////////////////////////////////////////////////////////// +sf::Key::Code LocalizedKeys(unichar ch); + +//////////////////////////////////////////////////////////// +/// Try to convert a keycode into a SFML key code. +/// Return sf::Key::Count if the keycode is unknown. +/// +//////////////////////////////////////////////////////////// +sf::Key::Code NonLocalizedKeys(unsigned short keycode); + //////////////////////////////////////////////////////////// /// SFOpenGLView class : Privates Methods Declaration /// @@ -48,6 +97,21 @@ //////////////////////////////////////////////////////////// -(BOOL)isMouseInside; +//////////////////////////////////////////////////////////// +/// Init the 'modifiers' key state. +/// +//////////////////////////////////////////////////////////// +-(void)initModifiersState; + +//////////////////////////////////////////////////////////// +/// Convert a key down/up NSEvent into an SFML key event. +/// Based on LocalizedKeys and NonLocalizedKeys function. +/// +/// Return sf::Key::Count as Code if the key is unknown. +/// +//////////////////////////////////////////////////////////// ++(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent; + @end @implementation SFOpenGLView @@ -58,11 +122,11 @@ //////////////////////////////////////////////////////// -(id)initWithFrame:(NSRect)frameRect { - if (self = [super initWithFrame:frameRect]) { + if ((self = [super initWithFrame:frameRect])) { [self setRequesterTo:0]; [self enableKeyRepeat]; - myRealSize = NSZeroSize; + [self initModifiersState]; // Register for mouse-move event myMouseIsIn = [self isMouseInside]; @@ -478,13 +542,26 @@ { if (myRequester == 0) return; - if (myUseKeyRepeat || ![theEvent isARepeat]) - myRequester->KeyDown([theEvent keyCode], [theEvent modifierFlags]); + if (myUseKeyRepeat || ![theEvent isARepeat]) { + sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent]; + + if (key.Code != sf::Key::Count) { // The key is recognized. + myRequester->KeyDown(key); + } + } if (myUseKeyRepeat || ![theEvent isARepeat]) { // Let's see if its a valid text. - // -interpretKeyEvents: will call -insertText: if theEvent is a valid caracter. - [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; + NSText* text = [[self window] fieldEditor:YES forObject:self]; + [text interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; + + NSString* string = [text string]; + if ([string length] > 0) { + // It's a valid TextEntered event. + myRequester->TextEntered([string characterAtIndex:0]); + + [text setString:@""]; + } } } @@ -494,22 +571,741 @@ { if (myRequester == 0) return; - myRequester->KeyUp([theEvent keyCode], [theEvent modifierFlags]); + sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent]; + + if (key.Code != sf::Key::Count) { // The key is recognized. + myRequester->KeyUp(key); + } } //////////////////////////////////////////////////////// --(void)insertText:(id)aString +-(void)flagsChanged:(NSEvent *)theEvent { - // aString can be either a NSString or a NSAttributedString. - if ([aString isKindOfClass:[NSAttributedString class]]) { - aString = [aString string]; // We want a NSString. + if (myRequester == 0) return; + + NSUInteger modifiers = [theEvent modifierFlags]; + + // Setup a potential event key. + sf::Event::KeyEvent key; + key.Code = sf::Key::Count; + key.Alt = modifiers & NSAlternateKeyMask; + key.Control = modifiers & NSControlKeyMask; + key.Shift = modifiers & NSShiftKeyMask; + + // State + BOOL rightShiftIsDown = NO; + BOOL leftShiftIsDown = NO; + BOOL rightCommandIsDown = NO; + BOOL leftCommandIsDown = NO; + BOOL rightAlternateIsDown = NO; + BOOL leftAlternateIsDown = NO; + BOOL controlIsDown = NO; + + // Shift keys. + if (modifiers & NSShiftKeyMask) { // At least one shift key is down. + // Clean up modifiers to keep only 'shift' bits. + NSUInteger shift = KeepOnlyMaskFromData(modifiers, NSRightShiftKeyMask | NSLeftShiftKeyMask); + + // Only right shift is down ? + if (shift == NSRightShiftKeyMask) { + + rightShiftIsDown = YES; + + if (myLeftShiftWasDown) { + // left shift released + leftShiftIsDown = NO; + + key.Code = sf::Key::LShift; + myRequester->KeyUp(key); + } + + if (!myRightShiftWasDown) { + // right shift pressed + + key.Code = sf::Key::RShift; + myRequester->KeyDown(key); + } + } + + // Only left shift is down ? + if (shift == NSLeftShiftKeyMask) { + + leftShiftIsDown = YES; + + if (myRightShiftWasDown) { + // right shift released + rightShiftIsDown = NO; + + key.Code = sf::Key::RShift; + myRequester->KeyUp(key); + } + + if (!myLeftShiftWasDown) { + // left shift pressed + + key.Code = sf::Key::LShift; + myRequester->KeyDown(key); + } + } + + // Or are they both down ? + if (shift == (NSRightShiftKeyMask | NSLeftShiftKeyMask)) { + + rightShiftIsDown = YES; + leftShiftIsDown = YES; + + if (!myRightShiftWasDown) { + // right shift pressed + + key.Code = sf::Key::RShift; + myRequester->KeyDown(key); + } + + if (!myLeftShiftWasDown) { + // left shift pressed + + key.Code = sf::Key::LShift; + myRequester->KeyDown(key); + } + } + } else { // No shift key down. + + rightShiftIsDown = NO; + leftShiftIsDown = NO; + + if (myRightShiftWasDown) { + // right shift released + + key.Code = sf::Key::RShift; + myRequester->KeyUp(key); + } + + if (myLeftShiftWasDown) { + // left shift released + + key.Code = sf::Key::LShift; + myRequester->KeyUp(key); + } } - if (myRequester == 0 || [aString length] == 0) return; + // Command keys. + if (modifiers & NSCommandKeyMask) { // At least one command key is down. + // Clean up modifiers to keep only 'Command' bits. + NSUInteger command = KeepOnlyMaskFromData(modifiers, NSRightCommandKeyMask | NSLeftCommandKeyMask); + + // Only right Command is down ? + if (command == NSRightCommandKeyMask) { + + rightCommandIsDown = YES; + + if (myLeftCommandWasDown) { + // left command released + leftCommandIsDown = NO; + + key.Code = sf::Key::LSystem; + myRequester->KeyUp(key); + } + + if (!myRightCommandWasDown) { + // right command pressed + + key.Code = sf::Key::RSystem; + myRequester->KeyDown(key); + } + } + + // Only left Command is down ? + if (command == NSLeftCommandKeyMask) { + + leftCommandIsDown = YES; + + if (myRightCommandWasDown) { + // right command released + rightCommandIsDown = NO; + + key.Code = sf::Key::RSystem; + myRequester->KeyUp(key); + } + + if (!myLeftCommandWasDown) { + // left command pressed + + key.Code = sf::Key::LSystem; + myRequester->KeyDown(key); + } + } + + // Or are they both down ? + if (command == (NSRightCommandKeyMask | NSLeftCommandKeyMask)) { + + rightCommandIsDown = YES; + leftCommandIsDown = YES; + + if (!myRightCommandWasDown) { + // right command pressed + + key.Code = sf::Key::RSystem; + myRequester->KeyDown(key); + } + + if (!myLeftCommandWasDown) { + // left command pressed + + key.Code = sf::Key::LSystem; + myRequester->KeyDown(key); + } + } + } else { // No Command key down. + + rightCommandIsDown = NO; + leftCommandIsDown = NO; + + if (myRightCommandWasDown) { + // right command released + + key.Code = sf::Key::RSystem; + myRequester->KeyUp(key); + } + + if (myLeftCommandWasDown) { + // left command released + + key.Code = sf::Key::LSystem; + myRequester->KeyUp(key); + } + } - // It's a valid TextEntered event. - myRequester->TextEntered([aString characterAtIndex:0]); + // Alternate keys. + if (modifiers & NSAlternateKeyMask) { // At least one alternate key is down. + // Clean up modifiers to keep only 'Alternate' bits. + NSUInteger alternate = KeepOnlyMaskFromData(modifiers, NSRightAlternateKeyMask | NSLeftAlternateKeyMask); + + // Only right Alternate is down ? + if (alternate == NSRightAlternateKeyMask) { + + rightAlternateIsDown = YES; + + if (myLeftAlternateWasDown) { + // left alt released + leftAlternateIsDown = NO; + + key.Code = sf::Key::LAlt; + myRequester->KeyUp(key); + } + + if (!myRightAlternateWasDown) { + // right alt pressed + + key.Code = sf::Key::RAlt; + myRequester->KeyDown(key); + } + } + + // Only left Alternate is down ? + if (alternate == NSLeftAlternateKeyMask) { + + leftAlternateIsDown = YES; + + if (myRightAlternateWasDown) { + // right alt released + rightAlternateIsDown = NO; + + key.Code = sf::Key::RAlt; + myRequester->KeyUp(key); + } + + if (!myLeftAlternateWasDown) { + // left alt pressed + + key.Code = sf::Key::LAlt; + myRequester->KeyDown(key); + } + } + + // Or are they both down ? + if (alternate == (NSRightAlternateKeyMask | NSLeftAlternateKeyMask)) { + + rightAlternateIsDown = YES; + leftAlternateIsDown = YES; + + if (!myRightAlternateWasDown) { + // right alt pressed + + key.Code = sf::Key::RAlt; + myRequester->KeyDown(key); + } + + if (!myLeftAlternateWasDown) { + // left alt pressed + + key.Code = sf::Key::LAlt; + myRequester->KeyDown(key); + } + } + } else { // No Alternate key down. + + rightAlternateIsDown = NO; + leftAlternateIsDown = NO; + + if (myRightAlternateWasDown) { + // right alt released + + key.Code = sf::Key::RAlt; + myRequester->KeyUp(key); + } + + if (myLeftAlternateWasDown) { + // left alt released + + key.Code = sf::Key::LAlt; + myRequester->KeyUp(key); + } + } + + // Control keys. + if (modifiers & NSControlKeyMask) { + // Currently only the left control key will be used in SFML (see note above). + + controlIsDown = YES; + + if (!myControlWasDown) { + // ctrl pressed + + key.Code = sf::Key::LControl; + myRequester->KeyDown(key); + } + } else { // No control key down. + controlIsDown = NO; + + if (myControlWasDown) { + // ctrl released + + key.Code = sf::Key::LControl; + myRequester->KeyUp(key); + } + } + + // Update the state + myRightShiftWasDown = rightShiftIsDown; + myLeftShiftWasDown = leftShiftIsDown; + myRightCommandWasDown = rightCommandIsDown; + myLeftCommandWasDown = leftCommandIsDown; + myRightAlternateWasDown = rightAlternateIsDown; + myLeftAlternateWasDown = leftAlternateIsDown; + myControlWasDown = controlIsDown; +} + + +//////////////////////////////////////////////////////// +-(void)initModifiersState +{ + // Set default value to NO. + myRightShiftWasDown = NO; + myLeftShiftWasDown = NO; + myRightCommandWasDown = NO; + myLeftCommandWasDown = NO; + myRightAlternateWasDown = NO; + myLeftAlternateWasDown = NO; + myControlWasDown = NO; + + NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; + modifiers = EraseMaskFromData(modifiers, 0x100); // We erase something useless that might be present. + + // Shift keys. + if (modifiers & NSShiftKeyMask) { // At least one shift key is down. + // Clean up modifiers to keep only 'shift' bits. + NSUInteger shift = KeepOnlyMaskFromData(modifiers, NSRightShiftKeyMask | NSLeftShiftKeyMask); + + // Only right shift is down ? + if (shift == NSRightShiftKeyMask) { + + myRightShiftWasDown = YES; + } + + // Only left shift is down ? + if (shift == NSLeftShiftKeyMask) { + + myLeftShiftWasDown = YES; + } + + // Or are they both down ? + if (shift == (NSRightShiftKeyMask | NSLeftShiftKeyMask)) { + + myRightShiftWasDown = YES; + myLeftShiftWasDown = YES; + } + } + + // Command keys. + if (modifiers & NSCommandKeyMask) { // At least one command key is down. + // Clean up modifiers to keep only 'Command' bits. + NSUInteger command = KeepOnlyMaskFromData(modifiers, NSRightCommandKeyMask | NSLeftCommandKeyMask); + + // Only right Command is down ? + if (command == NSRightCommandKeyMask) { + + myRightCommandWasDown = YES; + } + + // Only left Command is down ? + if (command == NSLeftCommandKeyMask) { + + myLeftCommandWasDown = YES; + } + + // Or are they both down ? + if (command == (NSRightCommandKeyMask | NSLeftCommandKeyMask)) { + + myRightCommandWasDown = YES; + myLeftCommandWasDown = YES; + } + } + + // Alternate keys. + if (modifiers & NSAlternateKeyMask) { // At least one alternate key is down. + // Clean up modifiers to keep only 'Alternate' bits. + NSUInteger alternate = KeepOnlyMaskFromData(modifiers, NSRightAlternateKeyMask | NSLeftAlternateKeyMask); + + // Only right Alternate is down ? + if (alternate == NSRightAlternateKeyMask) { + + myRightAlternateWasDown = YES; + } + + // Only left Alternate is down ? + if (alternate == NSLeftAlternateKeyMask) { + + myLeftAlternateWasDown = YES; + } + + // Or are they both down ? + if (alternate == (NSRightAlternateKeyMask | NSLeftAlternateKeyMask)) { + + myRightAlternateWasDown = YES; + myLeftAlternateWasDown = YES; + } + + } + + // Control keys. + if (modifiers & NSControlKeyMask) { + // Currently only the left control key will be used in SFML (see note above). + + myControlWasDown = YES; + } +} + + +//////////////////////////////////////////////////////// ++(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent +{ + sf::Event::KeyEvent key; + + // Modifiers. + NSUInteger modifierFlags = [anEvent modifierFlags]; + key.Alt = modifierFlags & NSAlternateKeyMask; + key.Control = modifierFlags & NSControlKeyMask; + key.Shift = modifierFlags & NSShiftKeyMask; + + // Key code. + key.Code = sf::Key::Count; + // First we look if the key down is from a list of caracter that depend on keyboard localization. + NSString* string = [anEvent charactersIgnoringModifiers]; + if ([string length] > 0) { + key.Code = LocalizedKeys([string characterAtIndex:0]); + } + + // The key is not a localized one, the other keys. + if (key.Code == sf::Key::Count) { + key.Code = NonLocalizedKeys([anEvent keyCode]); + } + +#ifdef SFML_DEBUG // We don't want to bother the final customer with anoying messages. + if (key.Code == sf::Key::Count) { // The key is unknown. + sf::Err() + << "This is an unknow key. Should not happen (?). Keycode is 0x" + << std::hex + << [anEvent keyCode] + << "." + << std::endl; + } +#endif + + return key; } @end + + +#pragma mark - C-like functions + + +//////////////////////////////////////////////////////// +NSUInteger EraseMaskFromData(NSUInteger data, NSUInteger mask) +{ + return (data | mask) ^ mask; +} + + +//////////////////////////////////////////////////////// +NSUInteger KeepOnlyMaskFromData(NSUInteger data, NSUInteger mask) +{ + NSUInteger negative = NSUIntegerMax ^ mask; + return EraseMaskFromData(data, negative); +} + + +//////////////////////////////////////////////////////// +sf::Key::Code LocalizedKeys(unichar ch) +{ + switch (ch) { + case 'a': + case 'A': return sf::Key::A; + + case 'b': + case 'B': return sf::Key::B; + + case 'c': + case 'C': return sf::Key::C; + + case 'd': + case 'D': return sf::Key::D; + + case 'e': + case 'E': return sf::Key::E; + + case 'f': + case 'F': return sf::Key::F; + + case 'g': + case 'G': return sf::Key::G; + + case 'h': + case 'H': return sf::Key::H; + + case 'i': + case 'I': return sf::Key::I; + + case 'j': + case 'J': return sf::Key::J; + + case 'k': + case 'K': return sf::Key::K; + + case 'l': + case 'L': return sf::Key::L; + + case 'm': + case 'M': return sf::Key::M; + + case 'n': + case 'N': return sf::Key::N; + + case 'o': + case 'O': return sf::Key::O; + + case 'p': + case 'P': return sf::Key::P; + + case 'q': + case 'Q': return sf::Key::Q; + + case 'r': + case 'R': return sf::Key::R; + + case 's': + case 'S': return sf::Key::S; + + case 't': + case 'T': return sf::Key::T; + + case 'u': + case 'U': return sf::Key::U; + + case 'v': + case 'V': return sf::Key::V; + + case 'w': + case 'W': return sf::Key::W; + + case 'x': + case 'X': return sf::Key::X; + + case 'y': + case 'Y': return sf::Key::Y; + + case 'z': + case 'Z': return sf::Key::Z; + + // The kew is not 'localized'. + default: return sf::Key::Count; + } +} + + +//////////////////////////////////////////////////////// +sf::Key::Code NonLocalizedKeys(unsigned short keycode) +{ + // (Some) 0x code based on http://forums.macrumors.com/showthread.php?t=780577 + // Some sf::Key are present twice. + switch (keycode) { + // These cases should not be used but anyway... + case 0x00: return sf::Key::A; + case 0x0b: return sf::Key::B; + case 0x08: return sf::Key::C; + case 0x02: return sf::Key::D; + case 0x0e: return sf::Key::E; + case 0x03: return sf::Key::F; + case 0x05: return sf::Key::G; + case 0x04: return sf::Key::H; + case 0x22: return sf::Key::I; + case 0x26: return sf::Key::J; + case 0x28: return sf::Key::K; + case 0x25: return sf::Key::L; + case 0x2e: return sf::Key::M; + case 0x2d: return sf::Key::N; + case 0x1f: return sf::Key::O; + case 0x23: return sf::Key::P; + case 0x0c: return sf::Key::Q; + case 0x0f: return sf::Key::R; + case 0x01: return sf::Key::S; + case 0x11: return sf::Key::T; + case 0x20: return sf::Key::U; + case 0x09: return sf::Key::V; + case 0x0d: return sf::Key::W; + case 0x07: return sf::Key::X; + case 0x10: return sf::Key::Y; + case 0x06: return sf::Key::Z; + + // These cases should not be used but anyway... + case 0x1d: return sf::Key::Num0; + case 0x12: return sf::Key::Num1; + case 0x13: return sf::Key::Num2; + case 0x14: return sf::Key::Num3; + case 0x15: return sf::Key::Num4; + case 0x17: return sf::Key::Num5; + case 0x16: return sf::Key::Num6; + case 0x1a: return sf::Key::Num7; + case 0x1c: return sf::Key::Num8; + case 0x19: return sf::Key::Num9; + + case 0x35: return sf::Key::Escape; + + // Modifier keys : never happen with keyDown/keyUp methods (?) + case 0x3b: return sf::Key::LControl; + case 0x38: return sf::Key::LShift; + case 0x3a: return sf::Key::LAlt; + case 0x37: return sf::Key::LSystem; + case 0x3e: return sf::Key::RControl; + case 0x3c: return sf::Key::RShift; + case 0x3d: return sf::Key::RAlt; + case 0x36: return sf::Key::RSystem; + + case NSMenuFunctionKey: return sf::Key::Menu; + + case 0x21: return sf::Key::LBracket; + case 0x1e: return sf::Key::RBracket; + case 0x29: return sf::Key::SemiColon; + case 0x2b: return sf::Key::Comma; + case 0x2f: return sf::Key::Period; + case 0x27: return sf::Key::Quote; + case 0x2c: return sf::Key::Slash; + case 0x2a: return sf::Key::BackSlash; + +#warning sf::Key::Tilde might be in conflict with some other key. + // 0x0a is for "Non-US Backslash" according to HID Calibrator, + // a sample provided by Apple. + case 0x0a: return sf::Key::Tilde; + + case 0x18: return sf::Key::Equal; + case 0x32: return sf::Key::Dash; + case 0x31: return sf::Key::Space; + case 0x24: return sf::Key::Return; + case 0x33: return sf::Key::Back; + case 0x30: return sf::Key::Tab; + + // Duplicates (see next §). + case 0x74: return sf::Key::PageUp; + case 0x79: return sf::Key::PageDown; + case 0x77: return sf::Key::End; + case 0x73: return sf::Key::Home; + + case NSPageUpFunctionKey: return sf::Key::PageUp; + case NSPageDownFunctionKey: return sf::Key::PageDown; + case NSEndFunctionKey: return sf::Key::End; + case NSHomeFunctionKey: return sf::Key::Home; + + case NSInsertFunctionKey: return sf::Key::Insert; + case NSDeleteFunctionKey: return sf::Key::Delete; + + case 0x45: return sf::Key::Add; + case 0x4e: return sf::Key::Subtract; + case 0x43: return sf::Key::Multiply; + case 0x4b: return sf::Key::Divide; + + // Duplicates (see next §). + case 0x7b: return sf::Key::Left; + case 0x7c: return sf::Key::Right; + case 0x7e: return sf::Key::Up; + case 0x7d: return sf::Key::Down; + + case NSLeftArrowFunctionKey: return sf::Key::Left; + case NSRightArrowFunctionKey: return sf::Key::Right; + case NSUpArrowFunctionKey: return sf::Key::Up; + case NSDownArrowFunctionKey: return sf::Key::Down; + + case 0x52: return sf::Key::Numpad0; + case 0x53: return sf::Key::Numpad1; + case 0x54: return sf::Key::Numpad2; + case 0x55: return sf::Key::Numpad3; + case 0x56: return sf::Key::Numpad4; + case 0x57: return sf::Key::Numpad5; + case 0x58: return sf::Key::Numpad6; + case 0x59: return sf::Key::Numpad7; + case 0x5b: return sf::Key::Numpad8; + case 0x5c: return sf::Key::Numpad9; + + // Duplicates (see next §). + case 0x7a: return sf::Key::F1; + case 0x78: return sf::Key::F2; + case 0x63: return sf::Key::F3; + case 0x76: return sf::Key::F4; + case 0x60: return sf::Key::F5; + case 0x61: return sf::Key::F6; + case 0x62: return sf::Key::F7; + case 0x64: return sf::Key::F8; + case 0x65: return sf::Key::F9; + case 0x6d: return sf::Key::F10; + case 0x67: return sf::Key::F11; + case 0x6f: return sf::Key::F12; + case 0x69: return sf::Key::F13; + case 0x6b: return sf::Key::F14; + case 0x71: return sf::Key::F15; + + case NSF1FunctionKey: return sf::Key::F1; + case NSF2FunctionKey: return sf::Key::F2; + case NSF3FunctionKey: return sf::Key::F3; + case NSF4FunctionKey: return sf::Key::F4; + case NSF5FunctionKey: return sf::Key::F5; + case NSF6FunctionKey: return sf::Key::F6; + case NSF7FunctionKey: return sf::Key::F7; + case NSF8FunctionKey: return sf::Key::F8; + case NSF9FunctionKey: return sf::Key::F9; + case NSF10FunctionKey: return sf::Key::F10; + case NSF11FunctionKey: return sf::Key::F11; + case NSF12FunctionKey: return sf::Key::F12; + case NSF13FunctionKey: return sf::Key::F13; + case NSF14FunctionKey: return sf::Key::F14; + case NSF15FunctionKey: return sf::Key::F15; + + case NSPauseFunctionKey: return sf::Key::Pause; + +#warning keycode 0x1b is not bound to any key. + // This key is ' on CH-FR, ) on FR and - on US layouts. + + // An unknown key. + default: return sf::Key::Count; + } +} + diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm index 171a2b711..6999b520a 100644 --- a/src/SFML/Window/OSX/SFWindowController.mm +++ b/src/SFML/Window/OSX/SFWindowController.mm @@ -66,7 +66,7 @@ //////////////////////////////////////////////////////// -(id)initWithWindow:(NSWindow *)window { - if (self = [super init]) { + if ((self = [super init])) { myRequester = 0; // Retain the window for our own use. @@ -105,7 +105,7 @@ //////////////////////////////////////////////////////// -(id)initWithMode:(sf::VideoMode const &)mode andStyle:(unsigned long)style { - if (self = [super init]) { + if ((self = [super init])) { myRequester = 0; // Create our window size. diff --git a/src/SFML/Window/OSX/WindowImplCocoa.hpp b/src/SFML/Window/OSX/WindowImplCocoa.hpp index ad38a64df..49ee63247 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.hpp +++ b/src/SFML/Window/OSX/WindowImplCocoa.hpp @@ -194,22 +194,20 @@ public: /// /// Send the event to SFML WindowImpl class. /// - /// \param keycode - /// \param modifierFlags + /// \param key /// //////////////////////////////////////////////////////////// - void KeyDown(unsigned short keycode, unsigned int modifierFlags); + void KeyDown(Event::KeyEvent key); //////////////////////////////////////////////////////////// /// \brief Key Up Event – called by the cocoa view object. /// /// Send the event to SFML WindowImpl class. /// - /// \param keycode - /// \param modifierFlags + /// \param key /// //////////////////////////////////////////////////////////// - void KeyUp(unsigned short keycode, unsigned int modifierFlags); + void KeyUp(Event::KeyEvent key); //////////////////////////////////////////////////////////// /// \brief Text Entred Event – called by the cocoa view object. @@ -232,14 +230,6 @@ public: void ApplyContext(NSOpenGLContextRef context) const; private: - //////////////////////////////////////////////////////////// - /// \brief Convert Cocoa keycode to SFML keycode. - /// - /// \param rawchar Cocoa keycode to convert - /// - //////////////////////////////////////////////////////////// - static Key::Code NSKeyCodeToSFMLKeyCode(unichar rawchar); - //////////////////////////////////////////////////////////// /// \brief Process incoming events from the operating system /// diff --git a/src/SFML/Window/OSX/WindowImplCocoa.mm b/src/SFML/Window/OSX/WindowImplCocoa.mm index 3f5f017b4..76550e226 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.mm +++ b/src/SFML/Window/OSX/WindowImplCocoa.mm @@ -241,40 +241,22 @@ void WindowImplCocoa::MouseMovedOut(void) //////////////////////////////////////////////////////////// -void WindowImplCocoa::KeyDown(unsigned short keycode, unsigned int modifierFlags) +void WindowImplCocoa::KeyDown(Event::KeyEvent key) { Event event; event.Type = Event::KeyPressed; - - event.Key.Code = NSKeyCodeToSFMLKeyCode(keycode); - if (event.Key.Code == Key::Count) { - sf::Err() << "Unknown key (pressed)" << std::endl; - return; // Not a valid/supported key. - } - - event.Key.Alt = modifierFlags & NSAlternateKeyMask; - event.Key.Control = modifierFlags & NSControlKeyMask; - event.Key.Shift = modifierFlags & NSShiftKeyMask; + event.Key = key; PushEvent(event); } //////////////////////////////////////////////////////////// -void WindowImplCocoa::KeyUp(unsigned short keycode, unsigned int modifierFlags) +void WindowImplCocoa::KeyUp(Event::KeyEvent key) { Event event; event.Type = Event::KeyReleased; - - event.Key.Code = NSKeyCodeToSFMLKeyCode(keycode); - if (event.Key.Code == Key::Count) { - sf::Err() << "Unknown key (released)" << std::endl; - return; // Not a valid/supported key. - } - - event.Key.Alt = modifierFlags & NSAlternateKeyMask; - event.Key.Control = modifierFlags & NSControlKeyMask; - event.Key.Shift = modifierFlags & NSShiftKeyMask; + event.Key = key; PushEvent(event); } @@ -289,121 +271,7 @@ void WindowImplCocoa::TextEntered(unichar charcode) PushEvent(event); } - - -//////////////////////////////////////////////////////////// -Key::Code WindowImplCocoa::NSKeyCodeToSFMLKeyCode(unsigned short keycode) { - /* Based on http://forums.macrumors.com/showthread.php?t=780577 */ - switch (keycode) { - case 0x00: return Key::A; - case 0x0b: return Key::B; - case 0x08: return Key::C; - case 0x02: return Key::D; - case 0x0e: return Key::E; - case 0x03: return Key::F; - case 0x05: return Key::G; - case 0x04: return Key::H; - case 0x22: return Key::I; - case 0x26: return Key::J; - case 0x28: return Key::K; - case 0x25: return Key::L; - case 0x2e: return Key::M; - case 0x2d: return Key::N; - case 0x1f: return Key::O; - case 0x23: return Key::P; - case 0x0c: return Key::Q; - case 0x0f: return Key::R; - case 0x01: return Key::S; - case 0x11: return Key::T; - case 0x20: return Key::U; - case 0x09: return Key::V; - case 0x0d: return Key::W; - case 0x07: return Key::X; - case 0x10: return Key::Y; - case 0x06: return Key::Z; - case 0x1d: return Key::Num0; - case 0x12: return Key::Num1; - case 0x13: return Key::Num2; - case 0x14: return Key::Num3; - case 0x15: return Key::Num4; - case 0x17: return Key::Num5; - case 0x16: return Key::Num6; - case 0x1a: return Key::Num7; - case 0x1c: return Key::Num8; - case 0x19: return Key::Num9; - case 0x35: return Key::Escape; - case 0x3b: return Key::LControl; - case 0x38: return Key::LShift; - case 0x3a: return Key::LAlt; - case 0x37: return Key::LSystem; - case 0x3e: return Key::RControl; - case 0x3c: return Key::RShift; - case 0x3d: return Key::RAlt; - case 0x36: return Key::RSystem; -#warning unknown key code for Menu -// case 0x: return Key::Menu; - case 0x21: return Key::LBracket; - case 0x1e: return Key::RBracket; - case 0x29: return Key::SemiColon; - case 0x2b: return Key::Comma; - case 0x2f: return Key::Period; - case 0x27: return Key::Quote; - case 0x2c: return Key::Slash; - case 0x2a: return Key::BackSlash; -#warning 0x0a is for "Non-US Backslash" (from HID Calibrator, a sample provided by Apple). - case 0x0a: return Key::Tilde; - case 0x18: return Key::Equal; - case 0x32: return Key::Dash; - case 0x31: return Key::Space; - case 0x24: return Key::Return; -#warning unknown key code for Back -// case 0x: return Key::Back; - case 0x30: return Key::Tab; - case 0x74: return Key::PageUp; - case 0x79: return Key::PageDown; - case 0x77: return Key::End; - case 0x73: return Key::Home; -#warning unknown key code for Insert -// case 0x: return Key::Insert; - case 0x33: return Key::Delete; - case 0x45: return Key::Add; - case 0x4e: return Key::Subtract; - case 0x43: return Key::Multiply; - case 0x4b: return Key::Divide; - case 0x7b: return Key::Left; - case 0x7c: return Key::Right; - case 0x7e: return Key::Up; - case 0x7d: return Key::Down; - case 0x52: return Key::Numpad0; - case 0x53: return Key::Numpad1; - case 0x54: return Key::Numpad2; - case 0x55: return Key::Numpad3; - case 0x56: return Key::Numpad4; - case 0x57: return Key::Numpad5; - case 0x58: return Key::Numpad6; - case 0x59: return Key::Numpad7; - case 0x5b: return Key::Numpad8; - case 0x5c: return Key::Numpad9; - case 0x7a: return Key::F1; - case 0x78: return Key::F2; - case 0x63: return Key::F3; - case 0x76: return Key::F4; - case 0x60: return Key::F5; - case 0x61: return Key::F6; - case 0x62: return Key::F7; - case 0x64: return Key::F8; - case 0x65: return Key::F9; - case 0x6d: return Key::F10; - case 0x67: return Key::F11; - case 0x6f: return Key::F12; - case 0x69: return Key::F13; - case 0x6b: return Key::F14; - case 0x71: return Key::F15; -#warning unknown key code for PAUSE -// case 0x: return Key::PAUSE; - default: return Key::Count; // An unknown key. - } -} + #pragma mark #pragma mark WindowImplCocoa's event-related methods