mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-13 00:04:19 +00:00
Added Animated App template and examples
This commit is contained in:
parent
fefcf7aca6
commit
ff6520a89a
1141 changed files with 438491 additions and 94 deletions
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
CaretComponent::CaretComponent (Component* const keyFocusOwner)
|
||||
: owner (keyFocusOwner)
|
||||
{
|
||||
setPaintingIsUnclipped (true);
|
||||
setInterceptsMouseClicks (false, false);
|
||||
}
|
||||
|
||||
CaretComponent::~CaretComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void CaretComponent::paint (Graphics& g)
|
||||
{
|
||||
g.setColour (findColour (caretColourId, true));
|
||||
g.fillRect (getLocalBounds());
|
||||
}
|
||||
|
||||
void CaretComponent::timerCallback()
|
||||
{
|
||||
setVisible (shouldBeShown() && ! isVisible());
|
||||
}
|
||||
|
||||
void CaretComponent::setCaretPosition (const Rectangle<int>& characterArea)
|
||||
{
|
||||
startTimer (380);
|
||||
setVisible (shouldBeShown());
|
||||
setBounds (characterArea.withWidth (2));
|
||||
}
|
||||
|
||||
bool CaretComponent::shouldBeShown() const
|
||||
{
|
||||
return owner == nullptr || (owner->hasKeyboardFocus (false)
|
||||
&& ! owner->isCurrentlyBlockedByAnotherModalComponent());
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_CARETCOMPONENT_H_INCLUDED
|
||||
#define JUCE_CARETCOMPONENT_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class JUCE_API CaretComponent : public Component,
|
||||
private Timer
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates the caret component.
|
||||
The keyFocusOwner is an optional component which the caret will check, making
|
||||
itself visible only when the keyFocusOwner has keyboard focus.
|
||||
*/
|
||||
CaretComponent (Component* keyFocusOwner);
|
||||
|
||||
/** Destructor. */
|
||||
~CaretComponent();
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the caret's position to place it next to the given character.
|
||||
The area is the rectangle containing the entire character that the caret is
|
||||
positioned on, so by default a vertical-line caret may choose to just show itself
|
||||
at the left of this area. You can override this method to customise its size.
|
||||
This method will also force the caret to reset its timer and become visible (if
|
||||
appropriate), so that as it moves, you can see where it is.
|
||||
*/
|
||||
virtual void setCaretPosition (const Rectangle<int>& characterArea);
|
||||
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the caret.
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
caretColourId = 0x1000204, /**< The colour with which to draw the caret. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
|
||||
private:
|
||||
Component* owner;
|
||||
|
||||
bool shouldBeShown() const;
|
||||
void timerCallback() override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (CaretComponent)
|
||||
};
|
||||
|
||||
|
||||
#endif // JUCE_CARETCOMPONENT_H_INCLUDED
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
bool KeyListener::keyStateChanged (const bool, Component*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_KEYLISTENER_H_INCLUDED
|
||||
#define JUCE_KEYLISTENER_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Receives callbacks when keys are pressed.
|
||||
|
||||
You can add a key listener to a component to be informed when that component
|
||||
gets key events. See the Component::addListener method for more details.
|
||||
|
||||
@see KeyPress, Component::addKeyListener, KeyPressMappingSet
|
||||
*/
|
||||
class JUCE_API KeyListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~KeyListener() {}
|
||||
|
||||
//==============================================================================
|
||||
/** Called to indicate that a key has been pressed.
|
||||
|
||||
If your implementation returns true, then the key event is considered to have
|
||||
been consumed, and will not be passed on to any other components. If it returns
|
||||
false, then the key will be passed to other components that might want to use it.
|
||||
|
||||
@param key the keystroke, including modifier keys
|
||||
@param originatingComponent the component that received the key event
|
||||
@see keyStateChanged, Component::keyPressed
|
||||
*/
|
||||
virtual bool keyPressed (const KeyPress& key,
|
||||
Component* originatingComponent) = 0;
|
||||
|
||||
/** Called when any key is pressed or released.
|
||||
|
||||
When this is called, classes that might be interested in
|
||||
the state of one or more keys can use KeyPress::isKeyCurrentlyDown() to
|
||||
check whether their key has changed.
|
||||
|
||||
If your implementation returns true, then the key event is considered to have
|
||||
been consumed, and will not be passed on to any other components. If it returns
|
||||
false, then the key will be passed to other components that might want to use it.
|
||||
|
||||
@param originatingComponent the component that received the key event
|
||||
@param isKeyDown true if a key is being pressed, false if one is being released
|
||||
@see KeyPress, Component::keyStateChanged
|
||||
*/
|
||||
virtual bool keyStateChanged (bool isKeyDown, Component* originatingComponent);
|
||||
};
|
||||
|
||||
|
||||
#endif // JUCE_KEYLISTENER_H_INCLUDED
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
KeyPress::KeyPress() noexcept
|
||||
: keyCode (0), textCharacter (0)
|
||||
{
|
||||
}
|
||||
|
||||
KeyPress::KeyPress (int code, ModifierKeys m, juce_wchar textChar) noexcept
|
||||
: keyCode (code), mods (m), textCharacter (textChar)
|
||||
{
|
||||
}
|
||||
|
||||
KeyPress::KeyPress (const int code) noexcept
|
||||
: keyCode (code), textCharacter (0)
|
||||
{
|
||||
}
|
||||
|
||||
KeyPress::KeyPress (const KeyPress& other) noexcept
|
||||
: keyCode (other.keyCode), mods (other.mods),
|
||||
textCharacter (other.textCharacter)
|
||||
{
|
||||
}
|
||||
|
||||
KeyPress& KeyPress::operator= (const KeyPress& other) noexcept
|
||||
{
|
||||
keyCode = other.keyCode;
|
||||
mods = other.mods;
|
||||
textCharacter = other.textCharacter;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
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::getCurrentModifiers().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()))
|
||||
{
|
||||
const juce_wchar 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 + 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
|
||||
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 <= 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)
|
||||
.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 == '/')
|
||||
return "/";
|
||||
|
||||
if (mods.isCtrlDown()) desc << "ctrl + ";
|
||||
if (mods.isShiftDown()) desc << "shift + ";
|
||||
|
||||
#if JUCE_MAC
|
||||
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;
|
||||
|
||||
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 ((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 == numberPadDelete) desc << KeyPressHelpers::numberPadPrefix() << "delete";
|
||||
else desc << '#' << String::toHexString (keyCode);
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
String KeyPress::getTextDescriptionWithIcons() const
|
||||
{
|
||||
#if JUCE_MAC
|
||||
String 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
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_KEYPRESS_H_INCLUDED
|
||||
#define JUCE_KEYPRESS_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a key press, including any modifier keys that are needed.
|
||||
|
||||
E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc.
|
||||
|
||||
@see Component, KeyListener, KeyPressMappingSet, Button::addShortcut
|
||||
*/
|
||||
class JUCE_API KeyPress
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an (invalid) KeyPress.
|
||||
|
||||
@see isValid
|
||||
*/
|
||||
KeyPress() noexcept;
|
||||
|
||||
/** Creates a KeyPress for a key and some modifiers.
|
||||
|
||||
e.g.
|
||||
CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier)
|
||||
SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier)
|
||||
|
||||
@param keyCode a code that represents the key - this value must be
|
||||
one of special constants listed in this class, or an
|
||||
8-bit character code such as a letter (case is ignored),
|
||||
digit or a simple key like "," or ".". Note that this
|
||||
isn't the same as the textCharacter parameter, so for example
|
||||
a keyCode of 'a' and a shift-key modifier should have a
|
||||
textCharacter value of 'A'.
|
||||
@param modifiers the modifiers to associate with the keystroke
|
||||
@param textCharacter the character that would be printed if someone typed
|
||||
this keypress into a text editor. This value may be
|
||||
null if the keypress is a non-printing character
|
||||
@see getKeyCode, isKeyCode, getModifiers
|
||||
*/
|
||||
KeyPress (int keyCode,
|
||||
ModifierKeys modifiers,
|
||||
juce_wchar textCharacter) noexcept;
|
||||
|
||||
/** Creates a keypress with a keyCode but no modifiers or text character. */
|
||||
explicit KeyPress (int keyCode) noexcept;
|
||||
|
||||
/** Creates a copy of another KeyPress. */
|
||||
KeyPress (const KeyPress& other) noexcept;
|
||||
|
||||
/** Copies this KeyPress from another one. */
|
||||
KeyPress& operator= (const KeyPress& other) noexcept;
|
||||
|
||||
/** Compares two KeyPress objects. */
|
||||
bool operator== (const KeyPress& other) const noexcept;
|
||||
|
||||
/** Compares two KeyPress objects. */
|
||||
bool operator!= (const KeyPress& other) const noexcept;
|
||||
|
||||
/** Returns true if this keypress is for the given keycode without any modifiers. */
|
||||
bool operator== (int keyCode) const noexcept;
|
||||
|
||||
/** Returns true if this keypress is not for the given keycode without any modifiers. */
|
||||
bool operator!= (int keyCode) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if this is a valid KeyPress.
|
||||
|
||||
A null keypress can be created by the default constructor, in case it's
|
||||
needed.
|
||||
*/
|
||||
bool isValid() const noexcept { return keyCode != 0; }
|
||||
|
||||
/** Returns the key code itself.
|
||||
|
||||
This will either be one of the special constants defined in this class,
|
||||
or an 8-bit character code.
|
||||
*/
|
||||
int getKeyCode() const noexcept { return keyCode; }
|
||||
|
||||
/** Returns the key modifiers.
|
||||
|
||||
@see ModifierKeys
|
||||
*/
|
||||
ModifierKeys getModifiers() const noexcept { return mods; }
|
||||
|
||||
/** Returns the character that is associated with this keypress.
|
||||
|
||||
This is the character that you'd expect to see printed if you press this
|
||||
keypress in a text editor or similar component.
|
||||
*/
|
||||
juce_wchar getTextCharacter() const noexcept { return textCharacter; }
|
||||
|
||||
/** Checks whether the KeyPress's key is the same as the one provided, without checking
|
||||
the modifiers.
|
||||
|
||||
The values for key codes can either be one of the special constants defined in
|
||||
this class, or an 8-bit character code.
|
||||
|
||||
@see getKeyCode
|
||||
*/
|
||||
bool isKeyCode (int keyCodeToCompare) const noexcept { return keyCode == keyCodeToCompare; }
|
||||
|
||||
//==============================================================================
|
||||
/** Converts a textual key description to a KeyPress.
|
||||
|
||||
This attempts to decode a textual version of a keypress, e.g. "CTRL + C" or "SPACE".
|
||||
|
||||
This isn't designed to cope with any kind of input, but should be given the
|
||||
strings that are created by the getTextDescription() method.
|
||||
|
||||
If the string can't be parsed, the object returned will be invalid.
|
||||
|
||||
@see getTextDescription
|
||||
*/
|
||||
static KeyPress createFromDescription (const String& textVersion);
|
||||
|
||||
/** Creates a textual description of the key combination.
|
||||
|
||||
e.g. "CTRL + C" or "DELETE".
|
||||
|
||||
To store a keypress in a file, use this method, along with createFromDescription()
|
||||
to retrieve it later.
|
||||
*/
|
||||
String getTextDescription() const;
|
||||
|
||||
/** Creates a textual description of the key combination, using unicode icon symbols if possible.
|
||||
|
||||
On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual
|
||||
modifier key descriptions that are returned by getTextDescription()
|
||||
*/
|
||||
String getTextDescriptionWithIcons() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Checks whether the user is currently holding down the keys that make up this
|
||||
KeyPress.
|
||||
|
||||
Note that this will return false if any extra modifier keys are
|
||||
down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x
|
||||
then it will be false.
|
||||
*/
|
||||
bool isCurrentlyDown() const;
|
||||
|
||||
/** Checks whether a particular key is held down, irrespective of modifiers.
|
||||
|
||||
The values for key codes can either be one of the special constants defined in
|
||||
this class, or an 8-bit character code.
|
||||
*/
|
||||
static bool isKeyCurrentlyDown (int keyCode);
|
||||
|
||||
//==============================================================================
|
||||
// Key codes
|
||||
//
|
||||
// Note that the actual values of these are platform-specific and may change
|
||||
// without warning, so don't store them anywhere as constants. For persisting/retrieving
|
||||
// KeyPress objects, use getTextDescription() and createFromDescription() instead.
|
||||
//
|
||||
|
||||
static const int spaceKey; /**< key-code for the space bar */
|
||||
static const int escapeKey; /**< key-code for the escape key */
|
||||
static const int returnKey; /**< key-code for the return key*/
|
||||
static const int tabKey; /**< key-code for the tab key*/
|
||||
|
||||
static const int deleteKey; /**< key-code for the delete key (not backspace) */
|
||||
static const int backspaceKey; /**< key-code for the backspace key */
|
||||
static const int insertKey; /**< key-code for the insert key */
|
||||
|
||||
static const int upKey; /**< key-code for the cursor-up key */
|
||||
static const int downKey; /**< key-code for the cursor-down key */
|
||||
static const int leftKey; /**< key-code for the cursor-left key */
|
||||
static const int rightKey; /**< key-code for the cursor-right key */
|
||||
static const int pageUpKey; /**< key-code for the page-up key */
|
||||
static const int pageDownKey; /**< key-code for the page-down key */
|
||||
static const int homeKey; /**< key-code for the home key */
|
||||
static const int endKey; /**< key-code for the end key */
|
||||
|
||||
static const int F1Key; /**< key-code for the F1 key */
|
||||
static const int F2Key; /**< key-code for the F2 key */
|
||||
static const int F3Key; /**< key-code for the F3 key */
|
||||
static const int F4Key; /**< key-code for the F4 key */
|
||||
static const int F5Key; /**< key-code for the F5 key */
|
||||
static const int F6Key; /**< key-code for the F6 key */
|
||||
static const int F7Key; /**< key-code for the F7 key */
|
||||
static const int F8Key; /**< key-code for the F8 key */
|
||||
static const int F9Key; /**< key-code for the F9 key */
|
||||
static const int F10Key; /**< key-code for the F10 key */
|
||||
static const int F11Key; /**< key-code for the F11 key */
|
||||
static const int F12Key; /**< key-code for the F12 key */
|
||||
static const int F13Key; /**< key-code for the F13 key */
|
||||
static const int F14Key; /**< key-code for the F14 key */
|
||||
static const int F15Key; /**< key-code for the F15 key */
|
||||
static const int F16Key; /**< key-code for the F16 key */
|
||||
|
||||
static const int numberPad0; /**< key-code for the 0 on the numeric keypad. */
|
||||
static const int numberPad1; /**< key-code for the 1 on the numeric keypad. */
|
||||
static const int numberPad2; /**< key-code for the 2 on the numeric keypad. */
|
||||
static const int numberPad3; /**< key-code for the 3 on the numeric keypad. */
|
||||
static const int numberPad4; /**< key-code for the 4 on the numeric keypad. */
|
||||
static const int numberPad5; /**< key-code for the 5 on the numeric keypad. */
|
||||
static const int numberPad6; /**< key-code for the 6 on the numeric keypad. */
|
||||
static const int numberPad7; /**< key-code for the 7 on the numeric keypad. */
|
||||
static const int numberPad8; /**< key-code for the 8 on the numeric keypad. */
|
||||
static const int numberPad9; /**< key-code for the 9 on the numeric keypad. */
|
||||
|
||||
static const int numberPadAdd; /**< key-code for the add sign on the numeric keypad. */
|
||||
static const int numberPadSubtract; /**< key-code for the subtract sign on the numeric keypad. */
|
||||
static const int numberPadMultiply; /**< key-code for the multiply sign on the numeric keypad. */
|
||||
static const int numberPadDivide; /**< key-code for the divide sign on the numeric keypad. */
|
||||
static const int numberPadSeparator; /**< key-code for the comma on the numeric keypad. */
|
||||
static const int numberPadDecimalPoint; /**< key-code for the decimal point sign on the numeric keypad. */
|
||||
static const int numberPadEquals; /**< key-code for the equals key on the numeric keypad. */
|
||||
static const int numberPadDelete; /**< key-code for the delete key on the numeric keypad. */
|
||||
|
||||
static const int playKey; /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */
|
||||
static const int stopKey; /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */
|
||||
static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */
|
||||
static const int rewindKey; /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int keyCode;
|
||||
ModifierKeys mods;
|
||||
juce_wchar textCharacter;
|
||||
|
||||
JUCE_LEAK_DETECTOR (KeyPress)
|
||||
};
|
||||
|
||||
|
||||
#endif // JUCE_KEYPRESS_H_INCLUDED
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace KeyboardFocusHelpers
|
||||
{
|
||||
// This will sort a set of components, so that they are ordered in terms of
|
||||
// left-to-right and then top-to-bottom.
|
||||
struct ScreenPositionComparator
|
||||
{
|
||||
static int compareElements (const Component* const first, const Component* const second)
|
||||
{
|
||||
const int explicitOrder1 = getOrder (first);
|
||||
const int explicitOrder2 = getOrder (second);
|
||||
|
||||
if (explicitOrder1 != explicitOrder2)
|
||||
return explicitOrder1 - explicitOrder2;
|
||||
|
||||
const int yDiff = first->getY() - second->getY();
|
||||
|
||||
return yDiff == 0 ? first->getX() - second->getX()
|
||||
: yDiff;
|
||||
}
|
||||
|
||||
static int getOrder (const Component* const c)
|
||||
{
|
||||
const int order = c->getExplicitFocusOrder();
|
||||
return order > 0 ? order : (std::numeric_limits<int>::max() / 2);
|
||||
}
|
||||
};
|
||||
|
||||
static void findAllFocusableComponents (Component* const parent, Array <Component*>& comps)
|
||||
{
|
||||
if (parent->getNumChildComponents() > 0)
|
||||
{
|
||||
Array <Component*> localComps;
|
||||
ScreenPositionComparator comparator;
|
||||
|
||||
for (int i = parent->getNumChildComponents(); --i >= 0;)
|
||||
{
|
||||
Component* const c = parent->getChildComponent (i);
|
||||
|
||||
if (c->isVisible() && c->isEnabled())
|
||||
localComps.addSorted (comparator, c);
|
||||
}
|
||||
|
||||
for (int i = 0; i < localComps.size(); ++i)
|
||||
{
|
||||
Component* const c = localComps.getUnchecked (i);
|
||||
|
||||
if (c->getWantsKeyboardFocus())
|
||||
comps.add (c);
|
||||
|
||||
if (! c->isFocusContainer())
|
||||
findAllFocusableComponents (c, comps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Component* findFocusContainer (Component* c)
|
||||
{
|
||||
c = c->getParentComponent();
|
||||
|
||||
if (c != nullptr)
|
||||
while (c->getParentComponent() != nullptr && ! c->isFocusContainer())
|
||||
c = c->getParentComponent();
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static Component* getIncrementedComponent (Component* const current, const int delta)
|
||||
{
|
||||
Component* focusContainer = findFocusContainer (current);
|
||||
|
||||
if (focusContainer != nullptr)
|
||||
{
|
||||
Array <Component*> comps;
|
||||
KeyboardFocusHelpers::findAllFocusableComponents (focusContainer, comps);
|
||||
|
||||
if (comps.size() > 0)
|
||||
{
|
||||
const int index = comps.indexOf (current);
|
||||
return comps [(index + comps.size() + delta) % comps.size()];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
KeyboardFocusTraverser::KeyboardFocusTraverser() {}
|
||||
KeyboardFocusTraverser::~KeyboardFocusTraverser() {}
|
||||
|
||||
Component* KeyboardFocusTraverser::getNextComponent (Component* current)
|
||||
{
|
||||
jassert (current != nullptr);
|
||||
return KeyboardFocusHelpers::getIncrementedComponent (current, 1);
|
||||
}
|
||||
|
||||
Component* KeyboardFocusTraverser::getPreviousComponent (Component* current)
|
||||
{
|
||||
jassert (current != nullptr);
|
||||
return KeyboardFocusHelpers::getIncrementedComponent (current, -1);
|
||||
}
|
||||
|
||||
Component* KeyboardFocusTraverser::getDefaultComponent (Component* parentComponent)
|
||||
{
|
||||
Array <Component*> comps;
|
||||
|
||||
if (parentComponent != nullptr)
|
||||
KeyboardFocusHelpers::findAllFocusableComponents (parentComponent, comps);
|
||||
|
||||
return comps.getFirst();
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_KEYBOARDFOCUSTRAVERSER_H_INCLUDED
|
||||
#define JUCE_KEYBOARDFOCUSTRAVERSER_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Controls the order in which focus moves between components.
|
||||
|
||||
The default algorithm used by this class to work out the order of traversal
|
||||
is as follows:
|
||||
- if two components both have an explicit focus order specified, then the
|
||||
one with the lowest number comes first (see the Component::setExplicitFocusOrder()
|
||||
method).
|
||||
- any component with an explicit focus order greater than 0 comes before ones
|
||||
that don't have an order specified.
|
||||
- any unspecified components are traversed in a left-to-right, then top-to-bottom
|
||||
order.
|
||||
|
||||
If you need traversal in a more customised way, you can create a subclass
|
||||
of KeyboardFocusTraverser that uses your own algorithm, and use
|
||||
Component::createFocusTraverser() to create it.
|
||||
|
||||
@see Component::setExplicitFocusOrder, Component::createFocusTraverser
|
||||
*/
|
||||
class JUCE_API KeyboardFocusTraverser
|
||||
{
|
||||
public:
|
||||
KeyboardFocusTraverser();
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~KeyboardFocusTraverser();
|
||||
|
||||
/** Returns the component that should be given focus after the specified one
|
||||
when moving "forwards".
|
||||
|
||||
The default implementation will return the next component which is to the
|
||||
right of or below this one.
|
||||
|
||||
This may return nullptr if there's no suitable candidate.
|
||||
*/
|
||||
virtual Component* getNextComponent (Component* current);
|
||||
|
||||
/** Returns the component that should be given focus after the specified one
|
||||
when moving "backwards".
|
||||
|
||||
The default implementation will return the next component which is to the
|
||||
left of or above this one.
|
||||
|
||||
This may return nullptr if there's no suitable candidate.
|
||||
*/
|
||||
virtual Component* getPreviousComponent (Component* current);
|
||||
|
||||
/** Returns the component that should receive focus be default within the given
|
||||
parent component.
|
||||
|
||||
The default implementation will just return the foremost child component that
|
||||
wants focus.
|
||||
|
||||
This may return nullptr if there's no suitable candidate.
|
||||
*/
|
||||
virtual Component* getDefaultComponent (Component* parentComponent);
|
||||
};
|
||||
|
||||
|
||||
#endif // JUCE_KEYBOARDFOCUSTRAVERSER_H_INCLUDED
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
ModifierKeys::ModifierKeys() noexcept : flags (0) {}
|
||||
ModifierKeys::ModifierKeys (int rawFlags) noexcept : flags (rawFlags) {}
|
||||
ModifierKeys::ModifierKeys (const ModifierKeys& other) noexcept : flags (other.flags) {}
|
||||
|
||||
ModifierKeys& ModifierKeys::operator= (const ModifierKeys other) noexcept
|
||||
{
|
||||
flags = other.flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ModifierKeys ModifierKeys::currentModifiers;
|
||||
|
||||
ModifierKeys ModifierKeys::getCurrentModifiers() noexcept
|
||||
{
|
||||
return currentModifiers;
|
||||
}
|
||||
|
||||
int ModifierKeys::getNumMouseButtonsDown() const noexcept
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
if (isLeftButtonDown()) ++num;
|
||||
if (isRightButtonDown()) ++num;
|
||||
if (isMiddleButtonDown()) ++num;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_MODIFIERKEYS_H_INCLUDED
|
||||
#define JUCE_MODIFIERKEYS_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents the state of the mouse buttons and modifier keys.
|
||||
|
||||
This is used both by mouse events and by KeyPress objects to describe
|
||||
the state of keys such as shift, control, alt, etc.
|
||||
|
||||
@see KeyPress, MouseEvent::mods
|
||||
*/
|
||||
class JUCE_API ModifierKeys
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a ModifierKeys object with no flags set. */
|
||||
ModifierKeys() noexcept;
|
||||
|
||||
/** Creates a ModifierKeys object from a raw set of flags.
|
||||
|
||||
@param flags to represent the keys that are down
|
||||
@see shiftModifier, ctrlModifier, altModifier, leftButtonModifier,
|
||||
rightButtonModifier, commandModifier, popupMenuClickModifier
|
||||
*/
|
||||
ModifierKeys (int flags) noexcept;
|
||||
|
||||
/** Creates a copy of another object. */
|
||||
ModifierKeys (const ModifierKeys& other) noexcept;
|
||||
|
||||
/** Copies this object from another one. */
|
||||
ModifierKeys& operator= (const ModifierKeys other) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Checks whether the 'command' key flag is set (or 'ctrl' on Windows/Linux).
|
||||
|
||||
This is a platform-agnostic way of checking for the operating system's
|
||||
preferred command-key modifier - so on the Mac it tests for the Apple key, on
|
||||
Windows/Linux, it's actually checking for the CTRL key.
|
||||
*/
|
||||
inline bool isCommandDown() const noexcept { return testFlags (commandModifier); }
|
||||
|
||||
/** Checks whether the user is trying to launch a pop-up menu.
|
||||
|
||||
This checks for platform-specific modifiers that might indicate that the user
|
||||
is following the operating system's normal method of showing a pop-up menu.
|
||||
|
||||
So on Windows/Linux, this method is really testing for a right-click.
|
||||
On the Mac, it tests for either the CTRL key being down, or a right-click.
|
||||
*/
|
||||
inline bool isPopupMenu() const noexcept { return testFlags (popupMenuClickModifier); }
|
||||
|
||||
/** Checks whether the flag is set for the left mouse-button. */
|
||||
inline bool isLeftButtonDown() const noexcept { return testFlags (leftButtonModifier); }
|
||||
|
||||
/** Checks whether the flag is set for the right mouse-button.
|
||||
|
||||
Note that for detecting popup-menu clicks, you should be using isPopupMenu() instead, as
|
||||
this is platform-independent (and makes your code more explanatory too).
|
||||
*/
|
||||
inline bool isRightButtonDown() const noexcept { return testFlags (rightButtonModifier); }
|
||||
|
||||
inline bool isMiddleButtonDown() const noexcept { return testFlags (middleButtonModifier); }
|
||||
|
||||
/** Tests for any of the mouse-button flags. */
|
||||
inline bool isAnyMouseButtonDown() const noexcept { return testFlags (allMouseButtonModifiers); }
|
||||
|
||||
/** Tests for any of the modifier key flags. */
|
||||
inline bool isAnyModifierKeyDown() const noexcept { return testFlags ((shiftModifier | ctrlModifier | altModifier | commandModifier)); }
|
||||
|
||||
/** Checks whether the shift key's flag is set. */
|
||||
inline bool isShiftDown() const noexcept { return testFlags (shiftModifier); }
|
||||
|
||||
/** Checks whether the CTRL key's flag is set.
|
||||
|
||||
Remember that it's better to use the platform-agnostic routines to test for command-key and
|
||||
popup-menu modifiers.
|
||||
|
||||
@see isCommandDown, isPopupMenu
|
||||
*/
|
||||
inline bool isCtrlDown() const noexcept { return testFlags (ctrlModifier); }
|
||||
|
||||
/** Checks whether the ALT key's flag is set. */
|
||||
inline bool isAltDown() const noexcept { return testFlags (altModifier); }
|
||||
|
||||
//==============================================================================
|
||||
/** Flags that represent the different keys. */
|
||||
enum Flags
|
||||
{
|
||||
/** Indicates no modifier keys. */
|
||||
noModifiers = 0,
|
||||
|
||||
/** Shift key flag. */
|
||||
shiftModifier = 1,
|
||||
|
||||
/** CTRL key flag. */
|
||||
ctrlModifier = 2,
|
||||
|
||||
/** ALT key flag. */
|
||||
altModifier = 4,
|
||||
|
||||
/** Left mouse button flag. */
|
||||
leftButtonModifier = 16,
|
||||
|
||||
/** Right mouse button flag. */
|
||||
rightButtonModifier = 32,
|
||||
|
||||
/** Middle mouse button flag. */
|
||||
middleButtonModifier = 64,
|
||||
|
||||
#if JUCE_MAC
|
||||
/** Command key flag - on windows this is the same as the CTRL key flag. */
|
||||
commandModifier = 8,
|
||||
|
||||
/** Popup menu flag - on windows this is the same as rightButtonModifier, on the
|
||||
Mac it's the same as (rightButtonModifier | ctrlModifier). */
|
||||
popupMenuClickModifier = rightButtonModifier | ctrlModifier,
|
||||
#else
|
||||
/** Command key flag - on windows this is the same as the CTRL key flag. */
|
||||
commandModifier = ctrlModifier,
|
||||
|
||||
/** Popup menu flag - on windows this is the same as rightButtonModifier, on the
|
||||
Mac it's the same as (rightButtonModifier | ctrlModifier). */
|
||||
popupMenuClickModifier = rightButtonModifier,
|
||||
#endif
|
||||
|
||||
/** Represents a combination of all the shift, alt, ctrl and command key modifiers. */
|
||||
allKeyboardModifiers = shiftModifier | ctrlModifier | altModifier | commandModifier,
|
||||
|
||||
/** Represents a combination of all the mouse buttons at once. */
|
||||
allMouseButtonModifiers = leftButtonModifier | rightButtonModifier | middleButtonModifier,
|
||||
|
||||
/** Represents a combination of all the alt, ctrl and command key modifiers. */
|
||||
ctrlAltCommandModifiers = ctrlModifier | altModifier | commandModifier
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a copy of only the mouse-button flags */
|
||||
ModifierKeys withOnlyMouseButtons() const noexcept { return ModifierKeys (flags & allMouseButtonModifiers); }
|
||||
|
||||
/** Returns a copy of only the non-mouse flags */
|
||||
ModifierKeys withoutMouseButtons() const noexcept { return ModifierKeys (flags & ~allMouseButtonModifiers); }
|
||||
|
||||
bool operator== (const ModifierKeys other) const noexcept { return flags == other.flags; }
|
||||
bool operator!= (const ModifierKeys other) const noexcept { return flags != other.flags; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the raw flags for direct testing. */
|
||||
inline int getRawFlags() const noexcept { return flags; }
|
||||
|
||||
ModifierKeys withoutFlags (int rawFlagsToClear) const noexcept { return ModifierKeys (flags & ~rawFlagsToClear); }
|
||||
ModifierKeys withFlags (int rawFlagsToSet) const noexcept { return ModifierKeys (flags | rawFlagsToSet); }
|
||||
|
||||
/** Tests a combination of flags and returns true if any of them are set. */
|
||||
bool testFlags (int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; }
|
||||
|
||||
/** Returns the total number of mouse buttons that are down. */
|
||||
int getNumMouseButtonsDown() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a ModifierKeys object to represent the last-known state of the
|
||||
keyboard and mouse buttons.
|
||||
|
||||
@see getCurrentModifiersRealtime
|
||||
*/
|
||||
static ModifierKeys getCurrentModifiers() noexcept;
|
||||
|
||||
/** Creates a ModifierKeys object to represent the current state of the
|
||||
keyboard and mouse buttons.
|
||||
|
||||
This isn't often needed and isn't recommended, but will actively check all the
|
||||
mouse and key states rather than just returning their last-known state like
|
||||
getCurrentModifiers() does.
|
||||
|
||||
This is only needed in special circumstances for up-to-date modifier information
|
||||
at times when the app's event loop isn't running normally.
|
||||
|
||||
Another reason to avoid this method is that it's not stateless, and calling it may
|
||||
update the value returned by getCurrentModifiers(), which could cause subtle changes
|
||||
in the behaviour of some components.
|
||||
*/
|
||||
static ModifierKeys getCurrentModifiersRealtime() noexcept;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int flags;
|
||||
|
||||
friend class ComponentPeer;
|
||||
friend class MouseInputSource;
|
||||
friend class MouseInputSourceInternal;
|
||||
|
||||
static ModifierKeys currentModifiers;
|
||||
static void updateCurrentModifiers() noexcept;
|
||||
};
|
||||
|
||||
|
||||
#endif // JUCE_MODIFIERKEYS_H_INCLUDED
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_SYSTEMCLIPBOARD_H_INCLUDED
|
||||
#define JUCE_SYSTEMCLIPBOARD_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Handles reading/writing to the system's clipboard.
|
||||
*/
|
||||
class JUCE_API SystemClipboard
|
||||
{
|
||||
public:
|
||||
/** Copies a string of text onto the clipboard */
|
||||
static void copyTextToClipboard (const String& text);
|
||||
|
||||
/** Gets the current clipboard's contents.
|
||||
|
||||
Obviously this might have come from another app, so could contain
|
||||
anything..
|
||||
*/
|
||||
static String getTextFromClipboard();
|
||||
};
|
||||
|
||||
#endif // JUCE_SYSTEMCLIPBOARD_H_INCLUDED
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_TEXTEDITORKEYMAPPER_H_INCLUDED
|
||||
#define JUCE_TEXTEDITORKEYMAPPER_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** This class is used to invoke a range of text-editor navigation methods on
|
||||
an object, based upon a keypress event.
|
||||
|
||||
It's currently used internally by the TextEditor and CodeEditorComponent.
|
||||
*/
|
||||
template <class CallbackClass>
|
||||
struct TextEditorKeyMapper
|
||||
{
|
||||
/** Checks the keypress and invokes one of a range of navigation functions that
|
||||
the target class must implement, based on the key event.
|
||||
*/
|
||||
static bool invokeKeyFunction (CallbackClass& target, const KeyPress& key)
|
||||
{
|
||||
const ModifierKeys& mods = key.getModifiers();
|
||||
|
||||
const bool isShiftDown = mods.isShiftDown();
|
||||
const bool ctrlOrAltDown = mods.isCtrlDown() || mods.isAltDown();
|
||||
|
||||
int numCtrlAltCommandKeys = 0;
|
||||
if (mods.isCtrlDown()) ++numCtrlAltCommandKeys;
|
||||
if (mods.isAltDown()) ++numCtrlAltCommandKeys;
|
||||
|
||||
if (key == KeyPress (KeyPress::downKey, ModifierKeys::ctrlModifier, 0) && target.scrollUp()) return true;
|
||||
if (key == KeyPress (KeyPress::upKey, ModifierKeys::ctrlModifier, 0) && target.scrollDown()) return true;
|
||||
|
||||
#if JUCE_MAC
|
||||
if (mods.isCommandDown() && ! ctrlOrAltDown)
|
||||
{
|
||||
if (key.isKeyCode (KeyPress::upKey)) return target.moveCaretToTop (isShiftDown);
|
||||
if (key.isKeyCode (KeyPress::downKey)) return target.moveCaretToEnd (isShiftDown);
|
||||
if (key.isKeyCode (KeyPress::leftKey)) return target.moveCaretToStartOfLine (isShiftDown);
|
||||
if (key.isKeyCode (KeyPress::rightKey)) return target.moveCaretToEndOfLine (isShiftDown);
|
||||
}
|
||||
|
||||
if (mods.isCommandDown())
|
||||
++numCtrlAltCommandKeys;
|
||||
#endif
|
||||
|
||||
if (numCtrlAltCommandKeys < 2)
|
||||
{
|
||||
if (key.isKeyCode (KeyPress::leftKey)) return target.moveCaretLeft (ctrlOrAltDown, isShiftDown);
|
||||
if (key.isKeyCode (KeyPress::rightKey)) return target.moveCaretRight (ctrlOrAltDown, isShiftDown);
|
||||
|
||||
if (key.isKeyCode (KeyPress::homeKey)) return ctrlOrAltDown ? target.moveCaretToTop (isShiftDown)
|
||||
: target.moveCaretToStartOfLine (isShiftDown);
|
||||
if (key.isKeyCode (KeyPress::endKey)) return ctrlOrAltDown ? target.moveCaretToEnd (isShiftDown)
|
||||
: target.moveCaretToEndOfLine (isShiftDown);
|
||||
}
|
||||
|
||||
if (numCtrlAltCommandKeys == 0)
|
||||
{
|
||||
if (key.isKeyCode (KeyPress::upKey)) return target.moveCaretUp (isShiftDown);
|
||||
if (key.isKeyCode (KeyPress::downKey)) return target.moveCaretDown (isShiftDown);
|
||||
|
||||
if (key.isKeyCode (KeyPress::pageUpKey)) return target.pageUp (isShiftDown);
|
||||
if (key.isKeyCode (KeyPress::pageDownKey)) return target.pageDown (isShiftDown);
|
||||
}
|
||||
|
||||
if (numCtrlAltCommandKeys < 2)
|
||||
{
|
||||
if (key.isKeyCode (KeyPress::backspaceKey)) return target.deleteBackwards (ctrlOrAltDown);
|
||||
if (key.isKeyCode (KeyPress::deleteKey)) return target.deleteForwards (ctrlOrAltDown);
|
||||
}
|
||||
|
||||
if (key == KeyPress ('c', ModifierKeys::commandModifier, 0)
|
||||
|| key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0))
|
||||
return target.copyToClipboard();
|
||||
|
||||
if (key == KeyPress ('x', ModifierKeys::commandModifier, 0)
|
||||
|| key == KeyPress (KeyPress::deleteKey, ModifierKeys::shiftModifier, 0))
|
||||
return target.cutToClipboard();
|
||||
|
||||
if (key == KeyPress ('v', ModifierKeys::commandModifier, 0)
|
||||
|| key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0))
|
||||
return target.pasteFromClipboard();
|
||||
|
||||
if (key == KeyPress ('a', ModifierKeys::commandModifier, 0))
|
||||
return target.selectAll();
|
||||
|
||||
if (key == KeyPress ('z', ModifierKeys::commandModifier, 0))
|
||||
return target.undo();
|
||||
|
||||
if (key == KeyPress ('y', ModifierKeys::commandModifier, 0)
|
||||
|| key == KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0))
|
||||
return target.redo();
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // JUCE_TEXTEDITORKEYMAPPER_H_INCLUDED
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found 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.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_TEXTINPUTTARGET_H_INCLUDED
|
||||
#define JUCE_TEXTINPUTTARGET_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An abstract base class which can be implemented by components that function as
|
||||
text editors.
|
||||
|
||||
This class allows different types of text editor component to provide a uniform
|
||||
interface, which can be used by things like OS-specific input methods, on-screen
|
||||
keyboards, etc.
|
||||
*/
|
||||
class JUCE_API TextInputTarget
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** */
|
||||
TextInputTarget() {}
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~TextInputTarget() {}
|
||||
|
||||
/** Returns true if this input target is currently accepting input.
|
||||
For example, a text editor might return false if it's in read-only mode.
|
||||
*/
|
||||
virtual bool isTextInputActive() const = 0;
|
||||
|
||||
/** Returns the extents of the selected text region, or an empty range if
|
||||
nothing is selected,
|
||||
*/
|
||||
virtual Range<int> getHighlightedRegion() const = 0;
|
||||
|
||||
/** Sets the currently-selected text region. */
|
||||
virtual void setHighlightedRegion (const Range<int>& newRange) = 0;
|
||||
|
||||
/** Sets a number of temporarily underlined sections.
|
||||
This is needed by MS Windows input method UI.
|
||||
*/
|
||||
virtual void setTemporaryUnderlining (const Array <Range<int> >& underlinedRegions) = 0;
|
||||
|
||||
/** Returns a specified sub-section of the text. */
|
||||
virtual String getTextInRange (const Range<int>& range) const = 0;
|
||||
|
||||
/** Inserts some text, overwriting the selected text region, if there is one. */
|
||||
virtual void insertTextAtCaret (const String& textToInsert) = 0;
|
||||
|
||||
/** Returns the position of the caret, relative to the component's origin. */
|
||||
virtual Rectangle<int> getCaretRectangle() = 0;
|
||||
|
||||
/** A set of possible on-screen keyboard types, for use in the
|
||||
getKeyboardType() method.
|
||||
*/
|
||||
enum VirtualKeyboardType
|
||||
{
|
||||
textKeyboard = 0,
|
||||
numericKeyboard,
|
||||
urlKeyboard,
|
||||
emailAddressKeyboard,
|
||||
phoneNumberKeyboard
|
||||
};
|
||||
|
||||
/** Returns the target's preference for the type of keyboard that would be most appropriate.
|
||||
This may be ignored, depending on the capabilities of the OS.
|
||||
*/
|
||||
virtual VirtualKeyboardType getKeyboardType() { return textKeyboard; }
|
||||
};
|
||||
|
||||
|
||||
#endif // JUCE_TEXTINPUTTARGET_H_INCLUDED
|
||||
Loading…
Add table
Add a link
Reference in a new issue