aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/org/connectbot/ConsoleActivity.java
diff options
context:
space:
mode:
authorRyan Hansberry <rhansby@gmail.com>2015-10-02 17:50:01 -0700
committerRyan Hansberry <rhansby@gmail.com>2015-10-07 10:28:29 -0700
commitf93f415b77fd777bccbac6c73f2aecfe01464fb8 (patch)
tree15ccab6857479e6f8e654ba5e57d69a2e2f0cae2 /app/src/main/java/org/connectbot/ConsoleActivity.java
parentfde40fdcb62c764df90e889ae95e28b86ac5f746 (diff)
downloadconnectbot-f93f415b77fd777bccbac6c73f2aecfe01464fb8.tar.gz
connectbot-f93f415b77fd777bccbac6c73f2aecfe01464fb8.tar.bz2
connectbot-f93f415b77fd777bccbac6c73f2aecfe01464fb8.zip
Text selection now uses TextView. Pre-Honeycomb uses the same method as before.
Diffstat (limited to 'app/src/main/java/org/connectbot/ConsoleActivity.java')
-rw-r--r--app/src/main/java/org/connectbot/ConsoleActivity.java363
1 files changed, 83 insertions, 280 deletions
diff --git a/app/src/main/java/org/connectbot/ConsoleActivity.java b/app/src/main/java/org/connectbot/ConsoleActivity.java
index d628a07..e979b34 100644
--- a/app/src/main/java/org/connectbot/ConsoleActivity.java
+++ b/app/src/main/java/org/connectbot/ConsoleActivity.java
@@ -50,10 +50,9 @@ import android.os.IBinder;
import android.os.Message;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
-import android.support.v4.app.ActivityCompat;
import android.support.design.widget.TabLayout;
+import android.support.v4.app.ActivityCompat;
import android.support.v4.view.MenuItemCompat;
-import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
@@ -61,9 +60,6 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.ClipboardManager;
import android.util.Log;
-import android.view.ContextMenu;
-import android.view.GestureDetector;
-import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -74,7 +70,6 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
@@ -100,8 +95,6 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
protected static final int REQUEST_EDIT = 1;
- private static final int CLICK_TIME = 400;
- private static final float MAX_CLICK_DISTANCE = 25f;
private static final int KEYBOARD_DISPLAY_TIME = 3000;
private static final int KEYBOARD_REPEAT_INITIAL = 500;
private static final int KEYBOARD_REPEAT = 100;
@@ -140,7 +133,6 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
private Animation fade_out_delayed;
private Animation keyboard_fade_in, keyboard_fade_out;
- private float lastX, lastY;
private InputMethodManager inputManager;
@@ -498,8 +490,9 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
inflater = LayoutInflater.from(this);
toolbar = (Toolbar) findViewById(R.id.toolbar);
+
pager = (ViewPager) findViewById(R.id.console_flip);
- registerForContextMenu(pager);
+
pager.addOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
@Override
@@ -669,255 +662,81 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
if (tabs != null)
setupTabLayoutWithViewPager();
- // detect fling gestures to switch between terminals
- final GestureDetector detect = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
- private float totalY = 0;
-
- @Override
- public void onLongPress(MotionEvent e) {
- super.onLongPress(e);
- openContextMenu(pager);
- }
-
+ 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;
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-
- // if copying, then ignore
- if (copySource != null && copySource.isSelectingForCopy())
- return false;
-
- if (e1 == null || e2 == null)
- return false;
-
- // if releasing then reset total scroll
- if (e2.getAction() == MotionEvent.ACTION_UP) {
- totalY = 0;
- }
-
- // activate consider if within x tolerance
- int touchSlop = ViewConfiguration.get(ConsoleActivity.this).getScaledTouchSlop();
- if (Math.abs(e1.getX() - e2.getX()) < touchSlop * 4) {
-
- View view = adapter.getCurrentTerminalView();
- if (view == null) return false;
- TerminalView terminal = (TerminalView) view;
-
- // estimate how many rows we have scrolled through
- // accumulate distance that doesn't trigger immediate scroll
- totalY += distanceY;
- final int moved = (int) (totalY / terminal.bridge.charHeight);
-
- // consume as scrollback only if towards right half of screen
- if (e2.getX() > view.getWidth() / 2) {
- if (moved != 0) {
- int base = terminal.bridge.buffer.getWindowBase();
- terminal.bridge.buffer.setWindowBase(base + moved);
- totalY = 0;
- return true;
- }
- } else {
- // otherwise consume as pgup/pgdown for every 5 lines
- if (moved > 5) {
- ((vt320) terminal.bridge.buffer).keyPressed(vt320.KEY_PAGE_DOWN, ' ', 0);
- terminal.bridge.tryKeyVibrate();
- totalY = 0;
- return true;
- } else if (moved < -5) {
- ((vt320) terminal.bridge.buffer).keyPressed(vt320.KEY_PAGE_UP, ' ', 0);
- terminal.bridge.tryKeyVibrate();
- totalY = 0;
- return true;
- }
+ boolean isCopyingInProgress =
+ (copySource != null && copySource.isSelectingForCopy());
+ if (!isCopyingInProgress && keyboardGroup.getVisibility() == View.GONE) {
+ showEmulatedKeys(true);
}
- }
-
- return false;
- }
-
-
- });
-
- pager.setLongClickable(true);
- pager.setOnTouchListener(new OnTouchListener() {
-
- public boolean onTouch(View v, MotionEvent event) {
- TerminalBridge bridge = adapter.getCurrentTerminalView().bridge;
+ // 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);
- // Handle mouse-specific actions.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH &&
- MotionEventCompat.getSource(event) == InputDevice.SOURCE_MOUSE) {
- if (onMouseEvent(event, bridge)) {
- return true;
- }
- }
+ 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;
- // when copying, highlight the area
- if (copySource != null && copySource.isSelectingForCopy()) {
- SelectionArea area = copySource.getSelectionArea();
- int row = (int) Math.floor(event.getY() / bridge.charHeight);
- int col = (int) Math.floor(event.getX() / bridge.charWidth);
+ // if the user moves, start the selection for other corner
+ area.finishSelectingOrigin();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // recording starting area
- if (area.isSelectingOrigin()) {
+ // update selected area
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;
- }
- }
+ 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;
+ }
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- lastX = event.getX();
- lastY = event.getY();
- } else if (event.getAction() == MotionEvent.ACTION_UP
- && keyboardGroup.getVisibility() == View.GONE
- && event.getEventTime() - event.getDownTime() < CLICK_TIME
- && Math.abs(event.getX() - lastX) < MAX_CLICK_DISTANCE
- && Math.abs(event.getY() - lastY) < MAX_CLICK_DISTANCE) {
- showEmulatedKeys(true);
- }
+ // copy selected area to clipboard
+ String copiedText = area.copyFrom(copySource.buffer);
- // pass any touch events back to detector
- return detect.onTouchEvent(event);
- }
+ clipboard.setText(copiedText);
+ Toast.makeText(ConsoleActivity.this, getString(R.string.console_copy_done, copiedText.length()), Toast.LENGTH_LONG).show();
+ // fall through to clear state
- /**
- * @param event
- * @param bridge
- * @return True if the event is handled.
- */
- @TargetApi(14)
- private boolean onMouseEvent(MotionEvent event, TerminalBridge bridge) {
- int row = (int) Math.floor(event.getY() / bridge.charHeight);
- int col = (int) Math.floor(event.getX() / bridge.charWidth);
- int meta = event.getMetaState();
- boolean shiftOn = (meta & KeyEvent.META_SHIFT_ON) != 0;
- boolean mouseReport = ((vt320) bridge.buffer).isMouseReportEnabled();
-
- // MouseReport can be "defeated" using the shift key.
- if ((!mouseReport || shiftOn)) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- switch (event.getButtonState()) {
- case MotionEvent.BUTTON_PRIMARY:
- // Automatically start copy mode if using a mouse.
- startCopyMode();
- break;
- case MotionEvent.BUTTON_SECONDARY:
- openContextMenu(pager);
- return true;
- case MotionEvent.BUTTON_TERTIARY:
- // Middle click pastes.
- pasteIntoTerminal();
+ case MotionEvent.ACTION_CANCEL:
+ // make sure we clear any highlighted area
+ area.reset();
+ copySource.setSelectingForCopy(false);
+ copySource.redraw();
return true;
}
}
- } else if (event.getAction() == MotionEvent.ACTION_DOWN) {
- ((vt320) bridge.buffer).mousePressed(
- col, row, mouseEventToJavaModifiers(event));
- return true;
- } else if (event.getAction() == MotionEvent.ACTION_UP) {
- ((vt320) bridge.buffer).mouseReleased(col, row);
- return true;
- } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
- int buttonState = event.getButtonState();
- int button = (buttonState & MotionEvent.BUTTON_PRIMARY) != 0 ? 0 :
- (buttonState & MotionEvent.BUTTON_SECONDARY) != 0 ? 1 :
- (buttonState & MotionEvent.BUTTON_TERTIARY) != 0 ? 2 : 3;
- ((vt320) bridge.buffer).mouseMoved(
- button,
- col,
- row,
- (meta & KeyEvent.META_CTRL_ON) != 0,
- (meta & KeyEvent.META_SHIFT_ON) != 0,
- (meta & KeyEvent.META_META_ON) != 0);
+
return true;
}
-
- return false;
- }
-
- });
- }
-
- /**
- * Takes an android mouse event and produces a Java InputEvent modifiers int which can be
- * passed to vt320.
- * @param mouseEvent The {@link MotionEvent} which should be a mouse click or release.
- * @return A Java InputEvent modifier int. See
- * http://docs.oracle.com/javase/7/docs/api/java/awt/event/InputEvent.html
- */
- @TargetApi(14)
- private static int mouseEventToJavaModifiers(MotionEvent mouseEvent) {
- if (MotionEventCompat.getSource(mouseEvent) != InputDevice.SOURCE_MOUSE) return 0;
-
- int mods = 0;
-
- // See http://docs.oracle.com/javase/7/docs/api/constant-values.html
- int buttonState = mouseEvent.getButtonState();
- if ((buttonState & MotionEvent.BUTTON_PRIMARY) != 0)
- mods |= 16;
- if ((buttonState & MotionEvent.BUTTON_SECONDARY) != 0)
- mods |= 8;
- if ((buttonState & MotionEvent.BUTTON_TERTIARY) != 0)
- mods |= 4;
-
- // Note: Meta and Ctrl are intentionally swapped here to keep logic in vt320 simple.
- int meta = mouseEvent.getMetaState();
- if ((meta & KeyEvent.META_META_ON) != 0)
- mods |= 2;
- if ((meta & KeyEvent.META_SHIFT_ON) != 0)
- mods |= 1;
- if ((meta & KeyEvent.META_CTRL_ON) != 0)
- mods |= 4;
-
- return mods;
+ });
+ }
}
/**
@@ -1011,19 +830,21 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
}
});
- copy = menu.add(R.string.console_menu_copy);
- if (hardKeyboard)
- copy.setAlphabeticShortcut('c');
- MenuItemCompat.setShowAsAction(copy, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
- copy.setIcon(R.drawable.ic_action_copy);
- copy.setEnabled(activeTerminal);
- copy.setOnMenuItemClickListener(new OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- startCopyMode();
- Toast.makeText(ConsoleActivity.this, getString(R.string.console_copy_start), Toast.LENGTH_LONG).show();
- return true;
- }
- });
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ copy = menu.add(R.string.console_menu_copy);
+ if (hardKeyboard)
+ copy.setAlphabeticShortcut('c');
+ MenuItemCompat.setShowAsAction(copy, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
+ copy.setIcon(R.drawable.ic_action_copy);
+ copy.setEnabled(activeTerminal);
+ copy.setOnMenuItemClickListener(new OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ startCopyMode();
+ Toast.makeText(ConsoleActivity.this, getString(R.string.console_copy_start), Toast.LENGTH_LONG).show();
+ return true;
+ }
+ });
+ }
paste = menu.add(R.string.console_menu_paste);
if (hardKeyboard)
@@ -1144,7 +965,10 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
disconnect.setTitle(R.string.list_host_disconnect);
else
disconnect.setTitle(R.string.console_menu_close);
- copy.setEnabled(activeTerminal);
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ copy.setEnabled(activeTerminal);
+ }
paste.setEnabled(clipboard.hasText() && sessionOpen);
portForward.setEnabled(sessionOpen && canForwardPorts);
urlscan.setEnabled(activeTerminal);
@@ -1174,32 +998,6 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
}
@Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
- final TerminalView view = adapter.getCurrentTerminalView();
- boolean activeTerminal = view != null;
- boolean sessionOpen = false;
-
- if (activeTerminal) {
- TerminalBridge bridge = view.bridge;
- sessionOpen = bridge.isSessionOpen();
- }
-
- MenuItem paste = menu.add(R.string.console_menu_paste);
- if (hardKeyboard)
- paste.setAlphabeticShortcut('v');
- paste.setIcon(android.R.drawable.ic_menu_edit);
- paste.setEnabled(clipboard.hasText() && sessionOpen);
- paste.setOnMenuItemClickListener(new OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- pasteIntoTerminal();
- return true;
- }
- });
-
-
- }
-
- @Override
public void onStart() {
super.onStart();
@@ -1308,6 +1106,9 @@ 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();
@@ -1494,7 +1295,7 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
overlay.setText(bridge.host.getNickname());
// and add our terminal view control, using index to place behind overlay
- final TerminalView terminal = new TerminalView(container.getContext(), bridge);
+ final TerminalView terminal = new TerminalView(container.getContext(), bridge, pager);
terminal.setId(R.id.terminal_view);
view.addView(terminal, 0);
@@ -1572,7 +1373,9 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne
public TerminalView getCurrentTerminalView() {
View currentView = pager.findViewWithTag(getBridgeAtPosition(pager.getCurrentItem()));
- if (currentView == null) return null;
+ if (currentView == null) {
+ return null;
+ }
return (TerminalView) currentView.findViewById(R.id.terminal_view);
}
}