|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-7 by Raw Material Software ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the
- GNU General Public License, as published by the Free Software Foundation;
- either version 2 of the License, or (at your option) any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with JUCE; if not, visit www.gnu.org/licenses or write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- ------------------------------------------------------------------------------
-
- If you'd like to release a closed-source product which uses JUCE, commercial
- licenses are also available: visit www.rawmaterialsoftware.com/juce for
- more information.
-
- ==============================================================================
- */
-
- #ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
- #define __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
-
- #include "juce_KeyListener.h"
- #include "../../../application/juce_ApplicationCommandManager.h"
- #include "../../../events/juce_ChangeBroadcaster.h"
- #include "../../../../juce_core/text/juce_StringArray.h"
- #include "../../../../juce_core/text/juce_XmlElement.h"
- #include "../../../../juce_core/containers/juce_OwnedArray.h"
-
-
- //==============================================================================
- /**
- Manages and edits a list of keypresses, which it uses to invoke the appropriate
- command in a 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,
- public 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
- */
- KeyPressMappingSet (ApplicationCommandManager* const commandManager) throw();
-
- /** Creates an copy of a KeyPressMappingSet. */
- KeyPressMappingSet (const KeyPressMappingSet& other) throw();
-
- /** Destructor. */
- ~KeyPressMappingSet();
-
- //==============================================================================
- ApplicationCommandManager* getCommandManager() const throw() { return commandManager; }
-
- //==============================================================================
- /** Returns a list of keypresses that are assigned to a particular command.
-
- @param commandID the command's ID
- */
- const Array <KeyPress> getKeyPressesAssignedToCommand (const CommandID commandID) const throw();
-
- /** 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 (const CommandID commandID,
- const KeyPress& newKeyPress,
- int insertIndex = -1) throw();
-
- /** Reset all mappings to the defaults, as dictated by the ApplicationCommandManager.
-
- @see resetToDefaultMapping
- */
- void resetToDefaultMappings() throw();
-
- /** Resets all key-mappings to the defaults for a particular command.
-
- @see resetToDefaultMappings
- */
- void resetToDefaultMapping (const CommandID commandID) throw();
-
- /** Removes all keypresses that are assigned to any commands. */
- void clearAllKeyPresses() throw();
-
- /** Removes all keypresses that are assigned to a particular command. */
- void clearAllKeyPresses (const CommandID commandID) throw();
-
- /** 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 (const CommandID commandID,
- const int keyPressIndex) throw();
-
- /** Removes a keypress from any command that it may be assigned to.
- */
- void removeKeyPress (const KeyPress& keypress) throw();
-
- /** Returns true if the given command is linked to this key. */
- bool containsMapping (const CommandID commandID,
- const KeyPress& keyPress) const throw();
-
- //==============================================================================
- /** 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 throw();
-
- //==============================================================================
- /** 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 (const bool saveDifferencesFromDefaultSet) const;
-
- //==============================================================================
- /** @internal */
- bool keyPressed (const KeyPress& key, Component* originatingComponent);
- /** @internal */
- bool keyStateChanged (Component* originatingComponent);
- /** @internal */
- void globalFocusChanged (Component* focusedComponent);
-
-
- //==============================================================================
- juce_UseDebuggingNewOperator
-
-
- 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 handleMessage (const Message& message);
-
- void invokeCommand (const CommandID commandID,
- const KeyPress& keyPress,
- const bool isKeyDown,
- const int millisecsSinceKeyPressed,
- Component* const originatingComponent) const;
-
- const KeyPressMappingSet& operator= (const KeyPressMappingSet&);
- };
-
-
- #endif // __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
|