Add remaining files
[juce-lv2.git] / juce / source / src / application / juce_ApplicationCommandManager.h
blob2cb41d0ceb0cce1dc13c016b3bf77cb96cc206d1
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
27 #define __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
29 #include "juce_ApplicationCommandTarget.h"
30 #include "../events/juce_AsyncUpdater.h"
31 #include "../gui/components/juce_Desktop.h"
32 #include "../containers/juce_SortedSet.h"
33 class KeyPressMappingSet;
34 class ApplicationCommandManagerListener;
37 //==============================================================================
38 /**
39 One of these objects holds a list of all the commands your app can perform,
40 and despatches these commands when needed.
42 Application commands are a good way to trigger actions in your app, e.g. "Quit",
43 "Copy", "Paste", etc. Menus, buttons and keypresses can all be given commands
44 to invoke automatically, which means you don't have to handle the result of a menu
45 or button click manually. Commands are despatched to ApplicationCommandTarget objects
46 which can choose which events they want to handle.
48 This architecture also allows for nested ApplicationCommandTargets, so that for example
49 you could have two different objects, one inside the other, both of which can respond to
50 a "delete" command. Depending on which one has focus, the command will be sent to the
51 appropriate place, regardless of whether it was triggered by a menu, keypress or some other
52 method.
54 To set up your app to use commands, you'll need to do the following:
56 - Create a global ApplicationCommandManager to hold the list of all possible
57 commands. (This will also manage a set of key-mappings for them).
59 - Make some of your UI components (or other objects) inherit from ApplicationCommandTarget.
60 This allows the object to provide a list of commands that it can perform, and
61 to handle them.
63 - Register each type of command using ApplicationCommandManager::registerAllCommandsForTarget(),
64 or ApplicationCommandManager::registerCommand().
66 - If you want key-presses to trigger your commands, use the ApplicationCommandManager::getKeyMappings()
67 method to access the key-mapper object, which you will need to register as a key-listener
68 in whatever top-level component you're using. See the KeyPressMappingSet class for more help
69 about setting this up.
71 - Use methods such as PopupMenu::addCommandItem() or Button::setCommandToTrigger() to
72 cause these commands to be invoked automatically.
74 - Commands can be invoked directly by your code using ApplicationCommandManager::invokeDirectly().
76 When a command is invoked, the ApplicationCommandManager will try to choose the best
77 ApplicationCommandTarget to receive the specified command. To do this it will use the
78 current keyboard focus to see which component might be interested, and will search the
79 component hierarchy for those that also implement the ApplicationCommandTarget interface.
80 If an ApplicationCommandTarget isn't interested in the command that is being invoked, then
81 the next one in line will be tried (see the ApplicationCommandTarget::getNextCommandTarget()
82 method), and so on until ApplicationCommandTarget::getNextCommandTarget() returns 0. At this
83 point if the command still hasn't been performed, it will be passed to the current
84 JUCEApplication object (which is itself an ApplicationCommandTarget).
86 To exert some custom control over which ApplicationCommandTarget is chosen to invoke a command,
87 you can override the ApplicationCommandManager::getFirstCommandTarget() method and choose
88 the object yourself.
90 @see ApplicationCommandTarget, ApplicationCommandInfo
92 class JUCE_API ApplicationCommandManager : private AsyncUpdater,
93 private FocusChangeListener
95 public:
96 //==============================================================================
97 /** Creates an ApplicationCommandManager.
99 Once created, you'll need to register all your app's commands with it, using
100 ApplicationCommandManager::registerAllCommandsForTarget() or
101 ApplicationCommandManager::registerCommand().
103 ApplicationCommandManager();
105 /** Destructor.
107 Make sure that you don't delete this if pointers to it are still being used by
108 objects such as PopupMenus or Buttons.
110 virtual ~ApplicationCommandManager();
112 //==============================================================================
113 /** Clears the current list of all commands.
115 Note that this will also clear the contents of the KeyPressMappingSet.
117 void clearCommands();
119 /** Adds a command to the list of registered commands.
121 @see registerAllCommandsForTarget
123 void registerCommand (const ApplicationCommandInfo& newCommand);
125 /** Adds all the commands that this target publishes to the manager's list.
127 This will use ApplicationCommandTarget::getAllCommands() and ApplicationCommandTarget::getCommandInfo()
128 to get details about all the commands that this target can do, and will call
129 registerCommand() to add each one to the manger's list.
131 @see registerCommand
133 void registerAllCommandsForTarget (ApplicationCommandTarget* target);
135 /** Removes the command with a specified ID.
137 Note that this will also remove any key mappings that are mapped to the command.
139 void removeCommand (CommandID commandID);
141 /** This should be called to tell the manager that one of its registered commands may have changed
142 its active status.
144 Because the command manager only finds out whether a command is active or inactive by querying
145 the current ApplicationCommandTarget, this is used to tell it that things may have changed. It
146 allows things like buttons to update their enablement, etc.
148 This method will cause an asynchronous call to ApplicationCommandManagerListener::applicationCommandListChanged()
149 for any registered listeners.
151 void commandStatusChanged();
153 //==============================================================================
154 /** Returns the number of commands that have been registered.
156 @see registerCommand
158 int getNumCommands() const noexcept { return commands.size(); }
160 /** Returns the details about one of the registered commands.
162 The index is between 0 and (getNumCommands() - 1).
164 const ApplicationCommandInfo* getCommandForIndex (int index) const noexcept { return commands [index]; }
166 /** Returns the details about a given command ID.
168 This will search the list of registered commands for one with the given command
169 ID number, and return its associated info. If no matching command is found, this
170 will return 0.
172 const ApplicationCommandInfo* getCommandForID (CommandID commandID) const noexcept;
174 /** Returns the name field for a command.
176 An empty string is returned if no command with this ID has been registered.
177 @see getDescriptionOfCommand
179 String getNameOfCommand (CommandID commandID) const noexcept;
181 /** Returns the description field for a command.
183 An empty string is returned if no command with this ID has been registered. If the
184 command has no description, this will return its short name field instead.
186 @see getNameOfCommand
188 String getDescriptionOfCommand (CommandID commandID) const noexcept;
190 /** Returns the list of categories.
192 This will go through all registered commands, and return a list of all the distict
193 categoryName values from their ApplicationCommandInfo structure.
195 @see getCommandsInCategory()
197 StringArray getCommandCategories() const;
199 /** Returns a list of all the command UIDs in a particular category.
201 @see getCommandCategories()
203 Array<CommandID> getCommandsInCategory (const String& categoryName) const;
205 //==============================================================================
206 /** Returns the manager's internal set of key mappings.
208 This object can be used to edit the keypresses. To actually link this object up
209 to invoke commands when a key is pressed, see the comments for the KeyPressMappingSet
210 class.
212 @see KeyPressMappingSet
214 KeyPressMappingSet* getKeyMappings() const noexcept { return keyMappings; }
217 //==============================================================================
218 /** Invokes the given command directly, sending it to the default target.
220 This is just an easy way to call invoke() without having to fill out the InvocationInfo
221 structure.
223 bool invokeDirectly (CommandID commandID, bool asynchronously);
225 /** Sends a command to the default target.
227 This will choose a target using getFirstCommandTarget(), and send the specified command
228 to it using the ApplicationCommandTarget::invoke() method. This means that if the
229 first target can't handle the command, it will be passed on to targets further down the
230 chain (see ApplicationCommandTarget::invoke() for more info).
232 @param invocationInfo this must be correctly filled-in, describing the context for
233 the invocation.
234 @param asynchronously if false, the command will be performed before this method returns.
235 If true, a message will be posted so that the command will be performed
236 later on the message thread, and this method will return immediately.
238 @see ApplicationCommandTarget::invoke
240 bool invoke (const ApplicationCommandTarget::InvocationInfo& invocationInfo,
241 bool asynchronously);
244 //==============================================================================
245 /** Chooses the ApplicationCommandTarget to which a command should be sent.
247 Whenever the manager needs to know which target a command should be sent to, it calls
248 this method to determine the first one to try.
250 By default, this method will return the target that was set by calling setFirstCommandTarget().
251 If no target is set, it will return the result of findDefaultComponentTarget().
253 If you need to make sure all commands go via your own custom target, then you can
254 either use setFirstCommandTarget() to specify a single target, or override this method
255 if you need more complex logic to choose one.
257 It may return 0 if no targets are available.
259 @see getTargetForCommand, invoke, invokeDirectly
261 virtual ApplicationCommandTarget* getFirstCommandTarget (CommandID commandID);
263 /** Sets a target to be returned by getFirstCommandTarget().
265 If this is set to 0, then getFirstCommandTarget() will by default return the
266 result of findDefaultComponentTarget().
268 If you use this to set a target, make sure you call setFirstCommandTarget (0) before
269 deleting the target object.
271 void setFirstCommandTarget (ApplicationCommandTarget* newTarget) noexcept;
273 /** Tries to find the best target to use to perform a given command.
275 This will call getFirstCommandTarget() to find the preferred target, and will
276 check whether that target can handle the given command. If it can't, then it'll use
277 ApplicationCommandTarget::getNextCommandTarget() to find the next one to try, and
278 so on until no more are available.
280 If no targets are found that can perform the command, this method will return 0.
282 If a target is found, then it will get the target to fill-in the upToDateInfo
283 structure with the latest info about that command, so that the caller can see
284 whether the command is disabled, ticked, etc.
286 ApplicationCommandTarget* getTargetForCommand (CommandID commandID,
287 ApplicationCommandInfo& upToDateInfo);
289 //==============================================================================
290 /** Registers a listener that will be called when various events occur. */
291 void addListener (ApplicationCommandManagerListener* listener);
293 /** Deregisters a previously-added listener. */
294 void removeListener (ApplicationCommandManagerListener* listener);
296 //==============================================================================
297 /** Looks for a suitable command target based on which Components have the keyboard focus.
299 This is used by the default implementation of ApplicationCommandTarget::getFirstCommandTarget(),
300 but is exposed here in case it's useful.
302 It tries to pick the best ApplicationCommandTarget by looking at focused components, top level
303 windows, etc., and using the findTargetForComponent() method.
305 static ApplicationCommandTarget* findDefaultComponentTarget();
307 /** Examines this component and all its parents in turn, looking for the first one
308 which is a ApplicationCommandTarget.
310 Returns the first ApplicationCommandTarget that it finds, or 0 if none of them implement
311 that class.
313 static ApplicationCommandTarget* findTargetForComponent (Component* component);
316 private:
317 //==============================================================================
318 OwnedArray <ApplicationCommandInfo> commands;
319 ListenerList <ApplicationCommandManagerListener> listeners;
320 ScopedPointer <KeyPressMappingSet> keyMappings;
321 ApplicationCommandTarget* firstTarget;
323 void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info);
324 void handleAsyncUpdate();
325 void globalFocusChanged (Component*);
327 #if JUCE_CATCH_DEPRECATED_CODE_MISUSE
328 // This is just here to cause a compile error in old code that hasn't been changed to use the new
329 // version of this method.
330 virtual short getFirstCommandTarget() { return 0; }
331 #endif
333 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandManager);
337 //==============================================================================
339 A listener that receives callbacks from an ApplicationCommandManager when
340 commands are invoked or the command list is changed.
342 @see ApplicationCommandManager::addListener, ApplicationCommandManager::removeListener
345 class JUCE_API ApplicationCommandManagerListener
347 public:
348 //==============================================================================
349 /** Destructor. */
350 virtual ~ApplicationCommandManagerListener() {}
352 /** Called when an app command is about to be invoked. */
353 virtual void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info) = 0;
355 /** Called when commands are registered or deregistered from the
356 command manager, or when commands are made active or inactive.
358 Note that if you're using this to watch for changes to whether a command is disabled,
359 you'll need to make sure that ApplicationCommandManager::commandStatusChanged() is called
360 whenever the status of your command might have changed.
362 virtual void applicationCommandListChanged() = 0;
367 #endif // __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__