diff --git a/DroidFishApp/src/main/java/org/petero/droidfish/ChessBoardPlayListener.java b/DroidFishApp/src/main/java/org/petero/droidfish/ChessBoardPlayListener.java
new file mode 100644
index 0000000..b5c53d3
--- /dev/null
+++ b/DroidFishApp/src/main/java/org/petero/droidfish/ChessBoardPlayListener.java
@@ -0,0 +1,196 @@
+/*
+ DroidFish - An Android chess program.
+ Copyright (C) 2020 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.os.Handler;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+import org.petero.droidfish.gamelogic.DroidChessController;
+import org.petero.droidfish.gamelogic.Move;
+import org.petero.droidfish.view.ChessBoard;
+
+public class ChessBoardPlayListener implements View.OnTouchListener,
+ ChessBoard.OnTrackballListener {
+ private DroidFish df;
+ private ChessBoardPlay cb;
+
+ private boolean pending = false;
+ private boolean pendingClick = false;
+ private int sq0 = -1;
+ private float scrollX = 0;
+ private float scrollY = 0;
+ private float prevX = 0;
+ private float prevY = 0;
+ private Handler handler = new Handler();
+ private Runnable runnable = new Runnable() {
+ public void run() {
+ pending = false;
+ handler.removeCallbacks(runnable);
+ df.reShowDialog(DroidFish.BOARD_MENU_DIALOG);
+ }
+ };
+
+ ChessBoardPlayListener(DroidFish df, ChessBoardPlay cb) {
+ this.df = df;
+ this.cb = cb;
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ int action = event.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ handler.postDelayed(runnable, ViewConfiguration.getLongPressTimeout());
+ pending = true;
+ pendingClick = true;
+ sq0 = cb.eventToSquare(event);
+ scrollX = 0;
+ scrollY = 0;
+ prevX = event.getX();
+ prevY = event.getY();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (pending) {
+ int sq = cb.eventToSquare(event);
+ if (sq != sq0) {
+ handler.removeCallbacks(runnable);
+ pendingClick = false;
+ }
+ float currX = event.getX();
+ float currY = event.getY();
+ if (onScroll(currX - prevX, currY - prevY)) {
+ handler.removeCallbacks(runnable);
+ pendingClick = false;
+ }
+ prevX = currX;
+ prevY = currY;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (pending) {
+ pending = false;
+ handler.removeCallbacks(runnable);
+ if (!pendingClick)
+ break;
+ int sq = cb.eventToSquare(event);
+ if (sq == sq0) {
+ if (df.ctrl.humansTurn()) {
+ Move m = cb.mousePressed(sq);
+ if (m != null) {
+ df.setAutoMode(DroidFish.AutoMode.OFF);
+ df.ctrl.makeHumanMove(m);
+ }
+ df.setEgtbHints(cb.getSelectedSquare());
+ }
+ }
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ pending = false;
+ handler.removeCallbacks(runnable);
+ break;
+ }
+ return true;
+ }
+
+ private boolean onScroll(float distanceX, float distanceY) {
+ if (df.invertScrollDirection) {
+ distanceX = -distanceX;
+ distanceY = -distanceY;
+ }
+ if ((df.scrollSensitivity > 0) && (cb.sqSize > 0)) {
+ scrollX += distanceX;
+ scrollY += distanceY;
+ final float scrollUnit = cb.sqSize * df.scrollSensitivity;
+ if (Math.abs(scrollX) >= Math.abs(scrollY)) {
+ // Undo/redo
+ int nRedo = 0, nUndo = 0;
+ while (scrollX > scrollUnit) {
+ nRedo++;
+ scrollX -= scrollUnit;
+ }
+ while (scrollX < -scrollUnit) {
+ nUndo++;
+ scrollX += scrollUnit;
+ }
+ if (nUndo + nRedo > 0) {
+ scrollY = 0;
+ df.setAutoMode(DroidFish.AutoMode.OFF);
+ }
+ if (nRedo + nUndo > 1) {
+ boolean analysis = df.gameMode.analysisMode();
+ boolean human = df.gameMode.playerWhite() || df.gameMode.playerBlack();
+ if (analysis || !human)
+ df.ctrl.setGameMode(new GameMode(GameMode.TWO_PLAYERS));
+ }
+ if (df.scrollGames) {
+ if (nRedo > 0) {
+ UIAction nextGame = df.actionFactory.getAction("nextGame");
+ if (nextGame.enabled())
+ for (int i = 0; i < nRedo; i++)
+ nextGame.run();
+ }
+ if (nUndo > 0) {
+ UIAction prevGame = df.actionFactory.getAction("prevGame");
+ if (prevGame.enabled())
+ for (int i = 0; i < nUndo; i++)
+ prevGame.run();
+ }
+ } else {
+ for (int i = 0; i < nRedo; i++) df.ctrl.redoMove();
+ for (int i = 0; i < nUndo; i++) df.ctrl.undoMove();
+ }
+ df.ctrl.setGameMode(df.gameMode);
+ return nRedo + nUndo > 0;
+ } else {
+ // Next/previous variation
+ int varDelta = 0;
+ while (scrollY > scrollUnit) {
+ varDelta++;
+ scrollY -= scrollUnit;
+ }
+ while (scrollY < -scrollUnit) {
+ varDelta--;
+ scrollY += scrollUnit;
+ }
+ if (varDelta != 0) {
+ scrollX = 0;
+ df.setAutoMode(DroidFish.AutoMode.OFF);
+ df.ctrl.changeVariation(varDelta);
+ }
+ return varDelta != 0;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void onTrackballEvent(MotionEvent event) {
+ if (df.ctrl.humansTurn()) {
+ Move m = cb.handleTrackballEvent(event);
+ if (m != null) {
+ df.setAutoMode(DroidFish.AutoMode.OFF);
+ df.ctrl.makeHumanMove(m);
+ }
+ df.setEgtbHints(cb.getSelectedSquare());
+ }
+ }
+}
diff --git a/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java b/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java
index 509623d..7d1d767 100644
--- a/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java
+++ b/DroidFishApp/src/main/java/org/petero/droidfish/DroidFish.java
@@ -60,7 +60,6 @@ import org.petero.droidfish.gamelogic.GameTree.Node;
import org.petero.droidfish.gamelogic.TimeControlData;
import org.petero.droidfish.tb.Probe;
import org.petero.droidfish.tb.ProbeResult;
-import org.petero.droidfish.view.ChessBoard;
import org.petero.droidfish.view.MoveListView;
import org.petero.droidfish.view.ChessBoard.SquareDecoration;
@@ -119,7 +118,6 @@ import android.preference.PreferenceManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
-import androidx.core.view.MotionEventCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.text.Editable;
import android.text.Html;
@@ -128,7 +126,6 @@ import android.text.TextWatcher;
import android.util.Pair;
import android.util.TypedValue;
import android.view.Gravity;
-import android.view.ViewConfiguration;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
@@ -173,7 +170,7 @@ public class DroidFish extends Activity
// FIXME!!! Use two engines in engine/engine games
private ChessBoardPlay cb;
- private DroidChessController ctrl = null;
+ DroidChessController ctrl = null;
private boolean mShowThinking;
private boolean mShowStats;
private boolean fullPVLines;
@@ -182,7 +179,7 @@ public class DroidFish extends Activity
private boolean mShowBookHints;
private int mEcoHints;
private int maxNumArrows;
- private GameMode gameMode;
+ GameMode gameMode;
private boolean mPonderMode;
private int timeControl;
private int movesPerSession;
@@ -214,9 +211,9 @@ public class DroidFish extends Activity
private SharedPreferences settings;
private ObjectCache cache;
- private float scrollSensitivity;
- private boolean invertScrollDirection;
- private boolean scrollGames;
+ float scrollSensitivity;
+ boolean invertScrollDirection;
+ boolean scrollGames;
private boolean autoScrollMoveList;
private boolean leftHanded;
@@ -274,7 +271,7 @@ public class DroidFish extends Activity
/** Defines all configurable button actions. */
- private ActionFactory actionFactory = new ActionFactory() {
+ ActionFactory actionFactory = new ActionFactory() {
private HashMap actions;
private void addAction(UIAction a) {
@@ -976,164 +973,9 @@ public class DroidFish extends Activity
cb.setClickable(true);
cb.setPgnOptions(pgnOptions);
- cb.setOnTouchListener(new OnTouchListener() {
- private boolean pending = false;
- private boolean pendingClick = false;
- private int sq0 = -1;
- private float scrollX = 0;
- private float scrollY = 0;
- private float prevX = 0;
- private float prevY = 0;
- private Handler handler = new Handler();
- private Runnable runnable = new Runnable() {
- public void run() {
- pending = false;
- handler.removeCallbacks(runnable);
- reShowDialog(BOARD_MENU_DIALOG);
- }
- };
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- int action = MotionEventCompat.getActionMasked(event);
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- handler.postDelayed(runnable, ViewConfiguration.getLongPressTimeout());
- pending = true;
- pendingClick = true;
- sq0 = cb.eventToSquare(event);
- scrollX = 0;
- scrollY = 0;
- prevX = event.getX();
- prevY = event.getY();
- break;
- case MotionEvent.ACTION_MOVE:
- if (pending) {
- int sq = cb.eventToSquare(event);
- if (sq != sq0) {
- handler.removeCallbacks(runnable);
- pendingClick = false;
- }
- float currX = event.getX();
- float currY = event.getY();
- if (onScroll(currX - prevX, currY - prevY)) {
- handler.removeCallbacks(runnable);
- pendingClick = false;
- }
- prevX = currX;
- prevY = currY;
- }
- break;
- case MotionEvent.ACTION_UP:
- if (pending) {
- pending = false;
- handler.removeCallbacks(runnable);
- if (!pendingClick)
- break;
- int sq = cb.eventToSquare(event);
- if (sq == sq0) {
- if (ctrl.humansTurn()) {
- Move m = cb.mousePressed(sq);
- if (m != null) {
- setAutoMode(AutoMode.OFF);
- ctrl.makeHumanMove(m);
- }
- setEgtbHints(cb.getSelectedSquare());
- }
- }
- }
- break;
- case MotionEvent.ACTION_CANCEL:
- pending = false;
- handler.removeCallbacks(runnable);
- break;
- }
- return true;
- }
-
- private boolean onScroll(float distanceX, float distanceY) {
- if (invertScrollDirection) {
- distanceX = -distanceX;
- distanceY = -distanceY;
- }
- if ((scrollSensitivity > 0) && (cb.sqSize > 0)) {
- scrollX += distanceX;
- scrollY += distanceY;
- final float scrollUnit = cb.sqSize * scrollSensitivity;
- if (Math.abs(scrollX) >= Math.abs(scrollY)) {
- // Undo/redo
- int nRedo = 0, nUndo = 0;
- while (scrollX > scrollUnit) {
- nRedo++;
- scrollX -= scrollUnit;
- }
- while (scrollX < -scrollUnit) {
- nUndo++;
- scrollX += scrollUnit;
- }
- if (nUndo + nRedo > 0) {
- scrollY = 0;
- setAutoMode(AutoMode.OFF);
- }
- if (nRedo + nUndo > 1) {
- boolean analysis = gameMode.analysisMode();
- boolean human = gameMode.playerWhite() || gameMode.playerBlack();
- if (analysis || !human)
- ctrl.setGameMode(new GameMode(GameMode.TWO_PLAYERS));
- }
- if (scrollGames) {
- if (nRedo > 0) {
- UIAction nextGame = actionFactory.getAction("nextGame");
- if (nextGame.enabled())
- for (int i = 0; i < nRedo; i++)
- nextGame.run();
- }
- if (nUndo > 0) {
- UIAction prevGame = actionFactory.getAction("prevGame");
- if (prevGame.enabled())
- for (int i = 0; i < nUndo; i++)
- prevGame.run();
- }
- } else {
- for (int i = 0; i < nRedo; i++) ctrl.redoMove();
- for (int i = 0; i < nUndo; i++) ctrl.undoMove();
- }
- ctrl.setGameMode(gameMode);
- return nRedo + nUndo > 0;
- } else {
- // Next/previous variation
- int varDelta = 0;
- while (scrollY > scrollUnit) {
- varDelta++;
- scrollY -= scrollUnit;
- }
- while (scrollY < -scrollUnit) {
- varDelta--;
- scrollY += scrollUnit;
- }
- if (varDelta != 0) {
- scrollX = 0;
- setAutoMode(AutoMode.OFF);
- ctrl.changeVariation(varDelta);
- }
- return varDelta != 0;
- }
- }
- return false;
- }
- });
- cb.setOnTrackballListener(new ChessBoard.OnTrackballListener() {
- public void onTrackballEvent(MotionEvent event) {
- if (ctrl.humansTurn()) {
- Move m = cb.handleTrackballEvent(event);
- if (m != null) {
- setAutoMode(AutoMode.OFF);
- ctrl.makeHumanMove(m);
- }
- setEgtbHints(cb.getSelectedSquare());
- }
- }
- });
+ ChessBoardPlayListener cbpListener = new ChessBoardPlayListener(this, cb);
+ cb.setOnTouchListener(cbpListener);
+ cb.setOnTrackballListener(cbpListener);
moveList.setOnLongClickListener(v -> {
reShowDialog(MOVELIST_MENU_DIALOG);
@@ -1579,7 +1421,7 @@ public class DroidFish extends Activity
engineOptions.networkID = id;
}
- private void setEgtbHints(int sq) {
+ void setEgtbHints(int sq) {
if (!engineOptions.hints || (sq < 0)) {
cb.setSquareDecorations(null);
return;
@@ -2164,7 +2006,7 @@ public class DroidFish extends Activity
}
static private final int PROMOTE_DIALOG = 0;
- static private final int BOARD_MENU_DIALOG = 1;
+ static final int BOARD_MENU_DIALOG = 1;
static private final int ABOUT_DIALOG = 2;
static private final int SELECT_BOOK_DIALOG = 4;
static private final int SELECT_ENGINE_DIALOG = 5;
@@ -2192,7 +2034,7 @@ public class DroidFish extends Activity
static private final int SELECT_FEN_FILE_DIALOG = 27;
/** Remove and show a dialog. */
- private void reShowDialog(int id) {
+ void reShowDialog(int id) {
removeDialog(id);
showDialog(id);
}
diff --git a/DroidFishApp/src/main/java/org/petero/droidfish/activities/EditBoard.java b/DroidFishApp/src/main/java/org/petero/droidfish/activities/EditBoard.java
index f1df5d5..f4a3399 100644
--- a/DroidFishApp/src/main/java/org/petero/droidfish/activities/EditBoard.java
+++ b/DroidFishApp/src/main/java/org/petero/droidfish/activities/EditBoard.java
@@ -228,6 +228,7 @@ public class EditBoard extends Activity {
}
});
cb.setOnTrackballListener(new ChessBoard.OnTrackballListener() {
+ @Override
public void onTrackballEvent(MotionEvent event) {
Move m = cb.handleTrackballEvent(event);
if (m != null)
diff --git a/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java b/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java
index dd186c5..80517af 100644
--- a/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java
+++ b/DroidFishApp/src/main/java/org/petero/droidfish/view/ChessBoard.java
@@ -562,8 +562,8 @@ public abstract class ChessBoard extends View {
protected abstract Move mousePressed(int sq);
- public static class OnTrackballListener {
- public void onTrackballEvent(MotionEvent event) { }
+ public interface OnTrackballListener {
+ void onTrackballEvent(MotionEvent event);
}
private OnTrackballListener otbl = null;
public final void setOnTrackballListener(OnTrackballListener onTrackballListener) {