mirror of
https://github.com/SFML/SFML.git
synced 2024-11-29 06:41:05 +08:00
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:
parent
95678e851a
commit
8ecdd3ae8c
@ -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
|
||||||
|
65
src/SFML/Window/OSX/SFKeyboardModifiersHelper.h
Normal file
65
src/SFML/Window/OSX/SFKeyboardModifiersHelper.h
Normal 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);
|
||||||
|
|
||||||
|
|
249
src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm
Normal file
249
src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user