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 {
private static final String TAG = GamesListDelegate.class.getSimpleName();
private static final String SAVE_NEXTSOLO = "SAVE_NEXTSOLO";
private static final String SAVE_REMATCHEXTRAS = "SAVE_REMATCHEXTRAS";
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 ROWID_EXTRA = "rowid";
@ -966,44 +964,46 @@ public class GamesListDelegate extends ListDelegateBase
private Dialog mkNewWithKnowns()
{
String[] names = XwJNI.kplr_getPlayers();
final String[] nameRef
= { DBUtils.getStringFor( m_activity, KP_NAME_KEY, null ) };
final NewWithKnowns view = (NewWithKnowns)
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()
.setView( view )
.setTitle( R.string.new_game_networked )
.setIcon( R.drawable.ic_multigame )
.setPositiveButton( "" /* can't be empty*/, new OnClickListener() {
.setPositiveButton( android.R.string.cancel, new OnClickListener() {
@Override
public void onClick( DialogInterface dlg, int item ) {
Assert.assertTrueNR( null != nameRef[0] );
DBUtils.setStringFor( m_activity, KP_NAME_KEY, nameRef[0] );
CommsAddrRec addr = XwJNI.kplr_getAddr( nameRef[0] );
view.onButtonPressed(new NewWithKnowns.ButtonCallbacks() {
@Override
public void onUseKnown( String knownName, String gameName )
{
CommsAddrRec addr = XwJNI.kplr_getAddr( knownName );
if ( null != addr ) {
launchLikeRematch( addr, view.gameName() );
launchLikeRematch( addr, gameName );
}
}
} )
.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 );
public void onInviteLater( String gameName )
{
curThis().makeThenLaunchOrConfigure( gameName, false, false );
}
} )
;
@Override
public void onConfigureFirst( String gameName )
{
curThis().makeThenLaunchOrConfigure( gameName, true, false );
}
} );
}
} );
final AlertDialog dialog = ab.create();
view.setOnNameChangeListener( new NewWithKnowns.OnNameChangeListener() {
view.setCallback( new NewWithKnowns.ButtonChangeListener() {
@Override
public void onNewName( String name ) {
nameRef[0] = name;
public void onNewButtonText( String txt ) {
Button button = dialog.getButton( DialogInterface.BUTTON_POSITIVE );
if ( null != button ) {
String msg = getString( R.string.invite_player_fmt, name );
button.setText( msg );
button.setText( txt );
} else {
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;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.Spinner;
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 {
void onNewName( String name );
private static final String TAG = NewWithKnowns.class.getSimpleName();
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 )
{
super( cx, as );
}
void setOnNameChangeListener( OnNameChangeListener listener )
void setCallback( ButtonChangeListener listener )
{
Assert.assertTrueNR( null == mListener );
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>( getContext(),
android.R.layout.simple_spinner_item,
knowns );
adapter.setDropDownViewResource( android.R.layout
.simple_spinner_dropdown_item );
Spinner spinner = (Spinner)findViewById( R.id.names );
spinner.setAdapter( adapter );
spinner.setOnItemSelectedListener( this );
if ( !TextUtils.isEmpty( dflt ) ) {
mNamesSpinner = (Spinner)findViewById( R.id.names );
mNamesSpinner.setAdapter( adapter );
mNamesSpinner.setOnItemSelectedListener( this );
Assert.assertTrueNR( !TextUtils.isEmpty( mCurKnown ) );
for ( int ii = 0; ii < knowns.length; ++ii ) {
if ( knowns[ii].equals( dflt ) ) {
spinner.setSelection( ii );
if ( knowns[ii].equals( mCurKnown ) ) {
mNamesSpinner.setSelection( ii );
break;
}
}
}
EditText et = (EditText)findViewById( R.id.name_edit );
EditWClear et = (EditWClear)findViewById( R.id.name_edit );
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();
}
@ -84,13 +122,52 @@ public class NewWithKnowns extends LinearLayout implements OnItemSelectedListene
public void onItemSelected( AdapterView<?> parent, View view,
int pos, long id )
{
OnNameChangeListener listener = mListener;
if ( null != listener && view instanceof TextView ) {
if ( view instanceof TextView ) {
TextView tv = (TextView)view;
listener.onNewName( tv.getText().toString() );
mCurKnown = tv.getText().toString();
onRadioChanged();
}
}
@Override
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
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
>
<TextView android:layout_width="fill_parent"
<RadioGroup android:id="@+id/group"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/choose_opponent"
>
<RadioButton android:id="@+id/radio_unknown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/newgame_radio_unknown"
/>
<TextView android:text="@string/choose_expl_new"
style="@style/new_game_expl"
/>
<RadioButton android:id="@+id/radio_known"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/newgame_radio_known"
/>
<Spinner android:id="@+id/names"
android:layout_width="fill_parent"
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"
/>
<TextView android:layout_width="fill_parent"
<RadioButton android:id="@+id/radio_configure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/name_game"
android:text="@string/newgame_configure_first"
/>
<TextView android:text="@string/choose_expl_config"
style="@style/new_game_expl"
/>
</RadioGroup>
<EditText android:id="@+id/name_edit"
android:layout_width="fill_parent"
<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>

View file

@ -1008,9 +1008,6 @@
# 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
this and a game will be created, but you probably won't see
it immediately because an email or messaging app will be
@ -1722,7 +1719,7 @@
<string name="relay_invite_title">Relay 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. -->
<!-- You can enable it in Settings->Network game settings.</string> -->
@ -2677,8 +2674,25 @@
happen because the name is in use) -->
<string name="knowns_dup_name_fmt">Unable to change name from
“%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>
<!-- Title of the game name field in quick-invite new game dialog -->
<string name="choose_opponent">Choose your opponent</string>
<!-- Quick-start new game explanations and buttons -->
<string name="choose_expl_new">Start a game with somebody new,
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>

View file

@ -174,4 +174,13 @@
<item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">5dp</item>
</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>