diff --git a/xwords4/android/XWords4/res/layout/game_list_item.xml b/xwords4/android/XWords4/res/layout/game_list_item.xml index fafdd705a..a396420af 100644 --- a/xwords4/android/XWords4/res/layout/game_list_item.xml +++ b/xwords4/android/XWords4/res/layout/game_list_item.xml @@ -38,6 +38,15 @@ android:paddingRight="8dip" /> + + key_notify_vibrate key_enable_sms key_keep_screenon + key_thumbsize key_summary_field key_default_loc @@ -135,6 +136,12 @@ Write DB to SD card Load DB from SD card + Off + 1/3 + 1/4 + 1/5 + 1/6 + @@ -281,4 +288,12 @@ @string/confirm_sms_willpay + + @string/game_thumb_off + @string/game_thumb_third + @string/game_thumb_quarter + @string/game_thumb_fifth + @string/game_thumb_sixth + + diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml index 637b53a03..6ce4485d7 100644 --- a/xwords4/android/XWords4/res/values/strings.xml +++ b/xwords4/android/XWords4/res/values/strings.xml @@ -2173,4 +2173,6 @@ Games: %d" Groups: %d" + + Thumbnail size diff --git a/xwords4/android/XWords4/res/xml/xwprefs.xml b/xwords4/android/XWords4/res/xml/xwprefs.xml index fb690b6e7..180625e89 100644 --- a/xwords4/android/XWords4/res/xml/xwprefs.xml +++ b/xwords4/android/XWords4/res/xml/xwprefs.xml @@ -138,6 +138,14 @@ android:defaultValue="false" /> + + diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java index 49cc98d6f..696578928 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java @@ -21,34 +21,39 @@ package org.eehouse.android.xw4; import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; + +import android.content.DialogInterface.OnDismissListener; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; + +import android.graphics.Bitmap; + import android.os.Bundle; -import android.text.TextUtils; -import android.view.View; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MenuInflater; -import android.view.KeyEvent; -import android.view.Window; import android.os.Handler; import android.os.Message; -import android.content.Intent; -import java.util.concurrent.Semaphore; -import java.util.ArrayList; -import java.util.Iterator; -import android.app.Dialog; -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.DialogInterface; -import android.content.DialogInterface.OnDismissListener; + +import android.text.TextUtils; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; import android.widget.Button; +import android.widget.EditText; import android.widget.ImageButton; import android.widget.LinearLayout; -import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.concurrent.Semaphore; import junit.framework.Assert; -import android.content.res.Configuration; -import android.content.pm.ActivityInfo; import org.eehouse.android.xw4.jni.*; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; @@ -2028,7 +2033,8 @@ public class BoardActivity extends XWActivity interruptBlockingThread(); if ( null != m_jniThread ) { - m_jniThread.waitToStop( save ); + Bitmap thumb = m_view.getScaledBoard(); + m_jniThread.waitToStop( save, thumb ); m_jniThread = null; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java index 6bda3c9db..ee0af9289 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java @@ -937,6 +937,19 @@ public class BoardView extends View implements DrawCtx, BoardHandler, } } + public Bitmap getScaledBoard() + { + Bitmap result = null; + int divisor = XWPrefs.getThumbScale( m_context ); + if ( 0 < divisor ) { + result = Bitmap.createScaledBitmap( s_bitmap, + m_layoutWidth / divisor, + m_layoutHeight / divisor, + false ); + } + return result; + } + private void drawTileImpl( Rect rect, String text, int val, int flags, boolean clearBack ) { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java index 62befe4f7..b5864b644 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java @@ -25,15 +25,21 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.graphics.Bitmap.CompressFormat; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Environment; import android.text.TextUtils; + +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.FileChannel; + import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -41,7 +47,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.StringTokenizer; - import junit.framework.Assert; import org.eehouse.android.xw4.jni.*; @@ -132,7 +137,7 @@ public class DBUtils { DBHelper.DICTLANG, DBHelper.GAMEID, DBHelper.SCORES, DBHelper.HASMSGS, DBHelper.LASTPLAY_TIME, DBHelper.REMOTEDEVS, - DBHelper.LASTMOVE + DBHelper.LASTMOVE, DBHelper.THUMBNAIL }; String selection = String.format( ROW_ID_FMT, lock.getRowid() ); @@ -179,6 +184,14 @@ public class DBUtils { summary.lastMoveTime = cursor.getInt(cursor.getColumnIndex(DBHelper.LASTMOVE)); + byte[] data = + cursor.getBlob( cursor.getColumnIndex(DBHelper.THUMBNAIL)); + if ( null != data ) { + Bitmap thumb = BitmapFactory.decodeByteArray( data, 0, + data.length ); + summary.setThumbnail( thumb ); + } + String scoresStr = cursor.getString( cursor.getColumnIndex(DBHelper.SCORES)); int[] scores = new int[summary.nPlayers]; @@ -308,6 +321,17 @@ public class DBUtils { break; } } + + Bitmap thumb = summary.getThumbnail(); + if ( null == thumb ) { + values.putNull( DBHelper.THUMBNAIL ); + } else { + ByteArrayOutputStream bas = new ByteArrayOutputStream(); + thumb.compress( CompressFormat.PNG, 0 , bas ); + byte[] data = bas.toByteArray(); + values.put( DBHelper.THUMBNAIL, data ); + } + values.put( DBHelper.SERVERROLE, summary.serverRole.ordinal() ); long result = db.update( DBHelper.TABLE_NAME_SUM, diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListItem.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListItem.java index bc65afdb2..3eaa434c2 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListItem.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListItem.java @@ -21,6 +21,7 @@ package org.eehouse.android.xw4; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.drawable.Drawable; @@ -51,6 +52,7 @@ public class GameListItem extends LinearLayout private boolean m_loaded; private long m_rowid; private View m_hideable; + private ImageView m_thumb; private ExpiringTextView m_name; private boolean m_expanded, m_haveTurn, m_haveTurnLocal; private long m_lastMoveTime; @@ -185,6 +187,7 @@ public class GameListItem extends LinearLayout R.drawable.expander_ic_maximized : R.drawable.expander_ic_minimized); m_hideable.setVisibility( m_expanded? View.VISIBLE : View.GONE ); + m_thumb.setVisibility( m_expanded? View.VISIBLE : View.GONE ); m_name.setBackgroundColor( android.R.color.transparent ); m_name.setPct( m_handler, m_haveTurn && !m_expanded, @@ -292,6 +295,14 @@ public class GameListItem extends LinearLayout } } ); + m_thumb = (ImageView)findViewById( R.id.thumbnail ); + Bitmap bmp = summary.getThumbnail(); + if ( null == bmp ) { + m_thumb.setVisibility( View.GONE ); + } else { + m_thumb.setImageBitmap( bmp ); + } + tview = (TextView)findViewById( R.id.role ); String roleSummary = summary.summarizeRole(); if ( null != roleSummary ) { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWPrefs.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWPrefs.java index 1cfecaaea..ac2e48a51 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWPrefs.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWPrefs.java @@ -328,6 +328,24 @@ public class XWPrefs { return posns; } + public static int getThumbScale( Context context ) + { + String scale = getPrefsString( context, R.string.key_thumbsize ); + int result = -1; + if ( context.getString(R.string.game_thumb_off).equals(scale) ) { + result = 0; + } else if ( context.getString(R.string.game_thumb_third).equals(scale) ) { + result = 3; + } else if ( context.getString(R.string.game_thumb_quarter).equals(scale) ) { + result = 4; + } else if ( context.getString(R.string.game_thumb_fifth).equals(scale) ) { + result = 5; + } else if ( context.getString(R.string.game_thumb_sixth).equals(scale) ) { + result = 6; + } + return result; + } + protected static String getPrefsString( Context context, int keyID ) { String key = context.getString( keyID ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java index 2f594e2cf..d179ef1ad 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java @@ -21,11 +21,14 @@ package org.eehouse.android.xw4.jni; import android.content.Context; +import android.graphics.Bitmap; import android.text.TextUtils; + import junit.framework.Assert; + +import org.eehouse.android.xw4.DbgUtils; import org.eehouse.android.xw4.R; import org.eehouse.android.xw4.Utils; -import org.eehouse.android.xw4.DbgUtils; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole; @@ -66,6 +69,7 @@ public class GameSummary { private CurGameInfo m_gi; private Context m_context; private String[] m_remotePhones; + private Bitmap m_thumb; private GameSummary() {} @@ -85,6 +89,16 @@ public class GameSummary { m_gi = gi; } + public void setThumbnail( Bitmap thumb ) + { + m_thumb = thumb; + } + + public Bitmap getThumbnail() + { + return m_thumb; + } + public boolean inNetworkGame() { return null != relayID; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java index d23443534..b9b57470a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIThread.java @@ -22,6 +22,7 @@ package org.eehouse.android.xw4.jni; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Paint; import android.graphics.Rect; import android.os.Handler; @@ -132,6 +133,7 @@ public class JNIThread extends Thread { private static final int kMinDivWidth = 10; private int m_connsIconID = 0; private String m_newDict = null; + private Bitmap m_thumbnail; LinkedBlockingQueue m_queue; @@ -160,11 +162,12 @@ public class JNIThread extends Thread { m_queue = new LinkedBlockingQueue(); } - public void waitToStop( boolean save ) + public void waitToStop( boolean save, Bitmap thumb ) { synchronized ( this ) { m_stopped = true; m_saveOnStop = save; + m_thumbnail = thumb; } handle( JNICmd.CMD_NONE ); // tickle it try { @@ -298,6 +301,7 @@ public class JNIThread extends Thread { // DbgUtils.logf( "no change in game; can skip saving" ); } else { GameSummary summary = new GameSummary( m_context, m_gi ); + summary.setThumbnail( m_thumbnail ); XwJNI.game_summarize( m_jniGamePtr, summary ); DBUtils.saveGame( m_context, m_lock, state, false ); DBUtils.saveSummary( m_context, m_lock, summary );