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_ios_Windowing.mm 10KB

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