1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
JUCE/src/gui/components/keyboard/juce_KeyPress.cpp
2010-03-26 18:23:54 +00:00

281 lines
9.7 KiB
C++

/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../../../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_KeyPress.h"
#include "../juce_Component.h"
//==============================================================================
KeyPress::KeyPress() throw()
: keyCode (0),
mods (0),
textCharacter (0)
{
}
KeyPress::KeyPress (const int keyCode_,
const ModifierKeys& mods_,
const juce_wchar textCharacter_) throw()
: keyCode (keyCode_),
mods (mods_),
textCharacter (textCharacter_)
{
}
KeyPress::KeyPress (const int keyCode_) throw()
: keyCode (keyCode_),
textCharacter (0)
{
}
KeyPress::KeyPress (const KeyPress& other) throw()
: keyCode (other.keyCode),
mods (other.mods),
textCharacter (other.textCharacter)
{
}
KeyPress& KeyPress::operator= (const KeyPress& other) throw()
{
keyCode = other.keyCode;
mods = other.mods;
textCharacter = other.textCharacter;
return *this;
}
bool KeyPress::operator== (const KeyPress& other) const throw()
{
return mods.getRawFlags() == other.mods.getRawFlags()
&& (textCharacter == other.textCharacter
|| textCharacter == 0
|| other.textCharacter == 0)
&& (keyCode == other.keyCode
|| (keyCode < 256
&& other.keyCode < 256
&& CharacterFunctions::toLowerCase ((tchar) keyCode)
== CharacterFunctions::toLowerCase ((tchar) other.keyCode)));
}
bool KeyPress::operator!= (const KeyPress& other) const throw()
{
return ! operator== (other);
}
bool KeyPress::isCurrentlyDown() const throw()
{
return isKeyCurrentlyDown (keyCode)
&& (ModifierKeys::getCurrentModifiers().getRawFlags() & ModifierKeys::allKeyboardModifiers)
== (mods.getRawFlags() & ModifierKeys::allKeyboardModifiers);
}
//==============================================================================
namespace KeyPressHelpers
{
struct KeyNameAndCode
{
const char* name;
int code;
};
static const KeyNameAndCode translations[] =
{
{ "spacebar", KeyPress::spaceKey },
{ "return", KeyPress::returnKey },
{ "escape", KeyPress::escapeKey },
{ "backspace", KeyPress::backspaceKey },
{ "cursor left", KeyPress::leftKey },
{ "cursor right", KeyPress::rightKey },
{ "cursor up", KeyPress::upKey },
{ "cursor down", KeyPress::downKey },
{ "page up", KeyPress::pageUpKey },
{ "page down", KeyPress::pageDownKey },
{ "home", KeyPress::homeKey },
{ "end", KeyPress::endKey },
{ "delete", KeyPress::deleteKey },
{ "insert", KeyPress::insertKey },
{ "tab", KeyPress::tabKey },
{ "play", KeyPress::playKey },
{ "stop", KeyPress::stopKey },
{ "fast forward", KeyPress::fastForwardKey },
{ "rewind", KeyPress::rewindKey }
};
static const String numberPadPrefix() { return "numpad "; }
}
//==============================================================================
const KeyPress KeyPress::createFromDescription (const String& desc) throw()
{
int modifiers = 0;
if (desc.containsWholeWordIgnoreCase ("ctrl")
|| desc.containsWholeWordIgnoreCase ("control")
|| desc.containsWholeWordIgnoreCase ("ctl"))
modifiers |= ModifierKeys::ctrlModifier;
if (desc.containsWholeWordIgnoreCase ("shift")
|| desc.containsWholeWordIgnoreCase ("shft"))
modifiers |= ModifierKeys::shiftModifier;
if (desc.containsWholeWordIgnoreCase ("alt")
|| desc.containsWholeWordIgnoreCase ("option"))
modifiers |= ModifierKeys::altModifier;
if (desc.containsWholeWordIgnoreCase ("command")
|| desc.containsWholeWordIgnoreCase ("cmd"))
modifiers |= ModifierKeys::commandModifier;
int key = 0;
for (int i = 0; i < numElementsInArray (KeyPressHelpers::translations); ++i)
{
if (desc.containsWholeWordIgnoreCase (String (KeyPressHelpers::translations[i].name)))
{
key = KeyPressHelpers::translations[i].code;
break;
}
}
if (key == 0)
{
// see if it's a numpad key..
if (desc.containsIgnoreCase (KeyPressHelpers::numberPadPrefix()))
{
const tchar lastChar = desc.trimEnd().getLastCharacter();
if (lastChar >= '0' && lastChar <= '9')
key = numberPad0 + lastChar - '0';
else if (lastChar == '+')
key = numberPadAdd;
else if (lastChar == '-')
key = numberPadSubtract;
else if (lastChar == '*')
key = numberPadMultiply;
else if (lastChar == '/')
key = numberPadDivide;
else if (lastChar == '.')
key = numberPadDecimalPoint;
else if (lastChar == '=')
key = numberPadEquals;
else if (desc.endsWith ("separator"))
key = numberPadSeparator;
else if (desc.endsWith ("delete"))
key = numberPadDelete;
}
if (key == 0)
{
// see if it's a function key..
for (int i = 1; i <= 12; ++i)
if (desc.containsWholeWordIgnoreCase ("f" + String (i)))
key = F1Key + i - 1;
if (key == 0)
{
// give up and use the hex code..
const int hexCode = desc.fromFirstOccurrenceOf ("#", false, false)
.toLowerCase()
.retainCharacters ("0123456789abcdef")
.getHexValue32();
if (hexCode > 0)
key = hexCode;
else
key = CharacterFunctions::toUpperCase (desc.getLastCharacter());
}
}
}
return KeyPress (key, ModifierKeys (modifiers), 0);
}
const String KeyPress::getTextDescription() const throw()
{
String desc;
if (keyCode > 0)
{
// some keyboard layouts use a shift-key to get the slash, but in those cases, we
// want to store it as being a slash, not shift+whatever.
if (textCharacter == '/')
return "/";
if (mods.isCtrlDown())
desc << "ctrl + ";
if (mods.isShiftDown())
desc << "shift + ";
#if JUCE_MAC
// only do this on the mac, because on Windows ctrl and command are the same,
// and this would get confusing
if (mods.isCommandDown())
desc << "command + ";
if (mods.isAltDown())
desc << "option + ";
#else
if (mods.isAltDown())
desc << "alt + ";
#endif
for (int i = 0; i < numElementsInArray (KeyPressHelpers::translations); ++i)
if (keyCode == KeyPressHelpers::translations[i].code)
return desc + KeyPressHelpers::translations[i].name;
if (keyCode >= F1Key && keyCode <= F16Key)
desc << 'F' << (1 + keyCode - F1Key);
else if (keyCode >= numberPad0 && keyCode <= numberPad9)
desc << KeyPressHelpers::numberPadPrefix() << (keyCode - numberPad0);
else if (keyCode >= 33 && keyCode < 176)
desc += CharacterFunctions::toUpperCase ((tchar) keyCode);
else if (keyCode == numberPadAdd)
desc << KeyPressHelpers::numberPadPrefix() << '+';
else if (keyCode == numberPadSubtract)
desc << KeyPressHelpers::numberPadPrefix() << '-';
else if (keyCode == numberPadMultiply)
desc << KeyPressHelpers::numberPadPrefix() << '*';
else if (keyCode == numberPadDivide)
desc << KeyPressHelpers::numberPadPrefix() << '/';
else if (keyCode == numberPadSeparator)
desc << KeyPressHelpers::numberPadPrefix() << "separator";
else if (keyCode == numberPadDecimalPoint)
desc << KeyPressHelpers::numberPadPrefix() << '.';
else if (keyCode == numberPadDelete)
desc << KeyPressHelpers::numberPadPrefix() << "delete";
else
desc << '#' << String::toHexString (keyCode);
}
return desc;
}
END_JUCE_NAMESPACE