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_android_Windowing.cpp 31KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  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. extern juce::JUCEApplicationBase* juce_CreateApplication(); // (from START_JUCE_APPLICATION)
  19. namespace juce
  20. {
  21. //==============================================================================
  22. JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, launchApp, void, (JNIEnv* env, jobject activity,
  23. jstring appFile, jstring appDataDir))
  24. {
  25. android.initialise (env, activity, appFile, appDataDir);
  26. DBG (SystemStats::getJUCEVersion());
  27. JUCEApplicationBase::createInstance = &juce_CreateApplication;
  28. initialiseJuce_GUI();
  29. JUCEApplicationBase* app = JUCEApplicationBase::createInstance();
  30. if (! app->initialiseApp())
  31. exit (app->getApplicationReturnValue());
  32. jassert (MessageManager::getInstance()->isThisTheMessageThread());
  33. }
  34. JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* env, jobject activity))
  35. {
  36. if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
  37. app->suspended();
  38. }
  39. JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, resumeApp, void, (JNIEnv* env, jobject activity))
  40. {
  41. if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
  42. app->resumed();
  43. }
  44. JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, quitApp, void, (JNIEnv* env, jobject activity))
  45. {
  46. JUCEApplicationBase::appWillTerminateByForce();
  47. android.shutdown (env);
  48. }
  49. //==============================================================================
  50. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
  51. METHOD (drawBitmap, "drawBitmap", "([IIIFFIIZLandroid/graphics/Paint;)V") \
  52. METHOD (getClipBounds, "getClipBounds", "()Landroid/graphics/Rect;")
  53. DECLARE_JNI_CLASS (CanvasMinimal, "android/graphics/Canvas");
  54. #undef JNI_CLASS_MEMBERS
  55. //==============================================================================
  56. #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
  57. METHOD (setViewName, "setViewName", "(Ljava/lang/String;)V") \
  58. METHOD (layout, "layout", "(IIII)V") \
  59. METHOD (getLeft, "getLeft", "()I") \
  60. METHOD (getTop, "getTop", "()I") \
  61. METHOD (getWidth, "getWidth", "()I") \
  62. METHOD (getHeight, "getHeight", "()I") \
  63. METHOD (getLocationOnScreen, "getLocationOnScreen", "([I)V") \
  64. METHOD (bringToFront, "bringToFront", "()V") \
  65. METHOD (requestFocus, "requestFocus", "()Z") \
  66. METHOD (setVisible, "setVisible", "(Z)V") \
  67. METHOD (isVisible, "isVisible", "()Z") \
  68. METHOD (hasFocus, "hasFocus", "()Z") \
  69. METHOD (invalidate, "invalidate", "(IIII)V") \
  70. METHOD (containsPoint, "containsPoint", "(II)Z") \
  71. METHOD (showKeyboard, "showKeyboard", "(Ljava/lang/String;)V") \
  72. METHOD (createGLView, "createGLView", "()L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$OpenGLView;") \
  73. DECLARE_JNI_CLASS (ComponentPeerView, JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView");
  74. #undef JNI_CLASS_MEMBERS
  75. //==============================================================================
  76. class AndroidComponentPeer : public ComponentPeer
  77. {
  78. public:
  79. AndroidComponentPeer (Component& comp, const int windowStyleFlags)
  80. : ComponentPeer (comp, windowStyleFlags),
  81. usingAndroidGraphics (false),
  82. fullScreen (false),
  83. sizeAllocated (0)
  84. {
  85. // NB: must not put this in the initialiser list, as it invokes a callback,
  86. // which will fail if the peer is only half-constructed.
  87. view = GlobalRef (android.activity.callObjectMethod (JuceAppActivity.createNewView,
  88. component.isOpaque(), (jlong) this));
  89. if (isFocused())
  90. handleFocusGain();
  91. }
  92. ~AndroidComponentPeer()
  93. {
  94. if (MessageManager::getInstance()->isThisTheMessageThread())
  95. {
  96. android.activity.callVoidMethod (JuceAppActivity.deleteView, view.get());
  97. }
  98. else
  99. {
  100. struct ViewDeleter : public CallbackMessage
  101. {
  102. ViewDeleter (const GlobalRef& view_) : view (view_) {}
  103. void messageCallback() override
  104. {
  105. android.activity.callVoidMethod (JuceAppActivity.deleteView, view.get());
  106. }
  107. private:
  108. GlobalRef view;
  109. };
  110. (new ViewDeleter (view))->post();
  111. }
  112. view.clear();
  113. }
  114. void* getNativeHandle() const override
  115. {
  116. return (void*) view.get();
  117. }
  118. void setVisible (bool shouldBeVisible) override
  119. {
  120. if (MessageManager::getInstance()->isThisTheMessageThread())
  121. {
  122. view.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible);
  123. }
  124. else
  125. {
  126. struct VisibilityChanger : public CallbackMessage
  127. {
  128. VisibilityChanger (const GlobalRef& view_, bool shouldBeVisible_)
  129. : view (view_), shouldBeVisible (shouldBeVisible_)
  130. {}
  131. void messageCallback() override
  132. {
  133. view.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible);
  134. }
  135. private:
  136. GlobalRef view;
  137. bool shouldBeVisible;
  138. };
  139. (new VisibilityChanger (view, shouldBeVisible))->post();
  140. }
  141. }
  142. void setTitle (const String& title) override
  143. {
  144. view.callVoidMethod (ComponentPeerView.setViewName, javaString (title).get());
  145. }
  146. void setBounds (const Rectangle<int>& r, bool isNowFullScreen) override
  147. {
  148. if (MessageManager::getInstance()->isThisTheMessageThread())
  149. {
  150. fullScreen = isNowFullScreen;
  151. view.callVoidMethod (ComponentPeerView.layout,
  152. r.getX(), r.getY(), r.getRight(), r.getBottom());
  153. }
  154. else
  155. {
  156. class ViewMover : public CallbackMessage
  157. {
  158. public:
  159. ViewMover (const GlobalRef& v, const Rectangle<int>& r) : view (v), bounds (r) {}
  160. void messageCallback() override
  161. {
  162. view.callVoidMethod (ComponentPeerView.layout,
  163. bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getBottom());
  164. }
  165. private:
  166. GlobalRef view;
  167. Rectangle<int> bounds;
  168. };
  169. (new ViewMover (view, r))->post();
  170. }
  171. }
  172. Rectangle<int> getBounds() const override
  173. {
  174. return Rectangle<int> (view.callIntMethod (ComponentPeerView.getLeft),
  175. view.callIntMethod (ComponentPeerView.getTop),
  176. view.callIntMethod (ComponentPeerView.getWidth),
  177. view.callIntMethod (ComponentPeerView.getHeight));
  178. }
  179. void handleScreenSizeChange()
  180. {
  181. ComponentPeer::handleScreenSizeChange();
  182. if (isFullScreen())
  183. setFullScreen (true);
  184. }
  185. Point<int> getScreenPosition() const
  186. {
  187. return Point<int> (view.callIntMethod (ComponentPeerView.getLeft),
  188. view.callIntMethod (ComponentPeerView.getTop));
  189. }
  190. Point<float> localToGlobal (Point<float> relativePosition) override
  191. {
  192. return relativePosition + getScreenPosition().toFloat();
  193. }
  194. Point<float> globalToLocal (Point<float> screenPosition) override
  195. {
  196. return screenPosition - getScreenPosition().toFloat();
  197. }
  198. void setMinimised (bool shouldBeMinimised) override
  199. {
  200. // n/a
  201. }
  202. bool isMinimised() const override
  203. {
  204. return false;
  205. }
  206. void setFullScreen (bool shouldBeFullScreen) override
  207. {
  208. Rectangle<int> r (shouldBeFullScreen ? Desktop::getInstance().getDisplays().getMainDisplay().userArea
  209. : lastNonFullscreenBounds);
  210. if ((! shouldBeFullScreen) && r.isEmpty())
  211. r = getBounds();
  212. // (can't call the component's setBounds method because that'll reset our fullscreen flag)
  213. if (! r.isEmpty())
  214. setBounds (r, shouldBeFullScreen);
  215. component.repaint();
  216. }
  217. bool isFullScreen() const override
  218. {
  219. return fullScreen;
  220. }
  221. void setIcon (const Image& newIcon) override
  222. {
  223. // n/a
  224. }
  225. bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override
  226. {
  227. return isPositiveAndBelow (localPos.x, component.getWidth())
  228. && isPositiveAndBelow (localPos.y, component.getHeight())
  229. && ((! trueIfInAChildWindow) || view.callBooleanMethod (ComponentPeerView.containsPoint,
  230. localPos.x, localPos.y));
  231. }
  232. BorderSize<int> getFrameSize() const override
  233. {
  234. // TODO
  235. return BorderSize<int>();
  236. }
  237. bool setAlwaysOnTop (bool alwaysOnTop) override
  238. {
  239. // TODO
  240. return false;
  241. }
  242. void toFront (bool makeActive) override
  243. {
  244. view.callVoidMethod (ComponentPeerView.bringToFront);
  245. if (makeActive)
  246. grabFocus();
  247. handleBroughtToFront();
  248. }
  249. void toBehind (ComponentPeer* other) override
  250. {
  251. // TODO
  252. }
  253. //==============================================================================
  254. void handleMouseDownCallback (int index, Point<float> pos, int64 time)
  255. {
  256. lastMousePos = pos;
  257. // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
  258. handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), time);
  259. if (isValidPeer (this))
  260. handleMouseDragCallback (index, pos, time);
  261. }
  262. void handleMouseDragCallback (int index, Point<float> pos, int64 time)
  263. {
  264. lastMousePos = pos;
  265. jassert (index < 64);
  266. touchesDown = (touchesDown | (1 << (index & 63)));
  267. currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
  268. handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons()
  269. .withFlags (ModifierKeys::leftButtonModifier), time);
  270. }
  271. void handleMouseUpCallback (int index, Point<float> pos, int64 time)
  272. {
  273. lastMousePos = pos;
  274. jassert (index < 64);
  275. touchesDown = (touchesDown & ~(1 << (index & 63)));
  276. if (touchesDown == 0)
  277. currentModifiers = currentModifiers.withoutMouseButtons();
  278. handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), time);
  279. }
  280. void handleKeyDownCallback (int k, int kc)
  281. {
  282. handleKeyPress (k, kc);
  283. }
  284. void handleKeyUpCallback (int k, int kc)
  285. {
  286. }
  287. //==============================================================================
  288. bool isFocused() const override
  289. {
  290. return view.callBooleanMethod (ComponentPeerView.hasFocus);
  291. }
  292. void grabFocus() override
  293. {
  294. view.callBooleanMethod (ComponentPeerView.requestFocus);
  295. }
  296. void handleFocusChangeCallback (bool hasFocus)
  297. {
  298. if (hasFocus)
  299. handleFocusGain();
  300. else
  301. handleFocusLoss();
  302. }
  303. static const char* getVirtualKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept
  304. {
  305. switch (type)
  306. {
  307. case TextInputTarget::textKeyboard: return "text";
  308. case TextInputTarget::numericKeyboard: return "number";
  309. case TextInputTarget::urlKeyboard: return "textUri";
  310. case TextInputTarget::emailAddressKeyboard: return "textEmailAddress";
  311. case TextInputTarget::phoneNumberKeyboard: return "phone";
  312. default: jassertfalse; break;
  313. }
  314. return "text";
  315. }
  316. void textInputRequired (Point<int>, TextInputTarget& target) override
  317. {
  318. view.callVoidMethod (ComponentPeerView.showKeyboard,
  319. javaString (getVirtualKeyboardType (target.getKeyboardType())).get());
  320. }
  321. void dismissPendingTextInput() override
  322. {
  323. view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get());
  324. }
  325. //==============================================================================
  326. void handlePaintCallback (JNIEnv* env, jobject canvas)
  327. {
  328. jobject rect = env->CallObjectMethod (canvas, CanvasMinimal.getClipBounds);
  329. const int left = env->GetIntField (rect, RectClass.left);
  330. const int top = env->GetIntField (rect, RectClass.top);
  331. const int right = env->GetIntField (rect, RectClass.right);
  332. const int bottom = env->GetIntField (rect, RectClass.bottom);
  333. env->DeleteLocalRef (rect);
  334. const Rectangle<int> clip (left, top, right - left, bottom - top);
  335. const int sizeNeeded = clip.getWidth() * clip.getHeight();
  336. if (sizeAllocated < sizeNeeded)
  337. {
  338. buffer.clear();
  339. sizeAllocated = sizeNeeded;
  340. buffer = GlobalRef (env->NewIntArray (sizeNeeded));
  341. }
  342. if (jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), 0))
  343. {
  344. {
  345. Image temp (new PreallocatedImage (clip.getWidth(), clip.getHeight(),
  346. dest, ! component.isOpaque()));
  347. {
  348. LowLevelGraphicsSoftwareRenderer g (temp);
  349. g.setOrigin (-clip.getPosition());
  350. handlePaint (g);
  351. }
  352. }
  353. env->ReleaseIntArrayElements ((jintArray) buffer.get(), dest, 0);
  354. env->CallVoidMethod (canvas, CanvasMinimal.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(),
  355. (jfloat) clip.getX(), (jfloat) clip.getY(),
  356. clip.getWidth(), clip.getHeight(), true, (jobject) 0);
  357. }
  358. }
  359. void repaint (const Rectangle<int>& area) override
  360. {
  361. if (MessageManager::getInstance()->isThisTheMessageThread())
  362. {
  363. view.callVoidMethod (ComponentPeerView.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom());
  364. }
  365. else
  366. {
  367. struct ViewRepainter : public CallbackMessage
  368. {
  369. ViewRepainter (const GlobalRef& view_, const Rectangle<int>& area_)
  370. : view (view_), area (area_) {}
  371. void messageCallback() override
  372. {
  373. view.callVoidMethod (ComponentPeerView.invalidate, area.getX(), area.getY(),
  374. area.getRight(), area.getBottom());
  375. }
  376. private:
  377. GlobalRef view;
  378. const Rectangle<int> area;
  379. };
  380. (new ViewRepainter (view, area))->post();
  381. }
  382. }
  383. void performAnyPendingRepaintsNow() override
  384. {
  385. // TODO
  386. }
  387. void setAlpha (float newAlpha) override
  388. {
  389. // TODO
  390. }
  391. StringArray getAvailableRenderingEngines() override
  392. {
  393. return StringArray ("Software Renderer");
  394. }
  395. //==============================================================================
  396. static ModifierKeys currentModifiers;
  397. static Point<float> lastMousePos;
  398. static int64 touchesDown;
  399. private:
  400. //==============================================================================
  401. GlobalRef view;
  402. GlobalRef buffer;
  403. bool usingAndroidGraphics, fullScreen;
  404. int sizeAllocated;
  405. class PreallocatedImage : public ImagePixelData
  406. {
  407. public:
  408. PreallocatedImage (const int width_, const int height_, jint* data_, bool hasAlpha_)
  409. : ImagePixelData (Image::ARGB, width_, height_), data (data_), hasAlpha (hasAlpha_)
  410. {
  411. if (hasAlpha_)
  412. zeromem (data_, width * height * sizeof (jint));
  413. }
  414. ~PreallocatedImage()
  415. {
  416. if (hasAlpha)
  417. {
  418. PixelARGB* pix = (PixelARGB*) data;
  419. for (int i = width * height; --i >= 0;)
  420. {
  421. pix->unpremultiply();
  422. ++pix;
  423. }
  424. }
  425. }
  426. ImageType* createType() const override { return new SoftwareImageType(); }
  427. LowLevelGraphicsContext* createLowLevelContext() override { return new LowLevelGraphicsSoftwareRenderer (Image (this)); }
  428. void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode mode)
  429. {
  430. bm.lineStride = width * sizeof (jint);
  431. bm.pixelStride = sizeof (jint);
  432. bm.pixelFormat = Image::ARGB;
  433. bm.data = (uint8*) (data + x + y * width);
  434. }
  435. ImagePixelData* clone()
  436. {
  437. PreallocatedImage* s = new PreallocatedImage (width, height, 0, hasAlpha);
  438. s->allocatedData.malloc (sizeof (jint) * width * height);
  439. s->data = s->allocatedData;
  440. memcpy (s->data, data, sizeof (jint) * width * height);
  441. return s;
  442. }
  443. private:
  444. jint* data;
  445. HeapBlock<jint> allocatedData;
  446. bool hasAlpha;
  447. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PreallocatedImage)
  448. };
  449. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer)
  450. };
  451. ModifierKeys AndroidComponentPeer::currentModifiers = 0;
  452. Point<float> AndroidComponentPeer::lastMousePos;
  453. int64 AndroidComponentPeer::touchesDown = 0;
  454. //==============================================================================
  455. #define JUCE_VIEW_CALLBACK(returnType, javaMethodName, params, juceMethodInvocation) \
  456. JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024ComponentPeerView), javaMethodName, returnType, params) \
  457. { \
  458. if (AndroidComponentPeer* peer = (AndroidComponentPeer*) (pointer_sized_uint) host) \
  459. peer->juceMethodInvocation; \
  460. }
  461. JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject view, jlong host, jobject canvas), handlePaintCallback (env, canvas))
  462. JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point<float> ((float) x, (float) y), (int64) time))
  463. JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point<float> ((float) x, (float) y), (int64) time))
  464. JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point<float> ((float) x, (float) y), (int64) time))
  465. JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject view, jlong host), handleMovedOrResized())
  466. JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject view, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus))
  467. JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject view, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc))
  468. JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject view, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc))
  469. //==============================================================================
  470. ComponentPeer* Component::createNewPeer (int styleFlags, void*)
  471. {
  472. return new AndroidComponentPeer (*this, styleFlags);
  473. }
  474. jobject createOpenGLView (ComponentPeer* peer)
  475. {
  476. jobject parentView = static_cast <jobject> (peer->getNativeHandle());
  477. return getEnv()->CallObjectMethod (parentView, ComponentPeerView.createGLView);
  478. }
  479. //==============================================================================
  480. bool Desktop::canUseSemiTransparentWindows() noexcept
  481. {
  482. return true;
  483. }
  484. double Desktop::getDefaultMasterScale()
  485. {
  486. return 1.0;
  487. }
  488. Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
  489. {
  490. // TODO
  491. return upright;
  492. }
  493. bool MouseInputSource::SourceList::addSource()
  494. {
  495. addSource (sources.size(), false);
  496. return true;
  497. }
  498. Point<float> MouseInputSource::getCurrentRawMousePosition()
  499. {
  500. return AndroidComponentPeer::lastMousePos;
  501. }
  502. void MouseInputSource::setRawMousePosition (Point<float>)
  503. {
  504. // not needed
  505. }
  506. //==============================================================================
  507. bool KeyPress::isKeyCurrentlyDown (const int keyCode)
  508. {
  509. // TODO
  510. return false;
  511. }
  512. void ModifierKeys::updateCurrentModifiers() noexcept
  513. {
  514. currentModifiers = AndroidComponentPeer::currentModifiers;
  515. }
  516. ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept
  517. {
  518. return AndroidComponentPeer::currentModifiers;
  519. }
  520. //==============================================================================
  521. // TODO
  522. JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() { return true; }
  523. JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {}
  524. JUCE_API void JUCE_CALLTYPE Process::hide() {}
  525. //==============================================================================
  526. void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
  527. const String& title, const String& message,
  528. Component* associatedComponent,
  529. ModalComponentManager::Callback* callback)
  530. {
  531. android.activity.callVoidMethod (JuceAppActivity.showMessageBox, javaString (title).get(),
  532. javaString (message).get(), (jlong) (pointer_sized_int) callback);
  533. }
  534. bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
  535. const String& title, const String& message,
  536. Component* associatedComponent,
  537. ModalComponentManager::Callback* callback)
  538. {
  539. jassert (callback != nullptr); // on android, all alerts must be non-modal!!
  540. android.activity.callVoidMethod (JuceAppActivity.showOkCancelBox, javaString (title).get(),
  541. javaString (message).get(), (jlong) (pointer_sized_int) callback);
  542. return false;
  543. }
  544. int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
  545. const String& title, const String& message,
  546. Component* associatedComponent,
  547. ModalComponentManager::Callback* callback)
  548. {
  549. jassert (callback != nullptr); // on android, all alerts must be non-modal!!
  550. android.activity.callVoidMethod (JuceAppActivity.showYesNoCancelBox, javaString (title).get(),
  551. javaString (message).get(), (jlong) (pointer_sized_int) callback);
  552. return 0;
  553. }
  554. JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, alertDismissed, void, (JNIEnv* env, jobject activity,
  555. jlong callbackAsLong, jint result))
  556. {
  557. if (ModalComponentManager::Callback* callback = (ModalComponentManager::Callback*) callbackAsLong)
  558. {
  559. callback->modalStateFinished (result);
  560. delete callback;
  561. }
  562. }
  563. //==============================================================================
  564. void Desktop::setScreenSaverEnabled (const bool isEnabled)
  565. {
  566. // TODO
  567. }
  568. bool Desktop::isScreenSaverEnabled()
  569. {
  570. return true;
  571. }
  572. //==============================================================================
  573. void Desktop::setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars)
  574. {
  575. // TODO
  576. }
  577. //==============================================================================
  578. bool juce_areThereAnyAlwaysOnTopWindows()
  579. {
  580. return false;
  581. }
  582. //==============================================================================
  583. void Desktop::Displays::findDisplays (float masterScale)
  584. {
  585. Display d;
  586. d.userArea = d.totalArea = Rectangle<int> (android.screenWidth,
  587. android.screenHeight) / masterScale;
  588. d.isMain = true;
  589. d.scale = masterScale;
  590. d.dpi = android.dpi;
  591. displays.add (d);
  592. }
  593. JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, setScreenSize, void, (JNIEnv* env, jobject activity,
  594. jint screenWidth, jint screenHeight,
  595. jint dpi))
  596. {
  597. android.screenWidth = screenWidth;
  598. android.screenHeight = screenHeight;
  599. android.dpi = dpi;
  600. const_cast<Desktop::Displays&> (Desktop::getInstance().getDisplays()).refresh();
  601. }
  602. //==============================================================================
  603. Image juce_createIconForFile (const File& file)
  604. {
  605. return Image::null;
  606. }
  607. //==============================================================================
  608. void* CustomMouseCursorInfo::create() const { return nullptr; }
  609. void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorType) { return nullptr; }
  610. void MouseCursor::deleteMouseCursor (void* const /*cursorHandle*/, const bool /*isStandard*/) {}
  611. //==============================================================================
  612. void MouseCursor::showInWindow (ComponentPeer*) const {}
  613. void MouseCursor::showInAllWindows() const {}
  614. //==============================================================================
  615. bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove)
  616. {
  617. return false;
  618. }
  619. bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
  620. {
  621. return false;
  622. }
  623. //==============================================================================
  624. void LookAndFeel::playAlertSound()
  625. {
  626. }
  627. //==============================================================================
  628. void SystemClipboard::copyTextToClipboard (const String& text)
  629. {
  630. const LocalRef<jstring> t (javaString (text));
  631. android.activity.callVoidMethod (JuceAppActivity.setClipboardContent, t.get());
  632. }
  633. String SystemClipboard::getTextFromClipboard()
  634. {
  635. const LocalRef<jstring> text ((jstring) android.activity.callObjectMethod (JuceAppActivity.getClipboardContent));
  636. return juceString (text);
  637. }
  638. //==============================================================================
  639. const int extendedKeyModifier = 0x10000;
  640. const int KeyPress::spaceKey = ' ';
  641. const int KeyPress::returnKey = 66;
  642. const int KeyPress::escapeKey = 4;
  643. const int KeyPress::backspaceKey = 67;
  644. const int KeyPress::leftKey = extendedKeyModifier + 1;
  645. const int KeyPress::rightKey = extendedKeyModifier + 2;
  646. const int KeyPress::upKey = extendedKeyModifier + 3;
  647. const int KeyPress::downKey = extendedKeyModifier + 4;
  648. const int KeyPress::pageUpKey = extendedKeyModifier + 5;
  649. const int KeyPress::pageDownKey = extendedKeyModifier + 6;
  650. const int KeyPress::endKey = extendedKeyModifier + 7;
  651. const int KeyPress::homeKey = extendedKeyModifier + 8;
  652. const int KeyPress::deleteKey = extendedKeyModifier + 9;
  653. const int KeyPress::insertKey = -1;
  654. const int KeyPress::tabKey = 61;
  655. const int KeyPress::F1Key = extendedKeyModifier + 10;
  656. const int KeyPress::F2Key = extendedKeyModifier + 11;
  657. const int KeyPress::F3Key = extendedKeyModifier + 12;
  658. const int KeyPress::F4Key = extendedKeyModifier + 13;
  659. const int KeyPress::F5Key = extendedKeyModifier + 14;
  660. const int KeyPress::F6Key = extendedKeyModifier + 16;
  661. const int KeyPress::F7Key = extendedKeyModifier + 17;
  662. const int KeyPress::F8Key = extendedKeyModifier + 18;
  663. const int KeyPress::F9Key = extendedKeyModifier + 19;
  664. const int KeyPress::F10Key = extendedKeyModifier + 20;
  665. const int KeyPress::F11Key = extendedKeyModifier + 21;
  666. const int KeyPress::F12Key = extendedKeyModifier + 22;
  667. const int KeyPress::F13Key = extendedKeyModifier + 23;
  668. const int KeyPress::F14Key = extendedKeyModifier + 24;
  669. const int KeyPress::F15Key = extendedKeyModifier + 25;
  670. const int KeyPress::F16Key = extendedKeyModifier + 26;
  671. const int KeyPress::numberPad0 = extendedKeyModifier + 27;
  672. const int KeyPress::numberPad1 = extendedKeyModifier + 28;
  673. const int KeyPress::numberPad2 = extendedKeyModifier + 29;
  674. const int KeyPress::numberPad3 = extendedKeyModifier + 30;
  675. const int KeyPress::numberPad4 = extendedKeyModifier + 31;
  676. const int KeyPress::numberPad5 = extendedKeyModifier + 32;
  677. const int KeyPress::numberPad6 = extendedKeyModifier + 33;
  678. const int KeyPress::numberPad7 = extendedKeyModifier + 34;
  679. const int KeyPress::numberPad8 = extendedKeyModifier + 35;
  680. const int KeyPress::numberPad9 = extendedKeyModifier + 36;
  681. const int KeyPress::numberPadAdd = extendedKeyModifier + 37;
  682. const int KeyPress::numberPadSubtract = extendedKeyModifier + 38;
  683. const int KeyPress::numberPadMultiply = extendedKeyModifier + 39;
  684. const int KeyPress::numberPadDivide = extendedKeyModifier + 40;
  685. const int KeyPress::numberPadSeparator = extendedKeyModifier + 41;
  686. const int KeyPress::numberPadDecimalPoint = extendedKeyModifier + 42;
  687. const int KeyPress::numberPadEquals = extendedKeyModifier + 43;
  688. const int KeyPress::numberPadDelete = extendedKeyModifier + 44;
  689. const int KeyPress::playKey = extendedKeyModifier + 45;
  690. const int KeyPress::stopKey = extendedKeyModifier + 46;
  691. const int KeyPress::fastForwardKey = extendedKeyModifier + 47;
  692. const int KeyPress::rewindKey = extendedKeyModifier + 48;