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_FocusOutline.cpp 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  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 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. //==============================================================================
  21. struct OutlineWindowComponent : public Component
  22. {
  23. OutlineWindowComponent (Component* c, FocusOutline::OutlineWindowProperties& p)
  24. : target (c), props (p)
  25. {
  26. setVisible (true);
  27. setInterceptsMouseClicks (false, false);
  28. if (target->isOnDesktop())
  29. {
  30. setSize (1, 1);
  31. addToDesktop (ComponentPeer::windowIgnoresMouseClicks
  32. | ComponentPeer::windowIsTemporary
  33. | ComponentPeer::windowIgnoresKeyPresses);
  34. }
  35. else if (auto* parent = target->getParentComponent())
  36. {
  37. auto targetIndex = parent->getIndexOfChildComponent (target);
  38. parent->addChildComponent (this, targetIndex + 1);
  39. }
  40. }
  41. void paint (Graphics& g) override
  42. {
  43. if (target != nullptr)
  44. props.drawOutline (g, getWidth(), getHeight());
  45. }
  46. void resized() override
  47. {
  48. repaint();
  49. }
  50. float getDesktopScaleFactor() const override
  51. {
  52. return target != nullptr ? target->getDesktopScaleFactor()
  53. : Component::getDesktopScaleFactor();
  54. }
  55. private:
  56. WeakReference<Component> target;
  57. FocusOutline::OutlineWindowProperties& props;
  58. JUCE_DECLARE_NON_COPYABLE (OutlineWindowComponent)
  59. };
  60. //==============================================================================
  61. FocusOutline::FocusOutline (std::unique_ptr<OutlineWindowProperties> props)
  62. : properties (std::move (props))
  63. {
  64. }
  65. FocusOutline::~FocusOutline()
  66. {
  67. if (owner != nullptr)
  68. owner->removeComponentListener (this);
  69. if (lastParentComp != nullptr)
  70. lastParentComp->removeComponentListener (this);
  71. }
  72. void FocusOutline::setOwner (Component* componentToFollow)
  73. {
  74. if (componentToFollow != owner)
  75. {
  76. if (owner != nullptr)
  77. owner->removeComponentListener (this);
  78. owner = componentToFollow;
  79. if (owner != nullptr)
  80. owner->addComponentListener (this);
  81. updateParent();
  82. updateOutlineWindow();
  83. }
  84. }
  85. void FocusOutline::componentMovedOrResized (Component& c, bool, bool)
  86. {
  87. if (owner == &c)
  88. updateOutlineWindow();
  89. }
  90. void FocusOutline::componentBroughtToFront (Component& c)
  91. {
  92. if (owner == &c)
  93. updateOutlineWindow();
  94. }
  95. void FocusOutline::componentParentHierarchyChanged (Component& c)
  96. {
  97. if (owner == &c)
  98. {
  99. updateParent();
  100. updateOutlineWindow();
  101. }
  102. }
  103. void FocusOutline::componentVisibilityChanged (Component& c)
  104. {
  105. if (owner == &c)
  106. updateOutlineWindow();
  107. }
  108. void FocusOutline::updateParent()
  109. {
  110. lastParentComp = (owner != nullptr ? owner->getParentComponent()
  111. : nullptr);
  112. }
  113. void FocusOutline::updateOutlineWindow()
  114. {
  115. if (reentrant)
  116. return;
  117. const ScopedValueSetter<bool> setter (reentrant, true);
  118. if (owner == nullptr)
  119. {
  120. outlineWindow = nullptr;
  121. return;
  122. }
  123. if (owner->isShowing()
  124. && owner->getWidth() > 0 && owner->getHeight() > 0)
  125. {
  126. if (outlineWindow == nullptr)
  127. outlineWindow = std::make_unique<OutlineWindowComponent> (owner, *properties);
  128. WeakReference<Component> deletionChecker (outlineWindow.get());
  129. outlineWindow->setAlwaysOnTop (owner->isAlwaysOnTop());
  130. if (deletionChecker == nullptr)
  131. return;
  132. const auto windowBounds = [this]
  133. {
  134. const auto bounds = properties->getOutlineBounds (*owner);
  135. if (lastParentComp != nullptr)
  136. return lastParentComp->getLocalArea (nullptr, bounds);
  137. return bounds;
  138. }();
  139. outlineWindow->setBounds (windowBounds);
  140. }
  141. else
  142. {
  143. outlineWindow = nullptr;
  144. }
  145. }
  146. } // namespace juce