git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
289
deps/juce/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp
vendored
Normal file
289
deps/juce/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp
vendored
Normal file
@ -0,0 +1,289 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
KeyPress::KeyPress (int code, ModifierKeys m, juce_wchar textChar) noexcept
|
||||
: keyCode (code), mods (m), textCharacter (textChar)
|
||||
{
|
||||
}
|
||||
|
||||
KeyPress::KeyPress (const int code) noexcept : keyCode (code)
|
||||
{
|
||||
}
|
||||
|
||||
bool KeyPress::operator== (int otherKeyCode) const noexcept
|
||||
{
|
||||
return keyCode == otherKeyCode && ! mods.isAnyModifierKeyDown();
|
||||
}
|
||||
|
||||
bool KeyPress::operator== (const KeyPress& other) const noexcept
|
||||
{
|
||||
return mods.getRawFlags() == other.mods.getRawFlags()
|
||||
&& (textCharacter == other.textCharacter
|
||||
|| textCharacter == 0
|
||||
|| other.textCharacter == 0)
|
||||
&& (keyCode == other.keyCode
|
||||
|| (keyCode < 256
|
||||
&& other.keyCode < 256
|
||||
&& CharacterFunctions::toLowerCase ((juce_wchar) keyCode)
|
||||
== CharacterFunctions::toLowerCase ((juce_wchar) other.keyCode)));
|
||||
}
|
||||
|
||||
bool KeyPress::operator!= (const KeyPress& other) const noexcept { return ! operator== (other); }
|
||||
bool KeyPress::operator!= (int otherKeyCode) const noexcept { return ! operator== (otherKeyCode); }
|
||||
|
||||
bool KeyPress::isCurrentlyDown() const
|
||||
{
|
||||
return isKeyCurrentlyDown (keyCode)
|
||||
&& (ModifierKeys::currentModifiers.getRawFlags() & ModifierKeys::allKeyboardModifiers)
|
||||
== (mods.getRawFlags() & ModifierKeys::allKeyboardModifiers);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
namespace KeyPressHelpers
|
||||
{
|
||||
struct KeyNameAndCode
|
||||
{
|
||||
const char* name;
|
||||
int code;
|
||||
};
|
||||
|
||||
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 }
|
||||
};
|
||||
|
||||
struct ModifierDescription
|
||||
{
|
||||
const char* name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
static const ModifierDescription modifierNames[] =
|
||||
{
|
||||
{ "ctrl", ModifierKeys::ctrlModifier },
|
||||
{ "control", ModifierKeys::ctrlModifier },
|
||||
{ "ctl", ModifierKeys::ctrlModifier },
|
||||
{ "shift", ModifierKeys::shiftModifier },
|
||||
{ "shft", ModifierKeys::shiftModifier },
|
||||
{ "alt", ModifierKeys::altModifier },
|
||||
{ "option", ModifierKeys::altModifier },
|
||||
{ "command", ModifierKeys::commandModifier },
|
||||
{ "cmd", ModifierKeys::commandModifier }
|
||||
};
|
||||
|
||||
static const char* numberPadPrefix() noexcept { return "numpad "; }
|
||||
|
||||
static int getNumpadKeyCode (const String& desc)
|
||||
{
|
||||
if (desc.containsIgnoreCase (numberPadPrefix()))
|
||||
{
|
||||
auto lastChar = desc.trimEnd().getLastCharacter();
|
||||
|
||||
switch (lastChar)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
return (int) (KeyPress::numberPad0 + (int) lastChar - '0');
|
||||
|
||||
case '+': return KeyPress::numberPadAdd;
|
||||
case '-': return KeyPress::numberPadSubtract;
|
||||
case '*': return KeyPress::numberPadMultiply;
|
||||
case '/': return KeyPress::numberPadDivide;
|
||||
case '.': return KeyPress::numberPadDecimalPoint;
|
||||
case '=': return KeyPress::numberPadEquals;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (desc.endsWith ("separator")) return KeyPress::numberPadSeparator;
|
||||
if (desc.endsWith ("delete")) return KeyPress::numberPadDelete;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if JUCE_MAC || JUCE_IOS
|
||||
struct OSXSymbolReplacement
|
||||
{
|
||||
const char* text;
|
||||
juce_wchar symbol;
|
||||
};
|
||||
|
||||
const OSXSymbolReplacement osxSymbols[] =
|
||||
{
|
||||
{ "shift + ", 0x21e7 },
|
||||
{ "command + ", 0x2318 },
|
||||
{ "option + ", 0x2325 },
|
||||
{ "ctrl + ", 0x2303 },
|
||||
{ "return", 0x21b5 },
|
||||
{ "cursor left", 0x2190 },
|
||||
{ "cursor right", 0x2192 },
|
||||
{ "cursor up", 0x2191 },
|
||||
{ "cursor down", 0x2193 },
|
||||
{ "backspace", 0x232b },
|
||||
{ "delete", 0x2326 },
|
||||
{ "spacebar", 0x2423 }
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
KeyPress KeyPress::createFromDescription (const String& desc)
|
||||
{
|
||||
int modifiers = 0;
|
||||
|
||||
for (int i = 0; i < numElementsInArray (KeyPressHelpers::modifierNames); ++i)
|
||||
if (desc.containsWholeWordIgnoreCase (KeyPressHelpers::modifierNames[i].name))
|
||||
modifiers |= KeyPressHelpers::modifierNames[i].flag;
|
||||
|
||||
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)
|
||||
key = KeyPressHelpers::getNumpadKeyCode (desc);
|
||||
|
||||
if (key == 0)
|
||||
{
|
||||
// see if it's a function key..
|
||||
if (! desc.containsChar ('#')) // avoid mistaking hex-codes like "#f1"
|
||||
{
|
||||
for (int i = 1; i <= 35; ++i)
|
||||
{
|
||||
if (desc.containsWholeWordIgnoreCase ("f" + String (i)))
|
||||
{
|
||||
if (i <= 16) key = F1Key + i - 1;
|
||||
else if (i <= 24) key = F17Key + i - 17;
|
||||
else if (i <= 35) key = F25Key + i - 25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key == 0)
|
||||
{
|
||||
// give up and use the hex code..
|
||||
auto hexCode = desc.fromFirstOccurrenceOf ("#", false, false)
|
||||
.retainCharacters ("0123456789abcdefABCDEF")
|
||||
.getHexValue32();
|
||||
|
||||
if (hexCode > 0)
|
||||
key = hexCode;
|
||||
else
|
||||
key = (int) CharacterFunctions::toUpperCase (desc.getLastCharacter());
|
||||
}
|
||||
}
|
||||
|
||||
return KeyPress (key, ModifierKeys (modifiers), 0);
|
||||
}
|
||||
|
||||
String KeyPress::getTextDescription() const
|
||||
{
|
||||
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 == '/' && keyCode != numberPadDivide)
|
||||
return "/";
|
||||
|
||||
if (mods.isCtrlDown()) desc << "ctrl + ";
|
||||
if (mods.isShiftDown()) desc << "shift + ";
|
||||
|
||||
#if JUCE_MAC || JUCE_IOS
|
||||
if (mods.isAltDown()) desc << "option + ";
|
||||
if (mods.isCommandDown()) desc << "command + ";
|
||||
#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;
|
||||
|
||||
// not all F keys have consecutive key codes on all platforms
|
||||
if (keyCode >= F1Key && keyCode <= F16Key) desc << 'F' << (1 + keyCode - F1Key);
|
||||
else if (keyCode >= F17Key && keyCode <= F24Key) desc << 'F' << (17 + keyCode - F17Key);
|
||||
else if (keyCode >= F25Key && keyCode <= F35Key) desc << 'F' << (25 + keyCode - F25Key);
|
||||
else if (keyCode >= numberPad0 && keyCode <= numberPad9) desc << KeyPressHelpers::numberPadPrefix() << (keyCode - numberPad0);
|
||||
else if (keyCode >= 33 && keyCode < 176) desc += CharacterFunctions::toUpperCase ((juce_wchar) 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 == numberPadEquals) desc << KeyPressHelpers::numberPadPrefix() << '=';
|
||||
else if (keyCode == numberPadDelete) desc << KeyPressHelpers::numberPadPrefix() << "delete";
|
||||
else desc << '#' << String::toHexString (keyCode);
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
String KeyPress::getTextDescriptionWithIcons() const
|
||||
{
|
||||
#if JUCE_MAC || JUCE_IOS
|
||||
auto s = getTextDescription();
|
||||
|
||||
for (int i = 0; i < numElementsInArray (KeyPressHelpers::osxSymbols); ++i)
|
||||
s = s.replace (KeyPressHelpers::osxSymbols[i].text,
|
||||
String::charToString (KeyPressHelpers::osxSymbols[i].symbol));
|
||||
|
||||
return s;
|
||||
#else
|
||||
return getTextDescription();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace juce
|
Reference in New Issue
Block a user