mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-06 20:45:54 +01:00
use GamesList's Handler to set timers to redraw turn expiry indicators
when the percent left changes. This may be done -- except for deciding what to do when the time actually runs out.
This commit is contained in:
parent
0a60419802
commit
b11da9d8eb
5 changed files with 138 additions and 95 deletions
|
@ -27,97 +27,105 @@ import android.graphics.Paint;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Handler;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
public class ExpiringDelegate {
|
public class ExpiringDelegate {
|
||||||
// private static final long INTERVAL_SECS = 3 * 24 * 60 * 60;
|
|
||||||
private static final long INTERVAL_SECS = 60 * 60;
|
|
||||||
|
|
||||||
private Drawable m_back = null;
|
private static final long INTERVAL_SECS = 3 * 24 * 60 * 60;
|
||||||
|
// private static final long INTERVAL_SECS = 60 * 10; // for testing
|
||||||
|
|
||||||
private Context m_context;
|
private Context m_context;
|
||||||
private View m_view;
|
private View m_view;
|
||||||
|
private boolean m_active = false;
|
||||||
private int m_pct = -1;
|
private int m_pct = -1;
|
||||||
|
private int m_backPct = -1;
|
||||||
|
private Drawable m_back = null;
|
||||||
private boolean m_doFrame = false;
|
private boolean m_doFrame = false;
|
||||||
// these could probably be static as drawing's all in same thread.
|
private Handler m_handler;
|
||||||
private Rect m_rect;
|
private boolean m_haveTurnLocal = false;
|
||||||
private Paint m_paint;
|
|
||||||
private float[] m_points;
|
|
||||||
private long m_startSecs;
|
private long m_startSecs;
|
||||||
|
private Runnable m_runnable = null;
|
||||||
|
// these can be static as drawing's all in same thread.
|
||||||
|
private static Rect s_rect;
|
||||||
|
private static Paint s_paint;
|
||||||
|
private static float[] s_points;
|
||||||
|
|
||||||
public ExpiringDelegate( Context context, View view, boolean haveTurn,
|
static {
|
||||||
boolean haveTurnLocal, long startSecs )
|
s_rect = new Rect();
|
||||||
|
s_paint = new Paint();
|
||||||
|
s_paint.setStyle(Paint.Style.STROKE);
|
||||||
|
s_paint.setStrokeWidth( 1 );
|
||||||
|
s_points = new float[4*6];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExpiringDelegate( Context context, View view, Handler handler )
|
||||||
{
|
{
|
||||||
m_context = context;
|
m_context = context;
|
||||||
m_view = view;
|
m_view = view;
|
||||||
|
m_handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure( boolean haveTurn, boolean haveTurnLocal,
|
||||||
|
long startSecs )
|
||||||
|
{
|
||||||
|
m_active = haveTurn;
|
||||||
|
m_doFrame = !haveTurnLocal;
|
||||||
|
if ( haveTurn ) {
|
||||||
m_startSecs = startSecs;
|
m_startSecs = startSecs;
|
||||||
|
m_haveTurnLocal = haveTurnLocal;
|
||||||
figurePct();
|
figurePct();
|
||||||
|
if ( haveTurnLocal ) {
|
||||||
if ( !haveTurn ) {
|
|
||||||
// nothing to do
|
|
||||||
} else if ( haveTurnLocal ) {
|
|
||||||
setBackground();
|
setBackground();
|
||||||
} else {
|
} else {
|
||||||
m_view.setWillNotDraw( false );
|
m_view.setWillNotDraw( false );
|
||||||
m_doFrame = true; // required if setWillNotDraw() used?
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDraw( Canvas canvas )
|
public void onDraw( Canvas canvas )
|
||||||
{
|
{
|
||||||
if ( m_doFrame ) {
|
if ( m_active && m_doFrame ) {
|
||||||
initDrawingIf();
|
|
||||||
Assert.assertTrue( 0 <= m_pct && m_pct <= 100 );
|
Assert.assertTrue( 0 <= m_pct && m_pct <= 100 );
|
||||||
m_view.getDrawingRect( m_rect );
|
m_view.getDrawingRect( s_rect );
|
||||||
int width = m_rect.width();
|
int width = s_rect.width();
|
||||||
int redWidth = width * m_pct / 100;
|
int redWidth = width * m_pct / 100;
|
||||||
Assert.assertTrue( redWidth <= width );
|
Assert.assertTrue( redWidth <= width );
|
||||||
|
|
||||||
// left edge
|
// left edge
|
||||||
addPoints( 0, m_rect.left, m_rect.top,
|
addPoints( 0, s_rect.left, s_rect.top,
|
||||||
m_rect.left, m_rect.bottom - 1 );
|
s_rect.left, s_rect.bottom - 1 );
|
||||||
|
|
||||||
// left horizontals
|
// left horizontals
|
||||||
addPoints( 1, m_rect.left, m_rect.top,
|
addPoints( 1, s_rect.left, s_rect.top,
|
||||||
m_rect.left + redWidth, m_rect.top );
|
s_rect.left + redWidth, s_rect.top );
|
||||||
addPoints( 2, m_rect.left, m_rect.bottom - 1,
|
addPoints( 2, s_rect.left, s_rect.bottom - 1,
|
||||||
m_rect.left + redWidth,
|
s_rect.left + redWidth,
|
||||||
m_rect.bottom - 1 );
|
s_rect.bottom - 1 );
|
||||||
|
|
||||||
// right horizontals
|
// right horizontals
|
||||||
addPoints( 3, m_rect.left + redWidth, m_rect.top,
|
addPoints( 3, s_rect.left + redWidth, s_rect.top,
|
||||||
m_rect.right - 1, m_rect.top );
|
s_rect.right - 1, s_rect.top );
|
||||||
addPoints( 4, m_rect.left + redWidth, m_rect.bottom - 1,
|
addPoints( 4, s_rect.left + redWidth, s_rect.bottom - 1,
|
||||||
m_rect.right - 1, m_rect.bottom - 1 );
|
s_rect.right - 1, s_rect.bottom - 1 );
|
||||||
|
|
||||||
// right edge
|
// right edge
|
||||||
addPoints( 5, m_rect.right - 1, m_rect.top,
|
addPoints( 5, s_rect.right - 1, s_rect.top,
|
||||||
m_rect.right - 1, m_rect.bottom );
|
s_rect.right - 1, s_rect.bottom );
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int count = m_points.length;
|
int count = s_points.length;
|
||||||
if ( 0 < redWidth ) {
|
if ( 0 < redWidth ) {
|
||||||
m_paint.setColor( Color.RED );
|
s_paint.setColor( Color.RED );
|
||||||
canvas.drawLines( m_points, offset, count / 2, m_paint );
|
canvas.drawLines( s_points, offset, count / 2, s_paint );
|
||||||
count /= 2;
|
count /= 2;
|
||||||
offset += count;
|
offset += count;
|
||||||
}
|
}
|
||||||
if ( redWidth < width ) {
|
if ( redWidth < width ) {
|
||||||
m_paint.setColor( Color.GREEN );
|
s_paint.setColor( Color.GREEN );
|
||||||
}
|
}
|
||||||
canvas.drawLines( m_points, offset, count, m_paint );
|
canvas.drawLines( s_points, offset, count, s_paint );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initDrawingIf()
|
|
||||||
{
|
|
||||||
if ( null == m_rect ) {
|
|
||||||
m_rect = new Rect();
|
|
||||||
m_paint = new Paint();
|
|
||||||
m_paint.setStyle(Paint.Style.STROKE);
|
|
||||||
m_paint.setStrokeWidth( 1 );
|
|
||||||
m_points = new float[4*6];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,37 +133,38 @@ public class ExpiringDelegate {
|
||||||
int right, int bottom )
|
int right, int bottom )
|
||||||
{
|
{
|
||||||
offset *= 4;
|
offset *= 4;
|
||||||
m_points[offset + 0] = left;
|
s_points[offset + 0] = left;
|
||||||
m_points[offset + 1] = top;
|
s_points[offset + 1] = top;
|
||||||
m_points[offset + 2] = right;
|
s_points[offset + 2] = right;
|
||||||
m_points[offset + 3] = bottom;
|
s_points[offset + 3] = bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBackground()
|
private void setBackground()
|
||||||
{
|
{
|
||||||
if ( null == m_back && -1 != m_pct ) {
|
Assert.assertTrue( m_active );
|
||||||
mkTurnIndicator();
|
Drawable back;
|
||||||
|
if ( -1 != m_pct && m_backPct != m_pct ) {
|
||||||
|
m_back = mkBackground( m_pct );
|
||||||
|
m_backPct = m_pct;
|
||||||
}
|
}
|
||||||
if ( null != m_back ) {
|
if ( null != m_back ) {
|
||||||
m_view.setBackgroundDrawable( m_back );
|
m_view.setBackgroundDrawable( m_back );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mkTurnIndicator()
|
private Drawable mkBackground( int pct )
|
||||||
{
|
{
|
||||||
Assert.assertTrue( 0 <= m_pct && m_pct <= 100 );
|
Assert.assertTrue( 0 <= pct && pct <= 100 );
|
||||||
if ( null == m_back ) {
|
|
||||||
Bitmap bm = Bitmap.createBitmap( 100, 1, Bitmap.Config.ARGB_8888 );
|
Bitmap bm = Bitmap.createBitmap( 100, 1, Bitmap.Config.ARGB_8888 );
|
||||||
Canvas canvas = new Canvas(bm);
|
Canvas canvas = new Canvas(bm);
|
||||||
|
|
||||||
Paint paint = new Paint();
|
Paint paint = new Paint();
|
||||||
paint.setStyle(Paint.Style.FILL);
|
paint.setStyle(Paint.Style.FILL);
|
||||||
paint.setColor( Color.RED );
|
paint.setColor( Color.RED );
|
||||||
canvas.drawRect( 0, 0, m_pct, 1, paint );
|
canvas.drawRect( 0, 0, pct, 1, paint );
|
||||||
paint.setColor( Utils.TURN_COLOR );
|
paint.setColor( Utils.TURN_COLOR );
|
||||||
canvas.drawRect( m_pct, 0, 100, 1, paint );
|
canvas.drawRect( pct, 0, 100, 1, paint );
|
||||||
m_back = new BitmapDrawable( m_context.getResources(), bm );
|
return new BitmapDrawable( m_context.getResources(), bm );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void figurePct()
|
private void figurePct()
|
||||||
|
@ -173,8 +182,29 @@ public class ExpiringDelegate {
|
||||||
long lastStart = m_startSecs + (onePct * m_pct);
|
long lastStart = m_startSecs + (onePct * m_pct);
|
||||||
Assert.assertTrue( lastStart <= now );
|
Assert.assertTrue( lastStart <= now );
|
||||||
long nextStartIn = lastStart + onePct - now;
|
long nextStartIn = lastStart + onePct - now;
|
||||||
DbgUtils.logf( "pct change %d seconds from now", nextStartIn );
|
// DbgUtils.logf( "pct change %d seconds from now", nextStartIn );
|
||||||
|
|
||||||
|
m_handler.postDelayed( mkRunnable(), 1000 * nextStartIn );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Runnable mkRunnable()
|
||||||
|
{
|
||||||
|
if ( null == m_runnable ) {
|
||||||
|
m_runnable = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if ( m_active ) {
|
||||||
|
figurePct();
|
||||||
|
if ( m_haveTurnLocal ) {
|
||||||
|
m_back = null;
|
||||||
|
setBackground();
|
||||||
|
}
|
||||||
|
m_view.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return m_runnable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.eehouse.android.xw4;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.os.Handler;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
@ -33,10 +34,13 @@ public class ExpiringLinearLayout extends LinearLayout {
|
||||||
m_context = context;
|
m_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPct( boolean haveTurn, boolean haveTurnLocal, long startSecs )
|
public void setPct( Handler handler, boolean haveTurn,
|
||||||
|
boolean haveTurnLocal, long startSecs )
|
||||||
{
|
{
|
||||||
m_delegate = new ExpiringDelegate( m_context, this, haveTurn,
|
if ( null == m_delegate ) {
|
||||||
haveTurnLocal, startSecs );
|
m_delegate = new ExpiringDelegate( m_context, this, handler );
|
||||||
|
}
|
||||||
|
m_delegate.configure( haveTurn, haveTurnLocal, startSecs );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.eehouse.android.xw4;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.os.Handler;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -34,10 +35,13 @@ class ExpiringTextView extends TextView {
|
||||||
m_context = context;
|
m_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPct( boolean haveTurn, boolean haveTurnLocal, long startSecs )
|
public void setPct( Handler handler, boolean haveTurn,
|
||||||
|
boolean haveTurnLocal, long startSecs )
|
||||||
{
|
{
|
||||||
m_delegate = new ExpiringDelegate( m_context, this, haveTurn,
|
if ( null == m_delegate ) {
|
||||||
haveTurnLocal, startSecs );
|
m_delegate = new ExpiringDelegate( m_context, this, handler );
|
||||||
|
}
|
||||||
|
m_delegate.configure( haveTurn, haveTurnLocal, startSecs );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,23 +19,24 @@
|
||||||
*/
|
*/
|
||||||
package org.eehouse.android.xw4;
|
package org.eehouse.android.xw4;
|
||||||
|
|
||||||
import android.widget.ListAdapter;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.DataSetObserver;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
|
||||||
import android.database.DataSetObserver;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ListAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap; // class is not synchronized
|
import java.util.HashMap; // class is not synchronized
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.text.DateFormat;
|
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
private Context m_context;
|
private Context m_context;
|
||||||
private LayoutInflater m_factory;
|
private LayoutInflater m_factory;
|
||||||
private int m_fieldID;
|
private int m_fieldID;
|
||||||
|
private Handler m_handler;
|
||||||
private static final boolean s_isFire;
|
private static final boolean s_isFire;
|
||||||
private static Random s_random;
|
private static Random s_random;
|
||||||
static {
|
static {
|
||||||
|
@ -96,8 +98,8 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
m_hideable.setVisibility( m_expanded? View.VISIBLE : View.GONE );
|
m_hideable.setVisibility( m_expanded? View.VISIBLE : View.GONE );
|
||||||
|
|
||||||
m_name.setBackgroundColor( android.R.color.transparent );
|
m_name.setBackgroundColor( android.R.color.transparent );
|
||||||
m_name.setPct( m_haveTurn && !m_expanded, m_haveTurnLocal,
|
m_name.setPct( m_handler, m_haveTurn && !m_expanded,
|
||||||
m_lastMoveTime );
|
m_haveTurnLocal, m_lastMoveTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onClick( View view ) {
|
public void onClick( View view ) {
|
||||||
|
@ -191,8 +193,8 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
|
|
||||||
LinearLayout list =
|
LinearLayout list =
|
||||||
(LinearLayout)layout.findViewById( R.id.player_list );
|
(LinearLayout)layout.findViewById( R.id.player_list );
|
||||||
boolean haveTurn = false;
|
boolean haveATurn = false;
|
||||||
boolean haveTurnLocal = false;
|
boolean haveALocalTurn = false;
|
||||||
boolean[] isLocal = new boolean[1];
|
boolean[] isLocal = new boolean[1];
|
||||||
for ( int ii = 0; ii < summary.nPlayers; ++ii ) {
|
for ( int ii = 0; ii < summary.nPlayers; ++ii ) {
|
||||||
ExpiringLinearLayout tmp = (ExpiringLinearLayout)
|
ExpiringLinearLayout tmp = (ExpiringLinearLayout)
|
||||||
|
@ -201,13 +203,15 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
view.setText( summary.summarizePlayer( ii ) );
|
view.setText( summary.summarizePlayer( ii ) );
|
||||||
view = (TextView)tmp.findViewById( R.id.item_score );
|
view = (TextView)tmp.findViewById( R.id.item_score );
|
||||||
view.setText( String.format( " %d", summary.scores[ii] ) );
|
view.setText( String.format( " %d", summary.scores[ii] ) );
|
||||||
if ( summary.isNextToPlay( ii, isLocal ) ) {
|
boolean thisHasTurn = summary.isNextToPlay( ii, isLocal );
|
||||||
haveTurn = true;
|
if ( thisHasTurn ) {
|
||||||
|
haveATurn = true;
|
||||||
if ( isLocal[0] ) {
|
if ( isLocal[0] ) {
|
||||||
haveTurnLocal = true;
|
haveALocalTurn = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmp.setPct( haveTurn, haveTurnLocal, summary.lastMoveTime );
|
tmp.setPct( m_handler, thisHasTurn, isLocal[0],
|
||||||
|
summary.lastMoveTime );
|
||||||
list.addView( tmp, ii );
|
list.addView( tmp, ii );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,8 +247,8 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
|
|
||||||
boolean expanded = DBUtils.getExpanded( m_context, m_rowid );
|
boolean expanded = DBUtils.getExpanded( m_context, m_rowid );
|
||||||
ViewInfo vi = new ViewInfo( layout, m_rowid, expanded,
|
ViewInfo vi = new ViewInfo( layout, m_rowid, expanded,
|
||||||
summary.lastMoveTime, haveTurn,
|
summary.lastMoveTime, haveATurn,
|
||||||
haveTurnLocal );
|
haveALocalTurn );
|
||||||
|
|
||||||
synchronized( m_viewsCache ) {
|
synchronized( m_viewsCache ) {
|
||||||
m_viewsCache.put( m_rowid, vi );
|
m_viewsCache.put( m_rowid, vi );
|
||||||
|
@ -263,9 +267,10 @@ public class GameListAdapter extends XWListAdapter {
|
||||||
}
|
}
|
||||||
} // class LoadItemTask
|
} // class LoadItemTask
|
||||||
|
|
||||||
public GameListAdapter( Context context, LoadItemCB cb ) {
|
public GameListAdapter( Context context, Handler handler, LoadItemCB cb ) {
|
||||||
super( DBUtils.gamesList(context).length );
|
super( DBUtils.gamesList(context).length );
|
||||||
m_context = context;
|
m_context = context;
|
||||||
|
m_handler = handler;
|
||||||
m_cb = cb;
|
m_cb = cb;
|
||||||
m_factory = LayoutInflater.from( context );
|
m_factory = LayoutInflater.from( context );
|
||||||
m_df = DateFormat.getDateTimeInstance( DateFormat.SHORT,
|
m_df = DateFormat.getDateTimeInstance( DateFormat.SHORT,
|
||||||
|
|
|
@ -267,7 +267,7 @@ public class GamesList extends XWListActivity
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_adapter = new GameListAdapter( this, this );
|
m_adapter = new GameListAdapter( this, new Handler(), this );
|
||||||
setListAdapter( m_adapter );
|
setListAdapter( m_adapter );
|
||||||
|
|
||||||
NetUtils.informOfDeaths( this );
|
NetUtils.informOfDeaths( this );
|
||||||
|
|
Loading…
Add table
Reference in a new issue