v3.2.3: initial overhaul to inset functionality for edge-to-edge
This commit is contained in:
@@ -58,15 +58,6 @@ public class DeviceCompat {
|
||||
Gdx.app.log( tag, message );
|
||||
}
|
||||
|
||||
public static RectF getSafeInsets(){
|
||||
RectF result = new RectF();
|
||||
result.left = Gdx.graphics.getSafeInsetLeft();
|
||||
result.top = Gdx.graphics.getSafeInsetTop();
|
||||
result.right = Gdx.graphics.getSafeInsetRight();
|
||||
result.bottom = Gdx.graphics.getSafeInsetBottom();
|
||||
return result;
|
||||
}
|
||||
|
||||
//some devices (macOS mainly) report virtual pixels to Shattered, but sometimes we want real pixel precision
|
||||
//this returns the number of real pixels per virtual pixel in the X dimension...
|
||||
public static float getRealPixelScaleX(){
|
||||
|
||||
@@ -39,6 +39,24 @@ public abstract class PlatformSupport {
|
||||
public boolean supportsFullScreen(){
|
||||
return true; //default
|
||||
}
|
||||
|
||||
public static final int INSET_ALL = 3; //All insets, from hole punches to nav bars
|
||||
public static final int INSET_LRG = 2; //Only big insets, full size notches and nav bars
|
||||
public static final int INSET_BLK = 1; //only complete blocker assets like navbars
|
||||
|
||||
public RectF getSafeInsets( int level ){
|
||||
return new RectF(
|
||||
Gdx.graphics.getSafeInsetLeft(),
|
||||
Gdx.graphics.getSafeInsetTop(),
|
||||
Gdx.graphics.getSafeInsetRight(),
|
||||
Gdx.graphics.getSafeInsetBottom()
|
||||
);
|
||||
}
|
||||
|
||||
//returns a display cutout (if one is present) in device pixels, or null is none is present
|
||||
public RectF getDisplayCutout(){
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract void updateSystemUI();
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Build;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
@@ -35,6 +36,7 @@ import com.badlogic.gdx.graphics.g2d.PixmapPacker;
|
||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -45,6 +47,8 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
||||
public void updateDisplaySize(){
|
||||
|
||||
//TODO seem to be existing bugs with handling split screen here, should look into that
|
||||
|
||||
//TODO display isn't refreshing when fullscreen toggled on/off, or on 180 degree rotate
|
||||
}
|
||||
|
||||
public boolean supportsFullScreen(){
|
||||
@@ -56,7 +60,46 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectF getSafeInsets( int level ) {
|
||||
RectF insets = new RectF();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
WindowInsets rootInsets = AndroidLauncher.instance.getApplicationWindow().getDecorView().getRootWindowInsets();
|
||||
if (rootInsets != null) {
|
||||
|
||||
//Navigation bar (never on the top)
|
||||
//Android 14 and below do this for us
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && supportsFullScreen() && !SPDSettings.fullscreen()) {
|
||||
insets.left = Math.max(insets.left, rootInsets.getStableInsetLeft());
|
||||
insets.right = Math.max(insets.right, rootInsets.getStableInsetRight());
|
||||
insets.bottom = Math.max(insets.bottom, rootInsets.getStableInsetBottom());
|
||||
}
|
||||
|
||||
//display cutout
|
||||
if (level > INSET_BLK && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
DisplayCutout cutout = rootInsets.getDisplayCutout();
|
||||
//TODO determine if a cutout is large or not based on its size in pixels:
|
||||
// on my OP7P, dev mode not simulations are:
|
||||
//top-left cutout is 0,0,136,136 (136x136 = 18.5k total)
|
||||
//center is 552,0,888,168 (336*168 = 56k total)
|
||||
//top-right corner is 1272,0,1440,168 (x168 = 28k total)
|
||||
//overall screen is 1440x3120 = 4400k pixels
|
||||
// 0.5% of 4400k is 22k
|
||||
//maybe judge a cutout to be large if it's bigger than 0.5% of the display?
|
||||
if (cutout != null) {
|
||||
insets.left = Math.max(insets.left, cutout.getSafeInsetLeft());
|
||||
insets.top = Math.max(insets.top, cutout.getSafeInsetTop());
|
||||
insets.right = Math.max(insets.right, cutout.getSafeInsetRight());
|
||||
insets.bottom = Math.max(insets.bottom, cutout.getSafeInsetBottom());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
|
||||
public void updateSystemUI() {
|
||||
|
||||
AndroidLauncher.instance.runOnUiThread(new Runnable() {
|
||||
@@ -80,8 +123,9 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY );
|
||||
} else {
|
||||
//still want to hide the status bar and cutout void
|
||||
AndroidLauncher.instance.getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE );
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">
|
||||
always <!-- For Android 14 and older devices-->
|
||||
</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -21,9 +21,6 @@ allprojects {
|
||||
|
||||
appAndroidCompileSDK = 35 //Android 15
|
||||
appAndroidMinSDK = 21 //Android 5.0
|
||||
// TODO currently we've opted-out of edge-to-edge but it will be required for Android 16
|
||||
// Need to figure out how the game will handle drawing into notches (and unify with iOS)
|
||||
// See: https://developer.android.com/about/versions/15/behavior-changes-15#ux
|
||||
appAndroidTargetSDK = 35 //Android 15
|
||||
|
||||
gdxVersion = '1.13.6-SNAPSHOT' //using snapshot as 1.13.5 has issues with Android R8
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.PointerArea;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
public class AboutScene extends PixelScene {
|
||||
|
||||
@@ -49,6 +50,8 @@ public class AboutScene extends PixelScene {
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
@@ -71,9 +74,9 @@ public class AboutScene extends PixelScene {
|
||||
"ShatteredPixel.com",
|
||||
"https://ShatteredPixel.com");
|
||||
if (landscape()){
|
||||
shpx.setRect((w - fullWidth)/2f - 6, 10, 120, 0);
|
||||
shpx.setRect((w - fullWidth)/2f - 6, insets.top + 10, 120, 0);
|
||||
} else {
|
||||
shpx.setRect((w - fullWidth)/2f, 6, 120, 0);
|
||||
shpx.setRect((w - fullWidth)/2f, insets.top + 6, 120, 0);
|
||||
}
|
||||
content.add(shpx);
|
||||
|
||||
@@ -232,7 +235,7 @@ public class AboutScene extends PixelScene {
|
||||
freesound.setRect(transifex.left()-10, transifex.bottom() + 8, colWidth+20, 0);
|
||||
content.add(freesound);
|
||||
|
||||
content.setSize( fullWidth, freesound.bottom()+10 );
|
||||
content.setSize( fullWidth, freesound.bottom()+10 + insets.bottom );
|
||||
|
||||
list.setRect( 0, 0, w, h );
|
||||
list.scrollTo(0, 0);
|
||||
|
||||
@@ -79,6 +79,7 @@ import com.watabou.noosa.SkinnedBlock;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -120,9 +121,13 @@ public class AlchemyScene extends PixelScene {
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
water = new SkinnedBlock(
|
||||
Camera.main.width, Camera.main.height,
|
||||
w, h,
|
||||
Dungeon.level.waterTex() ){
|
||||
|
||||
@Override
|
||||
@@ -143,18 +148,21 @@ public class AlchemyScene extends PixelScene {
|
||||
|
||||
Image im = new Image(TextureCache.createGradient(0x66000000, 0x88000000, 0xAA000000, 0xCC000000, 0xFF000000));
|
||||
im.angle = 90;
|
||||
im.x = Camera.main.width;
|
||||
im.scale.x = Camera.main.height/5f;
|
||||
im.scale.y = Camera.main.width;
|
||||
im.x = w;
|
||||
im.scale.x = h/5f;
|
||||
im.scale.y = w;
|
||||
add(im);
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
ExitButton btnExit = new ExitButton(){
|
||||
@Override
|
||||
protected void onClick() {
|
||||
Game.switchScene(GameScene.class);
|
||||
}
|
||||
};
|
||||
btnExit.setPos( Camera.main.width - btnExit.width(), 0 );
|
||||
btnExit.setPos( insets.left + w - btnExit.width(), insets.top );
|
||||
add( btnExit );
|
||||
|
||||
bubbleEmitter = new Emitter();
|
||||
@@ -166,30 +174,30 @@ public class AlchemyScene extends PixelScene {
|
||||
IconTitle title = new IconTitle(Icons.ALCHEMY.get(), Messages.get(this, "title") );
|
||||
title.setSize(200, 0);
|
||||
title.setPos(
|
||||
(Camera.main.width - title.reqWidth()) / 2f,
|
||||
(20 - title.height()) / 2f
|
||||
insets.left + (w - title.reqWidth()) / 2f,
|
||||
insets.top + (20 - title.height()) / 2f
|
||||
);
|
||||
align(title);
|
||||
add(title);
|
||||
|
||||
int w = Math.min(50 + Camera.main.width/2, 150);
|
||||
int left = (Camera.main.width - w)/2;
|
||||
int pw = Math.min(50 + w/2, 150);
|
||||
int left = (int)(insets.left) + (w - pw)/2;
|
||||
|
||||
centerW = left + w/2;
|
||||
centerW = left + pw/2;
|
||||
|
||||
int pos = (Camera.main.height - 120)/2;
|
||||
int pos = (int)(insets.top) + (h - 120)/2;
|
||||
|
||||
if (splitAlchGuide &&
|
||||
Camera.main.width >= 300 &&
|
||||
Camera.main.height >= PixelScene.MIN_HEIGHT_FULL){
|
||||
w = Math.min(150, Camera.main.width/2);
|
||||
left = (Camera.main.width/2 - w);
|
||||
centerW = left + w/2;
|
||||
w >= 300 &&
|
||||
h >= PixelScene.MIN_HEIGHT_FULL){
|
||||
pw = Math.min(150, w/2);
|
||||
left = (w/2 - pw);
|
||||
centerW = left + pw/2;
|
||||
|
||||
NinePatch guideBG = Chrome.get(Chrome.Type.TOAST);
|
||||
guideBG.size(126 + guideBG.marginHor(), Math.min(Camera.main.height - 18, 191 + guideBG.marginVer()));
|
||||
guideBG.y = Math.max(17, (Camera.main.height - guideBG.height())/2f);
|
||||
guideBG.x = Camera.main.width - left - guideBG.width();
|
||||
guideBG.y = Math.max(17, insets.top + (h - guideBG.height())/2f);
|
||||
guideBG.x = insets.left + w - left - guideBG.width();
|
||||
add(guideBG);
|
||||
|
||||
alchGuide = new WndJournal.AlchemyTab();
|
||||
@@ -204,9 +212,9 @@ public class AlchemyScene extends PixelScene {
|
||||
}
|
||||
|
||||
RenderedTextBlock desc = PixelScene.renderTextBlock(6);
|
||||
desc.maxWidth(w);
|
||||
desc.maxWidth(pw);
|
||||
desc.text( Messages.get(AlchemyScene.class, "text") );
|
||||
desc.setPos(left + (w - desc.width())/2, pos);
|
||||
desc.setPos(left + (pw - desc.width())/2, pos);
|
||||
add(desc);
|
||||
|
||||
pos += desc.height() + 6;
|
||||
@@ -383,8 +391,8 @@ public class AlchemyScene extends PixelScene {
|
||||
|
||||
if (i == 0){
|
||||
//first ones are always visible
|
||||
combines[i].setRect(left + (w-30)/2f, inputs[1].top()+5, 30, inputs[1].height()-10);
|
||||
outputs[i].setRect(left + w - BTN_SIZE - 10, inputs[1].top(), BTN_SIZE, BTN_SIZE);
|
||||
combines[i].setRect(left + (pw-30)/2f, inputs[1].top()+5, 30, inputs[1].height()-10);
|
||||
outputs[i].setRect(left + pw - BTN_SIZE - 10, inputs[1].top(), BTN_SIZE, BTN_SIZE);
|
||||
} else {
|
||||
combines[i].visible = false;
|
||||
outputs[i].visible = false;
|
||||
@@ -403,7 +411,7 @@ public class AlchemyScene extends PixelScene {
|
||||
|
||||
if (Camera.main.height >= 280){
|
||||
//last elements get centered even with a split alch guide UI, as long as there's enough height
|
||||
centerW = Camera.main.width/2;
|
||||
centerW = (int)(insets.left) + w/2;
|
||||
}
|
||||
|
||||
bubbleEmitter.pos(0,
|
||||
@@ -415,7 +423,7 @@ public class AlchemyScene extends PixelScene {
|
||||
lowerBubbles.pos(0,
|
||||
pos,
|
||||
2*centerW,
|
||||
Math.max(0, Camera.main.height-pos));
|
||||
Math.max(0, h-pos));
|
||||
lowerBubbles.pour(Speck.factory( Speck.BUBBLE ), 0.1f );
|
||||
|
||||
String energyText = Messages.get(AlchemyScene.class, "energy") + " " + Dungeon.energy;
|
||||
@@ -426,7 +434,7 @@ public class AlchemyScene extends PixelScene {
|
||||
energyLeft = PixelScene.renderTextBlock(energyText, 9);
|
||||
energyLeft.setPos(
|
||||
centerW - energyLeft.width()/2,
|
||||
Camera.main.height - 8 - energyLeft.height()
|
||||
insets.top + h - 8 - energyLeft.height()
|
||||
);
|
||||
energyLeft.hardlight(0x44CCFF);
|
||||
add(energyLeft);
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.tweeners.Delayer;
|
||||
import com.watabou.utils.Random;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
public class AmuletScene extends PixelScene {
|
||||
|
||||
@@ -119,30 +120,34 @@ public class AmuletScene extends PixelScene {
|
||||
btnStay.icon(Icons.CLOSE.get());
|
||||
btnStay.setSize( WIDTH, BTN_HEIGHT );
|
||||
add( btnStay );
|
||||
|
||||
|
||||
RectF insets = getCommonInsets();
|
||||
int w = (int) (Camera.main.width - insets.left + insets.right);
|
||||
int h = (int) (Camera.main.height - insets.top + insets.bottom);
|
||||
|
||||
float height;
|
||||
if (noText) {
|
||||
height = amulet.height + LARGE_GAP + btnExit.height() + SMALL_GAP + btnStay.height();
|
||||
|
||||
amulet.x = (Camera.main.width - amulet.width) / 2;
|
||||
amulet.y = (Camera.main.height - height) / 2;
|
||||
amulet.x = insets.left + (w - amulet.width) / 2;
|
||||
amulet.y = insets.top + (h - height) / 2;
|
||||
align(amulet);
|
||||
|
||||
btnExit.setPos( (Camera.main.width - btnExit.width()) / 2, amulet.y + amulet.height + LARGE_GAP );
|
||||
btnExit.setPos( insets.left + (w - btnExit.width()) / 2, amulet.y + amulet.height + LARGE_GAP );
|
||||
btnStay.setPos( btnExit.left(), btnExit.bottom() + SMALL_GAP );
|
||||
|
||||
} else {
|
||||
height = amulet.height + LARGE_GAP + text.height() + LARGE_GAP + btnExit.height() + SMALL_GAP + btnStay.height();
|
||||
|
||||
amulet.x = (Camera.main.width - amulet.width) / 2;
|
||||
amulet.y = (Camera.main.height - height) / 2;
|
||||
|
||||
amulet.x = insets.left + (w - amulet.width) / 2;
|
||||
amulet.y = insets.top + (h - height) / 2;
|
||||
align(amulet);
|
||||
|
||||
text.setPos((Camera.main.width - text.width()) / 2, amulet.y + amulet.height + LARGE_GAP);
|
||||
text.setPos(insets.left + (w - text.width()) / 2, amulet.y + amulet.height + LARGE_GAP);
|
||||
align(text);
|
||||
add(text);
|
||||
|
||||
btnExit.setPos( (Camera.main.width - btnExit.width()) / 2, text.top() + text.height() + LARGE_GAP );
|
||||
|
||||
btnExit.setPos( insets.left + (w - btnExit.width()) / 2, amulet.y + amulet.height + LARGE_GAP );
|
||||
btnStay.setPos( btnExit.left(), btnExit.bottom() + SMALL_GAP );
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.Scene;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -79,17 +80,26 @@ public class ChangesScene extends PixelScene {
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize(w, h);
|
||||
//archs added later
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
IconTitle title = new IconTitle(Icons.CHANGES.get(), Messages.get(this, "title"));
|
||||
title.setSize(200, 0);
|
||||
title.setPos(
|
||||
(w - title.reqWidth()) / 2f,
|
||||
(20 - title.height()) / 2f
|
||||
insets.left + (w - title.reqWidth()) / 2f,
|
||||
insets.top + (20 - title.height()) / 2f
|
||||
);
|
||||
align(title);
|
||||
add(title);
|
||||
|
||||
ExitButton btnExit = new ExitButton();
|
||||
btnExit.setPos( Camera.main.width - btnExit.width(), 0 );
|
||||
btnExit.setPos( insets.left + w - btnExit.width(), insets.top );
|
||||
add( btnExit );
|
||||
|
||||
NinePatch panel = Chrome.get(Chrome.Type.TOAST);
|
||||
@@ -99,8 +109,8 @@ public class ChangesScene extends PixelScene {
|
||||
|
||||
if (h >= PixelScene.MIN_HEIGHT_FULL && w >= 300) {
|
||||
panel.size( pw, ph );
|
||||
panel.x = (w - pw) / 2f - pw/2 - 1;
|
||||
panel.y = 20;
|
||||
panel.x = insets.left + (w - pw) / 2f - pw/2 - 1;
|
||||
panel.y = insets.top + 20;
|
||||
|
||||
rightPanel = Chrome.get(Chrome.Type.TOAST);
|
||||
rightPanel.size( pw, ph );
|
||||
@@ -131,8 +141,8 @@ public class ChangesScene extends PixelScene {
|
||||
|
||||
} else {
|
||||
panel.size( pw, ph );
|
||||
panel.x = (w - pw) / 2f;
|
||||
panel.y = 20;
|
||||
panel.x = insets.left + (w - pw) / 2f;
|
||||
panel.y = insets.top + 20;
|
||||
}
|
||||
align( panel );
|
||||
add( panel );
|
||||
@@ -340,8 +350,6 @@ public class ChangesScene extends PixelScene {
|
||||
btnOld.setRect(btn0_6.right()-2, btn0_8.top(), 22, changesSelected == 7 ? 19 : 15);
|
||||
addToBack(btnOld);
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( Camera.main.width, Camera.main.height );
|
||||
addToBack( archs );
|
||||
|
||||
fadeIn();
|
||||
|
||||
@@ -121,6 +121,7 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndKeyBindings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndMessage;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndResurrect;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.glwrap.Blending;
|
||||
import com.watabou.input.ControllerHandler;
|
||||
import com.watabou.input.KeyBindings;
|
||||
@@ -138,8 +139,8 @@ import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
import com.watabou.noosa.tweeners.Tweener;
|
||||
import com.watabou.utils.Callback;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.Random;
|
||||
@@ -231,6 +232,8 @@ public class GameScene extends PixelScene {
|
||||
case 1: Camera.main.setFollowDeadzone(0.9f); break;
|
||||
}
|
||||
|
||||
RectF insets = Game.platform.getSafeInsets(PlatformSupport.INSET_ALL).scale(1f/defaultZoom);
|
||||
|
||||
scene = this;
|
||||
|
||||
terrain = new Group();
|
||||
@@ -361,16 +364,24 @@ 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, uiSize > 0 ? 0 : 1);
|
||||
menu.setPos( uiCamera.width-MenuPane.WIDTH-insets.right, insets.top + (uiSize > 0 ? 0 : 1));
|
||||
add(menu);
|
||||
|
||||
status = new StatusPane( SPDSettings.interfaceSize() > 0 );
|
||||
status.camera = uiCamera;
|
||||
status.setRect(0, uiSize > 0 ? uiCamera.height-39 : 0, uiCamera.width, 0 );
|
||||
status.setRect(insets.left, uiSize > 0 ? uiCamera.height-39-insets.bottom : insets.top, uiCamera.width - insets.left - insets.right, 0 );
|
||||
add(status);
|
||||
|
||||
if (uiSize < 2 && insets.top > 0) {
|
||||
SkinnedBlock blackBar = new SkinnedBlock(uiCamera.width, insets.top, TextureCache.createSolid(0xFF000000));
|
||||
blackBar.camera = uiCamera;
|
||||
add(blackBar);
|
||||
}
|
||||
|
||||
boss = new BossHealthBar();
|
||||
boss.camera = uiCamera;
|
||||
boss.setPos( 6 + (uiCamera.width - boss.width())/2, 20);
|
||||
@@ -411,9 +422,9 @@ public class GameScene extends PixelScene {
|
||||
inventory.setPos(uiCamera.width - inventory.width(), uiCamera.height - inventory.height());
|
||||
add(inventory);
|
||||
|
||||
toolbar.setRect( 0, uiCamera.height - toolbar.height() - inventory.height(), uiCamera.width, toolbar.height() );
|
||||
toolbar.setRect( insets.left, uiCamera.height - toolbar.height() - inventory.height() - insets.bottom, uiCamera.width - insets.right, toolbar.height() );
|
||||
} else {
|
||||
toolbar.setRect( 0, uiCamera.height - toolbar.height(), uiCamera.width, toolbar.height() );
|
||||
toolbar.setRect( insets.left, uiCamera.height - toolbar.height() - insets.bottom, uiCamera.width - insets.right, toolbar.height() );
|
||||
}
|
||||
|
||||
layoutTags();
|
||||
@@ -840,7 +851,7 @@ public class GameScene extends PixelScene {
|
||||
|
||||
//primarily for phones displays with notches
|
||||
//TODO Android never draws into notch atm, perhaps allow it for center notches?
|
||||
RectF insets = DeviceCompat.getSafeInsets();
|
||||
RectF insets = Game.platform.getSafeInsets( PlatformSupport.INSET_ALL );
|
||||
insets = insets.scale(1f / uiCamera.zoom);
|
||||
|
||||
boolean tagsOnLeft = SPDSettings.flipTags();
|
||||
|
||||
@@ -59,7 +59,9 @@ import com.watabou.noosa.tweeners.Tweener;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
@@ -84,6 +86,8 @@ public class HeroSelectScene extends PixelScene {
|
||||
private GameOptions optionsPane;
|
||||
private IconButton btnExit;
|
||||
|
||||
private RectF insets;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
@@ -93,6 +97,11 @@ public class HeroSelectScene extends PixelScene {
|
||||
Badges.loadGlobal();
|
||||
Journal.loadGlobal();
|
||||
|
||||
insets = Game.platform.getSafeInsets(PlatformSupport.INSET_BLK).scale(1f/defaultZoom);
|
||||
|
||||
int w = (int)(Camera.main.width - insets.left - insets.right);
|
||||
int h = (int)(Camera.main.height - insets.top - insets.bottom);
|
||||
|
||||
background = new Image(TextureCache.createSolid(0xFF2d2f31), 0, 0, 800, 450){
|
||||
@Override
|
||||
public void update() {
|
||||
@@ -106,10 +115,10 @@ public class HeroSelectScene extends PixelScene {
|
||||
}
|
||||
}
|
||||
};
|
||||
background.scale.set(Camera.main.height/background.height);
|
||||
background.scale.set(h/background.height);
|
||||
|
||||
background.x = (Camera.main.width - background.width())/2f;
|
||||
background.y = (Camera.main.height - background.height())/2f;
|
||||
background.x = insets.left + (w - background.width())/2f;
|
||||
background.y = insets.top + (h - background.height())/2f;
|
||||
PixelScene.align(background);
|
||||
add(background);
|
||||
|
||||
@@ -157,11 +166,11 @@ public class HeroSelectScene extends PixelScene {
|
||||
super.onClick();
|
||||
HeroClass cls = GamesInProgress.selectedClass;
|
||||
if (cls != null) {
|
||||
Window w = new WndHeroInfo(GamesInProgress.selectedClass);
|
||||
Window info = new WndHeroInfo(GamesInProgress.selectedClass);
|
||||
if (landscape()) {
|
||||
w.offset(Camera.main.width / 6, 0);
|
||||
info.offset(w / 6, 0);
|
||||
}
|
||||
ShatteredPixelDungeon.scene().addToFront(w);
|
||||
ShatteredPixelDungeon.scene().addToFront(info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,19 +231,19 @@ public class HeroSelectScene extends PixelScene {
|
||||
}
|
||||
|
||||
if (landscape()){
|
||||
float leftArea = Math.max(100, Camera.main.width/3f);
|
||||
float uiHeight = Math.min(Camera.main.height-20, 300);
|
||||
float leftArea = Math.max(100, w/3f);
|
||||
float uiHeight = Math.min(h-20, 300);
|
||||
float uiSpacing = (uiHeight-120)/2f;
|
||||
|
||||
if (uiHeight >= 160) uiSpacing -= 5;
|
||||
if (uiHeight >= 180) uiSpacing -= 6;
|
||||
|
||||
background.x += leftArea/6f;
|
||||
background.x += insets.left + leftArea/6f;
|
||||
|
||||
float fadeLeftScale = 47 * (leftArea - background.x)/leftArea;
|
||||
fadeLeft.scale = new PointF(3 + Math.max(0, fadeLeftScale), background.height());
|
||||
|
||||
title.setPos( (leftArea - title.width())/2f, (Camera.main.height-uiHeight)/2f);
|
||||
title.setPos(insets.left + (leftArea - title.width())/2f, (h-uiHeight)/2f);
|
||||
align(title);
|
||||
|
||||
int btnWidth = HeroBtn.MIN_WIDTH + 15;
|
||||
@@ -244,7 +253,7 @@ public class HeroSelectScene extends PixelScene {
|
||||
}
|
||||
|
||||
int cols = (int)Math.ceil(heroBtns.size()/2f);
|
||||
float curX = (leftArea - btnWidth * cols + (cols-1))/2f;
|
||||
float curX = insets.left + (leftArea - btnWidth * cols + (cols-1))/2f;
|
||||
float curY = title.bottom() + uiSpacing;
|
||||
|
||||
int count = 0;
|
||||
@@ -264,7 +273,7 @@ public class HeroSelectScene extends PixelScene {
|
||||
}
|
||||
|
||||
heroName = renderTextBlock(9);
|
||||
heroName.setPos(0, heroBtns.get(heroBtns.size()-1).bottom()+5);
|
||||
heroName.setPos(insets.left, heroBtns.get(heroBtns.size()-1).bottom()+5);
|
||||
add(heroName);
|
||||
|
||||
if (uiHeight >= 160){
|
||||
@@ -273,12 +282,12 @@ public class HeroSelectScene extends PixelScene {
|
||||
heroDesc = renderTextBlock(5);
|
||||
}
|
||||
heroDesc.align(RenderedTextBlock.CENTER_ALIGN);
|
||||
heroDesc.setPos(0, heroName.bottom()+5);
|
||||
heroDesc.setPos(insets.left, heroName.bottom()+5);
|
||||
add(heroDesc);
|
||||
|
||||
startBtn.text(Messages.titleCase(Messages.get(this, "start")));
|
||||
startBtn.setSize(startBtn.reqWidth()+8, 21);
|
||||
startBtn.setPos((leftArea - startBtn.width())/2f, title.top() + uiHeight - startBtn.height());
|
||||
startBtn.setPos(insets.left + (leftArea - startBtn.width())/2f, title.top() + uiHeight - startBtn.height());
|
||||
align(startBtn);
|
||||
|
||||
btnFade = new IconButton(Icons.CHEVRON.get()){
|
||||
@@ -309,19 +318,19 @@ public class HeroSelectScene extends PixelScene {
|
||||
|
||||
int btnWidth = HeroBtn.MIN_WIDTH;
|
||||
|
||||
float curX = (Camera.main.width - btnWidth * heroBtns.size()) / 2f;
|
||||
float curX = insets.left + (w - btnWidth * heroBtns.size()) / 2f;
|
||||
if (curX > 0) {
|
||||
btnWidth += Math.min(curX / (heroBtns.size() / 2f), 15);
|
||||
curX = (Camera.main.width - btnWidth * heroBtns.size()) / 2f;
|
||||
curX = insets.left + (w - btnWidth * heroBtns.size()) / 2f;
|
||||
}
|
||||
float curY = Camera.main.height - HeroBtn.HEIGHT + 3;
|
||||
float curY = insets.top + h - HeroBtn.HEIGHT + 3;
|
||||
|
||||
for (StyledButton button : heroBtns) {
|
||||
button.setRect(curX, curY, btnWidth, HeroBtn.HEIGHT);
|
||||
curX += btnWidth;
|
||||
}
|
||||
|
||||
title.setPos((Camera.main.width - title.width()) / 2f, (Camera.main.height - HeroBtn.HEIGHT - title.height() - 4));
|
||||
title.setPos(insets.left + (w - title.width()) / 2f, insets.top + (h - HeroBtn.HEIGHT - title.height() - 4));
|
||||
|
||||
btnOptions.setRect(heroBtns.get(0).left() + 16, Camera.main.height-HeroBtn.HEIGHT-16, 20, 21);
|
||||
optionsPane.setPos(heroBtns.get(0).left(), 0);
|
||||
@@ -396,23 +405,23 @@ public class HeroSelectScene extends PixelScene {
|
||||
background.visible = true;
|
||||
background.hardlight(1.5f,1.5f,1.5f);
|
||||
|
||||
float leftPortion = Math.max(100, Camera.main.width/3f);
|
||||
float leftPortion = Math.max(100, (Camera.main.width - insets.left - insets.right)/3f);
|
||||
|
||||
if (landscape()) {
|
||||
|
||||
heroName.text(Messages.titleCase(cl.title()));
|
||||
heroName.hardlight(Window.TITLE_COLOR);
|
||||
heroName.setPos((leftPortion - heroName.width() - 20)/2f, heroName.top());
|
||||
heroName.setPos(insets.left + (leftPortion - heroName.width() - 20)/2f, heroName.top());
|
||||
align(heroName);
|
||||
|
||||
heroDesc.text(cl.shortDesc());
|
||||
heroDesc.maxWidth(80);
|
||||
heroDesc.setPos((leftPortion - heroDesc.width())/2f, heroName.bottom() + 5);
|
||||
heroDesc.setPos(insets.left +(leftPortion - heroDesc.width())/2f, heroName.bottom() + 5);
|
||||
align(heroDesc);
|
||||
|
||||
while(startBtn.top() < heroDesc.bottom()){
|
||||
heroDesc.maxWidth(heroDesc.maxWidth()+10);
|
||||
heroDesc.setPos(Math.max(0, (leftPortion - heroDesc.width())/2f), heroName.bottom() + 5);
|
||||
heroDesc.setPos(Math.max(insets.left, (leftPortion - heroDesc.width())/2f), heroName.bottom() + 5);
|
||||
align(heroDesc);
|
||||
}
|
||||
|
||||
@@ -433,7 +442,7 @@ public class HeroSelectScene extends PixelScene {
|
||||
startBtn.text(Messages.titleCase(cl.title()));
|
||||
startBtn.setSize(startBtn.reqWidth() + 8, 21);
|
||||
|
||||
startBtn.setPos((Camera.main.width - startBtn.width())/2f, (Camera.main.height - HeroBtn.HEIGHT + 2 - startBtn.height()));
|
||||
startBtn.setPos((Camera.main.width - startBtn.width())/2f, (Camera.main.height - insets.bottom - HeroBtn.HEIGHT + 2 - startBtn.height()));
|
||||
PixelScene.align(startBtn);
|
||||
|
||||
infoButton.visible = infoButton.active = true;
|
||||
@@ -496,13 +505,15 @@ public class HeroSelectScene extends PixelScene {
|
||||
|
||||
if (landscape()){
|
||||
|
||||
background.x = (Camera.main.width - background.width())/2f;
|
||||
int w = (int)(Camera.main.width - insets.left - insets.right);
|
||||
|
||||
float leftPortion = Math.max(100, Camera.main.width/3f);
|
||||
background.x = insets.left + (w - background.width())/2f;
|
||||
|
||||
float leftPortion = Math.max(100, w/3f);
|
||||
|
||||
background.x += (leftPortion/2f)*alpha;
|
||||
|
||||
float fadeLeftScale = 47 * (leftPortion - background.x)/leftPortion;
|
||||
float fadeLeftScale = 47 * (leftPortion - (background.x - insets.left))/leftPortion;
|
||||
fadeLeft.scale.x = 3 + Math.max(fadeLeftScale, 0)*alpha;
|
||||
fadeLeft.x = background.x-4;
|
||||
fadeRight.x = background.x + background.width() + 4;
|
||||
|
||||
@@ -56,7 +56,9 @@ import com.watabou.noosa.tweeners.Tweener;
|
||||
import com.watabou.utils.BArray;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import com.watabou.utils.Random;
|
||||
import com.watabou.utils.RectF;
|
||||
import com.watabou.utils.Signal;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -107,6 +109,8 @@ public class InterlevelScene extends PixelScene {
|
||||
|
||||
public static int lastRegion = -1;
|
||||
|
||||
private RectF insets;
|
||||
|
||||
{
|
||||
inGameScene = true;
|
||||
}
|
||||
@@ -210,16 +214,21 @@ public class InterlevelScene extends PixelScene {
|
||||
fadeTime = 0f;
|
||||
}
|
||||
|
||||
background = new Image(loadingAsset);
|
||||
background.scale.set(Camera.main.height/background.height);
|
||||
insets = Game.platform.getSafeInsets(PlatformSupport.INSET_BLK).scale(1f/defaultZoom);
|
||||
|
||||
if (Camera.main.width >= background.width()){
|
||||
background.x = (Camera.main.width - background.width())/2f;
|
||||
int w = (int)(Camera.main.width - insets.left - insets.right);
|
||||
int h = (int)(Camera.main.height - insets.top - insets.bottom);
|
||||
|
||||
background = new Image(loadingAsset);
|
||||
background.scale.set(h/background.height);
|
||||
|
||||
if (w >= background.width()){
|
||||
background.x = insets.left + (w - background.width())/2f;
|
||||
} else {
|
||||
background.x = Camera.main.width/2f - loadingCenter*background.scale.x;
|
||||
background.x = GameMath.gate(Camera.main.width - background.width(), background.x, 0);
|
||||
background.x = insets.left + w/2f - loadingCenter*background.scale.x;
|
||||
background.x = GameMath.gate(w - background.width(), background.x, 0);
|
||||
}
|
||||
background.y = (Camera.main.height - background.height())/2f;
|
||||
background.y = insets.top + (h - background.height())/2f;
|
||||
PixelScene.align(background);
|
||||
add(background);
|
||||
|
||||
@@ -248,17 +257,17 @@ public class InterlevelScene extends PixelScene {
|
||||
}
|
||||
};
|
||||
im.angle = 90;
|
||||
im.x = Camera.main.width;
|
||||
im.scale.x = Camera.main.height/5f;
|
||||
im.scale.y = Camera.main.width;
|
||||
im.x = insets.left + w;
|
||||
im.scale.x = h/5f;
|
||||
im.scale.y = w;
|
||||
add(im);
|
||||
|
||||
String text = Messages.get(Mode.class, mode.name());
|
||||
|
||||
loadingText = PixelScene.renderTextBlock( text, 9 );
|
||||
loadingText.setPos(
|
||||
(Camera.main.width - loadingText.width() - 8),
|
||||
(Camera.main.height - loadingText.height() - 6)
|
||||
insets.left + w - loadingText.width() - 8,
|
||||
insets.top + h - loadingText.height() - 6
|
||||
);
|
||||
align(loadingText);
|
||||
add(loadingText);
|
||||
@@ -267,7 +276,7 @@ public class InterlevelScene extends PixelScene {
|
||||
if (Dungeon.hero == null || (loadingDepth > Statistics.deepestFloor && loadingDepth % 5 == 1)){
|
||||
storyMessage = PixelScene.renderTextBlock(Document.INTROS.pageBody(region), 6);
|
||||
storyMessage.maxWidth( PixelScene.landscape() ? 180 : 125);
|
||||
storyMessage.setPos((Camera.main.width-storyMessage.width())/2f, (Camera.main.height-storyMessage.height())/2f);
|
||||
storyMessage.setPos(insets.left+(w-storyMessage.width())/2f, insets.top+(h-storyMessage.height())/2f);
|
||||
|
||||
storyBG = new ShadowBox();
|
||||
storyBG.boxRect(storyMessage.left()-10, storyMessage.top()-10, storyMessage.width()+20, storyMessage.height()+20);
|
||||
@@ -322,7 +331,7 @@ public class InterlevelScene extends PixelScene {
|
||||
}
|
||||
});
|
||||
|
||||
btnContinue.setPos((Camera.main.width - btnContinue.width())/2f, storyMessage.bottom()+10);
|
||||
btnContinue.setPos(insets.left + (w - btnContinue.width())/2f, storyMessage.bottom()+10);
|
||||
add(btnContinue);
|
||||
|
||||
btnHideStory = new IconButton(Icons.CHEVRON.get()){
|
||||
@@ -474,6 +483,9 @@ public class InterlevelScene extends PixelScene {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int w = (int)(Camera.main.width - insets.left - insets.right);
|
||||
int h = (int)(Camera.main.height - insets.top - insets.bottom);
|
||||
|
||||
switch (phase) {
|
||||
|
||||
@@ -528,12 +540,13 @@ public class InterlevelScene extends PixelScene {
|
||||
//slowly pan the background side to side in portait mode, if story text is displayed
|
||||
if (btnContinue != null && !textFadingIn && Game.width < Game.height){
|
||||
if (background.speed.isZero() && background.acc.isZero()){
|
||||
background.acc.x = background.center().x >= Camera.main.width ? -1f : 1f;
|
||||
background.acc.x = background.center().x >= (w+ insets.left) ? -1f : 1f;
|
||||
} else {
|
||||
float margin = 25 - insets.left;
|
||||
background.speed.x = GameMath.gate(-10, background.speed.x, 10);
|
||||
if (background.acc.x > 0 && background.x >= -25){
|
||||
if (background.acc.x > 0 && background.x >= -margin){
|
||||
background.acc.x = -2.5f;
|
||||
} else if (background.acc.x < 0 && background.x + background.width() <= Camera.main.width+25){
|
||||
} else if (background.acc.x < 0 && background.x + background.width() <= w+margin){
|
||||
background.acc.x = 2.5f;
|
||||
}
|
||||
}
|
||||
@@ -581,8 +594,8 @@ public class InterlevelScene extends PixelScene {
|
||||
//the randomization is effectively -2 to +2
|
||||
// we don't use the generator stack as levelgen may be occurring
|
||||
// and we don't want to accidentally use a seeded generator
|
||||
(Camera.main.width - loadingText.width() - 4) + 4*(Random.Float(false)-0.5f),
|
||||
(Camera.main.height - loadingText.height() - 6) + 4*(Random.Float(false)-0.5f)
|
||||
(w + insets.left - loadingText.width() - 4) + 4*(Random.Float(false)-0.5f),
|
||||
(h + insets.top - loadingText.height() - 6) + 4*(Random.Float(false)-0.5f)
|
||||
);
|
||||
align(loadingText);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndJournal;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.utils.RectF;
|
||||
import com.watabou.utils.SparseArray;
|
||||
|
||||
public class JournalScene extends PixelScene {
|
||||
@@ -79,13 +80,22 @@ public class JournalScene extends PixelScene {
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
//archs added later
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
float top = 20;
|
||||
|
||||
IconTitle title = new IconTitle( Icons.JOURNAL.get(), Messages.get(this, "title") );
|
||||
title.setSize(200, 0);
|
||||
title.setPos(
|
||||
(w - title.reqWidth()) / 2f,
|
||||
(top - title.height()) / 2f
|
||||
insets.left + (w - title.reqWidth()) / 2f,
|
||||
insets.top + (top - title.height()) / 2f
|
||||
);
|
||||
align(title);
|
||||
add(title);
|
||||
@@ -96,8 +106,8 @@ public class JournalScene extends PixelScene {
|
||||
int ph = h - 50 + panel.marginVer();
|
||||
|
||||
panel.size(pw, ph);
|
||||
panel.x = (w - pw) / 2f;
|
||||
panel.y = top;
|
||||
panel.x = insets.left + (w - pw) / 2f;
|
||||
panel.y = insets.top + top;
|
||||
add(panel);
|
||||
|
||||
switch (lastIDX){
|
||||
@@ -218,12 +228,10 @@ public class JournalScene extends PixelScene {
|
||||
if (lastIDX != 3) btnAlchemy.icon().brightness(0.6f);
|
||||
addToBack(btnAlchemy);
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
addToBack( archs );
|
||||
addToBack(archs);
|
||||
|
||||
ExitButton btnExit = new ExitButton();
|
||||
btnExit.setPos( Camera.main.width - btnExit.width(), 0 );
|
||||
btnExit.setPos( insets.left + w - btnExit.width(), insets.top );
|
||||
add( btnExit );
|
||||
|
||||
fadeIn();
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -61,34 +62,38 @@ public class NewsScene extends PixelScene {
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
int fullWidth = PixelScene.landscape() ? 202 : 100;
|
||||
int left = (w - fullWidth)/2;
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize(w, h);
|
||||
add(archs);
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
int fullWidth = PixelScene.landscape() ? 202 : 100;
|
||||
int left = (int)insets.left + (w - fullWidth)/2;
|
||||
|
||||
ExitButton btnExit = new ExitButton();
|
||||
btnExit.setPos(w - btnExit.width(), 0);
|
||||
btnExit.setPos(insets.left + w - btnExit.width(), insets.top);
|
||||
add(btnExit);
|
||||
|
||||
IconTitle title = new IconTitle( Icons.NEWS.get(), Messages.get(this, "title"));
|
||||
title.setSize(200, 0);
|
||||
title.setPos(
|
||||
(w - title.reqWidth()) / 2f,
|
||||
(20 - title.height()) / 2f
|
||||
insets.left + (w - title.reqWidth()) / 2f,
|
||||
insets.top + (20 - title.height()) / 2f
|
||||
);
|
||||
align(title);
|
||||
add(title);
|
||||
|
||||
float top = 18;
|
||||
float top = 18 + insets.top;
|
||||
|
||||
displayingNoArticles = !News.articlesAvailable();
|
||||
if (displayingNoArticles || Messages.lang() != Languages.ENGLISH) {
|
||||
|
||||
Component newsInfo = new NewsInfo();
|
||||
newsInfo.setRect(left, 20, fullWidth, 0);
|
||||
newsInfo.setRect(left, top, fullWidth, 0);
|
||||
add(newsInfo);
|
||||
|
||||
top = newsInfo.bottom();
|
||||
@@ -98,7 +103,7 @@ public class NewsScene extends PixelScene {
|
||||
if (!displayingNoArticles) {
|
||||
ArrayList<NewsArticle> articles = News.articles();
|
||||
|
||||
float articleSpace = h - top - 2;
|
||||
float articleSpace = h - top - 2 + insets.top;
|
||||
int rows = articles.size();
|
||||
if (PixelScene.landscape()){
|
||||
rows /= 2;
|
||||
|
||||
@@ -52,7 +52,9 @@ import com.watabou.noosa.ui.Cursor;
|
||||
import com.watabou.utils.Callback;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.RectF;
|
||||
import com.watabou.utils.Reflection;
|
||||
import com.watabou.utils.Signal;
|
||||
|
||||
@@ -119,7 +121,13 @@ public class PixelScene extends Scene {
|
||||
scaleFactor = 2.5f;
|
||||
}
|
||||
|
||||
maxDefaultZoom = (int)Math.min(Game.width/minWidth, Game.height/minHeight);
|
||||
//TODO all insets? or just blockers?
|
||||
RectF insets = Game.platform.getSafeInsets(PlatformSupport.INSET_ALL);
|
||||
|
||||
float w = Game.width - insets.left - insets.right;
|
||||
float h = Game.height - insets.top - insets.bottom;
|
||||
|
||||
maxDefaultZoom = (int)Math.min(w/minWidth, h/minHeight);
|
||||
maxDefaultZoom = Math.max(2, maxDefaultZoom);
|
||||
defaultZoom = SPDSettings.scale();
|
||||
|
||||
@@ -397,6 +405,18 @@ public class PixelScene extends Scene {
|
||||
magnitude *= SPDSettings.screenShake();
|
||||
Camera.main.shake(magnitude, duration);
|
||||
}
|
||||
|
||||
//returns insets for the common case of all on top/bottom and only blocking on left/right
|
||||
//plus scaled to pixel zoom
|
||||
public RectF getCommonInsets(){
|
||||
RectF all = Game.platform.getSafeInsets(PlatformSupport.INSET_ALL);
|
||||
RectF blocking = Game.platform.getSafeInsets(PlatformSupport.INSET_BLK);
|
||||
|
||||
all.left = blocking.left;
|
||||
all.right = blocking.right;
|
||||
|
||||
return all.scale(1f/defaultZoom);
|
||||
}
|
||||
|
||||
protected static class Fader extends ColorBlock {
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
public class RankingsScene extends PixelScene {
|
||||
|
||||
@@ -74,18 +75,22 @@ public class RankingsScene extends PixelScene {
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
Rankings.INSTANCE.load();
|
||||
|
||||
IconTitle title = new IconTitle( Icons.RANKINGS.get(), Messages.get(this, "title"));
|
||||
title.setSize(200, 0);
|
||||
title.setPos(
|
||||
(w - title.reqWidth()) / 2f,
|
||||
(20 - title.height()) / 2f
|
||||
insets.left + (w - title.reqWidth()) / 2f,
|
||||
insets.top + (20 - title.height()) / 2f
|
||||
);
|
||||
align(title);
|
||||
add(title);
|
||||
@@ -93,7 +98,7 @@ public class RankingsScene extends PixelScene {
|
||||
if (Rankings.INSTANCE.records.size() > 0) {
|
||||
|
||||
//attempts to give each record as much space as possible, ideally as much space as portrait mode
|
||||
float rowHeight = GameMath.gate(ROW_HEIGHT_MIN, (uiCamera.height - 26)/Rankings.INSTANCE.records.size(), ROW_HEIGHT_MAX);
|
||||
float rowHeight = GameMath.gate(ROW_HEIGHT_MIN, (h - 26)/Rankings.INSTANCE.records.size(), ROW_HEIGHT_MAX);
|
||||
|
||||
float left = (w - Math.min( MAX_ROW_WIDTH, w )) / 2 + GAP;
|
||||
float top = (h - rowHeight * Rankings.INSTANCE.records.size()) / 2;
|
||||
@@ -106,7 +111,7 @@ public class RankingsScene extends PixelScene {
|
||||
if (rowHeight <= 14){
|
||||
offset = (pos % 2 == 1) ? 5 : -5;
|
||||
}
|
||||
row.setRect( left+offset, top + pos * rowHeight, w - left * 2, rowHeight );
|
||||
row.setRect( insets.left + left+offset, insets.top + top + pos * rowHeight, w - left * 2, rowHeight );
|
||||
add(row);
|
||||
|
||||
pos++;
|
||||
@@ -121,8 +126,8 @@ public class RankingsScene extends PixelScene {
|
||||
add( label );
|
||||
|
||||
label.setPos(
|
||||
(w - label.width()) / 2,
|
||||
h - label.height() - 2*GAP
|
||||
insets.left + (w - label.width()) / 2,
|
||||
insets.top + h - label.height() - 2*GAP
|
||||
);
|
||||
align(label);
|
||||
|
||||
@@ -133,8 +138,8 @@ public class RankingsScene extends PixelScene {
|
||||
RenderedTextBlock noRec = PixelScene.renderTextBlock(Messages.get(this, "no_games"), 8);
|
||||
noRec.hardlight( 0xCCCCCC );
|
||||
noRec.setPos(
|
||||
(w - noRec.width()) / 2,
|
||||
(h - noRec.height()) / 2
|
||||
insets.left + (w - noRec.width()) / 2,
|
||||
insets.top + (h - noRec.height()) / 2
|
||||
);
|
||||
align(noRec);
|
||||
add(noRec);
|
||||
@@ -142,10 +147,10 @@ public class RankingsScene extends PixelScene {
|
||||
}
|
||||
|
||||
ExitButton btnExit = new ExitButton();
|
||||
btnExit.setPos( Camera.main.width - btnExit.width(), 0 );
|
||||
btnExit.setPos( Camera.main.width - btnExit.width() - insets.right, insets.top );
|
||||
add( btnExit );
|
||||
|
||||
int left = 0;
|
||||
float left = insets.left;
|
||||
|
||||
if (Rankings.INSTANCE.latestDaily != null) {
|
||||
IconButton btnDailies = new IconButton(Icons.CALENDAR.get()) {
|
||||
@@ -160,7 +165,7 @@ public class RankingsScene extends PixelScene {
|
||||
}
|
||||
};
|
||||
btnDailies.icon().hardlight(0.5f, 1f, 2f);
|
||||
btnDailies.setRect( left, 0, 16, 20 );
|
||||
btnDailies.setRect( left, insets.top, 16, 20 );
|
||||
left += 16;
|
||||
add(btnDailies);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -59,23 +60,27 @@ public class StartScene extends PixelScene {
|
||||
Journal.loadGlobal();
|
||||
|
||||
uiCamera.visible = false;
|
||||
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
ExitButton btnExit = new ExitButton();
|
||||
btnExit.setPos( w - btnExit.width(), 0 );
|
||||
btnExit.setPos( insets.left + w - btnExit.width(), insets.top );
|
||||
add( btnExit );
|
||||
|
||||
IconTitle title = new IconTitle( Icons.ENTER.get(), Messages.get(this, "title"));
|
||||
title.setSize(200, 0);
|
||||
title.setPos(
|
||||
(w - title.reqWidth()) / 2f,
|
||||
(20 - title.height()) / 2f
|
||||
insets.left + (w - title.reqWidth()) / 2f,
|
||||
insets.top + (20 - title.height()) / 2f
|
||||
);
|
||||
align(title);
|
||||
add(title);
|
||||
@@ -92,9 +97,9 @@ public class StartScene extends PixelScene {
|
||||
slotsHeight -= slotCount-1;
|
||||
}
|
||||
|
||||
float yPos = (h - slotsHeight + title.bottom() + 2)/2f - 4;
|
||||
float yPos = insets.top + (h - slotsHeight + title.bottom() + 2)/2f - 4;
|
||||
yPos = Math.max(yPos, title.bottom()+2);
|
||||
float slotLeft = (w - SLOT_WIDTH) / 2f;
|
||||
float slotLeft = insets.left + (w - SLOT_WIDTH) / 2f;
|
||||
|
||||
for (GamesInProgress.Info game : games) {
|
||||
SaveSlotButton existingGame = new SaveSlotButton();
|
||||
|
||||
@@ -36,6 +36,8 @@ import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
import com.watabou.utils.Callback;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
public class SupporterScene extends PixelScene {
|
||||
|
||||
@@ -50,6 +52,7 @@ public class SupporterScene extends PixelScene {
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
int elementWidth = PixelScene.landscape() ? 202 : 120;
|
||||
|
||||
@@ -57,15 +60,18 @@ public class SupporterScene extends PixelScene {
|
||||
archs.setSize(w, h);
|
||||
add(archs);
|
||||
|
||||
w -= insets.right + insets.left;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
ExitButton btnExit = new ExitButton();
|
||||
btnExit.setPos(w - btnExit.width(), 0);
|
||||
btnExit.setPos(insets.left + w - btnExit.width(), insets.top);
|
||||
add(btnExit);
|
||||
|
||||
IconTitle title = new IconTitle(Icons.GOLD.get(), Messages.get(this, "title"));
|
||||
title.setSize(200, 0);
|
||||
title.setPos(
|
||||
(w - title.reqWidth()) / 2f,
|
||||
(20 - title.height()) / 2f
|
||||
insets.left + (w - title.reqWidth()) / 2f,
|
||||
insets.top + (20 - title.height()) / 2f
|
||||
);
|
||||
align(title);
|
||||
add(title);
|
||||
@@ -93,8 +99,8 @@ public class SupporterScene extends PixelScene {
|
||||
|
||||
float elementHeight = msg.height() + BTN_HEIGHT + GAP;
|
||||
|
||||
float top = 16 + (h - 16 - elementHeight)/2f;
|
||||
float left = (w-elementWidth)/2f;
|
||||
float top = insets.top + 16 + (h - 16 - elementHeight)/2f;
|
||||
float left = insets.left + (w-elementWidth)/2f;
|
||||
|
||||
msg.setPos(left, top);
|
||||
align(msg);
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.Random;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.FloatBuffer;
|
||||
@@ -95,14 +96,19 @@ public class SurfaceScene extends PixelScene {
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.reversed = true;
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
float vx = align((w - SKY_WIDTH) / 2f);
|
||||
float vy = align((h - SKY_HEIGHT - BUTTON_HEIGHT) / 2f);
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
float vx = align(insets.left + (w - SKY_WIDTH) / 2f);
|
||||
float vy = align(insets.top + (h - SKY_HEIGHT - BUTTON_HEIGHT) / 2f);
|
||||
|
||||
Point s = Camera.main.cameraToScreen( vx, vy );
|
||||
viewport = new Camera( s.x, s.y, SKY_WIDTH, SKY_HEIGHT, defaultZoom );
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.utils.ColorMath;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -71,18 +72,23 @@ public class TitleScene extends PixelScene {
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
|
||||
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
add( archs );
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
Image title = BannerSprites.get( landscape() ? BannerSprites.Type.TITLE_LAND : BannerSprites.Type.TITLE_PORT);
|
||||
add( title );
|
||||
|
||||
float topRegion = Math.max(title.height - 6, h*0.45f);
|
||||
|
||||
title.x = (w - title.width()) / 2f;
|
||||
title.y = 2 + (topRegion - title.height()) / 2f;
|
||||
title.x = insets.left + (w - title.width()) / 2f;
|
||||
title.y = insets.top + 2 + (topRegion - title.height()) / 2f;
|
||||
|
||||
align(title);
|
||||
|
||||
@@ -190,9 +196,9 @@ public class TitleScene extends PixelScene {
|
||||
GAP = Math.max(GAP, 2);
|
||||
|
||||
float buttonAreaWidth = landscape() ? PixelScene.MIN_WIDTH_L-6 : PixelScene.MIN_WIDTH_P-2;
|
||||
float btnAreaLeft = (Camera.main.width - buttonAreaWidth) / 2f;
|
||||
float btnAreaLeft = insets.left + (w - buttonAreaWidth) / 2f;
|
||||
if (landscape()) {
|
||||
btnPlay.setRect(btnAreaLeft, topRegion+GAP, (buttonAreaWidth/2)-1, BTN_HEIGHT);
|
||||
btnPlay.setRect(btnAreaLeft, insets.top + topRegion+GAP, (buttonAreaWidth/2)-1, BTN_HEIGHT);
|
||||
align(btnPlay);
|
||||
btnSupport.setRect(btnPlay.right()+2, btnPlay.top(), btnPlay.width(), BTN_HEIGHT);
|
||||
btnRankings.setRect(btnPlay.left(), btnPlay.bottom()+ GAP, (float) (Math.floor(buttonAreaWidth/3f)-1), BTN_HEIGHT);
|
||||
@@ -202,7 +208,7 @@ public class TitleScene extends PixelScene {
|
||||
btnChanges.setRect(btnSettings.right()+2, btnSettings.top(), btnRankings.width(), BTN_HEIGHT);
|
||||
btnAbout.setRect(btnChanges.right()+2, btnSettings.top(), btnRankings.width(), BTN_HEIGHT);
|
||||
} else {
|
||||
btnPlay.setRect(btnAreaLeft, topRegion+GAP, buttonAreaWidth, BTN_HEIGHT);
|
||||
btnPlay.setRect(btnAreaLeft, insets.top + topRegion+GAP, buttonAreaWidth, BTN_HEIGHT);
|
||||
align(btnPlay);
|
||||
btnSupport.setRect(btnPlay.left(), btnPlay.bottom()+ GAP, btnPlay.width(), BTN_HEIGHT);
|
||||
btnRankings.setRect(btnPlay.left(), btnSupport.bottom()+ GAP, (btnPlay.width()/2)-1, BTN_HEIGHT);
|
||||
@@ -216,8 +222,9 @@ public class TitleScene extends PixelScene {
|
||||
BitmapText version = new BitmapText( "v" + Game.version, pixelFont);
|
||||
version.measure();
|
||||
version.hardlight( 0x888888 );
|
||||
version.x = w - version.width() - 4;
|
||||
version.y = h - version.height() - 2;
|
||||
//TODO perhaps extra check for Android top-right / top-left notches?
|
||||
version.x = insets.left + w - version.width() - 4;
|
||||
version.y = insets.top + h - version.height() - 2;
|
||||
add( version );
|
||||
|
||||
if (DeviceCompat.isDesktop()) {
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.utils.FileUtils;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -94,6 +95,7 @@ public class WelcomeScene extends PixelScene {
|
||||
|
||||
int w = Camera.main.width;
|
||||
int h = Camera.main.height;
|
||||
RectF insets = getCommonInsets();
|
||||
|
||||
Archs archs = new Archs();
|
||||
archs.setSize( w, h );
|
||||
@@ -102,13 +104,16 @@ public class WelcomeScene extends PixelScene {
|
||||
//darkens the arches
|
||||
add(new ColorBlock(w, h, 0x88000000));
|
||||
|
||||
w -= insets.left + insets.right;
|
||||
h -= insets.top + insets.bottom;
|
||||
|
||||
Image title = BannerSprites.get( landscape() ? BannerSprites.Type.TITLE_LAND : BannerSprites.Type.TITLE_PORT);
|
||||
add( title );
|
||||
|
||||
float topRegion = Math.max(title.height - 6, h*0.45f);
|
||||
|
||||
title.x = (w - title.width()) / 2f;
|
||||
title.y = 2 + (topRegion - title.height()) / 2f;
|
||||
title.x = insets.left + (w - title.width()) / 2f;
|
||||
title.y = insets.top + 2 + (topRegion - title.height()) / 2f;
|
||||
|
||||
align(title);
|
||||
|
||||
@@ -165,10 +170,10 @@ public class WelcomeScene extends PixelScene {
|
||||
}
|
||||
};
|
||||
|
||||
float buttonY = Math.min(topRegion + (PixelScene.landscape() ? 60 : 120), h - 24);
|
||||
float buttonY = insets.top + Math.min(topRegion + (PixelScene.landscape() ? 60 : 120), h - 24);
|
||||
|
||||
float buttonAreaWidth = landscape() ? PixelScene.MIN_WIDTH_L-6 : PixelScene.MIN_WIDTH_P-2;
|
||||
float btnAreaLeft = (Camera.main.width - buttonAreaWidth) / 2f;
|
||||
float btnAreaLeft = insets.left + (w - buttonAreaWidth) / 2f;
|
||||
if (previousVersion != 0 && !SPDSettings.intro()){
|
||||
StyledButton changes = new StyledButton(Chrome.Type.GREY_BUTTON_TR, Messages.get(TitleScene.class, "changes")){
|
||||
@Override
|
||||
@@ -216,7 +221,7 @@ public class WelcomeScene extends PixelScene {
|
||||
text.text(message, Math.min(w-20, 300));
|
||||
float titleBottom = title.y + title.height();
|
||||
float textSpace = okay.top() - titleBottom - 4;
|
||||
text.setPos((w - text.width()) / 2f, (titleBottom + 2) + (textSpace - text.height())/2);
|
||||
text.setPos(insets.left + (w - text.width()) / 2f, (titleBottom + 2) + (textSpace - text.height())/2);
|
||||
add(text);
|
||||
|
||||
if (SPDSettings.intro() && ControllerHandler.isControllerConnected()){
|
||||
|
||||
@@ -33,7 +33,9 @@ import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.NinePatch;
|
||||
import com.watabou.noosa.PointerArea;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.RectF;
|
||||
import com.watabou.utils.Signal;
|
||||
|
||||
public class Window extends Group implements Signal.Listener<KeyEvent> {
|
||||
@@ -94,13 +96,17 @@ public class Window extends Group implements Signal.Listener<KeyEvent> {
|
||||
width - chrome.x + chrome.marginRight(),
|
||||
height - chrome.y + chrome.marginBottom() );
|
||||
add( chrome );
|
||||
|
||||
RectF insets = Game.platform.getSafeInsets(PlatformSupport.INSET_BLK);
|
||||
int screenW = (int)(Game.width - insets.left - insets.right);
|
||||
int screenH = (int)(Game.height - insets.top - insets.bottom);
|
||||
|
||||
camera = new Camera( 0, 0,
|
||||
(int)chrome.width,
|
||||
(int)chrome.height,
|
||||
PixelScene.defaultZoom );
|
||||
camera.x = (int)(Game.width - camera.width * camera.zoom) / 2;
|
||||
camera.y = (int)(Game.height - camera.height * camera.zoom) / 2;
|
||||
camera.x = (int)(insets.left + (screenW - camera.width * camera.zoom) / 2);
|
||||
camera.y = (int)(insets.top + (screenH - camera.height * camera.zoom) / 2);
|
||||
camera.y -= yOffset * camera.zoom;
|
||||
camera.scroll.set( chrome.x, chrome.y );
|
||||
Camera.add( camera );
|
||||
@@ -123,10 +129,16 @@ public class Window extends Group implements Signal.Listener<KeyEvent> {
|
||||
|
||||
camera.resize( (int)chrome.width, (int)chrome.height );
|
||||
|
||||
camera.x = (int)(Game.width - camera.screenWidth()) / 2;
|
||||
RectF insets = Game.platform.getSafeInsets(PlatformSupport.INSET_BLK);
|
||||
int screenW = (int)(Game.width - insets.left - insets.right);
|
||||
int screenH = (int)(Game.height - insets.top - insets.bottom);
|
||||
|
||||
camera.x = (int)(screenW - camera.screenWidth()) / 2;
|
||||
camera.x += insets.left;
|
||||
camera.x += xOffset * camera.zoom;
|
||||
|
||||
camera.y = (int)(Game.height - camera.screenHeight()) / 2;
|
||||
camera.y = (int)(screenH - camera.screenHeight()) / 2;
|
||||
camera.y += insets.top;
|
||||
camera.y += yOffset * camera.zoom;
|
||||
|
||||
shadow.boxRect( camera.x / camera.zoom, camera.y / camera.zoom, chrome.width(), chrome.height );
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.watabou.input.ControllerHandler;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import com.watabou.utils.RectF;
|
||||
|
||||
import org.robovm.apple.audiotoolbox.AudioServices;
|
||||
import org.robovm.apple.systemconfiguration.SCNetworkReachability;
|
||||
@@ -63,6 +64,16 @@ public class IOSPlatformSupport extends PlatformSupport {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RectF getSafeInsets(int level) {
|
||||
//TODO currently returns all insets all the time. Needs testing based on particular iOS quirks
|
||||
// we roughly want:
|
||||
// ignore bottom home indicator insets in fullsceen
|
||||
// ignore side insets in landscape for side that isn't notch
|
||||
// older notch is large, compact dynamic island is not (maybe? Probably need UI adjustments then)
|
||||
return super.getSafeInsets(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSystemUI() {
|
||||
int prevInset = Game.bottomInset;
|
||||
|
||||
Reference in New Issue
Block a user