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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software 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. class ApplicationCommandTarget::CommandMessage : public MessageManager::MessageBase
  18. {
  19. public:
  20. CommandMessage (ApplicationCommandTarget* const target, const InvocationInfo& inf)
  21. : owner (target), info (inf)
  22. {
  23. }
  24. void messageCallback() override
  25. {
  26. if (ApplicationCommandTarget* const target = owner)
  27. target->tryToInvoke (info, false);
  28. }
  29. private:
  30. WeakReference<ApplicationCommandTarget> owner;
  31. const InvocationInfo info;
  32. JUCE_DECLARE_NON_COPYABLE (CommandMessage)
  33. };
  34. //==============================================================================
  35. ApplicationCommandTarget::ApplicationCommandTarget()
  36. {
  37. }
  38. ApplicationCommandTarget::~ApplicationCommandTarget()
  39. {
  40. masterReference.clear();
  41. }
  42. //==============================================================================
  43. bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bool async)
  44. {
  45. if (isCommandActive (info.commandID))
  46. {
  47. if (async)
  48. {
  49. (new CommandMessage (this, info))->post();
  50. return true;
  51. }
  52. if (perform (info))
  53. return true;
  54. // Hmm.. your target claimed that it could perform this command, but failed to do so.
  55. // If it can't do it at the moment for some reason, it should clear the 'isActive' flag
  56. // when it returns the command's info.
  57. jassertfalse;
  58. }
  59. return false;
  60. }
  61. ApplicationCommandTarget* ApplicationCommandTarget::findFirstTargetParentComponent()
  62. {
  63. if (Component* const c = dynamic_cast <Component*> (this))
  64. return c->findParentComponentOfClass<ApplicationCommandTarget>();
  65. return nullptr;
  66. }
  67. ApplicationCommandTarget* ApplicationCommandTarget::getTargetForCommand (const CommandID commandID)
  68. {
  69. ApplicationCommandTarget* target = this;
  70. int depth = 0;
  71. while (target != nullptr)
  72. {
  73. Array <CommandID> commandIDs;
  74. target->getAllCommands (commandIDs);
  75. if (commandIDs.contains (commandID))
  76. return target;
  77. target = target->getNextCommandTarget();
  78. ++depth;
  79. jassert (depth < 100); // could be a recursive command chain??
  80. jassert (target != this); // definitely a recursive command chain!
  81. if (depth > 100 || target == this)
  82. break;
  83. }
  84. if (target == nullptr)
  85. {
  86. target = JUCEApplication::getInstance();
  87. if (target != nullptr)
  88. {
  89. Array <CommandID> commandIDs;
  90. target->getAllCommands (commandIDs);
  91. if (commandIDs.contains (commandID))
  92. return target;
  93. }
  94. }
  95. return nullptr;
  96. }
  97. bool ApplicationCommandTarget::isCommandActive (const CommandID commandID)
  98. {
  99. ApplicationCommandInfo info (commandID);
  100. info.flags = ApplicationCommandInfo::isDisabled;
  101. getCommandInfo (commandID, info);
  102. return (info.flags & ApplicationCommandInfo::isDisabled) == 0;
  103. }
  104. //==============================================================================
  105. bool ApplicationCommandTarget::invoke (const InvocationInfo& info, const bool async)
  106. {
  107. ApplicationCommandTarget* target = this;
  108. int depth = 0;
  109. while (target != nullptr)
  110. {
  111. if (target->tryToInvoke (info, async))
  112. return true;
  113. target = target->getNextCommandTarget();
  114. ++depth;
  115. jassert (depth < 100); // could be a recursive command chain??
  116. jassert (target != this); // definitely a recursive command chain!
  117. if (depth > 100 || target == this)
  118. break;
  119. }
  120. if (target == nullptr)
  121. {
  122. target = JUCEApplication::getInstance();
  123. if (target != nullptr)
  124. return target->tryToInvoke (info, async);
  125. }
  126. return false;
  127. }
  128. bool ApplicationCommandTarget::invokeDirectly (const CommandID commandID, const bool asynchronously)
  129. {
  130. ApplicationCommandTarget::InvocationInfo info (commandID);
  131. info.invocationMethod = ApplicationCommandTarget::InvocationInfo::direct;
  132. return invoke (info, asynchronously);
  133. }
  134. //==============================================================================
  135. ApplicationCommandTarget::InvocationInfo::InvocationInfo (const CommandID command)
  136. : commandID (command),
  137. commandFlags (0),
  138. invocationMethod (direct),
  139. originatingComponent (nullptr),
  140. isKeyDown (false),
  141. millisecsSinceKeyPressed (0)
  142. {
  143. }