The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

326 lines
9.8KB

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