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.

361 lines
11KB

  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. extern bool isIOSAppActive;
  18. } // (juce namespace)
  19. @interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate>
  20. {
  21. }
  22. - (void) applicationDidFinishLaunching: (UIApplication*) application;
  23. - (void) applicationWillTerminate: (UIApplication*) application;
  24. - (void) applicationDidEnterBackground: (UIApplication*) application;
  25. - (void) applicationWillEnterForeground: (UIApplication*) application;
  26. - (void) applicationDidBecomeActive: (UIApplication*) application;
  27. - (void) applicationWillResignActive: (UIApplication*) application;
  28. @end
  29. @implementation JuceAppStartupDelegate
  30. - (void) applicationDidFinishLaunching: (UIApplication*) application
  31. {
  32. ignoreUnused (application);
  33. initialiseJuce_GUI();
  34. if (JUCEApplicationBase* app = JUCEApplicationBase::createInstance())
  35. {
  36. if (! app->initialiseApp())
  37. exit (app->shutdownApp());
  38. }
  39. else
  40. {
  41. jassertfalse; // you must supply an application object for an iOS app!
  42. }
  43. }
  44. - (void) applicationWillTerminate: (UIApplication*) application
  45. {
  46. ignoreUnused (application);
  47. JUCEApplicationBase::appWillTerminateByForce();
  48. }
  49. - (void) applicationDidEnterBackground: (UIApplication*) application
  50. {
  51. ignoreUnused (application);
  52. if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
  53. app->suspended();
  54. }
  55. - (void) applicationWillEnterForeground: (UIApplication*) application
  56. {
  57. ignoreUnused (application);
  58. if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
  59. app->resumed();
  60. }
  61. - (void) applicationDidBecomeActive: (UIApplication*) application
  62. {
  63. ignoreUnused (application);
  64. isIOSAppActive = true;
  65. }
  66. - (void) applicationWillResignActive: (UIApplication*) application
  67. {
  68. ignoreUnused (application);
  69. isIOSAppActive = false;
  70. }
  71. @end
  72. namespace juce
  73. {
  74. int juce_iOSMain (int argc, const char* argv[]);
  75. int juce_iOSMain (int argc, const char* argv[])
  76. {
  77. return UIApplicationMain (argc, const_cast<char**> (argv), nil, @"JuceAppStartupDelegate");
  78. }
  79. //==============================================================================
  80. void LookAndFeel::playAlertSound()
  81. {
  82. //xxx
  83. //AudioServicesPlaySystemSound ();
  84. }
  85. //==============================================================================
  86. class iOSMessageBox;
  87. } // (juce namespace)
  88. @interface JuceAlertBoxDelegate : NSObject <UIAlertViewDelegate>
  89. {
  90. @public
  91. iOSMessageBox* owner;
  92. }
  93. - (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex;
  94. @end
  95. namespace juce
  96. {
  97. class iOSMessageBox
  98. {
  99. public:
  100. iOSMessageBox (const String& title, const String& message,
  101. NSString* button1, NSString* button2, NSString* button3,
  102. ModalComponentManager::Callback* cb, const bool async)
  103. : result (0), resultReceived (false), delegate (nil), alert (nil),
  104. callback (cb), isYesNo (button3 != nil), isAsync (async)
  105. {
  106. delegate = [[JuceAlertBoxDelegate alloc] init];
  107. delegate->owner = this;
  108. alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title)
  109. message: juceStringToNS (message)
  110. delegate: delegate
  111. cancelButtonTitle: button1
  112. otherButtonTitles: button2, button3, nil];
  113. [alert retain];
  114. [alert show];
  115. }
  116. ~iOSMessageBox()
  117. {
  118. [alert release];
  119. [delegate release];
  120. }
  121. int getResult()
  122. {
  123. jassert (callback == nullptr);
  124. JUCE_AUTORELEASEPOOL
  125. {
  126. while (! (alert.hidden || resultReceived))
  127. [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
  128. }
  129. return result;
  130. }
  131. void buttonClicked (const int buttonIndex) noexcept
  132. {
  133. result = buttonIndex;
  134. resultReceived = true;
  135. if (callback != nullptr)
  136. callback->modalStateFinished (result);
  137. if (isAsync)
  138. delete this;
  139. }
  140. private:
  141. int result;
  142. bool resultReceived;
  143. JuceAlertBoxDelegate* delegate;
  144. UIAlertView* alert;
  145. ScopedPointer<ModalComponentManager::Callback> callback;
  146. const bool isYesNo, isAsync;
  147. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox)
  148. };
  149. } // (juce namespace)
  150. @implementation JuceAlertBoxDelegate
  151. - (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex
  152. {
  153. owner->buttonClicked ((int) buttonIndex);
  154. alertView.hidden = true;
  155. }
  156. @end
  157. namespace juce
  158. {
  159. //==============================================================================
  160. #if JUCE_MODAL_LOOPS_PERMITTED
  161. void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType /*iconType*/,
  162. const String& title, const String& message,
  163. Component* /*associatedComponent*/)
  164. {
  165. JUCE_AUTORELEASEPOOL
  166. {
  167. iOSMessageBox mb (title, message, @"OK", nil, nil, nullptr, false);
  168. ignoreUnused (mb.getResult());
  169. }
  170. }
  171. #endif
  172. void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType /*iconType*/,
  173. const String& title, const String& message,
  174. Component* /*associatedComponent*/,
  175. ModalComponentManager::Callback* callback)
  176. {
  177. new iOSMessageBox (title, message, @"OK", nil, nil, callback, true);
  178. }
  179. bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/,
  180. const String& title, const String& message,
  181. Component* /*associatedComponent*/,
  182. ModalComponentManager::Callback* callback)
  183. {
  184. ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"OK",
  185. nil, callback, callback != nullptr));
  186. if (callback == nullptr)
  187. return mb->getResult() == 1;
  188. mb.release();
  189. return false;
  190. }
  191. int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/,
  192. const String& title, const String& message,
  193. Component* /*associatedComponent*/,
  194. ModalComponentManager::Callback* callback)
  195. {
  196. ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != nullptr));
  197. if (callback == nullptr)
  198. return mb->getResult();
  199. mb.release();
  200. return 0;
  201. }
  202. //==============================================================================
  203. bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray&, bool)
  204. {
  205. jassertfalse; // no such thing on iOS!
  206. return false;
  207. }
  208. bool DragAndDropContainer::performExternalDragDropOfText (const String&)
  209. {
  210. jassertfalse; // no such thing on iOS!
  211. return false;
  212. }
  213. //==============================================================================
  214. void Desktop::setScreenSaverEnabled (const bool isEnabled)
  215. {
  216. [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled];
  217. }
  218. bool Desktop::isScreenSaverEnabled()
  219. {
  220. return ! [[UIApplication sharedApplication] isIdleTimerDisabled];
  221. }
  222. //==============================================================================
  223. bool juce_areThereAnyAlwaysOnTopWindows()
  224. {
  225. return false;
  226. }
  227. //==============================================================================
  228. Image juce_createIconForFile (const File&)
  229. {
  230. return Image::null;
  231. }
  232. //==============================================================================
  233. void SystemClipboard::copyTextToClipboard (const String& text)
  234. {
  235. [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text)
  236. forPasteboardType: @"public.text"];
  237. }
  238. String SystemClipboard::getTextFromClipboard()
  239. {
  240. if (NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"])
  241. return nsStringToJuce (text);
  242. return String();
  243. }
  244. //==============================================================================
  245. bool MouseInputSource::SourceList::addSource()
  246. {
  247. addSource (sources.size(), false);
  248. return true;
  249. }
  250. bool Desktop::canUseSemiTransparentWindows() noexcept
  251. {
  252. return true;
  253. }
  254. Point<float> MouseInputSource::getCurrentRawMousePosition()
  255. {
  256. return juce_lastMousePos;
  257. }
  258. void MouseInputSource::setRawMousePosition (Point<float>)
  259. {
  260. }
  261. double Desktop::getDefaultMasterScale()
  262. {
  263. return 1.0;
  264. }
  265. Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
  266. {
  267. return Orientations::convertToJuce ([[UIApplication sharedApplication] statusBarOrientation]);
  268. }
  269. void Desktop::Displays::findDisplays (float masterScale)
  270. {
  271. JUCE_AUTORELEASEPOOL
  272. {
  273. UIScreen* s = [UIScreen mainScreen];
  274. Display d;
  275. d.userArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s applicationFrame])) / masterScale;
  276. d.totalArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s bounds])) / masterScale;
  277. d.isMain = true;
  278. d.scale = masterScale;
  279. if ([s respondsToSelector: @selector (scale)])
  280. d.scale *= s.scale;
  281. d.dpi = 160 * d.scale;
  282. displays.add (d);
  283. }
  284. }