mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-11 23:54:18 +00:00
2162 lines
108 KiB
C++
2162 lines
108 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,212,138,183,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,120,84,213,181,
|
|
199,215,62,231,204,76,50,153,36,147,73,72,2,36,100,18,2,132,144,48,147,132,231,77,144,71,0,77,8,15,73,64,9,180,50,73,38,201,
|
|
192,228,204,48,51,121,160,237,173,40,21,172,214,71,11,62,177,190,253,188,109,109,109,171,94,63,31,183,180,246,179,253,20,253,
|
|
192,226,163,214,182,86,189,214,7,229,34,31,90,175,181,114,255,107,159,61,147,9,143,210,246,134,239,55,107,157,181,223,123,175,
|
|
189,246,62,19,210,19,28,113,250,27,102,211,219,117,91,222,126,241,223,63,156,100,111,184,247,80,238,157,199,91,61,254,101,3,
|
|
151,60,183,166,252,189,89,68,81,34,26,89,63,203,67,234,167,18,182,50,97,217,231,129,35,6,81,51,228,1,27,81,49,228,177,12,162,
|
|
203,32,31,206,36,66,18,237,206,38,122,115,42,81,70,14,209,75,165,68,135,193,171,224,117,240,22,120,23,124,1,196,36,34,27,200,0,
|
|
46,224,6,249,160,8,204,1,171,193,90,176,30,116,130,47,131,110,208,15,6,192,215,193,147,224,21,240,17,215,81,70,84,3,218,192,48,
|
|
184,17,124,23,252,20,188,12,142,2,167,151,104,54,104,5,61,96,31,120,26,28,3,149,229,68,155,192,181,224,39,224,15,32,167,2,253,
|
|
0,55,131,151,192,199,96,252,100,162,249,96,19,184,12,236,5,15,130,3,224,56,112,84,18,85,131,243,192,151,192,54,112,23,120,10,
|
|
252,26,188,3,62,1,159,3,231,20,162,108,144,7,138,65,9,168,4,213,160,14,204,5,77,96,17,88,6,90,193,106,176,14,108,0,1,208,3,66,
|
|
32,2,18,224,50,176,3,124,29,124,3,124,11,220,10,238,0,119,131,71,193,115,224,21,240,22,56,10,62,3,118,172,153,7,76,2,213,96,14,
|
|
104,6,107,65,63,136,130,175,130,93,224,30,240,16,120,24,60,3,158,7,191,6,191,5,239,128,15,193,167,192,54,141,104,28,168,4,181,
|
|
96,22,184,16,92,4,58,65,0,92,9,174,3,123,193,189,224,97,240,2,248,16,124,2,178,171,48,47,96,42,168,7,139,192,10,176,25,12,130,
|
|
43,193,117,224,78,240,16,120,12,252,20,28,0,191,7,71,129,62,29,99,3,21,96,17,88,14,218,192,106,176,25,196,192,78,240,109,112,
|
|
23,120,12,252,18,188,6,254,4,78,128,204,106,248,39,168,1,115,64,19,88,8,86,128,53,32,0,162,96,7,184,22,220,6,238,3,223,7,143,
|
|
131,159,131,223,129,247,192,71,192,57,3,190,4,188,192,7,102,131,5,96,25,184,0,172,2,23,129,0,136,128,97,240,85,112,37,184,9,
|
|
124,15,60,13,14,130,63,3,170,65,255,64,13,152,5,154,65,59,8,128,48,184,12,236,4,215,129,59,192,247,192,79,192,83,224,89,240,2,
|
|
248,13,120,15,252,15,200,169,133,95,130,9,224,60,176,9,116,131,126,48,2,174,2,119,130,31,130,167,193,171,224,40,200,154,9,95,6,
|
|
211,64,3,104,6,23,130,205,32,10,190,6,110,5,119,130,251,193,67,224,81,240,36,216,15,158,5,7,193,175,193,235,224,109,240,62,248,
|
|
12,216,124,136,15,96,42,168,7,179,193,60,208,4,22,129,165,224,2,208,6,236,152,18,132,38,202,2,133,160,136,172,120,53,30,76,0,
|
|
19,65,9,64,40,34,132,15,66,120,32,132,1,194,182,39,108,115,154,204,177,15,96,107,16,92,153,224,138,4,87,34,184,2,97,249,72,77,
|
|
57,97,200,132,174,17,154,36,63,168,3,245,160,1,32,116,210,108,48,7,204,85,241,115,62,248,55,208,8,154,192,2,112,30,88,8,22,129,
|
|
197,96,9,89,49,118,25,184,0,92,12,186,64,55,232,1,65,178,198,151,252,113,40,89,83,98,141,89,168,103,167,210,217,206,243,160,41,
|
|
187,75,233,179,96,207,77,171,203,163,230,172,73,217,115,148,61,87,165,37,245,113,74,119,171,121,229,250,243,149,190,84,149,45,
|
|
78,171,147,231,186,173,196,210,121,142,59,84,158,169,105,245,76,87,245,228,41,125,19,244,2,165,247,148,88,109,242,156,135,85,
|
|
61,172,39,84,61,181,170,158,113,106,29,190,162,250,195,107,177,179,196,154,195,122,149,167,69,233,220,86,171,210,175,133,190,
|
|
66,233,220,110,155,210,111,129,190,82,233,15,66,95,165,244,71,160,175,86,250,126,232,107,148,126,0,250,133,74,63,12,189,93,233,
|
|
111,164,217,223,73,211,143,64,95,167,244,19,105,118,118,202,164,158,145,166,187,75,71,235,44,78,179,123,161,119,40,189,42,205,
|
|
94,146,86,39,207,249,90,165,247,164,245,205,159,150,159,231,115,189,210,231,193,126,145,210,23,165,229,89,147,166,95,92,106,
|
|
249,102,131,154,219,13,74,223,12,123,167,210,251,211,244,4,244,141,74,191,28,250,38,165,239,134,254,37,165,239,129,126,137,210,
|
|
239,130,254,101,165,63,152,102,103,31,219,172,244,135,97,15,40,125,127,90,254,3,165,236,231,130,182,147,37,179,4,239,251,41,20,
|
|
39,75,62,42,165,160,199,149,124,66,201,39,149,124,74,201,167,85,254,95,201,101,241,82,134,176,100,158,224,184,209,64,191,36,
|
|
150,101,148,41,56,134,88,233,101,42,189,12,41,5,130,125,190,144,182,241,58,97,215,61,38,101,25,61,43,101,41,29,146,178,129,254,
|
|
36,101,22,125,32,125,126,42,45,135,180,33,2,125,68,188,63,237,116,131,148,227,232,78,200,76,68,49,93,202,89,116,130,120,159,87,
|
|
201,231,44,101,207,66,68,248,88,142,219,122,206,69,187,215,75,89,72,55,170,231,91,148,188,139,253,74,165,187,113,131,219,163,
|
|
158,111,147,82,167,219,201,218,159,251,148,188,67,74,65,247,43,249,0,241,126,212,104,175,148,211,233,62,226,189,55,69,182,155,
|
|
143,72,247,71,41,231,211,91,82,78,164,255,38,222,167,181,52,168,228,113,226,248,60,135,158,33,142,31,46,122,73,202,241,116,140,
|
|
125,92,245,127,60,34,45,203,18,68,203,71,164,172,166,79,165,92,72,154,92,15,191,76,47,197,200,119,74,89,76,187,213,243,213,82,
|
|
206,163,35,114,157,102,202,124,147,80,227,31,136,215,199,42,87,6,123,175,146,125,82,230,82,191,148,104,95,88,210,144,235,56,85,
|
|
230,247,98,101,66,82,250,104,139,148,139,105,171,148,249,20,86,114,64,202,69,100,74,57,158,70,148,252,170,148,115,105,135,148,
|
|
229,116,141,148,30,250,166,148,217,116,157,148,118,250,182,242,151,189,42,253,38,41,103,211,205,82,102,210,119,164,116,210,221,
|
|
42,223,61,82,102,208,189,82,90,235,224,197,12,61,168,228,127,40,249,93,229,127,223,147,114,18,125,95,217,31,82,254,248,3,37,
|
|
127,168,228,195,82,122,233,71,82,54,210,143,165,156,67,63,87,242,23,82,78,166,151,165,172,160,87,148,124,85,201,215,84,250,111,
|
|
212,243,235,74,254,86,202,28,122,67,202,105,244,59,41,107,232,247,82,158,71,111,74,105,249,143,87,249,15,63,191,173,246,203,59,
|
|
82,90,254,196,249,223,149,178,137,142,74,89,79,159,40,249,23,41,103,208,103,82,78,160,207,165,172,163,191,169,231,47,84,190,
|
|
147,74,146,176,210,133,176,230,197,35,248,156,42,162,91,137,229,18,250,153,220,159,26,253,84,202,60,114,11,62,139,44,63,157,
|
|
129,29,241,45,226,243,72,167,127,151,82,163,231,137,207,164,2,218,79,124,63,24,175,252,212,218,75,201,51,18,175,82,116,24,135,
|
|
228,7,234,144,154,164,236,124,198,113,12,231,244,35,72,207,84,129,182,76,149,159,145,86,254,115,164,151,168,116,47,89,231,40,
|
|
159,129,149,170,188,11,114,169,74,231,179,127,47,218,218,103,13,151,30,168,183,108,79,66,254,28,232,42,253,0,120,69,229,249,
|
|
131,180,235,82,95,237,179,238,9,27,133,147,162,110,110,109,163,150,133,181,204,64,45,220,86,167,207,186,43,121,68,71,151,147,
|
|
182,185,27,96,207,210,10,241,122,88,167,105,198,124,205,32,135,59,143,58,186,178,104,155,119,18,197,176,235,57,95,71,183,149,
|
|
87,167,44,99,219,154,217,180,100,208,169,205,215,254,124,210,116,243,120,29,238,170,63,25,170,253,168,186,223,85,96,70,163,238,
|
|
75,229,104,185,109,238,247,165,62,235,206,117,182,182,117,68,102,143,167,97,218,248,211,219,244,207,161,37,54,23,98,197,49,180,
|
|
201,231,132,83,152,222,169,136,78,46,81,245,238,233,185,231,202,220,85,239,115,188,53,100,127,110,240,89,107,215,17,181,242,
|
|
113,74,161,38,239,33,218,124,228,241,32,174,116,108,115,166,167,107,98,167,216,235,120,96,216,62,15,35,67,28,63,166,163,191,60,
|
|
198,125,62,142,239,152,89,79,54,198,56,8,155,135,54,185,93,242,78,150,129,39,30,235,253,62,235,108,205,183,23,80,133,230,66,62,
|
|
158,133,142,120,54,117,52,228,144,233,110,70,46,151,152,47,154,70,109,222,243,177,23,71,115,44,66,14,167,190,22,23,221,181,83,
|
|
4,253,168,227,70,210,141,217,155,39,208,186,56,230,65,47,36,143,190,9,90,50,127,71,34,27,253,246,97,36,46,131,251,111,200,121,
|
|
152,69,205,54,206,63,95,119,208,220,205,54,242,228,115,25,110,171,16,241,205,116,143,227,145,157,210,70,213,139,188,150,236,
|
|
115,7,125,214,29,110,163,39,71,141,179,2,115,24,245,86,195,195,55,186,65,126,174,28,179,144,255,136,222,244,89,223,51,68,221,
|
|
124,219,206,73,217,223,75,217,235,164,93,83,183,224,99,62,203,159,59,220,185,114,79,176,7,113,187,159,250,172,123,112,135,55,
|
|
23,125,92,202,59,132,58,202,221,232,245,68,180,156,147,202,119,242,172,249,74,100,190,28,120,60,143,196,142,238,28,96,191,115,
|
|
120,10,163,222,34,196,219,10,35,11,189,177,163,87,27,247,20,226,169,140,162,254,26,218,147,185,113,79,62,158,74,241,52,69,62,
|
|
21,160,222,133,88,107,151,49,193,22,69,189,88,65,232,101,70,33,202,229,81,137,97,131,45,134,120,238,52,230,25,95,162,50,39,63,
|
|
227,253,146,58,247,121,160,153,184,225,108,186,125,28,180,62,156,73,166,183,95,126,134,16,175,42,80,103,212,45,207,97,163,128,
|
|
38,47,158,69,83,5,223,0,77,175,129,158,119,112,159,108,216,191,94,27,113,141,14,180,234,209,77,247,144,234,201,255,146,103,234,
|
|
228,222,57,24,79,87,70,17,173,204,176,59,60,69,37,25,89,82,51,253,219,168,195,238,210,231,233,5,228,209,60,149,147,151,206,37,
|
|
143,109,155,59,129,121,112,217,87,218,13,155,103,156,71,74,211,191,157,190,109,176,167,177,119,243,168,172,222,239,161,170,187,
|
|
179,141,170,19,224,56,56,6,94,7,124,88,232,134,188,247,143,254,92,190,144,254,169,231,83,127,172,116,190,59,22,98,63,114,180,
|
|
224,123,139,166,87,221,42,166,221,44,102,238,21,90,205,29,162,250,118,65,42,186,224,158,234,183,124,166,221,235,145,113,214,
|
|
144,145,15,239,208,126,229,99,254,149,84,174,231,96,207,219,100,188,219,233,183,98,108,116,93,47,149,55,59,165,63,39,203,220,
|
|
152,76,243,47,70,25,151,244,193,100,218,109,169,180,5,169,52,135,188,237,17,221,171,210,134,236,107,101,100,224,58,109,106,223,
|
|
255,216,111,237,153,246,69,158,180,248,162,195,23,217,18,245,183,226,182,82,245,217,232,120,158,80,117,241,123,112,39,198,148,
|
|
163,250,192,63,251,253,86,236,247,184,115,83,123,230,57,127,114,207,20,200,62,37,237,7,149,125,29,246,116,174,178,115,202,43,
|
|
126,235,93,211,116,47,147,125,149,177,14,245,121,168,234,11,93,181,243,134,223,58,71,114,100,57,235,77,244,157,52,155,93,197,
|
|
239,15,207,49,182,11,212,216,146,249,79,156,35,127,75,106,46,172,126,252,237,12,253,176,213,157,110,115,165,217,12,213,86,126,
|
|
157,245,253,128,71,240,55,8,27,253,26,89,82,167,13,117,136,123,199,54,248,29,180,193,111,87,214,76,248,49,86,210,189,193,111,
|
|
32,61,3,251,113,60,250,83,78,94,145,167,198,203,107,82,81,103,157,213,103,238,127,199,146,66,138,174,189,144,140,11,171,62,101,
|
|
223,208,165,255,85,159,181,76,195,178,147,39,229,184,23,53,145,17,224,50,46,180,195,103,245,92,100,226,187,170,103,188,135,218,
|
|
239,65,57,62,17,133,102,204,195,25,222,113,119,30,214,174,148,215,14,167,133,78,28,233,178,177,87,156,25,166,59,7,50,203,254,
|
|
242,142,147,52,67,240,119,19,85,199,219,239,230,184,227,230,116,196,139,60,150,134,233,246,176,180,57,238,26,202,224,55,99,113,
|
|
67,213,239,207,149,111,149,149,239,185,115,229,91,99,229,227,23,39,97,200,239,58,120,14,120,61,248,254,196,223,193,56,241,196,
|
|
123,166,187,206,250,174,197,227,110,143,141,142,112,190,176,78,222,26,126,149,38,78,49,113,142,102,162,118,211,157,197,210,238,
|
|
216,38,118,14,217,87,96,252,85,127,142,248,139,105,87,38,78,226,247,76,247,124,180,86,197,23,77,205,154,247,228,247,71,44,243,
|
|
21,46,117,246,239,168,179,222,59,49,187,87,160,109,187,108,219,110,205,230,252,204,76,180,153,201,35,18,158,138,250,114,7,69,
|
|
22,141,167,91,158,64,43,199,77,183,19,118,151,152,39,248,166,99,233,166,119,152,215,194,198,53,113,31,179,184,143,59,196,30,
|
|
171,143,30,119,213,171,150,47,176,255,220,89,103,125,239,49,214,23,172,17,179,141,199,106,39,167,22,93,219,6,47,66,217,143,73,
|
|
69,24,162,135,210,124,60,83,197,178,39,149,111,69,46,158,64,29,67,233,181,206,67,155,214,158,138,98,79,113,153,92,229,91,7,144,
|
|
92,130,138,218,15,33,183,206,35,23,186,156,117,145,43,216,147,114,200,153,201,158,4,95,114,188,124,35,123,210,39,114,23,85,125,
|
|
212,254,146,7,146,87,127,146,92,245,60,206,107,227,213,207,225,49,31,98,47,193,136,243,170,222,56,119,206,53,86,206,95,158,59,
|
|
231,106,228,52,221,124,175,112,102,121,242,230,78,172,38,79,249,228,146,217,240,194,37,244,2,121,38,204,126,162,156,184,22,174,
|
|
227,7,92,135,55,159,165,240,216,150,218,92,182,43,214,61,59,206,244,22,88,150,194,165,118,151,253,138,222,103,11,147,245,190,
|
|
230,116,138,170,55,209,143,43,241,230,143,151,138,71,111,252,163,83,100,204,119,22,211,63,58,130,233,212,123,50,189,63,255,74,
|
|
79,184,166,170,223,254,243,61,88,165,122,48,229,255,221,131,85,178,7,188,103,173,111,39,217,183,56,46,250,148,228,253,203,239,
|
|
242,113,233,123,154,188,67,53,215,91,223,165,162,143,184,135,56,200,165,77,208,255,74,158,130,201,75,113,15,177,117,217,113,15,
|
|
145,119,138,109,84,111,240,189,214,129,126,103,227,140,1,159,123,60,147,43,112,11,209,249,22,146,129,155,198,74,67,211,249,246,
|
|
177,77,171,58,154,173,85,29,1,31,128,247,216,223,243,208,183,137,114,239,34,10,107,53,133,213,197,122,85,213,180,154,153,213,
|
|
105,241,63,82,63,186,55,116,101,29,174,183,238,228,243,52,7,241,140,132,145,35,135,60,139,170,254,202,227,179,206,136,203,235,
|
|
173,56,192,119,58,190,125,79,208,254,75,222,233,202,209,90,25,222,39,231,33,122,152,238,17,236,80,167,88,32,242,49,219,166,191,
|
|
146,252,24,241,114,153,223,244,79,38,183,209,81,151,143,155,118,173,172,63,153,226,209,76,127,5,185,53,43,109,38,207,239,113,
|
|
235,247,108,252,147,252,206,151,191,167,46,128,173,36,249,229,173,250,169,58,229,121,222,41,207,92,190,128,172,187,64,30,122,
|
|
39,148,141,241,42,153,161,210,61,234,220,159,160,236,101,74,106,10,175,154,175,25,52,87,218,107,149,189,22,209,217,146,66,198,
|
|
83,161,254,217,104,244,142,161,41,223,72,222,45,140,148,46,148,221,145,250,46,91,195,76,139,84,126,150,217,169,50,44,237,42,
|
|
205,78,13,50,157,109,14,37,51,149,76,126,23,158,35,123,69,234,190,195,99,108,80,99,241,74,123,131,242,225,134,84,175,173,242,
|
|
179,148,156,173,202,37,251,201,50,91,181,207,122,110,42,61,55,109,76,217,169,177,22,165,250,97,213,237,86,237,121,83,57,173,
|
|
113,121,85,110,65,214,251,191,168,34,188,223,217,155,66,102,40,113,30,105,231,53,82,97,115,100,32,26,49,131,102,98,77,48,24,91,
|
|
31,10,14,207,220,18,24,10,144,88,78,218,242,22,18,45,164,181,76,7,80,91,73,107,109,163,210,214,193,238,224,226,238,238,96,60,
|
|
30,234,10,133,67,137,237,171,34,61,193,53,177,200,80,168,39,24,163,162,21,193,237,93,145,64,172,103,105,40,62,16,138,199,219,
|
|
66,241,68,208,68,130,104,35,173,13,181,181,161,154,182,54,210,219,240,128,143,86,254,104,163,194,182,128,217,19,139,132,122,
|
|
124,129,104,212,183,184,59,17,26,66,205,141,52,107,172,61,26,13,135,186,3,137,80,196,172,76,230,105,11,245,6,187,183,119,135,
|
|
131,205,129,112,184,43,208,189,53,222,72,227,207,86,42,61,169,59,98,162,103,9,95,51,203,145,68,122,82,95,44,16,237,15,117,199,
|
|
125,205,1,115,40,128,10,39,157,33,41,18,142,196,150,135,194,137,96,236,236,233,43,3,137,88,104,164,145,166,255,221,244,49,85,
|
|
21,159,158,117,77,32,100,162,127,69,167,167,172,13,118,35,33,63,149,16,137,251,150,12,154,61,225,96,35,21,164,27,91,150,132,
|
|
204,30,174,125,180,142,33,44,181,15,139,181,108,40,200,149,79,24,155,176,50,194,211,165,210,166,143,77,99,39,169,92,109,46,143,
|
|
116,15,198,155,251,3,102,95,48,185,200,233,93,73,101,77,31,82,202,120,126,44,50,24,109,164,57,167,167,116,196,130,193,213,93,
|
|
241,96,108,40,24,67,43,231,135,35,93,129,112,91,96,123,100,48,49,218,76,217,223,47,215,72,117,99,51,4,210,253,213,55,198,123,
|
|
87,6,204,64,31,23,169,255,135,139,176,195,183,152,189,145,211,250,127,142,50,201,77,210,72,51,199,150,11,153,209,193,196,64,48,
|
|
209,31,233,241,45,9,196,81,57,158,225,151,38,150,87,122,237,148,179,231,95,214,19,74,68,98,86,119,170,207,158,237,180,42,107,
|
|
207,145,119,165,212,83,179,179,176,173,59,50,224,139,13,196,195,190,45,8,0,190,211,194,70,229,223,141,11,141,180,252,156,21,
|
|
156,37,114,84,142,93,217,249,255,106,61,141,84,126,174,162,141,84,209,214,19,8,15,133,182,250,2,166,25,73,200,152,225,91,102,
|
|
118,135,35,241,144,217,215,28,14,196,101,48,56,61,79,11,38,54,166,210,203,207,144,190,50,56,208,165,50,4,145,165,244,12,89,218,
|
|
67,125,102,32,49,24,11,242,134,225,24,236,11,99,111,249,176,195,98,237,193,109,131,65,179,27,41,121,233,41,86,115,21,105,166,
|
|
150,112,56,216,23,8,91,203,176,108,164,59,24,181,22,187,242,12,121,98,125,131,3,24,123,90,174,252,244,92,8,138,125,214,164,141,
|
|
26,87,69,218,7,187,251,45,207,72,43,231,73,203,178,186,107,139,140,73,165,105,182,246,96,247,96,12,14,113,150,34,237,136,129,
|
|
102,31,123,228,168,45,22,236,13,163,30,116,99,40,98,133,238,142,64,172,47,152,222,219,9,103,200,110,117,173,145,198,89,105,131,
|
|
137,80,216,183,56,22,11,108,103,39,104,164,220,52,51,91,200,125,138,161,145,140,142,13,107,150,145,43,221,231,72,172,39,109,
|
|
125,11,217,214,183,224,7,106,43,217,215,183,182,44,95,222,74,6,36,39,180,114,2,30,248,96,91,223,218,137,60,172,240,225,182,94,
|
|
154,218,58,145,218,214,137,163,111,125,39,10,119,202,138,68,39,233,157,92,14,31,109,172,182,145,173,179,149,117,3,2,199,101,39,
|
|
91,113,76,218,59,219,164,217,198,18,246,141,56,155,55,182,144,103,227,233,206,144,191,241,12,107,225,180,226,82,165,223,239,79,
|
|
233,117,105,122,125,154,222,144,166,207,74,211,103,167,233,115,210,244,185,105,250,60,232,89,150,190,60,28,232,139,83,246,152,
|
|
128,72,5,129,51,4,94,178,7,100,68,226,146,44,219,2,93,193,48,101,4,212,241,78,227,3,61,61,103,62,6,40,51,160,124,56,78,162,139,
|
|
242,248,240,95,50,152,72,68,204,53,49,52,19,236,33,123,87,4,143,3,144,242,80,36,123,183,60,207,201,209,45,143,173,30,178,225,
|
|
222,16,136,81,86,55,135,170,8,78,217,197,9,126,72,157,204,148,35,31,58,98,1,51,222,27,137,13,80,54,223,26,112,28,199,101,110,
|
|
84,100,93,30,80,81,100,16,207,19,187,99,193,64,226,244,48,200,225,153,140,158,80,111,47,137,32,217,130,124,174,146,183,23,135,
|
|
242,25,179,198,151,108,239,224,90,51,57,135,60,103,201,214,43,133,171,119,244,212,237,161,44,249,196,145,171,165,135,38,98,123,
|
|
140,169,109,121,90,98,201,169,137,99,46,109,153,50,85,174,194,56,86,71,47,76,234,114,68,217,48,115,36,194,178,4,99,113,202,224,
|
|
71,246,56,114,178,166,50,185,120,131,242,208,58,66,3,65,89,233,5,193,80,95,127,130,242,161,202,67,37,189,75,108,108,83,155,123,
|
|
181,217,142,153,11,154,178,10,108,226,64,59,130,162,85,133,181,165,41,23,170,156,115,68,81,57,213,174,81,3,42,115,224,105,109,
|
|
96,248,226,164,178,129,178,88,137,68,18,220,26,185,241,208,190,29,110,51,208,142,45,29,234,14,82,14,44,235,204,16,47,60,143,75,
|
|
246,230,212,107,132,28,245,250,80,202,127,185,204,69,88,145,200,112,71,100,43,58,91,146,122,150,153,194,65,156,56,209,112,96,
|
|
251,242,88,0,227,55,144,122,177,252,220,64,162,159,114,177,102,240,65,204,237,154,192,32,59,167,59,101,88,27,140,195,141,83,
|
|
150,37,41,63,166,108,203,130,19,109,105,100,24,91,36,245,184,46,74,5,169,7,121,218,93,16,234,233,65,159,84,51,43,35,104,67,150,
|
|
25,99,136,5,250,146,117,74,3,170,81,117,202,59,38,229,171,135,96,140,189,93,185,68,70,127,32,110,57,97,81,63,220,165,61,210,
|
|
171,22,51,22,25,176,134,143,44,40,45,93,214,232,143,32,174,138,16,57,225,3,171,101,168,142,147,30,26,24,160,92,126,233,8,5,194,
|
|
205,129,104,124,37,166,157,178,149,161,61,24,94,102,246,164,210,241,136,213,143,193,251,229,157,164,99,123,52,72,46,169,94,98,
|
|
221,79,40,3,141,173,15,132,7,177,161,67,56,31,182,6,209,88,188,197,140,39,2,56,35,145,26,95,29,13,224,192,164,241,161,120,71,4,
|
|
7,214,178,145,40,54,177,116,180,101,102,0,235,212,131,186,227,106,205,200,177,53,184,189,153,251,83,180,245,44,175,46,217,201,
|
|
132,246,126,158,81,91,88,134,168,108,172,116,48,198,221,91,133,75,4,25,225,96,111,130,236,225,160,217,151,232,39,187,234,170,
|
|
48,201,48,217,27,28,102,112,120,21,43,25,102,50,30,184,204,244,61,104,143,116,113,96,33,35,18,238,233,151,159,195,148,23,49,
|
|
147,175,57,205,50,176,96,215,140,154,150,6,227,137,88,100,59,59,206,168,81,57,87,90,201,164,119,77,28,53,181,7,134,130,201,249,
|
|
178,118,90,90,126,57,249,99,171,104,79,68,162,81,152,138,16,16,100,63,78,185,77,162,243,38,124,107,152,178,35,233,175,5,148,19,
|
|
25,19,184,201,21,49,47,136,96,99,201,32,65,153,17,51,233,216,217,82,93,57,24,78,132,162,188,36,242,17,206,153,193,231,129,44,
|
|
138,28,237,161,75,131,201,200,135,154,172,165,149,53,217,35,214,130,59,44,121,9,202,13,34,148,39,16,169,108,81,233,216,206,104,
|
|
32,134,156,50,24,100,71,199,184,183,45,42,67,121,105,52,18,29,12,159,53,120,139,24,57,98,214,139,38,85,196,130,125,236,27,177,
|
|
179,191,131,82,73,44,56,128,161,90,195,95,109,158,114,114,217,98,50,46,234,241,96,130,114,226,28,65,83,111,128,228,194,179,156,
|
|
68,246,84,42,74,127,106,177,6,45,119,15,23,75,187,168,203,98,109,73,143,164,98,60,157,241,21,141,198,197,147,161,112,93,40,45,
|
|
182,77,60,163,153,111,200,1,28,137,113,43,56,74,7,206,142,143,9,138,206,228,99,216,234,211,69,161,112,120,85,36,33,221,193,21,
|
|
199,134,73,6,40,20,196,83,42,122,32,51,59,154,213,47,220,255,144,12,47,27,125,44,142,91,189,105,25,109,75,141,212,144,135,141,
|
|
145,232,15,197,201,206,159,149,126,37,235,96,229,163,71,71,77,80,121,34,50,6,19,189,243,100,132,23,67,100,27,146,81,195,33,197,
|
|
234,94,50,248,213,135,114,249,51,221,185,50,217,208,17,89,23,15,146,123,232,180,51,97,40,20,75,12,6,194,234,20,115,14,141,78,
|
|
133,24,38,49,66,218,136,31,212,129,122,208,0,102,145,216,78,143,25,26,237,209,28,57,157,181,244,180,33,110,210,28,165,90,214,
|
|
33,109,164,116,139,78,135,68,241,91,43,232,69,67,219,165,193,158,67,135,13,113,141,112,148,62,175,93,90,122,92,167,111,138,234,
|
|
218,111,217,136,222,54,244,155,180,248,176,35,231,153,50,58,161,9,66,85,77,244,87,141,28,53,27,117,237,152,200,190,90,23,71,68,
|
|
254,204,145,191,232,116,149,208,182,52,137,188,188,80,147,22,47,181,81,147,200,178,163,188,102,117,64,155,179,65,91,49,92,75,
|
|
111,106,226,54,110,237,84,249,62,170,204,121,132,142,90,162,73,191,82,188,47,254,83,56,106,180,67,212,168,93,175,13,107,7,197,
|
|
240,136,118,232,178,55,119,11,205,230,92,92,219,52,179,169,233,188,141,58,93,46,156,95,209,197,14,49,187,233,129,114,93,127,65,
|
|
248,69,209,56,255,36,93,123,78,104,34,175,200,166,105,23,162,43,54,97,211,237,78,109,198,125,54,167,157,236,194,174,217,245,
|
|
234,106,109,168,198,166,85,107,241,26,154,107,117,97,174,118,155,118,187,84,12,86,246,105,119,140,181,166,20,91,50,249,59,252,
|
|
184,143,187,252,141,18,26,130,88,65,31,235,218,173,218,157,108,63,110,192,64,187,121,202,232,67,157,63,111,55,180,193,203,32,
|
|
247,26,98,16,226,164,206,2,37,31,144,207,215,148,208,245,42,195,221,86,134,171,45,113,143,46,62,192,194,172,88,81,219,185,162,
|
|
115,38,125,77,124,69,150,250,153,142,121,121,68,160,224,196,90,122,87,136,221,60,91,197,95,104,91,75,87,232,25,113,173,77,183,
|
|
95,163,233,90,86,191,200,207,213,134,75,241,233,101,109,164,148,238,215,180,103,57,119,233,46,109,92,169,54,80,170,229,54,206,
|
|
92,17,212,6,91,55,105,219,91,233,121,77,127,86,236,148,233,90,222,85,90,172,244,166,141,91,118,235,182,235,52,205,23,92,72,63,
|
|
83,101,115,118,121,75,110,162,39,116,219,87,159,23,215,106,39,196,165,232,231,143,116,227,22,237,65,241,178,56,140,244,5,187,
|
|
58,233,102,97,101,213,126,69,165,218,19,95,67,191,50,185,95,14,238,215,51,180,65,91,84,131,30,249,45,220,109,122,214,139,66,91,
|
|
208,164,187,142,138,57,11,132,208,157,143,11,173,86,148,100,47,180,57,109,174,58,91,214,22,187,115,166,200,47,212,46,107,108,
|
|
178,187,22,136,210,113,108,31,107,212,150,139,210,28,58,168,139,155,177,0,94,93,92,165,249,133,167,80,115,213,96,148,101,58,
|
|
237,18,181,147,108,36,149,25,147,109,244,71,127,53,29,208,197,65,116,145,142,233,98,196,145,19,42,161,171,53,241,77,20,254,133,
|
|
78,79,136,210,153,91,86,140,108,30,191,139,180,114,113,189,86,236,213,42,180,136,225,121,81,20,101,107,149,48,148,56,138,68,
|
|
209,162,162,204,162,165,69,90,81,117,145,97,229,42,147,185,52,228,58,63,149,63,71,155,204,249,69,241,36,75,209,138,75,139,203,
|
|
72,19,134,243,6,175,240,76,217,113,185,177,191,100,170,120,179,68,136,253,165,66,188,1,94,155,132,100,225,210,196,13,222,234,
|
|
203,47,55,238,43,155,33,126,85,70,186,157,114,184,132,240,212,160,204,181,229,98,183,247,41,254,56,204,31,71,202,133,182,179,
|
|
66,104,223,175,32,123,209,196,60,15,54,128,199,250,87,143,204,135,43,144,229,174,169,248,120,156,63,14,242,199,17,254,216,61,
|
|
13,31,247,77,51,174,208,72,0,150,14,165,255,35,20,0,39,152,47,246,79,19,226,24,184,182,74,23,119,85,141,19,143,87,9,113,16,156,
|
|
0,187,167,11,177,15,28,0,159,131,27,170,133,184,15,60,14,174,157,129,97,131,19,224,181,90,33,14,207,68,62,159,48,118,251,133,
|
|
177,207,143,58,252,54,113,203,108,228,159,163,137,199,193,27,115,220,105,191,15,72,202,228,223,255,240,247,211,201,191,1,226,
|
|
239,173,147,127,7,148,252,221,40,255,45,16,127,103,157,252,123,32,59,141,254,77,144,238,182,210,248,247,21,194,107,253,30,104,
|
|
17,116,187,215,202,195,255,255,77,184,45,59,255,159,55,205,107,181,203,127,67,164,171,252,252,255,206,12,175,245,123,136,189,
|
|
245,214,47,38,184,172,252,127,115,110,171,175,252,247,74,255,7,252,145,236,168,232,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));
|
|
}
|
|
|
|
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::invalidPressure,
|
|
MouseInputSource::invalidOrientation,
|
|
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::invalidPressure,
|
|
MouseInputSource::invalidOrientation,
|
|
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::invalidPressure,
|
|
MouseInputSource::invalidOrientation,
|
|
time,
|
|
{},
|
|
index);
|
|
}
|
|
|
|
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 (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 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;
|
|
bm.data = (uint8*) (data + x + y * width);
|
|
}
|
|
|
|
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
|