v3.2.5: more Android display cutout stuff:
- added proper support for top-left cutouts, hero pane can extend a bit - made Android 'smaller cutout' detection more permissive again - added a check to not trust devices with no reported cutout
This commit is contained in:
@@ -117,17 +117,29 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
||||
|
||||
if (cutout != null) {
|
||||
boolean largeCutout = false;
|
||||
boolean cutoutsPresent = false;
|
||||
|
||||
int screenSize = Game.width * Game.height;
|
||||
for (Rect r : cutout.getBoundingRects()){
|
||||
for (Rect r : cutout.getBoundingRects()) {
|
||||
//use abs as some cutouts can apparently be returned inverted
|
||||
int cutoutSize = Math.abs(r.height() * r.width());
|
||||
//display cutouts are considered large if they take up more than 0.667% of the screen
|
||||
//in reality we want less than about 0.5%, but some cutouts over-report their size
|
||||
//Pixel devices especially =S
|
||||
if (cutoutSize*150 >= screenSize){
|
||||
largeCutout = true;
|
||||
//display cutouts are considered large if they take up more than 0.75%
|
||||
// of the screen/ in reality we want less than about 0.5%,
|
||||
// but some cutouts over-report their size, Pixel devices especially =S
|
||||
if (cutoutSize > 0){
|
||||
cutoutsPresent = true;
|
||||
if (cutoutSize * 133.33f >= screenSize) {
|
||||
largeCutout = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cutoutsPresent){
|
||||
//if we get no cutouts reported, assume the device is lying to us
|
||||
// and there actually is a cutout, which we must assume is large =S
|
||||
largeCutout = true;
|
||||
}
|
||||
|
||||
if (largeCutout || level == INSET_ALL) {
|
||||
insets.left = Math.max(insets.left, cutout.getSafeInsetLeft());
|
||||
insets.top = Math.max(insets.top, cutout.getSafeInsetTop());
|
||||
|
||||
@@ -369,10 +369,11 @@ public class GameScene extends PixelScene {
|
||||
int uiSize = SPDSettings.interfaceSize();
|
||||
|
||||
//display cutouts can obstruct various UI elements, so we need to adjust for that sometimes
|
||||
float heroPaneExtraWidth = insets.left;
|
||||
float menuBarMaxLeft = uiCamera.width-insets.right-MenuPane.WIDTH;
|
||||
int hpBarMaxWidth = 50; //default max width
|
||||
float buffBarTopRowMaxWidth = 50; //default max width
|
||||
if (largeInsetTop != insets.top){
|
||||
if (largeInsetTop == 0){
|
||||
//iOS's Dynamic island badly obstructs the first buff bar row
|
||||
if (DeviceCompat.isiOS()){
|
||||
//TODO bad to hardcode and approximate this atm
|
||||
@@ -380,10 +381,18 @@ public class GameScene extends PixelScene {
|
||||
float cutoutLeft = (Game.width*0.3f)/defaultZoom;
|
||||
buffBarTopRowMaxWidth = Math.min(50, cutoutLeft - 32);
|
||||
} else if (DeviceCompat.isAndroid()) {
|
||||
//Android hole punches are of varying size and may obstruct the menu, HP bar, or buff bar
|
||||
//Android hole punches are of varying size and may obstruct various UI elements
|
||||
RectF cutout = Game.platform.getDisplayCutout().scale(1f / defaultZoom);
|
||||
//if the cutout is positioned to obstruct the hero portrait in the status pane
|
||||
if (cutout.top < 30
|
||||
&& cutout.left < 20
|
||||
&& cutout.right > 12) {
|
||||
heroPaneExtraWidth = Math.max(heroPaneExtraWidth, cutout.right-12);
|
||||
//make sure we have space to actually move it though
|
||||
heroPaneExtraWidth = Math.min(heroPaneExtraWidth, uiCamera.width - PixelScene.MIN_WIDTH_P);
|
||||
}
|
||||
//if the cutout is positioned to obstruct the menu bar
|
||||
if (cutout.top < 20
|
||||
else if (cutout.top < 20
|
||||
&& cutout.left < menuBarMaxLeft + MenuPane.WIDTH
|
||||
&& cutout.right > menuBarMaxLeft) {
|
||||
menuBarMaxLeft = Math.min(menuBarMaxLeft, cutout.left - MenuPane.WIDTH);
|
||||
@@ -391,7 +400,7 @@ public class GameScene extends PixelScene {
|
||||
menuBarMaxLeft = Math.max(menuBarMaxLeft, PixelScene.MIN_WIDTH_P-MenuPane.WIDTH);
|
||||
}
|
||||
//if the cutout is positioned to obstruct the HP bar
|
||||
if (cutout.left < 78
|
||||
else if (cutout.left < 78
|
||||
&& cutout.top < 4
|
||||
&& cutout.right > 32) {
|
||||
//subtract starting position, but add a bit back due to end of bar
|
||||
@@ -432,6 +441,7 @@ public class GameScene extends PixelScene {
|
||||
|
||||
status = new StatusPane( SPDSettings.interfaceSize() > 0 );
|
||||
status.camera = uiCamera;
|
||||
StatusPane.heroPaneExtraWidth = heroPaneExtraWidth;
|
||||
StatusPane.hpBarMaxWidth = hpBarMaxWidth;
|
||||
StatusPane.buffBarTopRowMaxWidth = buffBarTopRowMaxWidth;
|
||||
status.setRect(insets.left, uiSize > 0 ? uiCamera.height-39-insets.bottom : screentop, uiCamera.width - insets.left - insets.right, 0 );
|
||||
|
||||
@@ -78,6 +78,9 @@ public class StatusPane extends Component {
|
||||
|
||||
private boolean large;
|
||||
|
||||
//potentially extends the hero portrait space to avoid some cutouts
|
||||
public static float heroPaneExtraWidth = 0;
|
||||
private NinePatch heroPaneCutout;
|
||||
//potentially shrinks and/or repositions the hp bar to avoid some cutouts
|
||||
public static int hpBarMaxWidth = 50;
|
||||
private Image hpCutout;
|
||||
@@ -95,6 +98,10 @@ public class StatusPane extends Component {
|
||||
else bg = new NinePatch( asset, 0, 0, 82, 38, 32, 0, 5, 0 );
|
||||
add( bg );
|
||||
|
||||
heroPaneCutout = new NinePatch(asset, 0, 0, 5, 36, 4, 0, 0, 0);
|
||||
heroPaneCutout.visible = false;
|
||||
add(heroPaneCutout);
|
||||
|
||||
hpCutout = new Image(asset, 90, 0, 12, 9);
|
||||
hpCutout.visible = false;
|
||||
add(hpCutout);
|
||||
@@ -181,7 +188,9 @@ public class StatusPane extends Component {
|
||||
|
||||
height = large ? 39 : 38;
|
||||
|
||||
bg.x = x;
|
||||
float heroPaneWidth = 30 + heroPaneExtraWidth;
|
||||
|
||||
bg.x = x + heroPaneExtraWidth;
|
||||
bg.y = y;
|
||||
if (large) bg.size( 160, bg.height ); //HP bars must be 128px wide atm
|
||||
else bg.size(hpBarMaxWidth+32, bg.height ); //default max right is 50px health bar + 32
|
||||
@@ -190,7 +199,7 @@ public class StatusPane extends Component {
|
||||
avatar.y = bg.y - avatar.height / 2f + 16;
|
||||
PixelScene.align(avatar);
|
||||
|
||||
heroInfo.setRect( x, y, 30, large ? 40 : 36 );
|
||||
heroInfo.setRect( x, y, heroPaneWidth, large ? 40 : 36 );
|
||||
|
||||
compass.x = avatar.x + avatar.width / 2f - compass.origin.x;
|
||||
compass.y = avatar.y + avatar.height / 2f - compass.origin.y;
|
||||
@@ -221,7 +230,14 @@ public class StatusPane extends Component {
|
||||
exp.x = x+2;
|
||||
exp.y = y+30;
|
||||
|
||||
float hpleft = x + 30;
|
||||
if (heroPaneExtraWidth > 0){
|
||||
heroPaneCutout.visible = true;
|
||||
heroPaneCutout.x = x;
|
||||
heroPaneCutout.y = y;
|
||||
heroPaneCutout.size(heroPaneExtraWidth+4, heroPaneCutout.height);
|
||||
}
|
||||
|
||||
float hpleft = x + heroPaneWidth;
|
||||
if (hpBarMaxWidth < 82){
|
||||
//the class variable assumes the left of the bar can't move, but we can inset it 9px
|
||||
int hpWidth = (int)hpBarMaxWidth;
|
||||
@@ -255,7 +271,7 @@ public class StatusPane extends Component {
|
||||
heroInfoOnBar.setRect(heroInfo.right(), y, 50, 9);
|
||||
|
||||
buffs.firstRowWidth = buffBarTopRowMaxWidth;
|
||||
buffs.setRect( x + 31, y + 8, 50, 15 );
|
||||
buffs.setRect( x + heroPaneWidth + 1, y + 8, 50, 15 );
|
||||
|
||||
busy.x = x + 1;
|
||||
busy.y = y + 37;
|
||||
@@ -322,7 +338,7 @@ public class StatusPane extends Component {
|
||||
expText.x = hp.x + (128 - expText.width())/2f;
|
||||
|
||||
} else {
|
||||
exp.scale.x = (17 / exp.width) * Dungeon.hero.exp / Dungeon.hero.maxExp();
|
||||
exp.scale.x = ((17 + heroPaneExtraWidth) / exp.width) * Dungeon.hero.exp / Dungeon.hero.maxExp();
|
||||
expText.text(Dungeon.hero.exp + "/" + Dungeon.hero.maxExp());
|
||||
}
|
||||
|
||||
@@ -342,7 +358,7 @@ public class StatusPane extends Component {
|
||||
} else {
|
||||
level.text( Integer.toString( lastLvl ) );
|
||||
level.measure();
|
||||
level.x = x + 25.5f - level.width() / 2f;
|
||||
level.x = x + heroPaneExtraWidth + 25.5f - level.width() / 2f;
|
||||
level.y = y + 31.0f - level.baseLine() / 2f;
|
||||
}
|
||||
PixelScene.align(level);
|
||||
@@ -364,6 +380,8 @@ public class StatusPane extends Component {
|
||||
public void alpha( float value ){
|
||||
value = GameMath.gate(0, value, 1f);
|
||||
bg.alpha(value);
|
||||
heroPaneCutout.alpha(value);
|
||||
hpCutout.alpha(value);
|
||||
avatar.alpha(value);
|
||||
rawShielding.alpha(0.5f*value);
|
||||
shieldedHP.alpha(value);
|
||||
|
||||
Reference in New Issue
Block a user