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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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
  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), 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 && alert.superview != nil)
  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. if (callback != nullptr)
  116. callback->modalStateFinished (result);
  117. if (isAsync)
  118. delete this;
  119. }
  120. private:
  121. int result;
  122. JuceAlertBoxDelegate* delegate;
  123. UIAlertView* alert;
  124. ScopedPointer<ModalComponentManager::Callback> callback;
  125. const bool isYesNo, isAsync;
  126. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox)
  127. };
  128. } // (juce namespace)
  129. @implementation JuceAlertBoxDelegate
  130. - (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex
  131. {
  132. owner->buttonClicked (buttonIndex);
  133. alertView.hidden = true;
  134. }
  135. @end
  136. namespace juce
  137. {
  138. //==============================================================================
  139. #if JUCE_MODAL_LOOPS_PERMITTED
  140. void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType /*iconType*/,
  141. const String& title, const String& message,
  142. Component* /*associatedComponent*/)
  143. {
  144. JUCE_AUTORELEASEPOOL
  145. {
  146. iOSMessageBox mb (title, message, @"OK", nil, nil, nullptr, false);
  147. (void) mb.getResult();
  148. }
  149. }
  150. #endif
  151. void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType /*iconType*/,
  152. const String& title, const String& message,
  153. Component* /*associatedComponent*/,
  154. ModalComponentManager::Callback* callback)
  155. {
  156. new iOSMessageBox (title, message, @"OK", nil, nil, callback, true);
  157. }
  158. bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/,
  159. const String& title, const String& message,
  160. Component* /*associatedComponent*/,
  161. ModalComponentManager::Callback* callback)
  162. {
  163. ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"OK",
  164. nil, callback, callback != nullptr));
  165. if (callback == nullptr)
  166. return mb->getResult() == 1;
  167. mb.release();
  168. return false;
  169. }
  170. int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/,
  171. const String& title, const String& message,
  172. Component* /*associatedComponent*/,
  173. ModalComponentManager::Callback* callback)
  174. {
  175. ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != nullptr));
  176. if (callback == nullptr)
  177. return mb->getResult();
  178. mb.release();
  179. return 0;
  180. }
  181. //==============================================================================
  182. bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray&, bool)
  183. {
  184. jassertfalse; // no such thing on iOS!
  185. return false;
  186. }
  187. bool DragAndDropContainer::performExternalDragDropOfText (const String&)
  188. {
  189. jassertfalse; // no such thing on iOS!
  190. return false;
  191. }
  192. //==============================================================================
  193. void Desktop::setScreenSaverEnabled (const bool isEnabled)
  194. {
  195. [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled];
  196. }
  197. bool Desktop::isScreenSaverEnabled()
  198. {
  199. return ! [[UIApplication sharedApplication] isIdleTimerDisabled];
  200. }
  201. //==============================================================================
  202. bool juce_areThereAnyAlwaysOnTopWindows()
  203. {
  204. return false;
  205. }
  206. //==============================================================================
  207. Image juce_createIconForFile (const File&)
  208. {
  209. return Image::null;
  210. }
  211. //==============================================================================
  212. void SystemClipboard::copyTextToClipboard (const String& text)
  213. {
  214. [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text)
  215. forPasteboardType: @"public.text"];
  216. }
  217. String SystemClipboard::getTextFromClipboard()
  218. {
  219. NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"];
  220. return text == nil ? String::empty
  221. : nsStringToJuce (text);
  222. }
  223. //==============================================================================
  224. bool MouseInputSource::SourceList::addSource()
  225. {
  226. addSource (sources.size(), false);
  227. return true;
  228. }
  229. bool Desktop::canUseSemiTransparentWindows() noexcept
  230. {
  231. return true;
  232. }
  233. Point<int> MouseInputSource::getCurrentRawMousePosition()
  234. {
  235. return juce_lastMousePos;
  236. }
  237. void MouseInputSource::setRawMousePosition (Point<int>)
  238. {
  239. }
  240. double Desktop::getDefaultMasterScale()
  241. {
  242. return 1.0;
  243. }
  244. Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
  245. {
  246. return Orientations::convertToJuce ([[UIApplication sharedApplication] statusBarOrientation]);
  247. }
  248. void Desktop::Displays::findDisplays (float masterScale)
  249. {
  250. JUCE_AUTORELEASEPOOL
  251. {
  252. UIScreen* s = [UIScreen mainScreen];
  253. Display d;
  254. d.userArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s applicationFrame])) / masterScale;
  255. d.totalArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s bounds])) / masterScale;
  256. d.isMain = true;
  257. d.scale = masterScale;
  258. if ([s respondsToSelector: @selector (scale)])
  259. d.scale *= s.scale;
  260. d.dpi = 160 * d.scale;
  261. displays.add (d);
  262. }
  263. }