Skip to content

Commit 2c3d05c

Browse files
authored
Merge pull request #234 from dronov-dmitry/two-finger-pan
Add two-finger pan to move the text in all directions
2 parents fdc2ec6 + 0ca415c commit 2c3d05c

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

‎app/src/main/java/com/maxistar/textpad/activities/EditorActivity.java‎

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
import android.print.PrintManager;
3939
import android.text.Editable;
4040
import android.text.InputType;
41+
import android.text.Layout;
4142
import android.text.Spanned;
4243
import android.text.TextWatcher;
4344
import android.text.style.BackgroundColorSpan;
4445
import android.view.KeyEvent;
46+
import android.view.MotionEvent;
4547
import android.view.Menu;
4648
import android.view.MenuItem;
4749
import android.view.WindowInsets;
@@ -214,6 +216,7 @@ public void onCreate(Bundle savedInstanceState) {
214216
}
215217
mText = this.findViewById(R.id.editText1);
216218
mText.setBackgroundResource(android.R.color.transparent);
219+
mText.setOnTouchListener(new TwoFingerPanTouchListener());
217220
if (!settingsService.isAutoWrapping()) {
218221
disableEditorAutowrapping();
219222
}
@@ -1960,6 +1963,105 @@ protected void showToast(String toast_str) {
19601963
toast.show();
19611964
}
19621965

1966+
// TwoFingerPanTouchListener
1967+
private class TwoFingerPanTouchListener implements View.OnTouchListener {
1968+
1969+
private boolean panningActive = false;
1970+
private float lastFocalX;
1971+
private float lastFocalY;
1972+
1973+
@Override
1974+
public boolean onTouch(View view, MotionEvent event) {
1975+
switch (event.getActionMasked()) {
1976+
case MotionEvent.ACTION_DOWN:
1977+
panningActive = false;
1978+
return false;
1979+
case MotionEvent.ACTION_POINTER_DOWN:
1980+
if (event.getPointerCount() == 2) {
1981+
panningActive = true;
1982+
view.getParent().requestDisallowInterceptTouchEvent(true);
1983+
lastFocalX = focalX(event);
1984+
lastFocalY = focalY(event);
1985+
}
1986+
return panningActive;
1987+
case MotionEvent.ACTION_MOVE:
1988+
if (!panningActive) {
1989+
return false;
1990+
}
1991+
float focalX = focalX(event);
1992+
float focalY = focalY(event);
1993+
panContent(
1994+
Math.round(focalX - lastFocalX),
1995+
Math.round(focalY - lastFocalY)
1996+
);
1997+
lastFocalX = focalX;
1998+
lastFocalY = focalY;
1999+
return true;
2000+
case MotionEvent.ACTION_POINTER_UP:
2001+
if (panningActive) {
2002+
view.getParent().requestDisallowInterceptTouchEvent(false);
2003+
}
2004+
return panningActive;
2005+
case MotionEvent.ACTION_UP:
2006+
case MotionEvent.ACTION_CANCEL:
2007+
boolean wasPanning = panningActive;
2008+
panningActive = false;
2009+
view.getParent().requestDisallowInterceptTouchEvent(false);
2010+
return wasPanning;
2011+
default:
2012+
return panningActive;
2013+
}
2014+
}
2015+
2016+
private float focalX(MotionEvent event) {
2017+
float sum = 0;
2018+
for (int i = 0; i < event.getPointerCount(); i++) {
2019+
sum += event.getX(i);
2020+
}
2021+
return sum / event.getPointerCount();
2022+
}
2023+
2024+
private float focalY(MotionEvent event) {
2025+
float sum = 0;
2026+
for (int i = 0; i < event.getPointerCount(); i++) {
2027+
sum += event.getY(i);
2028+
}
2029+
return sum / event.getPointerCount();
2030+
}
2031+
}
2032+
2033+
private void panContent(int deltaX, int deltaY) {
2034+
Layout layout = mText.getLayout();
2035+
int maxX = layout == null ? 0 :
2036+
layout.getWidth() + mText.getTotalPaddingLeft() + mText.getTotalPaddingRight()
2037+
- mText.getWidth();
2038+
int newX = clampScroll(mText.getScrollX() - deltaX, maxX);
2039+
2040+
if (simpleScrolling()) {
2041+
int maxY = layout == null ? 0 :
2042+
layout.getHeight() + mText.getTotalPaddingTop() + mText.getTotalPaddingBottom()
2043+
- mText.getHeight();
2044+
int newY = clampScroll(mText.getScrollY() - deltaY, maxY);
2045+
mText.scrollTo(newX, newY);
2046+
return;
2047+
}
2048+
2049+
if (scrollView != null) {
2050+
scrollView.scrollBy(0, -deltaY);
2051+
}
2052+
mText.scrollTo(newX, mText.getScrollY());
2053+
}
2054+
2055+
private int clampScroll(int value, int max) {
2056+
if (value < 0) {
2057+
return 0;
2058+
}
2059+
if (max > 0 && value > max) {
2060+
return max;
2061+
}
2062+
return value;
2063+
}
2064+
19632065
// QueryTextListener
19642066
private class QueryTextListener
19652067
implements SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener {

0 commit comments

Comments
 (0)