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
This commit is contained in:
mantognini 2011-02-11 00:17:19 +00:00
parent 58632672cb
commit f85a1794bc
5 changed files with 833 additions and 167 deletions

View File

@ -45,6 +45,9 @@ namespace sf {
/// bound to its default value we don't recompute the mouse position /// bound to its default value we don't recompute the mouse position
/// and assume it's correct. /// 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 { @interface SFOpenGLView : NSOpenGLView {
sf::priv::WindowImplCocoa* myRequester; sf::priv::WindowImplCocoa* myRequester;
@ -52,6 +55,15 @@ namespace sf {
NSTrackingRectTag myTrackingTag; NSTrackingRectTag myTrackingTag;
BOOL myMouseIsIn; BOOL myMouseIsIn;
NSSize myRealSize; NSSize myRealSize;
/// 'modifiers' state
BOOL myRightShiftWasDown;
BOOL myLeftShiftWasDown;
BOOL myRightCommandWasDown;
BOOL myLeftCommandWasDown;
BOOL myRightAlternateWasDown;
BOOL myLeftAlternateWasDown;
BOOL myControlWasDown;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -27,9 +27,58 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/WindowImplCocoa.hpp> #include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/System/Err.hpp>
#import <SFML/Window/OSX/SFOpenGLView.h> #import <SFML/Window/OSX/SFOpenGLView.h>
////////////////////////////////////////////////////////////
/// 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 /// SFOpenGLView class : Privates Methods Declaration
/// ///
@ -48,6 +97,21 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
-(BOOL)isMouseInside; -(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 @end
@implementation SFOpenGLView @implementation SFOpenGLView
@ -58,11 +122,11 @@
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect -(id)initWithFrame:(NSRect)frameRect
{ {
if (self = [super initWithFrame:frameRect]) { if ((self = [super initWithFrame:frameRect])) {
[self setRequesterTo:0]; [self setRequesterTo:0];
[self enableKeyRepeat]; [self enableKeyRepeat];
myRealSize = NSZeroSize; myRealSize = NSZeroSize;
[self initModifiersState];
// Register for mouse-move event // Register for mouse-move event
myMouseIsIn = [self isMouseInside]; myMouseIsIn = [self isMouseInside];
@ -478,13 +542,26 @@
{ {
if (myRequester == 0) return; if (myRequester == 0) return;
if (myUseKeyRepeat || ![theEvent isARepeat]) if (myUseKeyRepeat || ![theEvent isARepeat]) {
myRequester->KeyDown([theEvent keyCode], [theEvent modifierFlags]); sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
if (key.Code != sf::Key::Count) { // The key is recognized.
myRequester->KeyDown(key);
}
}
if (myUseKeyRepeat || ![theEvent isARepeat]) { if (myUseKeyRepeat || ![theEvent isARepeat]) {
// Let's see if its a valid text. // Let's see if its a valid text.
// -interpretKeyEvents: will call -insertText: if theEvent is a valid caracter. NSText* text = [[self window] fieldEditor:YES forObject:self];
[self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; [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; 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 (myRequester == 0) return;
if ([aString isKindOfClass:[NSAttributedString class]]) {
aString = [aString string]; // We want a NSString. 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 (myRequester == 0 || [aString length] == 0) return; if (!myRightShiftWasDown) {
// right shift pressed
// It's a valid TextEntered event. key.Code = sf::Key::RShift;
myRequester->TextEntered([aString characterAtIndex:0]); 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);
}
}
// 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);
}
}
// 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 @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;
}
}

View File

@ -66,7 +66,7 @@
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(id)initWithWindow:(NSWindow *)window -(id)initWithWindow:(NSWindow *)window
{ {
if (self = [super init]) { if ((self = [super init])) {
myRequester = 0; myRequester = 0;
// Retain the window for our own use. // Retain the window for our own use.
@ -105,7 +105,7 @@
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(id)initWithMode:(sf::VideoMode const &)mode andStyle:(unsigned long)style -(id)initWithMode:(sf::VideoMode const &)mode andStyle:(unsigned long)style
{ {
if (self = [super init]) { if ((self = [super init])) {
myRequester = 0; myRequester = 0;
// Create our window size. // Create our window size.

View File

@ -194,22 +194,20 @@ public:
/// ///
/// Send the event to SFML WindowImpl class. /// Send the event to SFML WindowImpl class.
/// ///
/// \param keycode /// \param key
/// \param modifierFlags
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void KeyDown(unsigned short keycode, unsigned int modifierFlags); void KeyDown(Event::KeyEvent key);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Key Up Event called by the cocoa view object. /// \brief Key Up Event called by the cocoa view object.
/// ///
/// Send the event to SFML WindowImpl class. /// Send the event to SFML WindowImpl class.
/// ///
/// \param keycode /// \param key
/// \param modifierFlags
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void KeyUp(unsigned short keycode, unsigned int modifierFlags); void KeyUp(Event::KeyEvent key);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Text Entred Event called by the cocoa view object. /// \brief Text Entred Event called by the cocoa view object.
@ -232,14 +230,6 @@ public:
void ApplyContext(NSOpenGLContextRef context) const; void ApplyContext(NSOpenGLContextRef context) const;
private: 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 /// \brief Process incoming events from the operating system
/// ///

View File

@ -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 event;
event.Type = Event::KeyPressed; event.Type = Event::KeyPressed;
event.Key = key;
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;
PushEvent(event); PushEvent(event);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void WindowImplCocoa::KeyUp(unsigned short keycode, unsigned int modifierFlags) void WindowImplCocoa::KeyUp(Event::KeyEvent key)
{ {
Event event; Event event;
event.Type = Event::KeyReleased; event.Type = Event::KeyReleased;
event.Key = key;
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;
PushEvent(event); PushEvent(event);
} }
@ -291,120 +273,6 @@ void WindowImplCocoa::TextEntered(unichar charcode)
} }
////////////////////////////////////////////////////////////
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
#pragma mark WindowImplCocoa's event-related methods #pragma mark WindowImplCocoa's event-related methods