diff --git a/DroidFish/src/org/petero/droidfish/DroidFish.java b/DroidFish/src/org/petero/droidfish/DroidFish.java index d92f75e..16fcda5 100644 --- a/DroidFish/src/org/petero/droidfish/DroidFish.java +++ b/DroidFish/src/org/petero/droidfish/DroidFish.java @@ -107,10 +107,8 @@ import android.text.Html; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; -import android.text.TextPaint; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; -import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.LeadingMarginSpan; import android.text.style.StyleSpan; @@ -425,6 +423,7 @@ public class DroidFish extends Activity implements GUIInterface { initUI(); gameTextListener = new PgnScreenText(this, pgnOptions); + moveList.setOnLinkClickListener(gameTextListener); if (ctrl != null) ctrl.shutdownEngine(); ctrl = new DroidChessController(this, gameTextListener, pgnOptions); @@ -616,6 +615,7 @@ public class DroidFish extends Activity implements GUIInterface { setSelection(oldCB.selectedSquare); cb.userSelectedSquare = oldCB.userSelectedSquare; setStatusString(statusStr); + moveList.setOnLinkClickListener(gameTextListener); moveListUpdated(); updateThinkingInfo(); ctrl.updateRemainingTime(); @@ -3526,8 +3526,10 @@ public class DroidFish extends Activity implements GUIInterface { } /** PngTokenReceiver implementation that renders PGN data for screen display. */ - static class PgnScreenText implements PgnToken.PgnTokenReceiver { + static class PgnScreenText implements PgnToken.PgnTokenReceiver, + MoveListView.OnLinkClickListener { private SpannableStringBuilder sb = new SpannableStringBuilder(); + private TreeMap offs2Node = new TreeMap(); private int prevType = PgnToken.EOF; int nestLevel = 0; boolean col0 = true; @@ -3592,28 +3594,31 @@ public class DroidFish extends Activity implements GUIInterface { boolean pendingNewLine = false; - /** Makes moves in the move list clickable. */ - private final class MoveLink extends ClickableSpan { - private Node node; - MoveLink(Node n) { - node = n; - } - @Override - public void onClick(View widget) { - if (ctrl != null) { - // On android 4.1 this onClick method is called - // even when you long click the move list. The test - // below works around the problem. - Dialog mlmd = moveListMenuDlg; - if ((mlmd == null) || !mlmd.isShowing()) { - df.setAutoMode(AutoMode.OFF); - ctrl.goNode(node); - } - } - } - @Override - public void updateDrawState(TextPaint ds) { + private void addMoveLink(Node node, int l0, int l1) { + offs2Node.put(l0, node); + offs2Node.put(l1, null); + } + + @Override + public boolean onLinkClick(int offs) { + if (ctrl == null) + return false; + Map.Entry e = offs2Node.floorEntry(offs); + if (e == null) + return false; + Node node = e.getValue(); + if (node == null) + return false; + + // On android 4.1 this onClick method is called + // even when you long click the move list. The test + // below works around the problem. + Dialog mlmd = moveListMenuDlg; + if ((mlmd == null) || !mlmd.isShowing()) { + df.setAutoMode(AutoMode.OFF); + ctrl.goNode(node); } + return true; } public void processToken(Node node, int type, String token) { @@ -3677,7 +3682,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); + addMoveLink(node, l0, l1); if (endPos < l0) endPos = l0; col0 = false; if (nestLevel == 0) paraBold = true; @@ -3714,6 +3719,7 @@ public class DroidFish extends Activity implements GUIInterface { @Override public void clear() { sb = new SpannableStringBuilder(); + offs2Node.clear(); prevType = PgnToken.EOF; nestLevel = 0; col0 = true; diff --git a/DroidFish/src/org/petero/droidfish/MoveListView.java b/DroidFish/src/org/petero/droidfish/MoveListView.java index ff556bf..a6b22fb 100644 --- a/DroidFish/src/org/petero/droidfish/MoveListView.java +++ b/DroidFish/src/org/petero/droidfish/MoveListView.java @@ -25,10 +25,8 @@ import android.graphics.Paint; import android.graphics.Typeface; import android.text.Layout; import android.text.Layout.Alignment; -import android.text.Spannable; import android.text.StaticLayout; import android.text.TextPaint; -import android.text.style.ClickableSpan; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; @@ -154,23 +152,28 @@ public class MoveListView extends View { } } + public interface OnLinkClickListener { + boolean onLinkClick(int offs); + } + private OnLinkClickListener onLinkClickListener; + + public void setOnLinkClickListener(OnLinkClickListener listener) { + onLinkClickListener = listener; + } + @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getActionMasked(); boolean ret = super.onTouchEvent(event); if ((action == MotionEvent.ACTION_UP) && (layout != null) && - (text instanceof Spannable)) { - Spannable spannable = (Spannable)text; + (onLinkClickListener != null)) { int x = (int)event.getX() - getPaddingLeft() + getScrollX(); int y = (int)event.getY() - getPaddingTop() + getScrollY(); int line = layout.getLineForVertical(y); int offs = layout.getOffsetForHorizontal(line, x); - ClickableSpan[] link = spannable.getSpans(offs, offs, ClickableSpan.class); - if (link.length > 0) { - link[0].onClick(this); + if (onLinkClickListener.onLinkClick(offs)) return true; - } } return ret; }