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_mac_NSViewComponent.mm 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. class NSViewAttachment : public ReferenceCountedObject,
  21. public ComponentMovementWatcher
  22. {
  23. public:
  24. NSViewAttachment (NSView* v, Component& comp)
  25. : ComponentMovementWatcher (&comp),
  26. view (v), owner (comp),
  27. currentPeer (nullptr)
  28. {
  29. [view retain];
  30. [view setPostsFrameChangedNotifications: YES];
  31. updateAlpha();
  32. if (owner.isShowing())
  33. componentPeerChanged();
  34. }
  35. ~NSViewAttachment() override
  36. {
  37. removeFromParent();
  38. [view release];
  39. }
  40. void componentMovedOrResized (Component& comp, bool wasMoved, bool wasResized) override
  41. {
  42. ComponentMovementWatcher::componentMovedOrResized (comp, wasMoved, wasResized);
  43. // The ComponentMovementWatcher version of this method avoids calling
  44. // us when the top-level comp is resized, but if we're listening to the
  45. // top-level comp we still want the NSView to track its size.
  46. if (comp.isOnDesktop() && wasResized)
  47. componentMovedOrResized (wasMoved, wasResized);
  48. }
  49. void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override
  50. {
  51. if (auto* peer = owner.getTopLevelComponent()->getPeer())
  52. {
  53. const auto newArea = peer->getAreaCoveredBy (owner);
  54. if (convertToRectInt ([view frame]) != newArea)
  55. [view setFrame: makeNSRect (newArea)];
  56. }
  57. }
  58. void componentPeerChanged() override
  59. {
  60. auto* peer = owner.getPeer();
  61. if (currentPeer != peer)
  62. {
  63. currentPeer = peer;
  64. if (peer != nullptr)
  65. {
  66. auto peerView = (NSView*) peer->getNativeHandle();
  67. [peerView addSubview: view];
  68. componentMovedOrResized (false, false);
  69. }
  70. else
  71. {
  72. removeFromParent();
  73. }
  74. }
  75. [view setHidden: ! owner.isShowing()];
  76. }
  77. void componentVisibilityChanged() override
  78. {
  79. componentPeerChanged();
  80. }
  81. void updateAlpha()
  82. {
  83. [view setAlphaValue: (CGFloat) owner.getAlpha()];
  84. }
  85. NSView* const view;
  86. using Ptr = ReferenceCountedObjectPtr<NSViewAttachment>;
  87. private:
  88. Component& owner;
  89. ComponentPeer* currentPeer;
  90. NSViewFrameWatcher frameWatcher { view, [this] { owner.childBoundsChanged (nullptr); } };
  91. void removeFromParent()
  92. {
  93. if ([view superview] != nil)
  94. [view removeFromSuperview]; // Must be careful not to call this unless it's required - e.g. some Apple AU views
  95. // override the call and use it as a sign that they're being deleted, which breaks everything..
  96. }
  97. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewAttachment)
  98. };
  99. //==============================================================================
  100. NSViewComponent::NSViewComponent() = default;
  101. NSViewComponent::~NSViewComponent() = default;
  102. void NSViewComponent::setView (void* view)
  103. {
  104. if (view != getView())
  105. {
  106. auto old = attachment;
  107. attachment = nullptr;
  108. if (view != nullptr)
  109. attachment = attachViewToComponent (*this, view);
  110. old = nullptr;
  111. }
  112. }
  113. void* NSViewComponent::getView() const
  114. {
  115. return attachment != nullptr ? static_cast<NSViewAttachment*> (attachment.get())->view
  116. : nullptr;
  117. }
  118. void NSViewComponent::resizeToFitView()
  119. {
  120. if (attachment != nullptr)
  121. {
  122. auto* view = static_cast<NSViewAttachment*> (attachment.get())->view;
  123. auto r = [view frame];
  124. setBounds (Rectangle<int> ((int) r.size.width, (int) r.size.height));
  125. if (auto* peer = getTopLevelComponent()->getPeer())
  126. {
  127. const auto position = peer->getAreaCoveredBy (*this).getPosition();
  128. [view setFrameOrigin: convertToCGPoint (position)];
  129. }
  130. }
  131. }
  132. void NSViewComponent::paint (Graphics&) {}
  133. void NSViewComponent::alphaChanged()
  134. {
  135. if (attachment != nullptr)
  136. (static_cast<NSViewAttachment*> (attachment.get()))->updateAlpha();
  137. }
  138. ReferenceCountedObject* NSViewComponent::attachViewToComponent (Component& comp, void* view)
  139. {
  140. return new NSViewAttachment ((NSView*) view, comp);
  141. }
  142. } // namespace juce