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_APPLICATIONCOMMANDTARGET_JUCEHEADER__
27 #define __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__
29 #include "../gui/components/juce_Component.h"
30 #include "juce_ApplicationCommandInfo.h"
31 #include "../events/juce_MessageListener.h"
34 //==============================================================================
36 A command target publishes a list of command IDs that it can perform.
38 An ApplicationCommandManager despatches commands to targets, which must be
39 able to provide information about what commands they can handle.
41 To create a target, you'll need to inherit from this class, implementing all of
42 its pure virtual methods.
44 For info about how a target is chosen to receive a command, see
45 ApplicationCommandManager::getFirstCommandTarget().
47 @see ApplicationCommandManager, ApplicationCommandInfo
49 class JUCE_API ApplicationCommandTarget
52 //==============================================================================
53 /** Creates a command target. */
54 ApplicationCommandTarget();
57 virtual ~ApplicationCommandTarget();
59 //==============================================================================
62 struct JUCE_API InvocationInfo
64 //==============================================================================
65 InvocationInfo (const CommandID commandID
);
67 //==============================================================================
68 /** The UID of the command that should be performed. */
71 /** The command's flags.
73 See ApplicationCommandInfo for a description of these flag values.
77 //==============================================================================
78 /** The types of context in which the command might be called. */
81 direct
= 0, /**< The command is being invoked directly by a piece of code. */
82 fromKeyPress
, /**< The command is being invoked by a key-press. */
83 fromMenu
, /**< The command is being invoked by a menu selection. */
84 fromButton
/**< The command is being invoked by a button click. */
87 /** The type of event that triggered this command. */
88 InvocationMethod invocationMethod
;
90 //==============================================================================
91 /** If triggered by a keypress or menu, this will be the component that had the
92 keyboard focus at the time.
94 If triggered by a button, it may be set to that component, or it may be null.
96 Component
* originatingComponent
;
98 //==============================================================================
99 /** The keypress that was used to invoke it.
101 Note that this will be an invalid keypress if the command was invoked
102 by some other means than a keyboard shortcut.
106 /** True if the callback is being invoked when the key is pressed,
107 false if the key is being released.
109 @see KeyPressMappingSet::addCommand()
113 /** If the key is being released, this indicates how long it had been held
116 (Only relevant if isKeyDown is false.)
118 int millisecsSinceKeyPressed
;
121 //==============================================================================
122 /** This must return the next target to try after this one.
124 When a command is being sent, and the first target can't handle
125 that command, this method is used to determine the next target that should
128 It may return 0 if it doesn't know of another target.
130 If your target is a Component, you would usually use the findFirstTargetParentComponent()
131 method to return a parent component that might want to handle it.
135 virtual ApplicationCommandTarget
* getNextCommandTarget() = 0;
137 /** This must return a complete list of commands that this target can handle.
139 Your target should add all the command IDs that it handles to the array that is
142 virtual void getAllCommands (Array
<CommandID
>& commands
) = 0;
144 /** This must provide details about one of the commands that this target can perform.
146 This will be called with one of the command IDs that the target provided in its
147 getAllCommands() methods.
149 It should fill-in all appropriate fields of the ApplicationCommandInfo structure with
150 suitable information about the command. (The commandID field will already have been filled-in
153 The easiest way to set the info is using the ApplicationCommandInfo::setInfo() method to
154 set all the fields at once.
156 If the command is currently inactive for some reason, this method must use
157 ApplicationCommandInfo::setActive() to make that clear, (or it should set the isDisabled
158 bit of the ApplicationCommandInfo::flags field).
160 Any default key-presses for the command should be appended to the
161 ApplicationCommandInfo::defaultKeypresses field.
163 Note that if you change something that affects the status of the commands
164 that would be returned by this method (e.g. something that makes some commands
165 active or inactive), you should call ApplicationCommandManager::commandStatusChanged()
166 to cause the manager to refresh its status.
168 virtual void getCommandInfo (CommandID commandID
, ApplicationCommandInfo
& result
) = 0;
170 /** This must actually perform the specified command.
172 If this target is able to perform the command specified by the commandID field of the
173 InvocationInfo structure, then it should do so, and must return true.
175 If it can't handle this command, it should return false, which tells the caller to pass
176 the command on to the next target in line.
178 @see invoke, ApplicationCommandManager::invoke
180 virtual bool perform (const InvocationInfo
& info
) = 0;
182 //==============================================================================
183 /** Makes this target invoke a command.
185 Your code can call this method to invoke a command on this target, but normally
186 you'd call it indirectly via ApplicationCommandManager::invoke() or
187 ApplicationCommandManager::invokeDirectly().
189 If this target can perform the given command, it will call its perform() method to
190 do so. If not, then getNextCommandTarget() will be used to determine the next target
191 to try, and the command will be passed along to it.
193 @param invocationInfo this must be correctly filled-in, describing the context for
195 @param asynchronously if false, the command will be performed before this method returns.
196 If true, a message will be posted so that the command will be performed
197 later on the message thread, and this method will return immediately.
198 @see perform, ApplicationCommandManager::invoke
200 bool invoke (const InvocationInfo
& invocationInfo
,
201 const bool asynchronously
);
203 /** Invokes a given command directly on this target.
205 This is just an easy way to call invoke() without having to fill out the InvocationInfo
208 bool invokeDirectly (const CommandID commandID
,
209 const bool asynchronously
);
211 //==============================================================================
212 /** Searches this target and all subsequent ones for the first one that can handle
213 the specified command.
215 This will use getNextCommandTarget() to determine the chain of targets to try
218 ApplicationCommandTarget
* getTargetForCommand (const CommandID commandID
);
220 /** Checks whether this command can currently be performed by this target.
222 This will return true only if a call to getCommandInfo() doesn't set the
223 isDisabled flag to indicate that the command is inactive.
225 bool isCommandActive (const CommandID commandID
);
227 /** If this object is a Component, this method will seach upwards in its current
228 UI hierarchy for the next parent component that implements the
229 ApplicationCommandTarget class.
231 If your target is a Component, this is a very handy method to use in your
232 getNextCommandTarget() implementation.
234 ApplicationCommandTarget
* findFirstTargetParentComponent();
237 //==============================================================================
238 // (for async invocation of commands)
239 class CommandTargetMessageInvoker
: public MessageListener
242 CommandTargetMessageInvoker (ApplicationCommandTarget
* owner
);
243 ~CommandTargetMessageInvoker();
245 void handleMessage (const Message
& message
);
248 ApplicationCommandTarget
* const owner
;
250 JUCE_DECLARE_NON_COPYABLE (CommandTargetMessageInvoker
);
253 ScopedPointer
<CommandTargetMessageInvoker
> messageInvoker
;
255 friend class CommandTargetMessageInvoker
;
256 bool tryToInvoke (const InvocationInfo
& info
, bool async
);
258 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget
);
262 #endif // __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__