improve new-games dialog

Add radio buttons to make clear what the choices are. This should
eventually replace the alert that's show when you don't have any Known
Players.
This commit is contained in:
Eric House 2021-01-02 17:02:08 -08:00
parent 07c4deb185
commit 72f2db4f57
5 changed files with 219 additions and 76 deletions

View file

@ -82,11 +82,9 @@ public class GamesListDelegate extends ListDelegateBase
GroupStateListener, Log.ResultProcs { GroupStateListener, Log.ResultProcs {
private static final String TAG = GamesListDelegate.class.getSimpleName(); private static final String TAG = GamesListDelegate.class.getSimpleName();
private static final String SAVE_NEXTSOLO = "SAVE_NEXTSOLO"; private static final String SAVE_NEXTSOLO = "SAVE_NEXTSOLO";
private static final String SAVE_REMATCHEXTRAS = "SAVE_REMATCHEXTRAS"; private static final String SAVE_REMATCHEXTRAS = "SAVE_REMATCHEXTRAS";
private static final String SAVE_MYSIS = TAG + "/MYSIS"; private static final String SAVE_MYSIS = TAG + "/MYSIS";
private static final String KP_NAME_KEY = TAG + "/kp_last_name";
private static final String RELAYIDS_EXTRA = "relayids"; private static final String RELAYIDS_EXTRA = "relayids";
private static final String ROWID_EXTRA = "rowid"; private static final String ROWID_EXTRA = "rowid";
@ -966,44 +964,46 @@ public class GamesListDelegate extends ListDelegateBase
private Dialog mkNewWithKnowns() private Dialog mkNewWithKnowns()
{ {
String[] names = XwJNI.kplr_getPlayers(); String[] names = XwJNI.kplr_getPlayers();
final String[] nameRef
= { DBUtils.getStringFor( m_activity, KP_NAME_KEY, null ) };
final NewWithKnowns view = (NewWithKnowns) final NewWithKnowns view = (NewWithKnowns)
LocUtils.inflate( m_activity, R.layout.new_game_with_knowns ); LocUtils.inflate( m_activity, R.layout.new_game_with_knowns );
view.setNames( names, nameRef[0], GameUtils.makeDefaultName( m_activity ) ); view.setNames( names, GameUtils.makeDefaultName( m_activity ) );
AlertDialog.Builder ab = makeAlertBuilder() AlertDialog.Builder ab = makeAlertBuilder()
.setView( view ) .setView( view )
.setTitle( R.string.new_game_networked ) .setTitle( R.string.new_game_networked )
.setIcon( R.drawable.ic_multigame ) .setIcon( R.drawable.ic_multigame )
.setPositiveButton( "" /* can't be empty*/, new OnClickListener() { .setPositiveButton( android.R.string.cancel, new OnClickListener() {
@Override @Override
public void onClick( DialogInterface dlg, int item ) { public void onClick( DialogInterface dlg, int item ) {
Assert.assertTrueNR( null != nameRef[0] ); view.onButtonPressed(new NewWithKnowns.ButtonCallbacks() {
DBUtils.setStringFor( m_activity, KP_NAME_KEY, nameRef[0] ); @Override
CommsAddrRec addr = XwJNI.kplr_getAddr( nameRef[0] ); public void onUseKnown( String knownName, String gameName )
if ( null != addr ) { {
launchLikeRematch( addr, view.gameName() ); CommsAddrRec addr = XwJNI.kplr_getAddr( knownName );
} if ( null != addr ) {
launchLikeRematch( addr, gameName );
}
}
@Override
public void onInviteLater( String gameName )
{
curThis().makeThenLaunchOrConfigure( gameName, false, false );
}
@Override
public void onConfigureFirst( String gameName )
{
curThis().makeThenLaunchOrConfigure( gameName, true, false );
}
} );
} }
} ) } );
.setNegativeButton( R.string.newgame_configure_first, new OnClickListener() {
@Override
public void onClick( DialogInterface dlg, int item ) {
String name = view.gameName();
curThis().makeThenLaunchOrConfigure( name, true, false );
}
} )
;
final AlertDialog dialog = ab.create(); final AlertDialog dialog = ab.create();
view.setOnNameChangeListener( new NewWithKnowns.OnNameChangeListener() { view.setCallback( new NewWithKnowns.ButtonChangeListener() {
@Override @Override
public void onNewName( String name ) { public void onNewButtonText( String txt ) {
nameRef[0] = name;
Button button = dialog.getButton( DialogInterface.BUTTON_POSITIVE ); Button button = dialog.getButton( DialogInterface.BUTTON_POSITIVE );
if ( null != button ) { if ( null != button ) {
String msg = getString( R.string.invite_player_fmt, name ); button.setText( txt );
button.setText( msg );
} else { } else {
Log.e( TAG, "Button still null" ); Log.e( TAG, "Button still null" );
} }

View file

@ -26,57 +26,95 @@ import android.view.View;
import android.widget.AdapterView.OnItemSelectedListener; import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
public class NewWithKnowns extends LinearLayout implements OnItemSelectedListener import org.eehouse.android.xw4.loc.LocUtils;
public class NewWithKnowns extends LinearLayout
implements OnItemSelectedListener, RadioGroup.OnCheckedChangeListener
{ {
public interface OnNameChangeListener { private static final String TAG = NewWithKnowns.class.getSimpleName();
void onNewName( String name ); private static final String KP_NAME_KEY = TAG + "/kp_last_name";
public interface ButtonChangeListener {
void onNewButtonText( String txt );
} }
private OnNameChangeListener mListener; public interface ButtonCallbacks {
void onUseKnown( String knownName, String gameName );
void onInviteLater( String gameName );
void onConfigureFirst( String gameName );
}
private ButtonChangeListener mListener;
private String mCurKnown;
private int mCurRadio;
private Spinner mNamesSpinner;
public NewWithKnowns( Context cx, AttributeSet as ) public NewWithKnowns( Context cx, AttributeSet as )
{ {
super( cx, as ); super( cx, as );
} }
void setOnNameChangeListener( OnNameChangeListener listener ) void setCallback( ButtonChangeListener listener )
{ {
Assert.assertTrueNR( null == mListener ); Assert.assertTrueNR( null == mListener );
mListener = listener; mListener = listener;
} }
void setNames( String[] knowns, String dflt, String gameName ) void setNames( String[] knowns, String gameName )
{ {
mCurKnown = DBUtils.getStringFor( getContext(), KP_NAME_KEY,
knowns[0] );
ArrayAdapter<String> adapter = new ArrayAdapter<String> adapter = new
ArrayAdapter<String>( getContext(), ArrayAdapter<String>( getContext(),
android.R.layout.simple_spinner_item, android.R.layout.simple_spinner_item,
knowns ); knowns );
adapter.setDropDownViewResource( android.R.layout adapter.setDropDownViewResource( android.R.layout
.simple_spinner_dropdown_item ); .simple_spinner_dropdown_item );
Spinner spinner = (Spinner)findViewById( R.id.names ); mNamesSpinner = (Spinner)findViewById( R.id.names );
spinner.setAdapter( adapter ); mNamesSpinner.setAdapter( adapter );
spinner.setOnItemSelectedListener( this ); mNamesSpinner.setOnItemSelectedListener( this );
if ( !TextUtils.isEmpty( dflt ) ) { Assert.assertTrueNR( !TextUtils.isEmpty( mCurKnown ) );
for ( int ii = 0; ii < knowns.length; ++ii ) { for ( int ii = 0; ii < knowns.length; ++ii ) {
if ( knowns[ii].equals( dflt ) ) { if ( knowns[ii].equals( mCurKnown ) ) {
spinner.setSelection( ii ); mNamesSpinner.setSelection( ii );
break; break;
}
} }
} }
EditText et = (EditText)findViewById( R.id.name_edit ); EditWClear et = (EditWClear)findViewById( R.id.name_edit );
et.setText( gameName ); et.setText( gameName );
RadioGroup group = (RadioGroup)findViewById( R.id.group );
group.setOnCheckedChangeListener( this );
} }
String gameName() void onButtonPressed( ButtonCallbacks procs )
{ {
EditText et = (EditText)findViewById( R.id.name_edit ); String gameName = gameName();
switch ( mCurRadio ) {
case R.id.radio_known:
DBUtils.setStringFor( getContext(), KP_NAME_KEY, mCurKnown );
procs.onUseKnown( mCurKnown, gameName );
break;
case R.id.radio_unknown:
procs.onInviteLater( gameName );
break;
case R.id.radio_configure:
procs.onConfigureFirst( gameName );
break;
default:
break;
}
}
private String gameName()
{
EditWClear et = (EditWClear)findViewById( R.id.name_edit );
return et.getText().toString(); return et.getText().toString();
} }
@ -84,13 +122,52 @@ public class NewWithKnowns extends LinearLayout implements OnItemSelectedListene
public void onItemSelected( AdapterView<?> parent, View view, public void onItemSelected( AdapterView<?> parent, View view,
int pos, long id ) int pos, long id )
{ {
OnNameChangeListener listener = mListener; if ( view instanceof TextView ) {
if ( null != listener && view instanceof TextView ) {
TextView tv = (TextView)view; TextView tv = (TextView)view;
listener.onNewName( tv.getText().toString() ); mCurKnown = tv.getText().toString();
onRadioChanged();
} }
} }
@Override @Override
public void onNothingSelected( AdapterView<?> parent ) {} public void onNothingSelected( AdapterView<?> parent ) {}
@Override
public void onCheckedChanged( RadioGroup group, int checkedId )
{
mCurRadio = checkedId;
onRadioChanged();
}
private void onRadioChanged()
{
mNamesSpinner.setVisibility( mCurRadio == R.id.radio_known
? View.VISIBLE : View.GONE );
Context context = getContext();
int resId = 0;
String msg = null;
switch ( mCurRadio ) {
case R.id.radio_known:
msg = LocUtils
.getString( context, R.string.newgame_invite_fmt, mCurKnown );
break;
case R.id.radio_unknown:
resId = R.string.newgame_open_game;
break;
case R.id.radio_configure:
resId = R.string.newgame_configure_game;
break;
}
if ( 0 != resId ) {
msg = LocUtils.getString( context, resId );
}
if ( null != msg ) {
ButtonChangeListener listener = mListener;
if ( null != listener ) {
listener.onNewButtonText( msg );
}
}
}
} }

View file

@ -3,29 +3,72 @@
<org.eehouse.android.xw4.NewWithKnowns <org.eehouse.android.xw4.NewWithKnowns
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="match_parent"
android:padding="8dp" android:padding="8dp"
> >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/choose_opponent"
/>
<Spinner android:id="@+id/names" <RadioGroup android:id="@+id/group"
android:layout_width="fill_parent" android:orientation="vertical"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:drawSelectorOnTop="true" android:layout_height="wrap_content"
/> >
<TextView android:layout_width="fill_parent" <RadioButton android:id="@+id/radio_unknown"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="@string/name_game" android:layout_height="wrap_content"
/> android:text="@string/newgame_radio_unknown"
/>
<TextView android:text="@string/choose_expl_new"
style="@style/new_game_expl"
/>
<EditText android:id="@+id/name_edit" <RadioButton android:id="@+id/radio_known"
android:layout_width="fill_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
/> android:text="@string/newgame_radio_known"
/>
<Spinner android:id="@+id/names"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:paddingLeft="8dp"
android:visibility="gone"
/>
<TextView android:text="@string/choose_expl_known"
style="@style/new_game_expl"
/>
<RadioButton android:id="@+id/radio_configure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/newgame_configure_first"
/>
<TextView android:text="@string/choose_expl_config"
style="@style/new_game_expl"
/>
</RadioGroup>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/game_name_label"
android:layout_gravity="center_vertical"
/>
<org.eehouse.android.xw4.EditWClear
android:id="@+id/name_edit"
style="@style/edit_w_clear"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scrollHorizontally="true"
android:maxLines="1"
android:maxLength="32"
android:selectAllOnFocus="true"
android:focusable="false"
/>
</LinearLayout>
</org.eehouse.android.xw4.NewWithKnowns> </org.eehouse.android.xw4.NewWithKnowns>

View file

@ -1008,9 +1008,6 @@
# types of supported games, standalone and networked. # types of supported games, standalone and networked.
############################################################ ############################################################
--> -->
<!-- Text of second of two buttons for new standalone games. Tap
this and you'll get taken to the "Game configure" screen -->
<string name="newgame_configure_first">Configure first</string>
<!-- Text of first of two buttons for new networked games. Tap <!-- Text of first of two buttons for new networked games. Tap
this and a game will be created, but you probably won't see this and a game will be created, but you probably won't see
it immediately because an email or messaging app will be it immediately because an email or messaging app will be
@ -1722,7 +1719,7 @@
<string name="relay_invite_title">Relay Invitation</string> <string name="relay_invite_title">Relay Invitation</string>
<string name="p2p_invite_title">WiFi Direct Invitation</string> <string name="p2p_invite_title">WiFi Direct Invitation</string>
<!-- --> <!-- -->
<string name="game_name_label">New game name:</string> <string name="game_name_label">Game name:</string>
<!-- --> <!-- -->
<!-- <string name="sms_disabled">Playing via SMS is currently disabled. --> <!-- <string name="sms_disabled">Playing via SMS is currently disabled. -->
<!-- You can enable it in Settings->Network game settings.</string> --> <!-- You can enable it in Settings->Network game settings.</string> -->
@ -2677,8 +2674,25 @@
happen because the name is in use) --> happen because the name is in use) -->
<string name="knowns_dup_name_fmt">Unable to change name from <string name="knowns_dup_name_fmt">Unable to change name from
“%1$s” to “%2$s”. Is “%2$s” already in use?</string> “%1$s” to “%2$s”. Is “%2$s” already in use?</string>
<!-- Title of known-player spinner in quick-invite new game dialog -->
<string name="name_game">Name your game</string> <!-- Quick-start new game explanations and buttons -->
<!-- Title of the game name field in quick-invite new game dialog --> <string name="choose_expl_new">Start a game with somebody new,
<string name="choose_opponent">Choose your opponent</string> sending an invitation via email, SMS, or even a QR code</string>
<string name="choose_expl_known">OR start a game with somebody youve
played before, no invitation required</string>
<string name="choose_expl_config">OR start a game after configuring
it, e.g. to change the language or number of players</string>
<string name="newgame_radio_known">Invite Known</string>
<string name="newgame_radio_unknown">Invite Unknown</string>
<string name="newgame_invite_fmt">Start with %1$s</string>
<string name="newgame_open_game">Start game</string>
<string name="newgame_configure_game">Configure game</string>
<!-- Text of second of two buttons for new standalone games.
Tap this and you'll get taken to the "Game configure"
screen -->
<string name="newgame_configure_first">Configure first</string>
</resources> </resources>

View file

@ -174,4 +174,13 @@
<item name="android:paddingTop">5dp</item> <item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">5dp</item> <item name="android:paddingBottom">5dp</item>
</style> </style>
<style name="new_game_expl">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:textStyle">italic</item>
<item name="android:paddingLeft">20dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:textSize">10dp</item>
</style>
</resources> </resources>