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.

juce_ApplicationCommandTarget.cpp 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. namespace juce
  20. {
  21. class ApplicationCommandTarget::CommandMessage : public MessageManager::MessageBase
  22. {
  23. public:
  24. CommandMessage (ApplicationCommandTarget* const target, const InvocationInfo& inf)
  25. : owner (target), info (inf)
  26. {
  27. }
  28. void messageCallback() override
  29. {
  30. if (ApplicationCommandTarget* const target = owner)
  31. target->tryToInvoke (info, false);
  32. }
  33. private:
  34. WeakReference<ApplicationCommandTarget> owner;
  35. const InvocationInfo info;
  36. JUCE_DECLARE_NON_COPYABLE (CommandMessage)
  37. };
  38. //==============================================================================
  39. ApplicationCommandTarget::ApplicationCommandTarget() {}
  40. ApplicationCommandTarget::~ApplicationCommandTarget() {}
  41. //==============================================================================
  42. bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bool async)
  43. {
  44. if (isCommandActive (info.commandID))
  45. {
  46. if (async)
  47. {
  48. (new CommandMessage (this, info))->post();
  49. return true;
  50. }
  51. if (perform (info))
  52. return true;
  53. // Hmm.. your target claimed that it could perform this command, but failed to do so.
  54. // If it can't do it at the moment for some reason, it should clear the 'isActive' flag
  55. // when it returns the command's info.
  56. jassertfalse;
  57. }
  58. return false;
  59. }
  60. ApplicationCommandTarget* ApplicationCommandTarget::findFirstTargetParentComponent()
  61. {
  62. if (Component* const c = dynamic_cast<Component*> (this))
  63. return c->findParentComponentOfClass<ApplicationCommandTarget>();
  64. return nullptr;
  65. }
  66. ApplicationCommandTarget* ApplicationCommandTarget::getTargetForCommand (const CommandID commandID)
  67. {
  68. ApplicationCommandTarget* target = this;
  69. int depth = 0;
  70. while (target != nullptr)
  71. {
  72. Array<CommandID> commandIDs;
  73. target->getAllCommands (commandIDs);
  74. if (commandIDs.contains (commandID))
  75. return target;
  76. target = target->getNextCommandTarget();
  77. ++depth;
  78. jassert (depth < 100); // could be a recursive command chain??
  79. jassert (target != this); // definitely a recursive command chain!
  80. if (depth > 100 || target == this)
  81. break;
  82. }
  83. if (target == nullptr)
  84. {
  85. target = JUCEApplication::getInstance();
  86. if (target != nullptr)
  87. {
  88. Array<CommandID> commandIDs;
  89. target->getAllCommands (commandIDs);
  90. if (commandIDs.contains (commandID))
  91. return target;
  92. }
  93. }
  94. return nullptr;
  95. }
  96. bool ApplicationCommandTarget::isCommandActive (const CommandID commandID)
  97. {
  98. ApplicationCommandInfo info (commandID);
  99. info.flags = ApplicationCommandInfo::isDisabled;
  100. getCommandInfo (commandID, info);
  101. return (info.flags & ApplicationCommandInfo::isDisabled) == 0;
  102. }
  103. //==============================================================================
  104. bool ApplicationCommandTarget::invoke (const InvocationInfo& info, const bool async)
  105. {
  106. ApplicationCommandTarget* target = this;
  107. int depth = 0;
  108. while (target != nullptr)
  109. {
  110. if (target->tryToInvoke (info, async))
  111. return true;
  112. target = target->getNextCommandTarget();
  113. ++depth;
  114. jassert (depth < 100); // could be a recursive command chain??
  115. jassert (target != this); // definitely a recursive command chain!
  116. if (depth > 100 || target == this)
  117. break;
  118. }
  119. if (target == nullptr)
  120. {
  121. target = JUCEApplication::getInstance();
  122. if (target != nullptr)
  123. return target->tryToInvoke (info, async);
  124. }
  125. return false;
  126. }
  127. bool ApplicationCommandTarget::invokeDirectly (const CommandID commandID, const bool asynchronously)
  128. {
  129. ApplicationCommandTarget::InvocationInfo info (commandID);
  130. info.invocationMethod = ApplicationCommandTarget::InvocationInfo::direct;
  131. return invoke (info, asynchronously);
  132. }
  133. //==============================================================================
  134. ApplicationCommandTarget::InvocationInfo::InvocationInfo (const CommandID command)
  135. : commandID (command),
  136. commandFlags (0),
  137. invocationMethod (direct),
  138. originatingComponent (nullptr),
  139. isKeyDown (false),
  140. millisecsSinceKeyPressed (0)
  141. {
  142. }
  143. } // namespace juce