mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Added pinch to scale in terminal
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user