Added pinch to scale in terminal

This commit is contained in:
Akash Yadav
2022-06-17 14:03:34 +05:30
parent 3d47a5a629
commit fbe077fd63
3 changed files with 235 additions and 140 deletions
@@ -24,6 +24,7 @@ import static com.itsaky.androidide.utils.Environment.PREFIX;
import static com.itsaky.androidide.utils.Environment.getEnvironment;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -34,7 +35,6 @@ import androidx.annotation.NonNull;
import com.blankj.utilcode.util.ClipboardUtils;
import com.blankj.utilcode.util.KeyboardUtils;
import com.blankj.utilcode.util.SizeUtils;
import com.blankj.utilcode.util.ThrowableUtils;
import com.itsaky.androidide.app.StudioActivity;
import com.itsaky.androidide.databinding.ActivityTerminalBinding;
@@ -63,19 +63,24 @@ import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;
public class TerminalActivity extends StudioActivity {
public class TerminalActivity extends StudioActivity
implements TerminalViewClient, TerminalSessionClient {
public static final String KEY_WORKING_DIRECTORY = "terminal_workingDirectory";
private static final ILogger LOG = ILogger.newInstance("TerminalActivity");
private static final byte[] SOURCES_LIST_CONTENT =
"deb https://androidide.com/packages/apt/termux-main/ stable main".getBytes();
private final Client client = new Client();
private ActivityTerminalBinding binding;
private TerminalView terminal;
private TerminalSession session;
private boolean isVisible = false;
private KeyListener listener;
private int MIN_FONT_SIZE;
private int MAX_FONT_SIZE;
private int DEFAULT_FONT_SIZE;
private static final String KEY_FONT_SIZE = "terminal_fontSize";
@Override
protected View bindLayout() {
binding = ActivityTerminalBinding.inflate(getLayoutInflater());
@@ -154,11 +159,12 @@ public class TerminalActivity extends StudioActivity {
}
private void setupTerminalView() {
setFontVariables();
terminal = new TerminalView(this, null);
terminal.setTerminalViewClient(client);
terminal.setTerminalViewClient(this);
terminal.attachSession(createSession(getWorkingDirectory()));
terminal.setKeepScreenOn(true);
terminal.setTextSize(SizeUtils.dp2px(10));
terminal.setTextSize(getFontSize());
terminal.setTypeface(TypefaceUtils.jetbrainsMono());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, 0);
@@ -222,10 +228,10 @@ public class TerminalActivity extends StudioActivity {
}
private TerminalSession createSession(final String workingDirectory) {
final Map<String, String> envs = getEnvironment();
final String[] env = new String[envs.size()];
final Map<String, String> environment = getEnvironment();
final String[] env = new String[environment.size()];
int i = 0;
for (Map.Entry<String, String> entry : envs.entrySet()) {
for (Map.Entry<String, String> entry : environment.entrySet()) {
env[i] = entry.getKey() + "=" + entry.getValue();
i++;
}
@@ -237,7 +243,7 @@ public class TerminalActivity extends StudioActivity {
new String[] {}, // Arguments
env, // Environment variables
TerminalEmulator.DEFAULT_TERMINAL_TRANSCRIPT_ROWS, // Transcript rows
client // TerminalSessionClient
this // TerminalSessionClient
);
try {
@@ -270,6 +276,46 @@ public class TerminalActivity extends StudioActivity {
return "/system/bin/sh";
}
public void setFontVariables() {
int[] sizes = getDefaultFontSizes();
DEFAULT_FONT_SIZE = sizes[0];
MIN_FONT_SIZE = sizes[1];
MAX_FONT_SIZE = sizes[2];
}
// https://github.com/termux/termux-app/blob/82b15803126138eef8899e0c7b582713f872cd09/termux-shared/src/main/java/com/termux/shared/termux/settings/preferences/TermuxAppSharedPreferences.java
private int[] getDefaultFontSizes() {
float dipInPixels =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
int[] sizes = new int[3];
// This is a bit arbitrary and sub-optimal. We want to give a sensible default for minimum font
// size
// to prevent invisible text due to zoom be mistake:
sizes[1] = (int) (4f * dipInPixels); // min
// http://www.google.com/design/spec/style/typography.html#typography-line-height
int defaultFontSize = Math.round(9 * dipInPixels);
// Make it divisible by 2 since that is the minimal adjustment step:
if (defaultFontSize % 2 == 1) defaultFontSize--;
sizes[0] = defaultFontSize; // default
sizes[2] = 256; // max
if (getApp()
.getPrefManager()
.getString(KEY_FONT_SIZE, "<not_available>")
.equals("<not_available>")) {
setFontSize(defaultFontSize, false);
}
return sizes;
}
private static final class KeyListener implements VirtualKeysView.IVirtualKeysView {
private final TerminalView terminal;
@@ -311,7 +357,7 @@ public class TerminalActivity extends StudioActivity {
}
}
protected void onTerminalExtraKeyButtonClick(
private void onTerminalExtraKeyButtonClick(
String key, boolean ctrlDown, boolean altDown, boolean shiftDown, boolean fnDown) {
if (VirtualKeysConstants.PRIMARY_KEY_CODES_FOR_STRINGS.containsKey(key)) {
Integer keyCode = VirtualKeysConstants.PRIMARY_KEY_CODES_FOR_STRINGS.get(key);
@@ -353,160 +399,204 @@ public class TerminalActivity extends StudioActivity {
}
}
private final class Client implements TerminalViewClient, TerminalSessionClient {
@Override
public boolean onKeyUp(int keyCode, KeyEvent e) {
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent e) {
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent e, TerminalSession session) {
if (keyCode == KeyEvent.KEYCODE_ENTER && !session.isRunning()) {
finish();
return true;
}
return false;
}
@Override
public boolean onCodePoint(int codePoint, boolean ctrlDown, TerminalSession session) {
return false;
}
@Override
public void onTextChanged(TerminalSession changedSession) {
terminal.onScreenUpdated();
}
@Override
public void onTitleChanged(TerminalSession changedSession) {}
@Override
public void onSessionFinished(TerminalSession finishedSession) {
@Override
public boolean onKeyDown(int keyCode, KeyEvent e, TerminalSession session) {
if (keyCode == KeyEvent.KEYCODE_ENTER && !session.isRunning()) {
finish();
return true;
}
return false;
}
@Override
public void onCopyTextToClipboard(TerminalSession session, String text) {
ClipboardUtils.copyText("AndroidIDE Terminal", text);
@Override
public boolean onCodePoint(int codePoint, boolean ctrlDown, TerminalSession session) {
return false;
}
@Override
public void onTextChanged(TerminalSession changedSession) {
terminal.onScreenUpdated();
}
@Override
public void onTitleChanged(TerminalSession changedSession) {}
@Override
public void onSessionFinished(TerminalSession finishedSession) {
finish();
}
@Override
public void onCopyTextToClipboard(TerminalSession session, String text) {
ClipboardUtils.copyText("AndroidIDE Terminal", text);
}
@Override
public void onPasteTextFromClipboard(TerminalSession session) {
String clip = ClipboardUtils.getText().toString();
if (clip.trim().length() > 0 && terminal != null && terminal.mEmulator != null) {
terminal.mEmulator.paste(clip);
}
}
@Override
public void onPasteTextFromClipboard(TerminalSession session) {
String clip = ClipboardUtils.getText().toString();
if (clip.trim().length() > 0 && terminal != null && terminal.mEmulator != null) {
terminal.mEmulator.paste(clip);
}
}
@Override
public void onBell(TerminalSession session) {}
@Override
public void onBell(TerminalSession session) {}
@Override
public void onColorsChanged(TerminalSession session) {}
@Override
public void onColorsChanged(TerminalSession session) {}
@Override
public void onTerminalCursorStateChange(boolean state) {}
@Override
public void onTerminalCursorStateChange(boolean state) {}
@Override
public Integer getTerminalCursorStyle() {
return TerminalEmulator.DEFAULT_TERMINAL_CURSOR_STYLE;
}
@Override
public Integer getTerminalCursorStyle() {
return TerminalEmulator.DEFAULT_TERMINAL_CURSOR_STYLE;
}
@Override
public float onScale(float scale) {
@Override
public float onScale(float scale) {
if (scale < 0.9f || scale > 1.1f) {
boolean increase = scale > 1.f;
changeFontSize(increase);
return 1.0f;
}
return scale;
}
@Override
public void onSingleTapUp(MotionEvent e) {
KeyboardUtils.showSoftInput(terminal);
private void changeFontSize(final boolean increase) {
int fontSize = getFontSize();
fontSize += (increase ? 1 : -1) * 2;
fontSize = Math.max(MIN_FONT_SIZE, Math.min(fontSize, MAX_FONT_SIZE));
setFontSize(fontSize, true);
}
public int getFontSize() {
int fontSize;
try {
fontSize =
Integer.parseInt(
getApp()
.getPrefManager()
.getString(KEY_FONT_SIZE, String.valueOf(DEFAULT_FONT_SIZE)));
} catch (NumberFormatException | ClassCastException e) {
fontSize = DEFAULT_FONT_SIZE;
}
@Override
public boolean shouldBackButtonBeMappedToEscape() {
return false;
return Math.min(Math.max(fontSize, MIN_FONT_SIZE), MAX_FONT_SIZE);
}
public void setFontSize(int value, boolean apply) {
getApp().getPrefManager().putString(KEY_FONT_SIZE, String.valueOf(value));
if (apply) {
terminal.setTextSize(getFontSize());
}
}
@Override
public boolean shouldEnforceCharBasedInput() {
return true;
@Override
public void onSingleTapUp(MotionEvent e) {
KeyboardUtils.showSoftInput(terminal);
}
@Override
public boolean shouldBackButtonBeMappedToEscape() {
return false;
}
@Override
public boolean shouldEnforceCharBasedInput() {
return true;
}
@Override
public boolean shouldUseCtrlSpaceWorkaround() {
return false;
}
@Override
public boolean isTerminalViewSelected() {
return true;
}
@Override
public void copyModeChanged(boolean copyMode) {}
@Override
public boolean onLongPress(MotionEvent event) {
return false;
}
@Override
public boolean readControlKey() {
Boolean state = binding.virtualKeyTable.readSpecialButton(SpecialButton.CTRL, true);
return state != null && state;
}
@Override
public boolean readAltKey() {
Boolean state = binding.virtualKeyTable.readSpecialButton(SpecialButton.ALT, true);
return state != null && state;
}
@Override
public boolean readFnKey() {
return false;
}
@Override
public boolean readShiftKey() {
return false;
}
@Override
public void onEmulatorSet() {
setTerminalCursorBlinkingState(true);
if (session != null) {
binding
.getRoot()
.setBackgroundColor(
session.getEmulator().mColors.mCurrentColors[TextStyle.COLOR_INDEX_BACKGROUND]);
}
}
@Override
public boolean shouldUseCtrlSpaceWorkaround() {
return false;
}
@Override
public void logError(String tag, String message) {
LOG.error(tag + ":", message);
}
@Override
public boolean isTerminalViewSelected() {
return true;
}
@Override
public void logWarn(String tag, String message) {
LOG.warn(tag + ":", message);
}
@Override
public void copyModeChanged(boolean copyMode) {}
@Override
public void logInfo(String tag, String message) {
LOG.info(tag + ":", message);
}
@Override
public boolean onLongPress(MotionEvent event) {
return false;
}
@Override
public void logDebug(String tag, String message) {
LOG.debug(tag + ":", message);
}
@Override
public boolean readControlKey() {
Boolean state = binding.virtualKeyTable.readSpecialButton(SpecialButton.CTRL, true);
return state != null && state;
}
@Override
public void logVerbose(String tag, String message) {
LOG.verbose(tag + ":", message);
}
@Override
public boolean readAltKey() {
Boolean state = binding.virtualKeyTable.readSpecialButton(SpecialButton.ALT, true);
return state != null && state;
}
@Override
public void logStackTraceWithMessage(String tag, String message, Exception e) {
LOG.error(tag + ":", message, e);
}
@Override
public boolean readFnKey() {
return false;
}
@Override
public boolean readShiftKey() {
return false;
}
@Override
public void onEmulatorSet() {
setTerminalCursorBlinkingState(true);
if (session != null) {
binding
.getRoot()
.setBackgroundColor(
session.getEmulator().mColors.mCurrentColors[TextStyle.COLOR_INDEX_BACKGROUND]);
}
}
@Override
public void logError(String tag, String message) {
// No logs
}
@Override
public void logWarn(String tag, String message) {}
@Override
public void logInfo(String tag, String message) {}
@Override
public void logDebug(String tag, String message) {}
@Override
public void logVerbose(String tag, String message) {}
@Override
public void logStackTraceWithMessage(String tag, String message, Exception e) {}
@Override
public void logStackTrace(String tag, Exception e) {}
@Override
public void logStackTrace(String tag, Exception e) {
LOG.error(tag + ":", e);
}
}
@@ -58,6 +58,11 @@ public class PreferenceManager {
this.prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(ctx);
}
public PreferenceManager remove(String key) {
prefs.edit().remove(key).apply();
return this;
}
public PreferenceManager putInt(String key, int val) {
prefs.edit().putInt(key, val).apply();
return this;