Merge branch 'relay_proxy' of ssh://xwords.git.sourceforge.net/gitroot/xwords/xwords into relay_proxy

This commit is contained in:
Eric House 2010-11-01 21:54:28 -07:00
commit 892f30692b
13 changed files with 256 additions and 115 deletions

View file

@ -25,6 +25,13 @@
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical"> android:orientation="vertical">
<CheckBox android:id="@+id/game_locked_check"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/game_locked"
android:visibility="gone"
/>
<!-- players --> <!-- players -->
<TextView style="@style/config_separator" <TextView style="@style/config_separator"
android:id="@+id/players_label" android:id="@+id/players_label"

View file

@ -49,6 +49,10 @@
<string name="key_notagain_zoom">key_notagain_zoom</string> <string name="key_notagain_zoom">key_notagain_zoom</string>
<string name="key_notagain_undo">key_notagain_undo</string> <string name="key_notagain_undo">key_notagain_undo</string>
<string name="key_notagain_done">key_notagain_done</string> <string name="key_notagain_done">key_notagain_done</string>
<string name="key_notagain_unlock">key_notagain_unlock</string>
<string name="key_notagain_conndall">key_notagain_conndall</string>
<string name="key_notagain_conndfirst">key_notagain_conndfirst</string>
<string name="key_notagain_conndmid">key_notagain_conndmid</string>
<string name="relayids_extra">org.eehouse.android.xw4.relayids_extra</string> <string name="relayids_extra">org.eehouse.android.xw4.relayids_extra</string>

View file

@ -79,8 +79,8 @@
<string name="board_menu_done">Turn done</string> <string name="board_menu_done">Turn done</string>
<string name="board_menu_juggle">Shuffle</string> <string name="board_menu_juggle">Shuffle</string>
<string name="board_menu_flip">Flip</string> <string name="board_menu_flip">Flip</string>
<string name="board_menu_trade">Exchange</string> <string name="board_menu_trade">Exchange tiles</string>
<string name="board_menu_tray">Hide tray</string> <string name="board_menu_tray">Hide rack</string>
<string name="board_submenu_undo">Undo</string> <string name="board_submenu_undo">Undo</string>
<string name="board_menu_undo_current">Undo current</string> <string name="board_menu_undo_current">Undo current</string>
<string name="board_menu_undo_last">Undo last</string> <string name="board_menu_undo_last">Undo last</string>
@ -112,7 +112,7 @@
<string name="str_pass"> - %d [time]</string> <string name="str_pass"> - %d [time]</string>
<string name="strs_move_across">move (from %s across)</string> <string name="strs_move_across">move (from %s across)</string>
<string name="strs_move_down">move (from %s down)</string> <string name="strs_move_down">move (from %s down)</string>
<string name="strs_tray_at_start">Tray at start: %s</string> <string name="strs_tray_at_start">Rack at start: %s</string>
<string name="strss_traded_for">Exchanged %s for %s.</string> <string name="strss_traded_for">Exchanged %s for %s.</string>
<string name="str_phony_rejected">Illegal word in move; turn lost!</string> <string name="str_phony_rejected">Illegal word in move; turn lost!</string>
<string name="strd_cumulative_score">Cumulative score: %d</string> <string name="strd_cumulative_score">Cumulative score: %d</string>
@ -153,6 +153,7 @@
<string name="players_label_standalone">Players</string> <string name="players_label_standalone">Players</string>
<string name="players_label_host">Players (%d local, %d off-device)</string> <string name="players_label_host">Players (%d local, %d off-device)</string>
<string name="players_label_guest">Players -- local only</string> <string name="players_label_guest">Players -- local only</string>
<string name="game_locked">Lock settings</string>
<string name="button_add_player">Add player</string> <string name="button_add_player">Add player</string>
<string name="button_juggle_players">Shuffle players</string> <string name="button_juggle_players">Shuffle players</string>
@ -184,8 +185,14 @@
<string name="confirm_save">This game is in play. If you <string name="confirm_save">This game is in play. If you
save these changes it must be restarted. Do you want to save save these changes it must be restarted. Do you want to save
these changes?</string> these changes?</string>
<string name="confirm_delete_all">Are you sure you want to <string name="confirm_delete">Are you sure you want to delete this
delete all games? This action cannot be undone.</string> game?</string>
<string name="confirm_delete_all">Are you sure you want to delete
all games?</string>
<string name="confirm_reset">Are you sure you want to reset this
game? Resetting erases all moves and any connection
information.</string>
<string name="confirm_delete_dict">Are you sure you want to delete <string name="confirm_delete_dict">Are you sure you want to delete
this dictionary? You will not be able to open any games that use this dictionary? You will not be able to open any games that use
it.</string> it.</string>
@ -197,8 +204,8 @@
<string name="color_tiles_summary">Draw tiles using color of <string name="color_tiles_summary">Draw tiles using color of
player who played them</string> player who played them</string>
<string name="show_arrow">Show board arrow</string> <string name="show_arrow">Show board arrow</string>
<string name="show_arrow_summary">Tapped tray tiles land on this <string name="show_arrow_summary">Tapped rack tiles land on this
arrow when it is visible</string> arrow when it is visible</string>
<string name="explain_robot">Explain robot moves</string> <string name="explain_robot">Explain robot moves</string>
<string name="explain_robot_summary">Display score summary after <string name="explain_robot_summary">Display score summary after
every robot turn</string> every robot turn</string>
@ -206,8 +213,8 @@
<string name="skip_confirm_turn_summary">Do NOT display score <string name="skip_confirm_turn_summary">Do NOT display score
summary after every human turn</string> summary after every human turn</string>
<string name="title_sort_tiles">Sort new tiles</string> <string name="title_sort_tiles">Sort new tiles</string>
<string name="summary_sort_tiles">Sort trays whenever new tiles <string name="summary_sort_tiles">Sort racks whenever new tiles
are added</string> are added</string>
<string name="ringer_zoom">Volume keys zoom</string> <string name="ringer_zoom">Volume keys zoom</string>
<string name="ringer_zoom_summary">Zoom board using volume keys</string> <string name="ringer_zoom_summary">Zoom board using volume keys</string>
<string name="hide_title">Hide titlebar</string> <string name="hide_title">Hide titlebar</string>
@ -292,8 +299,8 @@
<string name="tab_sms">SMS (broken)</string> <string name="tab_sms">SMS (broken)</string>
<string name="tab_bluetooth">Bluetooth (pending)</string> <string name="tab_bluetooth">Bluetooth (pending)</string>
<string name="msg_relay_waiting">Connected to relay in room <string name="msg_relay_waiting">Device %d connected to relay in
\"%s\". Waiting for %d player[s].</string> room \"%s\". Waiting for %d player[s].</string>
<string name="msg_relay_all_heref">All players are here in room <string name="msg_relay_all_heref">All players are here in room
\"%s\".</string> \"%s\".</string>
<string name="title_relay_status">Connection status.</string> <string name="title_relay_status">Connection status.</string>
@ -418,9 +425,15 @@
Or try joining or creating a public room.</string> Or try joining or creating a public room.</string>
<string name="not_again_newgame">The new game you have created has <string name="not_again_newgame">The new game you have created has
two players, the first a robot, both on this device. To play two players, the first a robot, both on this device. Tap it to
the game, tap it; to change its configuration or for other play; long-tap it to change its configuration or for other
options, long-tap it.</string> options.</string>
<string name="not_again_newgamenet">The new game you have created
has two players but only one is on this device. To play the
game, tap it, and it will begin by connecting over the internet
looking for that other player in the default no-name
room. Long-tap it to configure - e.g. change the room name - or
for other options.</string>
<string name="not_again_hintprev">This button shows all possible <string name="not_again_hintprev">This button shows all possible
moves in ascending order (using tiles to the right of the rack moves in ascending order (using tiles to the right of the rack
@ -438,9 +451,25 @@
<string name="not_again_undo">This button undos or redoes the <string name="not_again_undo">This button undos or redoes the
current turn.</string> current turn.</string>
<string name="not_again_newgamenet">The new game you have created </string> <string name="not_again_done">Tapping the \"pts\" counter that
<string name="not_again_done">The \"pts\" counter that appears at appears at the right end of the rack is the easiest way to
the right end of the rack is an alternative to this menu commit a move. (There is no shortcut for ending a
item.</string> trade.)</string>
<string name="not_again_unlock">This game is in play. Some
settings, e.g. the number of players, cannot be changed without
restarting it. When you leave this page you will have a chance
to discard changes to avoid a restart.</string>
<string name="not_again_conndall">You have connected and joined a
game on the relay; the room is now full. The device that
created the room will now assign your initial tiles and play can
begin.</string>
<string name="not_again_conndfirst">You have connected and started
a game in a new room. Once the remaining devices have joined
your room and Crosswords has assigned them tiles the game can
begin.</string>
<string name="not_again_conndmid">You have connected and joined a
game on the relay. You will be notified when the remaining
device[s] have joined your room and play can begin.</string>
</resources> </resources>

View file

@ -471,7 +471,7 @@ public class BoardActivity extends XWActivity implements UtilCtxt {
// cmd = JNIThread.JNICmd.CMD_FLIP; // cmd = JNIThread.JNICmd.CMD_FLIP;
// break; // break;
case R.id.board_menu_trade: case R.id.board_menu_trade:
cmd = JNIThread.JNICmd.CMD_TOGGLE_TRADE; cmd = JNIThread.JNICmd.CMD_TRADE;
break; break;
case R.id.board_menu_tray: case R.id.board_menu_tray:
cmd = JNIThread.JNICmd.CMD_TOGGLE_TRAY; cmd = JNIThread.JNICmd.CMD_TOGGLE_TRAY;
@ -625,7 +625,9 @@ public class BoardActivity extends XWActivity implements UtilCtxt {
{ {
CommsTransport.ConndMsg cndmsg = CommsTransport.ConndMsg cndmsg =
(CommsTransport.ConndMsg)msg.obj; (CommsTransport.ConndMsg)msg.obj;
Utils.logf( "handleConndMessage: devOrder=%d", cndmsg.m_devOrder );
int naMsg = 0;
int naKey = 0;
String str = null; String str = null;
if ( cndmsg.m_allHere ) { if ( cndmsg.m_allHere ) {
// All players have now joined the game. The device that // All players have now joined the game. The device that
@ -633,16 +635,38 @@ public class BoardActivity extends XWActivity implements UtilCtxt {
// the first player's turn // the first player's turn
String fmt = getString( R.string.msg_relay_all_heref ); String fmt = getString( R.string.msg_relay_all_heref );
str = String.format( fmt, cndmsg.m_room ); str = String.format( fmt, cndmsg.m_room );
if ( cndmsg.m_devOrder > 1 ) {
naMsg = R.string.not_again_conndall;
naKey = R.string.key_notagain_conndall;
}
} else if ( cndmsg.m_nMissing > 0 ) { } else if ( cndmsg.m_nMissing > 0 ) {
String fmt = getString( R.string.msg_relay_waiting ); String fmt = getString( R.string.msg_relay_waiting );
str = String.format( fmt, cndmsg.m_room, cndmsg.m_nMissing ); str = String.format( fmt, cndmsg.m_devOrder,
cndmsg.m_room, cndmsg.m_nMissing );
if ( cndmsg.m_devOrder == 1 ) {
naMsg = R.string.not_again_conndfirst;
naKey = R.string.key_notagain_conndfirst;
} else {
naMsg = R.string.not_again_conndmid;
naKey = R.string.key_notagain_conndmid;
}
} }
if ( null != str ) { if ( null != str ) {
Toast.makeText( BoardActivity.this, str, final String fstr = str;
Toast.LENGTH_SHORT).show(); Runnable proc = new Runnable() {
public void run() {
Toast.makeText( BoardActivity.this, fstr,
Toast.LENGTH_SHORT).show();
}
};
if ( naMsg == 0 ) {
proc.run();
} else {
showNotAgainDlgThen( naMsg, naKey, proc );
}
} }
} } // handleConndMessage
////////////////////////////////////////// //////////////////////////////////////////
// XW_UtilCtxt interface implementation // // XW_UtilCtxt interface implementation //

View file

@ -69,6 +69,8 @@ public class GameConfig extends XWActivity
private static final int NO_NAME_FOUND = PLAYER_EDIT + 4; private static final int NO_NAME_FOUND = PLAYER_EDIT + 4;
private CheckBox m_joinPublicCheck; private CheckBox m_joinPublicCheck;
private CheckBox m_gameLockedCheck;
private boolean m_isLocked;
private LinearLayout m_publicRoomsSet; private LinearLayout m_publicRoomsSet;
private LinearLayout m_privateRoomsSet; private LinearLayout m_privateRoomsSet;
@ -98,9 +100,23 @@ public class GameConfig extends XWActivity
private CommonPrefs m_cp; private CommonPrefs m_cp;
private boolean m_canDoSMS = false; private boolean m_canDoSMS = false;
private boolean m_canDoBT = false; private boolean m_canDoBT = false;
private int m_nMoves = 0; private boolean m_gameStarted = false;
private CommsAddrRec.CommsConnType[] m_types; private CommsAddrRec.CommsConnType[] m_types;
private String[] m_connStrings; private String[] m_connStrings;
private static final int[] s_disabledWhenLocked = { R.id.juggle_players
,R.id.add_player
,R.id.dict_spinner
,R.id.join_public_room_check
,R.id.room_edit
,R.id.advertise_new_room_check
,R.id.room_spinner
,R.id.refresh_button
,R.id.hints_allowed
,R.id.use_timer
,R.id.timer_minutes_edit
,R.id.smart_robot
,R.id.phonies_spinner
};
class RemoteChoices extends XWListAdapter { class RemoteChoices extends XWListAdapter {
public RemoteChoices() { super( GameConfig.this, m_gi.nPlayers ); } public RemoteChoices() { super( GameConfig.this, m_gi.nPlayers ); }
@ -127,7 +143,7 @@ public class GameConfig extends XWActivity
} }
@Override @Override
protected Dialog onCreateDialog( int id ) protected Dialog onCreateDialog( final int id )
{ {
Dialog dialog = super.onCreateDialog( id ); Dialog dialog = super.onCreateDialog( id );
if ( null == dialog ) { if ( null == dialog ) {
@ -199,41 +215,40 @@ public class GameConfig extends XWActivity
} }
}); });
break; break;
case CONFIRM_CHANGE:
dialog = new AlertDialog.Builder( this )
.setTitle( R.string.confirm_save_title )
.setMessage( R.string.confirm_save )
.setPositiveButton( R.string.button_save,
new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
applyChanges( true );
finish();
}
})
.setNegativeButton( R.string.button_discard,
new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
finish();
}
})
.create();
break;
case CONFIRM_CHANGE_PLAY: case CONFIRM_CHANGE_PLAY:
dialog = new AlertDialog.Builder( this ) case CONFIRM_CHANGE:
dlpos = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg,
int whichButton ) {
applyChanges( true );
if ( CONFIRM_CHANGE_PLAY == id ) {
launchGame();
}
}
};
ab = new AlertDialog.Builder( this )
.setTitle( R.string.confirm_save_title ) .setTitle( R.string.confirm_save_title )
.setMessage( R.string.confirm_save ) .setMessage( R.string.confirm_save )
.setPositiveButton( R.string.button_save, .setPositiveButton( R.string.button_save, dlpos );
new DialogInterface.OnClickListener() { if ( CONFIRM_CHANGE_PLAY == id ) {
public void onClick( DialogInterface dlg, dlpos = new DialogInterface.OnClickListener() {
int whichButton ) { public void onClick( DialogInterface dlg,
applyChanges( true ); int whichButton ) {
launchGame(); launchGame();
} }
}) };
.setNegativeButton( R.string.button_cancel, null ) } else {
.create(); dlpos = null;
}
ab.setNegativeButton( R.string.button_discard, dlpos );
dialog = ab.create();
dialog.setOnDismissListener( new DialogInterface.
OnDismissListener() {
public void onDismiss( DialogInterface di ) {
finish();
}
});
break; break;
case NO_NAME_FOUND: case NO_NAME_FOUND:
dialog = new AlertDialog.Builder( this ) dialog = new AlertDialog.Builder( this )
@ -350,11 +365,23 @@ public class GameConfig extends XWActivity
m_path = m_path.substring( 1 ); m_path = m_path.substring( 1 );
} }
setContentView(R.layout.game_config);
int gamePtr = XwJNI.initJNI(); int gamePtr = XwJNI.initJNI();
m_giOrig = new CurGameInfo( this ); m_giOrig = new CurGameInfo( this );
GameUtils.loadMakeGame( this, gamePtr, m_giOrig, m_path ); GameUtils.loadMakeGame( this, gamePtr, m_giOrig, m_path );
m_nMoves = XwJNI.model_getNMoves( gamePtr ); m_gameStarted = XwJNI.model_getNMoves( gamePtr ) > 0
m_giOrig.setInProgress( 0 < m_nMoves ); || XwJNI.comms_isConnected( gamePtr );
m_giOrig.setInProgress( m_gameStarted );
if ( m_gameStarted ) {
m_gameLockedCheck = (CheckBox)findViewById( R.id.game_locked_check );
m_gameLockedCheck.setVisibility( View.VISIBLE );
m_gameLockedCheck.setChecked( true );
m_gameLockedCheck.setOnClickListener( this );
handleLockedChange();
}
int curSel = listAvailableDicts( m_giOrig.dictName ); int curSel = listAvailableDicts( m_giOrig.dictName );
m_giOrig.dictLang = m_giOrig.dictLang =
DictLangCache.getLangCode( this, DictLangCache.getLangCode( this,
@ -373,8 +400,6 @@ public class GameConfig extends XWActivity
m_car = new CommsAddrRec( m_carOrig ); m_car = new CommsAddrRec( m_carOrig );
setContentView(R.layout.game_config);
m_notNetworkedGame = DeviceRole.SERVER_STANDALONE == m_gi.serverRole; m_notNetworkedGame = DeviceRole.SERVER_STANDALONE == m_gi.serverRole;
if ( !m_notNetworkedGame ) { if ( !m_notNetworkedGame ) {
@ -463,6 +488,14 @@ public class GameConfig extends XWActivity
loadPlayers(); loadPlayers();
} else if ( m_joinPublicCheck == view ) { } else if ( m_joinPublicCheck == view ) {
adjustConnectStuff(); adjustConnectStuff();
} else if ( m_gameLockedCheck == view ) {
showNotAgainDlgThen( R.string.not_again_unlock,
R.string.key_notagain_unlock,
new Runnable() {
public void run() {
handleLockedChange();
}
});
} else if ( m_refreshRoomsButton == view ) { } else if ( m_refreshRoomsButton == view ) {
refreshNames(); refreshNames();
} else if ( m_playButton == view ) { } else if ( m_playButton == view ) {
@ -471,7 +504,7 @@ public class GameConfig extends XWActivity
// from here if there's no confirmation needed, or launch // from here if there's no confirmation needed, or launch
// a new dialog whose OK button does the same thing. // a new dialog whose OK button does the same thing.
saveChanges(); saveChanges();
if ( 0 >= m_nMoves ) { // no confirm needed if ( !m_gameStarted ) { // no confirm needed
applyChanges( true ); applyChanges( true );
launchGame(); launchGame();
} else if ( m_giOrig.changesMatter(m_gi) } else if ( m_giOrig.changesMatter(m_gi)
@ -494,7 +527,7 @@ public class GameConfig extends XWActivity
boolean consumed = false; boolean consumed = false;
if ( keyCode == KeyEvent.KEYCODE_BACK ) { if ( keyCode == KeyEvent.KEYCODE_BACK ) {
saveChanges(); saveChanges();
if ( 0 >= m_nMoves ) { // no confirm needed if ( !m_gameStarted ) { // no confirm needed
applyChanges( true ); applyChanges( true );
} else if ( m_giOrig.changesMatter(m_gi) } else if ( m_giOrig.changesMatter(m_gi)
|| (! m_notNetworkedGame || (! m_notNetworkedGame
@ -544,6 +577,7 @@ public class GameConfig extends XWActivity
} }
} ); } );
m_playerLayout.addView( view ); m_playerLayout.addView( view );
view.setEnabled( !m_isLocked );
View divider = factory.inflate( R.layout.divider_view, null ); View divider = factory.inflate( R.layout.divider_view, null );
divider.setVisibility( View.VISIBLE ); divider.setVisibility( View.VISIBLE );
@ -700,6 +734,26 @@ public class GameConfig extends XWActivity
m_publicRoomsSet.setVisibility( View.GONE ); m_publicRoomsSet.setVisibility( View.GONE );
} }
} }
// User's toggling whether everything's locked. That should mean
// we enable/disable a bunch of widgits. And if we're going from
// unlocked to locked we need to confirm that everything can be
// reverted.
private void handleLockedChange()
{
boolean locking = m_gameLockedCheck.isChecked();
m_isLocked = locking;
for ( int id : s_disabledWhenLocked ) {
View view = findViewById( id );
view.setEnabled( !m_isLocked );
}
if ( null != m_playerLayout ) {
for ( int ii = m_playerLayout.getChildCount()-1; ii >= 0; --ii ) {
View view = m_playerLayout.getChildAt( ii );
view.setEnabled( !m_isLocked );
}
}
}
private int connTypeToPos( CommsAddrRec.CommsConnType typ ) private int connTypeToPos( CommsAddrRec.CommsConnType typ )
{ {

View file

@ -274,15 +274,32 @@ public class GamesList extends XWListActivity
private boolean handleMenuItem( int menuID, int position ) private boolean handleMenuItem( int menuID, int position )
{ {
boolean handled = true; boolean handled = true;
byte[] stream;
String invalPath = null;
String path = GameUtils.gamesList( this )[position]; final String path = GameUtils.gamesList( this )[position];
if ( R.id.list_item_delete == menuID ) { if ( R.id.list_item_delete == menuID ) {
GameUtils.deleteGame( this, path ); DialogInterface.OnClickListener lstnr =
invalPath = path; new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int ii ) {
GameUtils.deleteGame( GamesList.this, path );
m_adapter.inval( path );
onContentChanged();
}
};
showConfirmThen( R.string.confirm_delete, lstnr );
} else if ( R.id.list_item_reset == menuID ) {
DialogInterface.OnClickListener lstnr =
new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int ii ) {
GameUtils.resetGame( GamesList.this,
path, path );
m_adapter.inval( path );
onContentChanged();
}
};
showConfirmThen( R.string.confirm_reset, lstnr );
} else { } else {
String invalPath = null;
String[] missingName = new String[1]; String[] missingName = new String[1];
int[] missingLang = new int[1]; int[] missingLang = new int[1];
boolean hasDict = GameUtils.gameDictHere( this, path, boolean hasDict = GameUtils.gameDictHere( this, path,
@ -296,11 +313,6 @@ public class GamesList extends XWListActivity
m_invalPath = path; m_invalPath = path;
break; break;
case R.id.list_item_reset:
// TODO confirm_data_loss();
GameUtils.resetGame( this, path, path );
invalPath = path;
break;
case R.id.list_item_new_from: case R.id.list_item_new_from:
String newName = GameUtils.resetGame( this, path ); String newName = GameUtils.resetGame( this, path );
invalPath = newName; invalPath = newName;
@ -311,7 +323,7 @@ public class GamesList extends XWListActivity
if ( summary.inNetworkGame() ) { if ( summary.inNetworkGame() ) {
showOKOnlyDialog( R.string.no_copy_network ); showOKOnlyDialog( R.string.no_copy_network );
} else { } else {
stream = GameUtils.savedGame( this, path ); byte[] stream = GameUtils.savedGame( this, path );
newName = GameUtils.saveGame( this, stream ); newName = GameUtils.saveGame( this, stream );
DBUtils.saveSummary( this, newName, summary ); DBUtils.saveSummary( this, newName, summary );
} }
@ -331,14 +343,13 @@ public class GamesList extends XWListActivity
break; break;
} }
} }
}
if ( null != invalPath ) { if ( null != invalPath ) {
m_adapter.inval( invalPath ); m_adapter.inval( invalPath );
} }
if ( handled ) {
if ( handled ) { onContentChanged();
onContentChanged(); }
} }
return handled; return handled;

View file

@ -30,7 +30,6 @@ import android.graphics.Rect;
public class XWListItem extends LinearLayout { public class XWListItem extends LinearLayout {
private int m_position; private int m_position;
private ImageButton m_button;
private Context m_context; private Context m_context;
DeleteCallback m_cb; DeleteCallback m_cb;
@ -64,4 +63,15 @@ public class XWListItem extends LinearLayout {
} ); } );
button.setVisibility( View.VISIBLE ); button.setVisibility( View.VISIBLE );
} }
@Override
public void setEnabled( boolean enabled )
{
ImageButton button = (ImageButton)getChildAt( 1 );
button.setEnabled( enabled );
// calling super here means the list item can't be opened for
// the user to inspect data. Might want to reconsider this.
// PENDING
super.setEnabled( enabled );
}
} }

View file

@ -61,7 +61,7 @@ public class JNIThread extends Thread {
CMD_JUGGLE, CMD_JUGGLE,
CMD_FLIP, CMD_FLIP,
CMD_TOGGLE_TRAY, CMD_TOGGLE_TRAY,
CMD_TOGGLE_TRADE, CMD_TRADE,
CMD_UNDO_CUR, CMD_UNDO_CUR,
CMD_UNDO_LAST, CMD_UNDO_LAST,
CMD_HINT, CMD_HINT,
@ -365,7 +365,7 @@ public class JNIThread extends Thread {
case CMD_TOGGLE_TRAY: case CMD_TOGGLE_TRAY:
draw = toggleTray(); draw = toggleTray();
break; break;
case CMD_TOGGLE_TRADE: case CMD_TRADE:
draw = XwJNI.board_beginTrade( m_jniGamePtr ); draw = XwJNI.board_beginTrade( m_jniGamePtr );
break; break;
case CMD_UNDO_CUR: case CMD_UNDO_CUR:

View file

@ -1215,10 +1215,8 @@ invalCellsWithTiles( BoardCtxt* board )
*/ */
for ( row = model_numRows( model )-1; row >= 0; --row ) { for ( row = model_numRows( model )-1; row >= 0; --row ) {
for ( col = model_numCols( model )-1; col >= 0; --col ) { for ( col = model_numCols( model )-1; col >= 0; --col ) {
Tile tile;
XP_Bool ignore;
if ( model_getTile( model, col, row, includePending, if ( model_getTile( model, col, row, includePending,
turn, &tile, &ignore, &ignore, &ignore ) ) { turn, NULL, NULL, NULL, NULL ) ) {
XP_U16 boardCol, boardRow; XP_U16 boardCol, boardRow;
flipIf( board, col, row, &boardCol, &boardRow ); flipIf( board, col, row, &boardCol, &boardRow );
invalCell( board, boardCol, boardRow ); invalCell( board, boardCol, boardRow );
@ -2327,13 +2325,12 @@ cellOccupied( const BoardCtxt* board, XP_U16 col, XP_U16 row,
XP_Bool inclPending ) XP_Bool inclPending )
{ {
Tile tile; Tile tile;
XP_Bool ignr;
XP_Bool result; XP_Bool result;
flipIf( board, col, row, &col, &row ); flipIf( board, col, row, &col, &row );
result = model_getTile( board->model, col, row, inclPending, result = model_getTile( board->model, col, row, inclPending,
board->selPlayer, &tile, board->selPlayer, &tile,
&ignr, &ignr, &ignr ); NULL, NULL, NULL );
return result; return result;
} /* cellOccupied */ } /* cellOccupied */
@ -2379,13 +2376,13 @@ XP_Bool
holdsPendingTile( BoardCtxt* board, XP_U16 pencol, XP_U16 penrow ) holdsPendingTile( BoardCtxt* board, XP_U16 pencol, XP_U16 penrow )
{ {
Tile tile; Tile tile;
XP_Bool ignore, isPending; XP_Bool isPending;
XP_U16 modcol, modrow; XP_U16 modcol, modrow;
flipIf( board, pencol, penrow, &modcol, &modrow ); flipIf( board, pencol, penrow, &modcol, &modrow );
return model_getTile( board->model, modcol, modrow, XP_TRUE, return model_getTile( board->model, modcol, modrow, XP_TRUE,
board->selPlayer, &tile, &ignore, &isPending, board->selPlayer, &tile, NULL, &isPending,
(XP_Bool*)NULL ) NULL )
&& isPending; && isPending;
} /* holdsPendingTile */ } /* holdsPendingTile */
@ -3232,16 +3229,14 @@ boardCellChanged( void* p_board, XP_U16 turn, XP_U16 modelCol, XP_U16 modelRow,
XP_Bool added ) XP_Bool added )
{ {
BoardCtxt* board = (BoardCtxt*)p_board; BoardCtxt* board = (BoardCtxt*)p_board;
XP_Bool pending, found, ignoreBlank; XP_Bool pending, found;
Tile ignoreTile;
XP_U16 col, row; XP_U16 col, row;
flipIf( board, modelCol, modelRow, &col, &row ); flipIf( board, modelCol, modelRow, &col, &row );
/* for each player, check if the tile overwrites the cursor */ /* for each player, check if the tile overwrites the cursor */
found = model_getTile( board->model, modelCol, modelRow, XP_TRUE, turn, found = model_getTile( board->model, modelCol, modelRow, XP_TRUE, turn,
&ignoreTile, &ignoreBlank, &pending, NULL, NULL, &pending, NULL );
(XP_Bool*)NULL );
XP_ASSERT( !added || found ); /* if added is true so must found be */ XP_ASSERT( !added || found ); /* if added is true so must found be */

View file

@ -91,14 +91,13 @@ ddStartBoard( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
trayVisible = board->trayVisState == TRAY_REVEALED; trayVisible = board->trayVisState == TRAY_REVEALED;
if ( trayVisible && holdsPendingTile( board, col, row ) ) { if ( trayVisible && holdsPendingTile( board, col, row ) ) {
XP_U16 modelc, modelr; XP_U16 modelc, modelr;
XP_Bool ignore;
ds->dtype = DT_TILE; ds->dtype = DT_TILE;
flipIf( board, col, row, &modelc, &modelr ); flipIf( board, col, row, &modelc, &modelr );
found = model_getTile( board->model, modelc, modelr, XP_TRUE, found = model_getTile( board->model, modelc, modelr, XP_TRUE,
board->selPlayer, &ds->tile, &ds->isBlank, board->selPlayer, &ds->tile, &ds->isBlank,
&ignore, &ignore ); NULL, NULL );
XP_ASSERT( found ); XP_ASSERT( found );
} else { } else {
/* If we're not dragging a tile, we can either drag the board (scroll) /* If we're not dragging a tile, we can either drag the board (scroll)

View file

@ -732,7 +732,7 @@ localGetBoardTile( EngineCtxt* engine, XP_U16 col, XP_U16 row,
XP_Bool substBlank ) XP_Bool substBlank )
{ {
Tile result; Tile result;
XP_Bool isBlank, ignore; XP_Bool isBlank;
if ( !engine->searchHorizontal ) { if ( !engine->searchHorizontal ) {
XP_U16 tmp = col; XP_U16 tmp = col;
@ -742,7 +742,7 @@ localGetBoardTile( EngineCtxt* engine, XP_U16 col, XP_U16 row,
if ( model_getTile( engine->model, col, row, XP_FALSE, if ( model_getTile( engine->model, col, row, XP_FALSE,
0, /* don't get pending, so turn doesn't matter */ 0, /* don't get pending, so turn doesn't matter */
&result, &isBlank, &ignore, (XP_Bool*)NULL ) ) { &result, &isBlank, NULL, NULL ) ) {
if ( isBlank && substBlank ) { if ( isBlank && substBlank ) {
result = engine->blankTile; result = engine->blankTile;
} }

View file

@ -327,10 +327,16 @@ model_getTile( const ModelCtxt* model, XP_U16 col, XP_U16 row,
if ( (cellTile & TILE_EMPTY_BIT) != 0 ) { if ( (cellTile & TILE_EMPTY_BIT) != 0 ) {
return XP_FALSE; return XP_FALSE;
} }
*tileP = cellTile & TILE_VALUE_MASK; if ( NULL != tileP ) {
*isBlank = IS_BLANK(cellTile); *tileP = cellTile & TILE_VALUE_MASK;
*pendingP = pending; }
if ( NULL != isBlank ) {
*isBlank = IS_BLANK(cellTile);
}
if ( NULL != pendingP ) {
*pendingP = pending;
}
if ( !!recentP ) { if ( !!recentP ) {
*recentP = (cellTile & PREV_MOVE_BIT) != 0; *recentP = (cellTile & PREV_MOVE_BIT) != 0;
} }
@ -1007,12 +1013,11 @@ model_moveTrayToBoard( ModelCtxt* model, XP_S16 turn, XP_U16 col, XP_U16 row,
XP_Bool XP_Bool
model_redoPendingTiles( ModelCtxt* model, XP_S16 turn ) model_redoPendingTiles( ModelCtxt* model, XP_S16 turn )
{ {
XP_Bool changed = XP_FALSE; XP_U16 actualCnt = 0;
PlayerCtxt* player = &model->players[turn]; PlayerCtxt* player = &model->players[turn];
XP_U16 nUndone = player->nUndone; XP_U16 nUndone = player->nUndone;
changed = nUndone > 0; if ( nUndone > 0 ) {
if ( changed ) {
PendingTile pendingTiles[nUndone]; PendingTile pendingTiles[nUndone];
PendingTile* pt = pendingTiles; PendingTile* pt = pendingTiles;
@ -1031,11 +1036,16 @@ model_redoPendingTiles( ModelCtxt* model, XP_S16 turn )
} }
foundAt = model_trayContains( model, turn, tile ); foundAt = model_trayContains( model, turn, tile );
XP_ASSERT( foundAt >= 0 ); XP_ASSERT( foundAt >= 0 );
model_moveTrayToBoard( model, turn, pt->col, pt->row,
foundAt, pt->tile & ~TILE_BLANK_BIT ); if ( !model_getTile( model, pt->col, pt->row, XP_FALSE, turn,
NULL, NULL, NULL, NULL ) ) {
model_moveTrayToBoard( model, turn, pt->col, pt->row,
foundAt, pt->tile & ~TILE_BLANK_BIT );
++actualCnt;
}
} }
} }
return changed; return actualCnt > 0;
} }
void void

View file

@ -317,11 +317,10 @@ static XP_Bool
modelIsEmptyAt( const ModelCtxt* model, XP_U16 col, XP_U16 row ) modelIsEmptyAt( const ModelCtxt* model, XP_U16 col, XP_U16 row )
{ {
Tile tile; Tile tile;
XP_Bool ignore;
XP_Bool found; XP_Bool found;
found = model_getTile( model, col, row, XP_FALSE, -1, &tile, found = model_getTile( model, col, row, XP_FALSE, -1, &tile,
&ignore, &ignore, (XP_Bool*)NULL ); NULL, NULL, NULL );
return !found; return !found;
} /* modelIsEmptyAt */ } /* modelIsEmptyAt */
@ -643,11 +642,10 @@ scoreWord( const ModelCtxt* model, MoveInfo* movei, /* new tiles */
++tiles; ++tiles;
--nTiles; --nTiles;
} else { /* placed on the board before this move */ } else { /* placed on the board before this move */
XP_Bool ignore;
tileMultiplier = 1; tileMultiplier = 1;
(void)model_getTile( model, col, row, XP_FALSE, -1, &tile, (void)model_getTile( model, col, row, XP_FALSE, -1, &tile,
&isBlank, &ignore, (XP_Bool*)NULL ); &isBlank, NULL, NULL );
XP_ASSERT( (tile & TILE_VALUE_MASK) == tile ); XP_ASSERT( (tile & TILE_VALUE_MASK) == tile );
} }