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.

759 lines
28KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - 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 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-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. extern bool isIOSAppActive;
  21. struct AppInactivityCallback // NB: careful, this declaration is duplicated in other modules
  22. {
  23. virtual ~AppInactivityCallback() {}
  24. virtual void appBecomingInactive() = 0;
  25. };
  26. // This is an internal list of callbacks (but currently used between modules)
  27. Array<AppInactivityCallback*> appBecomingInactiveCallbacks;
  28. }
  29. #if JUCE_PUSH_NOTIFICATIONS && defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  30. @interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate, UNUserNotificationCenterDelegate>
  31. #else
  32. @interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate>
  33. #endif
  34. {
  35. UIBackgroundTaskIdentifier appSuspendTask;
  36. }
  37. @property (strong, nonatomic) UIWindow *window;
  38. - (id) init;
  39. - (void) dealloc;
  40. - (void) applicationDidFinishLaunching: (UIApplication*) application;
  41. - (void) applicationWillTerminate: (UIApplication*) application;
  42. - (void) applicationDidEnterBackground: (UIApplication*) application;
  43. - (void) applicationWillEnterForeground: (UIApplication*) application;
  44. - (void) applicationDidBecomeActive: (UIApplication*) application;
  45. - (void) applicationWillResignActive: (UIApplication*) application;
  46. - (void) application: (UIApplication*) application handleEventsForBackgroundURLSession: (NSString*) identifier
  47. completionHandler: (void (^)(void)) completionHandler;
  48. - (void) applicationDidReceiveMemoryWarning: (UIApplication *) application;
  49. #if JUCE_PUSH_NOTIFICATIONS
  50. - (void) application: (UIApplication*) application didRegisterUserNotificationSettings: (UIUserNotificationSettings*) notificationSettings;
  51. - (void) application: (UIApplication*) application didRegisterForRemoteNotificationsWithDeviceToken: (NSData*) deviceToken;
  52. - (void) application: (UIApplication*) application didFailToRegisterForRemoteNotificationsWithError: (NSError*) error;
  53. - (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo;
  54. - (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo
  55. fetchCompletionHandler: (void (^)(UIBackgroundFetchResult result)) completionHandler;
  56. - (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier
  57. forRemoteNotification: (NSDictionary*) userInfo withResponseInfo: (NSDictionary*) responseInfo
  58. completionHandler: (void(^)()) completionHandler;
  59. - (void) application: (UIApplication*) application didReceiveLocalNotification: (UILocalNotification*) notification;
  60. - (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier
  61. forLocalNotification: (UILocalNotification*) notification completionHandler: (void(^)()) completionHandler;
  62. - (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier
  63. forLocalNotification: (UILocalNotification*) notification withResponseInfo: (NSDictionary*) responseInfo
  64. completionHandler: (void(^)()) completionHandler;
  65. #if defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  66. - (void) userNotificationCenter: (UNUserNotificationCenter*) center willPresentNotification: (UNNotification*) notification
  67. withCompletionHandler: (void (^)(UNNotificationPresentationOptions options)) completionHandler;
  68. - (void) userNotificationCenter: (UNUserNotificationCenter*) center didReceiveNotificationResponse: (UNNotificationResponse*) response
  69. withCompletionHandler: (void(^)())completionHandler;
  70. #endif
  71. #endif
  72. @end
  73. @implementation JuceAppStartupDelegate
  74. NSObject* _pushNotificationsDelegate;
  75. - (id) init
  76. {
  77. self = [super init];
  78. appSuspendTask = UIBackgroundTaskInvalid;
  79. #if JUCE_PUSH_NOTIFICATIONS && defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  80. [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  81. #endif
  82. return self;
  83. }
  84. - (void) dealloc
  85. {
  86. [super dealloc];
  87. }
  88. - (void) applicationDidFinishLaunching: (UIApplication*) application
  89. {
  90. ignoreUnused (application);
  91. initialiseJuce_GUI();
  92. if (auto* app = JUCEApplicationBase::createInstance())
  93. {
  94. if (! app->initialiseApp())
  95. exit (app->shutdownApp());
  96. }
  97. else
  98. {
  99. jassertfalse; // you must supply an application object for an iOS app!
  100. }
  101. }
  102. - (void) applicationWillTerminate: (UIApplication*) application
  103. {
  104. ignoreUnused (application);
  105. JUCEApplicationBase::appWillTerminateByForce();
  106. }
  107. - (void) applicationDidEnterBackground: (UIApplication*) application
  108. {
  109. if (auto* app = JUCEApplicationBase::getInstance())
  110. {
  111. #if JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK
  112. appSuspendTask = [application beginBackgroundTaskWithName:@"JUCE Suspend Task" expirationHandler:^{
  113. if (appSuspendTask != UIBackgroundTaskInvalid)
  114. {
  115. [application endBackgroundTask:appSuspendTask];
  116. appSuspendTask = UIBackgroundTaskInvalid;
  117. }
  118. }];
  119. MessageManager::callAsync ([app] { app->suspended(); });
  120. #else
  121. ignoreUnused (application);
  122. app->suspended();
  123. #endif
  124. }
  125. }
  126. - (void) applicationWillEnterForeground: (UIApplication*) application
  127. {
  128. ignoreUnused (application);
  129. if (auto* app = JUCEApplicationBase::getInstance())
  130. app->resumed();
  131. }
  132. - (void) applicationDidBecomeActive: (UIApplication*) application
  133. {
  134. application.applicationIconBadgeNumber = 0;
  135. isIOSAppActive = true;
  136. }
  137. - (void) applicationWillResignActive: (UIApplication*) application
  138. {
  139. ignoreUnused (application);
  140. isIOSAppActive = false;
  141. for (int i = appBecomingInactiveCallbacks.size(); --i >= 0;)
  142. appBecomingInactiveCallbacks.getReference(i)->appBecomingInactive();
  143. }
  144. - (void) application: (UIApplication*) application handleEventsForBackgroundURLSession: (NSString*)identifier
  145. completionHandler: (void (^)(void))completionHandler
  146. {
  147. ignoreUnused (application);
  148. URL::DownloadTask::juce_iosURLSessionNotify (nsStringToJuce (identifier));
  149. completionHandler();
  150. }
  151. - (void) applicationDidReceiveMemoryWarning: (UIApplication*) application
  152. {
  153. ignoreUnused (application);
  154. if (auto* app = JUCEApplicationBase::getInstance())
  155. app->memoryWarningReceived();
  156. }
  157. - (void) setPushNotificationsDelegateToUse: (NSObject*) delegate
  158. {
  159. _pushNotificationsDelegate = delegate;
  160. }
  161. #if JUCE_PUSH_NOTIFICATIONS
  162. - (void) application: (UIApplication*) application didRegisterUserNotificationSettings: (UIUserNotificationSettings*) notificationSettings
  163. {
  164. ignoreUnused (application);
  165. SEL selector = NSSelectorFromString (@"application:didRegisterUserNotificationSettings:");
  166. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  167. {
  168. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  169. [invocation setSelector: selector];
  170. [invocation setTarget: _pushNotificationsDelegate];
  171. [invocation setArgument: &application atIndex:2];
  172. [invocation setArgument: &notificationSettings atIndex:3];
  173. [invocation invoke];
  174. }
  175. }
  176. - (void) application: (UIApplication*) application didRegisterForRemoteNotificationsWithDeviceToken: (NSData*) deviceToken
  177. {
  178. ignoreUnused (application);
  179. SEL selector = NSSelectorFromString (@"application:didRegisterForRemoteNotificationsWithDeviceToken:");
  180. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  181. {
  182. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  183. [invocation setSelector: selector];
  184. [invocation setTarget: _pushNotificationsDelegate];
  185. [invocation setArgument: &application atIndex:2];
  186. [invocation setArgument: &deviceToken atIndex:3];
  187. [invocation invoke];
  188. }
  189. }
  190. - (void) application: (UIApplication*) application didFailToRegisterForRemoteNotificationsWithError: (NSError*) error
  191. {
  192. ignoreUnused (application);
  193. SEL selector = NSSelectorFromString (@"application:didFailToRegisterForRemoteNotificationsWithError:");
  194. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  195. {
  196. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  197. [invocation setSelector: selector];
  198. [invocation setTarget: _pushNotificationsDelegate];
  199. [invocation setArgument: &application atIndex:2];
  200. [invocation setArgument: &error atIndex:3];
  201. [invocation invoke];
  202. }
  203. }
  204. - (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo
  205. {
  206. ignoreUnused (application);
  207. SEL selector = NSSelectorFromString (@"application:didReceiveRemoteNotification:");
  208. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  209. {
  210. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  211. [invocation setSelector: selector];
  212. [invocation setTarget: _pushNotificationsDelegate];
  213. [invocation setArgument: &application atIndex:2];
  214. [invocation setArgument: &userInfo atIndex:3];
  215. [invocation invoke];
  216. }
  217. }
  218. - (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo
  219. fetchCompletionHandler: (void (^)(UIBackgroundFetchResult result)) completionHandler
  220. {
  221. ignoreUnused (application);
  222. SEL selector = NSSelectorFromString (@"application:didReceiveRemoteNotification:fetchCompletionHandler:");
  223. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  224. {
  225. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  226. [invocation setSelector: selector];
  227. [invocation setTarget: _pushNotificationsDelegate];
  228. [invocation setArgument: &application atIndex:2];
  229. [invocation setArgument: &userInfo atIndex:3];
  230. [invocation setArgument: &completionHandler atIndex:4];
  231. [invocation invoke];
  232. }
  233. }
  234. - (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier
  235. forRemoteNotification: (NSDictionary*) userInfo withResponseInfo: (NSDictionary*) responseInfo
  236. completionHandler: (void(^)()) completionHandler
  237. {
  238. ignoreUnused (application);
  239. SEL selector = NSSelectorFromString (@"application:handleActionWithIdentifier:forRemoteNotification:withResponseInfo:completionHandler:");
  240. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  241. {
  242. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  243. [invocation setSelector: selector];
  244. [invocation setTarget: _pushNotificationsDelegate];
  245. [invocation setArgument: &application atIndex:2];
  246. [invocation setArgument: &identifier atIndex:3];
  247. [invocation setArgument: &userInfo atIndex:4];
  248. [invocation setArgument: &responseInfo atIndex:5];
  249. [invocation setArgument: &completionHandler atIndex:6];
  250. [invocation invoke];
  251. }
  252. }
  253. - (void) application: (UIApplication*) application didReceiveLocalNotification: (UILocalNotification*) notification
  254. {
  255. ignoreUnused (application);
  256. SEL selector = NSSelectorFromString (@"application:didReceiveLocalNotification:");
  257. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  258. {
  259. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  260. [invocation setSelector: selector];
  261. [invocation setTarget: _pushNotificationsDelegate];
  262. [invocation setArgument: &application atIndex:2];
  263. [invocation setArgument: &notification atIndex:3];
  264. [invocation invoke];
  265. }
  266. }
  267. - (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier
  268. forLocalNotification: (UILocalNotification*) notification completionHandler: (void(^)()) completionHandler
  269. {
  270. ignoreUnused (application);
  271. SEL selector = NSSelectorFromString (@"application:handleActionWithIdentifier:forLocalNotification:completionHandler:");
  272. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  273. {
  274. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  275. [invocation setSelector: selector];
  276. [invocation setTarget: _pushNotificationsDelegate];
  277. [invocation setArgument: &application atIndex:2];
  278. [invocation setArgument: &identifier atIndex:3];
  279. [invocation setArgument: &notification atIndex:4];
  280. [invocation setArgument: &completionHandler atIndex:5];
  281. [invocation invoke];
  282. }
  283. }
  284. - (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier
  285. forLocalNotification: (UILocalNotification*) notification withResponseInfo: (NSDictionary*) responseInfo
  286. completionHandler: (void(^)()) completionHandler
  287. {
  288. ignoreUnused (application);
  289. SEL selector = NSSelectorFromString (@"application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:");
  290. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  291. {
  292. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  293. [invocation setSelector: selector];
  294. [invocation setTarget: _pushNotificationsDelegate];
  295. [invocation setArgument: &application atIndex:2];
  296. [invocation setArgument: &identifier atIndex:3];
  297. [invocation setArgument: &notification atIndex:4];
  298. [invocation setArgument: &responseInfo atIndex:5];
  299. [invocation setArgument: &completionHandler atIndex:6];
  300. [invocation invoke];
  301. }
  302. }
  303. #if defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  304. - (void) userNotificationCenter: (UNUserNotificationCenter*) center willPresentNotification: (UNNotification*) notification
  305. withCompletionHandler: (void (^)(UNNotificationPresentationOptions options)) completionHandler
  306. {
  307. ignoreUnused (center);
  308. SEL selector = NSSelectorFromString (@"userNotificationCenter:willPresentNotification:withCompletionHandler:");
  309. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  310. {
  311. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  312. [invocation setSelector: selector];
  313. [invocation setTarget: _pushNotificationsDelegate];
  314. [invocation setArgument: &center atIndex:2];
  315. [invocation setArgument: &notification atIndex:3];
  316. [invocation setArgument: &completionHandler atIndex:4];
  317. [invocation invoke];
  318. }
  319. }
  320. - (void) userNotificationCenter: (UNUserNotificationCenter*) center didReceiveNotificationResponse: (UNNotificationResponse*) response
  321. withCompletionHandler: (void(^)()) completionHandler
  322. {
  323. ignoreUnused (center);
  324. SEL selector = NSSelectorFromString (@"userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:");
  325. if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector])
  326. {
  327. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]];
  328. [invocation setSelector: selector];
  329. [invocation setTarget: _pushNotificationsDelegate];
  330. [invocation setArgument: &center atIndex:2];
  331. [invocation setArgument: &response atIndex:3];
  332. [invocation setArgument: &completionHandler atIndex:4];
  333. [invocation invoke];
  334. }
  335. }
  336. #endif
  337. #endif
  338. @end
  339. namespace juce
  340. {
  341. int juce_iOSMain (int argc, const char* argv[], void* customDelegatePtr);
  342. int juce_iOSMain (int argc, const char* argv[], void* customDelegatePtr)
  343. {
  344. Class delegateClass = (customDelegatePtr != nullptr ? reinterpret_cast<Class> (customDelegatePtr) : [JuceAppStartupDelegate class]);
  345. return UIApplicationMain (argc, const_cast<char**> (argv), nil, NSStringFromClass (delegateClass));
  346. }
  347. //==============================================================================
  348. void LookAndFeel::playAlertSound()
  349. {
  350. // TODO
  351. }
  352. //==============================================================================
  353. class iOSMessageBox;
  354. #if defined (__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
  355. #define JUCE_USE_NEW_IOS_ALERTWINDOW 1
  356. #endif
  357. #if ! JUCE_USE_NEW_IOS_ALERTWINDOW
  358. } // (juce namespace)
  359. @interface JuceAlertBoxDelegate : NSObject <UIAlertViewDelegate>
  360. {
  361. @public
  362. iOSMessageBox* owner;
  363. }
  364. - (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex;
  365. @end
  366. namespace juce
  367. {
  368. #endif
  369. class iOSMessageBox
  370. {
  371. public:
  372. iOSMessageBox (const String& title, const String& message,
  373. NSString* button1, NSString* button2, NSString* button3,
  374. ModalComponentManager::Callback* cb, const bool async)
  375. : result (0), resultReceived (false), callback (cb), isAsync (async)
  376. {
  377. #if JUCE_USE_NEW_IOS_ALERTWINDOW
  378. if (currentlyFocusedPeer != nullptr)
  379. {
  380. UIAlertController* alert = [UIAlertController alertControllerWithTitle: juceStringToNS (title)
  381. message: juceStringToNS (message)
  382. preferredStyle: UIAlertControllerStyleAlert];
  383. addButton (alert, button1, 0);
  384. addButton (alert, button2, 1);
  385. addButton (alert, button3, 2);
  386. [currentlyFocusedPeer->controller presentViewController: alert
  387. animated: YES
  388. completion: nil];
  389. }
  390. else
  391. {
  392. // Since iOS8, alert windows need to be associated with a window, so you need to
  393. // have at least one window on screen when you use this
  394. jassertfalse;
  395. }
  396. #else
  397. delegate = [[JuceAlertBoxDelegate alloc] init];
  398. delegate->owner = this;
  399. alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title)
  400. message: juceStringToNS (message)
  401. delegate: delegate
  402. cancelButtonTitle: button1
  403. otherButtonTitles: button2, button3, nil];
  404. [alert retain];
  405. [alert show];
  406. #endif
  407. }
  408. ~iOSMessageBox()
  409. {
  410. #if ! JUCE_USE_NEW_IOS_ALERTWINDOW
  411. [alert release];
  412. [delegate release];
  413. #endif
  414. }
  415. int getResult()
  416. {
  417. jassert (callback == nullptr);
  418. JUCE_AUTORELEASEPOOL
  419. {
  420. #if JUCE_USE_NEW_IOS_ALERTWINDOW
  421. while (! resultReceived)
  422. #else
  423. while (! (alert.hidden || resultReceived))
  424. #endif
  425. [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
  426. }
  427. return result;
  428. }
  429. void buttonClicked (const int buttonIndex) noexcept
  430. {
  431. result = buttonIndex;
  432. resultReceived = true;
  433. if (callback != nullptr)
  434. callback->modalStateFinished (result);
  435. if (isAsync)
  436. delete this;
  437. }
  438. private:
  439. int result;
  440. bool resultReceived;
  441. std::unique_ptr<ModalComponentManager::Callback> callback;
  442. const bool isAsync;
  443. #if JUCE_USE_NEW_IOS_ALERTWINDOW
  444. void addButton (UIAlertController* alert, NSString* text, int index)
  445. {
  446. if (text != nil)
  447. [alert addAction: [UIAlertAction actionWithTitle: text
  448. style: UIAlertActionStyleDefault
  449. handler: ^(UIAlertAction*) { this->buttonClicked (index); }]];
  450. }
  451. #else
  452. UIAlertView* alert;
  453. JuceAlertBoxDelegate* delegate;
  454. #endif
  455. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox)
  456. };
  457. #if ! JUCE_USE_NEW_IOS_ALERTWINDOW
  458. } // (juce namespace)
  459. @implementation JuceAlertBoxDelegate
  460. - (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex
  461. {
  462. owner->buttonClicked ((int) buttonIndex);
  463. alertView.hidden = true;
  464. }
  465. @end
  466. namespace juce
  467. {
  468. #endif
  469. //==============================================================================
  470. #if JUCE_MODAL_LOOPS_PERMITTED
  471. void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType /*iconType*/,
  472. const String& title, const String& message,
  473. Component* /*associatedComponent*/)
  474. {
  475. JUCE_AUTORELEASEPOOL
  476. {
  477. iOSMessageBox mb (title, message, @"OK", nil, nil, nullptr, false);
  478. ignoreUnused (mb.getResult());
  479. }
  480. }
  481. #endif
  482. void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType /*iconType*/,
  483. const String& title, const String& message,
  484. Component* /*associatedComponent*/,
  485. ModalComponentManager::Callback* callback)
  486. {
  487. new iOSMessageBox (title, message, @"OK", nil, nil, callback, true);
  488. }
  489. bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/,
  490. const String& title, const String& message,
  491. Component* /*associatedComponent*/,
  492. ModalComponentManager::Callback* callback)
  493. {
  494. std::unique_ptr<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"OK",
  495. nil, callback, callback != nullptr));
  496. if (callback == nullptr)
  497. return mb->getResult() == 1;
  498. mb.release();
  499. return false;
  500. }
  501. int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/,
  502. const String& title, const String& message,
  503. Component* /*associatedComponent*/,
  504. ModalComponentManager::Callback* callback)
  505. {
  506. std::unique_ptr<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != nullptr));
  507. if (callback == nullptr)
  508. return mb->getResult();
  509. mb.release();
  510. return 0;
  511. }
  512. int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/,
  513. const String& title, const String& message,
  514. Component* /*associatedComponent*/,
  515. ModalComponentManager::Callback* callback)
  516. {
  517. std::unique_ptr<iOSMessageBox> mb (new iOSMessageBox (title, message, @"No", @"Yes", nil, callback, callback != nullptr));
  518. if (callback == nullptr)
  519. return mb->getResult();
  520. mb.release();
  521. return 0;
  522. }
  523. //==============================================================================
  524. bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray&, bool, Component*, std::function<void()>)
  525. {
  526. jassertfalse; // no such thing on iOS!
  527. return false;
  528. }
  529. bool DragAndDropContainer::performExternalDragDropOfText (const String&, Component*, std::function<void()>)
  530. {
  531. jassertfalse; // no such thing on iOS!
  532. return false;
  533. }
  534. //==============================================================================
  535. void Desktop::setScreenSaverEnabled (const bool isEnabled)
  536. {
  537. if (! SystemStats::isRunningInAppExtensionSandbox())
  538. [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled];
  539. }
  540. bool Desktop::isScreenSaverEnabled()
  541. {
  542. if (SystemStats::isRunningInAppExtensionSandbox())
  543. return true;
  544. return ! [[UIApplication sharedApplication] isIdleTimerDisabled];
  545. }
  546. //==============================================================================
  547. bool juce_areThereAnyAlwaysOnTopWindows()
  548. {
  549. return false;
  550. }
  551. //==============================================================================
  552. Image juce_createIconForFile (const File&)
  553. {
  554. return Image();
  555. }
  556. //==============================================================================
  557. void SystemClipboard::copyTextToClipboard (const String& text)
  558. {
  559. [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text)
  560. forPasteboardType: @"public.text"];
  561. }
  562. String SystemClipboard::getTextFromClipboard()
  563. {
  564. return nsStringToJuce ([[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"]);
  565. }
  566. //==============================================================================
  567. bool MouseInputSource::SourceList::addSource()
  568. {
  569. addSource (sources.size(), MouseInputSource::InputSourceType::touch);
  570. return true;
  571. }
  572. bool MouseInputSource::SourceList::canUseTouch()
  573. {
  574. return true;
  575. }
  576. bool Desktop::canUseSemiTransparentWindows() noexcept
  577. {
  578. return true;
  579. }
  580. Point<float> MouseInputSource::getCurrentRawMousePosition()
  581. {
  582. return juce_lastMousePos;
  583. }
  584. void MouseInputSource::setRawMousePosition (Point<float>)
  585. {
  586. }
  587. double Desktop::getDefaultMasterScale()
  588. {
  589. return 1.0;
  590. }
  591. Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
  592. {
  593. UIInterfaceOrientation orientation = SystemStats::isRunningInAppExtensionSandbox() ? UIInterfaceOrientationPortrait
  594. : getWindowOrientation();
  595. return Orientations::convertToJuce (orientation);
  596. }
  597. void Displays::findDisplays (float masterScale)
  598. {
  599. JUCE_AUTORELEASEPOOL
  600. {
  601. UIScreen* s = [UIScreen mainScreen];
  602. Display d;
  603. d.userArea = d.totalArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s bounds])) / masterScale;
  604. d.isMain = true;
  605. d.scale = masterScale;
  606. if ([s respondsToSelector: @selector (scale)])
  607. d.scale *= s.scale;
  608. d.dpi = 160 * d.scale;
  609. displays.add (d);
  610. }
  611. }
  612. } // namespace juce