diff --git a/DroidFish/res/layout-land/main.xml b/DroidFish/res/layout-land/main.xml
index 911524e..9ab591d 100644
--- a/DroidFish/res/layout-land/main.xml
+++ b/DroidFish/res/layout-land/main.xml
@@ -99,17 +99,13 @@
android:layout_above="@+id/scrollViewBot"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
-
+ android:padding="0dp"/>
diff --git a/DroidFish/res/layout/main.xml b/DroidFish/res/layout/main.xml
index 981a6b0..80d0206 100644
--- a/DroidFish/res/layout/main.xml
+++ b/DroidFish/res/layout/main.xml
@@ -93,17 +93,13 @@
android:layout_above="@+id/scrollViewBot"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
-
+ android:padding="0dp"/>
diff --git a/DroidFish/res/layout/main_left_handed.xml b/DroidFish/res/layout/main_left_handed.xml
index 619e6a7..e76932a 100644
--- a/DroidFish/res/layout/main_left_handed.xml
+++ b/DroidFish/res/layout/main_left_handed.xml
@@ -94,17 +94,13 @@
android:layout_above="@+id/scrollViewBot"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
-
+ android:padding="0dp"/>
diff --git a/DroidFish/src/org/petero/droidfish/DroidFish.java b/DroidFish/src/org/petero/droidfish/DroidFish.java
index 6a6d5d8..d92f75e 100644
--- a/DroidFish/src/org/petero/droidfish/DroidFish.java
+++ b/DroidFish/src/org/petero/droidfish/DroidFish.java
@@ -104,13 +104,11 @@ import android.preference.PreferenceManager;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.widget.DrawerLayout;
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.TextUtils;
-import android.text.method.LinkMovementMethod;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
@@ -139,7 +137,6 @@ import android.widget.ImageView.ScaleType;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
-import android.widget.TextView.BufferType;
import android.widget.Toast;
@SuppressLint("ClickableViewAccessibility")
@@ -190,7 +187,7 @@ public class DroidFish extends Activity implements GUIInterface {
private TextView status;
private ScrollView moveListScroll;
- private TextView moveList;
+ private MoveListView moveList;
private TextView thinking;
private ImageButton custom1Button, custom2Button, custom3Button;
private ImageButton modeButton, undoButton, redoButton;
@@ -242,7 +239,6 @@ public class DroidFish extends Activity implements GUIInterface {
private boolean useWakeLock = false;
private Typeface figNotation;
- private Typeface defaultMoveListTypeFace;
private Typeface defaultThinkingListTypeFace;
@@ -667,14 +663,12 @@ public class DroidFish extends Activity implements GUIInterface {
status = (TextView)findViewById(R.id.status);
moveListScroll = (ScrollView)findViewById(R.id.scrollView);
- moveList = (TextView)findViewById(R.id.moveList);
- defaultMoveListTypeFace = moveList.getTypeface();
+ moveList = (MoveListView)findViewById(R.id.moveList);
thinking = (TextView)findViewById(R.id.thinking);
defaultThinkingListTypeFace = thinking.getTypeface();
status.setFocusable(false);
moveListScroll.setFocusable(false);
moveList.setFocusable(false);
- moveList.setMovementMethod(LinkMovementMethod.getInstance());
thinking.setFocusable(false);
initDrawers();
@@ -1029,8 +1023,6 @@ public class DroidFish extends Activity implements GUIInterface {
if (config.orientation == Configuration.ORIENTATION_PORTRAIT)
statusFontSize = Math.min(statusFontSize, 16);
status.setTextSize(statusFontSize);
- moveList.setTextSize(fontSize);
- thinking.setTextSize(fontSize);
soundEnabled = settings.getBoolean("soundEnabled", false);
vibrateEnabled = settings.getBoolean("vibrateEnabled", false);
animateMoves = settings.getBoolean("animateMoves", true);
@@ -1114,13 +1106,13 @@ public class DroidFish extends Activity implements GUIInterface {
if (displayAsFigures) {
// increase the font cause it has different kerning and looks small
float increaseFontSize = fontSize * 1.1f;
- moveList.setTypeface(figNotation);
- moveList.setTextSize(increaseFontSize);
+ moveList.setTypeface(figNotation, increaseFontSize);
thinking.setTypeface(figNotation);
thinking.setTextSize(increaseFontSize);
} else {
- moveList.setTypeface(defaultMoveListTypeFace);
+ moveList.setTypeface(null, fontSize);
thinking.setTypeface(defaultThinkingListTypeFace);
+ thinking.setTextSize(fontSize);
}
}
@@ -1717,12 +1709,11 @@ public class DroidFish extends Activity implements GUIInterface {
@Override
public void moveListUpdated() {
- moveList.setText(gameTextListener.getSpannableData(), BufferType.SPANNABLE);
- Layout layout = moveList.getLayout();
- if (layout != null) {
- int currPos = gameTextListener.getCurrPos();
- int line = layout.getLineForOffset(currPos);
- int y = (int) ((line - 1.5) * moveList.getLineHeight());
+ moveList.setText(gameTextListener.getText());
+ int currPos = gameTextListener.getCurrPos();
+ int line = moveList.getLineForOffset(currPos);
+ if (line >= 0) {
+ int y = (line - 1) * moveList.getLineHeight();
moveListScroll.scrollTo(0, y);
}
}
@@ -3562,7 +3553,7 @@ public class DroidFish extends Activity implements GUIInterface {
this.options = options;
}
- public final SpannableStringBuilder getSpannableData() {
+ public final CharSequence getText() {
return sb;
}
public final int getCurrPos() {
@@ -3722,7 +3713,7 @@ public class DroidFish extends Activity implements GUIInterface {
@Override
public void clear() {
- sb.clear();
+ sb = new SpannableStringBuilder();
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
new file mode 100644
index 0000000..ff556bf
--- /dev/null
+++ b/DroidFish/src/org/petero/droidfish/MoveListView.java
@@ -0,0 +1,191 @@
+/*
+ DroidFish - An Android chess program.
+ Copyright (C) 2015 Peter Ă–sterlund, peterosterlund2@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+package org.petero.droidfish;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Canvas;
+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;
+import android.view.View;
+
+/** Custom view for displaying move list.
+ * This is much faster than using a TextView. */
+public class MoveListView extends View {
+ private CharSequence text = null;
+ private Layout layout = null;
+ private int layoutWidth = -1;
+ private TextPaint textPaint;
+ private Typeface defaultTypeface;
+
+ /** Constructor. */
+ public MoveListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ textPaint.density = getResources().getDisplayMetrics().density;
+ defaultTypeface = Typeface.create("monospace", Typeface.NORMAL);
+ textPaint.setTypeface(defaultTypeface);
+ }
+
+ /** Set text to display. */
+ public void setText(CharSequence text) {
+ if (text != this.text) {
+ this.text = text;
+ createLayout(getWidth());
+ requestLayout();
+ }
+ invalidate();
+ }
+
+ /** Set typeface and text size. If tf is null the default typeface is used. */
+ public void setTypeface(Typeface tf, float size) {
+ if (tf == null)
+ tf = defaultTypeface;
+ boolean modified = false;
+ if (tf != textPaint.getTypeface()) {
+ textPaint.setTypeface(tf);
+ modified = true;
+ }
+ DisplayMetrics metric = getContext().getResources().getDisplayMetrics();
+ size *= metric.scaledDensity;
+ if (size != textPaint.getTextSize()) {
+ textPaint.setTextSize(size);
+ modified = true;
+ }
+ if (modified) {
+ createLayout(getWidth());
+ requestLayout();
+ invalidate();
+ }
+ }
+
+ public void setTextColor(int color) {
+ if (color != textPaint.getColor()) {
+ textPaint.setColor(color);
+ invalidate();
+ }
+ }
+
+ /** Get line number corresponding to a character offset,
+ * or -1 if layout has not been created yet. */
+ public int getLineForOffset(int currPos) {
+ if (layout == null)
+ return -1;
+ return layout.getLineForOffset(currPos);
+ }
+
+ /** Get line height in pixels. */
+ public int getLineHeight() {
+ return textPaint.getFontMetricsInt(null);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ int widthMeasure = MeasureSpec.getSize(widthMeasureSpec);
+ int heightMeasure = MeasureSpec.getSize(heightMeasureSpec);
+
+ int width = getMeasuredWidth();
+ switch (MeasureSpec.getMode(widthMeasureSpec)) {
+ case MeasureSpec.UNSPECIFIED:
+ break;
+ case MeasureSpec.EXACTLY:
+ width = widthMeasure;
+ break;
+ case MeasureSpec.AT_MOST:
+ width = Math.min(width, widthMeasure);
+ break;
+ }
+
+ if (width != layoutWidth)
+ createLayout(width);
+
+ int height = 0;
+ if (layout != null)
+ height = layout.getLineCount() * getLineHeight();
+ switch (MeasureSpec.getMode(heightMeasureSpec)) {
+ case MeasureSpec.UNSPECIFIED:
+ break;
+ case MeasureSpec.EXACTLY:
+ height = heightMeasure;
+ break;
+ case MeasureSpec.AT_MOST:
+ height = Math.min(height, heightMeasure);
+ break;
+ }
+
+ setMeasuredDimension(width, height);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (layout != null) {
+ canvas.save();
+ canvas.translate(getPaddingLeft(), getPaddingTop());
+ layout.draw(canvas);
+ canvas.restore();
+ }
+ }
+
+ @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;
+ 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);
+ return true;
+ }
+ }
+ return ret;
+ }
+
+ /** Create a StaticLayout corresponding to the current text. */
+ private void createLayout(int width) {
+ if (width <= 0)
+ return;
+ if (text == null) {
+ layout = null;
+ layoutWidth = -1;
+ } else {
+ layout = new StaticLayout(text, textPaint, width,
+ Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true);
+ layoutWidth = width;
+ }
+ }
+}
diff --git a/DroidFish/src/org/petero/droidfish/Util.java b/DroidFish/src/org/petero/droidfish/Util.java
index d4f25c3..6c26f69 100644
--- a/DroidFish/src/org/petero/droidfish/Util.java
+++ b/DroidFish/src/org/petero/droidfish/Util.java
@@ -121,7 +121,7 @@ public final class Util {
final int bg = ColorTheme.instance().getColor(ColorTheme.GENERAL_BACKGROUND);
Object tag = v.getTag();
final boolean excludedItems = v instanceof Button ||
- ((v instanceof EditText) && !"moveList".equals(tag)) ||
+ ((v instanceof EditText) && !(v instanceof MoveListView)) ||
v instanceof ImageButton ||
"title".equals(tag);
if (!excludedItems) {
@@ -140,6 +140,9 @@ public final class Util {
} else if (!excludedItems && (v instanceof TextView)) {
int fg = ColorTheme.instance().getColor(ColorTheme.FONT_FOREGROUND);
((TextView) v).setTextColor(fg);
+ } else if (!excludedItems && (v instanceof MoveListView)) {
+ int fg = ColorTheme.instance().getColor(ColorTheme.FONT_FOREGROUND);
+ ((MoveListView) v).setTextColor(fg);
}
}
}