Replace crazy screen scaling code with more crazy screen scaling code.

This commit is contained in:
James Sanford 2012-10-22 22:48:49 -07:00
parent feef9a1c3d
commit 5ee9ac2c1a
5 changed files with 108 additions and 102 deletions

View File

@ -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>

View File

@ -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.
}

View File

@ -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);

View File

@ -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);

View 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);
}
}
}