mirror of
https://github.com/jamessanford/kegs.git
synced 2025-03-05 23:29:18 +00:00
Replace crazy screen scaling code with more crazy screen scaling code.
This commit is contained in:
parent
feef9a1c3d
commit
5ee9ac2c1a
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.froop.app.kegs.SpecialRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/mainview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
@ -71,4 +71,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</com.froop.app.kegs.SpecialRelativeLayout>
|
||||
|
@ -24,14 +24,12 @@ class BitmapSize {
|
||||
}
|
||||
|
||||
public boolean showActionBar() {
|
||||
if (mScaleFactorY != 1.0f && mScaleFactorX != mScaleFactorY) {
|
||||
return false;
|
||||
} else if (mHeight < getViewHeight()) {
|
||||
// However, beware that disabling the action bar may increase
|
||||
// the space enough to think that we should reenable it.
|
||||
return false;
|
||||
} else {
|
||||
if (mWidth < mHeight) {
|
||||
// portrait mode
|
||||
return true;
|
||||
} else {
|
||||
// TODO FIXME: also if the screen is BIG, return true.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,25 +38,17 @@ class BitmapSize {
|
||||
}
|
||||
|
||||
public int getViewHeight() {
|
||||
if (!doCropBorder()) {
|
||||
return (int)(Const.A2Height * mScaleFactorY);
|
||||
} else {
|
||||
return (int)((Const.A2Height - 32 - 30) * mScaleFactorY);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doCropBorder() {
|
||||
return mCropped;
|
||||
}
|
||||
|
||||
public int getCropPixelCount() {
|
||||
if (doCropBorder()) {
|
||||
return 30; // pixels dropped from the *bottom*
|
||||
return (int)(400 * mScaleFactorY);
|
||||
} else {
|
||||
return 0;
|
||||
return (int)(Const.A2Height * mScaleFactorY);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean doCropBorder() {
|
||||
return mCropped;
|
||||
}
|
||||
|
||||
public boolean isScaled() {
|
||||
return (mScaleFactorX != 1.0f || mScaleFactorY != 1.0f);
|
||||
}
|
||||
@ -87,32 +77,35 @@ class BitmapSize {
|
||||
}
|
||||
}
|
||||
|
||||
// If we can fit at least 90% of a scaled screen into the display area, do it.
|
||||
// If we hit less than 100% height, turn off system action bar and title.
|
||||
// If ((400 + 32) * scale) > height, then crop border.
|
||||
private void calculateScale(int width, int height) {
|
||||
float scaleX = 1.0f;
|
||||
float scaleY = 1.0f;
|
||||
float scaleX;
|
||||
float scaleY;
|
||||
boolean crop = false;
|
||||
|
||||
// Force integer scaling on X axis.
|
||||
scaleX = (float)Math.round((width * 0.9) / 640);
|
||||
scaleX = Math.max(1, scaleX);
|
||||
scaleY = Math.min(scaleX, height / 400.0f);
|
||||
scaleY = scaleX;
|
||||
|
||||
// NOTE: scaleY should really never be less than '1',
|
||||
// although theoretically 0.5-1 would look OK, it causes poor performance
|
||||
if (height < Const.A2Height * scaleY) {
|
||||
// Scale it so that only the 400 pixels that matter take up the view.
|
||||
scaleY = Math.min(scaleX, height / 400.0f);
|
||||
|
||||
// User should only use the 400 pixels that matter.
|
||||
crop = true;
|
||||
}
|
||||
|
||||
// If Y would be compressed in a weird way, reduce the scale and use 1:1.
|
||||
if ((scaleX - scaleY) > 0.5) {
|
||||
scaleX = Math.max(1, scaleX - 1);
|
||||
scaleY = scaleX;
|
||||
}
|
||||
|
||||
// If the 32 line border and the 400 pixel display do not fit, try
|
||||
// cropping out the 32 line border.
|
||||
if (height < 432 * scaleY) {
|
||||
crop = true;
|
||||
// See whether we should crop it at that height.
|
||||
if (height < Const.A2Height * scaleY) {
|
||||
crop = true;
|
||||
} else {
|
||||
crop = false;
|
||||
}
|
||||
}
|
||||
|
||||
mCropped = crop;
|
||||
@ -120,13 +113,4 @@ class BitmapSize {
|
||||
mScaleFactorY = scaleY;
|
||||
Log.w("kegs", "using scale " + scaleX + ":" + scaleY + " crop=" + crop + " from screen " + width + "x" + height);
|
||||
}
|
||||
|
||||
// call us when you update your screen size/configuration
|
||||
|
||||
// helper to calculate view area for KegsView:onMeasure
|
||||
|
||||
// helper to create size struct
|
||||
|
||||
// helper struct for scale factors (&isScaled), crop info, source/dest rects
|
||||
// KegsView can get this and pass it into the thread.
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset, Asse
|
||||
|
||||
private boolean mAssetsReady = false;
|
||||
private boolean mModeMouse = true;
|
||||
private int mLastActionBar = 0; // window height at last ActionBar change.
|
||||
|
||||
private long mScreenSizeTime = 0;
|
||||
|
||||
private View.OnClickListener mButtonClick = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
@ -241,63 +242,37 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset, Asse
|
||||
}
|
||||
}
|
||||
|
||||
private void setScreenSize(boolean quick) {
|
||||
int width;
|
||||
int height;
|
||||
|
||||
if (quick) {
|
||||
width = getResources().getDisplayMetrics().widthPixels;
|
||||
height = getResources().getDisplayMetrics().heightPixels;
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
// NOTE: 48 is a guess at the System Bar obstruction.
|
||||
// These are 'visible insets' into the display from the window manager.
|
||||
height -= 48;
|
||||
}
|
||||
} else {
|
||||
Rect displaySize = new Rect();
|
||||
// We use the mKegsView object here, but we could ask any view.
|
||||
mKegsView.getWindowVisibleDisplayFrame(displaySize);
|
||||
width = displaySize.width();
|
||||
height = displaySize.height();
|
||||
private void updateScreenSize(int width, int height, long sent) {
|
||||
if (mScreenSizeTime != sent) {
|
||||
// There's a newer event coming soon, wait for it.
|
||||
return;
|
||||
}
|
||||
final BitmapSize bitmapSize = new BitmapSize(width, height);
|
||||
|
||||
mKegsView.updateScreenSize(bitmapSize);
|
||||
updateActionBar(bitmapSize.showActionBar());
|
||||
|
||||
// Only change action bar if the window height is significantly
|
||||
// different from the last time we changed the action bar.
|
||||
if (height < (mLastActionBar * 0.85) || height > (mLastActionBar * 1.15)) {
|
||||
mLastActionBar = height;
|
||||
updateActionBar(bitmapSize.showActionBar());
|
||||
}
|
||||
mKegsView.updateScreenSize(bitmapSize);
|
||||
|
||||
// Force another redraw of the bitmap into the canvas. Bug workaround.
|
||||
getThread().updateScreen();
|
||||
}
|
||||
|
||||
private void workaroundScreenSize() {
|
||||
// First use displayMetrics.
|
||||
setScreenSize(true);
|
||||
|
||||
// Then update with getWindowVisibleDisplayFrame in 250ms.
|
||||
//
|
||||
// We want to use getWindowVisibleDisplayFrame, but it's not
|
||||
// always immediately available. Bug workaround.
|
||||
//
|
||||
// BUG: Sometimes if the device rotates as the soft keyboard
|
||||
// is becoming visible for the first time, the reported
|
||||
// window size is reduced and we don't scale to full screen.
|
||||
// The user can fix this by rotating the screen again.
|
||||
// We may want to trap IME visible/hidden events and update the size.
|
||||
mKegsView.postDelayed(new Runnable() {
|
||||
public void run() { setScreenSize(false); }
|
||||
}, 250);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
workaroundScreenSize();
|
||||
|
||||
// Fire off a guess at a new size during this request,
|
||||
// it makes the animation transition look better.
|
||||
int width = getResources().getDisplayMetrics().widthPixels;
|
||||
int height = getResources().getDisplayMetrics().heightPixels;
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
// NOTE: 48 is a guess at the System Bar obstruction.
|
||||
// These are 'visible insets' into the display from the window manager.
|
||||
height -= 48;
|
||||
}
|
||||
final BitmapSize bitmapSize = new BitmapSize(width, height);
|
||||
updateActionBar(bitmapSize.showActionBar());
|
||||
mKegsView.updateScreenSize(bitmapSize);
|
||||
getThread().updateScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -380,12 +355,10 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset, Asse
|
||||
mKegsView.getBitmap());
|
||||
mKegsThread.registerUpdateScreenInterface(mKegsView);
|
||||
|
||||
workaroundScreenSize();
|
||||
|
||||
mKegsTouch = new KegsTouch(this, getThread().getEventQueue());
|
||||
mJoystick = new TouchJoystick(getThread().getEventQueue());
|
||||
|
||||
final View mainView = findViewById(R.id.mainview);
|
||||
final SpecialRelativeLayout mainView = (SpecialRelativeLayout)findViewById(R.id.mainview);
|
||||
mainView.setClickable(true);
|
||||
mainView.setLongClickable(true);
|
||||
mainView.setOnTouchListener(new OnTouchListener() {
|
||||
@ -398,6 +371,15 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset, Asse
|
||||
}
|
||||
}
|
||||
});
|
||||
mainView.setNotifySizeChanged(
|
||||
new SpecialRelativeLayout.NotifySizeChanged() {
|
||||
public void onSizeChanged(final int w, final int h, int oldw, int oldh) {
|
||||
final long now = System.currentTimeMillis();
|
||||
mScreenSizeTime = now;
|
||||
mKegsView.postDelayed(new Runnable() { public void run() { updateScreenSize(w, h, now); } }, 250);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
mKegsKeyboard = new KegsKeyboard(getThread().getEventQueue());
|
||||
mKegsKeyboard.setOnStickyReset(this);
|
||||
|
@ -51,7 +51,7 @@ class KegsRenderer implements GLSurfaceView.Renderer {
|
||||
private int mHeight = 0;
|
||||
private float mScaleX = 1.0f;
|
||||
private float mScaleY = 1.0f;
|
||||
private float mCropBorder = 0.0f;
|
||||
private boolean mCropBorder = false;
|
||||
private boolean mScaled = false;
|
||||
private boolean mSizeChange = false;
|
||||
|
||||
@ -86,11 +86,12 @@ class KegsRenderer implements GLSurfaceView.Renderer {
|
||||
private void setupOrtho(GL10 gl) {
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
// 50.0f is 512-(400+32+30) (the distance from the bottom of the texture to our actual bitmap)
|
||||
float cropBorder = 50.0f;
|
||||
cropBorder *= mScaleY;
|
||||
cropBorder += mCropBorder * mScaleY; // likely zero
|
||||
gl.glOrthof(0.0f, (float)mWidth, cropBorder, mHeight + cropBorder, 0.0f, 1.0f);
|
||||
// 50.0f is 512-(30+400+32) (the distance from the bottom of the texture to our actual bitmap)
|
||||
if (mCropBorder) {
|
||||
gl.glOrthof(0.0f, (float)mWidth, (50.0f+30.0f) * mScaleY, (50.0f+400.0f+30.0f) * mScaleY, 0.0f, 1.0f);
|
||||
} else {
|
||||
gl.glOrthof(0.0f, (float)mWidth, 50.0f * mScaleY, (50.0f+30.0f+400.0f+32.0f) * mScaleY, 0.0f, 1.0f);
|
||||
}
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
}
|
||||
@ -210,7 +211,7 @@ class KegsRenderer implements GLSurfaceView.Renderer {
|
||||
mHeight = bitmapSize.getViewHeight();
|
||||
mScaleX = bitmapSize.getScaleX();
|
||||
mScaleY = bitmapSize.getScaleY();
|
||||
mCropBorder = (float)bitmapSize.getCropPixelCount();
|
||||
mCropBorder = bitmapSize.doCropBorder();
|
||||
mScaled = bitmapSize.isScaled();
|
||||
mSizeChange = true;
|
||||
Log.e("kegs", "screen size " + mWidth + "x" + mHeight + " " + mScaleX + ":" + mScaleY + " crop=" + mCropBorder);
|
||||
|
39
src/com/froop/app/kegs/SpecialRelativeLayout.java
Normal file
39
src/com/froop/app/kegs/SpecialRelativeLayout.java
Normal file
@ -0,0 +1,39 @@
|
||||
package com.froop.app.kegs;
|
||||
|
||||
import android.widget.RelativeLayout;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
class SpecialRelativeLayout extends RelativeLayout {
|
||||
public SpecialRelativeLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
interface NotifySizeChanged {
|
||||
void onSizeChanged(int w, int h, int oldw, int oldh);
|
||||
}
|
||||
|
||||
private NotifySizeChanged mNotify;
|
||||
private int mWidth = 0;
|
||||
private int mHeight = 0;
|
||||
|
||||
public void setNotifySizeChanged(NotifySizeChanged notify) {
|
||||
mNotify = notify;
|
||||
|
||||
// In case the call had come in earlier.
|
||||
if (notify != null && mWidth != 0 && mHeight != 0) {
|
||||
mNotify.onSizeChanged(mWidth, mHeight, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
if (mNotify != null) {
|
||||
mNotify.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user