mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-12 17:12:40 +01:00
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:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user