mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-07 05:24:46 +01:00
snapshot on the way to handling rotation of the board view. Pass
orientation changes down to it (or any other interested delegate), and have it lay its container out again. There appear to be race conditions here: sometimes the toolbar winds up in the wrong orientation, and on some devices the board can be blank. One problem is that on a multi-paned device a single pane may be portrait (taller than wide) though the whole device is in landscape mode. The big challege is to get the view's max dimensions (and whether it's landscape or portrait) when layout hasn't yet begun, because we that for the jni part of layout. Messy still, but better than before and I think progress in the right direction.
This commit is contained in:
parent
b6431f0373
commit
ae8a66f37b
8 changed files with 146 additions and 70 deletions
|
@ -596,6 +596,7 @@ public class BoardDelegate extends DelegateBase
|
|||
m_timers = new TimerRunnable[4]; // needs to be in sync with
|
||||
// XWTimerReason
|
||||
m_view = (BoardView)findViewById( R.id.board_view );
|
||||
m_view.setBoardDelegate( this );
|
||||
if ( ! ABUtils.haveActionBar() ) {
|
||||
m_tradeButtons = findViewById( R.id.exchange_buttons );
|
||||
if ( null != m_tradeButtons ) {
|
||||
|
@ -752,6 +753,26 @@ public class BoardDelegate extends DelegateBase
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void orientationChanged()
|
||||
{
|
||||
boolean isPortrait = isPortrait();
|
||||
DbgUtils.logdf( "BoardDelegate.orientationChanged(isPortrait=%b)",
|
||||
isPortrait );
|
||||
positionToolbar( isPortrait );
|
||||
m_view.orientationChanged();
|
||||
}
|
||||
|
||||
private void positionToolbar( boolean isPortrait )
|
||||
{
|
||||
if ( null != findViewById( R.id.tbar_parent_hor ) ) {
|
||||
if ( null == m_toolbar ) {
|
||||
m_toolbar = new Toolbar( m_activity, this );
|
||||
}
|
||||
m_toolbar.setIsPortrait( isPortrait );
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean onKeyDown( int keyCode, KeyEvent event )
|
||||
{
|
||||
boolean handled = false;
|
||||
|
@ -2155,12 +2176,7 @@ public class BoardDelegate extends DelegateBase
|
|||
setTitle( GameUtils.getName( m_activity, m_rowid ) );
|
||||
}
|
||||
|
||||
if ( null != findViewById( R.id.tbar_parent_hor ) ) {
|
||||
int orient = m_activity.getResources().getConfiguration().orientation;
|
||||
boolean isLandscape = Configuration.ORIENTATION_LANDSCAPE == orient;
|
||||
m_toolbar = new Toolbar( m_activity, this, isLandscape );
|
||||
}
|
||||
|
||||
positionToolbar( isPortrait() );
|
||||
populateToolbar();
|
||||
adjustTradeVisibility();
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
private static final int PINCH_THRESHOLD = 40;
|
||||
|
||||
private Context m_context;
|
||||
private BoardDelegate m_boardDlgt;
|
||||
private int m_defaultFontHt;
|
||||
private int m_mediumFontHt;
|
||||
private Runnable m_invalidator;
|
||||
|
@ -142,33 +143,21 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
return wantMore; // true required to get subsequent events
|
||||
}
|
||||
|
||||
// private void printMode( String comment, int mode )
|
||||
// {
|
||||
// comment += ": ";
|
||||
// switch( mode ) {
|
||||
// case View.MeasureSpec.AT_MOST:
|
||||
// comment += "AT_MOST";
|
||||
// break;
|
||||
// case View.MeasureSpec.EXACTLY:
|
||||
// comment += "EXACTLY";
|
||||
// break;
|
||||
// case View.MeasureSpec.UNSPECIFIED:
|
||||
// comment += "UNSPECIFIED";
|
||||
// break;
|
||||
// default:
|
||||
// comment += "<bogus>";
|
||||
// }
|
||||
// DbgUtils.logf( comment );
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
|
||||
{
|
||||
// One of the android sample apps ignores mode entirely:
|
||||
// int w = MeasureSpec.getSize(widthMeasureSpec);
|
||||
// int h = MeasureSpec.getSize(heightMeasureSpec);
|
||||
// int d = w == 0 ? h : h == 0 ? w : w < h ? w : h;
|
||||
// setMeasuredDimension(d, d);
|
||||
// DbgUtils.logf( "onMeasure(width: %s, height: %s)",
|
||||
// MeasureSpec.toString( widthMeasureSpec ),
|
||||
// MeasureSpec.toString( heightMeasureSpec ) );
|
||||
|
||||
if ( null != m_dims ) {
|
||||
if ( m_boardDlgt.isPortrait() != (m_dims.height > m_dims.width) ) {
|
||||
// square possible; will break above!
|
||||
Assert.assertTrue( m_dims.height != m_dims.width );
|
||||
// DbgUtils.logf( "onMeasure: discarding m_dims" );
|
||||
m_dims = null;
|
||||
}
|
||||
}
|
||||
|
||||
int width, height;
|
||||
m_measuredFromDims = null != m_dims;
|
||||
|
@ -189,8 +178,17 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
width = minWidth;
|
||||
}
|
||||
setMeasuredDimension( width, height );
|
||||
DbgUtils.logdf( "BoardView.onMeasure: calling setMeasuredDimension( width=%d, height=%d )",
|
||||
width, height );
|
||||
}
|
||||
|
||||
// public void onSizeChanged( int width, int height, int oldWidth, int oldHeight )
|
||||
// {
|
||||
// DbgUtils.logf( "BoardView.onSizeChanged(): width: %d => %d; height: %d => %d",
|
||||
// oldWidth, width, oldHeight, height );
|
||||
// super.onSizeChanged( width, height, oldWidth, oldHeight );
|
||||
// }
|
||||
|
||||
// This will be called from the UI thread
|
||||
@Override
|
||||
protected void onDraw( Canvas canvas )
|
||||
|
@ -268,6 +266,11 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
return layoutDone;
|
||||
} // layoutBoardOnce
|
||||
|
||||
protected void setBoardDelegate( BoardDelegate dlgt )
|
||||
{
|
||||
m_boardDlgt = dlgt;
|
||||
}
|
||||
|
||||
// BoardHandler interface implementation
|
||||
public void startHandling( Activity parent, JNIThread thread,
|
||||
XwJNI.GamePtr gamePtr, CurGameInfo gi,
|
||||
|
@ -334,6 +337,12 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
|
|||
});
|
||||
}
|
||||
|
||||
protected void orientationChanged()
|
||||
{
|
||||
m_dims = null;
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
public void setInTrade( boolean inTrade )
|
||||
{
|
||||
if ( null != m_canvas ) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
|
@ -86,7 +87,8 @@ public class DelegateBase implements DlgClickNotify,
|
|||
protected void onDestroy() {}
|
||||
protected void onWindowFocusChanged( boolean hasFocus ) {}
|
||||
protected boolean onBackPressed() { return false; }
|
||||
|
||||
public void orientationChanged() {}
|
||||
|
||||
protected void requestWindowFeature( int feature ) {}
|
||||
|
||||
// Fragments only
|
||||
|
@ -232,6 +234,29 @@ public class DelegateBase implements DlgClickNotify,
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean isPortrait()
|
||||
{
|
||||
int[] containerDims = new int[2];
|
||||
getContainerDims( containerDims );
|
||||
boolean result = containerDims[0] < containerDims[1];
|
||||
DbgUtils.logdf( "%s.isPortrait() => %b", getClass().getName(), result );
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void getContainerDims( int[] outDims )
|
||||
{
|
||||
if ( m_activity instanceof FragActivity ) {
|
||||
((FragActivity)m_activity).getFragmentDims( outDims );
|
||||
} else {
|
||||
Rect rect = new Rect();
|
||||
m_rootView.getWindowVisibleDisplayFrame( rect );
|
||||
outDims[0] = rect.width();
|
||||
outDims[1] = rect.height();
|
||||
}
|
||||
DbgUtils.logdf( "getContainerDims(): width => %d, height => %d",
|
||||
outDims[0], outDims[1] );
|
||||
}
|
||||
|
||||
protected String getString( int resID, Object... params )
|
||||
{
|
||||
return LocUtils.getString( m_activity, resID, params );
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "find-and-ant.sh debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2014 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2014-2016 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -20,6 +20,7 @@
|
|||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.app.Dialog;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
|
@ -39,8 +40,10 @@ import junit.framework.Assert;
|
|||
public class FragActivity extends FragmentActivity
|
||||
implements FragmentManager.OnBackStackChangedListener {
|
||||
|
||||
private static final int MAX_PANES_LANDSCAPE = 2;
|
||||
|
||||
public interface OrientChangeListener {
|
||||
void orientationChanged( int orientation );
|
||||
void orientationChanged();
|
||||
}
|
||||
|
||||
private static FragActivity s_this;
|
||||
|
@ -79,17 +82,35 @@ public class FragActivity extends FragmentActivity
|
|||
@Override
|
||||
public void onConfigurationChanged( Configuration newConfig )
|
||||
{
|
||||
int orientation = newConfig.orientation;
|
||||
boolean isPortrait = orientation == Configuration.ORIENTATION_PORTRAIT;
|
||||
int maxPanes = isPortrait? 1 : 2;
|
||||
Rect rect = new Rect();
|
||||
m_root.getWindowVisibleDisplayFrame( rect );
|
||||
// DbgUtils.logf( "FragActivity.onConfigurationChanged(): width=%d; height=%d",
|
||||
// rect.width(), rect.height());
|
||||
|
||||
boolean isPortrait
|
||||
= Configuration.ORIENTATION_PORTRAIT == newConfig.orientation;
|
||||
if ( isPortrait != (rect.width() <= rect.height()) ) {
|
||||
DbgUtils.logdf( "FragActivity.onConfigurationChanged(): isPortrait:"
|
||||
+ " %b; width: %d; height: %d",
|
||||
isPortrait, rect.width(), rect.height() );
|
||||
}
|
||||
int maxPanes = isPortrait? 1 : MAX_PANES_LANDSCAPE;
|
||||
if ( m_maxPanes != maxPanes ) {
|
||||
m_maxPanes = maxPanes;
|
||||
setVisiblePanes();
|
||||
tellOrientationChanged( orientation );
|
||||
}
|
||||
tellOrientationChanged();
|
||||
super.onConfigurationChanged( newConfig );
|
||||
}
|
||||
|
||||
protected void getFragmentDims( int[] dims )
|
||||
{
|
||||
Rect rect = new Rect();
|
||||
m_root.getWindowVisibleDisplayFrame( rect );
|
||||
dims[0] = rect.width() / Math.min( m_maxPanes, m_root.getChildCount() );
|
||||
dims[1] = rect.height();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog( int id )
|
||||
{
|
||||
|
@ -225,7 +246,7 @@ public class FragActivity extends FragmentActivity
|
|||
}
|
||||
|
||||
// Walk all Fragment children and if they care notify of change.
|
||||
private void tellOrientationChanged( int orientation )
|
||||
private void tellOrientationChanged()
|
||||
{
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
int nPanes = m_root.getChildCount();
|
||||
|
@ -236,7 +257,7 @@ public class FragActivity extends FragmentActivity
|
|||
if ( null == frag ) {
|
||||
DbgUtils.logf( "tellOrienationChanged: NO FRAG at %d, id=%d", ii, id );
|
||||
} else if ( frag instanceof OrientChangeListener ) {
|
||||
((OrientChangeListener)frag).orientationChanged( orientation );
|
||||
((OrientChangeListener)frag).orientationChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import junit.framework.Assert;
|
|||
// obtainable when other read locks are granted but not when a
|
||||
// write lock is. Write-locks are exclusive.
|
||||
public class GameLock {
|
||||
private static final boolean DEBUG_LOCKS = true;
|
||||
private static final boolean DEBUG_LOCKS = false;
|
||||
private static final int SLEEP_TIME = 100;
|
||||
private static final long ASSERT_TIME = 2000;
|
||||
private long m_rowid;
|
||||
|
|
|
@ -72,17 +72,12 @@ public class Toolbar {
|
|||
private DlgDelegate.HasDlgDelegate m_dlgDlgt;
|
||||
private LinearLayout m_layout;
|
||||
private boolean m_visible;
|
||||
private Boolean m_isPortrait;
|
||||
|
||||
private enum ORIENTATION { ORIENT_PORTRAIT, ORIENT_LANDSCAPE };
|
||||
private ORIENTATION m_curOrient = null;
|
||||
|
||||
public Toolbar( Activity activity, HasDlgDelegate dlgDlgt,
|
||||
boolean isLandscape )
|
||||
public Toolbar( Activity activity, HasDlgDelegate dlgDlgt )
|
||||
{
|
||||
m_activity = activity;
|
||||
m_dlgDlgt = dlgDlgt;
|
||||
|
||||
setIsLandscape( isLandscape );
|
||||
}
|
||||
|
||||
public void setVisible( boolean visible )
|
||||
|
@ -123,18 +118,10 @@ public class Toolbar {
|
|||
setLongClickListener( index, listener );
|
||||
}
|
||||
|
||||
private void setIsLandscape( boolean landscape )
|
||||
protected void setIsPortrait( boolean isPortrait )
|
||||
{
|
||||
if ( landscape && m_curOrient == ORIENTATION.ORIENT_LANDSCAPE ) {
|
||||
// do nothing
|
||||
} else if ( !landscape && m_curOrient == ORIENTATION.ORIENT_PORTRAIT ) {
|
||||
// do nothing
|
||||
} else {
|
||||
if ( landscape ) {
|
||||
m_curOrient = ORIENTATION.ORIENT_LANDSCAPE;
|
||||
} else {
|
||||
m_curOrient = ORIENTATION.ORIENT_PORTRAIT;
|
||||
}
|
||||
if ( null == m_isPortrait || m_isPortrait != isPortrait ) {
|
||||
m_isPortrait = isPortrait;
|
||||
doShowHide();
|
||||
}
|
||||
}
|
||||
|
@ -151,20 +138,21 @@ public class Toolbar {
|
|||
|
||||
private void doShowHide()
|
||||
{
|
||||
Assert.assertTrue( null != m_curOrient );
|
||||
boolean isLandscape = ORIENTATION.ORIENT_LANDSCAPE == m_curOrient;
|
||||
Assert.assertTrue( null != m_isPortrait );
|
||||
if ( null == m_layout ) {
|
||||
m_layout = (LinearLayout)LocUtils.inflate( m_activity, R.layout.toolbar );
|
||||
m_layout.setOrientation(ORIENTATION.ORIENT_PORTRAIT == m_curOrient
|
||||
? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL );
|
||||
} else {
|
||||
((ViewGroup)m_layout.getParent()).removeView( m_layout );
|
||||
}
|
||||
m_layout.setOrientation( m_isPortrait ?
|
||||
LinearLayout.HORIZONTAL : LinearLayout.VERTICAL );
|
||||
|
||||
int id = isLandscape ? R.id.tbar_parent_vert : R.id.tbar_parent_hor;
|
||||
ViewGroup scroller = (ViewGroup)m_activity.findViewById( id );
|
||||
if ( null != scroller ) {
|
||||
// Google's had reports of a crash adding second view
|
||||
scroller.removeAllViews();
|
||||
scroller.addView( m_layout ); // failing
|
||||
}
|
||||
int id = m_isPortrait ? R.id.tbar_parent_hor : R.id.tbar_parent_vert;
|
||||
ViewGroup scroller = (ViewGroup)m_activity.findViewById( id );
|
||||
if ( null != scroller ) {
|
||||
// Google's had reports of a crash adding second view
|
||||
scroller.removeAllViews();
|
||||
scroller.addView( m_layout );
|
||||
}
|
||||
|
||||
m_layout.setVisibility( m_visible? View.VISIBLE : View.GONE );
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.eehouse.android.xw4;
|
|||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.ContextMenu;
|
||||
|
@ -178,6 +179,13 @@ public class XWActivity extends Activity implements Delegator {
|
|||
m_dlgt.prepareDialog( DlgID.values()[id], dialog );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged( Configuration newConfig )
|
||||
{
|
||||
m_dlgt.orientationChanged();
|
||||
super.onConfigurationChanged( newConfig );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult( int requestCode, int resultCode,
|
||||
Intent data )
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -33,7 +34,9 @@ import android.widget.ListView;
|
|||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class XWFragment extends Fragment implements Delegator {
|
||||
public class XWFragment extends Fragment
|
||||
implements Delegator,
|
||||
FragActivity.OrientChangeListener {
|
||||
|
||||
private DelegateBase m_dlgt;
|
||||
|
||||
|
@ -122,6 +125,12 @@ public class XWFragment extends Fragment implements Delegator {
|
|||
Assert.fail();
|
||||
}
|
||||
|
||||
// FragActivity.OrientChangeListener
|
||||
public void orientationChanged()
|
||||
{
|
||||
m_dlgt.orientationChanged();
|
||||
}
|
||||
|
||||
public ListView getListView()
|
||||
{
|
||||
ListView view = (ListView)m_dlgt.findViewById( android.R.id.list );
|
||||
|
|
Loading…
Reference in a new issue