Feature: Improve EKS
This commit is contained in:
@ -9,4 +9,5 @@ object NeoTermPath {
|
|||||||
const val HOME_PATH = "$ROOT_PATH/home"
|
const val HOME_PATH = "$ROOT_PATH/home"
|
||||||
|
|
||||||
const val EKS_PATH = "$USR_PATH/share/eks"
|
const val EKS_PATH = "$USR_PATH/share/eks"
|
||||||
|
const val EKS_DEFAULT_FILE = "$EKS_PATH/default.eks"
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package io.neoterm.customize.shortcut
|
package io.neoterm.customize.shortcut
|
||||||
|
|
||||||
import io.neoterm.view.ExtraKeysView
|
import io.neoterm.view.eks.ExtraButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kiva
|
* @author kiva
|
||||||
@ -8,5 +8,6 @@ import io.neoterm.view.ExtraKeysView
|
|||||||
class ShortcutConfig {
|
class ShortcutConfig {
|
||||||
var version: Int = -1
|
var version: Int = -1
|
||||||
val programNames: MutableList<String> = mutableListOf()
|
val programNames: MutableList<String> = mutableListOf()
|
||||||
val shortcutKeys: MutableList<ExtraKeysView.ExtraButton> = mutableListOf()
|
val shortcutKeys: MutableList<ExtraButton> = mutableListOf()
|
||||||
|
var withDefaultKeys: Boolean = true
|
||||||
}
|
}
|
@ -11,6 +11,9 @@ import java.io.File
|
|||||||
object ShortcutConfigLoader {
|
object ShortcutConfigLoader {
|
||||||
class ConfiguredShortcutKey(val config: ShortcutConfig) : ShortcutKey {
|
class ConfiguredShortcutKey(val config: ShortcutConfig) : ShortcutKey {
|
||||||
override fun applyShortcutKeys(extraKeysView: ExtraKeysView) {
|
override fun applyShortcutKeys(extraKeysView: ExtraKeysView) {
|
||||||
|
if (config.withDefaultKeys) {
|
||||||
|
extraKeysView.loadDefaultUserDefinedExtraKeys()
|
||||||
|
}
|
||||||
for (button in config.shortcutKeys) {
|
for (button in config.shortcutKeys) {
|
||||||
extraKeysView.addExternalButton(button)
|
extraKeysView.addExternalButton(button)
|
||||||
}
|
}
|
||||||
@ -26,6 +29,12 @@ object ShortcutConfigLoader {
|
|||||||
try {
|
try {
|
||||||
parser.setInput(file)
|
parser.setInput(file)
|
||||||
val config = parser.parse()
|
val config = parser.parse()
|
||||||
|
|
||||||
|
// "default" is a reserved program used for default extra keys
|
||||||
|
// see ExtraKeysView.loadDefaultUserDefinedExtraKeys()
|
||||||
|
if (config.programNames.contains("default")) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
registerConfig(config)
|
registerConfig(config)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("NeoTerm-EKS", "Load $file failed: " + e.toString())
|
Log.e("NeoTerm-EKS", "Load $file failed: " + e.toString())
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.neoterm.customize.shortcut
|
package io.neoterm.customize.shortcut
|
||||||
|
|
||||||
import io.neoterm.view.ExtraKeysView
|
import io.neoterm.view.eks.TextButton
|
||||||
import java.io.*
|
import java.io.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -8,7 +8,7 @@ import java.io.*
|
|||||||
*/
|
*/
|
||||||
class ShortcutConfigParser {
|
class ShortcutConfigParser {
|
||||||
companion object {
|
companion object {
|
||||||
const val PARSER_VERSION = 1
|
const val PARSER_VERSION = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var source: BufferedReader
|
private lateinit var source: BufferedReader
|
||||||
@ -42,6 +42,8 @@ class ShortcutConfigParser {
|
|||||||
parseProgram(line, config)
|
parseProgram(line, config)
|
||||||
} else if (line.startsWith("define")) {
|
} else if (line.startsWith("define")) {
|
||||||
parseKeyDefine(line, config)
|
parseKeyDefine(line, config)
|
||||||
|
} else if (line.startsWith("with-default")) {
|
||||||
|
parseWithDefault(line, config)
|
||||||
}
|
}
|
||||||
line = source.readLine()
|
line = source.readLine()
|
||||||
}
|
}
|
||||||
@ -55,6 +57,11 @@ class ShortcutConfigParser {
|
|||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun parseWithDefault(line: String, config: ShortcutConfig) {
|
||||||
|
val value = line.substring("with-default".length).trim().trimEnd()
|
||||||
|
config.withDefaultKeys = value == "true"
|
||||||
|
}
|
||||||
|
|
||||||
private fun parseKeyDefine(line: String, config: ShortcutConfig) {
|
private fun parseKeyDefine(line: String, config: ShortcutConfig) {
|
||||||
val keyDefine = line.substring("define".length).trim().trimEnd()
|
val keyDefine = line.substring("define".length).trim().trimEnd()
|
||||||
val keyValues = keyDefine.split(" ")
|
val keyValues = keyDefine.split(" ")
|
||||||
@ -65,7 +72,7 @@ class ShortcutConfigParser {
|
|||||||
val buttonText = keyValues[0]
|
val buttonText = keyValues[0]
|
||||||
val withEnter = keyValues[1] == "true"
|
val withEnter = keyValues[1] == "true"
|
||||||
|
|
||||||
config.shortcutKeys.add(ExtraKeysView.TextButton(buttonText, withEnter))
|
config.shortcutKeys.add(TextButton(buttonText, withEnter))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseProgram(line: String, config: ShortcutConfig) {
|
private fun parseProgram(line: String, config: ShortcutConfig) {
|
||||||
|
@ -19,7 +19,7 @@ object ShortcutKeysManager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
extraKeysView.resetExternalButtons()
|
extraKeysView.loadDefaultUserDefinedExtraKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerShortcutKeys(program: String, shortcutKey: ShortcutKey?) {
|
fun registerShortcutKeys(program: String, shortcutKey: ShortcutKey?) {
|
||||||
|
@ -11,9 +11,9 @@ import java.io.File
|
|||||||
object BuiltinShortcutKeys {
|
object BuiltinShortcutKeys {
|
||||||
private const val vimKeys = "version ${ShortcutConfigParser.PARSER_VERSION}\n" +
|
private const val vimKeys = "version ${ShortcutConfigParser.PARSER_VERSION}\n" +
|
||||||
"program vim neovim vi\n" +
|
"program vim neovim vi\n" +
|
||||||
"define / false\n" +
|
|
||||||
"define :w true\n" +
|
|
||||||
"define dd true\n" +
|
"define dd true\n" +
|
||||||
|
"define :x true\n" +
|
||||||
|
"define :w true\n" +
|
||||||
"define :q true\n"
|
"define :q true\n"
|
||||||
|
|
||||||
private const val moreKeys = "version ${ShortcutConfigParser.PARSER_VERSION}\n" +
|
private const val moreKeys = "version ${ShortcutConfigParser.PARSER_VERSION}\n" +
|
||||||
|
@ -84,7 +84,7 @@ object NeoTermPreference {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildEnvironment(cwd: String?, systemShell: Boolean): Array<String> {
|
fun buildEnvironment(cwd: String?, systemShell: Boolean, executablePath: String): Array<String> {
|
||||||
var cwd = cwd
|
var cwd = cwd
|
||||||
File(NeoTermPath.HOME_PATH).mkdirs()
|
File(NeoTermPath.HOME_PATH).mkdirs()
|
||||||
|
|
||||||
|
@ -93,7 +93,9 @@ class NeoTermService : Service() {
|
|||||||
arguments = arrayOf<String>(executablePath)
|
arguments = arrayOf<String>(executablePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
val session = TerminalSession(executablePath, cwd, arguments, env ?: NeoTermPreference.buildEnvironment(cwd, systemShell), sessionCallback)
|
val session = TerminalSession(executablePath, cwd, arguments,
|
||||||
|
env ?: NeoTermPreference.buildEnvironment(cwd, systemShell, executablePath),
|
||||||
|
sessionCallback)
|
||||||
mTerminalSessions.add(session)
|
mTerminalSessions.add(session)
|
||||||
updateNotification()
|
updateNotification()
|
||||||
return session
|
return session
|
||||||
|
@ -2,7 +2,6 @@ package io.neoterm.view;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -11,121 +10,67 @@ import android.widget.Button;
|
|||||||
import android.widget.GridLayout;
|
import android.widget.GridLayout;
|
||||||
import android.widget.ToggleButton;
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import io.neoterm.R;
|
import io.neoterm.R;
|
||||||
import io.neoterm.backend.TerminalSession;
|
import io.neoterm.backend.TerminalSession;
|
||||||
|
import io.neoterm.customize.NeoTermPath;
|
||||||
|
import io.neoterm.customize.shortcut.ShortcutConfig;
|
||||||
|
import io.neoterm.customize.shortcut.ShortcutConfigParser;
|
||||||
|
import io.neoterm.preference.NeoTermPreference;
|
||||||
|
import io.neoterm.utils.FileUtils;
|
||||||
|
import io.neoterm.view.eks.ControlButton;
|
||||||
|
import io.neoterm.view.eks.ExtraButton;
|
||||||
|
import io.neoterm.view.eks.StatedControlButton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A view showing extra keys (such as Escape, Ctrl, Alt) not normally available on an Android soft
|
* A view showing extra keys (such as Escape, Ctrl, Alt) not normally available on an Android soft
|
||||||
* keyboard.
|
* keyboard.
|
||||||
*/
|
*/
|
||||||
public final class ExtraKeysView extends GridLayout {
|
public final class ExtraKeysView extends GridLayout {
|
||||||
public static abstract class ExtraButton implements OnClickListener {
|
public static final String KEY_ESC = "Esc";
|
||||||
public String buttonText;
|
public static final String KEY_TAB = "Tab";
|
||||||
|
public static final String KEY_CTRL = "Ctrl";
|
||||||
|
|
||||||
@Override
|
public static final ControlButton ESC = new ControlButton(KEY_ESC);
|
||||||
public abstract void onClick(View view);
|
public static final ControlButton TAB = new ControlButton(KEY_TAB);
|
||||||
}
|
public static final StatedControlButton CTRL = new StatedControlButton(KEY_CTRL);
|
||||||
|
|
||||||
public static class ControlButton extends ExtraButton {
|
|
||||||
public ControlButton(String text) {
|
|
||||||
buttonText = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
ExtraKeysView.sendKey(view, buttonText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TextButton extends ExtraButton {
|
|
||||||
boolean withEnter = false;
|
|
||||||
|
|
||||||
public TextButton(String text) {
|
|
||||||
this(text, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextButton(String text, boolean withEnter) {
|
|
||||||
this.buttonText = text;
|
|
||||||
this.withEnter = withEnter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
ExtraKeysView.sendKey(view, buttonText);
|
|
||||||
if (withEnter) {
|
|
||||||
ExtraKeysView.sendKey(view, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class StatedControlButton extends ControlButton {
|
|
||||||
public ToggleButton toggleButton;
|
|
||||||
|
|
||||||
public StatedControlButton(String text) {
|
|
||||||
super(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
toggleButton.setChecked(toggleButton.isChecked());
|
|
||||||
toggleButton.setTextColor(toggleButton.isChecked() ? 0xFF80DEEA : TEXT_COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean readState() {
|
|
||||||
if (toggleButton.isPressed()) return true;
|
|
||||||
boolean result = toggleButton.isChecked();
|
|
||||||
if (result) {
|
|
||||||
toggleButton.setChecked(false);
|
|
||||||
toggleButton.setTextColor(TEXT_COLOR);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final ControlButton ESC = new ControlButton("ESC");
|
|
||||||
public static final ControlButton TAB = new ControlButton("TAB");
|
|
||||||
public static final StatedControlButton CTRL = new StatedControlButton("CTRL");
|
|
||||||
public static final StatedControlButton ALT = new StatedControlButton("ALT");
|
|
||||||
public static final StatedControlButton FN = new StatedControlButton("FN");
|
|
||||||
|
|
||||||
public static final ControlButton ARROW_UP = new ControlButton("▲");
|
public static final ControlButton ARROW_UP = new ControlButton("▲");
|
||||||
public static final ControlButton ARROW_DOWN = new ControlButton("▼");
|
public static final ControlButton ARROW_DOWN = new ControlButton("▼");
|
||||||
public static final ControlButton ARROW_LEFT = new ControlButton("◀");
|
public static final ControlButton ARROW_LEFT = new ControlButton("◀");
|
||||||
public static final ControlButton ARROW_RIGHT = new ControlButton("▶");
|
public static final ControlButton ARROW_RIGHT = new ControlButton("▶");
|
||||||
|
|
||||||
public static final TextButton HORIZONTAL = new TextButton("-");
|
public static final String DEFAULT_FILE_CONTENT = "version " + ShortcutConfigParser.PARSER_VERSION + "\n" +
|
||||||
public static final TextButton SLASH = new TextButton("/");
|
"program default\n" +
|
||||||
public static final TextButton PIPE = new TextButton("|");
|
"define - false\n" +
|
||||||
|
"define / false\n" +
|
||||||
|
"define | false\n";
|
||||||
|
|
||||||
private static final int TEXT_COLOR = 0xFFFFFFFF;
|
public static final int NORMAL_TEXT_COLOR = 0xFFFFFFFF;
|
||||||
|
|
||||||
private List<ExtraButton> extraButtons;
|
private List<ExtraButton> builtinExtraKeys;
|
||||||
private List<ExtraButton> externalButtons;
|
private List<ExtraButton> userDefinedExtraKeys;
|
||||||
|
|
||||||
public ExtraKeysView(Context context, AttributeSet attrs) {
|
public ExtraKeysView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
try {
|
builtinExtraKeys = new ArrayList<>(7);
|
||||||
externalButtons = new ArrayList<>(3);
|
userDefinedExtraKeys = new ArrayList<>(7);
|
||||||
extraButtons = new ArrayList<>();
|
loadDefaultBuiltinExtraKeys();
|
||||||
resetExternalButtons();
|
loadDefaultUserDefinedExtraKeys();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
} catch (Throwable e) {
|
|
||||||
Log.e("NeoTerm", e.toString());
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendKey(View view, String keyName) {
|
public static void sendKey(View view, String keyName) {
|
||||||
int keyCode = 0;
|
int keyCode = 0;
|
||||||
String chars = null;
|
String chars = null;
|
||||||
switch (keyName) {
|
switch (keyName) {
|
||||||
case "ESC":
|
case KEY_ESC:
|
||||||
keyCode = KeyEvent.KEYCODE_ESCAPE;
|
keyCode = KeyEvent.KEYCODE_ESCAPE;
|
||||||
break;
|
break;
|
||||||
case "TAB":
|
case KEY_TAB:
|
||||||
keyCode = KeyEvent.KEYCODE_TAB;
|
keyCode = KeyEvent.KEYCODE_TAB;
|
||||||
break;
|
break;
|
||||||
case "▲":
|
case "▲":
|
||||||
@ -162,89 +107,97 @@ public final class ExtraKeysView extends GridLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean readAltButton() {
|
public boolean readAltButton() {
|
||||||
return ALT.readState();
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
public boolean readFnButton() {
|
|
||||||
return FN.readState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addExternalButton(ExtraButton button) {
|
public void addExternalButton(ExtraButton button) {
|
||||||
externalButtons.add(button);
|
userDefinedExtraKeys.add(button);
|
||||||
}
|
|
||||||
|
|
||||||
public void removeExternalButton(ExtraButton button) {
|
|
||||||
externalButtons.remove(button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearExternalButton() {
|
public void clearExternalButton() {
|
||||||
externalButtons.clear();
|
userDefinedExtraKeys.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetExternalButtons() {
|
public void loadDefaultUserDefinedExtraKeys() {
|
||||||
|
File defaultFile = new File(NeoTermPath.EKS_DEFAULT_FILE);
|
||||||
|
if (!defaultFile.exists()) {
|
||||||
|
generateDefaultFile(defaultFile);
|
||||||
|
}
|
||||||
|
|
||||||
clearExternalButton();
|
clearExternalButton();
|
||||||
externalButtons.add(ALT);
|
try {
|
||||||
externalButtons.add(HORIZONTAL);
|
ShortcutConfigParser parser = new ShortcutConfigParser();
|
||||||
externalButtons.add(SLASH);
|
parser.setInput(defaultFile);
|
||||||
externalButtons.add(PIPE);
|
ShortcutConfig config = parser.parse();
|
||||||
|
userDefinedExtraKeys.addAll(config.getShortcutKeys());
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadDefaultButtons(List<ExtraButton> buttons) {
|
private void generateDefaultFile(File defaultFile) {
|
||||||
buttons.add(ESC);
|
FileUtils.INSTANCE.writeFile(defaultFile, DEFAULT_FILE_CONTENT.getBytes());
|
||||||
buttons.add(CTRL);
|
|
||||||
buttons.add(TAB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadExternalButtons(List<ExtraButton> buttons) {
|
void loadDefaultBuiltinExtraKeys() {
|
||||||
buttons.addAll(externalButtons);
|
builtinExtraKeys.clear();
|
||||||
|
builtinExtraKeys.add(ESC);
|
||||||
|
builtinExtraKeys.add(CTRL);
|
||||||
|
builtinExtraKeys.add(TAB);
|
||||||
|
builtinExtraKeys.add(ARROW_LEFT);
|
||||||
|
builtinExtraKeys.add(ARROW_RIGHT);
|
||||||
|
builtinExtraKeys.add(ARROW_UP);
|
||||||
|
builtinExtraKeys.add(ARROW_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateButtons() {
|
public void updateButtons() {
|
||||||
removeAllViews();
|
removeAllViews();
|
||||||
|
List[] buttons = new List[]{userDefinedExtraKeys, builtinExtraKeys};
|
||||||
|
|
||||||
extraButtons.clear();
|
setRowCount(buttons[0].size() == 0 ? 1 : 2);
|
||||||
loadDefaultButtons(extraButtons);
|
setColumnCount(buttons[1].size());
|
||||||
loadExternalButtons(extraButtons);
|
|
||||||
|
|
||||||
setRowCount(1);
|
for (int row = 0; row < buttons.length; row++) {
|
||||||
setColumnCount(extraButtons.size());
|
for (int col = 0; col < buttons[row].size(); col++) {
|
||||||
|
final ExtraButton extraButton = (ExtraButton) buttons[row].get(col);
|
||||||
|
|
||||||
for (int col = 0; col < extraButtons.size(); col++) {
|
Button button;
|
||||||
final ExtraButton extraButton = extraButtons.get(col);
|
if (extraButton instanceof StatedControlButton) {
|
||||||
|
StatedControlButton btn = ((StatedControlButton) extraButton);
|
||||||
Button button;
|
button = btn.toggleButton = new ToggleButton(getContext(), null, android.R.attr.buttonBarButtonStyle);
|
||||||
if (extraButton instanceof StatedControlButton) {
|
button.setClickable(true);
|
||||||
StatedControlButton btn = ((StatedControlButton) extraButton);
|
} else {
|
||||||
button = btn.toggleButton = new ToggleButton(getContext(), null, android.R.attr.buttonBarButtonStyle);
|
button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle);
|
||||||
button.setClickable(true);
|
|
||||||
} else {
|
|
||||||
button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
button.setText(extraButton.buttonText);
|
|
||||||
button.setTextColor(TEXT_COLOR);
|
|
||||||
button.setAllCaps(false);
|
|
||||||
|
|
||||||
final Button finalButton = button;
|
|
||||||
button.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
finalButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
|
||||||
View root = getRootView();
|
|
||||||
extraButton.onClick(root);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
LayoutParams param = new LayoutParams();
|
button.setText(extraButton.buttonText);
|
||||||
param.height = param.width = 0;
|
button.setTextColor(NORMAL_TEXT_COLOR);
|
||||||
param.rightMargin = param.topMargin = 0;
|
button.setAllCaps(false);
|
||||||
param.setGravity(Gravity.START);
|
|
||||||
float weight = "▲▼◀▶".contains(extraButton.buttonText) ? 0.7f : 1.f;
|
|
||||||
param.columnSpec = GridLayout.spec(col, GridLayout.FILL, weight);
|
|
||||||
param.rowSpec = GridLayout.spec(0, GridLayout.FILL, 1.f);
|
|
||||||
button.setLayoutParams(param);
|
|
||||||
|
|
||||||
addView(button);
|
final Button finalButton = button;
|
||||||
|
button.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
finalButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||||
|
View root = getRootView();
|
||||||
|
extraButton.onClick(root);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LayoutParams param = new LayoutParams();
|
||||||
|
param.height = param.width = 0;
|
||||||
|
param.rightMargin = param.topMargin = 0;
|
||||||
|
param.setGravity(Gravity.START);
|
||||||
|
|
||||||
|
float weight = 1.f;
|
||||||
|
if (NeoTermPreference.INSTANCE.loadBoolean(R.string.key_ui_wide_char_weigh_explicit, false)) {
|
||||||
|
weight = "▲▼◀▶".contains(extraButton.buttonText) ? 0.7f : 1.f;
|
||||||
|
}
|
||||||
|
param.columnSpec = GridLayout.spec(col, GridLayout.FILL, weight);
|
||||||
|
param.rowSpec = GridLayout.spec(row, GridLayout.FILL, 1.f);
|
||||||
|
button.setLayoutParams(param);
|
||||||
|
|
||||||
|
addView(button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
app/src/main/java/io/neoterm/view/eks/ControlButton.java
Normal file
20
app/src/main/java/io/neoterm/view/eks/ControlButton.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package io.neoterm.view.eks;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import io.neoterm.view.ExtraKeysView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kiva
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ControlButton extends ExtraButton {
|
||||||
|
public ControlButton(String text) {
|
||||||
|
buttonText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
ExtraKeysView.sendKey(view, buttonText);
|
||||||
|
}
|
||||||
|
}
|
14
app/src/main/java/io/neoterm/view/eks/ExtraButton.java
Normal file
14
app/src/main/java/io/neoterm/view/eks/ExtraButton.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package io.neoterm.view.eks;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kiva
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class ExtraButton implements View.OnClickListener {
|
||||||
|
public String buttonText;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract void onClick(View view);
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package io.neoterm.view.eks;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
import io.neoterm.view.ExtraKeysView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kiva
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatedControlButton extends ControlButton {
|
||||||
|
public ToggleButton toggleButton;
|
||||||
|
|
||||||
|
public StatedControlButton(String text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
toggleButton.setChecked(toggleButton.isChecked());
|
||||||
|
toggleButton.setTextColor(toggleButton.isChecked() ? 0xFF80DEEA : ExtraKeysView.NORMAL_TEXT_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean readState() {
|
||||||
|
if (toggleButton.isPressed()) return true;
|
||||||
|
boolean result = toggleButton.isChecked();
|
||||||
|
if (result) {
|
||||||
|
toggleButton.setChecked(false);
|
||||||
|
toggleButton.setTextColor(ExtraKeysView.NORMAL_TEXT_COLOR);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
30
app/src/main/java/io/neoterm/view/eks/TextButton.java
Normal file
30
app/src/main/java/io/neoterm/view/eks/TextButton.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package io.neoterm.view.eks;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import io.neoterm.view.ExtraKeysView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kiva
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TextButton extends ExtraButton {
|
||||||
|
boolean withEnter = false;
|
||||||
|
|
||||||
|
public TextButton(String text) {
|
||||||
|
this(text, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextButton(String text, boolean withEnter) {
|
||||||
|
this.buttonText = text;
|
||||||
|
this.withEnter = withEnter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
ExtraKeysView.sendKey(view, buttonText);
|
||||||
|
if (withEnter) {
|
||||||
|
ExtraKeysView.sendKey(view, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,8 @@ class TermTab(title: CharSequence) : Tab(title) {
|
|||||||
toolbar?.title = title
|
toolbar?.title = title
|
||||||
if (NeoTermPreference.loadBoolean(R.string.key_ui_suggestions, true)) {
|
if (NeoTermPreference.loadBoolean(R.string.key_ui_suggestions, true)) {
|
||||||
viewClient?.updateSuggestions(title)
|
viewClient?.updateSuggestions(title)
|
||||||
|
} else {
|
||||||
|
viewClient?.removeSuggestions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,11 +110,15 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastTitle != title || force) {
|
if (lastTitle != title || force) {
|
||||||
extraKeysView?.clearExternalButton()
|
removeSuggestions()
|
||||||
ShortcutKeysManager.showShortcutKeys(title, extraKeysView)
|
ShortcutKeysManager.showShortcutKeys(title, extraKeysView)
|
||||||
extraKeysView?.updateButtons()
|
extraKeysView?.updateButtons()
|
||||||
lastTitle = title
|
lastTitle = title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun removeSuggestions() {
|
||||||
|
extraKeysView?.clearExternalButton()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -17,7 +17,7 @@
|
|||||||
android:id="@+id/extra_keys"
|
android:id="@+id/extra_keys"
|
||||||
style="?android:buttonBarStyle"
|
style="?android:buttonBarStyle"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="36dp"
|
android:layout_height="@dimen/eks_height_two_line"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:background="@color/terminal_background"
|
android:background="@color/terminal_background"
|
||||||
android:orientation="horizontal" />
|
android:orientation="horizontal" />
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
<string name="pref_ui_fullscreen">全屏</string>
|
<string name="pref_ui_fullscreen">全屏</string>
|
||||||
<string name="pref_ui_suggestions">显示建议 (需要 oh-my-zsh)</string>
|
<string name="pref_ui_suggestions">显示建议 (需要 oh-my-zsh)</string>
|
||||||
<string name="pref_ui_suggestions_desc">使用一些软件时,屏幕下方显示快捷键</string>
|
<string name="pref_ui_suggestions_desc">使用一些软件时,屏幕下方显示快捷键</string>
|
||||||
|
<string name="pref_ui_wide_char_weight_explicit">为宽字符设置权重</string>
|
||||||
|
<string name="pref_ui_wide_char_weight_explicit_desc">如果快捷输入栏显示不正确,请勾选本项</string>
|
||||||
<string name="settings">设置</string>
|
<string name="settings">设置</string>
|
||||||
<string name="text_selection_more">更多</string>
|
<string name="text_selection_more">更多</string>
|
||||||
<string name="toggle_ime">切换输入法</string>
|
<string name="toggle_ime">切换输入法</string>
|
||||||
|
@ -2,4 +2,6 @@
|
|||||||
<dimen name="app_bar_height">180dp</dimen>
|
<dimen name="app_bar_height">180dp</dimen>
|
||||||
<dimen name="fab_margin">16dp</dimen>
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
<dimen name="text_margin">16dp</dimen>
|
<dimen name="text_margin">16dp</dimen>
|
||||||
|
<dimen name="eks_height">36dp</dimen>
|
||||||
|
<dimen name="eks_height_two_line">72dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<string name="key_ui_color_scheme" translatable="false">neoterm_ui_color_scheme</string>
|
<string name="key_ui_color_scheme" translatable="false">neoterm_ui_color_scheme</string>
|
||||||
<string name="key_ui_next_tab_anim" translatable="false">neoterm_ui_next_tab_anim</string>
|
<string name="key_ui_next_tab_anim" translatable="false">neoterm_ui_next_tab_anim</string>
|
||||||
<string name="key_ui_suggestions" translatable="false">neoterm_ui_suggestions</string>
|
<string name="key_ui_suggestions" translatable="false">neoterm_ui_suggestions</string>
|
||||||
|
<string name="key_ui_wide_char_weigh_explicit">neoterm_ui_wide_char_explicit</string>
|
||||||
|
|
||||||
<string name="key_package_source" translatable="false">neoterm_package_source</string>
|
<string name="key_package_source" translatable="false">neoterm_package_source</string>
|
||||||
</resources>
|
</resources>
|
@ -28,6 +28,8 @@
|
|||||||
<string name="pref_ui_close_tab_anim_next_tab_desc">Switch to the next tab instead of the previous tab when closing tab</string>
|
<string name="pref_ui_close_tab_anim_next_tab_desc">Switch to the next tab instead of the previous tab when closing tab</string>
|
||||||
<string name="pref_ui_suggestions">Show Suggestions (oh-my-zsh required)</string>
|
<string name="pref_ui_suggestions">Show Suggestions (oh-my-zsh required)</string>
|
||||||
<string name="pref_ui_suggestions_desc">When using some programs, show shortcut keys</string>
|
<string name="pref_ui_suggestions_desc">When using some programs, show shortcut keys</string>
|
||||||
|
<string name="pref_ui_wide_char_weight_explicit">Use explicit weight for wide char</string>
|
||||||
|
<string name="pref_ui_wide_char_weight_explicit_desc">If suggestion bar show incorrect, please enable this</string>
|
||||||
<string name="pref_package_source">Source</string>
|
<string name="pref_package_source">Source</string>
|
||||||
<string name="toggle_ime">Toggle IME</string>
|
<string name="toggle_ime">Toggle IME</string>
|
||||||
|
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
android:summary="@string/pref_ui_suggestions_desc"
|
android:summary="@string/pref_ui_suggestions_desc"
|
||||||
android:title="@string/pref_ui_suggestions" />
|
android:title="@string/pref_ui_suggestions" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="@string/key_ui_wide_char_weigh_explicit"
|
||||||
|
android:summary="@string/pref_ui_wide_char_weight_explicit_desc"
|
||||||
|
android:title="@string/pref_ui_wide_char_weight_explicit" />
|
||||||
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:key="@string/key_ui_font"
|
android:key="@string/key_ui_font"
|
||||||
android:title="@string/pref_ui_font" />
|
android:title="@string/pref_ui_font" />
|
||||||
|
@ -7,7 +7,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
|
classpath 'com.android.tools.build:gradle:3.0.0-alpha4'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Sun Jun 11 16:46:54 CST 2017
|
#Fri Jun 16 12:14:31 CST 2017
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-milestone-1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-rc-1-all.zip
|
||||||
|
Reference in New Issue
Block a user