v3.2.4: overhauled status and menu bar to better support display cutouts

This commit is contained in:
Evan Debenham
2025-09-05 13:24:52 -04:00
parent dacac930a5
commit 21f2753e97
5 changed files with 70 additions and 43 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -233,6 +233,7 @@ public class GameScene extends PixelScene {
}
RectF insets = getCommonInsets();
insets.top = Game.platform.getSafeInsets(PlatformSupport.INSET_LRG).scale(1f/defaultZoom).top;
scene = this;
@@ -364,13 +365,16 @@ public class GameScene extends PixelScene {
int uiSize = SPDSettings.interfaceSize();
//TODO this is a good start but just emulating black bars is boring. There must be more to do here.
menu = new MenuPane();
menu.camera = uiCamera;
menu.setPos( uiCamera.width-MenuPane.WIDTH-insets.right, insets.top + (uiSize > 0 ? 0 : 1));
menu.setPos( uiCamera.width-MenuPane.WIDTH-insets.right, insets.top);
add(menu);
//TODO buff indicator and boss HP need to be moved down slightly on iOS devices with dynamic island
//TODO buff indicator probably cut off on some Android devices, get display cutout size and check?
//TODO need to reject inputs on the bars (just turn then into hotareas?
//TODO make top bar transparent and add 1px of top status and menu bar to it?
status = new StatusPane( SPDSettings.interfaceSize() > 0 );
status.camera = uiCamera;
status.setRect(insets.left, uiSize > 0 ? uiCamera.height-39-insets.bottom : insets.top, uiCamera.width - insets.left - insets.right, 0 );
@@ -384,7 +388,7 @@ public class GameScene extends PixelScene {
boss = new BossHealthBar();
boss.camera = uiCamera;
boss.setPos( insets.left + 6 + (uiCamera.width - insets.left - insets.right - boss.width())/2, insets.top + 20);
boss.setPos( insets.left + 6 + (uiCamera.width - insets.left - insets.right - boss.width())/2, insets.top + 21);
add(boss);
resume = new ResumeIndicator();

View File

@@ -42,8 +42,10 @@ import com.watabou.input.GameAction;
import com.watabou.noosa.BitmapText;
import com.watabou.noosa.Game;
import com.watabou.noosa.Image;
import com.watabou.noosa.NinePatch;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.ui.Component;
import com.watabou.utils.DeviceCompat;
public class MenuPane extends Component {
@@ -63,18 +65,26 @@ public class MenuPane extends Component {
private Toolbar.PickedUpItem pickedUp;
private BitmapText version;
private NinePatch versionOverflowBG;
private DangerIndicator danger;
public static final int WIDTH = 32;
public static final int WIDTH = 31;
@Override
protected void createChildren() {
super.createChildren();
bg = new Image(Assets.Interfaces.MENU);
bg = new Image(Assets.Interfaces.MENU, 1, 0, 31, 20);
add(bg);
versionOverflowBG = new NinePatch(bg.texture, 1, 23, 6, 7, 3, 0, 2, 0);
add(versionOverflowBG);
version = new BitmapText( "v" + Game.version , PixelScene.pixelFont);
version.alpha( 0.5f );
add(version);
depthIcon = Icons.get(Dungeon.level.feeling);
add(depthIcon);
@@ -137,10 +147,6 @@ public class MenuPane extends Component {
btnMenu = new MenuButton();
add( btnMenu );
version = new BitmapText( "v" + Game.version, PixelScene.pixelFont);
version.alpha( 0.5f );
add(version);
danger = new DangerIndicator();
add( danger );
@@ -154,13 +160,31 @@ public class MenuPane extends Component {
bg.x = x;
bg.y = y;
version.scale.set(PixelScene.align(0.5f));
version.measure();
float rightMargin = DeviceCompat.isDesktop() ? 1 : 8;
if (DeviceCompat.isDebug()) rightMargin = 1; //don't care about hiding 'indev'
float overFlow = version.width()-(bg.width()-4-rightMargin);
if (overFlow >= 1){
version.x = x + 2 - overFlow;
versionOverflowBG.size(overFlow+3, 7);
versionOverflowBG.x = version.x-3;
versionOverflowBG.y = y;
} else {
version.x = x + 3;
versionOverflowBG.visible = false;
}
version.y = y + 2 - (version.baseLine()*version.scale.y)/2f;
version.y -= .001f;
PixelScene.align(version);
btnMenu.setPos( x + WIDTH - btnMenu.width(), y );
btnJournal.setPos( btnMenu.left() - btnJournal.width() + 2, y );
depthIcon.x = btnJournal.left() - 7 + (7 - depthIcon.width())/2f - 0.1f;
depthIcon.y = y + 1;
if (SPDSettings.interfaceSize() == 0) depthIcon.y++;
depthIcon.y = y+7;
PixelScene.align(depthIcon);
depthText.scale.set(PixelScene.align(0.67f));
@@ -172,8 +196,7 @@ public class MenuPane extends Component {
if (challengeIcon != null){
challengeIcon.x = btnJournal.left() - 14 + (7 - challengeIcon.width())/2f - 0.1f;
challengeIcon.y = y + 1;
if (SPDSettings.interfaceSize() == 0) challengeIcon.y++;
challengeIcon.y = depthIcon.y;
PixelScene.align(challengeIcon);
challengeText.scale.set(PixelScene.align(0.67f));
@@ -184,13 +207,7 @@ public class MenuPane extends Component {
challengeButton.setRect(challengeIcon.x, challengeIcon.y, challengeIcon.width(), challengeIcon.height() + challengeText.height());
}
version.scale.set(PixelScene.align(0.5f));
version.measure();
version.x = x + WIDTH - version.width();
version.y = y + bg.height() + (3 - version.baseLine());
PixelScene.align(version);
danger.setPos( x + WIDTH - danger.width(), y + bg.height + 3 );
danger.setPos( x + WIDTH - danger.width(), y + bg.height + 1 );
}
public void pickup(Item item, int cell) {
@@ -222,7 +239,7 @@ public class MenuPane extends Component {
super();
width = bg.width + 4;
height = bg.height + 4;
height = bg.height + 9;
}
@Override
@@ -250,7 +267,7 @@ public class MenuPane extends Component {
super.layout();
bg.x = x + 2;
bg.y = y + 2;
bg.y = y + 7;
journalIcon.x = bg.x + (bg.width() - journalIcon.width())/2f;
journalIcon.y = bg.y + (bg.height() - journalIcon.height())/2f;
@@ -355,7 +372,7 @@ public class MenuPane extends Component {
super();
width = image.width + 4;
height = image.height + 4;
height = image.height + 9;
}
@Override
@@ -371,7 +388,7 @@ public class MenuPane extends Component {
super.layout();
image.x = x + 2;
image.y = y + 2;
image.y = y + 7;
}
@Override

View File

@@ -86,7 +86,8 @@ public class StatusPane extends Component {
this.large = large;
if (large) bg = new NinePatch( asset, 0, 64, 41, 39, 33, 0, 4, 0 );
else bg = new NinePatch( asset, 0, 0, 128, 36, 85, 0, 45, 0 );
//right part is transparent now so Ninepatching doesn't actually do anything
else bg = new NinePatch( asset, 0, 0, 128, 35, 85, 0, 45, 0 );
add( bg );
heroInfo = new Button(){
@@ -143,15 +144,13 @@ public class StatusPane extends Component {
add(heroInfoOnBar);
if (large) exp = new Image(asset, 0, 121, 128, 7);
else exp = new Image(asset, 0, 44, 16, 1);
else exp = new Image(asset, 0, 44, 17, 4);
add( exp );
if (large){
expText = new BitmapText(PixelScene.pixelFont);
expText.hardlight( 0xFFFFAA );
expText.alpha(0.6f);
add(expText);
}
expText = new BitmapText(PixelScene.pixelFont);
expText.hardlight( 0xFFFFAA );
expText.alpha(0.6f);
add(expText);
level = new BitmapText( PixelScene.pixelFont);
level.hardlight( 0xFFFFAA );
@@ -171,7 +170,7 @@ public class StatusPane extends Component {
@Override
protected void layout() {
height = large ? 39 : 32;
height = large ? 39 : 35;
bg.x = x;
bg.y = y;
@@ -179,10 +178,10 @@ public class StatusPane extends Component {
else bg.size( width, bg.height );
avatar.x = bg.x - avatar.width / 2f + 15;
avatar.y = bg.y - avatar.height / 2f + (large ? 15 : 16);
avatar.y = bg.y - avatar.height / 2f + (large ? 15 : 14);
PixelScene.align(avatar);
heroInfo.setRect( x, y+(large ? 0 : 1), 30, large ? 40 : 30 );
heroInfo.setRect( x, y, 30, large ? 40 : 35 );
compass.x = avatar.x + avatar.width / 2f - compass.origin.x;
compass.y = avatar.y + avatar.height / 2f - compass.origin.y;
@@ -210,11 +209,11 @@ public class StatusPane extends Component {
busy.x = x + bg.width + 1;
busy.y = y + bg.height - 9;
} else {
exp.x = x;
exp.y = y;
exp.x = x+2;
exp.y = y+29;
hp.x = shieldedHP.x = rawShielding.x = x + 30;
hp.y = shieldedHP.y = rawShielding.y = y + 3;
hp.y = shieldedHP.y = rawShielding.y = y + 1;
hpText.scale.set(PixelScene.align(0.5f));
hpText.x = hp.x + 1;
@@ -222,12 +221,18 @@ public class StatusPane extends Component {
hpText.y -= 0.001f; //prefer to be slightly higher
PixelScene.align(hpText);
expText.scale.set(PixelScene.align(0.5f));
expText.x = exp.x + 1;
expText.y = exp.y + (exp.height - (expText.baseLine()+expText.scale.y))/2f;
expText.y -= 0.001f; //prefer to be slightly higher
PixelScene.align(expText);
heroInfoOnBar.setRect(heroInfo.right(), y, 50, 9);
buffs.setRect( x + 31, y + 9, 50, 8 );
buffs.setRect( x + 31, y + 7, 50, 8 );
busy.x = x + 1;
busy.y = y + 33;
busy.y = y + 37;
}
counter.point(busy.center());
@@ -291,7 +296,8 @@ public class StatusPane extends Component {
expText.x = hp.x + (128 - expText.width())/2f;
} else {
exp.scale.x = (width / exp.width) * Dungeon.hero.exp / Dungeon.hero.maxExp();
exp.scale.x = (17 / exp.width) * Dungeon.hero.exp / Dungeon.hero.maxExp();
expText.text(Dungeon.hero.exp + "/" + Dungeon.hero.maxExp());
}
if (Dungeon.hero.lvl != lastLvl) {
@@ -310,7 +316,7 @@ public class StatusPane extends Component {
} else {
level.text( Integer.toString( lastLvl ) );
level.measure();
level.x = x + 27.5f - level.width() / 2f;
level.x = x + 25.5f - level.width() / 2f;
level.y = y + 28.0f - level.baseLine() / 2f;
}
PixelScene.align(level);