/* ============================================================================== 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,174,115,161,94,0,3,106,97,118,97,67,111,109,112,111,110,101,110,116,80,101,101,114,86,105,101,119,46,100,101,120,0, 165,154,9,120,91,213,149,199,207,189,79,139,45,203,178,44,111,137,45,39,242,26,37,113,108,153,0,113,176,3,89,77,157,56,100,177, 146,18,59,52,60,75,207,182,18,249,61,69,146,237,4,232,16,150,38,41,100,90,104,3,221,82,186,165,25,74,51,109,153,161,148,73,75, 39,3,101,107,25,26,104,233,164,45,75,232,199,180,64,7,62,160,105,203,116,33,243,191,247,93,217,202,86,218,142,252,253,116,206, 59,247,220,253,222,115,175,100,197,141,29,158,200,252,139,40,84,84,16,62,178,99,227,93,78,119,55,171,63,246,210,255,110,45,251, 64,100,247,111,158,226,203,231,16,165,136,104,199,198,11,3,164,94,187,102,19,253,154,108,123,59,8,58,136,22,64,158,128,44,135, 204,186,137,12,200,242,2,34,13,178,171,136,232,238,25,68,7,32,127,82,69,116,28,156,0,239,128,63,130,83,128,79,35,114,129,66,80, 12,154,193,108,48,15,180,131,139,193,21,224,102,240,57,112,4,60,11,126,11,42,166,19,45,6,253,32,3,246,130,187,192,183,192,143, 192,187,160,172,26,101,1,3,236,6,247,131,231,65,97,13,81,7,216,5,190,13,94,0,60,72,84,15,86,128,45,32,13,238,4,223,1,79,131,147, 160,160,150,104,22,232,4,91,193,110,176,15,124,26,124,22,124,1,220,13,14,131,251,192,17,112,20,60,2,158,0,79,129,31,129,227, 224,5,240,11,240,26,120,29,188,13,222,1,127,6,12,227,230,2,30,224,3,245,96,1,88,6,214,128,1,48,12,50,96,23,216,11,238,0,159,3, 71,192,131,224,24,56,14,78,128,87,192,91,224,29,224,156,73,20,0,245,160,29,92,2,150,128,203,193,74,176,14,108,1,91,193,13,224, 54,240,105,112,8,220,7,254,29,252,24,188,8,222,4,239,2,119,136,200,15,106,65,27,184,12,68,65,12,100,192,237,224,19,224,179,224, 243,224,94,240,48,120,22,188,12,222,2,238,58,162,105,96,54,232,0,43,192,26,48,2,210,96,7,184,22,236,1,251,192,103,193,97,240, 32,120,28,252,4,188,0,94,3,39,193,41,80,80,79,84,7,34,96,1,232,6,189,32,10,54,131,45,192,0,38,200,130,107,192,63,130,47,130,251, 192,99,224,101,240,123,224,105,32,106,0,115,193,37,96,37,216,0,226,96,20,76,128,221,96,63,56,0,190,12,190,14,238,7,15,129, 39,192,147,224,77,224,107,196,250,5,213,96,14,232,0,235,128,14,44,240,97,240,121,240,32,248,62,248,41,248,111,240,91,160,53,97, 254,64,61,104,7,171,192,58,176,9,232,96,24,36,65,26,92,7,174,7,187,193,71,193,29,224,16,184,23,60,12,126,8,158,1,207,130,159, 130,231,155,236,189,235,4,216,206,228,3,37,192,15,74,129,8,6,101,100,239,247,10,80,9,176,141,9,219,145,176,221,8,91,139,106,68, 108,0,88,198,132,229,70,88,30,132,233,37,76,7,97,24,9,221,39,116,131,80,21,53,131,89,32,12,16,94,8,97,135,230,130,22,48,15, 180,130,54,16,81,49,231,2,48,31,92,8,46,2,29,224,114,176,26,92,1,214,128,181,100,247,33,247,114,40,121,115,165,221,47,166,158, 93,74,23,118,209,87,174,236,5,74,223,7,187,71,249,137,151,87,165,237,87,118,159,178,123,212,184,228,244,138,60,127,49,46,7,42, 109,93,140,201,65,149,183,78,249,20,169,177,16,109,40,86,227,113,88,249,11,253,62,229,31,86,254,197,106,140,190,83,105,247,125, 174,178,47,84,186,40,231,18,165,127,15,122,167,210,143,65,239,82,250,113,232,139,148,254,10,244,75,149,126,18,250,101,185,50, 49,169,139,149,94,0,125,169,210,253,121,246,105,121,122,8,250,114,165,135,243,236,23,230,233,93,121,250,242,188,50,123,243,236, 81,232,203,148,190,57,207,158,173,156,210,197,24,46,81,122,60,175,156,100,158,191,24,183,21,185,188,176,119,43,253,186,60,159, 125,121,250,254,42,123,29,181,168,241,124,159,210,15,192,222,163,244,131,208,87,42,253,27,208,123,149,254,0,244,85,74,63,154, 103,127,60,207,126,172,74,204,41,163,171,200,150,63,151,67,28,162,43,149,252,168,148,140,62,166,228,126,37,239,80,242,78,37,63, 161,252,63,79,98,175,181,208,231,164,172,161,159,146,216,119,65,58,174,228,75,82,86,211,203,36,214,29,167,219,164,172,161,187, 164,108,161,111,75,89,68,223,149,235,175,142,46,38,177,55,106,233,33,18,235,221,69,163,82,250,233,26,200,66,236,120,38,229,60, 122,132,196,122,172,147,207,69,202,94,132,221,243,168,236,151,253,92,130,250,146,82,150,146,169,158,175,21,107,71,217,253,216, 145,219,213,243,152,148,26,141,147,29,99,38,148,220,33,37,163,93,74,222,64,98,143,113,74,75,89,79,215,147,136,67,51,100,125, 101,136,10,223,148,178,157,238,151,178,130,254,141,196,62,108,166,126,37,31,38,17,171,154,164,255,116,68,144,143,72,217,64,79, 72,121,17,253,72,142,227,44,153,94,141,18,238,147,227,55,91,62,215,192,190,78,201,245,82,122,169,79,202,50,250,177,146,207,202, 241,156,41,253,131,24,201,168,148,97,218,32,101,25,109,86,82,151,50,34,239,73,65,212,180,77,74,151,188,83,5,85,255,130,136,122, 25,41,11,105,167,148,30,186,78,165,127,80,202,2,250,7,41,237,113,8,162,103,55,41,121,179,146,31,146,114,26,237,86,114,143,178, 239,149,178,138,62,172,228,45,74,222,42,229,116,218,39,101,27,125,70,201,3,82,6,233,30,181,126,190,170,228,97,37,255,89,165,127, 77,61,127,93,201,111,168,245,117,175,148,33,250,23,41,155,232,95,165,180,231,43,168,230,75,60,127,75,173,203,7,164,180,231, 47,136,40,127,68,202,185,244,152,146,143,75,217,72,63,144,178,156,254,83,202,57,244,148,122,254,161,242,59,166,228,211,42,253, 25,213,255,95,144,136,189,1,202,74,121,49,125,90,174,127,31,157,32,17,111,237,245,219,140,40,107,145,136,185,26,13,74,201,233, 75,36,226,110,9,125,138,236,51,142,200,142,207,34,46,137,179,98,57,228,199,85,144,174,81,107,184,89,249,137,244,40,210,15,169, 116,113,14,148,146,125,142,94,167,242,199,33,159,10,79,249,111,129,62,20,182,207,177,20,228,4,184,33,108,159,87,183,72,59,151, 250,137,38,177,47,113,31,12,20,81,202,127,53,108,1,218,236,247,200,179,169,0,79,34,255,171,240,25,16,245,185,202,169,158,123, 225,87,128,220,209,76,17,69,231,123,201,244,95,0,47,47,11,208,66,214,53,101,13,93,140,221,49,229,19,129,143,71,91,143,163,106, 125,19,163,123,163,183,147,230,184,232,234,106,218,144,241,80,135,86,73,1,109,51,180,156,127,52,91,68,219,253,77,216,231,94,199, 118,255,108,200,34,199,246,200,28,90,230,20,254,11,53,55,45,184,218,73,129,50,145,199,135,186,42,48,23,166,191,28,237,61,179, 142,240,83,226,252,214,228,152,248,154,237,187,200,64,192,171,250,90,143,185,72,133,66,24,237,1,191,143,6,202,138,101,191,153, 252,195,221,163,217,62,251,83,126,49,19,190,73,123,243,164,125,150,180,115,117,35,104,109,182,199,59,234,47,150,243,163,193, 46,234,189,184,217,62,143,163,161,98,180,82,220,62,208,195,58,209,238,106,212,236,155,244,91,116,94,191,26,233,231,67,92,16,61, 89,14,63,177,238,3,174,64,69,42,84,73,95,161,122,135,152,61,23,90,53,176,31,209,205,81,67,41,92,88,247,23,14,236,247,227,83, 150,19,37,124,128,14,146,199,209,225,184,138,102,122,196,51,110,228,212,127,160,4,90,63,37,104,243,103,16,105,67,125,180,9,239, 81,249,190,1,43,181,30,43,35,229,23,61,42,115,148,83,195,146,121,212,204,68,28,51,67,14,180,39,42,106,114,122,48,126,78,18, 37,186,17,179,2,154,233,215,145,203,235,168,118,126,159,2,205,13,67,109,20,112,15,22,148,209,234,2,151,59,80,21,44,40,146,154, 25,185,138,162,46,175,214,161,149,83,128,7,26,27,150,71,40,224,220,238,223,130,222,121,93,171,93,14,103,160,34,32,165,25,137, 211,199,29,24,3,63,230,22,229,206,116,216,173,223,79,225,47,20,59,194,39,193,219,224,77,240,51,112,28,83,46,239,150,83,175,93, 151,209,223,244,124,230,203,78,23,231,118,37,226,145,65,246,121,194,181,134,155,89,253,141,108,246,46,198,103,237,101,77,187, 153,61,223,226,117,143,90,7,125,161,18,185,143,197,250,19,207,247,230,214,77,164,139,234,52,49,155,246,254,58,162,214,101,223, 226,18,170,228,242,158,202,23,34,197,39,45,169,200,66,114,176,240,31,166,202,127,168,217,190,135,138,187,115,63,234,240,169, 58,196,235,241,102,123,255,7,252,37,147,235,242,25,213,158,13,254,82,89,15,87,235,248,120,179,125,55,52,253,23,138,157,131,59, 160,67,230,11,80,248,93,77,149,247,66,179,29,51,124,50,159,125,195,253,101,158,205,5,155,240,124,253,61,250,176,64,245,33,231, 255,187,247,240,239,152,236,179,221,142,83,231,104,135,123,214,217,54,95,158,205,161,234,170,152,101,223,151,3,76,68,222,129,8, 39,91,106,180,169,29,81,228,205,77,17,55,109,138,184,148,181,16,235,7,55,118,255,166,136,3,233,5,216,5,149,104,15,206,32,86, 170,250,43,198,190,113,150,29,131,207,221,254,232,210,0,165,214,47,38,199,186,240,59,226,179,129,38,231,189,229,188,121,230,175, 56,117,74,246,123,113,43,57,116,145,167,16,118,81,207,194,89,246,103,151,128,191,111,16,185,80,76,59,227,142,133,12,51,133, 241,107,113,139,207,78,34,197,244,23,33,94,123,88,106,221,37,212,156,9,255,198,138,84,209,120,129,135,194,111,152,254,185,104, 117,248,53,49,72,118,59,114,159,181,196,103,142,98,133,7,41,162,190,190,89,246,231,166,0,155,172,143,163,62,228,44,97,11,221, 133,168,167,16,109,243,240,64,195,5,23,184,201,90,60,141,198,63,233,97,225,183,77,156,25,216,247,188,131,191,126,42,167,155,161, 65,212,225,145,237,75,173,69,187,180,64,105,248,121,123,60,68,93,163,179,236,207,58,167,143,135,221,51,97,19,125,114,161,174, 212,250,78,140,100,192,31,254,173,125,183,20,175,107,242,230,185,144,156,178,188,189,106,124,173,43,167,83,116,60,191,212,14, 212,105,175,171,205,88,87,246,103,82,46,63,139,125,10,121,130,40,168,239,105,120,107,98,116,153,38,71,151,149,48,211,239,69,249, 158,66,211,47,206,133,34,247,179,183,159,162,185,236,119,114,116,194,111,245,61,131,157,194,76,236,191,25,136,172,166,95,68,104, 143,211,196,30,131,116,185,159,30,47,88,36,78,211,210,240,115,239,237,121,153,237,249,216,123,123,94,10,79,211,47,206,2,79, 81,160,116,65,205,28,10,212,53,4,91,17,19,219,113,151,9,84,95,116,164,142,68,41,162,140,175,137,50,66,1,33,89,192,185,220,233, 117,222,184,225,209,10,51,84,102,91,42,151,187,188,174,27,135,30,173,204,149,123,220,131,153,60,129,118,220,84,206,232,20,209, 55,111,127,201,195,10,22,122,166,209,95,219,131,217,52,116,42,191,61,127,79,75,68,73,225,159,255,237,45,88,164,90,208,244,255, 110,193,34,217,2,76,51,115,203,181,38,214,150,136,13,109,74,138,152,34,238,247,25,185,246,184,60,147,75,194,246,119,13,104,35, 78,64,55,86,127,181,246,36,5,202,27,150,227,4,116,14,186,112,2,202,211,236,42,186,192,225,101,11,81,178,15,251,46,252,46,248,83, 32,208,80,143,243,79,19,231,95,1,206,184,213,14,174,137,115,111,59,15,191,81,204,195,255,3,94,3,175,136,245,94,138,182,137, 251,161,87,68,34,62,171,178,105,154,214,16,174,111,153,61,39,47,6,46,12,79,237,13,77,89,151,132,237,123,94,7,119,99,127,153,161, 43,225,225,163,192,226,240,31,69,255,236,56,185,50,108,127,55,98,250,219,228,141,174,154,127,18,158,28,177,211,139,79,38,211, 169,3,145,195,244,199,176,67,61,108,17,43,195,104,155,145,153,20,65,143,47,146,254,102,100,6,249,29,209,118,63,238,110,13,178, 252,92,74,128,155,145,90,242,115,59,173,81,140,239,219,246,247,186,249,175,187,207,120,126,224,140,103,209,167,114,178,207,183, 82,180,130,41,155,253,153,201,150,5,74,86,41,89,163,252,155,17,69,197,115,88,61,135,49,155,14,202,221,245,236,243,144,171,185, 206,157,155,92,205,117,238,188,180,117,183,252,206,133,75,90,242,236,66,22,203,103,135,170,219,165,210,92,240,227,202,230,86, 178,80,73,175,202,235,67,139,236,249,85,231,183,202,19,84,243,39,62,35,137,244,22,213,198,150,188,118,11,230,41,217,170,242,51, 117,183,16,178,100,210,86,162,234,178,243,249,39,235,82,247,90,209,214,174,132,153,200,94,74,149,203,172,209,148,101,26,102, 118,173,97,164,55,38,140,137,214,173,250,184,78,172,155,120,119,15,177,30,226,61,16,43,137,175,236,165,170,85,198,206,65,75,79, 199,151,39,50,163,137,76,166,55,145,201,26,166,145,38,214,75,188,23,174,189,189,164,245,226,173,178,87,55,227,105,43,17,111, 211,83,169,182,37,177,108,98,60,145,221,217,73,23,158,110,79,165,146,137,152,158,77,88,102,99,206,167,55,49,100,196,118,198,146, 198,50,61,153,28,212,99,219,50,157,52,253,124,185,242,147,98,150,137,182,100,219,150,9,185,35,155,159,52,156,214,83,35,137, 88,166,109,153,110,142,235,40,112,198,57,146,172,164,149,238,78,36,179,70,250,252,233,171,245,108,58,177,163,147,102,255,197, 244,211,138,154,118,182,235,90,61,97,162,125,85,103,167,172,55,98,72,40,155,76,176,50,109,75,199,204,120,210,232,164,242,124, 99,207,210,132,25,23,165,79,149,49,142,153,107,195,244,172,24,55,68,225,213,167,39,172,182,196,112,169,180,217,167,167,137,57, 111,92,99,118,91,177,177,204,178,17,221,28,54,114,211,154,223,148,73,215,252,46,77,26,47,79,91,99,169,78,186,248,236,148,104, 218,48,214,12,102,140,244,184,145,70,45,151,39,173,65,61,217,171,239,180,198,178,83,213,204,252,203,249,58,169,245,116,135,132, 153,26,203,142,26,217,17,43,222,182,84,207,24,61,226,25,19,111,98,252,228,178,104,58,191,255,138,120,34,107,165,123,204,33, 171,147,230,156,223,237,172,34,231,189,135,239,106,169,175,214,77,125,88,180,184,187,55,102,141,182,165,71,51,201,182,173,99,49, 163,237,172,109,214,120,158,189,212,120,122,207,23,254,189,229,116,82,221,123,101,237,164,250,222,184,158,28,79,108,107,211, 77,211,202,202,61,213,182,194,140,37,173,76,194,28,94,150,212,51,114,179,156,237,211,131,113,73,171,244,186,115,164,175,54,70,7, 149,131,145,17,43,70,196,148,182,36,22,87,27,150,88,186,207,216,62,102,152,49,44,235,210,252,20,187,188,250,60,83,79,50,105, 12,235,201,37,177,152,145,201,172,216,17,51,82,246,100,52,158,195,39,61,60,54,138,206,229,121,149,229,123,33,42,12,219,163,50, 101,188,194,234,27,139,141,216,51,151,151,47,144,231,178,102,112,171,220,148,181,121,182,62,35,54,150,70,172,58,79,150,62,4, 1,115,88,172,152,41,91,218,24,74,162,28,52,99,220,178,99,87,84,79,15,27,249,173,173,62,135,187,221,52,220,138,163,155,214,174, 32,111,254,210,32,182,145,248,198,30,114,110,236,193,11,234,74,114,109,92,217,211,221,189,146,28,144,61,226,93,132,227,141,43, 251,145,40,148,222,149,226,77,106,253,72,237,237,71,80,223,216,143,92,253,178,4,214,79,90,191,200,135,183,94,161,34,166,247,11, 69,4,246,1,28,7,3,61,20,24,56,123,190,202,6,206,49,92,30,93,78,89,99,36,18,153,212,219,243,244,11,242,244,249,121,250,133,208, 139,108,189,59,169,15,103,200,165,203,253,39,140,66,246,234,131,70,146,10,116,117,90,208,116,61,30,63,119,84,33,54,72,165,226, 0,89,58,150,205,90,230,218,52,138,52,226,228,26,180,240,56,10,41,3,43,185,98,242,76,32,119,76,134,190,56,57,113,246,232,105, 42,138,89,113,99,173,133,72,189,36,43,30,38,163,59,249,228,67,52,173,155,153,33,43,61,74,197,226,228,65,72,207,72,111,20,100,31, 64,40,200,26,195,179,35,158,24,26,34,102,144,211,16,225,151,188,67,83,129,54,78,133,88,3,75,236,30,86,8,117,234,108,83,231, 24,21,195,44,246,12,186,108,164,51,84,32,30,197,192,147,71,104,202,201,43,150,146,40,62,154,24,53,100,161,239,51,18,195,35,89, 42,131,218,171,86,220,26,179,47,134,5,100,202,116,123,101,81,9,84,217,110,236,86,217,92,239,148,161,39,78,110,60,173,215,39, 174,204,41,155,168,72,40,150,149,21,241,131,252,120,232,219,137,241,30,237,195,154,76,196,12,242,193,178,193,76,136,193,19,141, 150,245,159,25,206,101,151,54,38,50,137,193,68,82,204,161,200,243,126,28,104,214,68,212,218,134,230,5,39,159,165,83,210,64, 100,75,37,245,157,221,105,29,157,115,32,245,74,249,190,137,216,8,149,96,32,49,143,24,184,181,250,152,152,96,255,164,97,189,145, 65,68,152,180,44,157,92,11,84,108,91,16,57,151,91,19,88,91,147,143,27,82,84,62,249,32,163,234,251,18,241,56,218,164,170,89, 109,161,14,153,231,52,67,90,31,206,149,41,13,40,70,149,41,207,122,42,24,209,51,242,124,165,170,145,68,220,232,179,134,178,242, 204,232,78,91,163,118,79,225,2,199,168,152,75,199,136,149,201,18,75,144,7,115,185,70,6,135,12,105,137,209,81,42,17,87,182,132, 158,92,166,167,50,171,49,194,84,172,12,125,70,114,133,25,159,76,199,99,95,86,79,103,169,80,158,82,209,157,41,131,188,82,221,98, 159,88,228,74,32,14,109,51,80,69,166,199,204,100,117,196,98,42,72,100,214,164,116,4,102,100,203,168,145,39,247,54,99,231,50, 81,85,213,182,243,92,253,138,115,9,125,35,98,92,156,73,185,67,139,49,95,70,90,212,124,5,142,28,114,36,141,161,44,185,146,134,57, 156,29,33,151,106,5,51,201,97,138,57,117,155,198,196,21,114,114,173,100,124,68,190,79,80,169,101,230,46,133,203,210,134,158, 197,76,150,77,153,150,27,153,108,218,218,41,166,119,202,168,150,64,94,206,220,26,168,153,50,245,233,227,70,174,211,24,166,172, 145,239,47,199,237,244,34,250,178,86,42,5,83,21,246,164,108,199,25,87,3,114,89,38,86,192,4,21,91,249,151,40,242,89,167,197,37, 42,180,204,220,130,43,150,234,234,177,100,54,145,18,131,44,31,177,104,10,68,128,147,206,240,232,75,92,99,228,194,132,23,231,133, 133,163,74,238,113,84,104,207,147,219,150,248,48,137,44,75,178,89,132,7,103,74,46,56,79,74,79,195,83,110,82,103,74,198,37, 150,166,250,180,49,44,166,45,125,254,203,54,5,211,198,168,53,110,216,45,95,99,158,17,83,157,105,25,85,180,140,145,37,95,70,196, 159,201,171,46,121,241,44,251,175,139,133,83,149,255,212,99,183,94,174,89,145,45,239,194,36,179,245,230,22,11,77,195,211,57, 239,162,84,145,201,197,154,13,137,188,224,81,115,78,179,184,234,232,136,219,25,59,250,200,181,85,156,57,45,234,120,114,143,73, 187,77,239,79,36,147,87,88,89,57,147,222,12,214,114,46,2,32,35,158,38,247,44,156,197,26,177,219,133,115,30,201,88,32,83,143, 211,50,118,107,122,166,234,82,61,117,100,71,18,56,208,196,123,99,68,201,118,88,69,200,214,80,6,84,49,4,5,99,217,161,14,25,60, 217,56,57,199,245,164,152,105,41,214,12,145,67,92,62,169,68,188,231,175,143,66,97,136,90,27,50,6,249,199,207,12,183,158,241,169, 94,179,9,98,59,136,239,136,128,118,98,59,233,7,156,145,219,215,223,69,207,224,19,111,203,128,198,31,98,197,123,52,118,148,149, 205,212,40,193,91,119,252,126,107,23,43,45,77,116,241,76,109,23,29,225,156,94,102,110,31,191,100,19,191,124,98,30,125,139,179, 87,241,120,150,60,138,194,124,247,209,35,182,232,208,134,31,100,183,51,119,11,127,154,58,249,27,108,130,63,252,193,137,189,140, 59,61,75,230,117,181,118,117,93,58,160,81,220,115,157,198,140,214,174,67,117,154,246,101,54,151,85,85,68,102,104,252,139,140, 179,210,42,39,231,235,106,157,228,100,78,205,229,225,115,15,58,61,46,114,49,23,119,105,115,230,240,241,22,39,159,195,51,45,52, 223,174,122,62,127,149,189,38,148,63,136,142,221,18,164,52,196,42,58,166,241,87,216,175,133,253,102,97,167,71,53,241,254,59, 141,247,111,129,124,83,99,253,16,63,147,2,121,110,112,8,229,214,32,189,166,28,254,100,59,188,108,139,63,115,246,93,230,174,93, 181,106,94,255,170,254,86,186,150,93,45,115,29,208,248,139,236,35,168,227,214,154,121,116,19,231,119,177,109,238,218,61,60,80, 203,83,181,188,164,147,143,29,220,204,119,174,164,67,92,187,139,141,32,137,23,239,230,227,181,119,14,108,221,163,209,11,140,247, 211,1,59,143,111,79,40,120,39,221,161,57,245,47,177,231,216,35,236,3,168,114,159,230,248,21,187,137,221,195,190,130,242,23, 237,233,167,143,51,233,201,31,167,90,126,228,250,218,85,90,225,149,188,87,115,255,156,105,252,97,218,196,23,183,176,178,146,136 ,141,191,87,43,58,196,248,162,46,205,251,31,172,109,17,99,154,231,99,140,207,99,193,226,203,156,30,167,183,221,89,180,213,229, 105,101,101,149,252,218,206,46,151,119,17,171,173,16,246,211,141,188,155,213,250,232,171,26,251,37,26,16,210,216,127,97,146,2, 149,220,219,194,71,107,177,84,182,134,103,56,73,200,230,6,39,189,20,153,67,255,164,177,187,197,112,255,64,99,155,221,190,68, 144,126,197,216,243,48,124,79,163,253,172,186,117,235,170,29,87,79,223,67,188,150,189,200,166,213,240,25,124,163,131,31,98,85, 11,108,67,80,26,2,48,20,242,153,48,4,217,180,234,156,82,67,156,49,15,103,183,133,66,187,118,57,142,86,213,177,151,171,72,115, 145,247,182,16,86,11,175,191,97,151,227,240,116,182,55,244,156,120,59,41,222,246,85,51,126,16,60,89,77,142,146,233,37,156,201, 191,48,28,79,86,35,121,255,12,188,29,158,225,184,145,83,33,96,127,5,65,48,151,125,111,6,99,39,193,109,51,203,217,193,153,140, 125,7,156,0,39,193,222,16,99,15,128,87,192,159,192,109,117,140,29,4,239,128,195,245,240,3,199,26,144,167,145,57,222,1,251,154, 24,59,218,228,96,123,231,48,182,127,46,103,119,131,39,231,218,223,221,228,190,19,203,201,220,111,43,197,119,58,185,223,87,138, 239,128,114,191,177,116,208,212,239,44,197,119,72,185,223,90,230,190,167,18,191,183,212,252,182,46,190,155,99,33,251,183,69,71, 161,187,66,182,93,252,159,154,249,237,239,209,228,255,174,67,118,189,226,247,153,154,242,23,255,83,118,132,236,114,197,255, 161,73,229,149,255,223,246,219,109,21,191,5,253,63,31,222,169,74,68,42,0,0,0,0}; //============================================================================== #if JUCE_PUSH_NOTIFICATIONS && JUCE_MODULE_AVAILABLE_juce_gui_extra // Returns true if the intent was handled. 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, "", "(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, "", "(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 (getDecorView, "getDecorView", "()Landroid/view/View;") \ METHOD (setFlags, "setFlags", "(II)V") \ METHOD (clearFlags, "clearFlags", "(I)V") DECLARE_JNI_CLASS (AndroidWindow, "android/view/Window") #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; } //============================================================================== class AndroidComponentPeer : public ComponentPeer, private Timer { public: AndroidComponentPeer (Component& comp, int windowStyleFlags, void* nativeViewHandle) : ComponentPeer (comp, windowStyleFlags), fullScreen (false), navBarsHidden (false), sizeAllocated (0), scale ((float) Desktop::getInstance().getDisplays().getMainDisplay().scale) { 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 (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(env->NewLocalRef(static_cast (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 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 viewLayoutParams (env->NewObject (AndroidLayoutParams, AndroidLayoutParams.create, -2, -2)); env->CallVoidMethod (view.get(), AndroidView.setLayoutParams, viewLayoutParams.get()); Rectangle physicalBounds = comp.getBoundsInParent() * scale; view.callVoidMethod (AndroidView.layout, physicalBounds.getX(), physicalBounds.getY(), physicalBounds.getRight(), physicalBounds.getBottom()); LocalRef 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 (Desktop::getInstance().getKioskModeComponent() != nullptr) setNavBarsHidden (true); LocalRef activity (getCurrentActivity()); if (activity == nullptr) activity = getMainActivity(); viewGroup = GlobalRef (LocalRef (env->CallObjectMethod (activity.get(), AndroidContext.getSystemService, javaString ("window").get()))); env->CallVoidMethod (viewGroup.get(), AndroidViewManager.addView, view.get(), windowLayoutParams.get()); } if (isFocused()) handleFocusGain(); } ~AndroidComponentPeer() override { auto* env = getEnv(); env->CallVoidMethod (view, ComponentPeerView.clear); frontWindow = nullptr; if (MessageManager::getInstance()->isThisTheMessageThread()) { if (env->IsInstanceOf (viewGroup.get(), AndroidActivity)) env->CallVoidMethod (viewGroup.get(), AndroidActivity.setContentView, nullptr); else env->CallVoidMethod (viewGroup.get(), AndroidViewManager.removeView, view.get()); } else { struct ViewDeleter : public CallbackMessage { ViewDeleter (const GlobalRef& view_, const GlobalRef& viewGroup_) : view (view_), group (viewGroup_) {} void messageCallback() override { auto* callbackEnv = getEnv(); if (callbackEnv->IsInstanceOf (group.get(), AndroidActivity)) callbackEnv->CallVoidMethod (group.get(), AndroidActivity.setContentView, nullptr); else callbackEnv->CallVoidMethod (group.get(), AndroidViewManager.removeView, view.get()); } private: GlobalRef view, group; }; (new ViewDeleter (view, viewGroup))->post(); } } void* getNativeHandle() const override { return (void*) view.get(); } void setVisible (bool shouldBeVisible) override { if (MessageManager::getInstance()->isThisTheMessageThread()) { view.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible); } else { struct VisibilityChanger : public CallbackMessage { VisibilityChanger (const GlobalRef& view_, bool shouldBeVisible_) : view (view_), shouldBeVisible (shouldBeVisible_) {} void messageCallback() override { view.callVoidMethod (ComponentPeerView.setVisible, shouldBeVisible); } GlobalRef view; bool shouldBeVisible; }; (new VisibilityChanger (view, shouldBeVisible))->post(); } } void setTitle (const String& title) override { view.callVoidMethod (ComponentPeerView.setViewName, javaString (title).get()); } void setBounds (const Rectangle& userRect, bool isNowFullScreen) override { Rectangle r = (userRect.toFloat() * scale).toNearestInt(); if (MessageManager::getInstance()->isThisTheMessageThread()) { auto* env = getEnv(); fullScreen = isNowFullScreen; { view.callVoidMethod (AndroidView.layout, r.getX(), r.getY(), r.getRight(), r.getBottom()); if (viewGroup != nullptr && viewGroupIsWindow) { LocalRef windowLayoutParams (env->NewObject (AndroidWindowManagerLayoutParams, AndroidWindowManagerLayoutParams.create, r.getWidth(), r.getHeight(), r.getX(), r.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, 0x3 /* LEFT */ | 0x30 /* TOP */); env->CallVoidMethod (viewGroup.get(), AndroidViewManager.updateViewLayout, view.get(), windowLayoutParams.get()); } } } else { class ViewMover : public CallbackMessage { public: ViewMover (const GlobalRef& v, Rectangle boundsToUse) : view (v), bounds (boundsToUse) {} void messageCallback() override { view.callVoidMethod (AndroidView.layout, bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getBottom()); } private: GlobalRef view; Rectangle bounds; }; (new ViewMover (view, r))->post(); } } Rectangle getBounds() const override { Rectangle r (view.callIntMethod (AndroidView.getLeft), view.callIntMethod (AndroidView.getTop), view.callIntMethod (AndroidView.getWidth), view.callIntMethod (AndroidView.getHeight)); return r / scale; } void handleScreenSizeChange() override { ComponentPeer::handleScreenSizeChange(); if (isFullScreen()) setFullScreen (true); } Point getScreenPosition() const { auto* env = getEnv(); LocalRef position (env->NewIntArray (2)); env->CallVoidMethod (view.get(), AndroidView.getLocationOnScreen, position.get()); jint* const screenPosition = env->GetIntArrayElements (position.get(), nullptr); Point pos (screenPosition[0], screenPosition[1]); env->ReleaseIntArrayElements (position.get(), screenPosition, 0); return pos; } Point localToGlobal (Point relativePosition) override { return relativePosition + (getScreenPosition().toFloat() / scale); } using ComponentPeer::localToGlobal; Point globalToLocal (Point screenPosition) override { return screenPosition - (getScreenPosition().toFloat() / scale); } using ComponentPeer::globalToLocal; void setMinimised (bool /*shouldBeMinimised*/) override { // n/a } bool isMinimised() const override { return false; } bool shouldNavBarsBeHidden (bool shouldBeFullScreen) const { if (shouldBeFullScreen) if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) if (kiosk->getPeer() == this) return true; return false; } void setNavBarsHidden (bool hidden) { view.callVoidMethod (ComponentPeerView.setSystemUiVisibilityCompat, hidden ? (jint) (fullScreenFlags) : (jint) (SYSTEM_UI_FLAG_VISIBLE)); navBarsHidden = hidden; } void setFullScreen (bool shouldBeFullScreen) override { // updating the nav bar visibility is a bit odd on Android - need to wait for if (shouldNavBarsBeHidden (shouldBeFullScreen)) { if (! isTimerRunning()) { startTimer (500); } } else { setNavBarsHidden (false); } Rectangle r (shouldBeFullScreen ? Desktop::getInstance().getDisplays().getMainDisplay().userArea : lastNonFullscreenBounds); if ((! shouldBeFullScreen) && r.isEmpty()) r = getBounds(); // (can't call the component's setBounds method because that'll reset our fullscreen flag) if (! r.isEmpty()) setBounds (r, shouldBeFullScreen); component.repaint(); } bool isFullScreen() const override { return fullScreen; } void timerCallback() override { setNavBarsHidden (shouldNavBarsBeHidden (fullScreen)); setFullScreen (fullScreen); stopTimer(); } void setIcon (const Image& /*newIcon*/) override { // n/a } bool contains (Point localPos, bool trueIfInAChildWindow) const override { return isPositiveAndBelow (localPos.x, component.getWidth()) && isPositiveAndBelow (localPos.y, component.getHeight()) && ((! trueIfInAChildWindow) || view.callBooleanMethod (ComponentPeerView.containsPoint, localPos.x * scale, localPos.y * scale)); } BorderSize getFrameSize() const override { // TODO return BorderSize(); } 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 sysPos, int64 time) { lastMousePos = sysPos / scale; Point 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 sysPos, int64 time) { lastMousePos = sysPos / scale; Point 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 sysPos, int64 time) { lastMousePos = sysPos / scale; Point 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) { handleKeyPress (k, static_cast (kc)); } void handleKeyUpCallback (int /*k*/, int /*kc*/) { } void handleBackButtonCallback() { bool handled = false; if (auto* app = JUCEApplicationBase::getInstance()) handled = app->backButtonPressed(); if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) if (kiosk->getPeer() == this) setNavBarsHidden (navBarsHidden); if (! handled) { auto* env = getEnv(); LocalRef 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 (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) if (kiosk->getPeer() == this) setNavBarsHidden (navBarsHidden); } //============================================================================== 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, TextInputTarget& target) override { view.callVoidMethod (ComponentPeerView.showKeyboard, javaString (getVirtualKeyboardType (target.getKeyboardType())).get()); } void dismissPendingTextInput() override { view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get()); // updating the nav bar visibility is a bit odd on Android - need to wait for if (! isTimerRunning()) hideNavBarDelayed(); } void hideNavBarDelayed() { startTimer (500); } //============================================================================== void handlePaintCallback (jobject canvas, jobject paint) { auto* env = getEnv(); jobject rect = env->CallObjectMethod (canvas, AndroidCanvas.getClipBounds); const int left = env->GetIntField (rect, AndroidRect.left); const int top = env->GetIntField (rect, AndroidRect.top); const int right = env->GetIntField (rect, AndroidRect.right); const int bottom = env->GetIntField (rect, AndroidRect.bottom); env->DeleteLocalRef (rect); const Rectangle clip (left, top, right - left, bottom - top); const int sizeNeeded = clip.getWidth() * clip.getHeight(); if (sizeAllocated < sizeNeeded) { buffer.clear(); sizeAllocated = sizeNeeded; buffer = GlobalRef (LocalRef ((jobject) env->NewIntArray (sizeNeeded))); } else if (sizeNeeded == 0) { return; } 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& userArea) override { Rectangle area = userArea * scale; if (MessageManager::getInstance()->isThisTheMessageThread()) { view.callVoidMethod (AndroidView.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom()); } else { struct ViewRepainter : public CallbackMessage { ViewRepainter (const GlobalRef& view_, const Rectangle& area_) : view (view_), area (area_) {} void messageCallback() override { view.callVoidMethod (AndroidView.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom()); } private: GlobalRef view; const Rectangle area; }; (new ViewRepainter (view, area))->post(); } } void performAnyPendingRepaintsNow() override { // TODO } void setAlpha (float /*newAlpha*/) override { // TODO } StringArray getAvailableRenderingEngines() override { return StringArray ("Software Renderer"); } //============================================================================== static Point lastMousePos; static int64 touchesDown; //============================================================================== struct StartupActivityCallbackListener : ActivityLifecycleCallbacks { void onActivityStarted (jobject /*activity*/) override { auto* env = getEnv(); LocalRef appContext (getAppContext()); if (appContext.get() != nullptr) { env->CallVoidMethod (appContext.get(), AndroidApplication.unregisterActivityLifecycleCallbacks, activityCallbackListener.get()); clear(); activityCallbackListener.clear(); const_cast (Desktop::getInstance().getDisplays()).refresh(); } } }; private: //============================================================================== GlobalRef view, viewGroup; bool viewGroupIsWindow = false; GlobalRef buffer; bool fullScreen; bool navBarsHidden; int sizeAllocated; float scale; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (create, "", "(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", "(JII)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") \ 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 (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 (host)) myself->handleMouseDownCallback (i, Point ((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 (host)) myself->handleMouseDragCallback (i, Point ((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 (host)) myself->handleMouseUpCallback (i, Point ((float) x, (float) y), (int64) time); } static void JNICALL viewSizeChangedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleMovedOrResized(); } static void JNICALL focusChangedJni (JNIEnv*, jobject /*view*/, jlong host, jboolean hasFocus) { if (auto* myself = reinterpret_cast (host)) myself->handleFocusChangeCallback (hasFocus); } static void JNICALL handleKeyDownJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc) { if (auto* myself = reinterpret_cast (host)) myself->handleKeyDownCallback ((int) k, (int) kc); } static void JNICALL handleKeyUpJni (JNIEnv*, jobject /*view*/, jlong host, jint k, jint kc) { if (auto* myself = reinterpret_cast (host)) myself->handleKeyUpCallback ((int) k, (int) kc); } static void JNICALL handleBackButtonJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleBackButtonCallback(); } static void JNICALL handleKeyboardHiddenJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleKeyboardHiddenCallback(); } static void JNICALL handleAppPausedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleAppPausedCallback(); } static void JNICALL handleAppResumedJni (JNIEnv*, jobject /*view*/, jlong host) { if (auto* myself = reinterpret_cast (host)) myself->handleAppResumedCallback(); } //============================================================================== 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; 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 (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 createType() const override { return std::make_unique(); } std::unique_ptr createLowLevelContext() override { return std::make_unique (Image (this)); } void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/) override { bm.lineStride = width * static_cast (sizeof (jint)); bm.pixelStride = static_cast (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 (width * height)); s->data = s->allocatedData; memcpy (s->data, data, sizeof (jint) * static_cast (width * height)); return s; } private: jint* data; HeapBlock allocatedData; bool hasAlpha; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PreallocatedImage) }; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer) }; Point 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; } 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 windowServiceString (javaString ("window")); LocalRef windowManager = LocalRef (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get())); if (windowManager.get() != nullptr) { LocalRef display = LocalRef (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 MouseInputSource::getCurrentRawMousePosition() { return AndroidComponentPeer::lastMousePos; } void MouseInputSource::setRawMousePosition (Point) { // not needed } //============================================================================== bool KeyPress::isKeyCurrentlyDown (int /*keyCode*/) { // TODO return false; } JUCE_API void JUCE_CALLTYPE Process::hide() { auto* env = getEnv(); LocalRef currentActivity (getCurrentActivity().get()); if (env->CallBooleanMethod (currentActivity.get(), AndroidActivity.moveTaskToBack, true) == 0) { GlobalRef intent (LocalRef (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, "", "(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 (ModalComponentManager::Callback* callbackToUse, int resultToUse) : callback (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::unique_ptr callback; int result; }; //============================================================================== static void createAndroidDialog (const String& title, const String& message, ModalComponentManager::Callback* callback, const String& positiveButton = {}, const String& negativeButton = {}, const String& neutralButton = {}) { auto* env = getEnv(); LocalRef builder (env->NewObject (AndroidAlertDialogBuilder, AndroidAlertDialogBuilder.construct, getMainActivity().get())); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setTitle, javaString (title).get())); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setMessage, javaString (message).get())); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setCancelable, true)); builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setOnCancelListener, CreateJavaInterface (new DialogListener (callback, 0), "android/content/DialogInterface$OnCancelListener").get())); auto positiveButtonText = positiveButton.isEmpty() ? String ("OK") : positiveButton; builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setPositiveButton, javaString (positiveButtonText).get(), CreateJavaInterface (new DialogListener (callback, positiveButton.isEmpty() ? 0 : 1), "android/content/DialogInterface$OnClickListener").get())); if (negativeButton.isNotEmpty()) builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNegativeButton, javaString (negativeButton).get(), CreateJavaInterface (new DialogListener (callback, neutralButton.isEmpty() ? 0 : 2), "android/content/DialogInterface$OnClickListener").get())); if (neutralButton.isNotEmpty()) builder = LocalRef (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.setNegativeButton, javaString (neutralButton).get(), CreateJavaInterface (new DialogListener (callback, 0), "android/content/DialogInterface$OnClickListener").get())); LocalRef dialog (env->CallObjectMethod (builder.get(), AndroidAlertDialogBuilder.create)); LocalRef 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 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 (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { createAndroidDialog (title, message, callback); } bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! createAndroidDialog (title, message, callback, "OK", "Cancel"); return false; } int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! createAndroidDialog (title, message, callback, "Yes", "No", "Cancel"); return 0; } int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! createAndroidDialog (title, message, callback, "Yes", "No"); return 0; } //============================================================================== static bool androidScreenSaverEnabled = true; void Desktop::setScreenSaverEnabled (bool shouldEnable) { constexpr auto FLAG_KEEP_SCREEN_ON = 0x80; if (shouldEnable != androidScreenSaverEnabled) { LocalRef activity (getMainActivity()); if (activity != nullptr) { auto* env = getEnv(); LocalRef 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 (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 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, "", "()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 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 view (env->GetObjectArrayElement (args, 0)); int dims[8]; for (int i = 1; i < 9; ++i) { LocalRef 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 callback; }; //============================================================================== class MainActivityWindowLayoutListener : public LayoutChangeListener { public: void onLayoutChange (LocalRef /*view*/, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) override { auto newBounds = Rectangle::leftTopRightBottom (left, top, right, bottom); auto oldBounds = Rectangle::leftTopRightBottom (oldLeft, oldTop, oldRight, oldBottom); if (newBounds != oldBounds) { auto& displays = Desktop::getInstance().getDisplays(); auto& mainDisplay = displays.getMainDisplay(); Rectangle userArea = newBounds / mainDisplay.scale; if (userArea != mainDisplay.userArea) const_cast (displays).refresh(); } } }; //============================================================================== void Displays::findDisplays (float masterScale) { auto* env = getEnv(); LocalRef usableSize (env->NewObject (AndroidPoint, AndroidPoint.create, 0, 0)); LocalRef windowServiceString (javaString ("window")); LocalRef displayMetrics (env->NewObject (AndroidDisplayMetrics, AndroidDisplayMetrics.create)); LocalRef windowManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get())); LocalRef 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 (env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.widthPixels), env->GetIntField (displayMetrics.get(), AndroidDisplayMetrics.heightPixels)) / d.scale; d.userArea = Rectangle (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 activity (getMainActivity()); if (activity != nullptr) { LocalRef mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow)); LocalRef decorView (env->CallObjectMethod (mainWindow.get(), AndroidWindow.getDecorView)); LocalRef contentView (env->CallObjectMethod (decorView.get(), AndroidView.findViewById, 0x01020002 /* android.R.id.content */)); if (contentView != nullptr) { Rectangle 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; static bool hasAddedMainActivityListener = false; if (! hasAddedMainActivityListener) { hasAddedMainActivityListener = true; env->CallVoidMethod (contentView.get(), AndroidView.addOnLayoutChangeListener, CreateJavaInterface (new MainActivityWindowLayoutListener, "android/view/View$OnLayoutChangeListener").get()); } } } else { // the main activity may have not started yet so add an activity listener if (AndroidComponentPeer::activityCallbackListener == nullptr) { LocalRef 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(); } //============================================================================== void* CustomMouseCursorInfo::create() const { return nullptr; } void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType) { return nullptr; } void MouseCursor::deleteMouseCursor (void* /*cursorHandle*/, bool /*isStandard*/) {} //============================================================================== void MouseCursor::showInWindow (ComponentPeer*) const {} //============================================================================== bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& /*files*/, bool /*canMove*/, Component* /*srcComp*/, std::function /*callback*/) { jassertfalse; // no such thing on Android! return false; } bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/, Component* /*srcComp*/, std::function /*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 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 clipboardManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, javaString ("clipboard").get())); LocalRef charSequence (env->CallObjectMethod (clipboardManager.get(), AndroidClipboardManager.getText)); if (charSequence == nullptr) return {}; return juceString(LocalRef ((jstring) env->CallObjectMethod(charSequence.get(), JavaCharSequence.toString))); } //============================================================================== const int extendedKeyModifier = 0x10000; const int KeyPress::spaceKey = ' '; const int KeyPress::returnKey = 66; const int KeyPress::escapeKey = 4; const int KeyPress::backspaceKey = 67; const int KeyPress::leftKey = extendedKeyModifier + 1; const int KeyPress::rightKey = extendedKeyModifier + 2; const int KeyPress::upKey = extendedKeyModifier + 3; const int KeyPress::downKey = extendedKeyModifier + 4; const int KeyPress::pageUpKey = extendedKeyModifier + 5; const int KeyPress::pageDownKey = extendedKeyModifier + 6; const int KeyPress::endKey = extendedKeyModifier + 7; const int KeyPress::homeKey = extendedKeyModifier + 8; const int KeyPress::deleteKey = extendedKeyModifier + 9; const int KeyPress::insertKey = -1; const int KeyPress::tabKey = 61; const int KeyPress::F1Key = extendedKeyModifier + 10; const int KeyPress::F2Key = extendedKeyModifier + 11; const int KeyPress::F3Key = extendedKeyModifier + 12; const int KeyPress::F4Key = extendedKeyModifier + 13; const int KeyPress::F5Key = extendedKeyModifier + 14; const int KeyPress::F6Key = extendedKeyModifier + 16; const int KeyPress::F7Key = extendedKeyModifier + 17; const int KeyPress::F8Key = extendedKeyModifier + 18; const int KeyPress::F9Key = extendedKeyModifier + 19; const int KeyPress::F10Key = extendedKeyModifier + 20; const int KeyPress::F11Key = extendedKeyModifier + 21; const int KeyPress::F12Key = extendedKeyModifier + 22; const int KeyPress::F13Key = extendedKeyModifier + 23; const int KeyPress::F14Key = extendedKeyModifier + 24; const int KeyPress::F15Key = extendedKeyModifier + 25; const int KeyPress::F16Key = extendedKeyModifier + 26; const int KeyPress::F17Key = extendedKeyModifier + 50; const int KeyPress::F18Key = extendedKeyModifier + 51; const int KeyPress::F19Key = extendedKeyModifier + 52; const int KeyPress::F20Key = extendedKeyModifier + 53; const int KeyPress::F21Key = extendedKeyModifier + 54; const int KeyPress::F22Key = extendedKeyModifier + 55; const int KeyPress::F23Key = extendedKeyModifier + 56; const int KeyPress::F24Key = extendedKeyModifier + 57; const int KeyPress::F25Key = extendedKeyModifier + 58; const int KeyPress::F26Key = extendedKeyModifier + 59; const int KeyPress::F27Key = extendedKeyModifier + 60; const int KeyPress::F28Key = extendedKeyModifier + 61; const int KeyPress::F29Key = extendedKeyModifier + 62; const int KeyPress::F30Key = extendedKeyModifier + 63; const int KeyPress::F31Key = extendedKeyModifier + 64; const int KeyPress::F32Key = extendedKeyModifier + 65; const int KeyPress::F33Key = extendedKeyModifier + 66; const int KeyPress::F34Key = extendedKeyModifier + 67; const int KeyPress::F35Key = extendedKeyModifier + 68; const int KeyPress::numberPad0 = extendedKeyModifier + 27; const int KeyPress::numberPad1 = extendedKeyModifier + 28; const int KeyPress::numberPad2 = extendedKeyModifier + 29; const int KeyPress::numberPad3 = extendedKeyModifier + 30; const int KeyPress::numberPad4 = extendedKeyModifier + 31; const int KeyPress::numberPad5 = extendedKeyModifier + 32; const int KeyPress::numberPad6 = extendedKeyModifier + 33; const int KeyPress::numberPad7 = extendedKeyModifier + 34; const int KeyPress::numberPad8 = extendedKeyModifier + 35; const int KeyPress::numberPad9 = extendedKeyModifier + 36; const int KeyPress::numberPadAdd = extendedKeyModifier + 37; const int KeyPress::numberPadSubtract = extendedKeyModifier + 38; const int KeyPress::numberPadMultiply = extendedKeyModifier + 39; const int KeyPress::numberPadDivide = extendedKeyModifier + 40; const int KeyPress::numberPadSeparator = extendedKeyModifier + 41; const int KeyPress::numberPadDecimalPoint = extendedKeyModifier + 42; const int KeyPress::numberPadEquals = extendedKeyModifier + 43; const int KeyPress::numberPadDelete = extendedKeyModifier + 44; const int KeyPress::playKey = extendedKeyModifier + 45; const int KeyPress::stopKey = extendedKeyModifier + 46; const int KeyPress::fastForwardKey = extendedKeyModifier + 47; const int KeyPress::rewindKey = extendedKeyModifier + 48; } // namespace juce