DroidFish: Made it possible to click on moves in the move list to navigate to the corresponding position in the game. Idea from Scid on the go.

This commit is contained in:
Peter Osterlund
2011-12-17 23:01:53 +00:00
parent 4fe1d1d578
commit 5c2dec7499
4 changed files with 70 additions and 6 deletions

View File

@@ -74,7 +74,11 @@ import android.text.Html;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.StyleSpan;
import android.util.TypedValue;
@@ -101,7 +105,6 @@ public class DroidFish extends Activity implements GUIInterface {
// FIXME!!! book.txt (and test classes) should not be included in apk
// FIXME!!! PGN view option: game continuation (for training)
// FIXME!!! Command to go to next/previous move in PGN export order.
// FIXME!!! Remove invalid playerActions in PGN import (should be done in verifyChildren)
// FIXME!!! Implement bookmark mechanism for positions in pgn files
@@ -303,6 +306,7 @@ public class DroidFish extends Activity implements GUIInterface {
status.setFocusable(false);
moveListScroll.setFocusable(false);
moveList.setFocusable(false);
moveList.setMovementMethod(LinkMovementMethod.getInstance());
thinking.setFocusable(false);
cb = (ChessBoard)findViewById(R.id.chessboard);
@@ -1889,6 +1893,22 @@ public class DroidFish extends Activity implements GUIInterface {
boolean pendingNewLine = false;
/** Makes moves in the move list clickable. */
private final static class MoveLink extends ClickableSpan {
private Node node;
MoveLink(Node n) {
node = n;
}
@Override
public void onClick(View widget) {
if (ctrl != null)
ctrl.goNode(node);
}
@Override
public void updateDrawState(TextPaint ds) {
}
}
public void processToken(Node node, int type, String token) {
if ( (prevType == PgnToken.RIGHT_BRACKET) &&
(type != PgnToken.LEFT_BRACKET)) {
@@ -1950,6 +1970,7 @@ public class DroidFish extends Activity implements GUIInterface {
sb.append(token);
int l1 = sb.length();
nodeToCharPos.put(node, new NodeInfo(l0, l1));
sb.setSpan(new MoveLink(node), l0, l1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (endPos < l0) endPos = l0;
col0 = false;
if (nestLevel == 0) paraBold = true;

View File

@@ -377,7 +377,7 @@ public class DroidChessController {
} else {
// Don't undo first white move if playing black vs computer,
// because that would cause computer to immediately make
// a new move and the whole redo history will be lost.
// a new move.
if (gameMode.playerWhite() || gameMode.playerBlack()) {
game.redoMove();
return false;
@@ -427,6 +427,26 @@ public class DroidChessController {
}
}
public final void goNode(Node node) {
if (node == null)
return;
ss.searchResultWanted = false;
stopAnalysis();
stopComputerThinking();
game.goNode(node);
ponderMove = null;
if (!humansTurn()) {
if (game.getLastMove() != null) {
game.undoMove();
if (!humansTurn())
game.redoMove();
}
}
updateComputeThreads(true);
setSelection();
updateGUI();
}
public final int numVariations() {
return game.numVariations();
}

View File

@@ -323,6 +323,12 @@ public class Game {
}
}
public final void goNode(Node node) {
tree.goNode(node);
pendingDrawOffer = false;
updateTimeControl(true);
}
public final void newGame() {
tree = new GameTree(gameTextListener);
if (computerPlayer != null)

View File

@@ -571,7 +571,7 @@ public class GameTree {
dos.writeUTF(tagPairs.get(i).tagValue);
}
Node.writeToStream(dos, rootNode);
List<Integer> pathFromRoot = currentNode.getPathFromRoot();
ArrayList<Integer> pathFromRoot = currentNode.getPathFromRoot();
int pathLen = pathFromRoot.size();
dos.writeInt(pathLen);
for (int i = 0; i < pathLen; i++)
@@ -654,6 +654,15 @@ public class GameTree {
}
}
/** Go to given node in game tree. */
public final void goNode(Node node) {
ArrayList<Integer> path = node.getPathFromRoot();
while (currentNode != rootNode)
goBack();
for (Integer c : path)
goForward(c);
}
/** List of possible continuation moves. */
public final List<Move> variations() {
if (currentNode.verifyChildren(currentPos))
@@ -985,11 +994,19 @@ public class GameTree {
return anyToRemove;
}
final List<Integer> getPathFromRoot() {
List<Integer> ret = new ArrayList<Integer>(64);
final ArrayList<Integer> getPathFromRoot() {
ArrayList<Integer> ret = new ArrayList<Integer>(64);
Node node = this;
while (node.parent != null) {
ret.add(node.parent.defaultChild);
Node p = node.parent;
int childNo = -1;
for (int i = 0; i < p.children.size(); i++)
if (p.children.get(i) == node) {
childNo = i;
break;
}
if (childNo == -1) throw new RuntimeException();
ret.add(childNo);
node = node.parent;
}
Collections.reverse(ret);