1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 By using JUCE, you agree to the terms of both the JUCE 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-licence 14 Privacy Policy: www.juce.com/juce-privacy-policy 15 16 Or: You may also use this code under the terms of the GPL v3 (see 17 www.gnu.org/licenses). 18 19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 21 DISCLAIMED. 22 23 ============================================================================== 24 */ 25 26 namespace juce 27 { 28 29 //============================================================================== 30 /** 31 A command target publishes a list of command IDs that it can perform. 32 33 An ApplicationCommandManager despatches commands to targets, which must be 34 able to provide information about what commands they can handle. 35 36 To create a target, you'll need to inherit from this class, implementing all of 37 its pure virtual methods. 38 39 For info about how a target is chosen to receive a command, see 40 ApplicationCommandManager::getFirstCommandTarget(). 41 42 @see ApplicationCommandManager, ApplicationCommandInfo 43 44 @tags{GUI} 45 */ 46 class JUCE_API ApplicationCommandTarget 47 { 48 public: 49 //============================================================================== 50 /** Creates a command target. */ 51 ApplicationCommandTarget(); 52 53 /** Destructor. */ 54 virtual ~ApplicationCommandTarget(); 55 56 //============================================================================== 57 /** 58 Contains contextual details about the invocation of a command. 59 */ 60 struct JUCE_API InvocationInfo 61 { 62 //============================================================================== 63 InvocationInfo (const CommandID commandID); 64 65 //============================================================================== 66 /** The UID of the command that should be performed. */ 67 CommandID commandID; 68 69 /** The command's flags. 70 See ApplicationCommandInfo for a description of these flag values. 71 */ 72 int commandFlags; 73 74 //============================================================================== 75 /** The types of context in which the command might be called. */ 76 enum InvocationMethod 77 { 78 direct = 0, /**< The command is being invoked directly by a piece of code. */ 79 fromKeyPress, /**< The command is being invoked by a key-press. */ 80 fromMenu, /**< The command is being invoked by a menu selection. */ 81 fromButton /**< The command is being invoked by a button click. */ 82 }; 83 84 /** The type of event that triggered this command. */ 85 InvocationMethod invocationMethod; 86 87 //============================================================================== 88 /** If triggered by a keypress or menu, this will be the component that had the 89 keyboard focus at the time. 90 91 If triggered by a button, it may be set to that component, or it may be null. 92 */ 93 Component* originatingComponent; 94 95 //============================================================================== 96 /** The keypress that was used to invoke it. 97 98 Note that this will be an invalid keypress if the command was invoked 99 by some other means than a keyboard shortcut. 100 */ 101 KeyPress keyPress; 102 103 /** True if the callback is being invoked when the key is pressed, 104 false if the key is being released. 105 106 @see KeyPressMappingSet::addCommand() 107 */ 108 bool isKeyDown; 109 110 /** If the key is being released, this indicates how long it had been held 111 down for. 112 113 (Only relevant if isKeyDown is false.) 114 */ 115 int millisecsSinceKeyPressed; 116 }; 117 118 //============================================================================== 119 /** This must return the next target to try after this one. 120 121 When a command is being sent, and the first target can't handle 122 that command, this method is used to determine the next target that should 123 be tried. 124 125 It may return nullptr if it doesn't know of another target. 126 127 If your target is a Component, you would usually use the findFirstTargetParentComponent() 128 method to return a parent component that might want to handle it. 129 130 @see invoke 131 */ 132 virtual ApplicationCommandTarget* getNextCommandTarget() = 0; 133 134 /** This must return a complete list of commands that this target can handle. 135 136 Your target should add all the command IDs that it handles to the array that is 137 passed-in. 138 */ 139 virtual void getAllCommands (Array<CommandID>& commands) = 0; 140 141 /** This must provide details about one of the commands that this target can perform. 142 143 This will be called with one of the command IDs that the target provided in its 144 getAllCommands() methods. 145 146 It should fill-in all appropriate fields of the ApplicationCommandInfo structure with 147 suitable information about the command. (The commandID field will already have been filled-in 148 by the caller). 149 150 The easiest way to set the info is using the ApplicationCommandInfo::setInfo() method to 151 set all the fields at once. 152 153 If the command is currently inactive for some reason, this method must use 154 ApplicationCommandInfo::setActive() to make that clear, (or it should set the isDisabled 155 bit of the ApplicationCommandInfo::flags field). 156 157 Any default key-presses for the command should be appended to the 158 ApplicationCommandInfo::defaultKeypresses field. 159 160 Note that if you change something that affects the status of the commands 161 that would be returned by this method (e.g. something that makes some commands 162 active or inactive), you should call ApplicationCommandManager::commandStatusChanged() 163 to cause the manager to refresh its status. 164 */ 165 virtual void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result) = 0; 166 167 /** This must actually perform the specified command. 168 169 If this target is able to perform the command specified by the commandID field of the 170 InvocationInfo structure, then it should do so, and must return true. 171 172 If it can't handle this command, it should return false, which tells the caller to pass 173 the command on to the next target in line. 174 175 @see invoke, ApplicationCommandManager::invoke 176 */ 177 virtual bool perform (const InvocationInfo& info) = 0; 178 179 //============================================================================== 180 /** Makes this target invoke a command. 181 182 Your code can call this method to invoke a command on this target, but normally 183 you'd call it indirectly via ApplicationCommandManager::invoke() or 184 ApplicationCommandManager::invokeDirectly(). 185 186 If this target can perform the given command, it will call its perform() method to 187 do so. If not, then getNextCommandTarget() will be used to determine the next target 188 to try, and the command will be passed along to it. 189 190 @param invocationInfo this must be correctly filled-in, describing the context for 191 the invocation. 192 @param asynchronously if false, the command will be performed before this method returns. 193 If true, a message will be posted so that the command will be performed 194 later on the message thread, and this method will return immediately. 195 @see perform, ApplicationCommandManager::invoke 196 */ 197 bool invoke (const InvocationInfo& invocationInfo, 198 const bool asynchronously); 199 200 /** Invokes a given command directly on this target. 201 202 This is just an easy way to call invoke() without having to fill out the InvocationInfo 203 structure. 204 */ 205 bool invokeDirectly (const CommandID commandID, 206 const bool asynchronously); 207 208 //============================================================================== 209 /** Searches this target and all subsequent ones for the first one that can handle 210 the specified command. 211 212 This will use getNextCommandTarget() to determine the chain of targets to try 213 after this one. 214 */ 215 ApplicationCommandTarget* getTargetForCommand (const CommandID commandID); 216 217 /** Checks whether this command can currently be performed by this target. 218 219 This will return true only if a call to getCommandInfo() doesn't set the 220 isDisabled flag to indicate that the command is inactive. 221 */ 222 bool isCommandActive (const CommandID commandID); 223 224 /** If this object is a Component, this method will search upwards in its current 225 UI hierarchy for the next parent component that implements the 226 ApplicationCommandTarget class. 227 228 If your target is a Component, this is a very handy method to use in your 229 getNextCommandTarget() implementation. 230 */ 231 ApplicationCommandTarget* findFirstTargetParentComponent(); 232 233 private: 234 //============================================================================== 235 class CommandMessage; 236 friend class CommandMessage; 237 238 bool tryToInvoke (const InvocationInfo&, bool async); 239 240 JUCE_DECLARE_WEAK_REFERENCEABLE (ApplicationCommandTarget) 241 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget) 242 }; 243 244 } // namespace juce 245