Skip to content

Commit

Permalink
iOS: Added optional sourceComponent parameter to ContentSharer::setPa…
Browse files Browse the repository at this point in the history
…rentComponent() to facilitate popover sourceRect calculation. Made popover repositioning use peer view bounds too (instead of UIScreen)
  • Loading branch information
amethystdeceiver committed Sep 20, 2020
1 parent fc49c84 commit d8ffe9e
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 16 deletions.
11 changes: 11 additions & 0 deletions modules/juce_core/native/juce_osx_ObjCHelpers.h
Expand Up @@ -193,6 +193,17 @@ NSRect makeNSRect (const RectangleType& r) noexcept
}
#endif

#if JUCE_IOS
template <typename RectangleType>
CGRect makeCGRect (const RectangleType& r) noexcept
{
return CGRectMake (static_cast<CGFloat> (r.getX()),
static_cast<CGFloat> (r.getY()),
static_cast<CGFloat> (r.getWidth()),
static_cast<CGFloat> (r.getHeight()));
}
#endif

#if JUCE_INTEL
template <typename T>
struct NeedsStret { static constexpr auto value = sizeof (T) > 16; };
Expand Down
3 changes: 2 additions & 1 deletion modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp
Expand Up @@ -150,8 +150,9 @@ JUCE_IMPLEMENT_SINGLETON (ContentSharer)
ContentSharer::ContentSharer() {}
ContentSharer::~ContentSharer() { clearSingletonInstance(); }

void ContentSharer::setParentComponent(Component* parentComponentToUse) {
void ContentSharer::setParentComponent(Component* parentComponentToUse, Component* sourceComponentToUse) {
parentComponent = parentComponentToUse;
sourceComponent = sourceComponentToUse;
}

void ContentSharer::shareFiles (const Array<URL>& files,
Expand Down
3 changes: 2 additions & 1 deletion modules/juce_gui_basics/filebrowser/juce_ContentSharer.h
Expand Up @@ -43,7 +43,7 @@ class JUCE_API ContentSharer : public DeletedAtShutdown
* Sets the parent component to be used in subsequent calls to iOS native sharer.
* Required to make ContentSharer work in AUv3 plugins.
*/
void setParentComponent(Component* parentComponentToUse);
void setParentComponent(Component* parentComponent, Component* sourceComponent = nullptr);

/** Shares the given files. Each URL should be either a full file path
or it should point to a resource within the application bundle. For
Expand Down Expand Up @@ -116,6 +116,7 @@ class JUCE_API ContentSharer : public DeletedAtShutdown
std::function<void (bool, String)> callback;

Component* parentComponent = nullptr;
Component::SafePointer<Component> sourceComponent;

#if JUCE_CONTENT_SHARING
struct Pimpl
Expand Down
42 changes: 28 additions & 14 deletions modules/juce_gui_basics/native/juce_ios_ContentSharer.cpp
Expand Up @@ -34,7 +34,9 @@ class ContentSharer::ContentSharerNativeImpl : public ContentSharer::Pimpl,
: owner (cs)
{
static PopoverDelegateClass cls;
popoverDelegate.reset ([cls.createInstance() init]);
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wobjc-method-access")
popoverDelegate.reset ([cls.createInstance() initWithContentSharerNativeImpl:this]);
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
}

~ContentSharerNativeImpl() override
Expand Down Expand Up @@ -161,13 +163,9 @@ class ContentSharer::ContentSharerNativeImpl : public ContentSharer::Pimpl,

if (isIPad())
{
controller.get().preferredContentSize = peer->view.frame.size;

auto bounds = peer->view.bounds;

auto* popoverController = controller.get().popoverPresentationController;
popoverController.sourceView = peer->view;
popoverController.sourceRect = CGRectMake (0.f, bounds.size.height - 10.f, bounds.size.width, 10.f);
popoverController.sourceRect = getPopoverSourceRect();
popoverController.canOverlapSourceViewRect = YES;
popoverController.delegate = popoverDelegate.get();
}
Expand All @@ -177,25 +175,41 @@ class ContentSharer::ContentSharerNativeImpl : public ContentSharer::Pimpl,
}
}

CGRect getPopoverSourceRect() {
auto bounds = peer->view.bounds;

return owner.sourceComponent == nullptr
? CGRectMake (0.f, bounds.size.height - 10.f, bounds.size.width, 10.f)
: makeCGRect (peer->getAreaCoveredBy (*owner.sourceComponent.getComponent()));
}

//==============================================================================
struct PopoverDelegateClass : public ObjCClass<NSObject<UIPopoverPresentationControllerDelegate>>
{
PopoverDelegateClass() : ObjCClass<NSObject<UIPopoverPresentationControllerDelegate>> ("PopoverDelegateClass_")
PopoverDelegateClass() : ObjCClass<NSObject<UIPopoverPresentationControllerDelegate>> ("PopoverDelegateClass_")
{
addIvar<ContentSharer::ContentSharerNativeImpl*>("nativeSharer");

JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
addMethod (@selector (initWithContentSharerNativeImpl:), initWithContentSharerNativeImpl, "@@:^v");
JUCE_END_IGNORE_WARNINGS_GCC_LIKE

addMethod (@selector (popoverPresentationController:willRepositionPopoverToRect:inView:), willRepositionPopover, "v@:@@@");

registerClass();
}

//==============================================================================
static void willRepositionPopover (id, SEL, UIPopoverPresentationController*, CGRect* rect, UIView*)
static id initWithContentSharerNativeImpl (id _self, SEL, ContentSharer::ContentSharerNativeImpl* nativeSharer)
{
auto screenBounds = [UIScreen mainScreen].bounds;
NSObject* self = sendSuperclassMessage<NSObject*> (_self, @selector (init));
object_setInstanceVariable (self, "nativeSharer", nativeSharer);
return self;
}

rect->origin.x = 0.f;
rect->origin.y = screenBounds.size.height - 10.f;
rect->size.width = screenBounds.size.width;
rect->size.height = 10.f;
//==============================================================================
static void willRepositionPopover (id self, SEL, UIPopoverPresentationController*, CGRect* rect, UIView*)
{
*rect = getIvar<ContentSharer::ContentSharerNativeImpl*> (self, "nativeSharer")->getPopoverSourceRect();
}
};

Expand Down

0 comments on commit d8ffe9e

Please sign in to comment.