Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
10KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #ifndef JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED
  18. #define JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED
  19. //==============================================================================
  20. /**
  21. A command target publishes a list of command IDs that it can perform.
  22. An ApplicationCommandManager despatches commands to targets, which must be
  23. able to provide information about what commands they can handle.
  24. To create a target, you'll need to inherit from this class, implementing all of
  25. its pure virtual methods.
  26. For info about how a target is chosen to receive a command, see
  27. ApplicationCommandManager::getFirstCommandTarget().
  28. @see ApplicationCommandManager, ApplicationCommandInfo
  29. */
  30. class JUCE_API ApplicationCommandTarget
  31. {
  32. public:
  33. //==============================================================================
  34. /** Creates a command target. */
  35. ApplicationCommandTarget();
  36. /** Destructor. */
  37. virtual ~ApplicationCommandTarget();
  38. //==============================================================================
  39. /**
  40. Contains contextual details about the invocation of a command.
  41. */
  42. struct JUCE_API InvocationInfo
  43. {
  44. //==============================================================================
  45. InvocationInfo (const CommandID commandID);
  46. //==============================================================================
  47. /** The UID of the command that should be performed. */
  48. CommandID commandID;
  49. /** The command's flags.
  50. See ApplicationCommandInfo for a description of these flag values.
  51. */
  52. int commandFlags;
  53. //==============================================================================
  54. /** The types of context in which the command might be called. */
  55. enum InvocationMethod
  56. {
  57. direct = 0, /**< The command is being invoked directly by a piece of code. */
  58. fromKeyPress, /**< The command is being invoked by a key-press. */
  59. fromMenu, /**< The command is being invoked by a menu selection. */
  60. fromButton /**< The command is being invoked by a button click. */
  61. };
  62. /** The type of event that triggered this command. */
  63. InvocationMethod invocationMethod;
  64. //==============================================================================
  65. /** If triggered by a keypress or menu, this will be the component that had the
  66. keyboard focus at the time.
  67. If triggered by a button, it may be set to that component, or it may be null.
  68. */
  69. Component* originatingComponent;
  70. //==============================================================================
  71. /** The keypress that was used to invoke it.
  72. Note that this will be an invalid keypress if the command was invoked
  73. by some other means than a keyboard shortcut.
  74. */
  75. KeyPress keyPress;
  76. /** True if the callback is being invoked when the key is pressed,
  77. false if the key is being released.
  78. @see KeyPressMappingSet::addCommand()
  79. */
  80. bool isKeyDown;
  81. /** If the key is being released, this indicates how long it had been held
  82. down for.
  83. (Only relevant if isKeyDown is false.)
  84. */
  85. int millisecsSinceKeyPressed;
  86. };
  87. //==============================================================================
  88. /** This must return the next target to try after this one.
  89. When a command is being sent, and the first target can't handle
  90. that command, this method is used to determine the next target that should
  91. be tried.
  92. It may return nullptr if it doesn't know of another target.
  93. If your target is a Component, you would usually use the findFirstTargetParentComponent()
  94. method to return a parent component that might want to handle it.
  95. @see invoke
  96. */
  97. virtual ApplicationCommandTarget* getNextCommandTarget() = 0;
  98. /** This must return a complete list of commands that this target can handle.
  99. Your target should add all the command IDs that it handles to the array that is
  100. passed-in.
  101. */
  102. virtual void getAllCommands (Array<CommandID>& commands) = 0;
  103. /** This must provide details about one of the commands that this target can perform.
  104. This will be called with one of the command IDs that the target provided in its
  105. getAllCommands() methods.
  106. It should fill-in all appropriate fields of the ApplicationCommandInfo structure with
  107. suitable information about the command. (The commandID field will already have been filled-in
  108. by the caller).
  109. The easiest way to set the info is using the ApplicationCommandInfo::setInfo() method to
  110. set all the fields at once.
  111. If the command is currently inactive for some reason, this method must use
  112. ApplicationCommandInfo::setActive() to make that clear, (or it should set the isDisabled
  113. bit of the ApplicationCommandInfo::flags field).
  114. Any default key-presses for the command should be appended to the
  115. ApplicationCommandInfo::defaultKeypresses field.
  116. Note that if you change something that affects the status of the commands
  117. that would be returned by this method (e.g. something that makes some commands
  118. active or inactive), you should call ApplicationCommandManager::commandStatusChanged()
  119. to cause the manager to refresh its status.
  120. */
  121. virtual void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result) = 0;
  122. /** This must actually perform the specified command.
  123. If this target is able to perform the command specified by the commandID field of the
  124. InvocationInfo structure, then it should do so, and must return true.
  125. If it can't handle this command, it should return false, which tells the caller to pass
  126. the command on to the next target in line.
  127. @see invoke, ApplicationCommandManager::invoke
  128. */
  129. virtual bool perform (const InvocationInfo& info) = 0;
  130. //==============================================================================
  131. /** Makes this target invoke a command.
  132. Your code can call this method to invoke a command on this target, but normally
  133. you'd call it indirectly via ApplicationCommandManager::invoke() or
  134. ApplicationCommandManager::invokeDirectly().
  135. If this target can perform the given command, it will call its perform() method to
  136. do so. If not, then getNextCommandTarget() will be used to determine the next target
  137. to try, and the command will be passed along to it.
  138. @param invocationInfo this must be correctly filled-in, describing the context for
  139. the invocation.
  140. @param asynchronously if false, the command will be performed before this method returns.
  141. If true, a message will be posted so that the command will be performed
  142. later on the message thread, and this method will return immediately.
  143. @see perform, ApplicationCommandManager::invoke
  144. */
  145. bool invoke (const InvocationInfo& invocationInfo,
  146. const bool asynchronously);
  147. /** Invokes a given command directly on this target.
  148. This is just an easy way to call invoke() without having to fill out the InvocationInfo
  149. structure.
  150. */
  151. bool invokeDirectly (const CommandID commandID,
  152. const bool asynchronously);
  153. //==============================================================================
  154. /** Searches this target and all subsequent ones for the first one that can handle
  155. the specified command.
  156. This will use getNextCommandTarget() to determine the chain of targets to try
  157. after this one.
  158. */
  159. ApplicationCommandTarget* getTargetForCommand (const CommandID commandID);
  160. /** Checks whether this command can currently be performed by this target.
  161. This will return true only if a call to getCommandInfo() doesn't set the
  162. isDisabled flag to indicate that the command is inactive.
  163. */
  164. bool isCommandActive (const CommandID commandID);
  165. /** If this object is a Component, this method will search upwards in its current
  166. UI hierarchy for the next parent component that implements the
  167. ApplicationCommandTarget class.
  168. If your target is a Component, this is a very handy method to use in your
  169. getNextCommandTarget() implementation.
  170. */
  171. ApplicationCommandTarget* findFirstTargetParentComponent();
  172. private:
  173. //==============================================================================
  174. WeakReference<ApplicationCommandTarget>::Master masterReference;
  175. friend class WeakReference<ApplicationCommandTarget>;
  176. class CommandMessage;
  177. friend class CommandMessage;
  178. bool tryToInvoke (const InvocationInfo&, bool async);
  179. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget)
  180. };
  181. #endif // JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED