/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
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_KEYPRESSMAPPINGSET_H_INCLUDED
# define JUCE_KEYPRESSMAPPINGSET_H_INCLUDED
//==============================================================================
/**
Manages and edits a list of keypresses , which it uses to invoke the appropriate
command in an ApplicationCommandManager .
Normally , you won ' t actually create a KeyPressMappingSet directly , because
each ApplicationCommandManager contains its own KeyPressMappingSet , so typically
you ' d create yourself an ApplicationCommandManager , and call its
ApplicationCommandManager : : getKeyMappings ( ) method to get a pointer to its
KeyPressMappingSet .
For one of these to actually use keypresses , you ' ll need to add it as a KeyListener
to the top - level component for which you want to handle keystrokes . So for example :
@ code
class MyMainWindow : public Component
{
ApplicationCommandManager * myCommandManager ;
public :
MyMainWindow ( )
{
myCommandManager = new ApplicationCommandManager ( ) ;
// first, make sure the command manager has registered all the commands that its
// targets can perform..
myCommandManager - > registerAllCommandsForTarget ( myCommandTarget1 ) ;
myCommandManager - > registerAllCommandsForTarget ( myCommandTarget2 ) ;
// this will use the command manager to initialise the KeyPressMappingSet with
// the default keypresses that were specified when the targets added their commands
// to the manager.
myCommandManager - > getKeyMappings ( ) - > resetToDefaultMappings ( ) ;
// having set up the default key-mappings, you might now want to load the last set
// of mappings that the user configured.
myCommandManager - > getKeyMappings ( ) - > restoreFromXml ( lastSavedKeyMappingsXML ) ;
// Now tell our top-level window to send any keypresses that arrive to the
// KeyPressMappingSet, which will use them to invoke the appropriate commands.
addKeyListener ( myCommandManager - > getKeyMappings ( ) ) ;
}
. . .
}
@ endcode
KeyPressMappingSet derives from ChangeBroadcaster so that interested parties can
register to be told when a command or mapping is added , removed , etc .
There ' s also a UI component called KeyMappingEditorComponent that can be used
to easily edit the key mappings .
@ see Component : : addKeyListener ( ) , KeyMappingEditorComponent , ApplicationCommandManager
*/
class JUCE_API KeyPressMappingSet : public KeyListener ,
public ChangeBroadcaster ,
private FocusChangeListener
{
public :
//==============================================================================
/** Creates a KeyPressMappingSet for a given command manager.
Normally , you won ' t actually create a KeyPressMappingSet directly , because
each ApplicationCommandManager contains its own KeyPressMappingSet , so the
best thing to do is to create your ApplicationCommandManager , and use the
ApplicationCommandManager : : getKeyMappings ( ) method to access its mappings .
When a suitable keypress happens , the manager ' s invoke ( ) method will be
used to invoke the appropriate command .
@ see ApplicationCommandManager
*/
explicit KeyPressMappingSet ( ApplicationCommandManager & ) ;
/** Creates an copy of a KeyPressMappingSet. */
KeyPressMappingSet ( const KeyPressMappingSet & ) ;
/** Destructor. */
~ KeyPressMappingSet ( ) ;
//==============================================================================
ApplicationCommandManager & getCommandManager ( ) const noexcept { return commandManager ; }
//==============================================================================
/** Returns a list of keypresses that are assigned to a particular command.
@ param commandID the command ' s ID
*/
Array < KeyPress > getKeyPressesAssignedToCommand ( CommandID commandID ) const ;
/** Assigns a keypress to a command.
If the keypress is already assigned to a different command , it will first be
removed from that command , to avoid it triggering multiple functions .
@ param commandID the ID of the command that you want to add a keypress to . If
this is 0 , the keypress will be removed from anything that it
was previously assigned to , but not re - assigned
@ param newKeyPress the new key - press
@ param insertIndex if this is less than zero , the key will be appended to the
end of the list of keypresses ; otherwise the new keypress will
be inserted into the existing list at this index
*/
void addKeyPress ( CommandID commandID ,
const KeyPress & newKeyPress ,
int insertIndex = - 1 ) ;
/** Reset all mappings to the defaults, as dictated by the ApplicationCommandManager.
@ see resetToDefaultMapping
*/
void resetToDefaultMappings ( ) ;
/** Resets all key-mappings to the defaults for a particular command.
@ see resetToDefaultMappings
*/
void resetToDefaultMapping ( CommandID commandID ) ;
/** Removes all keypresses that are assigned to any commands. */
void clearAllKeyPresses ( ) ;
/** Removes all keypresses that are assigned to a particular command. */
void clearAllKeyPresses ( CommandID commandID ) ;
/** Removes one of the keypresses that are assigned to a command.
See the getKeyPressesAssignedToCommand ( ) for the list of keypresses to
which the keyPressIndex refers .
*/
void removeKeyPress ( CommandID commandID , int keyPressIndex ) ;
/** Removes a keypress from any command that it may be assigned to. */
void removeKeyPress ( const KeyPress & keypress ) ;
/** Returns true if the given command is linked to this key. */
bool containsMapping ( CommandID commandID , const KeyPress & keyPress ) const noexcept ;
//==============================================================================
/** Looks for a command that corresponds to a keypress.
@ returns the UID of the command or 0 if none was found
*/
CommandID findCommandForKeyPress ( const KeyPress & keyPress ) const noexcept ;
//==============================================================================
/** Tries to recreate the mappings from a previously stored state.
The XML passed in must have been created by the createXml ( ) method .
If the stored state makes any reference to commands that aren ' t
currently available , these will be ignored .
If the set of mappings being loaded was a set of differences ( using createXml ( true ) ) ,
then this will call resetToDefaultMappings ( ) and then merge the saved mappings
on top . If the saved set was created with createXml ( false ) , then this method
will first clear all existing mappings and load the saved ones as a complete set .
@ returns true if it manages to load the XML correctly
@ see createXml
*/
bool restoreFromXml ( const XmlElement & xmlVersion ) ;
/** Creates an XML representation of the current mappings.
This will produce a lump of XML that can be later reloaded using
restoreFromXml ( ) to recreate the current mapping state .
The object that is returned must be deleted by the caller .
@ param saveDifferencesFromDefaultSet if this is false , then all keypresses
will be saved into the XML . If it ' s true , then the XML will
only store the differences between the current mappings and
the default mappings you ' d get from calling resetToDefaultMappings ( ) .
The advantage of saving a set of differences from the default is that
if you change the default mappings ( in a new version of your app , for
example ) , then these will be merged into a user ' s saved preferences .
@ see restoreFromXml
*/
XmlElement * createXml ( bool saveDifferencesFromDefaultSet ) const ;
//==============================================================================
/** @internal */
bool keyPressed ( const KeyPress & , Component * ) override ;
/** @internal */
bool keyStateChanged ( bool isKeyDown , Component * ) override ;
/** @internal */
void globalFocusChanged ( Component * ) override ;
private :
//==============================================================================
ApplicationCommandManager & commandManager ;
struct CommandMapping
{
CommandID commandID ;
Array < KeyPress > keypresses ;
bool wantsKeyUpDownCallbacks ;
} ;
OwnedArray < CommandMapping > mappings ;
struct KeyPressTime
{
KeyPress key ;
uint32 timeWhenPressed ;
} ;
OwnedArray < KeyPressTime > keysDown ;
void invokeCommand ( const CommandID , const KeyPress & , const bool isKeyDown ,
const int millisecsSinceKeyPressed , Component * originator ) const ;
KeyPressMappingSet & operator = ( const KeyPressMappingSet & ) ;
JUCE_LEAK_DETECTOR ( KeyPressMappingSet )
} ;
# endif // JUCE_KEYPRESSMAPPINGSET_H_INCLUDED