Refactor SFOpenGLView and move code related to modifiers to a new file

Now SFKeyboardModifiersHelper.(h|mm) manage all the logic of modifier
flags and the state of the corresponding keys

Also, now modifiers key release events are correctly fired with
multiple SFML windows.
This commit is contained in:
Marco Antognini 2013-06-28 10:46:14 +02:00
parent 95678e851a
commit 8ecdd3ae8c
5 changed files with 331 additions and 490 deletions

View File

@ -82,6 +82,8 @@ else() # MACOSX
${SRCROOT}/OSX/SFApplication.m ${SRCROOT}/OSX/SFApplication.m
${SRCROOT}/OSX/SFContext.hpp ${SRCROOT}/OSX/SFContext.hpp
${SRCROOT}/OSX/SFContext.mm ${SRCROOT}/OSX/SFContext.mm
${SRCROOT}/OSX/SFKeyboardModifiersHelper.h
${SRCROOT}/OSX/SFKeyboardModifiersHelper.mm
${SRCROOT}/OSX/SFOpenGLView.h ${SRCROOT}/OSX/SFOpenGLView.h
${SRCROOT}/OSX/SFOpenGLView.mm ${SRCROOT}/OSX/SFOpenGLView.mm
${SRCROOT}/OSX/SFSilentResponder.h ${SRCROOT}/OSX/SFSilentResponder.h

View File

@ -0,0 +1,65 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2012 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent.gom@gmail.com),
//
// 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
////////////////////////////////////////////////////////////
#import <AppKit/AppKit.h>
namespace sf {
namespace priv {
class WindowImplCocoa;
}
}
////////////////////////////////////////////////////////////
/// Keyboard Modifiers Helper
///
/// Handle modifiers (cmd, ctrl, alt, shift) events and send
/// them back to the requester.
///
/// As I don't have the right control keycode I cannot
/// implement left-right recognition for this key.
/// (See SFKeyboardModifiersHelper.mm for more info.)
///
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// Set up a SFML key event based on the given modifiers
/// flags and key code.
///
////////////////////////////////////////////////////////////
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key);
////////////////////////////////////////////////////////////
/// Handle the state of modifiers keys and send key
/// release & pressed events to the requester.
///
////////////////////////////////////////////////////////////
void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& requester);

View File

@ -0,0 +1,249 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2012 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent.gom@gmail.com),
//
// 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/SFKeyboardModifiersHelper.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
////////////////////////////////////////////////////////////
// Local Data Structures
////////////////////////////////////////////////////////////
/// Modifiers states
struct ModifiersState
{
BOOL rightShiftWasDown;
BOOL leftShiftWasDown;
BOOL rightCommandWasDown;
BOOL leftCommandWasDown;
BOOL rightAlternateWasDown;
BOOL leftAlternateWasDown;
BOOL controlWasDown;
// Left & right control keys not yet supported. See the note above.
};
////////////////////////////////////////////////////////////
// Global Variables
////////////////////////////////////////////////////////////
/// Share 'modifiers' state with all windows to correctly fire pressed/released events
static ModifiersState state;
static BOOL isStateInitialized = NO;
////////////////////////////////////////////////////////////
// Local & Private Functions
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// Carefully observe if the key mask is on in the modifiers
///
////////////////////////////////////////////////////////////
BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask);
////////////////////////////////////////////////////////
/// Init the global state only if needed
///
////////////////////////////////////////////////////////////
void ensureModifiersStateIsInitilized();
////////////////////////////////////////////////////////////
/// Handle one modifier key mask, update the key state and
/// send events to the requester
///
////////////////////////////////////////////////////////////
void processOneModifier(NSUInteger modifiers, NSUInteger mask,
BOOL& wasDown, sf::Keyboard::Key key,
sf::priv::WindowImplCocoa& requester);
////////////////////////////////////////////////////////////
/// Handle left & right modifier keys, update the keys state and
/// send events to the requester
///
////////////////////////////////////////////////////////////
void processLeftRightModifiers(NSUInteger modifiers,
NSUInteger leftMask, NSUInteger rightMask,
BOOL& leftWasDown, BOOL& rightWasDown,
sf::Keyboard::Key leftKey, sf::Keyboard::Key rightKey,
sf::priv::WindowImplCocoa& requester);
////////////////////////////////////////////////////////////
// Implementations
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key)
{
sf::Event::KeyEvent event;
event.code = key;
event.alt = modifiers & NSAlternateKeyMask;
event.control = modifiers & NSControlKeyMask;
event.shift = modifiers & NSShiftKeyMask;
event.system = modifiers & NSCommandKeyMask;
return event;
}
////////////////////////////////////////////////////////
void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& requester)
{
// Handle shift
processLeftRightModifiers(
modifiers,
NSLeftShiftKeyMask, NSRightShiftKeyMask,
state.leftShiftWasDown, state.rightShiftWasDown,
sf::Keyboard::LShift, sf::Keyboard::RShift,
requester
);
// Handle command
processLeftRightModifiers(
modifiers,
NSLeftCommandKeyMask, NSRightCommandKeyMask,
state.leftCommandWasDown, state.rightCommandWasDown,
sf::Keyboard::LSystem, sf::Keyboard::RSystem,
requester
);
// Handle option (alt)
processLeftRightModifiers(
modifiers,
NSLeftAlternateKeyMask, NSRightAlternateKeyMask,
state.leftAlternateWasDown, state.rightAlternateWasDown,
sf::Keyboard::LAlt, sf::Keyboard::RAlt,
requester
);
// Handle control
// Currently only the left control key will be used in SFML (see note above).
processOneModifier(
modifiers, NSControlKeyMask,
state.controlWasDown, sf::Keyboard::LControl,
requester
);
}
////////////////////////////////////////////////////////
BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask)
{
// Here we need to make sure it's exactly the mask since some masks
// share some bits such that the & operation would result in a non zero
// value without corresponding to the processed key.
return (modifiers & mask) == mask;
}
////////////////////////////////////////////////////////
void ensureModifiersStateIsInitilized()
{
if (isStateInitialized) return;
NSUInteger modifiers = [[NSApp currentEvent] modifierFlags];
// Load current keyboard state
state.leftShiftWasDown = isKeyMaskActive(modifiers, NSLeftShiftKeyMask);
state.rightShiftWasDown = isKeyMaskActive(modifiers, NSRightShiftKeyMask);
state.leftCommandWasDown = isKeyMaskActive(modifiers, NSLeftCommandKeyMask);
state.rightCommandWasDown = isKeyMaskActive(modifiers, NSRightCommandKeyMask);
state.leftAlternateWasDown = isKeyMaskActive(modifiers, NSLeftAlternateKeyMask);
state.rightAlternateWasDown = isKeyMaskActive(modifiers, NSRightAlternateKeyMask);
state.controlWasDown = isKeyMaskActive(modifiers, NSControlKeyMask);
// Currently only the left control key will be used in SFML (see note above).
isStateInitialized = YES;
}
////////////////////////////////////////////////////////
void processOneModifier(NSUInteger modifiers, NSUInteger mask,
BOOL& wasDown, sf::Keyboard::Key key,
sf::priv::WindowImplCocoa& requester)
{
ensureModifiersStateIsInitilized();
// Setup a potential event key.
sf::Event::KeyEvent event = keyEventWithModifiers(modifiers, key);
// State
BOOL isDown = isKeyMaskActive(modifiers, mask);
// Check for key pressed event
if (isDown && !wasDown) {
requester.keyDown(event);
}
// And check for key released event
else if (!isDown && wasDown) {
requester.keyUp(event);
}
// else isDown == wasDown, so no change
// Update state
wasDown = isDown;
}
////////////////////////////////////////////////////////
void processLeftRightModifiers(NSUInteger modifiers,
NSUInteger leftMask, NSUInteger rightMask,
BOOL& leftWasDown, BOOL& rightWasDown,
sf::Keyboard::Key leftKey, sf::Keyboard::Key rightKey,
sf::priv::WindowImplCocoa& requester)
{
processOneModifier(modifiers, leftMask, leftWasDown, leftKey, requester);
processOneModifier(modifiers, rightMask, rightWasDown, rightKey, requester);
}

View File

@ -47,8 +47,8 @@ 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 /// Modifiers keys (cmd, ctrl, alt, shift) are handled by this class
/// recognition for this key. (See SFOpenGLView.mm for more info.) /// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm).
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@interface SFOpenGLView : NSOpenGLView { @interface SFOpenGLView : NSOpenGLView {
@ -57,18 +57,9 @@ namespace sf {
NSTrackingRectTag m_trackingTag; NSTrackingRectTag m_trackingTag;
BOOL m_mouseIsIn; BOOL m_mouseIsIn;
NSSize m_realSize; NSSize m_realSize;
/// 'modifiers' state
BOOL m_rightShiftWasDown;
BOOL m_leftShiftWasDown;
BOOL m_rightCommandWasDown;
BOOL m_leftCommandWasDown;
BOOL m_rightAlternateWasDown;
BOOL m_leftAlternateWasDown;
BOOL m_controlWasDown;
// Hidden text view use to convert key event to actual chars. // Hidden text view used to convert key event to actual chars.
// To prevent sound alert we use a silent responder. // We use a silent responder to prevent sound alerts.
SFSilentResponder* m_silentResponder; SFSilentResponder* m_silentResponder;
NSTextView* m_hiddenTextView; NSTextView* m_hiddenTextView;
} }

View File

@ -32,35 +32,8 @@
#import <SFML/Window/OSX/SFOpenGLView.h> #import <SFML/Window/OSX/SFOpenGLView.h>
#import <SFML/Window/OSX/SFSilentResponder.h> #import <SFML/Window/OSX/SFSilentResponder.h>
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.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);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Returns true if `event` represents a representable character. /// Returns true if `event` represents a representable character.
@ -71,6 +44,7 @@ NSUInteger keepOnlyMaskFromData(NSUInteger data, NSUInteger mask);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
BOOL isValidTextUnicode(NSEvent* event); BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// SFOpenGLView class : Privates Methods Declaration /// SFOpenGLView class : Privates Methods Declaration
/// ///
@ -89,12 +63,6 @@ BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
-(BOOL)isMouseInside; -(BOOL)isMouseInside;
////////////////////////////////////////////////////////////
/// Init the 'modifiers' key state.
///
////////////////////////////////////////////////////////////
-(void)initModifiersState;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Convert the NSEvent mouse button type to SFML type. /// Convert the NSEvent mouse button type to SFML type.
/// ///
@ -126,7 +94,6 @@ BOOL isValidTextUnicode(NSEvent* event);
[self setRequesterTo:0]; [self setRequesterTo:0];
[self enableKeyRepeat]; [self enableKeyRepeat];
m_realSize = NSZeroSize; m_realSize = NSZeroSize;
[self initModifiersState];
// Register for mouse-move event // Register for mouse-move event
m_mouseIsIn = [self isMouseInside]; m_mouseIsIn = [self isMouseInside];
@ -627,445 +594,27 @@ BOOL isValidTextUnicode(NSEvent* event);
if (m_requester == 0) return; if (m_requester == 0) return;
NSUInteger modifiers = [theEvent modifierFlags]; NSUInteger modifiers = [theEvent modifierFlags];
handleModifiersChanged(modifiers, *m_requester);
// Setup a potential event key.
sf::Event::KeyEvent key;
key.code = sf::Keyboard::Unknown;
key.alt = modifiers & NSAlternateKeyMask;
key.control = modifiers & NSControlKeyMask;
key.shift = modifiers & NSShiftKeyMask;
key.system = modifiers & NSCommandKeyMask;
// 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 (m_leftShiftWasDown) {
// left shift released
leftShiftIsDown = NO;
key.code = sf::Keyboard::LShift;
m_requester->keyUp(key);
}
if (!m_rightShiftWasDown) {
// right shift pressed
key.code = sf::Keyboard::RShift;
m_requester->keyDown(key);
}
}
// Only left shift is down ?
if (shift == NSLeftShiftKeyMask) {
leftShiftIsDown = YES;
if (m_rightShiftWasDown) {
// right shift released
rightShiftIsDown = NO;
key.code = sf::Keyboard::RShift;
m_requester->keyUp(key);
}
if (!m_leftShiftWasDown) {
// left shift pressed
key.code = sf::Keyboard::LShift;
m_requester->keyDown(key);
}
}
// Or are they both down ?
if (shift == (NSRightShiftKeyMask | NSLeftShiftKeyMask)) {
rightShiftIsDown = YES;
leftShiftIsDown = YES;
if (!m_rightShiftWasDown) {
// right shift pressed
key.code = sf::Keyboard::RShift;
m_requester->keyDown(key);
}
if (!m_leftShiftWasDown) {
// left shift pressed
key.code = sf::Keyboard::LShift;
m_requester->keyDown(key);
}
}
} else { // No shift key down.
rightShiftIsDown = NO;
leftShiftIsDown = NO;
if (m_rightShiftWasDown) {
// right shift released
key.code = sf::Keyboard::RShift;
m_requester->keyUp(key);
}
if (m_leftShiftWasDown) {
// left shift released
key.code = sf::Keyboard::LShift;
m_requester->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 (m_leftCommandWasDown) {
// left command released
leftCommandIsDown = NO;
key.code = sf::Keyboard::LSystem;
m_requester->keyUp(key);
}
if (!m_rightCommandWasDown) {
// right command pressed
key.code = sf::Keyboard::RSystem;
m_requester->keyDown(key);
}
}
// Only left Command is down ?
if (command == NSLeftCommandKeyMask) {
leftCommandIsDown = YES;
if (m_rightCommandWasDown) {
// right command released
rightCommandIsDown = NO;
key.code = sf::Keyboard::RSystem;
m_requester->keyUp(key);
}
if (!m_leftCommandWasDown) {
// left command pressed
key.code = sf::Keyboard::LSystem;
m_requester->keyDown(key);
}
}
// Or are they both down ?
if (command == (NSRightCommandKeyMask | NSLeftCommandKeyMask)) {
rightCommandIsDown = YES;
leftCommandIsDown = YES;
if (!m_rightCommandWasDown) {
// right command pressed
key.code = sf::Keyboard::RSystem;
m_requester->keyDown(key);
}
if (!m_leftCommandWasDown) {
// left command pressed
key.code = sf::Keyboard::LSystem;
m_requester->keyDown(key);
}
}
} else { // No Command key down.
rightCommandIsDown = NO;
leftCommandIsDown = NO;
if (m_rightCommandWasDown) {
// right command released
key.code = sf::Keyboard::RSystem;
m_requester->keyUp(key);
}
if (m_leftCommandWasDown) {
// left command released
key.code = sf::Keyboard::LSystem;
m_requester->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 (m_leftAlternateWasDown) {
// left alt released
leftAlternateIsDown = NO;
key.code = sf::Keyboard::LAlt;
m_requester->keyUp(key);
}
if (!m_rightAlternateWasDown) {
// right alt pressed
key.code = sf::Keyboard::RAlt;
m_requester->keyDown(key);
}
}
// Only left Alternate is down ?
if (alternate == NSLeftAlternateKeyMask) {
leftAlternateIsDown = YES;
if (m_rightAlternateWasDown) {
// right alt released
rightAlternateIsDown = NO;
key.code = sf::Keyboard::RAlt;
m_requester->keyUp(key);
}
if (!m_leftAlternateWasDown) {
// left alt pressed
key.code = sf::Keyboard::LAlt;
m_requester->keyDown(key);
}
}
// Or are they both down ?
if (alternate == (NSRightAlternateKeyMask | NSLeftAlternateKeyMask)) {
rightAlternateIsDown = YES;
leftAlternateIsDown = YES;
if (!m_rightAlternateWasDown) {
// right alt pressed
key.code = sf::Keyboard::RAlt;
m_requester->keyDown(key);
}
if (!m_leftAlternateWasDown) {
// left alt pressed
key.code = sf::Keyboard::LAlt;
m_requester->keyDown(key);
}
}
} else { // No Alternate key down.
rightAlternateIsDown = NO;
leftAlternateIsDown = NO;
if (m_rightAlternateWasDown) {
// right alt released
key.code = sf::Keyboard::RAlt;
m_requester->keyUp(key);
}
if (m_leftAlternateWasDown) {
// left alt released
key.code = sf::Keyboard::LAlt;
m_requester->keyUp(key);
}
}
// Control keys.
if (modifiers & NSControlKeyMask) {
// Currently only the left control key will be used in SFML (see note above).
controlIsDown = YES;
if (!m_controlWasDown) {
// ctrl pressed
key.code = sf::Keyboard::LControl;
m_requester->keyDown(key);
}
} else { // No control key down.
controlIsDown = NO;
if (m_controlWasDown) {
// ctrl released
key.code = sf::Keyboard::LControl;
m_requester->keyUp(key);
}
}
// Update the state
m_rightShiftWasDown = rightShiftIsDown;
m_leftShiftWasDown = leftShiftIsDown;
m_rightCommandWasDown = rightCommandIsDown;
m_leftCommandWasDown = leftCommandIsDown;
m_rightAlternateWasDown = rightAlternateIsDown;
m_leftAlternateWasDown = leftAlternateIsDown;
m_controlWasDown = controlIsDown;
}
////////////////////////////////////////////////////////
-(void)initModifiersState
{
// Set default value to NO.
m_rightShiftWasDown = NO;
m_leftShiftWasDown = NO;
m_rightCommandWasDown = NO;
m_leftCommandWasDown = NO;
m_rightAlternateWasDown = NO;
m_leftAlternateWasDown = NO;
m_controlWasDown = 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) {
m_rightShiftWasDown = YES;
}
// Only left shift is down ?
if (shift == NSLeftShiftKeyMask) {
m_leftShiftWasDown = YES;
}
// Or are they both down ?
if (shift == (NSRightShiftKeyMask | NSLeftShiftKeyMask)) {
m_rightShiftWasDown = YES;
m_leftShiftWasDown = 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) {
m_rightCommandWasDown = YES;
}
// Only left Command is down ?
if (command == NSLeftCommandKeyMask) {
m_leftCommandWasDown = YES;
}
// Or are they both down ?
if (command == (NSRightCommandKeyMask | NSLeftCommandKeyMask)) {
m_rightCommandWasDown = YES;
m_leftCommandWasDown = 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) {
m_rightAlternateWasDown = YES;
}
// Only left Alternate is down ?
if (alternate == NSLeftAlternateKeyMask) {
m_leftAlternateWasDown = YES;
}
// Or are they both down ?
if (alternate == (NSRightAlternateKeyMask | NSLeftAlternateKeyMask)) {
m_rightAlternateWasDown = YES;
m_leftAlternateWasDown = YES;
}
}
// Control keys.
if (modifiers & NSControlKeyMask) {
// Currently only the left control key will be used in SFML (see note above).
m_controlWasDown = YES;
}
} }
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent +(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent
{ {
sf::Event::KeyEvent key; // Key code
sf::Keyboard::Key key = sf::Keyboard::Unknown;
// Modifiers. // First we look if the key down is from a list of characters
NSUInteger modifierFlags = [anEvent modifierFlags];
key.alt = modifierFlags & NSAlternateKeyMask;
key.control = modifierFlags & NSControlKeyMask;
key.shift = modifierFlags & NSShiftKeyMask;
key.system = modifierFlags & NSCommandKeyMask;
// Key code.
key.code = sf::Keyboard::Unknown;
// First we look if the key down is from a list of caracter
// that depend on keyboard localization. // that depend on keyboard localization.
NSString* string = [anEvent charactersIgnoringModifiers]; NSString* string = [anEvent charactersIgnoringModifiers];
if ([string length] > 0) { if ([string length] > 0) {
key.code = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]); key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
} }
// The key is not a localized one, so we try to find a corresponding code // If the key is not a localized one, we try to find a corresponding code
// through virtual key code. // through virtual key code.
if (key.code == sf::Keyboard::Unknown) { if (key == sf::Keyboard::Unknown) {
key.code = sf::priv::HIDInputManager::nonLocalizedKeys([anEvent keyCode]); key = sf::priv::HIDInputManager::nonLocalizedKeys([anEvent keyCode]);
} }
//#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages. //#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages.
@ -1078,7 +627,7 @@ BOOL isValidTextUnicode(NSEvent* event);
// } // }
//#endif //#endif
return key; return keyEventWithModifiers([anEvent modifierFlags], key);
} }
@end @end
@ -1086,21 +635,6 @@ BOOL isValidTextUnicode(NSEvent* event);
#pragma mark - C-like functions #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);
}
BOOL isValidTextUnicode(NSEvent* event) BOOL isValidTextUnicode(NSEvent* event)
{ {
if ([event keyCode] == 0x35) { // Escape if ([event keyCode] == 0x35) { // Escape