Add custom GameOver alert for GameOver with Archive checkbox

I didn't like having to re-open a game to archive it after
rematching, so now there's a checkbox that lets you archive it after
either rematching OR just using OK to dismiss the alert. Also fixed
rematch of a solo game causing new game to be created in Archive
group if that's where the source game was.

squash me
This commit is contained in:
Eric House 2019-02-10 08:53:39 -08:00
parent 0ad9b0f891
commit babca4a696
8 changed files with 277 additions and 62 deletions

View file

@ -190,37 +190,6 @@ public class BoardDelegate extends DelegateBase
}
break;
case GAME_OVER: {
GameSummary summary = (GameSummary)params[0];
int title = (Integer)params[1];
String msg = (String)params[2];
ab.setTitle( title )
.setMessage( msg )
.setPositiveButton( android.R.string.ok, null );
if ( rematchSupported( m_activity, true, summary ) ) {
lstnr = new OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
doRematchIf();
}
};
ab.setNegativeButton( R.string.button_rematch, lstnr );
// If we're not already in the "archive" group, offer to move
if ( !inArchiveGroup() ) {
lstnr = new OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
showArchiveNA();
}
};
ab.setNeutralButton( R.string.button_archive, lstnr );
}
}
dialog = ab.create();
}
break;
case DLG_USEDICT:
case DLG_GETDICT: {
int title = (Integer)params[0];
@ -897,7 +866,7 @@ public class BoardDelegate extends DelegateBase
break;
case R.id.board_menu_archive:
showArchiveNA();
showArchiveNA( false );
break;
case R.id.board_menu_trade_commit:
@ -1013,6 +982,7 @@ public class BoardDelegate extends DelegateBase
@Override
public boolean onPosButton( Action action, final Object[] params )
{
// Log.d( TAG, "onPosButton(%s, %s)", action, DbgUtils.toStr( params ) );
boolean handled = true;
JNICmd cmd = JNICmd.CMD_NONE;
switch ( action ) {
@ -1122,7 +1092,24 @@ public class BoardDelegate extends DelegateBase
break;
case ARCHIVE_ACTION:
archiveAndClose();
boolean rematchAfter = params.length >= 1 && (Boolean)params[0];
long curGroup = DBUtils.getGroupForGame( m_activity, m_rowid );
archiveGame( !rematchAfter );
if ( rematchAfter ) {
doRematchIf( curGroup ); // closes game
}
break;
case REMATCH_ACTION:
if ( params.length >= 1 && (Boolean)params[0] ) {
showArchiveNA( true );
} else {
doRematchIf(); // closes game
}
break;
case ARCHIVE_SEL_ACTION:
showArchiveNA( false );
break;
case ENABLE_SMS_DO:
@ -2106,7 +2093,7 @@ public class BoardDelegate extends DelegateBase
private Handler makeJNIHandler()
{
Handler handler = new Handler() {
public void handleMessage( Message msg ) {
public void handleMessage( final Message msg ) {
switch( msg.what ) {
case JNIThread.DIALOG:
showDialogFragment( DlgID.DLG_OKONLY, msg.arg1,
@ -2135,8 +2122,16 @@ public class BoardDelegate extends DelegateBase
break;
case JNIThread.GAME_OVER:
if ( m_isFirstLaunch ) {
showDialogFragment( DlgID.GAME_OVER, m_summary, msg.arg1,
(String)msg.obj );
runOnUiThread( new Runnable() {
@Override
public void run() {
show( GameOverAlert
.newInstance( m_summary,
msg.arg1,
(String)msg.obj,
inArchiveGroup() ) );
}
} );
}
break;
case JNIThread.MSGS_SENT:
@ -2648,15 +2643,16 @@ public class BoardDelegate extends DelegateBase
return curGroup == archiveGroup;
}
private void showArchiveNA()
private void showArchiveNA( boolean rematchAfter )
{
makeNotAgainBuilder( R.string.not_again_archive,
R.string.key_na_archive,
Action.ARCHIVE_ACTION )
.setParams( rematchAfter )
.show();
}
private void archiveAndClose()
private void archiveGame( boolean closeAfter )
{
String archiveName = LocUtils
.getString( m_activity, R.string.group_name_archive );
@ -2666,8 +2662,10 @@ public class BoardDelegate extends DelegateBase
archiveGroupID = DBUtils.addGroup( m_activity, archiveName );
}
DBUtils.moveGame( m_activity, m_rowid, archiveGroupID );
waitCloseGame( false );
finish();
if ( closeAfter ) {
waitCloseGame( false );
finish();
}
}
// For now, supported if standalone or either BT or SMS used for transport
@ -2719,12 +2717,19 @@ public class BoardDelegate extends DelegateBase
private void doRematchIf()
{
doRematchIf( m_activity, this, m_rowid, m_summary, m_gi, m_jniGamePtr );
doRematchIf( DBUtils.GROUPID_UNSPEC );
}
private void doRematchIf( long groupID )
{
doRematchIf( m_activity, this, m_rowid, groupID, m_summary,
m_gi, m_jniGamePtr );
}
private static void doRematchIf( Activity activity, DelegateBase dlgt,
long rowid, GameSummary summary,
CurGameInfo gi, GamePtr jniGamePtr )
long rowid, long groupID,
GameSummary summary, CurGameInfo gi,
GamePtr jniGamePtr )
{
boolean doIt = true;
String phone = null;
@ -2768,8 +2773,8 @@ public class BoardDelegate extends DelegateBase
CommsConnTypeSet connTypes = summary.conTypes;
String newName = summary.getRematchName( activity );
Intent intent = GamesListDelegate
.makeRematchIntent( activity, rowid, gi, connTypes, btAddr,
phone, relayID, p2pMacAddress, newName );
.makeRematchIntent( activity, rowid, groupID, gi, connTypes,
btAddr, phone, relayID, p2pMacAddress, newName );
if ( null != intent ) {
activity.startActivity( intent );
}
@ -2800,7 +2805,8 @@ public class BoardDelegate extends DelegateBase
}
if ( null != gamePtr ) {
doRematchIf( activity, null, rowID, summary, gi, gamePtr );
doRematchIf( activity, null, rowID, DBUtils.GROUPID_UNSPEC,
summary, gi, gamePtr );
gamePtr.release();
} else {
Log.w( TAG, "setupRematchFor(): unable to lock game" );

View file

@ -30,12 +30,11 @@ import android.text.format.Time;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import java.util.Set;
import org.eehouse.android.xw4.loc.LocUtils;
public class DbgUtils {
private static final String TAG = DbgUtils.class.getSimpleName();
@ -117,6 +116,17 @@ public class DbgUtils {
Log.i( TAG, "cursor: %s", dump );
}
public static String toStr( Object[] params )
{
List<String> strs = new ArrayList<>();
if ( null != params ) {
for ( Object obj : params ) {
strs.add( obj.toString() );
}
}
return TextUtils.join( ", ", strs );
}
// public static String secondsToDateStr( long seconds )
// {
// return millisToDateStr( seconds * 1000 );

View file

@ -83,7 +83,9 @@ public class DlgDelegate {
TRAY_PICKED,
INVITE_INFO,
DISABLE_DUALPANE,
ARCHIVE_SEL_ACTION, // archive was clicked
ARCHIVE_ACTION,
REMATCH_ACTION,
// Dict Browser
FINISH_ACTION,

View file

@ -36,7 +36,6 @@ public enum DlgID {
, DLG_OKONLY
, ENABLE_NFC
, FORCE_REMOTE
, GAME_OVER
, GET_NAME
, GET_NUMBER
, INVITE_CHOICES_THEN

View file

@ -0,0 +1,160 @@
/* -*- compile-command: "find-and-gradle.sh insXw4Deb"; -*- */
/*
* Copyright 2010 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.eehouse.android.xw4.DlgDelegate.Action;
import org.eehouse.android.xw4.jni.GameSummary;
import org.eehouse.android.xw4.loc.LocUtils;
public class GameOverAlert extends XWDialogFragment
implements DialogInterface.OnClickListener
{
private static final String TAG = GameOverAlert.class.getSimpleName();
private static final String SUMMARY = "SUMMARY";
private static final String TITLE = "TITLE";
private static final String MSG = "MSG";
private static final String IN_ARCH = "IN_ARCH";
private AlertDialog m_dialog;
private GameSummary mSummary;
private int mTitleID;
private String mMsg;
private LinearLayout m_view;
private boolean mInArchive;
private CheckBox mArchiveBox;
// private boolean mArchiveChecked;
public static GameOverAlert newInstance( GameSummary summary,
int titleID, String msg,
boolean inArchiveGroup )
{
Log.d( TAG, "newInstance(msg=%s)", msg );
GameOverAlert result = new GameOverAlert();
Bundle args = new Bundle();
args.putSerializable( SUMMARY, summary );
args.putInt( TITLE, titleID );
args.putString( MSG, msg );
args.putBoolean( IN_ARCH, inArchiveGroup );
result.setArguments( args );
Log.d( TAG, "newInstance() => %s", result );
return result;
}
public GameOverAlert() {}
@Override
public void onSaveInstanceState( Bundle bundle )
{
bundle.putSerializable( SUMMARY, mSummary );
bundle.putInt( TITLE, mTitleID );
bundle.putString( MSG, mMsg );
bundle.putBoolean( IN_ARCH, mInArchive );
super.onSaveInstanceState( bundle );
}
@Override
public Dialog onCreateDialog( Bundle sis )
{
Log.d( TAG, "onCreateDialog()" );
if ( null == sis ) {
sis = getArguments();
}
mSummary = (GameSummary)sis.getSerializable( SUMMARY );
mTitleID = sis.getInt( TITLE );
mMsg = sis.getString( MSG );
mInArchive = sis.getBoolean( IN_ARCH );
Activity activity = getActivity();
m_view = (LinearLayout)LocUtils.inflate( activity, R.layout.game_over );
initView();
AlertDialog.Builder ab = LocUtils.makeAlertBuilder( activity )
.setTitle( mTitleID )
.setView( m_view )
.setPositiveButton( android.R.string.ok, this )
.setNeutralButton( R.string.button_rematch, this )
;
m_dialog = ab.create();
Log.d( TAG, "onCreateDialog() => %s", m_dialog );
return m_dialog;
}
@Override
protected String getFragTag() { return TAG; }
// @Override
// public void onCheckedChanged( CompoundButton buttonView, boolean isChecked )
// {
// Log.d( TAG, "onCheckedChanged(%b)", isChecked );
// mArchiveChecked = isChecked;
// }
@Override
public void onClick( DialogInterface dialog, int which )
{
Action action = null;
boolean archiveAfter =
((CheckBox)m_view.findViewById(R.id.archive_check))
.isChecked();
if ( which == AlertDialog.BUTTON_NEUTRAL ) {
action = Action.REMATCH_ACTION;
} else if ( which == AlertDialog.BUTTON_POSITIVE && archiveAfter ) {
action = Action.ARCHIVE_SEL_ACTION;
}
if ( null != action ) {
Activity activity = getActivity();
if ( activity instanceof DlgDelegate.DlgClickNotify ) {
DlgDelegate.DlgClickNotify notify
= (DlgDelegate.DlgClickNotify)activity;
notify.onPosButton( action, archiveAfter );
}
}
}
// private void trySend( Action action, boolean bool )
// {
// Log.d( TAG, "trySend(%s)", action );
// }
private void initView()
{
((TextView)m_view.findViewById( R.id.msg )).setText( mMsg );
mArchiveBox = (CheckBox)m_view.findViewById( R.id.archive_check );
if ( mInArchive ) {
mArchiveBox.setVisibility( View.GONE );
}
}
}

View file

@ -119,7 +119,8 @@ public class GameUtils {
* basis for a new one.
*/
public static GameLock resetGame( Context context, GameLock lockSrc,
GameLock lockDest, boolean juggle )
GameLock lockDest, long groupID,
boolean juggle )
{
CurGameInfo gi = new CurGameInfo( context );
CommsAddrRec addr = null;
@ -148,7 +149,9 @@ public class GameUtils {
}
if ( null == lockDest ) {
long groupID = DBUtils.getGroupForGame( context, lockSrc.getRowid() );
if ( DBUtils.GROUPID_UNSPEC == groupID ) {
groupID = DBUtils.getGroupForGame( context, lockSrc.getRowid() );
}
long rowid = saveNewGame( context, gamePtr, gi, groupID );
lockDest = GameLock.tryLock( rowid );
} else {
@ -166,7 +169,7 @@ public class GameUtils {
try ( GameLock lock = GameLock.lock( rowidIn, 500 ) ) {
if ( null != lock ) {
tellDied( context, lock, true );
resetGame( context, lock, lock, false );
resetGame( context, lock, lock, DBUtils.GROUPID_UNSPEC, false );
Utils.cancelNotification( context, (int)rowidIn );
success = true;
@ -251,6 +254,11 @@ public class GameUtils {
}
public static long dupeGame( Context context, long rowidIn )
{
return dupeGame( context, rowidIn, DBUtils.GROUPID_UNSPEC );
}
public static long dupeGame( Context context, long rowidIn, long groupID )
{
long rowid = DBUtils.ROWID_NOTFOUND;
GameLock lockSrc = null;
@ -264,7 +272,8 @@ public class GameUtils {
if ( null != lockSrc ) {
boolean juggle = CommonPrefs.getAutoJuggle( context );
GameLock lockDest = resetGame( context, lockSrc, null, juggle );
GameLock lockDest = resetGame( context, lockSrc, null, groupID,
juggle );
rowid = lockDest.getRowid();
lockDest.unlock();

View file

@ -87,6 +87,7 @@ public class GamesListDelegate extends ListDelegateBase
private static final String ROWID_EXTRA = "rowid";
private static final String GAMEID_EXTRA = "gameid";
private static final String REMATCH_ROWID_EXTRA = "rm_rowid";
private static final String REMATCH_GROUPID_EXTRA = "rm_groupid";
private static final String REMATCH_DICT_EXTRA = "rm_dict";
private static final String REMATCH_LANG_EXTRA = "rm_lang";
private static final String REMATCH_PREFS_EXTRA = "rm_prefs";
@ -2235,12 +2236,22 @@ public class GamesListDelegate extends ListDelegateBase
{
if ( null != gameName && 0 < gameName.length() ) {
Bundle extras = m_rematchExtras;
long srcRowID = extras.getLong( REMATCH_ROWID_EXTRA, DBUtils.ROWID_NOTFOUND );
long srcRowID = extras.getLong( REMATCH_ROWID_EXTRA,
DBUtils.ROWID_NOTFOUND );
long groupID = extras.getLong( REMATCH_GROUPID_EXTRA,
DBUtils.GROUPID_UNSPEC );
if ( DBUtils.GROUPID_UNSPEC == groupID ) {
groupID = DBUtils.getGroupForGame( m_activity, srcRowID );
}
// Don't save rematch in Archive group
if ( groupID == DBUtils.getArchiveGroup( m_activity ) ) {
groupID = XWPrefs.getDefaultNewGameGroup( m_activity );
}
boolean solo = extras.getBoolean( REMATCH_IS_SOLO, true );
long newid;
if ( solo ) {
newid = GameUtils.dupeGame( m_activity, srcRowID );
newid = GameUtils.dupeGame( m_activity, srcRowID, groupID );
if ( DBUtils.ROWID_NOTFOUND != newid ) {
DBUtils.setName( m_activity, newid, gameName );
}
@ -2253,12 +2264,6 @@ public class GamesListDelegate extends ListDelegateBase
int lang = extras.getInt( REMATCH_LANG_EXTRA, -1 );
String json = extras.getString( REMATCH_PREFS_EXTRA );
// Don't save rematch in Archive group
long groupID = DBUtils.getGroupForGame( m_activity, srcRowID );
if ( groupID == DBUtils.getArchiveGroup( m_activity ) ) {
groupID = XWPrefs.getDefaultNewGameGroup( m_activity );
}
newid = GameUtils.makeNewMultiGame( m_activity, groupID, dict,
lang, json, addrs, gameName );
DBUtils.addRematchInfo( m_activity, newid, btAddr, phone,
@ -2709,7 +2714,7 @@ public class GamesListDelegate extends ListDelegateBase
}
public static Intent makeRematchIntent( Context context, long rowid,
CurGameInfo gi,
long groupID, CurGameInfo gi,
CommsConnTypeSet addrTypes,
String btAddr, String phone,
String relayID, String p2pMacAddress,
@ -2719,6 +2724,7 @@ public class GamesListDelegate extends ListDelegateBase
boolean isSolo = gi.serverRole == CurGameInfo.DeviceRole.SERVER_STANDALONE;
intent = makeSelfIntent( context )
.putExtra( REMATCH_ROWID_EXTRA, rowid )
.putExtra( REMATCH_GROUPID_EXTRA, groupID )
.putExtra( REMATCH_DICT_EXTRA, gi.dictName )
.putExtra( REMATCH_IS_SOLO, isSolo )
.putExtra( REMATCH_LANG_EXTRA, gi.dictLang )

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
<TextView android:id="@+id/msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<!-- spacer -->
<View android:layout_height="15dp"
android:layout_width="match_parent"
/>
<CheckBox android:id="@+id/archive_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_archive"
/>
</LinearLayout>