mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
2108 lines
110 KiB
C++
2108 lines
110 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library.
|
|
Copyright (c) 2020 - Raw Material Software Limited
|
|
|
|
JUCE is an open source library subject to commercial or open-source
|
|
licensing.
|
|
|
|
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
|
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
|
|
|
End User License Agreement: www.juce.com/juce-6-licence
|
|
Privacy Policy: www.juce.com/juce-privacy-policy
|
|
|
|
Or: You may also use this code under the terms of the GPL v3 (see
|
|
www.gnu.org/licenses).
|
|
|
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
|
DISCLAIMED.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
namespace juce
|
|
{
|
|
// This byte-code is generated from native/java/com/rmsl/juce/ComponentPeerView.java with min sdk version 16
|
|
// See juce_core/native/java/README.txt on how to generate this byte-code.
|
|
static const uint8 javaComponentPeerView[] =
|
|
{ 31,139,8,8,217,126,216,97,0,3,74,97,118,97,68,101,120,66,121,116,101,67,111,100,101,46,100,101,120,0,165,155,11,124,212,213,149,199,207,189,255,255,204,36,147,215,100,18,146,64,18,50,9,175,16,72,102,8,111,19,148,183,6,18,64,18,16,18,171,76,146,127,146,
|
|
129,201,127,134,153,73,72,124,21,149,143,96,173,21,45,82,21,109,177,165,182,110,109,215,90,219,181,22,181,93,93,215,173,186,85,107,87,180,90,31,69,197,150,90,180,86,105,117,117,127,247,49,147,9,143,210,118,195,231,59,231,252,207,125,223,123,238,185,247,
|
|
63,33,221,214,144,59,48,115,54,125,253,172,186,247,86,249,42,166,141,253,112,218,236,231,195,83,47,91,120,183,99,205,99,123,255,208,184,125,22,81,148,136,134,214,207,242,146,254,57,56,147,168,146,41,251,60,240,129,73,180,4,242,121,7,81,9,228,241,12,162,
|
|
203,33,31,200,36,66,18,237,207,33,218,52,153,200,151,75,212,94,78,116,33,184,24,116,130,205,192,6,215,128,107,193,245,96,55,216,3,110,1,251,192,215,192,195,224,5,240,18,248,13,120,3,188,5,126,15,142,129,63,131,156,241,232,7,184,8,12,131,61,224,126,240,
|
|
60,248,12,140,173,32,170,7,231,130,207,129,65,112,19,120,8,60,7,142,130,137,62,162,101,96,8,220,3,14,131,194,74,162,6,208,11,246,130,23,64,69,21,198,2,46,7,119,130,159,129,195,192,152,64,84,14,2,160,13,92,2,110,0,247,129,199,193,155,224,47,160,122,34,
|
|
209,82,208,1,194,224,10,176,3,220,4,110,6,183,130,253,224,0,184,7,220,7,126,12,30,1,143,129,39,192,211,224,57,240,2,120,5,188,14,222,1,71,193,123,224,35,240,9,48,38,17,101,130,28,224,5,227,64,37,152,4,166,130,5,96,45,184,8,108,6,131,224,42,240,37,112,
|
|
27,184,11,220,7,30,6,79,130,151,192,49,112,28,56,176,174,121,160,6,204,6,243,192,74,208,10,58,64,23,8,131,56,216,14,174,7,119,128,123,192,15,193,65,240,34,120,21,188,1,222,1,89,83,136,138,64,57,152,6,230,129,117,32,14,174,0,55,128,187,192,15,193,35,224,
|
|
73,240,34,56,12,254,2,114,171,137,202,192,20,48,15,44,7,171,193,6,96,129,109,96,39,184,29,124,7,252,4,188,8,94,5,111,130,35,128,79,37,42,0,147,192,92,176,28,180,130,16,184,4,92,7,110,3,223,2,7,193,227,224,85,240,14,248,35,120,31,124,10,140,26,248,15,
|
|
152,0,102,129,115,64,11,184,0,92,12,182,128,1,176,27,236,3,7,192,67,224,41,240,75,240,6,56,2,142,129,227,224,99,192,166,17,185,65,33,168,2,53,32,0,230,128,38,112,17,136,130,171,193,126,240,3,240,56,120,21,188,13,62,4,206,233,40,15,42,64,29,152,11,22,
|
|
129,53,224,34,208,3,34,96,24,108,7,95,4,251,192,215,193,207,192,99,224,105,240,30,200,171,197,122,129,82,48,13,204,7,107,65,39,136,130,47,128,59,193,195,224,73,240,18,120,11,124,8,204,58,204,51,152,0,234,65,51,88,11,54,128,77,160,15,216,32,14,134,193,
|
|
213,224,26,112,61,216,11,110,7,223,5,15,128,159,131,23,193,155,224,8,248,61,248,35,248,19,248,8,124,12,62,3,78,196,36,132,40,202,2,69,160,152,84,220,26,11,198,129,82,80,6,16,82,8,97,131,16,22,8,97,128,176,237,9,91,156,176,125,9,219,138,224,254,4,119,
|
|
37,184,28,193,101,8,203,77,88,30,194,244,18,166,133,48,60,66,115,228,7,1,48,3,212,3,132,79,66,88,165,217,96,14,152,171,227,232,124,112,22,104,0,141,96,1,56,27,156,3,22,130,69,96,49,169,88,187,12,156,7,54,128,78,208,5,186,129,69,106,124,201,31,151,150,
|
|
247,151,170,49,51,253,236,214,186,176,139,121,224,218,158,173,245,131,176,231,165,213,229,213,115,246,152,182,231,106,123,158,78,75,234,99,180,238,209,243,42,234,47,208,250,83,186,108,73,90,157,98,174,159,47,85,186,152,227,151,117,158,201,105,245,76,
|
|
213,245,228,107,253,48,244,66,173,31,45,85,109,138,57,255,64,215,35,244,79,116,61,181,186,158,49,122,29,204,50,213,31,177,22,217,101,106,14,235,117,158,38,173,139,182,86,104,189,16,121,86,106,93,180,219,172,117,31,236,45,90,15,64,95,165,245,70,232,171,
|
|
181,126,30,244,53,90,111,131,126,190,214,47,132,222,170,245,238,52,123,56,77,79,64,95,167,245,203,210,236,187,210,244,221,105,250,45,105,117,238,79,179,127,27,122,155,214,239,77,179,31,40,29,209,197,156,175,213,186,152,207,100,61,15,164,229,23,243,185,
|
|
94,235,63,133,253,2,173,63,145,150,231,80,154,254,90,153,242,205,153,122,110,55,106,253,8,236,237,90,63,150,166,127,2,189,67,235,25,226,142,160,117,15,244,207,105,189,76,220,27,180,94,13,253,34,173,7,210,236,194,199,54,105,125,30,236,65,173,159,151,150,
|
|
191,173,92,248,57,163,97,82,50,135,137,125,63,137,226,164,228,191,73,201,232,65,45,15,106,249,144,150,15,107,249,136,206,255,115,18,177,194,71,110,166,100,1,19,113,99,38,253,23,9,89,65,89,76,196,16,149,94,161,211,43,144,82,196,132,207,23,209,86,225,79,
|
|
216,117,15,72,89,65,79,72,89,78,191,148,114,38,189,35,101,22,29,149,62,63,153,150,67,58,16,129,254,68,98,127,58,233,70,41,199,208,126,200,76,68,49,67,202,89,244,33,137,125,94,45,159,179,180,61,11,17,225,35,57,110,245,156,135,118,111,144,178,136,110,210,
|
|
207,183,106,121,167,152,127,157,46,228,110,41,77,186,89,63,239,147,210,160,219,73,237,211,59,180,252,170,148,140,238,210,242,91,36,246,37,167,189,82,78,165,111,146,216,131,147,100,251,5,136,120,191,149,114,62,29,150,178,148,222,38,177,95,107,105,64,203,
|
|
15,72,196,233,57,244,31,36,226,72,54,61,47,229,88,122,159,68,44,81,227,24,139,136,43,100,25,162,230,143,164,172,161,191,74,121,14,153,114,93,2,50,189,28,51,176,67,202,18,218,165,159,175,149,114,30,189,43,215,171,78,230,27,143,26,95,39,177,78,170,92,5,
|
|
236,61,90,246,74,153,71,125,82,142,37,7,83,210,41,215,115,178,204,239,195,10,133,164,244,211,102,41,23,209,22,41,11,40,172,101,191,148,11,201,150,114,44,13,105,121,185,148,115,233,74,41,43,233,58,41,189,116,189,148,57,244,37,41,157,180,71,251,205,94,
|
|
157,254,21,41,103,211,45,82,102,210,215,164,116,211,215,117,190,111,72,153,65,7,164,84,235,32,252,236,110,41,203,232,95,180,252,142,150,247,104,127,252,174,148,227,233,123,218,254,175,186,220,189,90,126,95,203,251,164,244,209,15,164,108,160,251,165,156,
|
|
67,143,105,249,184,148,19,232,5,41,171,232,144,150,47,106,249,146,78,255,181,126,126,89,203,87,164,204,165,223,72,57,133,94,149,114,58,189,38,229,217,244,134,148,202,143,124,218,143,196,243,155,122,255,188,37,165,242,43,145,255,136,148,141,116,76,202,
|
|
122,58,174,229,95,164,156,70,159,72,57,142,62,149,114,6,125,166,159,137,169,124,76,75,206,84,186,193,212,188,20,50,113,110,21,211,109,36,228,98,122,84,238,87,78,63,147,50,159,188,76,156,77,202,95,167,97,103,124,153,196,249,100,208,21,82,114,122,154,196,
|
|
25,85,72,255,78,226,190,48,86,251,171,218,83,201,51,19,175,88,116,33,98,220,21,250,208,26,175,237,226,204,19,49,93,164,39,32,239,208,233,21,186,252,180,180,242,59,144,126,175,78,247,145,58,87,197,153,120,143,46,191,7,242,144,78,23,119,129,169,208,3,245,
|
|
234,190,112,86,189,178,173,134,92,15,12,157,190,9,108,214,121,226,210,110,72,157,251,213,189,161,131,185,41,234,17,55,168,14,158,133,181,204,64,45,162,173,28,191,186,59,121,89,91,167,155,182,122,102,193,158,197,139,240,218,56,131,115,115,62,55,201,229,
|
|
201,167,182,206,44,218,234,171,160,24,118,191,200,215,214,165,242,26,148,101,110,93,51,135,22,15,184,249,124,254,135,207,108,143,24,143,203,83,253,182,169,219,159,224,87,119,152,42,204,104,212,115,153,28,173,104,91,244,187,214,175,238,96,167,107,219,
|
|
160,124,230,245,206,156,50,246,228,54,3,115,105,177,35,27,49,227,24,218,20,113,202,205,108,223,20,68,169,108,86,253,214,201,185,231,201,220,213,239,136,248,107,202,254,44,241,171,181,107,139,170,124,34,165,136,203,123,9,159,143,60,94,196,151,182,173,
|
|
238,244,116,206,118,176,155,93,119,109,115,206,199,200,16,215,143,25,232,175,24,227,106,191,136,247,152,89,111,14,198,184,13,54,47,93,232,201,150,119,180,12,60,137,177,110,240,171,179,182,192,89,72,85,60,27,249,196,44,180,197,115,168,109,102,46,217,158,
|
|
165,200,149,205,230,179,198,17,155,239,60,236,197,145,28,139,144,195,109,172,157,40,222,21,25,125,191,237,70,50,204,217,155,198,209,186,56,230,193,40,34,175,113,33,180,100,254,182,68,14,250,29,192,72,178,77,209,127,83,206,195,108,90,226,16,249,231,27,
|
|
46,154,187,201,65,222,2,81,70,180,85,140,56,103,123,138,196,200,78,104,163,250,191,197,90,10,159,187,218,175,238,116,29,222,92,61,206,42,204,97,212,39,246,82,135,7,20,228,201,49,51,249,143,232,203,126,245,253,67,212,35,110,123,185,41,251,190,148,189,
|
|
94,218,185,190,21,127,195,175,252,185,205,147,39,247,132,240,32,209,238,119,252,234,94,220,230,203,67,31,197,205,27,227,172,244,160,215,101,104,57,55,149,239,190,211,230,43,151,249,114,225,241,98,36,63,70,190,167,132,223,185,188,69,81,95,9,226,111,149,
|
|
153,133,222,56,209,171,142,61,69,120,170,160,104,160,150,246,100,118,236,41,192,83,57,158,38,203,167,66,212,187,16,107,157,109,142,115,68,81,47,86,16,122,133,89,132,114,249,84,102,58,96,75,32,190,187,205,121,230,231,168,194,45,158,241,158,74,237,183,
|
|
123,161,69,113,227,185,112,223,24,104,33,156,77,182,111,179,252,220,130,243,190,10,117,70,61,242,60,54,11,105,194,162,89,52,153,137,27,161,237,51,209,243,54,209,39,7,246,175,207,65,162,70,23,90,245,26,182,103,72,247,228,99,242,78,158,208,51,7,227,233,
|
|
204,40,166,150,12,167,203,91,92,150,145,37,53,59,16,167,54,103,182,49,207,40,36,47,247,78,156,176,116,46,121,29,91,61,131,152,135,108,103,139,211,116,120,199,120,165,180,3,151,210,151,77,225,105,194,187,197,168,84,239,247,80,245,157,57,102,245,7,224,
|
|
125,112,12,188,4,196,225,97,152,242,61,96,228,103,251,57,244,15,61,159,248,163,210,197,93,178,8,251,241,18,82,247,23,110,84,223,202,166,124,133,213,221,204,248,244,59,88,205,62,70,58,186,224,221,47,160,124,166,213,231,149,113,214,148,145,15,239,125,1,
|
|
237,99,129,213,84,105,228,98,207,59,100,188,155,27,80,49,54,186,174,143,42,151,184,165,63,39,203,44,77,166,5,22,163,76,182,244,193,100,90,75,42,237,236,84,154,75,222,254,16,135,117,218,160,179,77,70,6,81,167,67,239,123,43,160,246,76,235,66,111,90,124,
|
|
49,224,139,194,18,13,52,227,118,84,253,215,145,241,244,235,186,196,123,113,59,198,148,171,251,32,126,226,1,21,251,189,158,188,212,158,185,60,144,220,51,133,178,79,73,251,213,218,190,206,51,70,182,207,245,222,187,54,160,222,61,109,207,114,217,87,25,235,
|
|
80,159,151,170,63,53,116,59,55,4,212,57,146,43,203,169,55,211,175,164,217,156,58,126,127,245,12,99,91,161,199,150,204,255,173,51,228,95,153,154,11,213,143,123,79,209,143,7,78,97,123,36,205,102,234,182,30,15,168,239,11,188,76,124,163,208,17,224,164,164,
|
|
65,27,103,32,238,29,219,24,112,209,198,128,83,91,51,225,199,88,73,207,198,128,137,244,12,236,199,177,232,79,21,249,88,190,30,175,88,147,95,5,212,89,125,234,254,183,45,46,162,232,218,86,50,207,175,62,46,124,195,144,254,247,202,105,203,204,92,246,217,103,
|
|
114,220,11,23,144,25,20,101,220,104,71,156,213,191,11,168,239,57,218,182,231,99,157,196,41,229,198,73,55,142,90,175,68,20,241,228,98,215,187,177,251,189,66,154,182,167,64,72,135,141,53,204,164,44,167,107,251,96,70,147,246,17,177,166,110,180,37,124,244,
|
|
163,128,250,174,195,235,105,141,161,39,226,140,101,56,99,153,58,233,166,139,87,62,18,41,54,206,45,85,95,150,144,78,215,86,182,99,208,217,130,249,173,254,67,36,48,150,118,102,226,228,59,98,123,206,194,8,171,197,69,143,171,113,38,191,191,17,178,64,147,
|
|
173,207,218,49,51,212,123,159,151,90,175,66,219,78,217,182,115,62,51,208,242,252,204,76,180,137,158,227,4,247,86,213,87,186,40,178,112,28,221,242,32,90,121,223,246,184,97,207,102,243,152,184,89,40,221,246,13,11,191,117,136,154,68,31,179,68,31,175,100,
|
|
123,84,31,189,158,234,23,212,220,139,245,154,57,67,125,239,48,122,238,213,136,133,77,140,213,73,110,30,93,187,10,171,134,178,127,38,189,163,137,22,205,24,241,169,76,29,59,86,207,80,107,25,217,80,74,109,131,233,181,206,67,155,202,135,99,240,97,81,38,79,
|
|
175,229,38,36,151,161,162,214,103,145,219,16,35,103,134,156,117,150,199,108,79,14,234,119,103,138,181,203,165,44,215,175,110,252,140,166,177,15,165,215,86,191,215,250,156,23,210,246,229,227,140,21,235,44,98,129,88,151,2,33,157,174,103,7,51,214,136,17,
|
|
231,87,191,124,230,156,107,85,206,255,60,115,206,243,145,211,246,136,211,210,157,229,205,159,91,90,67,222,202,9,101,179,113,18,44,193,253,216,59,110,246,131,149,36,106,17,117,124,79,212,225,43,20,146,121,29,75,29,217,142,171,214,61,62,198,246,141,81,
|
|
150,162,165,206,108,231,85,61,143,23,37,235,61,228,118,179,234,215,208,143,171,113,83,199,165,254,135,55,190,238,102,25,243,221,37,244,247,142,96,42,245,124,150,222,159,127,166,39,162,166,234,95,255,227,61,88,163,123,48,233,255,221,131,53,178,7,88,102,
|
|
166,190,29,20,190,37,226,144,95,75,17,191,196,187,91,92,250,30,151,119,150,23,102,168,239,50,209,71,156,251,46,202,230,227,140,255,37,111,225,132,165,56,247,29,157,78,156,251,242,12,143,83,189,41,238,145,46,244,59,7,251,31,124,226,245,78,168,194,169,
|
|
111,136,83,63,3,39,123,139,201,13,113,218,111,229,213,239,230,240,234,163,224,119,224,136,240,247,124,244,173,84,238,93,68,61,62,189,168,166,196,168,174,158,50,189,174,38,45,222,26,245,35,123,195,208,214,172,122,117,7,158,199,93,36,102,196,70,142,92,
|
|
242,46,172,254,88,140,79,197,228,194,122,21,7,196,29,74,220,118,199,241,159,202,59,84,37,90,171,192,251,219,60,68,15,219,115,9,118,168,155,45,96,5,152,109,59,48,137,2,24,241,185,50,191,29,152,72,30,179,109,70,1,110,182,117,178,254,100,138,151,219,129,
|
|
9,228,225,42,205,47,230,247,125,146,191,239,18,63,201,239,92,197,123,206,116,216,102,37,191,60,213,63,11,79,120,94,115,194,179,40,95,72,234,236,205,71,239,152,182,9,124,90,102,232,116,175,62,103,199,105,123,133,150,92,227,211,243,53,141,230,74,123,173,
|
|
182,215,34,58,43,201,100,60,101,250,159,131,70,206,116,174,125,35,121,150,155,41,157,105,187,43,245,93,50,199,76,179,84,126,33,115,82,101,132,116,234,52,39,242,113,109,115,105,153,169,101,242,187,232,92,217,43,210,247,11,49,198,153,122,44,62,105,159,
|
|
169,125,120,102,170,215,170,252,44,45,103,235,114,201,126,10,153,163,219,23,122,94,42,61,47,109,76,57,169,177,22,167,250,161,234,246,232,246,124,169,156,106,92,62,157,155,145,122,223,102,213,132,247,41,103,99,200,14,37,206,38,126,118,3,21,45,137,244,
|
|
71,35,182,101,39,214,88,86,108,125,200,218,86,183,57,56,24,36,182,156,248,242,38,98,77,196,155,166,2,168,43,136,175,104,166,242,21,3,93,214,162,174,46,43,30,15,117,134,194,161,196,240,170,72,183,181,38,22,25,12,117,91,49,42,94,105,13,119,70,130,177,238,
|
|
165,161,120,127,40,30,111,14,197,19,150,141,4,214,76,188,25,181,53,163,154,230,102,50,154,241,128,143,21,226,163,153,138,154,131,118,119,44,18,234,246,7,163,81,255,162,174,68,104,16,53,55,208,172,209,246,104,52,28,234,10,38,66,17,123,98,50,79,115,168,
|
|
199,234,26,238,10,91,75,130,225,112,103,176,107,75,188,129,198,158,174,84,122,82,87,196,70,207,18,254,37,66,14,37,210,147,122,99,193,104,95,168,43,238,95,18,180,7,131,168,112,252,41,146,34,225,72,108,121,40,156,176,98,167,79,111,9,38,98,161,161,6,154,
|
|
250,55,211,71,85,85,114,114,214,53,193,144,141,254,21,159,156,178,214,234,66,66,65,42,33,18,247,47,30,176,187,195,86,3,21,166,27,155,22,135,236,110,81,251,72,29,131,88,106,63,22,107,217,160,37,42,31,55,58,161,37,34,166,75,167,77,29,157,38,156,100,226,
|
|
106,123,121,164,107,32,190,164,47,104,247,90,201,69,78,239,74,42,107,250,144,82,198,115,99,145,129,104,3,205,57,57,165,45,102,89,171,59,227,86,108,208,138,161,149,115,195,145,206,96,184,57,56,28,25,72,140,52,83,241,183,203,53,208,140,209,25,130,233,254,
|
|
234,31,229,189,45,65,59,216,43,138,212,255,221,69,132,195,55,217,61,145,147,250,127,134,50,201,77,210,64,117,163,203,133,236,232,64,162,223,74,244,69,186,253,139,131,113,84,142,103,248,165,141,229,149,94,59,233,244,249,151,117,135,18,145,152,234,78,205,
|
|
233,179,157,84,101,237,25,242,182,72,61,53,59,231,52,119,69,250,253,177,254,120,216,191,25,1,192,127,82,216,152,248,55,227,66,3,45,63,99,5,167,137,28,19,71,175,236,252,127,182,158,6,170,60,83,209,6,170,106,238,14,134,7,67,91,252,65,219,142,36,100,204,
|
|
240,47,179,187,194,145,120,200,238,93,18,14,198,101,48,56,57,79,19,38,54,166,211,43,79,145,222,98,245,119,234,12,22,178,148,159,34,75,107,168,215,14,38,6,98,150,216,48,34,6,251,195,216,91,126,236,176,88,171,181,117,192,178,187,144,146,159,158,162,154,
|
|
171,74,51,53,133,195,86,111,48,172,150,97,217,80,151,21,85,139,61,241,20,121,98,189,3,253,24,123,90,174,130,244,92,8,138,189,106,210,70,140,171,34,173,3,93,125,202,51,210,202,121,211,178,172,238,220,44,99,82,121,154,173,213,234,26,136,193,33,78,83,164,
|
|
21,49,208,238,21,30,57,98,139,89,61,97,212,131,110,12,70,84,232,110,11,198,122,173,244,222,142,59,69,118,213,181,6,26,163,210,6,18,161,176,127,81,44,22,28,22,78,208,64,121,105,102,97,33,207,9,134,6,50,219,54,174,89,70,217,233,62,71,108,61,241,245,77,
|
|
228,88,223,132,31,168,43,200,185,126,69,211,242,229,120,155,135,20,9,43,68,2,30,196,193,182,126,69,59,242,8,69,28,110,235,165,169,185,29,169,205,237,56,250,214,183,163,112,187,172,136,181,147,209,46,202,225,163,89,168,205,228,104,95,33,116,19,2,199,101,
|
|
187,176,226,152,116,182,55,75,179,67,72,216,59,112,54,119,52,145,183,227,100,103,40,232,56,197,90,184,85,92,154,24,8,4,82,250,140,52,189,62,77,159,153,166,207,74,211,103,167,233,115,210,244,185,105,250,60,232,89,74,95,30,14,246,198,41,103,84,64,164,194,
|
|
224,41,2,47,57,131,50,34,137,146,66,54,7,59,173,48,101,4,245,241,78,99,131,221,221,167,62,6,40,51,168,125,56,78,172,147,242,197,225,191,120,32,145,136,216,107,98,104,198,234,38,103,103,4,143,253,144,242,80,36,103,151,60,207,201,213,37,143,173,110,114,
|
|
224,222,16,140,81,86,151,8,85,17,156,178,139,18,226,33,117,50,83,174,124,104,139,5,237,120,79,36,214,79,57,226,214,128,227,56,46,115,163,34,117,121,64,69,145,1,60,151,118,197,172,96,226,228,48,40,194,51,153,221,161,158,30,98,22,57,44,113,174,146,175,
|
|
7,135,242,41,179,198,23,15,183,137,90,51,69,14,121,206,146,163,71,138,236,158,145,83,183,155,178,228,147,136,92,77,221,84,138,237,49,170,182,229,105,137,101,39,38,142,186,180,101,202,84,185,10,121,41,181,37,24,223,130,54,198,8,195,200,13,74,223,150,40,
|
|
7,102,17,154,176,78,86,44,78,25,226,81,184,32,185,133,166,51,101,139,29,43,198,218,22,234,183,100,43,231,89,161,222,190,4,21,64,149,167,76,122,31,133,177,89,239,246,213,118,43,166,210,178,101,21,216,213,193,86,68,73,85,133,218,227,178,163,114,17,16,86,
|
|
229,220,103,143,24,80,153,11,79,107,131,219,54,36,149,141,148,37,148,72,36,33,90,35,15,30,90,135,225,71,253,173,216,227,161,46,139,114,97,89,103,135,132,39,136,113,201,222,156,120,175,144,163,94,31,74,57,180,40,115,1,150,40,178,173,45,178,5,157,45,75,
|
|
61,203,76,97,11,71,80,52,28,28,94,30,11,98,252,38,82,55,200,207,141,196,250,168,4,139,8,167,28,181,42,231,69,68,43,121,58,37,26,93,19,28,16,126,236,73,25,214,90,113,120,124,202,178,56,229,242,148,163,44,56,252,150,70,182,97,55,165,30,215,69,169,48,245,
|
|
32,15,198,243,66,221,221,232,173,110,166,37,130,54,100,153,81,134,88,176,55,89,167,52,160,26,93,167,188,142,82,129,126,176,98,98,99,104,239,201,232,11,198,149,191,22,247,193,179,90,35,61,122,153,99,145,126,53,49,200,130,210,210,187,205,190,8,66,48,11,
|
|
145,27,222,177,90,70,245,56,25,161,254,126,202,19,239,39,161,96,120,73,48,26,111,193,130,80,142,54,180,90,225,101,118,119,42,29,143,240,139,24,54,138,188,190,180,13,71,45,202,150,234,197,234,42,67,25,104,108,125,48,60,128,189,31,194,81,178,197,66,99,
|
|
241,38,59,158,8,226,56,69,106,124,117,52,136,179,149,198,134,226,109,17,156,109,203,134,162,216,239,210,5,151,217,65,172,96,55,234,142,235,213,36,215,22,107,120,137,232,79,241,150,211,188,229,228,36,19,90,251,196,140,58,194,50,154,229,192,7,172,152,232,
|
|
222,42,220,55,200,12,91,61,9,114,134,45,187,55,209,71,78,221,85,102,147,105,11,63,113,217,214,182,85,66,201,176,147,161,35,219,78,223,174,206,72,167,136,65,100,70,194,221,125,242,115,27,229,71,236,228,27,209,18,25,131,176,159,70,76,75,173,120,34,22,25,
|
|
22,142,51,98,212,206,149,86,50,233,93,165,35,166,214,224,160,149,156,47,181,7,211,242,203,201,31,93,69,107,34,18,141,194,84,140,80,33,251,113,194,197,19,157,183,225,91,219,40,39,146,254,6,65,185,145,81,49,158,178,35,182,220,12,50,124,80,102,196,78,58,
|
|
118,142,84,91,6,194,137,80,84,44,137,124,132,115,102,136,163,67,22,69,142,214,208,37,86,50,72,162,38,181,180,178,38,103,68,45,184,75,201,139,81,110,0,81,63,129,24,230,136,74,199,118,71,131,49,228,148,97,34,39,58,202,189,29,81,25,245,203,163,145,232,64,
|
|
248,180,113,158,197,200,21,83,239,164,84,21,179,122,133,111,196,78,255,186,74,101,49,171,31,67,85,195,95,109,159,112,200,57,98,50,98,26,113,43,65,185,113,17,91,83,47,139,148,141,103,57,137,194,83,169,56,253,169,73,13,90,238,30,81,44,237,78,47,139,53,
|
|
39,61,146,74,240,116,202,183,57,26,19,79,6,201,117,161,180,168,87,122,74,179,184,76,7,113,122,198,85,216,148,14,156,19,31,21,46,221,201,199,176,234,211,5,161,112,120,85,36,33,221,33,59,142,13,147,12,80,40,136,167,84,244,64,102,225,104,170,95,184,42,34,
|
|
25,94,54,242,88,18,87,189,105,26,105,75,143,212,148,199,144,153,232,11,197,201,41,62,39,6,180,156,1,171,56,148,12,212,4,85,76,68,198,64,162,103,158,140,253,108,144,28,131,50,106,184,164,88,221,67,166,120,75,162,60,241,153,238,92,153,194,208,22,89,23,
|
|
183,200,51,120,210,105,49,24,138,37,6,130,97,125,190,185,7,71,166,130,109,35,54,68,124,40,0,102,128,122,48,19,204,34,54,76,223,52,57,237,229,174,220,246,90,186,199,100,183,112,87,57,207,122,150,15,149,111,54,232,151,172,228,141,149,244,144,201,175,229,
|
|
176,231,210,163,38,187,142,185,202,159,228,151,148,191,111,208,245,172,166,246,38,7,209,115,166,113,11,143,111,115,229,62,90,65,191,229,140,80,85,35,253,142,147,107,122,135,193,223,103,57,215,26,236,93,86,80,55,244,145,65,215,48,190,185,145,229,231,135,
|
|
26,121,188,220,65,141,44,203,137,242,92,117,128,207,217,200,87,110,171,165,95,112,118,187,104,237,68,121,8,85,230,222,79,175,40,209,104,92,205,126,207,126,204,92,211,249,179,212,192,63,101,219,248,51,108,219,16,127,227,210,215,118,49,238,112,47,170,109,
|
|
172,107,108,60,187,195,160,237,204,125,153,193,174,100,179,27,239,170,52,140,95,176,0,43,30,19,24,111,240,167,24,103,249,197,14,206,207,71,87,28,204,97,56,221,124,218,1,135,219,73,78,230,228,78,163,166,134,15,78,119,240,26,30,159,78,115,85,23,230,242,
|
|
219,249,29,82,49,133,242,85,254,181,209,214,148,226,72,38,239,23,143,215,137,46,127,161,140,6,33,86,210,97,131,239,227,119,10,251,235,38,12,180,75,76,25,189,100,136,207,47,152,124,224,82,200,29,38,27,128,120,215,16,2,37,111,150,207,215,149,209,167,134,
|
|
202,176,91,101,56,46,51,208,141,6,59,138,133,89,185,178,182,125,101,123,29,125,158,93,38,75,221,107,240,27,249,143,24,10,150,214,210,219,140,237,130,186,139,21,229,249,104,15,231,79,136,199,242,157,124,76,57,239,47,231,121,13,117,43,45,62,176,226,66,
|
|
62,188,130,30,228,198,19,108,135,76,231,249,215,240,88,249,222,142,205,187,12,199,110,206,253,214,57,116,175,46,155,187,211,87,182,151,238,54,28,151,63,205,190,196,63,100,151,160,35,251,13,243,54,126,55,123,129,253,15,210,23,236,108,167,91,84,171,59,
|
|
249,19,84,206,31,252,124,249,74,35,51,206,155,13,215,245,220,224,143,210,70,190,112,58,43,200,11,40,60,205,70,214,51,140,47,104,52,178,143,177,57,11,24,51,220,15,50,94,203,202,114,206,113,184,29,217,51,28,89,155,157,238,58,86,80,196,47,109,104,116,102,
|
|
47,96,229,99,132,125,180,145,47,103,229,185,244,136,193,110,197,12,251,12,182,139,7,152,183,136,103,79,199,40,43,12,218,201,106,199,59,72,42,211,38,56,232,245,64,13,253,196,96,207,161,139,244,170,193,134,92,185,161,50,58,206,216,13,40,252,152,65,7,89,
|
|
121,221,230,149,67,155,198,238,36,94,201,110,228,37,62,94,197,35,166,247,25,86,156,195,39,194,80,230,42,102,197,11,139,51,139,151,22,243,226,154,98,83,229,170,144,185,224,143,197,231,166,242,231,242,9,34,63,43,25,175,20,94,82,94,82,65,156,153,238,221,
|
|
62,230,157,124,229,118,243,80,217,20,118,188,140,177,67,229,140,125,0,142,141,71,50,203,230,108,183,111,218,246,237,230,193,138,233,236,181,10,50,156,148,43,74,48,111,45,202,28,168,100,187,124,207,139,143,163,226,99,71,21,227,183,131,199,170,200,89,82,
|
|
154,239,133,135,123,213,191,153,200,124,180,10,89,30,152,140,143,103,196,199,17,241,177,99,10,62,246,139,143,131,83,204,171,56,49,32,164,75,235,127,47,133,192,13,206,98,135,166,96,201,171,25,59,80,109,176,7,170,139,216,51,208,143,128,47,78,101,108,63,
|
|
184,31,28,6,123,106,24,251,54,56,8,158,1,7,166,97,232,224,139,211,25,123,13,188,92,203,216,243,117,204,220,237,103,230,1,63,210,252,14,182,127,22,99,247,204,230,236,167,224,240,108,79,218,239,7,146,50,249,119,57,226,251,234,228,223,230,136,239,177,147,
|
|
127,159,147,252,93,169,248,27,29,241,29,118,242,239,116,156,52,242,183,58,134,71,127,191,157,139,58,125,234,247,66,27,160,59,125,42,143,248,255,103,204,163,236,226,255,156,113,159,106,87,252,109,143,161,243,139,255,247,101,250,212,239,37,166,214,171,
|
|
95,84,136,178,242,255,173,121,84,95,197,223,17,253,31,67,245,215,66,128,52,0,0,0,0 };
|
|
|
|
//==============================================================================
|
|
#if JUCE_PUSH_NOTIFICATIONS && JUCE_MODULE_AVAILABLE_juce_gui_extra
|
|
extern bool juce_handleNotificationIntent (void*);
|
|
extern void juce_firebaseDeviceNotificationsTokenRefreshed (void*);
|
|
extern void juce_firebaseRemoteNotificationReceived (void*);
|
|
extern void juce_firebaseRemoteMessagesDeleted();
|
|
extern void juce_firebaseRemoteMessageSent(void*);
|
|
extern void juce_firebaseRemoteMessageSendError (void*, void*);
|
|
#endif
|
|
|
|
//==============================================================================
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (create, "<init>", "(II)V")
|
|
|
|
DECLARE_JNI_CLASS (AndroidLayoutParams, "android/view/ViewGroup$LayoutParams")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (addView, "addView", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V") \
|
|
METHOD (removeView, "removeView", "(Landroid/view/View;)V") \
|
|
METHOD (updateViewLayout, "updateViewLayout", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V")
|
|
|
|
DECLARE_JNI_CLASS (AndroidViewManager, "android/view/ViewManager")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (create, "<init>", "(IIIIIII)V") \
|
|
FIELD (gravity, "gravity", "I") \
|
|
FIELD (windowAnimations, "windowAnimations", "I")
|
|
|
|
DECLARE_JNI_CLASS (AndroidWindowManagerLayoutParams, "android/view/WindowManager$LayoutParams")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (getDisplayCutout, "getDisplayCutout", "()Landroid/view/DisplayCutout;")
|
|
|
|
DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidWindowInsets, "android/view/WindowInsets", 28)
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (getSafeInsetBottom, "getSafeInsetBottom", "()I") \
|
|
METHOD (getSafeInsetLeft, "getSafeInsetLeft", "()I") \
|
|
METHOD (getSafeInsetRight, "getSafeInsetRight", "()I") \
|
|
METHOD (getSafeInsetTop, "getSafeInsetTop", "()I")
|
|
|
|
DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidDisplayCutout, "android/view/DisplayCutout", 28)
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
//==============================================================================
|
|
namespace
|
|
{
|
|
enum
|
|
{
|
|
SYSTEM_UI_FLAG_VISIBLE = 0,
|
|
SYSTEM_UI_FLAG_LOW_PROFILE = 1,
|
|
SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2,
|
|
SYSTEM_UI_FLAG_FULLSCREEN = 4,
|
|
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512,
|
|
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024,
|
|
SYSTEM_UI_FLAG_IMMERSIVE = 2048,
|
|
SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096
|
|
};
|
|
|
|
constexpr int fullScreenFlags = SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
|
constexpr int FLAG_NOT_FOCUSABLE = 0x8;
|
|
}
|
|
|
|
//==============================================================================
|
|
static bool supportsDisplayCutout()
|
|
{
|
|
return getAndroidSDKVersion() >= 28;
|
|
}
|
|
|
|
static BorderSize<int> androidDisplayCutoutToBorderSize (LocalRef<jobject> displayCutout, double displayScale)
|
|
{
|
|
if (displayCutout.get() == nullptr)
|
|
return {};
|
|
|
|
auto* env = getEnv();
|
|
|
|
auto getInset = [&] (jmethodID methodID)
|
|
{
|
|
return roundToInt (env->CallIntMethod (displayCutout.get(), methodID) / displayScale);
|
|
};
|
|
|
|
return { getInset (AndroidDisplayCutout.getSafeInsetTop),
|
|
getInset (AndroidDisplayCutout.getSafeInsetLeft),
|
|
getInset (AndroidDisplayCutout.getSafeInsetBottom),
|
|
getInset (AndroidDisplayCutout.getSafeInsetRight) };
|
|
}
|
|
|
|
/* The usage of the KeyPress class relies on its keyCode member having the standard ASCII values
|
|
represent ASCII keycodes. However in the native Android keycodes the values for special keys
|
|
e.g. RETURN, F1-F12 overlap with the ASCII range. Hence we need to translate them.
|
|
*/
|
|
static constexpr int translateAndroidKeyCode (int keyCode) noexcept
|
|
{
|
|
switch (keyCode)
|
|
{
|
|
case 7: return '0';
|
|
case 8: return '1';
|
|
case 9: return '2';
|
|
case 10: return '3';
|
|
case 11: return '4';
|
|
case 12: return '5';
|
|
case 13: return '6';
|
|
case 14: return '7';
|
|
case 15: return '8';
|
|
case 16: return '9';
|
|
case 17: return '*';
|
|
case 18: return '#';
|
|
case 19: return KeyPress::upKey; // KEYCODE_DPAD_UP
|
|
case 20: return KeyPress::downKey; // KEYCODE_DPAD_DOWN
|
|
case 21: return KeyPress::leftKey; // KEYCODE_DPAD_LEFT
|
|
case 22: return KeyPress::rightKey; // KEYCODE_DPAD_RIGHT
|
|
case 29: return 'A';
|
|
case 30: return 'B';
|
|
case 31: return 'C';
|
|
case 32: return 'D';
|
|
case 33: return 'E';
|
|
case 34: return 'F';
|
|
case 35: return 'G';
|
|
case 36: return 'H';
|
|
case 37: return 'I';
|
|
case 38: return 'J';
|
|
case 39: return 'K';
|
|
case 40: return 'L';
|
|
case 41: return 'M';
|
|
case 42: return 'N';
|
|
case 43: return 'O';
|
|
case 44: return 'P';
|
|
case 45: return 'Q';
|
|
case 46: return 'R';
|
|
case 47: return 'S';
|
|
case 48: return 'T';
|
|
case 49: return 'U';
|
|
case 50: return 'V';
|
|
case 51: return 'W';
|
|
case 52: return 'X';
|
|
case 53: return 'Y';
|
|
case 54: return 'Z';
|
|
case 55: return ',';
|
|
case 56: return '.';
|
|
case 61: return KeyPress::tabKey; // KEYCODE_TAB
|
|
case 62: return KeyPress::spaceKey; // KEYCODE_SPACE
|
|
case 66: return KeyPress::returnKey; // KEYCODE_ENTER
|
|
case 67: return KeyPress::backspaceKey; // KEYCODE_DEL
|
|
case 68: return '`';
|
|
case 69: return '-';
|
|
case 70: return '=';
|
|
case 71: return '[';
|
|
case 72: return ']';
|
|
case 73: return '\\';
|
|
case 74: return ';';
|
|
case 75: return '\'';
|
|
case 76: return '/';
|
|
case 77: return '@';
|
|
case 81: return '+';
|
|
case 85: return KeyPress::playKey; // KEYCODE_MEDIA_PLAY_PAUSE
|
|
case 86: return KeyPress::stopKey; // KEYCODE_MEDIA_STOP
|
|
case 87: return KeyPress::fastForwardKey; // KEYCODE_MEDIA_NEXT
|
|
case 88: return KeyPress::rewindKey; // KEYCODE_MEDIA_PREVIOUS
|
|
case 92: return KeyPress::pageUpKey; // KEYCODE_PAGE_UP
|
|
case 93: return KeyPress::pageDownKey; // KEYCODE_PAGE_DOWN
|
|
case 111: return KeyPress::escapeKey; // KEYCODE_ESCAPE
|
|
case 112: return KeyPress::deleteKey; // KEYCODE_FORWARD_DEL
|
|
case 122: return KeyPress::homeKey; // KEYCODE_MOVE_HOME
|
|
case 123: return KeyPress::endKey; // KEYCODE_MOVE_END
|
|
case 124: return KeyPress::insertKey; // KEYCODE_INSERT
|
|
case 131: return KeyPress::F1Key; // KEYCODE_F1
|
|
case 132: return KeyPress::F2Key; // KEYCODE_F2
|
|
case 133: return KeyPress::F3Key; // KEYCODE_F3
|
|
case 134: return KeyPress::F4Key; // KEYCODE_F4
|
|
case 135: return KeyPress::F5Key; // KEYCODE_F5
|
|
case 136: return KeyPress::F6Key; // KEYCODE_F6
|
|
case 137: return KeyPress::F7Key; // KEYCODE_F7
|
|
case 138: return KeyPress::F8Key; // KEYCODE_F8
|
|
case 139: return KeyPress::F9Key; // KEYCODE_F9
|
|
case 140: return KeyPress::F10Key; // KEYCODE_F10
|
|
case 141: return KeyPress::F11Key; // KEYCODE_F11
|
|
case 142: return KeyPress::F12Key; // KEYCODE_F12
|
|
case 144: return '0';
|
|
case 145: return '1';
|
|
case 146: return '2';
|
|
case 147: return '3';
|
|
case 148: return '4';
|
|
case 149: return '5';
|
|
case 150: return '6';
|
|
case 151: return '7';
|
|
case 152: return '8';
|
|
case 153: return '9';
|
|
case 154: return '/';
|
|
case 155: return '*';
|
|
case 156: return '-';
|
|
case 157: return '+';
|
|
case 158: return '.';
|
|
case 159: return ',';
|
|
case 161: return '=';
|
|
case 162: return '(';
|
|
case 163: return ')';
|
|
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
static constexpr int translateAndroidKeyboardFlags (int javaFlags) noexcept
|
|
{
|
|
constexpr int metaShiftOn = 0x1;
|
|
constexpr int metaAltOn = 0x02;
|
|
constexpr int metaCtrlOn = 0x1000;
|
|
|
|
int flags = 0;
|
|
|
|
if ((javaFlags & metaShiftOn) != 0) flags |= ModifierKeys::shiftModifier;
|
|
if ((javaFlags & metaAltOn) != 0) flags |= ModifierKeys::altModifier;
|
|
if ((javaFlags & metaCtrlOn) != 0) flags |= ModifierKeys::ctrlModifier;
|
|
|
|
return flags;
|
|
}
|
|
|
|
//==============================================================================
|
|
class AndroidComponentPeer : public ComponentPeer,
|
|
private Timer
|
|
{
|
|
public:
|
|
AndroidComponentPeer (Component& comp, int windowStyleFlags, void* nativeViewHandle)
|
|
: ComponentPeer (comp, windowStyleFlags)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
// NB: must not put this in the initialiser list, as it invokes a callback,
|
|
// which will fail if the peer is only half-constructed.
|
|
view = GlobalRef (LocalRef<jobject> (env->NewObject (ComponentPeerView, ComponentPeerView.create,
|
|
getAppContext().get(), (jboolean) component.isOpaque(),
|
|
(jlong) this)));
|
|
|
|
if (nativeViewHandle != nullptr)
|
|
{
|
|
viewGroupIsWindow = false;
|
|
|
|
// we don't know if the user is holding on to a local ref to this, so
|
|
// explicitly create a new one
|
|
auto nativeView = LocalRef<jobject> (env->NewLocalRef (static_cast<jobject> (nativeViewHandle)));
|
|
|
|
if (env->IsInstanceOf (nativeView.get(), AndroidActivity))
|
|
{
|
|
viewGroup = GlobalRef (nativeView);
|
|
env->CallVoidMethod (viewGroup.get(), AndroidActivity.setContentView, view.get());
|
|
}
|
|
else if (env->IsInstanceOf (nativeView.get(), AndroidViewGroup))
|
|
{
|
|
viewGroup = GlobalRef (nativeView);
|
|
LocalRef<jobject> layoutParams (env->NewObject (AndroidLayoutParams, AndroidLayoutParams.create, -2, -2));
|
|
|
|
env->CallVoidMethod (view.get(), AndroidView.setLayoutParams, layoutParams.get());
|
|
env->CallVoidMethod ((jobject) viewGroup.get(), AndroidViewGroup.addView, view.get());
|
|
}
|
|
else
|
|
{
|
|
// the native handle you passed as a second argument to Component::addToDesktop must
|
|
// either be an Activity or a ViewGroup
|
|
jassertfalse;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
viewGroupIsWindow = true;
|
|
|
|
LocalRef<jobject> viewLayoutParams (env->NewObject (AndroidLayoutParams, AndroidLayoutParams.create, -2, -2));
|
|
env->CallVoidMethod (view.get(), AndroidView.setLayoutParams, viewLayoutParams.get());
|
|
|
|
auto physicalBounds = (comp.getBoundsInParent().toFloat() * scale).toNearestInt();
|
|
|
|
view.callVoidMethod (AndroidView.layout,
|
|
physicalBounds.getX(), physicalBounds.getY(), physicalBounds.getRight(), physicalBounds.getBottom());
|
|
|
|
LocalRef<jobject> windowLayoutParams (env->NewObject (AndroidWindowManagerLayoutParams, AndroidWindowManagerLayoutParams.create,
|
|
physicalBounds.getWidth(), physicalBounds.getHeight(),
|
|
physicalBounds.getX(), physicalBounds.getY(),
|
|
TYPE_APPLICATION, FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_NO_LIMITS | FLAG_NOT_FOCUSABLE,
|
|
component.isOpaque() ? PIXEL_FORMAT_OPAQUE : PIXEL_FORMAT_TRANSPARENT));
|
|
|
|
env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.gravity, GRAVITY_LEFT | GRAVITY_TOP);
|
|
env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.windowAnimations, 0x01030000 /* android.R.style.Animation */);
|
|
|
|
if (supportsDisplayCutout())
|
|
{
|
|
jfieldID layoutInDisplayCutoutModeFieldId = env->GetFieldID (AndroidWindowManagerLayoutParams,
|
|
"layoutInDisplayCutoutMode",
|
|
"I");
|
|
|
|
if (layoutInDisplayCutoutModeFieldId != nullptr)
|
|
env->SetIntField (windowLayoutParams.get(),
|
|
layoutInDisplayCutoutModeFieldId,
|
|
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS);
|
|
}
|
|
|
|
if (Desktop::getInstance().getKioskModeComponent() != nullptr)
|
|
setNavBarsHidden (true);
|
|
|
|
LocalRef<jobject> activity (getCurrentActivity());
|
|
|
|
if (activity == nullptr)
|
|
activity = getMainActivity();
|
|
|
|
viewGroup = GlobalRef (LocalRef<jobject> (env->CallObjectMethod (activity.get(), AndroidContext.getSystemService, javaString ("window").get())));
|
|
env->CallVoidMethod (viewGroup.get(), AndroidViewManager.addView, view.get(), windowLayoutParams.get());
|
|
}
|
|
|
|
if (supportsDisplayCutout())
|
|
{
|
|
jmethodID setOnApplyWindowInsetsListenerMethodId = env->GetMethodID (AndroidView,
|
|
"setOnApplyWindowInsetsListener",
|
|
"(Landroid/view/View$OnApplyWindowInsetsListener;)V");
|
|
|
|
if (setOnApplyWindowInsetsListenerMethodId != nullptr)
|
|
env->CallVoidMethod (view.get(), setOnApplyWindowInsetsListenerMethodId,
|
|
CreateJavaInterface (new ViewWindowInsetsListener,
|
|
"android/view/View$OnApplyWindowInsetsListener").get());
|
|
}
|
|
|
|
if (isFocused())
|
|
handleFocusGain();
|
|
}
|
|
|
|
~AndroidComponentPeer() override
|
|
{
|
|
stopTimer();
|
|
|
|
auto* env = getEnv();
|
|
|
|
env->CallVoidMethod (view, ComponentPeerView.clear);
|
|
frontWindow = nullptr;
|
|
|
|
GlobalRef localView (view);
|
|
GlobalRef localViewGroup (viewGroup);
|
|
|
|
callOnMessageThread ([env, localView, localViewGroup]
|
|
{
|
|
if (env->IsInstanceOf (localViewGroup.get(), AndroidActivity))
|
|
env->CallVoidMethod (localViewGroup.get(), AndroidActivity.setContentView, nullptr);
|
|
else
|
|
env->CallVoidMethod (localViewGroup.get(), AndroidViewManager.removeView, localView.get());
|
|
});
|
|
}
|
|
|
|
void* getNativeHandle() const override
|
|
{
|
|
return (void*) view.get();
|
|
}
|
|
|
|
void setVisible (bool shouldBeVisible) override
|
|
{
|
|
GlobalRef localView (view);
|
|
|
|
callOnMessageThread ([localView, shouldBeVisible]
|
|
{
|
|
localView.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible);
|
|
});
|
|
}
|
|
|
|
void setTitle (const String& title) override
|
|
{
|
|
view.callVoidMethod (ComponentPeerView.setViewName, javaString (title).get());
|
|
}
|
|
|
|
void setBounds (const Rectangle<int>& userRect, bool isNowFullScreen) override
|
|
{
|
|
auto bounds = (userRect.toFloat() * scale).toNearestInt();
|
|
|
|
if (MessageManager::getInstance()->isThisTheMessageThread())
|
|
{
|
|
fullScreen = isNowFullScreen;
|
|
|
|
view.callVoidMethod (AndroidView.layout,
|
|
bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getBottom());
|
|
|
|
if (viewGroup != nullptr && viewGroupIsWindow)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jobject> windowLayoutParams (env->NewObject (AndroidWindowManagerLayoutParams, AndroidWindowManagerLayoutParams.create,
|
|
bounds.getWidth(), bounds.getHeight(), bounds.getX(), bounds.getY(),
|
|
TYPE_APPLICATION, FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_NO_LIMITS,
|
|
component.isOpaque() ? PIXEL_FORMAT_OPAQUE : PIXEL_FORMAT_TRANSPARENT));
|
|
|
|
env->SetIntField (windowLayoutParams.get(), AndroidWindowManagerLayoutParams.gravity, GRAVITY_LEFT | GRAVITY_TOP);
|
|
env->CallVoidMethod (viewGroup.get(), AndroidViewManager.updateViewLayout, view.get(), windowLayoutParams.get());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GlobalRef localView (view);
|
|
|
|
MessageManager::callAsync ([localView, bounds]
|
|
{
|
|
localView.callVoidMethod (AndroidView.layout,
|
|
bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getBottom());
|
|
});
|
|
}
|
|
}
|
|
|
|
Rectangle<int> getBounds() const override
|
|
{
|
|
Rectangle<int> bounds (view.callIntMethod (AndroidView.getLeft),
|
|
view.callIntMethod (AndroidView.getTop),
|
|
view.callIntMethod (AndroidView.getWidth),
|
|
view.callIntMethod (AndroidView.getHeight));
|
|
|
|
return (bounds.toFloat() / scale).toNearestInt();
|
|
}
|
|
|
|
void handleScreenSizeChange() override
|
|
{
|
|
ComponentPeer::handleScreenSizeChange();
|
|
|
|
if (isFullScreen())
|
|
setFullScreen (true);
|
|
}
|
|
|
|
Point<int> getScreenPosition() const
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jintArray> position (env->NewIntArray (2));
|
|
env->CallVoidMethod (view.get(), AndroidView.getLocationOnScreen, position.get());
|
|
|
|
jint* const screenPosition = env->GetIntArrayElements (position.get(), nullptr);
|
|
Point<int> pos (screenPosition[0], screenPosition[1]);
|
|
env->ReleaseIntArrayElements (position.get(), screenPosition, 0);
|
|
|
|
return pos;
|
|
}
|
|
|
|
Point<float> localToGlobal (Point<float> relativePosition) override
|
|
{
|
|
return relativePosition + (getScreenPosition().toFloat() / scale);
|
|
}
|
|
|
|
using ComponentPeer::localToGlobal;
|
|
|
|
Point<float> globalToLocal (Point<float> screenPosition) override
|
|
{
|
|
return screenPosition - (getScreenPosition().toFloat() / scale);
|
|
}
|
|
|
|
using ComponentPeer::globalToLocal;
|
|
|
|
void setMinimised (bool /*shouldBeMinimised*/) override
|
|
{
|
|
// n/a
|
|
}
|
|
|
|
bool isMinimised() const override
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void setFullScreen (bool shouldBeFullScreen) override
|
|
{
|
|
if (shouldNavBarsBeHidden (shouldBeFullScreen))
|
|
{
|
|
if (isTimerRunning())
|
|
return;
|
|
|
|
startTimer (500);
|
|
}
|
|
else
|
|
{
|
|
setNavBarsHidden (false);
|
|
}
|
|
|
|
auto newBounds = [&]
|
|
{
|
|
if (navBarsHidden || shouldBeFullScreen)
|
|
if (auto* display = Desktop::getInstance().getDisplays().getPrimaryDisplay())
|
|
return navBarsHidden ? display->totalArea
|
|
: display->userArea;
|
|
|
|
return lastNonFullscreenBounds.isEmpty() ? getBounds() : lastNonFullscreenBounds;
|
|
}();
|
|
|
|
if (! newBounds.isEmpty())
|
|
setBounds (newBounds, shouldBeFullScreen);
|
|
|
|
component.repaint();
|
|
}
|
|
|
|
bool isFullScreen() const override
|
|
{
|
|
return fullScreen;
|
|
}
|
|
|
|
void setIcon (const Image& /*newIcon*/) override
|
|
{
|
|
// n/a
|
|
}
|
|
|
|
bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override
|
|
{
|
|
return isPositiveAndBelow (localPos.x, component.getWidth())
|
|
&& isPositiveAndBelow (localPos.y, component.getHeight())
|
|
&& ((! trueIfInAChildWindow) || view.callBooleanMethod (ComponentPeerView.containsPoint,
|
|
(float) localPos.x * scale,
|
|
(float) localPos.y * scale));
|
|
}
|
|
|
|
OptionalBorderSize getFrameSizeIfPresent() const override
|
|
{
|
|
// TODO
|
|
return {};
|
|
}
|
|
|
|
BorderSize<int> getFrameSize() const override
|
|
{
|
|
// TODO
|
|
return {};
|
|
}
|
|
|
|
bool setAlwaysOnTop (bool /*alwaysOnTop*/) override
|
|
{
|
|
// TODO
|
|
return false;
|
|
}
|
|
|
|
void toFront (bool makeActive) override
|
|
{
|
|
// Avoid calling bringToFront excessively: it's very slow
|
|
if (frontWindow != this)
|
|
{
|
|
view.callVoidMethod (AndroidView.bringToFront);
|
|
frontWindow = this;
|
|
}
|
|
|
|
if (makeActive)
|
|
grabFocus();
|
|
|
|
handleBroughtToFront();
|
|
}
|
|
|
|
void toBehind (ComponentPeer*) override
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
//==============================================================================
|
|
void handleMouseDownCallback (int index, Point<float> sysPos, int64 time)
|
|
{
|
|
lastMousePos = sysPos / scale;
|
|
auto pos = globalToLocal (lastMousePos);
|
|
|
|
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
|
|
handleMouseEvent (MouseInputSource::InputSourceType::touch,
|
|
pos,
|
|
ModifierKeys::currentModifiers.withoutMouseButtons(),
|
|
MouseInputSource::defaultPressure,
|
|
MouseInputSource::defaultOrientation,
|
|
time,
|
|
{},
|
|
index);
|
|
|
|
if (isValidPeer (this))
|
|
handleMouseDragCallback (index, sysPos, time);
|
|
}
|
|
|
|
void handleMouseDragCallback (int index, Point<float> sysPos, int64 time)
|
|
{
|
|
lastMousePos = sysPos / scale;
|
|
auto pos = globalToLocal (lastMousePos);
|
|
|
|
jassert (index < 64);
|
|
touchesDown = (touchesDown | (1 << (index & 63)));
|
|
|
|
ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
|
|
|
|
handleMouseEvent (MouseInputSource::InputSourceType::touch,
|
|
pos,
|
|
ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier),
|
|
MouseInputSource::defaultPressure,
|
|
MouseInputSource::defaultOrientation,
|
|
time,
|
|
{},
|
|
index);
|
|
}
|
|
|
|
void handleMouseUpCallback (int index, Point<float> sysPos, int64 time)
|
|
{
|
|
lastMousePos = sysPos / scale;
|
|
auto pos = globalToLocal (lastMousePos);
|
|
|
|
jassert (index < 64);
|
|
touchesDown = (touchesDown & ~(1 << (index & 63)));
|
|
|
|
if (touchesDown == 0)
|
|
ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons();
|
|
|
|
handleMouseEvent (MouseInputSource::InputSourceType::touch,
|
|
pos,
|
|
ModifierKeys::currentModifiers.withoutMouseButtons(),
|
|
MouseInputSource::defaultPressure,
|
|
MouseInputSource::defaultOrientation,
|
|
time,
|
|
{},
|
|
index);
|
|
}
|
|
|
|
void handleAccessibilityHoverCallback (int command, Point<float> sysPos, int64)
|
|
{
|
|
enum
|
|
{
|
|
TYPE_VIEW_HOVER_ENTER = 0x00000080,
|
|
TYPE_VIEW_HOVER_EXIT = 0x00000100,
|
|
|
|
ACTION_HOVER_ENTER = 0x00000009,
|
|
ACTION_HOVER_MOVE = 0x00000007,
|
|
ACTION_HOVER_EXIT = 0x0000000a
|
|
};
|
|
|
|
if (auto* topHandler = component.getAccessibilityHandler())
|
|
{
|
|
if (auto* virtualHandler = topHandler->getChildAt ((sysPos / scale).roundToInt()))
|
|
{
|
|
switch (command)
|
|
{
|
|
case ACTION_HOVER_ENTER:
|
|
case ACTION_HOVER_MOVE:
|
|
sendAccessibilityEventImpl (*virtualHandler, TYPE_VIEW_HOVER_ENTER, 0);
|
|
break;
|
|
|
|
case ACTION_HOVER_EXIT:
|
|
sendAccessibilityEventImpl (*virtualHandler, TYPE_VIEW_HOVER_EXIT, 0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void handleKeyDownCallback (int k, int kc, int kbFlags)
|
|
{
|
|
ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withOnlyMouseButtons()
|
|
.withFlags (translateAndroidKeyboardFlags (kbFlags));
|
|
handleKeyPress (translateAndroidKeyCode (k), static_cast<juce_wchar> (kc));
|
|
}
|
|
|
|
void handleKeyUpCallback (int /*k*/, int /*kc*/)
|
|
{
|
|
}
|
|
|
|
void handleBackButtonCallback()
|
|
{
|
|
bool handled = false;
|
|
|
|
if (auto* app = JUCEApplicationBase::getInstance())
|
|
handled = app->backButtonPressed();
|
|
|
|
if (isKioskModeComponent())
|
|
setNavBarsHidden (navBarsHidden);
|
|
|
|
if (! handled)
|
|
{
|
|
auto* env = getEnv();
|
|
LocalRef<jobject> activity (getCurrentActivity());
|
|
|
|
if (activity != nullptr)
|
|
{
|
|
jmethodID finishMethod = env->GetMethodID (AndroidActivity, "finish", "()V");
|
|
|
|
if (finishMethod != nullptr)
|
|
env->CallVoidMethod (activity.get(), finishMethod);
|
|
}
|
|
}
|
|
}
|
|
|
|
void handleKeyboardHiddenCallback()
|
|
{
|
|
Component::unfocusAllComponents();
|
|
}
|
|
|
|
void handleAppPausedCallback() {}
|
|
|
|
void handleAppResumedCallback()
|
|
{
|
|
if (isKioskModeComponent())
|
|
setNavBarsHidden (navBarsHidden);
|
|
}
|
|
|
|
//==============================================================================
|
|
AccessibilityNativeHandle* getNativeHandleForViewId (jint virtualViewId) const
|
|
{
|
|
if (auto* handler = (virtualViewId == HOST_VIEW_ID
|
|
? component.getAccessibilityHandler()
|
|
: AccessibilityNativeHandle::getAccessibilityHandlerForVirtualViewId (virtualViewId)))
|
|
{
|
|
return handler->getNativeImplementation();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
jboolean populateAccessibilityNodeInfoCallback (jint virtualViewId, jobject info) const
|
|
{
|
|
if (auto* handle = getNativeHandleForViewId (virtualViewId))
|
|
{
|
|
handle->populateNodeInfo (info);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
jboolean handlePerformActionCallback (jint virtualViewId, jint action, jobject arguments) const
|
|
{
|
|
if (auto* handle = getNativeHandleForViewId (virtualViewId))
|
|
return handle->performAction (action, arguments);
|
|
|
|
return false;
|
|
}
|
|
|
|
static jobject getFocusViewIdForHandler (const AccessibilityHandler* handler)
|
|
{
|
|
if (handler != nullptr)
|
|
return getEnv()->NewObject (JavaInteger,
|
|
JavaInteger.constructor,
|
|
handler->getNativeImplementation()->getVirtualViewId());
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
jobject getInputFocusViewIdCallback()
|
|
{
|
|
if (auto* comp = dynamic_cast<Component*> (findCurrentTextInputTarget()))
|
|
return getFocusViewIdForHandler (comp->getAccessibilityHandler());
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
jobject getAccessibilityFocusViewIdCallback() const
|
|
{
|
|
if (auto* handler = component.getAccessibilityHandler())
|
|
{
|
|
if (auto* modal = Component::getCurrentlyModalComponent())
|
|
{
|
|
if (! component.isParentOf (modal)
|
|
&& component.isCurrentlyBlockedByAnotherModalComponent())
|
|
{
|
|
if (auto* modalHandler = modal->getAccessibilityHandler())
|
|
{
|
|
if (auto* focusChild = modalHandler->getChildFocus())
|
|
return getFocusViewIdForHandler (focusChild);
|
|
|
|
return getFocusViewIdForHandler (modalHandler);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (auto* focusChild = handler->getChildFocus())
|
|
return getFocusViewIdForHandler (focusChild);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
//==============================================================================
|
|
bool isFocused() const override
|
|
{
|
|
if (view != nullptr)
|
|
return view.callBooleanMethod (AndroidView.hasFocus);
|
|
|
|
return false;
|
|
}
|
|
|
|
void grabFocus() override
|
|
{
|
|
if (view != nullptr)
|
|
view.callBooleanMethod (AndroidView.requestFocus);
|
|
}
|
|
|
|
void handleFocusChangeCallback (bool hasFocus)
|
|
{
|
|
if (isFullScreen())
|
|
setFullScreen (true);
|
|
|
|
if (hasFocus)
|
|
handleFocusGain();
|
|
else
|
|
handleFocusLoss();
|
|
}
|
|
|
|
static const char* getVirtualKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept
|
|
{
|
|
switch (type)
|
|
{
|
|
case TextInputTarget::textKeyboard: return "text";
|
|
case TextInputTarget::numericKeyboard: return "number";
|
|
case TextInputTarget::decimalKeyboard: return "numberDecimal";
|
|
case TextInputTarget::urlKeyboard: return "textUri";
|
|
case TextInputTarget::emailAddressKeyboard: return "textEmailAddress";
|
|
case TextInputTarget::phoneNumberKeyboard: return "phone";
|
|
default: jassertfalse; break;
|
|
}
|
|
|
|
return "text";
|
|
}
|
|
|
|
void textInputRequired (Point<int>, TextInputTarget& target) override
|
|
{
|
|
view.callVoidMethod (ComponentPeerView.showKeyboard,
|
|
javaString (getVirtualKeyboardType (target.getKeyboardType())).get());
|
|
}
|
|
|
|
void dismissPendingTextInput() override
|
|
{
|
|
view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get());
|
|
|
|
if (! isTimerRunning())
|
|
startTimer (500);
|
|
}
|
|
|
|
//==============================================================================
|
|
void handlePaintCallback (jobject canvas, jobject paint)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
jobject rect = env->CallObjectMethod (canvas, AndroidCanvas.getClipBounds);
|
|
auto left = env->GetIntField (rect, AndroidRect.left);
|
|
auto top = env->GetIntField (rect, AndroidRect.top);
|
|
auto right = env->GetIntField (rect, AndroidRect.right);
|
|
auto bottom = env->GetIntField (rect, AndroidRect.bottom);
|
|
env->DeleteLocalRef (rect);
|
|
|
|
auto clip = Rectangle<int>::leftTopRightBottom (left, top, right, bottom);
|
|
|
|
if (clip.isEmpty())
|
|
return;
|
|
|
|
auto sizeNeeded = clip.getWidth() * clip.getHeight();
|
|
|
|
if (sizeAllocated < sizeNeeded)
|
|
{
|
|
buffer.clear();
|
|
sizeAllocated = sizeNeeded;
|
|
buffer = GlobalRef (LocalRef<jobject> ((jobject) env->NewIntArray (sizeNeeded)));
|
|
}
|
|
|
|
if (jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), nullptr))
|
|
{
|
|
{
|
|
Image temp (new PreallocatedImage (clip.getWidth(), clip.getHeight(),
|
|
dest, ! component.isOpaque()));
|
|
|
|
{
|
|
LowLevelGraphicsSoftwareRenderer g (temp);
|
|
g.setOrigin (-clip.getPosition());
|
|
g.addTransform (AffineTransform::scale (scale));
|
|
handlePaint (g);
|
|
}
|
|
}
|
|
|
|
env->ReleaseIntArrayElements ((jintArray) buffer.get(), dest, 0);
|
|
|
|
env->CallVoidMethod (canvas, AndroidCanvas.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(),
|
|
(jfloat) clip.getX(), (jfloat) clip.getY(),
|
|
clip.getWidth(), clip.getHeight(), true, paint);
|
|
}
|
|
}
|
|
|
|
void repaint (const Rectangle<int>& userArea) override
|
|
{
|
|
auto area = (userArea.toFloat() * scale).toNearestInt();
|
|
|
|
GlobalRef localView (view);
|
|
|
|
callOnMessageThread ([area, localView]
|
|
{
|
|
localView.callVoidMethod (AndroidView.invalidate,
|
|
area.getX(), area.getY(), area.getRight(), area.getBottom());
|
|
});
|
|
}
|
|
|
|
void performAnyPendingRepaintsNow() override
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
void setAlpha (float /*newAlpha*/) override
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
StringArray getAvailableRenderingEngines() override
|
|
{
|
|
return StringArray ("Software Renderer");
|
|
}
|
|
|
|
//==============================================================================
|
|
static Point<float> lastMousePos;
|
|
static int64 touchesDown;
|
|
|
|
//==============================================================================
|
|
struct StartupActivityCallbackListener : public ActivityLifecycleCallbacks
|
|
{
|
|
void onActivityStarted (jobject /*activity*/) override
|
|
{
|
|
auto* env = getEnv();
|
|
LocalRef<jobject> appContext (getAppContext());
|
|
|
|
if (appContext.get() != nullptr)
|
|
{
|
|
env->CallVoidMethod (appContext.get(),
|
|
AndroidApplication.unregisterActivityLifecycleCallbacks,
|
|
activityCallbackListener.get());
|
|
clear();
|
|
activityCallbackListener.clear();
|
|
|
|
forceDisplayUpdate();
|
|
}
|
|
}
|
|
};
|
|
|
|
private:
|
|
//==============================================================================
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (create, "<init>", "(Landroid/content/Context;ZJ)V") \
|
|
METHOD (clear, "clear", "()V") \
|
|
METHOD (setViewName, "setViewName", "(Ljava/lang/String;)V") \
|
|
METHOD (setVisible, "setVisible", "(Z)V") \
|
|
METHOD (isVisible, "isVisible", "()Z") \
|
|
METHOD (containsPoint, "containsPoint", "(II)Z") \
|
|
METHOD (showKeyboard, "showKeyboard", "(Ljava/lang/String;)V") \
|
|
METHOD (setSystemUiVisibilityCompat, "setSystemUiVisibilityCompat", "(I)V") \
|
|
CALLBACK (handlePaintJni, "handlePaint", "(JLandroid/graphics/Canvas;Landroid/graphics/Paint;)V") \
|
|
CALLBACK (handleMouseDownJni, "handleMouseDown", "(JIFFJ)V") \
|
|
CALLBACK (handleMouseDragJni, "handleMouseDrag", "(JIFFJ)V") \
|
|
CALLBACK (handleMouseUpJni, "handleMouseUp", "(JIFFJ)V") \
|
|
CALLBACK (handleAccessibleHoverJni, "handleAccessibilityHover", "(JIFFJ)V") \
|
|
CALLBACK (handleKeyDownJni, "handleKeyDown", "(JIII)V") \
|
|
CALLBACK (handleKeyUpJni, "handleKeyUp", "(JII)V") \
|
|
CALLBACK (handleBackButtonJni, "handleBackButton", "(J)V") \
|
|
CALLBACK (handleKeyboardHiddenJni, "handleKeyboardHidden", "(J)V") \
|
|
CALLBACK (viewSizeChangedJni, "viewSizeChanged", "(J)V") \
|
|
CALLBACK (focusChangedJni, "focusChanged", "(JZ)V") \
|
|
CALLBACK (handleAppPausedJni, "handleAppPaused", "(J)V") \
|
|
CALLBACK (handleAppResumedJni, "handleAppResumed", "(J)V") \
|
|
CALLBACK (populateAccessibilityNodeInfoJni, "populateAccessibilityNodeInfo", "(JILandroid/view/accessibility/AccessibilityNodeInfo;)Z") \
|
|
CALLBACK (handlePerformActionJni, "handlePerformAction", "(JIILandroid/os/Bundle;)Z") \
|
|
CALLBACK (getInputFocusViewIdJni, "getInputFocusViewId", "(J)Ljava/lang/Integer;") \
|
|
CALLBACK (getAccessibilityFocusViewIdJni, "getAccessibilityFocusViewId", "(J)Ljava/lang/Integer;") \
|
|
|
|
DECLARE_JNI_CLASS_WITH_BYTECODE (ComponentPeerView, "com/rmsl/juce/ComponentPeerView", 16, javaComponentPeerView, sizeof (javaComponentPeerView))
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
static void JNICALL handlePaintJni (JNIEnv*, jobject /*view*/, jlong host, jobject canvas, jobject paint) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handlePaintCallback (canvas, paint); }
|
|
static void JNICALL handleMouseDownJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMouseDownCallback (i, Point<float> ((float) x, (float) y), (int64) time); }
|
|
static void JNICALL handleMouseDragJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMouseDragCallback (i, Point<float> ((float) x, (float) y), (int64) time); }
|
|
static void JNICALL handleMouseUpJni (JNIEnv*, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMouseUpCallback (i, Point<float> ((float) x, (float) y), (int64) time); }
|
|
static void JNICALL handleAccessibleHoverJni(JNIEnv*, jobject /*view*/, jlong host, jint c, jfloat x, jfloat y, jlong time) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleAccessibilityHoverCallback ((int) c, Point<float> ((float) x, (float) y), (int64) time); }
|
|
static void JNICALL viewSizeChangedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleMovedOrResized(); }
|
|
static void JNICALL focusChangedJni (JNIEnv*, jobject /*view*/, jlong host, jboolean hasFocus) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleFocusChangeCallback (hasFocus); }
|
|
static void JNICALL handleKeyDownJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc, jint kbFlags) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleKeyDownCallback ((int) k, (int) kc, (int) kbFlags); }
|
|
static void JNICALL handleKeyUpJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleKeyUpCallback ((int) k, (int) kc); }
|
|
static void JNICALL handleBackButtonJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleBackButtonCallback(); }
|
|
static void JNICALL handleKeyboardHiddenJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleKeyboardHiddenCallback(); }
|
|
static void JNICALL handleAppPausedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleAppPausedCallback(); }
|
|
static void JNICALL handleAppResumedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handleAppResumedCallback(); }
|
|
|
|
static jboolean JNICALL populateAccessibilityNodeInfoJni (JNIEnv*, jobject /*view*/, jlong host, jint virtualViewId, jobject info)
|
|
{
|
|
if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
|
|
return myself->populateAccessibilityNodeInfoCallback (virtualViewId, info);
|
|
|
|
return false;
|
|
}
|
|
|
|
static jboolean JNICALL handlePerformActionJni (JNIEnv*, jobject /*view*/, jlong host, jint virtualViewId, jint action, jobject arguments)
|
|
{
|
|
if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
|
|
return myself->handlePerformActionCallback (virtualViewId, action, arguments);
|
|
|
|
return false;
|
|
}
|
|
|
|
static jobject JNICALL getInputFocusViewIdJni (JNIEnv*, jobject /*view*/, jlong host)
|
|
{
|
|
if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
|
|
return myself->getInputFocusViewIdCallback();
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
static jobject JNICALL getAccessibilityFocusViewIdJni (JNIEnv*, jobject /*view*/, jlong host)
|
|
{
|
|
if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host))
|
|
return myself->getAccessibilityFocusViewIdCallback();
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
//==============================================================================
|
|
struct ViewWindowInsetsListener : public juce::AndroidInterfaceImplementer
|
|
{
|
|
jobject onApplyWindowInsets (LocalRef<jobject> v, LocalRef<jobject> insets)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jobject> displayCutout (env->CallObjectMethod (insets.get(), AndroidWindowInsets.getDisplayCutout));
|
|
|
|
if (displayCutout != nullptr)
|
|
{
|
|
const auto& mainDisplay = *Desktop::getInstance().getDisplays().getPrimaryDisplay();
|
|
auto newSafeAreaInsets = androidDisplayCutoutToBorderSize (displayCutout, mainDisplay.scale);
|
|
|
|
if (newSafeAreaInsets != mainDisplay.safeAreaInsets)
|
|
forceDisplayUpdate();
|
|
|
|
auto* fieldId = env->GetStaticFieldID (AndroidWindowInsets, "CONSUMED", "Landroid/view/WindowInsets");
|
|
jassert (fieldId != nullptr);
|
|
|
|
return env->GetStaticObjectField (AndroidWindowInsets, fieldId);
|
|
}
|
|
|
|
jmethodID onApplyWindowInsetsMethodId = env->GetMethodID (AndroidView,
|
|
"onApplyWindowInsets",
|
|
"(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;");
|
|
|
|
jassert (onApplyWindowInsetsMethodId != nullptr);
|
|
|
|
return env->CallObjectMethod (v.get(), onApplyWindowInsetsMethodId, insets.get());
|
|
}
|
|
|
|
private:
|
|
jobject invoke (jobject proxy, jobject method, jobjectArray args) override
|
|
{
|
|
auto* env = getEnv();
|
|
auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
|
|
|
|
if (methodName == "onApplyWindowInsets")
|
|
{
|
|
jassert (env->GetArrayLength (args) == 2);
|
|
|
|
LocalRef<jobject> windowView (env->GetObjectArrayElement (args, 0));
|
|
LocalRef<jobject> insets (env->GetObjectArrayElement (args, 1));
|
|
|
|
return onApplyWindowInsets (std::move (windowView), std::move (insets));
|
|
}
|
|
|
|
// invoke base class
|
|
return AndroidInterfaceImplementer::invoke (proxy, method, args);
|
|
}
|
|
};
|
|
|
|
//==============================================================================
|
|
struct PreallocatedImage : public ImagePixelData
|
|
{
|
|
PreallocatedImage (int width_, int height_, jint* data_, bool hasAlpha_)
|
|
: ImagePixelData (Image::ARGB, width_, height_), data (data_), hasAlpha (hasAlpha_)
|
|
{
|
|
if (hasAlpha_)
|
|
zeromem (data_, static_cast<size_t> (width * height) * sizeof (jint));
|
|
}
|
|
|
|
~PreallocatedImage() override
|
|
{
|
|
if (hasAlpha)
|
|
{
|
|
auto pix = (PixelARGB*) data;
|
|
|
|
for (int i = width * height; --i >= 0;)
|
|
{
|
|
pix->unpremultiply();
|
|
++pix;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<ImageType> createType() const override
|
|
{
|
|
return std::make_unique<SoftwareImageType>();
|
|
}
|
|
|
|
std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override
|
|
{
|
|
return std::make_unique<LowLevelGraphicsSoftwareRenderer> (Image (this));
|
|
}
|
|
|
|
void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/) override
|
|
{
|
|
bm.lineStride = width * static_cast<int> (sizeof (jint));
|
|
bm.pixelStride = static_cast<int> (sizeof (jint));
|
|
bm.pixelFormat = Image::ARGB;
|
|
const auto offset = (size_t) x + (size_t) y * (size_t) width;
|
|
bm.data = (uint8*) (data + offset);
|
|
bm.size = sizeof (jint) * (((size_t) height * (size_t) width) - offset);
|
|
}
|
|
|
|
ImagePixelData::Ptr clone() override
|
|
{
|
|
auto s = new PreallocatedImage (width, height, nullptr, hasAlpha);
|
|
s->allocatedData.malloc (sizeof (jint) * static_cast<size_t> (width * height));
|
|
s->data = s->allocatedData;
|
|
memcpy (s->data, data, sizeof (jint) * static_cast<size_t> (width * height));
|
|
return s;
|
|
}
|
|
|
|
private:
|
|
jint* data;
|
|
HeapBlock<jint> allocatedData;
|
|
bool hasAlpha;
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PreallocatedImage)
|
|
};
|
|
|
|
//==============================================================================
|
|
void timerCallback() override
|
|
{
|
|
setNavBarsHidden (shouldNavBarsBeHidden (fullScreen));
|
|
setFullScreen (fullScreen);
|
|
stopTimer();
|
|
}
|
|
|
|
bool isKioskModeComponent() const
|
|
{
|
|
if (auto* kiosk = Desktop::getInstance().getKioskModeComponent())
|
|
return kiosk->getPeer() == this;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool shouldNavBarsBeHidden (bool shouldBeFullScreen) const
|
|
{
|
|
return (shouldBeFullScreen && isKioskModeComponent());
|
|
}
|
|
|
|
void setNavBarsHidden (bool hidden)
|
|
{
|
|
if (navBarsHidden != hidden)
|
|
{
|
|
navBarsHidden = hidden;
|
|
|
|
view.callVoidMethod (ComponentPeerView.setSystemUiVisibilityCompat,
|
|
(navBarsHidden ? (jint) (fullScreenFlags) : (jint) (SYSTEM_UI_FLAG_VISIBLE)));
|
|
}
|
|
}
|
|
|
|
template <typename Callback>
|
|
static void callOnMessageThread (Callback&& callback)
|
|
{
|
|
if (MessageManager::getInstance()->isThisTheMessageThread())
|
|
callback();
|
|
else
|
|
MessageManager::callAsync (std::forward<Callback> (callback));
|
|
}
|
|
|
|
//==============================================================================
|
|
friend class Displays;
|
|
static AndroidComponentPeer* frontWindow;
|
|
static GlobalRef activityCallbackListener;
|
|
|
|
static constexpr int GRAVITY_LEFT = 0x3, GRAVITY_TOP = 0x30;
|
|
static constexpr int TYPE_APPLICATION = 0x2;
|
|
static constexpr int FLAG_NOT_TOUCH_MODAL = 0x20, FLAG_LAYOUT_IN_SCREEN = 0x100, FLAG_LAYOUT_NO_LIMITS = 0x200;
|
|
static constexpr int PIXEL_FORMAT_OPAQUE = -1, PIXEL_FORMAT_TRANSPARENT = -2;
|
|
static constexpr int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 0x3;
|
|
|
|
GlobalRef view, viewGroup, buffer;
|
|
bool viewGroupIsWindow = false, fullScreen = false, navBarsHidden = false;
|
|
int sizeAllocated = 0;
|
|
float scale = (float) Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale;
|
|
|
|
//==============================================================================
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer)
|
|
};
|
|
|
|
Point<float> AndroidComponentPeer::lastMousePos;
|
|
int64 AndroidComponentPeer::touchesDown = 0;
|
|
AndroidComponentPeer* AndroidComponentPeer::frontWindow = nullptr;
|
|
GlobalRef AndroidComponentPeer::activityCallbackListener;
|
|
AndroidComponentPeer::ComponentPeerView_Class AndroidComponentPeer::ComponentPeerView;
|
|
|
|
//==============================================================================
|
|
ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindow)
|
|
{
|
|
return new AndroidComponentPeer (*this, styleFlags, nativeWindow);
|
|
}
|
|
|
|
//==============================================================================
|
|
bool Desktop::canUseSemiTransparentWindows() noexcept
|
|
{
|
|
return true;
|
|
}
|
|
|
|
class Desktop::NativeDarkModeChangeDetectorImpl : public ActivityLifecycleCallbacks
|
|
{
|
|
public:
|
|
NativeDarkModeChangeDetectorImpl()
|
|
{
|
|
LocalRef<jobject> appContext (getAppContext());
|
|
|
|
if (appContext != nullptr)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
myself = GlobalRef (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks"));
|
|
env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, myself.get());
|
|
}
|
|
}
|
|
|
|
~NativeDarkModeChangeDetectorImpl() override
|
|
{
|
|
LocalRef<jobject> appContext (getAppContext());
|
|
|
|
if (appContext != nullptr && myself != nullptr)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
env->CallVoidMethod (appContext.get(),
|
|
AndroidApplication.unregisterActivityLifecycleCallbacks,
|
|
myself.get());
|
|
clear();
|
|
myself.clear();
|
|
}
|
|
}
|
|
|
|
bool isDarkModeEnabled() const noexcept { return darkModeEnabled; }
|
|
|
|
void onActivityStarted (jobject /*activity*/) override
|
|
{
|
|
const auto isEnabled = getDarkModeSetting();
|
|
|
|
if (darkModeEnabled != isEnabled)
|
|
{
|
|
darkModeEnabled = isEnabled;
|
|
Desktop::getInstance().darkModeChanged();
|
|
}
|
|
}
|
|
|
|
private:
|
|
static bool getDarkModeSetting()
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
const LocalRef<jobject> resources (env->CallObjectMethod (getAppContext().get(), AndroidContext.getResources));
|
|
const LocalRef<jobject> configuration (env->CallObjectMethod (resources, AndroidResources.getConfiguration));
|
|
|
|
const auto uiMode = env->GetIntField (configuration, AndroidConfiguration.uiMode);
|
|
|
|
return ((uiMode & UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES);
|
|
}
|
|
|
|
static constexpr int UI_MODE_NIGHT_MASK = 0x00000030,
|
|
UI_MODE_NIGHT_NO = 0x00000010,
|
|
UI_MODE_NIGHT_UNDEFINED = 0x00000000,
|
|
UI_MODE_NIGHT_YES = 0x00000020;
|
|
|
|
GlobalRef myself;
|
|
bool darkModeEnabled = getDarkModeSetting();
|
|
|
|
//==============================================================================
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
|
|
};
|
|
|
|
std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
|
|
{
|
|
return std::make_unique<NativeDarkModeChangeDetectorImpl>();
|
|
}
|
|
|
|
bool Desktop::isDarkModeActive() const
|
|
{
|
|
return nativeDarkModeChangeDetectorImpl->isDarkModeEnabled();
|
|
}
|
|
|
|
double Desktop::getDefaultMasterScale()
|
|
{
|
|
return 1.0;
|
|
}
|
|
|
|
Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
|
|
{
|
|
enum
|
|
{
|
|
ROTATION_0 = 0,
|
|
ROTATION_90 = 1,
|
|
ROTATION_180 = 2,
|
|
ROTATION_270 = 3
|
|
};
|
|
|
|
JNIEnv* env = getEnv();
|
|
LocalRef<jstring> windowServiceString (javaString ("window"));
|
|
|
|
|
|
LocalRef<jobject> windowManager = LocalRef<jobject> (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get()));
|
|
|
|
if (windowManager.get() != nullptr)
|
|
{
|
|
LocalRef<jobject> display = LocalRef<jobject> (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay));
|
|
|
|
if (display.get() != nullptr)
|
|
{
|
|
int rotation = env->CallIntMethod (display, AndroidDisplay.getRotation);
|
|
|
|
switch (rotation)
|
|
{
|
|
case ROTATION_0: return upright;
|
|
case ROTATION_90: return rotatedAntiClockwise;
|
|
case ROTATION_180: return upsideDown;
|
|
case ROTATION_270: return rotatedClockwise;
|
|
}
|
|
}
|
|
}
|
|
|
|
jassertfalse;
|
|
return upright;
|
|
}
|
|
|
|
bool MouseInputSource::SourceList::addSource()
|
|
{
|
|
addSource (sources.size(), MouseInputSource::InputSourceType::touch);
|
|
return true;
|
|
}
|
|
|
|
bool MouseInputSource::SourceList::canUseTouch()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
Point<float> MouseInputSource::getCurrentRawMousePosition()
|
|
{
|
|
return AndroidComponentPeer::lastMousePos;
|
|
}
|
|
|
|
void MouseInputSource::setRawMousePosition (Point<float>)
|
|
{
|
|
// not needed
|
|
}
|
|
|
|
//==============================================================================
|
|
bool KeyPress::isKeyCurrentlyDown (int /*keyCode*/)
|
|
{
|
|
// TODO
|
|
return false;
|
|
}
|
|
|
|
JUCE_API void JUCE_CALLTYPE Process::hide()
|
|
{
|
|
auto* env = getEnv();
|
|
LocalRef<jobject> currentActivity (getCurrentActivity().get());
|
|
|
|
if (env->CallBooleanMethod (currentActivity.get(), AndroidActivity.moveTaskToBack, true) == 0)
|
|
{
|
|
GlobalRef intent (LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructor)));
|
|
env->CallObjectMethod (intent, AndroidIntent.setAction, javaString ("android.intent.action.MAIN") .get());
|
|
env->CallObjectMethod (intent, AndroidIntent.addCategory, javaString ("android.intent.category.HOME").get());
|
|
|
|
env->CallVoidMethod (currentActivity.get(), AndroidContext.startActivity, intent.get());
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
// TODO
|
|
JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() { return true; }
|
|
JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {}
|
|
|
|
//==============================================================================
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (show, "show", "()V") \
|
|
METHOD (getWindow, "getWindow", "()Landroid/view/Window;")
|
|
|
|
DECLARE_JNI_CLASS (AndroidDialog, "android/app/Dialog")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (construct, "<init>", "(Landroid/content/Context;)V") \
|
|
METHOD (create, "create", "()Landroid/app/AlertDialog;") \
|
|
METHOD (setTitle, "setTitle", "(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;") \
|
|
METHOD (setMessage, "setMessage", "(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;") \
|
|
METHOD (setCancelable, "setCancelable", "(Z)Landroid/app/AlertDialog$Builder;") \
|
|
METHOD (setOnCancelListener, "setOnCancelListener", "(Landroid/content/DialogInterface$OnCancelListener;)Landroid/app/AlertDialog$Builder;") \
|
|
METHOD (setPositiveButton, "setPositiveButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;") \
|
|
METHOD (setNegativeButton, "setNegativeButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;") \
|
|
METHOD (setNeutralButton, "setNeutralButton", "(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;")
|
|
|
|
DECLARE_JNI_CLASS (AndroidAlertDialogBuilder, "android/app/AlertDialog$Builder")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (dismiss, "dismiss", "()V")
|
|
|
|
DECLARE_JNI_CLASS (AndroidDialogInterface, "android/content/DialogInterface")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
|
|
DECLARE_JNI_CLASS (AndroidDialogOnClickListener, "android/content/DialogInterface$OnClickListener")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
//==============================================================================
|
|
class DialogListener : public juce::AndroidInterfaceImplementer
|
|
{
|
|
public:
|
|
DialogListener (std::shared_ptr<ModalComponentManager::Callback> callbackToUse, int resultToUse)
|
|
: callback (std::move (callbackToUse)), result (resultToUse)
|
|
{}
|
|
|
|
void onResult (jobject dialog)
|
|
{
|
|
auto* env = getEnv();
|
|
env->CallVoidMethod (dialog, AndroidDialogInterface.dismiss);
|
|
|
|
if (callback != nullptr)
|
|
callback->modalStateFinished (result);
|
|
|
|
callback = nullptr;
|
|
}
|
|
|
|
private:
|
|
jobject invoke (jobject proxy, jobject method, jobjectArray args) override
|
|
{
|
|
auto* env = getEnv();
|
|
auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
|
|
|
|
if (methodName == "onCancel" || methodName == "onClick")
|
|
{
|
|
onResult (env->GetObjectArrayElement (args, 0));
|
|
return nullptr;
|
|
}
|
|
|
|
// invoke base class
|
|
return AndroidInterfaceImplementer::invoke (proxy, method, args);
|
|
}
|
|
|
|
std::shared_ptr<ModalComponentManager::Callback> callback;
|
|
int result;
|
|
};
|
|
|
|
//==============================================================================
|
|
static void createAndroidDialog (const MessageBoxOptions& opts,
|
|
ModalComponentManager::Callback* callbackIn,
|
|
AlertWindowMappings::MapFn mapFn)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jobject> builder (env->NewObject (AndroidAlertDialogBuilder, AndroidAlertDialogBuilder.construct, getMainActivity().get()));
|
|
|
|
builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setTitle, javaString (opts.getTitle()).get()));
|
|
builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setMessage, javaString (opts.getMessage()).get()));
|
|
builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setCancelable, true));
|
|
|
|
std::shared_ptr<ModalComponentManager::Callback> sharedCallback (AlertWindowMappings::getWrappedCallback (callbackIn, mapFn));
|
|
|
|
builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setOnCancelListener,
|
|
CreateJavaInterface (new DialogListener (sharedCallback, 0),
|
|
"android/content/DialogInterface$OnCancelListener").get()));
|
|
|
|
builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setPositiveButton,
|
|
javaString (opts.getButtonText (0)).get(),
|
|
CreateJavaInterface (new DialogListener (sharedCallback, 0),
|
|
"android/content/DialogInterface$OnClickListener").get()));
|
|
|
|
if (opts.getButtonText (1).isNotEmpty())
|
|
builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNegativeButton,
|
|
javaString (opts.getButtonText (1)).get(),
|
|
CreateJavaInterface (new DialogListener (sharedCallback, 1),
|
|
"android/content/DialogInterface$OnClickListener").get()));
|
|
|
|
if (opts.getButtonText (2).isNotEmpty())
|
|
builder = LocalRef<jobject> (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNeutralButton,
|
|
javaString (opts.getButtonText (2)).get(),
|
|
CreateJavaInterface (new DialogListener (sharedCallback, 2),
|
|
"android/content/DialogInterface$OnClickListener").get()));
|
|
|
|
LocalRef<jobject> dialog (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.create));
|
|
|
|
LocalRef<jobject> window (env->CallObjectMethod (dialog.get(), AndroidDialog.getWindow));
|
|
|
|
if (Desktop::getInstance().getKioskModeComponent() != nullptr)
|
|
{
|
|
env->CallVoidMethod (window.get(), AndroidWindow.setFlags, FLAG_NOT_FOCUSABLE, FLAG_NOT_FOCUSABLE);
|
|
LocalRef<jobject> decorView (env->CallObjectMethod (window.get(), AndroidWindow.getDecorView));
|
|
env->CallVoidMethod (decorView.get(), AndroidView.setSystemUiVisibility, fullScreenFlags);
|
|
}
|
|
|
|
env->CallVoidMethod (dialog.get(), AndroidDialog.show);
|
|
|
|
if (Desktop::getInstance().getKioskModeComponent() != nullptr)
|
|
env->CallVoidMethod (window.get(), AndroidWindow.clearFlags, FLAG_NOT_FOCUSABLE);
|
|
}
|
|
|
|
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (MessageBoxIconType /*iconType*/,
|
|
const String& title, const String& message,
|
|
Component* /*associatedComponent*/,
|
|
ModalComponentManager::Callback* callback)
|
|
{
|
|
createAndroidDialog (MessageBoxOptions()
|
|
.withTitle (title)
|
|
.withMessage (message)
|
|
.withButton (TRANS("OK")),
|
|
callback, AlertWindowMappings::messageBox);
|
|
}
|
|
|
|
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (MessageBoxIconType /*iconType*/,
|
|
const String& title, const String& message,
|
|
Component* /*associatedComponent*/,
|
|
ModalComponentManager::Callback* callback)
|
|
{
|
|
createAndroidDialog (MessageBoxOptions()
|
|
.withTitle (title)
|
|
.withMessage (message)
|
|
.withButton (TRANS("OK"))
|
|
.withButton (TRANS("Cancel")),
|
|
callback, AlertWindowMappings::okCancel);
|
|
|
|
return false;
|
|
}
|
|
|
|
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (MessageBoxIconType /*iconType*/,
|
|
const String& title, const String& message,
|
|
Component* /*associatedComponent*/,
|
|
ModalComponentManager::Callback* callback)
|
|
{
|
|
createAndroidDialog (MessageBoxOptions()
|
|
.withTitle (title)
|
|
.withMessage (message)
|
|
.withButton (TRANS("Yes"))
|
|
.withButton (TRANS("No"))
|
|
.withButton (TRANS("Cancel")),
|
|
callback, AlertWindowMappings::yesNoCancel);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (MessageBoxIconType /*iconType*/,
|
|
const String& title, const String& message,
|
|
Component* /*associatedComponent*/,
|
|
ModalComponentManager::Callback* callback)
|
|
{
|
|
createAndroidDialog (MessageBoxOptions()
|
|
.withTitle (title)
|
|
.withMessage (message)
|
|
.withButton (TRANS("Yes"))
|
|
.withButton (TRANS("No")),
|
|
callback, AlertWindowMappings::okCancel);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void JUCE_CALLTYPE NativeMessageBox::showAsync (const MessageBoxOptions& options,
|
|
ModalComponentManager::Callback* callback)
|
|
{
|
|
createAndroidDialog (options, callback, AlertWindowMappings::noMapping);
|
|
}
|
|
|
|
void JUCE_CALLTYPE NativeMessageBox::showAsync (const MessageBoxOptions& options,
|
|
std::function<void (int)> callback)
|
|
{
|
|
showAsync (options, ModalCallbackFunction::create (callback));
|
|
}
|
|
|
|
//==============================================================================
|
|
static bool androidScreenSaverEnabled = true;
|
|
|
|
void Desktop::setScreenSaverEnabled (bool shouldEnable)
|
|
{
|
|
constexpr auto FLAG_KEEP_SCREEN_ON = 0x80;
|
|
|
|
if (shouldEnable != androidScreenSaverEnabled)
|
|
{
|
|
LocalRef<jobject> activity (getMainActivity());
|
|
|
|
if (activity != nullptr)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jobject> mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow));
|
|
env->CallVoidMethod (mainWindow.get(), AndroidWindow.setFlags, shouldEnable ? 0 : FLAG_KEEP_SCREEN_ON, FLAG_KEEP_SCREEN_ON);
|
|
}
|
|
|
|
androidScreenSaverEnabled = shouldEnable;
|
|
}
|
|
}
|
|
|
|
bool Desktop::isScreenSaverEnabled()
|
|
{
|
|
return androidScreenSaverEnabled;
|
|
}
|
|
|
|
//==============================================================================
|
|
void Desktop::setKioskComponent (Component* kioskComp, bool enableOrDisable, bool allowMenusAndBars)
|
|
{
|
|
ignoreUnused (allowMenusAndBars);
|
|
|
|
if (AndroidComponentPeer* peer = dynamic_cast<AndroidComponentPeer*> (kioskComp->getPeer()))
|
|
peer->setFullScreen (enableOrDisable);
|
|
else
|
|
jassertfalse; // (this should have been checked by the caller)
|
|
}
|
|
|
|
//==============================================================================
|
|
static jint getAndroidOrientationFlag (int orientations) noexcept
|
|
{
|
|
enum
|
|
{
|
|
SCREEN_ORIENTATION_LANDSCAPE = 0,
|
|
SCREEN_ORIENTATION_PORTRAIT = 1,
|
|
SCREEN_ORIENTATION_USER = 2,
|
|
SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8,
|
|
SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9,
|
|
SCREEN_ORIENTATION_USER_LANDSCAPE = 11,
|
|
SCREEN_ORIENTATION_USER_PORTRAIT = 12,
|
|
};
|
|
|
|
switch (orientations)
|
|
{
|
|
case Desktop::upright: return (jint) SCREEN_ORIENTATION_PORTRAIT;
|
|
case Desktop::upsideDown: return (jint) SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
|
case Desktop::upright + Desktop::upsideDown: return (jint) SCREEN_ORIENTATION_USER_PORTRAIT;
|
|
case Desktop::rotatedAntiClockwise: return (jint) SCREEN_ORIENTATION_LANDSCAPE;
|
|
case Desktop::rotatedClockwise: return (jint) SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
|
case Desktop::rotatedClockwise + Desktop::rotatedAntiClockwise: return (jint) SCREEN_ORIENTATION_USER_LANDSCAPE;
|
|
default: return (jint) SCREEN_ORIENTATION_USER;
|
|
}
|
|
}
|
|
|
|
void Desktop::allowedOrientationsChanged()
|
|
{
|
|
LocalRef<jobject> activity (getMainActivity());
|
|
|
|
if (activity != nullptr)
|
|
getEnv()->CallVoidMethod (activity.get(), AndroidActivity.setRequestedOrientation, getAndroidOrientationFlag (allowedOrientations));
|
|
}
|
|
|
|
//==============================================================================
|
|
bool juce_areThereAnyAlwaysOnTopWindows()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//==============================================================================
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (create, "<init>", "()V") \
|
|
FIELD (density, "density", "F") \
|
|
FIELD (widthPixels, "widthPixels", "I") \
|
|
FIELD (heightPixels, "heightPixels", "I")
|
|
|
|
DECLARE_JNI_CLASS (AndroidDisplayMetrics, "android/util/DisplayMetrics")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
//==============================================================================
|
|
class LayoutChangeListener : public juce::AndroidInterfaceImplementer
|
|
{
|
|
public:
|
|
virtual void onLayoutChange (LocalRef<jobject> view, int left, int top, int right, int bottom,
|
|
int oldLeft, int oldTop, int oldRight, int oldBottom) = 0;
|
|
|
|
private:
|
|
jobject invoke (jobject proxy, jobject method, jobjectArray args) override
|
|
{
|
|
auto* env = getEnv();
|
|
auto methodName = juce::juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
|
|
|
|
if (methodName == "onLayoutChange")
|
|
{
|
|
jassert (env->GetArrayLength (args) == 9);
|
|
|
|
LocalRef<jobject> view (env->GetObjectArrayElement (args, 0));
|
|
int dims[8];
|
|
|
|
for (int i = 1; i < 9; ++i)
|
|
{
|
|
LocalRef<jobject> integer (env->GetObjectArrayElement (args, i));
|
|
dims[i - 1] = env->CallIntMethod (integer.get(), JavaInteger.intValue);
|
|
}
|
|
|
|
onLayoutChange (std::move (view), dims[0], dims[1], dims[2], dims[3],
|
|
dims[4], dims[5], dims[6], dims[7]);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// invoke base class
|
|
return AndroidInterfaceImplementer::invoke (proxy, method, args);
|
|
}
|
|
|
|
std::unique_ptr<ModalComponentManager::Callback> callback;
|
|
};
|
|
|
|
//==============================================================================
|
|
struct MainActivityWindowLayoutListener : public LayoutChangeListener
|
|
{
|
|
MainActivityWindowLayoutListener (std::function<void()>&& updateDisplaysCb)
|
|
: forceDisplayUpdate (std::move (updateDisplaysCb))
|
|
{
|
|
}
|
|
|
|
void onLayoutChange (LocalRef<jobject> /*view*/, int left, int top, int right, int bottom,
|
|
int oldLeft, int oldTop, int oldRight, int oldBottom) override
|
|
{
|
|
auto newBounds = Rectangle<int>::leftTopRightBottom (left, top, right, bottom);
|
|
auto oldBounds = Rectangle<int>::leftTopRightBottom (oldLeft, oldTop, oldRight, oldBottom);
|
|
|
|
if (newBounds != oldBounds)
|
|
{
|
|
const auto& mainDisplay = *Desktop::getInstance().getDisplays().getPrimaryDisplay();
|
|
auto userArea = (newBounds.toFloat() / mainDisplay.scale).toNearestInt();
|
|
|
|
if (userArea != mainDisplay.userArea)
|
|
forceDisplayUpdate();
|
|
}
|
|
}
|
|
|
|
std::function<void()> forceDisplayUpdate;
|
|
};
|
|
|
|
//==============================================================================
|
|
void Displays::findDisplays (float masterScale)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jobject> usableSize (env->NewObject (AndroidPoint, AndroidPoint.create, 0, 0));
|
|
LocalRef<jstring> windowServiceString (javaString ("window"));
|
|
LocalRef<jobject> displayMetrics (env->NewObject (AndroidDisplayMetrics, AndroidDisplayMetrics.create));
|
|
LocalRef<jobject> windowManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get()));
|
|
LocalRef <jobject> display (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay));
|
|
|
|
jmethodID getRealMetricsMethod = env->GetMethodID (AndroidDisplay, "getRealMetrics", "(Landroid/util/DisplayMetrics;)V");
|
|
|
|
if (getRealMetricsMethod != nullptr)
|
|
env->CallVoidMethod (display.get(), getRealMetricsMethod, displayMetrics.get());
|
|
else
|
|
env->CallVoidMethod (display.get(), AndroidDisplay.getMetrics, displayMetrics.get());
|
|
|
|
env->CallVoidMethod (display.get(), AndroidDisplay.getSize, usableSize.get());
|
|
|
|
Display d;
|
|
|
|
d.isMain = true;
|
|
d.scale = env->GetFloatField (displayMetrics.get(), AndroidDisplayMetrics.density);
|
|
d.dpi = (d.scale * 160.f);
|
|
d.scale *= masterScale;
|
|
|
|
d.totalArea = Rectangle<int> (env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.widthPixels),
|
|
env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.heightPixels)) / d.scale;
|
|
|
|
d.userArea = Rectangle<int> (env->GetIntField (usableSize.get(), AndroidPoint.x),
|
|
env->GetIntField (usableSize.get(), AndroidPoint.y)) / d.scale;
|
|
|
|
// unfortunately usableSize still contains the nav bar
|
|
// the best workaround is to try to get the size of the top-level view of
|
|
// the main activity
|
|
LocalRef<jobject> activity (getMainActivity());
|
|
|
|
if (activity != nullptr)
|
|
{
|
|
LocalRef<jobject> mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow));
|
|
LocalRef<jobject> decorView (env->CallObjectMethod (mainWindow.get(), AndroidWindow.getDecorView));
|
|
LocalRef<jobject> contentView (env->CallObjectMethod (decorView.get(), AndroidView.findViewById, 0x01020002 /* android.R.id.content */));
|
|
|
|
if (contentView != nullptr)
|
|
{
|
|
Rectangle<int> activityArea (env->CallIntMethod (contentView.get(), AndroidView.getLeft),
|
|
env->CallIntMethod (contentView.get(), AndroidView.getTop),
|
|
env->CallIntMethod (contentView.get(), AndroidView.getWidth),
|
|
env->CallIntMethod (contentView.get(), AndroidView.getHeight));
|
|
|
|
if (! activityArea.isEmpty())
|
|
d.userArea = activityArea / d.scale;
|
|
|
|
if (supportsDisplayCutout())
|
|
{
|
|
jmethodID getRootWindowInsetsMethodId = env->GetMethodID (AndroidView,
|
|
"getRootWindowInsets",
|
|
"()Landroid/view/WindowInsets;");
|
|
|
|
if (getRootWindowInsetsMethodId != nullptr)
|
|
{
|
|
LocalRef<jobject> insets (env->CallObjectMethod (contentView.get(), getRootWindowInsetsMethodId));
|
|
|
|
if (insets != nullptr)
|
|
{
|
|
LocalRef<jobject> displayCutout (env->CallObjectMethod (insets.get(), AndroidWindowInsets.getDisplayCutout));
|
|
|
|
if (displayCutout.get() != nullptr)
|
|
d.safeAreaInsets = androidDisplayCutoutToBorderSize (displayCutout, d.scale);
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool hasAddedMainActivityListener = false;
|
|
|
|
if (! hasAddedMainActivityListener)
|
|
{
|
|
hasAddedMainActivityListener = true;
|
|
|
|
env->CallVoidMethod (contentView.get(), AndroidView.addOnLayoutChangeListener,
|
|
CreateJavaInterface (new MainActivityWindowLayoutListener ([this] { refresh(); }),
|
|
"android/view/View$OnLayoutChangeListener").get());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// the main activity may have not started yet so add an activity listener
|
|
if (AndroidComponentPeer::activityCallbackListener == nullptr)
|
|
{
|
|
LocalRef<jobject> appContext (getAppContext());
|
|
|
|
if (appContext.get() != nullptr)
|
|
{
|
|
AndroidComponentPeer::activityCallbackListener = GlobalRef (CreateJavaInterface (
|
|
new AndroidComponentPeer::StartupActivityCallbackListener,
|
|
"android/app/Application$ActivityLifecycleCallbacks"));
|
|
|
|
env->CallVoidMethod (appContext.get(),
|
|
AndroidApplication.registerActivityLifecycleCallbacks,
|
|
AndroidComponentPeer::activityCallbackListener.get());
|
|
}
|
|
}
|
|
}
|
|
|
|
displays.add (d);
|
|
}
|
|
|
|
//==============================================================================
|
|
Image juce_createIconForFile (const File& /*file*/)
|
|
{
|
|
return Image();
|
|
}
|
|
|
|
//==============================================================================
|
|
class MouseCursor::PlatformSpecificHandle
|
|
{
|
|
public:
|
|
PlatformSpecificHandle (const MouseCursor::StandardCursorType) {}
|
|
PlatformSpecificHandle (const CustomMouseCursorInfo&) {}
|
|
|
|
static void showInWindow (PlatformSpecificHandle*, ComponentPeer*) {}
|
|
};
|
|
|
|
//==============================================================================
|
|
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& /*files*/, bool /*canMove*/,
|
|
Component* /*srcComp*/, std::function<void()> /*callback*/)
|
|
{
|
|
jassertfalse; // no such thing on Android!
|
|
return false;
|
|
}
|
|
|
|
bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/, Component* /*srcComp*/,
|
|
std::function<void()> /*callback*/)
|
|
{
|
|
jassertfalse; // no such thing on Android!
|
|
return false;
|
|
}
|
|
|
|
//==============================================================================
|
|
void LookAndFeel::playAlertSound()
|
|
{
|
|
}
|
|
|
|
//==============================================================================
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
METHOD (getText, "getText", "()Ljava/lang/CharSequence;") \
|
|
METHOD (setText, "setText", "(Ljava/lang/CharSequence;)V")
|
|
|
|
DECLARE_JNI_CLASS (AndroidClipboardManager, "android/content/ClipboardManager")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
//==============================================================================
|
|
void SystemClipboard::copyTextToClipboard (const String& text)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jobject> clipboardManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, javaString ("clipboard").get()));
|
|
env->CallVoidMethod (clipboardManager.get(), AndroidClipboardManager.setText, javaString(text).get());
|
|
}
|
|
|
|
String SystemClipboard::getTextFromClipboard()
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
LocalRef<jobject> clipboardManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, javaString ("clipboard").get()));
|
|
LocalRef<jobject> charSequence (env->CallObjectMethod (clipboardManager.get(), AndroidClipboardManager.getText));
|
|
|
|
if (charSequence == nullptr)
|
|
return {};
|
|
|
|
return juceString(LocalRef<jstring> ((jstring) env->CallObjectMethod(charSequence.get(), JavaCharSequence.toString)));
|
|
}
|
|
|
|
//==============================================================================
|
|
constexpr int extendedKeyModifier = 0x10000;
|
|
|
|
const int KeyPress::spaceKey = ' ';
|
|
const int KeyPress::returnKey = extendedKeyModifier + 2;
|
|
const int KeyPress::escapeKey = extendedKeyModifier + 3;
|
|
const int KeyPress::backspaceKey = extendedKeyModifier + 4;
|
|
const int KeyPress::leftKey = extendedKeyModifier + 5;
|
|
const int KeyPress::rightKey = extendedKeyModifier + 6;
|
|
const int KeyPress::upKey = extendedKeyModifier + 7;
|
|
const int KeyPress::downKey = extendedKeyModifier + 8;
|
|
const int KeyPress::pageUpKey = extendedKeyModifier + 9;
|
|
const int KeyPress::pageDownKey = extendedKeyModifier + 10;
|
|
const int KeyPress::endKey = extendedKeyModifier + 11;
|
|
const int KeyPress::homeKey = extendedKeyModifier + 12;
|
|
const int KeyPress::deleteKey = extendedKeyModifier + 13;
|
|
const int KeyPress::insertKey = extendedKeyModifier + 14;
|
|
const int KeyPress::tabKey = extendedKeyModifier + 15;
|
|
const int KeyPress::F1Key = extendedKeyModifier + 16;
|
|
const int KeyPress::F2Key = extendedKeyModifier + 17;
|
|
const int KeyPress::F3Key = extendedKeyModifier + 18;
|
|
const int KeyPress::F4Key = extendedKeyModifier + 19;
|
|
const int KeyPress::F5Key = extendedKeyModifier + 20;
|
|
const int KeyPress::F6Key = extendedKeyModifier + 21;
|
|
const int KeyPress::F7Key = extendedKeyModifier + 22;
|
|
const int KeyPress::F8Key = extendedKeyModifier + 23;
|
|
const int KeyPress::F9Key = extendedKeyModifier + 24;
|
|
const int KeyPress::F10Key = extendedKeyModifier + 25;
|
|
const int KeyPress::F11Key = extendedKeyModifier + 26;
|
|
const int KeyPress::F12Key = extendedKeyModifier + 27;
|
|
const int KeyPress::F13Key = extendedKeyModifier + 28;
|
|
const int KeyPress::F14Key = extendedKeyModifier + 29;
|
|
const int KeyPress::F15Key = extendedKeyModifier + 30;
|
|
const int KeyPress::F16Key = extendedKeyModifier + 31;
|
|
const int KeyPress::F17Key = extendedKeyModifier + 32;
|
|
const int KeyPress::F18Key = extendedKeyModifier + 33;
|
|
const int KeyPress::F19Key = extendedKeyModifier + 34;
|
|
const int KeyPress::F20Key = extendedKeyModifier + 35;
|
|
const int KeyPress::F21Key = extendedKeyModifier + 36;
|
|
const int KeyPress::F22Key = extendedKeyModifier + 37;
|
|
const int KeyPress::F23Key = extendedKeyModifier + 38;
|
|
const int KeyPress::F24Key = extendedKeyModifier + 39;
|
|
const int KeyPress::F25Key = extendedKeyModifier + 40;
|
|
const int KeyPress::F26Key = extendedKeyModifier + 41;
|
|
const int KeyPress::F27Key = extendedKeyModifier + 42;
|
|
const int KeyPress::F28Key = extendedKeyModifier + 43;
|
|
const int KeyPress::F29Key = extendedKeyModifier + 44;
|
|
const int KeyPress::F30Key = extendedKeyModifier + 45;
|
|
const int KeyPress::F31Key = extendedKeyModifier + 46;
|
|
const int KeyPress::F32Key = extendedKeyModifier + 47;
|
|
const int KeyPress::F33Key = extendedKeyModifier + 48;
|
|
const int KeyPress::F34Key = extendedKeyModifier + 49;
|
|
const int KeyPress::F35Key = extendedKeyModifier + 50;
|
|
const int KeyPress::numberPad0 = extendedKeyModifier + 51;
|
|
const int KeyPress::numberPad1 = extendedKeyModifier + 52;
|
|
const int KeyPress::numberPad2 = extendedKeyModifier + 53;
|
|
const int KeyPress::numberPad3 = extendedKeyModifier + 54;
|
|
const int KeyPress::numberPad4 = extendedKeyModifier + 55;
|
|
const int KeyPress::numberPad5 = extendedKeyModifier + 56;
|
|
const int KeyPress::numberPad6 = extendedKeyModifier + 57;
|
|
const int KeyPress::numberPad7 = extendedKeyModifier + 58;
|
|
const int KeyPress::numberPad8 = extendedKeyModifier + 59;
|
|
const int KeyPress::numberPad9 = extendedKeyModifier + 60;
|
|
const int KeyPress::numberPadAdd = extendedKeyModifier + 61;
|
|
const int KeyPress::numberPadSubtract = extendedKeyModifier + 62;
|
|
const int KeyPress::numberPadMultiply = extendedKeyModifier + 63;
|
|
const int KeyPress::numberPadDivide = extendedKeyModifier + 64;
|
|
const int KeyPress::numberPadSeparator = extendedKeyModifier + 65;
|
|
const int KeyPress::numberPadDecimalPoint = extendedKeyModifier + 66;
|
|
const int KeyPress::numberPadEquals = extendedKeyModifier + 67;
|
|
const int KeyPress::numberPadDelete = extendedKeyModifier + 68;
|
|
const int KeyPress::playKey = extendedKeyModifier + 69;
|
|
const int KeyPress::stopKey = extendedKeyModifier + 70;
|
|
const int KeyPress::fastForwardKey = extendedKeyModifier + 71;
|
|
const int KeyPress::rewindKey = extendedKeyModifier + 72;
|
|
|
|
//==============================================================================
|
|
#ifdef JUCE_PUSH_NOTIFICATIONS_ACTIVITY
|
|
struct JuceActivityNewIntentListener
|
|
{
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
|
CALLBACK (appNewIntent, "appNewIntent", "(Landroid/content/Intent;)V")
|
|
|
|
DECLARE_JNI_CLASS (JavaActivity, JUCE_PUSH_NOTIFICATIONS_ACTIVITY)
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
static void JNICALL appNewIntent (JNIEnv*, jobject /*activity*/, jobject intentData)
|
|
{
|
|
juce_handleNotificationIntent (static_cast<void*> (intentData));
|
|
}
|
|
};
|
|
|
|
JuceActivityNewIntentListener::JavaActivity_Class JuceActivityNewIntentListener::JavaActivity;
|
|
#endif
|
|
|
|
} // namespace juce
|