From b11da9d8eb563fed805b2161ecc2324b7493ef9a Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 2 Oct 2012 07:30:31 -0700 Subject: [PATCH] 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. --- .../eehouse/android/xw4/ExpiringDelegate.java | 174 ++++++++++-------- .../android/xw4/ExpiringLinearLayout.java | 10 +- .../eehouse/android/xw4/ExpiringTextView.java | 10 +- .../eehouse/android/xw4/GameListAdapter.java | 37 ++-- .../org/eehouse/android/xw4/GamesList.java | 2 +- 5 files changed, 138 insertions(+), 95 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java index a2a637b31..7d1b13968 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringDelegate.java @@ -27,97 +27,105 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.os.Handler; import android.view.View; import junit.framework.Assert; 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 View m_view; + private boolean m_active = false; private int m_pct = -1; + private int m_backPct = -1; + private Drawable m_back = null; private boolean m_doFrame = false; - // these could probably be static as drawing's all in same thread. - private Rect m_rect; - private Paint m_paint; - private float[] m_points; + private Handler m_handler; + private boolean m_haveTurnLocal = false; 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, - boolean haveTurnLocal, long startSecs ) + static { + 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_view = view; - m_startSecs = startSecs; + m_handler = handler; + } - figurePct(); - - if ( !haveTurn ) { - // nothing to do - } else if ( haveTurnLocal ) { - setBackground(); - } else { - m_view.setWillNotDraw( false ); - m_doFrame = true; // required if setWillNotDraw() used? + public void configure( boolean haveTurn, boolean haveTurnLocal, + long startSecs ) + { + m_active = haveTurn; + m_doFrame = !haveTurnLocal; + if ( haveTurn ) { + m_startSecs = startSecs; + m_haveTurnLocal = haveTurnLocal; + figurePct(); + if ( haveTurnLocal ) { + setBackground(); + } else { + m_view.setWillNotDraw( false ); + } } } public void onDraw( Canvas canvas ) { - if ( m_doFrame ) { - initDrawingIf(); + if ( m_active && m_doFrame ) { Assert.assertTrue( 0 <= m_pct && m_pct <= 100 ); - m_view.getDrawingRect( m_rect ); - int width = m_rect.width(); + m_view.getDrawingRect( s_rect ); + int width = s_rect.width(); int redWidth = width * m_pct / 100; Assert.assertTrue( redWidth <= width ); // left edge - addPoints( 0, m_rect.left, m_rect.top, - m_rect.left, m_rect.bottom - 1 ); + addPoints( 0, s_rect.left, s_rect.top, + s_rect.left, s_rect.bottom - 1 ); // left horizontals - addPoints( 1, m_rect.left, m_rect.top, - m_rect.left + redWidth, m_rect.top ); - addPoints( 2, m_rect.left, m_rect.bottom - 1, - m_rect.left + redWidth, - m_rect.bottom - 1 ); + addPoints( 1, s_rect.left, s_rect.top, + s_rect.left + redWidth, s_rect.top ); + addPoints( 2, s_rect.left, s_rect.bottom - 1, + s_rect.left + redWidth, + s_rect.bottom - 1 ); // right horizontals - addPoints( 3, m_rect.left + redWidth, m_rect.top, - m_rect.right - 1, m_rect.top ); - addPoints( 4, m_rect.left + redWidth, m_rect.bottom - 1, - m_rect.right - 1, m_rect.bottom - 1 ); + addPoints( 3, s_rect.left + redWidth, s_rect.top, + s_rect.right - 1, s_rect.top ); + addPoints( 4, s_rect.left + redWidth, s_rect.bottom - 1, + s_rect.right - 1, s_rect.bottom - 1 ); // right edge - addPoints( 5, m_rect.right - 1, m_rect.top, - m_rect.right - 1, m_rect.bottom ); + addPoints( 5, s_rect.right - 1, s_rect.top, + s_rect.right - 1, s_rect.bottom ); int offset = 0; - int count = m_points.length; + int count = s_points.length; if ( 0 < redWidth ) { - m_paint.setColor( Color.RED ); - canvas.drawLines( m_points, offset, count / 2, m_paint ); + s_paint.setColor( Color.RED ); + canvas.drawLines( s_points, offset, count / 2, s_paint ); count /= 2; offset += count; } if ( redWidth < width ) { - m_paint.setColor( Color.GREEN ); + s_paint.setColor( Color.GREEN ); } - canvas.drawLines( m_points, offset, count, m_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]; + canvas.drawLines( s_points, offset, count, s_paint ); } } @@ -125,37 +133,38 @@ public class ExpiringDelegate { int right, int bottom ) { offset *= 4; - m_points[offset + 0] = left; - m_points[offset + 1] = top; - m_points[offset + 2] = right; - m_points[offset + 3] = bottom; + s_points[offset + 0] = left; + s_points[offset + 1] = top; + s_points[offset + 2] = right; + s_points[offset + 3] = bottom; } private void setBackground() { - if ( null == m_back && -1 != m_pct ) { - mkTurnIndicator(); + Assert.assertTrue( m_active ); + Drawable back; + if ( -1 != m_pct && m_backPct != m_pct ) { + m_back = mkBackground( m_pct ); + m_backPct = m_pct; } if ( null != m_back ) { m_view.setBackgroundDrawable( m_back ); } } - private void mkTurnIndicator() + private Drawable mkBackground( int pct ) { - Assert.assertTrue( 0 <= m_pct && m_pct <= 100 ); - if ( null == m_back ) { - Bitmap bm = Bitmap.createBitmap( 100, 1, Bitmap.Config.ARGB_8888 ); - Canvas canvas = new Canvas(bm); + Assert.assertTrue( 0 <= pct && pct <= 100 ); + Bitmap bm = Bitmap.createBitmap( 100, 1, Bitmap.Config.ARGB_8888 ); + Canvas canvas = new Canvas(bm); - Paint paint = new Paint(); - paint.setStyle(Paint.Style.FILL); - paint.setColor( Color.RED ); - canvas.drawRect( 0, 0, m_pct, 1, paint ); - paint.setColor( Utils.TURN_COLOR ); - canvas.drawRect( m_pct, 0, 100, 1, paint ); - m_back = new BitmapDrawable( m_context.getResources(), bm ); - } + Paint paint = new Paint(); + paint.setStyle(Paint.Style.FILL); + paint.setColor( Color.RED ); + canvas.drawRect( 0, 0, pct, 1, paint ); + paint.setColor( Utils.TURN_COLOR ); + canvas.drawRect( pct, 0, 100, 1, paint ); + return new BitmapDrawable( m_context.getResources(), bm ); } private void figurePct() @@ -173,8 +182,29 @@ public class ExpiringDelegate { long lastStart = m_startSecs + (onePct * m_pct); Assert.assertTrue( lastStart <= 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; + } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringLinearLayout.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringLinearLayout.java index cff216d52..c3164eead 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringLinearLayout.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringLinearLayout.java @@ -21,6 +21,7 @@ package org.eehouse.android.xw4; import android.content.Context; import android.graphics.Canvas; +import android.os.Handler; import android.util.AttributeSet; import android.widget.LinearLayout; @@ -33,10 +34,13 @@ public class ExpiringLinearLayout extends LinearLayout { 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, - haveTurnLocal, startSecs ); + if ( null == m_delegate ) { + m_delegate = new ExpiringDelegate( m_context, this, handler ); + } + m_delegate.configure( haveTurn, haveTurnLocal, startSecs ); } @Override diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringTextView.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringTextView.java index 35ae60cd7..e32bdccfd 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringTextView.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ExpiringTextView.java @@ -21,6 +21,7 @@ package org.eehouse.android.xw4; import android.content.Context; import android.graphics.Canvas; +import android.os.Handler; import android.util.AttributeSet; import android.widget.TextView; @@ -34,10 +35,13 @@ class ExpiringTextView extends TextView { 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, - haveTurnLocal, startSecs ); + if ( null == m_delegate ) { + m_delegate = new ExpiringDelegate( m_context, this, handler ); + } + m_delegate.configure( haveTurn, haveTurnLocal, startSecs ); } @Override diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java index 88b035d5b..c234cb09a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java @@ -19,23 +19,24 @@ */ package org.eehouse.android.xw4; -import android.widget.ListAdapter; import android.content.Context; +import android.database.DataSetObserver; import android.os.AsyncTask; import android.os.Build; +import android.os.Handler; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.TextView; -import android.database.DataSetObserver; -import android.view.LayoutInflater; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ListAdapter; +import android.widget.TextView; import java.io.FileInputStream; +import java.text.DateFormat; import java.util.Date; import java.util.HashMap; // class is not synchronized import java.util.Random; -import java.text.DateFormat; import junit.framework.Assert; @@ -48,6 +49,7 @@ public class GameListAdapter extends XWListAdapter { private Context m_context; private LayoutInflater m_factory; private int m_fieldID; + private Handler m_handler; private static final boolean s_isFire; private static Random s_random; static { @@ -96,8 +98,8 @@ public class GameListAdapter extends XWListAdapter { m_hideable.setVisibility( m_expanded? View.VISIBLE : View.GONE ); m_name.setBackgroundColor( android.R.color.transparent ); - m_name.setPct( m_haveTurn && !m_expanded, m_haveTurnLocal, - m_lastMoveTime ); + m_name.setPct( m_handler, m_haveTurn && !m_expanded, + m_haveTurnLocal, m_lastMoveTime ); } public void onClick( View view ) { @@ -191,8 +193,8 @@ public class GameListAdapter extends XWListAdapter { LinearLayout list = (LinearLayout)layout.findViewById( R.id.player_list ); - boolean haveTurn = false; - boolean haveTurnLocal = false; + boolean haveATurn = false; + boolean haveALocalTurn = false; boolean[] isLocal = new boolean[1]; for ( int ii = 0; ii < summary.nPlayers; ++ii ) { ExpiringLinearLayout tmp = (ExpiringLinearLayout) @@ -201,13 +203,15 @@ public class GameListAdapter extends XWListAdapter { view.setText( summary.summarizePlayer( ii ) ); view = (TextView)tmp.findViewById( R.id.item_score ); view.setText( String.format( " %d", summary.scores[ii] ) ); - if ( summary.isNextToPlay( ii, isLocal ) ) { - haveTurn = true; + boolean thisHasTurn = summary.isNextToPlay( ii, isLocal ); + if ( thisHasTurn ) { + haveATurn = true; 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 ); } @@ -243,8 +247,8 @@ public class GameListAdapter extends XWListAdapter { boolean expanded = DBUtils.getExpanded( m_context, m_rowid ); ViewInfo vi = new ViewInfo( layout, m_rowid, expanded, - summary.lastMoveTime, haveTurn, - haveTurnLocal ); + summary.lastMoveTime, haveATurn, + haveALocalTurn ); synchronized( m_viewsCache ) { m_viewsCache.put( m_rowid, vi ); @@ -263,9 +267,10 @@ public class GameListAdapter extends XWListAdapter { } } // class LoadItemTask - public GameListAdapter( Context context, LoadItemCB cb ) { + public GameListAdapter( Context context, Handler handler, LoadItemCB cb ) { super( DBUtils.gamesList(context).length ); m_context = context; + m_handler = handler; m_cb = cb; m_factory = LayoutInflater.from( context ); m_df = DateFormat.getDateTimeInstance( DateFormat.SHORT, diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java index 93eca3af1..7fd3c9fbe 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java @@ -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 ); NetUtils.informOfDeaths( this );