From 17f70f5e62c4c5bee31d418bb4c94fd356e36cec Mon Sep 17 00:00:00 2001 From: Ryan Hansberry Date: Wed, 7 Oct 2015 11:20:21 -0700 Subject: Move old copying logic to TerminalView. Add comments to TerminalView. --- .../main/java/org/connectbot/ConsoleActivity.java | 95 +------------ app/src/main/java/org/connectbot/TerminalView.java | 150 ++++++++++++++++----- 2 files changed, 120 insertions(+), 125 deletions(-) (limited to 'app/src/main/java/org/connectbot') diff --git a/app/src/main/java/org/connectbot/ConsoleActivity.java b/app/src/main/java/org/connectbot/ConsoleActivity.java index ba97f45..15b5e63 100644 --- a/app/src/main/java/org/connectbot/ConsoleActivity.java +++ b/app/src/main/java/org/connectbot/ConsoleActivity.java @@ -137,9 +137,6 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne private MenuItem disconnect, copy, paste, portForward, resize, urlscan; - protected TerminalBridge copySource = null; - private int lastTouchRow, lastTouchCol; - private boolean forcedOrientation; private Handler handler = new Handler(); @@ -669,78 +666,6 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne } } }); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - pager.setOnTouchListener(new OnTouchListener() { - public boolean onTouch(View v, MotionEvent event) { - TerminalBridge bridge = adapter.getCurrentTerminalView().bridge; - - boolean isCopyingInProgress = - (copySource != null && copySource.isSelectingForCopy()); - - // when copying, highlight the area - if (isCopyingInProgress) { - SelectionArea area = copySource.getSelectionArea(); - int row = (int) Math.floor(event.getY() / bridge.charHeight); - int col = (int) Math.floor(event.getX() / bridge.charWidth); - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - // recording starting area - if (area.isSelectingOrigin()) { - area.setRow(row); - area.setColumn(col); - lastTouchRow = row; - lastTouchCol = col; - copySource.redraw(); - } - return true; - case MotionEvent.ACTION_MOVE: - /* ignore when user hasn't moved since last time so - * we can fine-tune with directional pad - */ - if (row == lastTouchRow && col == lastTouchCol) - return true; - - // if the user moves, start the selection for other corner - area.finishSelectingOrigin(); - - // update selected area - area.setRow(row); - area.setColumn(col); - lastTouchRow = row; - lastTouchCol = col; - copySource.redraw(); - return true; - case MotionEvent.ACTION_UP: - /* If they didn't move their finger, maybe they meant to - * select the rest of the text with the directional pad. - */ - if (area.getLeft() == area.getRight() && - area.getTop() == area.getBottom()) { - return true; - } - - // copy selected area to clipboard - String copiedText = area.copyFrom(copySource.buffer); - - clipboard.setText(copiedText); - Toast.makeText(ConsoleActivity.this, getString(R.string.console_copy_done, copiedText.length()), Toast.LENGTH_LONG).show(); - // fall through to clear state - - case MotionEvent.ACTION_CANCEL: - // make sure we clear any highlighted area - area.reset(); - copySource.setSelectingForCopy(false); - copySource.redraw(); - return true; - } - } - - return true; - } - }); - } } /** @@ -843,7 +768,7 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne copy.setEnabled(activeTerminal); copy.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { - startCopyMode(); + adapter.getCurrentTerminalView().startPreHoneycombCopyMode(); Toast.makeText(ConsoleActivity.this, getString(R.string.console_copy_start), Toast.LENGTH_LONG).show(); return true; } @@ -1110,24 +1035,6 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne super.onSaveInstanceState(savedInstanceState); } - /** - * Only intended for pre-Honeycomb devices. - */ - private void startCopyMode() { - // mark as copying and reset any previous bounds - TerminalView terminalView = (TerminalView) adapter.getCurrentTerminalView(); - copySource = terminalView.bridge; - - SelectionArea area = copySource.getSelectionArea(); - area.reset(); - area.setBounds(copySource.buffer.getColumns(), copySource.buffer.getRows()); - - copySource.setSelectingForCopy(true); - - // Make sure we show the initial selection - copySource.redraw(); - } - /** * Save the currently shown {@link TerminalView} as the default. This is * saved back down into {@link TerminalManager} where we can read it again diff --git a/app/src/main/java/org/connectbot/TerminalView.java b/app/src/main/java/org/connectbot/TerminalView.java index 42414b9..914b466 100644 --- a/app/src/main/java/org/connectbot/TerminalView.java +++ b/app/src/main/java/org/connectbot/TerminalView.java @@ -70,6 +70,10 @@ import de.mud.terminal.vt320; * {@link android.app.Activity}. Handles drawing bitmap updates and passing keystrokes down * to terminal. * + * On Honeycomb devices and above (>= APIv11), a TextView with transparent text (which is identical + * to the bitmap) is drawn above the bitmap. This TextView exists to allow the user to + * select and copy text. + * * @author jsharkey */ public class TerminalView extends TextView implements FontSizeChangedListener { @@ -84,6 +88,9 @@ public class TerminalView extends TextView implements FontSizeChangedListener { private ActionMode selectionActionMode = null; private String currentSelection = ""; + // These are only used for pre-Honeycomb copying. + private int lastTouchedRow, lastTouchedCol; + private final Paint paint; private final Paint cursorPaint; private final Paint cursorStrokePaint; @@ -178,43 +185,43 @@ public class TerminalView extends TextView implements FontSizeChangedListener { setTypeface(Typeface.MONOSPACE); onFontSizeChanged(bridge.getFontSize()); + // Allow selection of and copying text for Honeycomb and above devices. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setTextIsSelectable(true); - setCustomSelectionActionModeCallback(new TextSelectionActionModeCallback()); + } - gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { - private TerminalBridge bridge = TerminalView.this.bridge; - private float totalY = 0; - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - // if releasing then reset total scroll - if (e2.getAction() == MotionEvent.ACTION_UP) { - totalY = 0; - } + gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { + private TerminalBridge bridge = TerminalView.this.bridge; + private float totalY = 0; - totalY += distanceY; - final int moved = (int) (totalY / bridge.charHeight); + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + // if releasing then reset total scroll + if (e2.getAction() == MotionEvent.ACTION_UP) { + totalY = 0; + } - if (moved != 0) { - int base = bridge.buffer.getWindowBase(); - bridge.buffer.setWindowBase(base + moved); - totalY = 0; + totalY += distanceY; + final int moved = (int) (totalY / bridge.charHeight); - refreshTextFromBuffer(); - } + if (moved != 0) { + int base = bridge.buffer.getWindowBase(); + bridge.buffer.setWindowBase(base + moved); + totalY = 0; - return true; + refreshTextFromBuffer(); } - @Override - public boolean onSingleTapConfirmed(MotionEvent e) { - viewPager.performClick(); - return super.onSingleTapConfirmed(e); - } - }); - } + return true; + } + + @Override + public boolean onSingleTapConfirmed(MotionEvent e) { + viewPager.performClick(); + return super.onSingleTapConfirmed(e); + } + }); } @TargetApi(11) @@ -253,10 +260,6 @@ public class TerminalView extends TextView implements FontSizeChangedListener { @Override public boolean onTouchEvent(MotionEvent event) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - return false; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && MotionEventCompat.getSource(event) == InputDevice.SOURCE_MOUSE) { if (onMouseEvent(event, bridge)) { @@ -267,6 +270,76 @@ public class TerminalView extends TextView implements FontSizeChangedListener { gestureDetector.onTouchEvent(event); } + // Old version of copying, only for pre-Honeycomb. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + // when copying, highlight the area + if (bridge.isSelectingForCopy()) { + SelectionArea area = bridge.getSelectionArea(); + int row = (int) Math.floor(event.getY() / bridge.charHeight); + int col = (int) Math.floor(event.getX() / bridge.charWidth); + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + // recording starting area + viewPager.setPagingEnabled(false); + if (area.isSelectingOrigin()) { + area.setRow(row); + area.setColumn(col); + lastTouchedRow = row; + lastTouchedCol = col; + bridge.redraw(); + } + return true; + case MotionEvent.ACTION_MOVE: + /* ignore when user hasn't moved since last time so + * we can fine-tune with directional pad + */ + if (row == lastTouchedRow && col == lastTouchedCol) + return true; + + // if the user moves, start the selection for other corner + area.finishSelectingOrigin(); + + // update selected area + area.setRow(row); + area.setColumn(col); + lastTouchedRow = row; + lastTouchedCol = col; + bridge.redraw(); + return true; + case MotionEvent.ACTION_UP: + /* If they didn't move their finger, maybe they meant to + * select the rest of the text with the directional pad. + */ + if (area.getLeft() == area.getRight() && + area.getTop() == area.getBottom()) { + return true; + } + + // copy selected area to clipboard + String copiedText = area.copyFrom(bridge.buffer); + + clipboard.setText(copiedText); + Toast.makeText( + context, + context.getString(R.string.console_copy_done, copiedText.length()), + Toast.LENGTH_LONG).show(); + + // fall through to clear state + + case MotionEvent.ACTION_CANCEL: + // make sure we clear any highlighted area + area.reset(); + bridge.setSelectingForCopy(false); + bridge.redraw(); + viewPager.setPagingEnabled(true); + return true; + } + } + + return true; + } + super.onTouchEvent(event); return true; @@ -485,6 +558,21 @@ public class TerminalView extends TextView implements FontSizeChangedListener { setText(buffer); } + /** + * Only intended for pre-Honeycomb devices. + */ + public void startPreHoneycombCopyMode() { + // mark as copying and reset any previous bounds + SelectionArea area = bridge.getSelectionArea(); + area.reset(); + area.setBounds(bridge.buffer.getColumns(), bridge.buffer.getRows()); + + bridge.setSelectingForCopy(true); + + // Make sure we show the initial selection + bridge.redraw(); + } + public void destroy() { // tell bridge to destroy its bitmap bridge.parentDestroyed(); -- cgit v1.2.3