Feature: Customize color schemes

This commit is contained in:
zt515
2017-07-03 17:05:42 +08:00
parent 9ae461433e
commit 9c5f817db8
35 changed files with 507 additions and 178 deletions

View File

@ -0,0 +1,28 @@
foreground=#f8f8f2
cursor=#f8f8f2
background=#282a36
color0=#000000
color8=#4d4d4d
color1=#ff5555
color9=#ff6e67
color2=#50fa7b
color10=#5af78e
color3=#f1fa8c
color11=#f4f99d
color4=#caa9fa
color12=#caa9fa
color5=#ff79c6
color13=#ff92d0
color6=#8be9fd
color14=#9aedfe
color7=#bfbfbf
color15=#e6e6e6

View File

@ -0,0 +1,26 @@
background=#263238
foreground=#eceff1
color0=#263238
color8=#37474f
color1=#ff9800
color9=#ffa74d
color2=#8bc34a
color10=#9ccc65
color3=#ffc107
color11=#ffa000
color4=#03a9f4
color12=#81d4fa
color5=#e91e63
color13=#ad1457
color6=#009688
color14=#26a69a
color7=#cfd8dc
color15=#eceff1

View File

@ -0,0 +1,21 @@
background=#002b36
foreground=#839496
cursor=#93a1a1
color0=#073642
color1=#dc322f
color2=#859900
color3=#b58900
color4=#268bd2
color5=#d33682
color6=#2aa198
color7=#eee8d5
color9=#cb4b16
color8=#002b36
color10=#586e75
color11=#657b83
color12=#839496
color13=#6c71c4
color14=#93a1a1
color15=#fdf6e3

View File

@ -0,0 +1,20 @@
background=#fdf6e3
foreground=#657b83
cursor=#586e75
color0=#073642
color1=#dc322f
color2=#859900
color3=#b58900
color4=#268bd2
color5=#d33682
color6=#2aa198
color7=#eee8d5
color8=#002b36
color9=#cb4b16
color10=#586e75
color11=#657b83
color12=#839496
color13=#6c71c4
color14=#93a1a1
color15=#fdf6e3

View File

@ -10,6 +10,7 @@ import io.neoterm.customize.font.FontManager
class App : Application() { class App : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
// ensure that we can access these any time
ColorSchemeManager.init(this) ColorSchemeManager.init(this)
FontManager.init(this) FontManager.init(this)
} }

View File

@ -136,7 +136,7 @@ public final class TerminalBuffer {
* *
* @param newColumns The number of columns the screen should have. * @param newColumns The number of columns the screen should have.
* @param newRows The number of rows the screen should have. * @param newRows The number of rows the screen should have.
* @param cursor An int[2] containing the (column, row) cursor location. * @param cursor An int[2] containing the (column, row) cursorColor location.
*/ */
public void resize(int newColumns, int newRows, int newTotalRows, int[] cursor, long currentStyle, boolean altScreen) { public void resize(int newColumns, int newRows, int newTotalRows, int[] cursor, long currentStyle, boolean altScreen) {
// newRows > mTotalRows should not normally happen since mTotalRows is TRANSCRIPT_ROWS (10000): // newRows > mTotalRows should not normally happen since mTotalRows is TRANSCRIPT_ROWS (10000):
@ -144,7 +144,7 @@ public final class TerminalBuffer {
// Fast resize where just the rows changed. // Fast resize where just the rows changed.
int shiftDownOfTopRow = mScreenRows - newRows; int shiftDownOfTopRow = mScreenRows - newRows;
if (shiftDownOfTopRow > 0 && shiftDownOfTopRow < mScreenRows) { if (shiftDownOfTopRow > 0 && shiftDownOfTopRow < mScreenRows) {
// Shrinking. Check if we can skip blank rows at bottom below cursor. // Shrinking. Check if we can skip blank rows at bottom below cursorColor.
for (int i = mScreenRows - 1; i > 0; i--) { for (int i = mScreenRows - 1; i > 0; i--) {
if (cursor[1] >= i) break; if (cursor[1] >= i) break;
int r = externalToInternalRow(i); int r = externalToInternalRow(i);
@ -204,7 +204,7 @@ public final class TerminalBuffer {
TerminalRow oldLine = oldLines[internalOldRow]; TerminalRow oldLine = oldLines[internalOldRow];
boolean cursorAtThisRow = externalOldRow == oldCursorRow; boolean cursorAtThisRow = externalOldRow == oldCursorRow;
// The cursor may only be on a non-null line, which we should not skip: // The cursorColor may only be on a non-null line, which we should not skip:
if (oldLine == null || (!(!newCursorPlaced && cursorAtThisRow)) && oldLine.isBlank()) { if (oldLine == null || (!(!newCursorPlaced && cursorAtThisRow)) && oldLine.isBlank()) {
skippedBlankLines++; skippedBlankLines++;
continue; continue;
@ -224,7 +224,7 @@ public final class TerminalBuffer {
int lastNonSpaceIndex = 0; int lastNonSpaceIndex = 0;
boolean justToCursor = false; boolean justToCursor = false;
if (cursorAtThisRow || oldLine.mLineWrap) { if (cursorAtThisRow || oldLine.mLineWrap) {
// Take the whole line, either because of cursor on it, or if line wrapping. // Take the whole line, either because of cursorColor on it, or if line wrapping.
lastNonSpaceIndex = oldLine.getSpaceUsed(); lastNonSpaceIndex = oldLine.getSpaceUsed();
if (cursorAtThisRow) justToCursor = true; if (cursorAtThisRow) justToCursor = true;
} else { } else {
@ -287,7 +287,7 @@ public final class TerminalBuffer {
cursor[1] = newCursorRow; cursor[1] = newCursorRow;
} }
// Handle cursor scrolling off screen: // Handle cursorColor scrolling off screen:
if (cursor[0] < 0 || cursor[1] < 0) cursor[0] = cursor[1] = 0; if (cursor[0] < 0 || cursor[1] < 0) cursor[0] = cursor[1] = 0;
} }

View File

@ -12,7 +12,7 @@ import java.util.Properties;
public final class TerminalColorScheme { public final class TerminalColorScheme {
/** http://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg, but with blue color brighter. */ /** http://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg, but with blue color brighter. */
private static final int[] DEFAULT_COLORSCHEME = { public static final int[] DEFAULT_COLORS = {
// 16 original colors. First 8 are dim. // 16 original colors. First 8 are dim.
0xff000000, // black 0xff000000, // black
0xffcd0000, // dim red 0xffcd0000, // dim red
@ -66,14 +66,20 @@ public final class TerminalColorScheme {
} }
private void reset() { private void reset() {
System.arraycopy(DEFAULT_COLORSCHEME, 0, mDefaultColors, 0, TextStyle.NUM_INDEXED_COLORS); System.arraycopy(DEFAULT_COLORS, 0, mDefaultColors, 0, TextStyle.NUM_INDEXED_COLORS);
} }
public void updateWith(String foreground, String background, String cursor, Map<Integer, String> color) { public void updateWith(String foreground, String background, String cursor, Map<Integer, String> color) {
Properties prop = new Properties(); Properties prop = new Properties();
if (foreground != null) {
prop.put("foreground", foreground); prop.put("foreground", foreground);
}
if (background != null) {
prop.put("background", background); prop.put("background", background);
}
if (cursor != null) {
prop.put("cursor", cursor); prop.put("cursor", cursor);
}
for (int i : color.keySet()) { for (int i : color.keySet()) {
prop.put("color" + i, color.get(i)); prop.put("color" + i, color.get(i));
} }

View File

@ -36,7 +36,7 @@ public final class TerminalColors {
* <p/> * <p/>
* Highest bit is set if successful, so return value is 0xFF${R}${G}${B}. Return 0 if failed. * Highest bit is set if successful, so return value is 0xFF${R}${G}${B}. Return 0 if failed.
*/ */
static int parse(String c) { public static int parse(String c) {
try { try {
int skipInitial, skipBetween; int skipInitial, skipBetween;
if (c.charAt(0) == '#') { if (c.charAt(0) == '#') {

View File

@ -91,25 +91,25 @@ public final class TerminalEmulator {
/** Needs to be large enough to contain reasonable OSC 52 pastes. */ /** Needs to be large enough to contain reasonable OSC 52 pastes. */
private static final int MAX_OSC_STRING_LENGTH = 8192; private static final int MAX_OSC_STRING_LENGTH = 8192;
/** DECSET 1 - application cursor keys. */ /** DECSET 1 - application cursorColor keys. */
private static final int DECSET_BIT_APPLICATION_CURSOR_KEYS = 1; private static final int DECSET_BIT_APPLICATION_CURSOR_KEYS = 1;
private static final int DECSET_BIT_REVERSE_VIDEO = 1 << 1; private static final int DECSET_BIT_REVERSE_VIDEO = 1 << 1;
/** /**
* http://www.vt100.net/docs/vt510-rm/DECOM: "When DECOM is set, the home cursor position is at the upper-left * http://www.vt100.net/docs/vt510-rm/DECOM: "When DECOM is set, the home cursorColor position is at the upper-left
* corner of the screen, within the margins. The starting point for line numbers depends on the current top margin * corner of the screen, within the margins. The starting point for line numbers depends on the current top margin
* setting. The cursor cannot move outside of the margins. When DECOM is reset, the home cursor position is at the * setting. The cursorColor cannot move outside of the margins. When DECOM is reset, the home cursorColor position is at the
* upper-left corner of the screen. The starting point for line numbers is independent of the margins. The cursor * upper-left corner of the screen. The starting point for line numbers is independent of the margins. The cursorColor
* can move outside of the margins." * can move outside of the margins."
*/ */
private static final int DECSET_BIT_ORIGIN_MODE = 1 << 2; private static final int DECSET_BIT_ORIGIN_MODE = 1 << 2;
/** /**
* http://www.vt100.net/docs/vt510-rm/DECAWM: "If the DECAWM function is set, then graphic characters received when * http://www.vt100.net/docs/vt510-rm/DECAWM: "If the DECAWM function is set, then graphic characters received when
* the cursor is at the right border of the page appear at the beginning of the next line. Any text on the page * the cursorColor is at the right border of the page appear at the beginning of the next line. Any text on the page
* scrolls up if the cursor is at the end of the scrolling region. If the DECAWM function is reset, then graphic * scrolls up if the cursorColor is at the end of the scrolling region. If the DECAWM function is reset, then graphic
* characters received when the cursor is at the right border of the page replace characters already on the page." * characters received when the cursorColor is at the right border of the page replace characters already on the page."
*/ */
private static final int DECSET_BIT_AUTOWRAP = 1 << 3; private static final int DECSET_BIT_AUTOWRAP = 1 << 3;
/** DECSET 25 - if the cursor should be visible, {@link #isShowingCursor()}. */ /** DECSET 25 - if the cursorColor should be visible, {@link #isShowingCursor()}. */
private static final int DECSET_BIT_SHOWING_CURSOR = 1 << 4; private static final int DECSET_BIT_SHOWING_CURSOR = 1 << 4;
private static final int DECSET_BIT_APPLICATION_KEYPAD = 1 << 5; private static final int DECSET_BIT_APPLICATION_KEYPAD = 1 << 5;
/** DECSET 1000 - if to report mouse press&release events. */ /** DECSET 1000 - if to report mouse press&release events. */
@ -130,7 +130,7 @@ public final class TerminalEmulator {
private String mTitle; private String mTitle;
private final Stack<String> mTitleStack = new Stack<>(); private final Stack<String> mTitleStack = new Stack<>();
/** The cursor position. Between (0,0) and (mRows-1, mColumns-1). */ /** The cursorColor position. Between (0,0) and (mRows-1, mColumns-1). */
private int mCursorRow, mCursorCol; private int mCursorRow, mCursorCol;
private int mCursorStyle = CURSOR_STYLE_BLOCK; private int mCursorStyle = CURSOR_STYLE_BLOCK;
@ -198,14 +198,14 @@ public final class TerminalEmulator {
/** /**
* If the next character to be emitted will be automatically wrapped to the next line. Used to disambiguate the case * If the next character to be emitted will be automatically wrapped to the next line. Used to disambiguate the case
* where the cursor is positioned on the last column (mColumns-1). When standing there, a written character will be * where the cursorColor is positioned on the last column (mColumns-1). When standing there, a written character will be
* output in the last column, the cursor not moving but this flag will be set. When outputting another character * output in the last column, the cursorColor not moving but this flag will be set. When outputting another character
* this will move to the next line. * this will move to the next line.
*/ */
private boolean mAboutToAutoWrap; private boolean mAboutToAutoWrap;
/** /**
* Current foreground and background colors. Can either be a color index in [0,259] or a truecolor (24-bit) value. * Current foregroundColor and backgroundColor colors. Can either be a color index in [0,259] or a truecolor (24-bit) value.
* For a 24-bit value the top byte (0xff000000) is set. * For a 24-bit value the top byte (0xff000000) is set.
* *
* @see TextStyle * @see TextStyle
@ -492,8 +492,8 @@ public final class TerminalEmulator {
// The OSX Terminal.app colors the spaces from the tab_switcher red, but xterm does not. // The OSX Terminal.app colors the spaces from the tab_switcher red, but xterm does not.
// Note that Terminal.app only colors on new cells, in e.g. // Note that Terminal.app only colors on new cells, in e.g.
// printf "\033[41m\t\r\033[42m\tXX\033[0m\n" // printf "\033[41m\t\r\033[42m\tXX\033[0m\n"
// the first cells are created with a red background, but when tabbing over // the first cells are created with a red backgroundColor, but when tabbing over
// them again with a green background they are not overwritten. // them again with a green backgroundColor they are not overwritten.
mCursorCol = nextTabStop(1); mCursorCol = nextTabStop(1);
break; break;
case 10: // Line feed (LF, \n). case 10: // Line feed (LF, \n).
@ -579,7 +579,7 @@ public final class TerminalEmulator {
// If the value of Pt, Pl, Pb, or Pr exceeds the width or height of the active page, then the value // If the value of Pt, Pl, Pb, or Pr exceeds the width or height of the active page, then the value
// is treated as the width or height of that page. // is treated as the width or height of that page.
// If the destination area is partially off the page, then DECCRA clips the off-page data. // If the destination area is partially off the page, then DECCRA clips the off-page data.
// DECCRA does not change the active cursor position." // DECCRA does not change the active cursorColor position."
int topSource = Math.min(getArg(0, 1, true) - 1 + effectiveTopMargin, mRows); int topSource = Math.min(getArg(0, 1, true) - 1 + effectiveTopMargin, mRows);
int leftSource = Math.min(getArg(1, 1, true) - 1 + effectiveLeftMargin, mColumns); int leftSource = Math.min(getArg(1, 1, true) - 1 + effectiveLeftMargin, mColumns);
// Inclusive, so do not subtract one: // Inclusive, so do not subtract one:
@ -756,7 +756,7 @@ public final class TerminalEmulator {
case ESC_CSI_ARGS_SPACE: case ESC_CSI_ARGS_SPACE:
int arg = getArg0(0); int arg = getArg0(0);
switch (b) { switch (b) {
case 'q': // "${CSI}${STYLE} q" - set cursor style (http://www.vt100.net/docs/vt510-rm/DECSCUSR). case 'q': // "${CSI}${STYLE} q" - set cursorColor style (http://www.vt100.net/docs/vt510-rm/DECSCUSR).
switch (arg) { switch (arg) {
case 0: // Blinking block. case 0: // Blinking block.
case 1: // Blinking block. case 1: // Blinking block.
@ -837,9 +837,9 @@ public final class TerminalEmulator {
// k1=F1 function key // k1=F1 function key
// Example: Request for ku is "ESC P + q 6 b 7 5 ESC \", where 6b7d=ku in hexadecimal. // Example: Request for ku is "ESC P + q 6 b 7 5 ESC \", where 6b7d=ku in hexadecimal.
// Xterm response in normal cursor mode: // Xterm response in normal cursorColor mode:
// "<27> P 1 + r 6 b 7 5 = 1 B 5 B 4 1" where 0x1B 0x5B 0x41 = 27 91 65 = ESC [ A // "<27> P 1 + r 6 b 7 5 = 1 B 5 B 4 1" where 0x1B 0x5B 0x41 = 27 91 65 = ESC [ A
// Xterm response in application cursor mode: // Xterm response in application cursorColor mode:
// "<27> P 1 + r 6 b 7 5 = 1 B 5 B 4 1" where 0x1B 0x4F 0x41 = 27 91 65 = ESC 0 A // "<27> P 1 + r 6 b 7 5 = 1 B 5 B 4 1" where 0x1B 0x4F 0x41 = 27 91 65 = ESC 0 A
// #4 is "shift arrow left": // #4 is "shift arrow left":
@ -1038,8 +1038,8 @@ public final class TerminalEmulator {
case 7: // Wrap-around bit, not specific action. case 7: // Wrap-around bit, not specific action.
case 8: // Auto-repeat Keys (DECARM). Do not implement. case 8: // Auto-repeat Keys (DECARM). Do not implement.
case 9: // X10 mouse reporting - outdated. Do not implement. case 9: // X10 mouse reporting - outdated. Do not implement.
case 12: // Control cursor blinking - ignore. case 12: // Control cursorColor blinking - ignore.
case 25: // Hide/show cursor - no action needed, renderer will check with isShowingCursor(). case 25: // Hide/show cursorColor - no action needed, renderer will check with isShowingCursor().
case 40: // Allow 80 => 132 Mode, ignore. case 40: // Allow 80 => 132 Mode, ignore.
case 45: // TODO: Reverse wrap-around. Implement??? case 45: // TODO: Reverse wrap-around. Implement???
case 66: // Application keypad (DECNKM). case 66: // Application keypad (DECNKM).
@ -1060,7 +1060,7 @@ public final class TerminalEmulator {
case 1015: case 1015:
case 1034: // Interpret "meta" key, sets eighth bit. case 1034: // Interpret "meta" key, sets eighth bit.
break; break;
case 1048: // Set: Save cursor as in DECSC. Reset: Restore cursor as in DECRC. case 1048: // Set: Save cursorColor as in DECSC. Reset: Restore cursorColor as in DECRC.
if (setting) if (setting)
saveCursor(); saveCursor();
else else
@ -1069,8 +1069,8 @@ public final class TerminalEmulator {
case 47: case 47:
case 1047: case 1047:
case 1049: { case 1049: {
// Set: Save cursor as in DECSC and use Alternate Screen Buffer, clearing it first. // Set: Save cursorColor as in DECSC and use Alternate Screen Buffer, clearing it first.
// Reset: Use Normal Screen Buffer and restore cursor as in DECRC. // Reset: Use Normal Screen Buffer and restore cursorColor as in DECRC.
TerminalBuffer newScreen = setting ? mAltBuffer : mMainBuffer; TerminalBuffer newScreen = setting ? mAltBuffer : mMainBuffer;
if (newScreen != mScreen) { if (newScreen != mScreen) {
boolean resized = !(newScreen.mColumns == mColumns && newScreen.mScreenRows == mRows); boolean resized = !(newScreen.mColumns == mColumns && newScreen.mScreenRows == mRows);
@ -1081,7 +1081,7 @@ public final class TerminalEmulator {
int row = mSavedStateMain.mSavedCursorRow; int row = mSavedStateMain.mSavedCursorRow;
restoreCursor(); restoreCursor();
if (resized) { if (resized) {
// Restore cursor position _not_ clipped to current screen (let resizeScreen() handle that): // Restore cursorColor position _not_ clipped to current screen (let resizeScreen() handle that):
mCursorCol = col; mCursorCol = col;
mCursorRow = row; mCursorRow = row;
} }
@ -1139,7 +1139,7 @@ public final class TerminalEmulator {
// * modifyCursorKeys (parameter=2): // * modifyCursorKeys (parameter=2):
// Tells how to handle the special case where Control-, Shift-, Alt- or Meta-modifiers are used to add a // Tells how to handle the special case where Control-, Shift-, Alt- or Meta-modifiers are used to add a
// parameter to the escape sequence returned by a cursor-key. The default is "2". // parameter to the escape sequence returned by a cursorColor-key. The default is "2".
// - Set it to -1 to disable it. // - Set it to -1 to disable it.
// - Set it to 0 to use the old/obsolete behavior. // - Set it to 0 to use the old/obsolete behavior.
// - Set it to 1 to prefix modified sequences with CSI. // - Set it to 1 to prefix modified sequences with CSI.
@ -1235,10 +1235,10 @@ public final class TerminalEmulator {
mScreen.blockSet(mLeftMargin, mTopMargin, 1, rows, ' ', TextStyle.encode(mForeColor, mBackColor, 0)); mScreen.blockSet(mLeftMargin, mTopMargin, 1, rows, ' ', TextStyle.encode(mForeColor, mBackColor, 0));
} }
break; break;
case '7': // DECSC save cursor - http://www.vt100.net/docs/vt510-rm/DECSC case '7': // DECSC save cursorColor - http://www.vt100.net/docs/vt510-rm/DECSC
saveCursor(); saveCursor();
break; break;
case '8': // DECRC restore cursor - http://www.vt100.net/docs/vt510-rm/DECRC case '8': // DECRC restore cursorColor - http://www.vt100.net/docs/vt510-rm/DECRC
restoreCursor(); restoreCursor();
break; break;
case '9': // Forward Index (http://www.vt100.net/docs/vt510-rm/DECFI). Move right, insert blank column if end. case '9': // Forward Index (http://www.vt100.net/docs/vt510-rm/DECFI). Move right, insert blank column if end.
@ -1304,7 +1304,7 @@ public final class TerminalEmulator {
} }
} }
/** DECSC save cursor - http://www.vt100.net/docs/vt510-rm/DECSC . See {@link #restoreCursor()}. */ /** DECSC save cursorColor - http://www.vt100.net/docs/vt510-rm/DECSC . See {@link #restoreCursor()}. */
private void saveCursor() { private void saveCursor() {
SavedScreenState state = (mScreen == mMainBuffer) ? mSavedStateMain : mSavedStateAlt; SavedScreenState state = (mScreen == mMainBuffer) ? mSavedStateMain : mSavedStateAlt;
state.mSavedCursorRow = mCursorRow; state.mSavedCursorRow = mCursorRow;
@ -1318,7 +1318,7 @@ public final class TerminalEmulator {
state.mUseLineDrawingUsesG0 = mUseLineDrawingUsesG0; state.mUseLineDrawingUsesG0 = mUseLineDrawingUsesG0;
} }
/** DECRS restore cursor - http://www.vt100.net/docs/vt510-rm/DECRC. See {@link #saveCursor()}. */ /** DECRS restore cursorColor - http://www.vt100.net/docs/vt510-rm/DECRC. See {@link #saveCursor()}. */
private void restoreCursor() { private void restoreCursor() {
SavedScreenState state = (mScreen == mMainBuffer) ? mSavedStateMain : mSavedStateAlt; SavedScreenState state = (mScreen == mMainBuffer) ? mSavedStateMain : mSavedStateAlt;
setCursorRowCol(state.mSavedCursorRow, state.mSavedCursorCol); setCursorRowCol(state.mSavedCursorRow, state.mSavedCursorCol);
@ -1400,7 +1400,7 @@ public final class TerminalEmulator {
blockClear(0, 0, mColumns, mCursorRow); blockClear(0, 0, mColumns, mCursorRow);
blockClear(0, mCursorRow, mCursorCol + 1); blockClear(0, mCursorRow, mCursorCol + 1);
break; break;
case 2: // Erase all of the display - all lines are erased, changed to single-width, and the cursor does not case 2: // Erase all of the display - all lines are erased, changed to single-width, and the cursorColor does not
// move.. // move..
blockClear(0, 0, mColumns, mRows); blockClear(0, 0, mColumns, mRows);
break; break;
@ -1412,10 +1412,10 @@ public final class TerminalEmulator {
break; break;
case 'K': // "CSI{n}K" - Erase in line (EL). case 'K': // "CSI{n}K" - Erase in line (EL).
switch (getArg0(0)) { switch (getArg0(0)) {
case 0: // Erase from the cursor to the end of the line, inclusive (default) case 0: // Erase from the cursorColor to the end of the line, inclusive (default)
blockClear(mCursorCol, mCursorRow, mColumns - mCursorCol); blockClear(mCursorCol, mCursorRow, mColumns - mCursorCol);
break; break;
case 1: // Erase from the start of the screen to the cursor, inclusive. case 1: // Erase from the start of the screen to the cursorColor, inclusive.
blockClear(0, mCursorRow, mCursorCol + 1); blockClear(0, mCursorRow, mCursorCol + 1);
break; break;
case 2: // Erase all of the line. case 2: // Erase all of the line.
@ -1449,8 +1449,8 @@ public final class TerminalEmulator {
case 'P': // "${CSI}{N}P" - delete ${N} characters (DCH). case 'P': // "${CSI}{N}P" - delete ${N} characters (DCH).
{ {
// http://www.vt100.net/docs/vt510-rm/DCH: "If ${N} is greater than the number of characters between the // http://www.vt100.net/docs/vt510-rm/DCH: "If ${N} is greater than the number of characters between the
// cursor and the right margin, then DCH only deletes the remaining characters. // cursorColor and the right margin, then DCH only deletes the remaining characters.
// As characters are deleted, the remaining characters between the cursor and right margin move to the left. // As characters are deleted, the remaining characters between the cursorColor and right margin move to the left.
// Character attributes move with the characters. The terminal adds blank spaces with no visual character // Character attributes move with the characters. The terminal adds blank spaces with no visual character
// attributes at the right margin. DCH has no effect outside the scrolling margins." // attributes at the right margin. DCH has no effect outside the scrolling margins."
mAboutToAutoWrap = false; mAboutToAutoWrap = false;
@ -1555,7 +1555,7 @@ public final class TerminalEmulator {
break; break;
case 6: // Cursor position report (CPR): case 6: // Cursor position report (CPR):
// Answer is ESC [ y ; x R, where x,y is // Answer is ESC [ y ; x R, where x,y is
// the cursor location. // the cursorColor location.
mSession.write(String.format(Locale.US, "\033[%d;%dR", mCursorRow + 1, mCursorCol + 1)); mSession.write(String.format(Locale.US, "\033[%d;%dR", mCursorRow + 1, mCursorCol + 1));
break; break;
default: default:
@ -1573,7 +1573,7 @@ public final class TerminalEmulator {
// Also require that top + 2 <= bottom. // Also require that top + 2 <= bottom.
mTopMargin = Math.max(0, Math.min(getArg0(1) - 1, mRows - 2)); mTopMargin = Math.max(0, Math.min(getArg0(1) - 1, mRows - 2));
mBottomMargin = Math.max(mTopMargin + 2, Math.min(getArg1(mRows), mRows)); mBottomMargin = Math.max(mTopMargin + 2, Math.min(getArg1(mRows), mRows));
// DECSTBM moves the cursor to column 1, line 1 of the page respecting origin mode. // DECSTBM moves the cursorColor to column 1, line 1 of the page respecting origin mode.
setCursorPosition(0, 0); setCursorPosition(0, 0);
} }
break; break;
@ -1582,10 +1582,10 @@ public final class TerminalEmulator {
// Set left and right margins (DECSLRM - http://www.vt100.net/docs/vt510-rm/DECSLRM). // Set left and right margins (DECSLRM - http://www.vt100.net/docs/vt510-rm/DECSLRM).
mLeftMargin = Math.min(getArg0(1) - 1, mColumns - 2); mLeftMargin = Math.min(getArg0(1) - 1, mColumns - 2);
mRightMargin = Math.max(mLeftMargin + 1, Math.min(getArg1(mColumns), mColumns)); mRightMargin = Math.max(mLeftMargin + 1, Math.min(getArg1(mColumns), mColumns));
// DECSLRM moves the cursor to column 1, line 1 of the page. // DECSLRM moves the cursorColor to column 1, line 1 of the page.
setCursorPosition(0, 0); setCursorPosition(0, 0);
} else { } else {
// Save cursor (ANSI.SYS), available only when DECLRMM is disabled. // Save cursorColor (ANSI.SYS), available only when DECLRMM is disabled.
saveCursor(); saveCursor();
} }
break; break;
@ -1632,7 +1632,7 @@ public final class TerminalEmulator {
break; break;
} }
break; break;
case 'u': // Restore cursor (ANSI.SYS). case 'u': // Restore cursorColor (ANSI.SYS).
restoreCursor(); restoreCursor();
break; break;
case ' ': case ' ':
@ -1697,7 +1697,7 @@ public final class TerminalEmulator {
} else if (code >= 30 && code <= 37) { } else if (code >= 30 && code <= 37) {
mForeColor = code - 30; mForeColor = code - 30;
} else if (code == 38 || code == 48) { } else if (code == 38 || code == 48) {
// Extended set foreground(38)/background (48) color. // Extended set foregroundColor(38)/backgroundColor (48) color.
// This is followed by either "2;$R;$G;$B" to set a 24-bit color or // This is followed by either "2;$R;$G;$B" to set a 24-bit color or
// "5;$INDEX" to set an indexed color. // "5;$INDEX" to set an indexed color.
if (i + 2 > mArgIndex) continue; if (i + 2 > mArgIndex) continue;
@ -1734,15 +1734,15 @@ public final class TerminalEmulator {
} else { } else {
finishSequenceAndLogError("Invalid ISO-8613-3 SGR first argument: " + firstArg); finishSequenceAndLogError("Invalid ISO-8613-3 SGR first argument: " + firstArg);
} }
} else if (code == 39) { // Set default foreground color. } else if (code == 39) { // Set default foregroundColor color.
mForeColor = TextStyle.COLOR_INDEX_FOREGROUND; mForeColor = TextStyle.COLOR_INDEX_FOREGROUND;
} else if (code >= 40 && code <= 47) { // Set background color. } else if (code >= 40 && code <= 47) { // Set backgroundColor color.
mBackColor = code - 40; mBackColor = code - 40;
} else if (code == 49) { // Set default background color. } else if (code == 49) { // Set default backgroundColor color.
mBackColor = TextStyle.COLOR_INDEX_BACKGROUND; mBackColor = TextStyle.COLOR_INDEX_BACKGROUND;
} else if (code >= 90 && code <= 97) { // Bright foreground colors (aixterm codes). } else if (code >= 90 && code <= 97) { // Bright foregroundColor colors (aixterm codes).
mForeColor = code - 90 + 8; mForeColor = code - 90 + 8;
} else if (code >= 100 && code <= 107) { // Bright background color (aixterm codes). } else if (code >= 100 && code <= 107) { // Bright backgroundColor color (aixterm codes).
mBackColor = code - 100 + 8; mBackColor = code - 100 + 8;
} else { } else {
if (LOG_ESCAPE_SEQUENCES) if (LOG_ESCAPE_SEQUENCES)
@ -1842,9 +1842,9 @@ public final class TerminalEmulator {
if (endOfInput) break; if (endOfInput) break;
} }
break; break;
case 10: // Set foreground color. case 10: // Set foregroundColor color.
case 11: // Set background color. case 11: // Set backgroundColor color.
case 12: // Set cursor color. case 12: // Set cursorColor color.
int specialIndex = TextStyle.COLOR_INDEX_FOREGROUND + (value - 10); int specialIndex = TextStyle.COLOR_INDEX_FOREGROUND + (value - 10);
int lastSemiIndex = 0; int lastSemiIndex = 0;
for (int charIndex = 0; ; charIndex++) { for (int charIndex = 0; ; charIndex++) {
@ -1910,9 +1910,9 @@ public final class TerminalEmulator {
} }
} }
break; break;
case 110: // Reset foreground color. case 110: // Reset foregroundColor color.
case 111: // Reset background color. case 111: // Reset backgroundColor color.
case 112: // Reset cursor color. case 112: // Reset cursorColor color.
mColors.reset(TextStyle.COLOR_INDEX_FOREGROUND + (value - 110)); mColors.reset(TextStyle.COLOR_INDEX_FOREGROUND + (value - 110));
mSession.onColorsChanged(); mSession.onColorsChanged();
break; break;
@ -1949,7 +1949,7 @@ public final class TerminalEmulator {
// http://www.vt100.net/docs/vt510-rm/LNM // http://www.vt100.net/docs/vt510-rm/LNM
break; break;
case 34: case 34:
// Normal cursor visibility - when using TERM=screen, see // Normal cursorColor visibility - when using TERM=screen, see
// http://www.gnu.org/software/screen/manual/html_node/Control-Sequences.html // http://www.gnu.org/software/screen/manual/html_node/Control-Sequences.html
break; break;
default: default:
@ -2210,7 +2210,7 @@ public final class TerminalEmulator {
} }
} }
} else if (cursorInLastColumn && displayWidth == 2) { } else if (cursorInLastColumn && displayWidth == 2) {
// The behaviour when a wide character is output with cursor in the last column when // The behaviour when a wide character is output with cursorColor in the last column when
// autowrap is disabled is not obvious - it's ignored here. // autowrap is disabled is not obvious - it's ignored here.
return; return;
} }
@ -2241,7 +2241,7 @@ public final class TerminalEmulator {
mAboutToAutoWrap = false; mAboutToAutoWrap = false;
} }
/** Set the cursor mode, but limit it to margins if {@link #DECSET_BIT_ORIGIN_MODE} is enabled. */ /** Set the cursorColor mode, but limit it to margins if {@link #DECSET_BIT_ORIGIN_MODE} is enabled. */
private void setCursorColRespectingOriginMode(int col) { private void setCursorColRespectingOriginMode(int col) {
setCursorPosition(col, mCursorRow); setCursorPosition(col, mCursorRow);
} }
@ -2294,6 +2294,11 @@ public final class TerminalEmulator {
mSession.onColorsChanged(); mSession.onColorsChanged();
} }
public void setColorScheme(TerminalColorScheme colorScheme) {
mColors.reset(colorScheme);
mSession.onColorsChanged();
}
public String getSelectedText(int x1, int y1, int x2, int y2) { public String getSelectedText(int x1, int y1, int x2, int y2) {
return mScreen.getSelectedText(x1, y1, x2, y2); return mScreen.getSelectedText(x1, y1, x2, y2);
} }
@ -2325,7 +2330,7 @@ public final class TerminalEmulator {
/** http://www.vt100.net/docs/vt510-rm/DECSC */ /** http://www.vt100.net/docs/vt510-rm/DECSC */
static final class SavedScreenState { static final class SavedScreenState {
/** Saved state of the cursor position, Used to implement the save/restore cursor position escape sequences. */ /** Saved state of the cursorColor position, Used to implement the save/restore cursorColor position escape sequences. */
int mSavedCursorRow, mSavedCursorCol; int mSavedCursorRow, mSavedCursorCol;
int mSavedEffect, mSavedForeColor, mSavedBackColor; int mSavedEffect, mSavedForeColor, mSavedBackColor;
int mSavedDecFlags; int mSavedDecFlags;

View File

@ -2,15 +2,15 @@ package io.neoterm.backend;
/** /**
* <p> * <p>
* Encodes effects, foreground and background colors into a 64 bit long, which are stored for each cell in a terminal * Encodes effects, foregroundColor and backgroundColor colors into a 64 bit long, which are stored for each cell in a terminal
* row in {@link TerminalRow#mStyle}. * row in {@link TerminalRow#mStyle}.
* </p> * </p>
* <p> * <p>
* The bit layout is: * The bit layout is:
* </p> * </p>
* - 16 flags (11 currently used). * - 16 flags (11 currently used).
* - 24 for foreground color (only 9 first bits if a color index). * - 24 for foregroundColor color (only 9 first bits if a color index).
* - 24 for background color (only 9 first bits if a color index). * - 24 for backgroundColor color (only 9 first bits if a color index).
*/ */
public final class TextStyle { public final class TextStyle {
@ -31,19 +31,19 @@ public final class TextStyle {
public final static int CHARACTER_ATTRIBUTE_PROTECTED = 1 << 7; public final static int CHARACTER_ATTRIBUTE_PROTECTED = 1 << 7;
/** Dim colors. Also known as faint or half intensity. */ /** Dim colors. Also known as faint or half intensity. */
public final static int CHARACTER_ATTRIBUTE_DIM = 1 << 8; public final static int CHARACTER_ATTRIBUTE_DIM = 1 << 8;
/** If true (24-bit) color is used for the cell for foreground. */ /** If true (24-bit) color is used for the cell for foregroundColor. */
private final static int CHARACTER_ATTRIBUTE_TRUECOLOR_FOREGROUND = 1 << 9; private final static int CHARACTER_ATTRIBUTE_TRUECOLOR_FOREGROUND = 1 << 9;
/** If true (24-bit) color is used for the cell for foreground. */ /** If true (24-bit) color is used for the cell for foregroundColor. */
private final static int CHARACTER_ATTRIBUTE_TRUECOLOR_BACKGROUND= 1 << 10; private final static int CHARACTER_ATTRIBUTE_TRUECOLOR_BACKGROUND= 1 << 10;
public final static int COLOR_INDEX_FOREGROUND = 256; public final static int COLOR_INDEX_FOREGROUND = 256;
public final static int COLOR_INDEX_BACKGROUND = 257; public final static int COLOR_INDEX_BACKGROUND = 257;
public final static int COLOR_INDEX_CURSOR = 258; public final static int COLOR_INDEX_CURSOR = 258;
/** The 256 standard color entries and the three special (foreground, background and cursor) ones. */ /** The 256 standard color entries and the three special (foregroundColor, backgroundColor and cursorColor) ones. */
public final static int NUM_INDEXED_COLORS = 259; public final static int NUM_INDEXED_COLORS = 259;
/** Normal foreground and background colors and no effects. */ /** Normal foregroundColor and backgroundColor colors and no effects. */
final static long NORMAL = encode(COLOR_INDEX_FOREGROUND, COLOR_INDEX_BACKGROUND, 0); final static long NORMAL = encode(COLOR_INDEX_FOREGROUND, COLOR_INDEX_BACKGROUND, 0);
static long encode(int foreColor, int backColor, int effect) { static long encode(int foreColor, int backColor, int effect) {

View File

@ -1,25 +1,120 @@
package io.neoterm.customize.color package io.neoterm.customize.color
import android.content.Context import android.content.Context
import io.neoterm.backend.TerminalEmulator import io.neoterm.R
import io.neoterm.customize.NeoTermPath import io.neoterm.preference.NeoPreference
import io.neoterm.preference.NeoTermPath
import io.neoterm.utils.FileUtils
import io.neoterm.view.ExtraKeysView
import io.neoterm.view.TerminalView
import java.io.File import java.io.File
import java.io.FileOutputStream
/** /**
* @author kiva * @author kiva
*/ */
object ColorSchemeManager { object ColorSchemeManager {
private const val DEFAULT_COLOR_NAME = "Default"
private lateinit var DEFAULT_COLOR: NeoColorScheme
private lateinit var colors: MutableMap<String, NeoColorScheme>
fun init(context: Context) { fun init(context: Context) {
File(NeoTermPath.COLORS_PATH).mkdirs() File(NeoTermPath.COLORS_PATH).mkdirs()
} colors = mutableMapOf()
fun applyColorScheme(emulator: TerminalEmulator?, colorScheme: NeoColorScheme?) { val defaultColorFile = colorFile(DEFAULT_COLOR_NAME)
if (emulator != null && colorScheme != null) { if (!defaultColorFile.exists()) {
colorScheme.applyLocal(emulator) if (extractDefaultColor(context, defaultColorFile)) {
DEFAULT_COLOR = DefaultColorScheme
colors[DEFAULT_COLOR.colorName] = DEFAULT_COLOR
return
} }
} }
fun applyGlobalColorScheme(colorScheme: NeoColorScheme?) { if (!refreshColorList()) {
colorScheme?.applyGlobal() DEFAULT_COLOR = DefaultColorScheme
colors[DEFAULT_COLOR.colorName] = DEFAULT_COLOR
}
}
private fun extractDefaultColor(context: Context, defaultColorFile: File): Boolean {
try {
val prop = DefaultColorScheme.createConfig()
FileOutputStream(defaultColorFile).use {
prop.store(it, "Created by NeoColorSchemeManager")
}
val asset = context.assets
for (i in asset.list("colors")) {
val targetFile = File(NeoTermPath.COLORS_PATH, i)
if (!targetFile.exists()) {
asset.open("colors/$i").use {
FileUtils.writeFile(targetFile, it)
}
}
}
return true
} catch (e: Exception) {
return false
}
}
fun refreshColorList(): Boolean {
colors.clear()
val colorDir = File(NeoTermPath.COLORS_PATH)
for (file in colorDir.listFiles({ pathname -> pathname.name.endsWith(".color") })) {
val colorName = colorName(file)
val color = NeoColorScheme(colorName)
color.parseConfig(file)
colors.put(colorName, color)
}
if (colors.containsKey(DEFAULT_COLOR_NAME)) {
DEFAULT_COLOR = colors[DEFAULT_COLOR_NAME]!!
return true
}
return false
}
fun applyColorScheme(view: TerminalView?, extraKeysView: ExtraKeysView?, colorScheme: NeoColorScheme?) {
if (view != null && colorScheme != null) {
colorScheme.applyColors(view, extraKeysView)
}
}
private fun colorFile(colorName: String): File {
return File("${NeoTermPath.COLORS_PATH}/$colorName.color")
}
private fun colorName(colorFile: File): String {
return colorFile.nameWithoutExtension
}
fun getCurrentColorScheme(): NeoColorScheme {
return colors[getCurrentColorName()]!!
}
fun getCurrentColorName(): String {
var currentColorName = NeoPreference.loadString(R.string.key_customization_color_scheme, DEFAULT_COLOR_NAME)
if (!colors.containsKey(currentColorName)) {
currentColorName = DEFAULT_COLOR_NAME
NeoPreference.store(R.string.key_customization_color_scheme, DEFAULT_COLOR_NAME)
}
return currentColorName
}
fun getColor(colorName: String): NeoColorScheme {
return if (colors.containsKey(colorName)) colors[colorName]!! else getCurrentColorScheme()
}
fun getColorNames(): List<String> {
val list = ArrayList<String>()
list += colors.keys
return list
}
fun setCurrentColor(colorName: String) {
NeoPreference.store(R.string.key_customization_color_scheme, colorName)
} }
} }

View File

@ -0,0 +1,12 @@
package io.neoterm.customize.color
/**
* @author kiva
*/
object DefaultColorScheme : NeoColorScheme("Default") {
init {
foregroundColor = "#ffffff"
backgroundColor = "#14181c"
cursorColor = "#a9aaa9"
}
}

View File

@ -2,24 +2,101 @@ package io.neoterm.customize.color
import io.neoterm.backend.TerminalColorScheme import io.neoterm.backend.TerminalColorScheme
import io.neoterm.backend.TerminalColors import io.neoterm.backend.TerminalColors
import io.neoterm.backend.TerminalEmulator import io.neoterm.view.ExtraKeysView
import io.neoterm.view.TerminalView
import java.io.File
import java.io.FileInputStream
import java.util.*
/** /**
* @author kiva * @author kiva
*/ */
open class NeoColorScheme { open class NeoColorScheme(val colorName: String) {
var foreground: String? = null companion object {
var background: String? = null private const val COLOR_PREFIX = "color"
var cursor: String? = null
const val COLOR_DIM_BLACK = 0
const val COLOR_DIM_RED = 1
const val COLOR_DIM_GREEN = 2
const val COLOR_DIM_YELLOW = 3
const val COLOR_DIM_BLUE = 4
const val COLOR_DIM_MAGENTA = 5
const val COLOR_DIM_CYAN = 6
const val COLOR_DIM_WHITE = 7
const val COLOR_BRIGHT_BLACK = 8
const val COLOR_BRIGHT_RED = 9
const val COLOR_BRIGHT_GREEN = 10
const val COLOR_BRIGHT_YELLOW = 11
const val COLOR_BRIGHT_BLUE = 12
const val COLOR_BRIGHT_MAGENTA = 13
const val COLOR_BRIGHT_CYAN = 14
const val COLOR_BRIGHT_WHITE = 15
}
var foregroundColor: String? = null
var backgroundColor: String? = null
var cursorColor: String? = null
var color: MutableMap<Int, String> = mutableMapOf() var color: MutableMap<Int, String> = mutableMapOf()
fun applyGlobal() { fun setColor(type: Int, color: String) {
TerminalColors.COLOR_SCHEME.updateWith(foreground, background, cursor, color) this.color[type] = color
} }
fun applyLocal(emulator: TerminalEmulator) { fun applyColors(view: TerminalView, extraKeysView: ExtraKeysView?) {
validateColors()
val scheme = TerminalColorScheme() val scheme = TerminalColorScheme()
scheme.updateWith(foreground, background, cursor, color) scheme.updateWith(foregroundColor, backgroundColor, cursorColor, color)
emulator.mColors.reset(scheme) val session = view.currentSession
if (session != null && session.emulator != null) {
session.emulator.setColorScheme(scheme)
}
view.setBackgroundColor(TerminalColors.parse(backgroundColor))
extraKeysView?.setBackgroundColor(TerminalColors.parse(backgroundColor))
extraKeysView?.setTextColor(TerminalColors.parse(foregroundColor))
}
private fun validateColors() {
backgroundColor = backgroundColor ?: DefaultColorScheme.backgroundColor
foregroundColor = foregroundColor ?: DefaultColorScheme.foregroundColor
cursorColor = cursorColor ?: DefaultColorScheme.cursorColor
}
fun createConfig(): Properties {
// TODO: 设计新的配色方案语法,这个只是临时用一下
validateColors()
val prop = Properties()
prop.put("foreground", foregroundColor)
prop.put("background", backgroundColor)
prop.put("cursor", cursorColor)
for (i in color.keys) {
prop.put(COLOR_PREFIX + i, color[i])
}
return prop
}
fun parseConfig(file: File): Boolean {
try {
return FileInputStream(file).use {
val prop = Properties()
prop.load(it)
prop.all {
when (it.key) {
"foreground" -> foregroundColor = it.value as String
"background" -> backgroundColor = it.value as String
"cursor" -> cursorColor = it.value as String
(it.key as String).startsWith(COLOR_PREFIX) -> {
val colorType = (it.key as String).substringAfter(COLOR_PREFIX)
setColor(colorType.toInt(), it.value as String)
}
}
true
}
true
}
} catch (e: Exception) {
return false
}
} }
} }

View File

@ -1,30 +0,0 @@
package io.neoterm.customize.color.builtin
import io.neoterm.customize.color.NeoColorScheme
/**
* @author kiva
*/
class MaterialColorScheme : NeoColorScheme() {
init {
foreground = "#263238"
background = "#263238"
cursor = "#a9aaa5"
color[0] = "#263238"
color[8] = "#37474f"
color[1] = "#ff9800"
color[9] = "#ffa74d"
color[2] = "#8bc34a"
color[10] = "#9ccc65"
color[3] = "#ffc107"
color[11] = "#ffa000"
color[4] = "#03a9f4"
color[12] = "#81d4fa"
color[5] = "#e91e63"
color[13] = "#ad1457"
color[6] = "#009688"
color[14] = "#26a69a"
color[7] = "#cfd8dc"
color[15] = "#eceff1"
}
}

View File

@ -1,7 +1,7 @@
package io.neoterm.customize.eks package io.neoterm.customize.eks
import android.util.Log import android.util.Log
import io.neoterm.customize.NeoTermPath import io.neoterm.preference.NeoTermPath
import io.neoterm.view.ExtraKeysView import io.neoterm.view.ExtraKeysView
import java.io.File import java.io.File

View File

@ -1,5 +1,7 @@
package io.neoterm.customize.eks package io.neoterm.customize.eks
import android.content.Context
import io.neoterm.customize.eks.builtin.BuiltinEksKeys
import io.neoterm.view.ExtraKeysView import io.neoterm.view.ExtraKeysView
/** /**
@ -32,4 +34,9 @@ object EksKeysManager {
this.EKS_KEYS[program] = eksKey this.EKS_KEYS[program] = eksKey
} }
fun init(context: Context) {
BuiltinEksKeys.registerAll()
EksConfigLoader.loadDefinedConfigs()
}
} }

View File

@ -1,6 +1,6 @@
package io.neoterm.customize.eks.builtin package io.neoterm.customize.eks.builtin
import io.neoterm.customize.NeoTermPath import io.neoterm.preference.NeoTermPath
import io.neoterm.customize.eks.EksConfigParser import io.neoterm.customize.eks.EksConfigParser
import io.neoterm.utils.FileUtils import io.neoterm.utils.FileUtils
import java.io.File import java.io.File

View File

@ -3,7 +3,7 @@ package io.neoterm.customize.font
import android.content.Context import android.content.Context
import android.graphics.Typeface import android.graphics.Typeface
import io.neoterm.R import io.neoterm.R
import io.neoterm.customize.NeoTermPath import io.neoterm.preference.NeoTermPath
import io.neoterm.preference.NeoPreference import io.neoterm.preference.NeoPreference
import io.neoterm.utils.FileUtils import io.neoterm.utils.FileUtils
import java.io.File import java.io.File
@ -52,7 +52,7 @@ object FontManager {
var currentFontName = NeoPreference.loadString(R.string.key_customization_font, DEFAULT_FONT_NAME) var currentFontName = NeoPreference.loadString(R.string.key_customization_font, DEFAULT_FONT_NAME)
if (!fonts.containsKey(currentFontName)) { if (!fonts.containsKey(currentFontName)) {
currentFontName = DEFAULT_FONT_NAME currentFontName = DEFAULT_FONT_NAME
NeoPreference.store(R.string.key_customization_font, DEFAULT_FONT) NeoPreference.store(R.string.key_customization_font, DEFAULT_FONT_NAME)
} }
return currentFontName return currentFontName
} }
@ -92,10 +92,11 @@ object FontManager {
private fun extractDefaultFont(context: Context, defaultFontFile: File): Boolean { private fun extractDefaultFont(context: Context, defaultFontFile: File): Boolean {
try { try {
val assets = context.assets val assets = context.assets
val ttfInput = assets.open("$DEFAULT_FONT_NAME.ttf") val input = assets.open("$DEFAULT_FONT_NAME.ttf")
FileUtils.writeFile(defaultFontFile, ttfInput) return input.use {
ttfInput.close() FileUtils.writeFile(defaultFontFile, it)
return true true
}
} catch (e: Exception) { } catch (e: Exception) {
return false return false
} }

View File

@ -22,10 +22,9 @@ import java.util.List;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import io.neoterm.BuildConfig;
import io.neoterm.R; import io.neoterm.R;
import io.neoterm.backend.EmulatorDebug; import io.neoterm.backend.EmulatorDebug;
import io.neoterm.customize.NeoTermPath; import io.neoterm.preference.NeoTermPath;
import io.neoterm.utils.FileUtils; import io.neoterm.utils.FileUtils;
public final class BaseFileInstaller { public final class BaseFileInstaller {

View File

@ -29,16 +29,14 @@ object NeoPermission {
AlertDialog.Builder(context).setMessage("需要存储权限来访问存储设备上的文件") AlertDialog.Builder(context).setMessage("需要存储权限来访问存储设备上的文件")
.setPositiveButton(android.R.string.ok, { _: DialogInterface, _: Int -> .setPositiveButton(android.R.string.ok, { _: DialogInterface, _: Int ->
ActivityCompat.requestPermissions(context, ActivityCompat.requestPermissions(context,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
Manifest.permission.RECEIVE_BOOT_COMPLETED),
requestCode) requestCode)
}) })
.show() .show()
} else { } else {
ActivityCompat.requestPermissions(context, ActivityCompat.requestPermissions(context,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
Manifest.permission.RECEIVE_BOOT_COMPLETED),
requestCode) requestCode)
} }
} }

View File

@ -5,7 +5,6 @@ import android.content.SharedPreferences
import android.preference.PreferenceManager import android.preference.PreferenceManager
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.services.NeoTermService import io.neoterm.services.NeoTermService
import io.neoterm.utils.FileUtils import io.neoterm.utils.FileUtils
import java.io.File import java.io.File

View File

@ -1,4 +1,4 @@
package io.neoterm.customize package io.neoterm.preference
import android.annotation.SuppressLint import android.annotation.SuppressLint
import io.neoterm.BuildConfig import io.neoterm.BuildConfig
@ -9,17 +9,17 @@ import io.neoterm.BuildConfig
object NeoTermPath { object NeoTermPath {
@SuppressLint("SdCardPath") @SuppressLint("SdCardPath")
const val ROOT_PATH = "/data/data/io.neoterm/files" const val ROOT_PATH = "/data/data/io.neoterm/files"
const val USR_PATH = "$ROOT_PATH/usr" const val USR_PATH = "${ROOT_PATH}/usr"
const val HOME_PATH = "$ROOT_PATH/home" const val HOME_PATH = "${ROOT_PATH}/home"
const val CUSTOM_PATH = "$HOME_PATH/.neoterm" const val CUSTOM_PATH = "${HOME_PATH}/.neoterm"
const val EKS_PATH = "$CUSTOM_PATH/eks" const val EKS_PATH = "${CUSTOM_PATH}/eks"
const val EKS_DEFAULT_FILE = "$EKS_PATH/default.eks" const val EKS_DEFAULT_FILE = "${EKS_PATH}/default.eks"
const val FONT_PATH = "$CUSTOM_PATH/font" const val FONT_PATH = "${CUSTOM_PATH}/font"
const val COLORS_PATH = "$CUSTOM_PATH/color" const val COLORS_PATH = "${CUSTOM_PATH}/color"
const val SOURCE_FILE = "$USR_PATH/etc/apt/sources.list" const val SOURCE_FILE = "${USR_PATH}/etc/apt/sources.list"
const val PACKAGE_LIST_DIR = "$USR_PATH/var/lib/apt/lists" const val PACKAGE_LIST_DIR = "${USR_PATH}/var/lib/apt/lists"
private const val RELEASE_SOURCE = "https://mirrors.geekpie.org/neoterm" private const val RELEASE_SOURCE = "https://mirrors.geekpie.org/neoterm"
private const val DEBUG_SOURCE = "http://192.243.117.135" private const val DEBUG_SOURCE = "http://192.243.117.135"
@ -31,6 +31,6 @@ object NeoTermPath {
init { init {
DEFAULT_SOURCE = if (BuildConfig.DEBUG) DEBUG_SOURCE else RELEASE_SOURCE DEFAULT_SOURCE = if (BuildConfig.DEBUG) DEBUG_SOURCE else RELEASE_SOURCE
SERVER_BASE_URL = DEFAULT_SOURCE SERVER_BASE_URL = DEFAULT_SOURCE
SERVER_BOOT_URL = "$SERVER_BASE_URL/boot" SERVER_BOOT_URL = "${SERVER_BASE_URL}/boot"
} }
} }

View File

@ -10,15 +10,11 @@ import android.os.Binder
import android.os.IBinder import android.os.IBinder
import android.support.v4.content.WakefulBroadcastReceiver import android.support.v4.content.WakefulBroadcastReceiver
import android.util.Log import android.util.Log
import android.widget.Toast
import io.neoterm.R import io.neoterm.R
import io.neoterm.backend.EmulatorDebug import io.neoterm.backend.EmulatorDebug
import io.neoterm.backend.TerminalSession import io.neoterm.backend.TerminalSession
import io.neoterm.customize.NeoTermPath
import io.neoterm.preference.NeoPreference
import io.neoterm.ui.NeoTermActivity import io.neoterm.ui.NeoTermActivity
import io.neoterm.utils.TerminalUtils import io.neoterm.utils.TerminalUtils
import java.io.File
import java.util.* import java.util.*
/** /**

View File

@ -17,8 +17,11 @@ import android.widget.ImageButton
import de.mrapp.android.tabswitcher.* import de.mrapp.android.tabswitcher.*
import io.neoterm.R import io.neoterm.R
import io.neoterm.backend.TerminalSession import io.neoterm.backend.TerminalSession
import io.neoterm.customize.color.ColorSchemeManager
import io.neoterm.customize.eks.EksConfigLoader import io.neoterm.customize.eks.EksConfigLoader
import io.neoterm.customize.eks.EksKeysManager
import io.neoterm.customize.eks.builtin.BuiltinEksKeys import io.neoterm.customize.eks.builtin.BuiltinEksKeys
import io.neoterm.customize.font.FontManager
import io.neoterm.customize.setup.BaseFileInstaller import io.neoterm.customize.setup.BaseFileInstaller
import io.neoterm.preference.NeoPermission import io.neoterm.preference.NeoPermission
import io.neoterm.preference.NeoPreference import io.neoterm.preference.NeoPreference
@ -50,6 +53,8 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
ColorSchemeManager.init(this)
FontManager.init(this)
NeoPreference.init(this) NeoPreference.init(this)
NeoPermission.initAppPermission(this, NeoPermission.REQUEST_APP_PERMISSION) NeoPermission.initAppPermission(this, NeoPermission.REQUEST_APP_PERMISSION)
@ -151,8 +156,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
private fun initShortcutKeys() { private fun initShortcutKeys() {
Thread { Thread {
BuiltinEksKeys.registerAll() EksKeysManager.init(this)
EksConfigLoader.loadDefinedConfigs()
}.start() }.start()
} }
@ -250,6 +254,13 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (key == getString(R.string.key_ui_fullscreen)) { if (key == getString(R.string.key_ui_fullscreen)) {
setFullScreenMode(NeoPreference.loadBoolean(key, false)) setFullScreenMode(NeoPreference.loadBoolean(key, false))
} else if (key == getString(R.string.key_customization_color_scheme)) {
if (tabSwitcher.count > 0) {
val tab = tabSwitcher.selectedTab
if (tab is TermTab) {
tab.updateColorScheme()
}
}
} }
} }

View File

@ -2,6 +2,7 @@ package io.neoterm.ui.customization
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar import android.support.v7.widget.Toolbar
@ -13,13 +14,15 @@ import android.widget.Spinner
import android.widget.Toast import android.widget.Toast
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.color.ColorSchemeManager
import io.neoterm.preference.NeoTermPath
import io.neoterm.customize.font.FontManager import io.neoterm.customize.font.FontManager
import io.neoterm.utils.FileUtils import io.neoterm.utils.FileUtils
import io.neoterm.utils.MediaUtils import io.neoterm.utils.MediaUtils
import io.neoterm.utils.TerminalUtils import io.neoterm.utils.TerminalUtils
import io.neoterm.view.BasicSessionCallback import io.neoterm.view.BasicSessionCallback
import io.neoterm.view.BasicViewClient import io.neoterm.view.BasicViewClient
import io.neoterm.view.ExtraKeysView
import io.neoterm.view.TerminalView import io.neoterm.view.TerminalView
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
@ -32,6 +35,7 @@ class CustomizationActivity : AppCompatActivity() {
lateinit var viewClient: BasicViewClient lateinit var viewClient: BasicViewClient
lateinit var sessionCallback: BasicSessionCallback lateinit var sessionCallback: BasicSessionCallback
lateinit var session: TerminalSession lateinit var session: TerminalSession
lateinit var extraKeysView: ExtraKeysView
val REQUEST_SELECT_FONT = 22222 val REQUEST_SELECT_FONT = 22222
val REQUEST_SELECT_COLOR = 22223 val REQUEST_SELECT_COLOR = 22223
@ -39,11 +43,17 @@ class CustomizationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.ui_customization) setContentView(R.layout.ui_customization)
// ensure that folders and files are exist
ColorSchemeManager.init(this)
FontManager.init(this)
val toolbar = findViewById(R.id.custom_toolbar) as Toolbar val toolbar = findViewById(R.id.custom_toolbar) as Toolbar
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
terminalView = findViewById(R.id.terminal_view) as TerminalView terminalView = findViewById(R.id.terminal_view) as TerminalView
extraKeysView = findViewById(R.id.custom_extra_keys) as ExtraKeysView
viewClient = BasicViewClient(terminalView) viewClient = BasicViewClient(terminalView)
sessionCallback = BasicSessionCallback(terminalView) sessionCallback = BasicSessionCallback(terminalView)
TerminalUtils.setupTerminalView(terminalView, viewClient) TerminalUtils.setupTerminalView(terminalView, viewClient)
@ -68,16 +78,33 @@ class CustomizationActivity : AppCompatActivity() {
private fun setupSpinners() { private fun setupSpinners() {
FontManager.refreshFontList() FontManager.refreshFontList()
setupSpinner(R.id.custom_font_spinner, FontManager.getFontNames(), FontManager.getCurrentFontName(), object : AdapterView.OnItemSelectedListener { setupSpinner(R.id.custom_font_spinner, FontManager.getFontNames(),
FontManager.getCurrentFontName(), object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) { override fun onNothingSelected(parent: AdapterView<*>?) {
} }
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val fontName = parent!!.adapter!!.getItem(position) as String val fontName = parent!!.adapter!!.getItem(position) as String
terminalView.setTypeface(FontManager.getFont(fontName).getTypeFace()) val typeface = FontManager.getFont(fontName).getTypeFace()
terminalView.setTypeface(typeface)
extraKeysView.setTypeface(typeface)
FontManager.setCurrentFont(fontName) FontManager.setCurrentFont(fontName)
} }
}) })
ColorSchemeManager.refreshColorList()
setupSpinner(R.id.custom_color_spinner, ColorSchemeManager.getColorNames(),
ColorSchemeManager.getCurrentColorName(), object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val colorName = parent!!.adapter!!.getItem(position) as String
val color = ColorSchemeManager.getColor(colorName)
ColorSchemeManager.applyColorScheme(terminalView, extraKeysView, color)
ColorSchemeManager.setCurrentColor(colorName)
}
})
} }
private fun setupSpinner(id: Int, data: List<String>, selected: String, listener: AdapterView.OnItemSelectedListener) { private fun setupSpinner(id: Int, data: List<String>, selected: String, listener: AdapterView.OnItemSelectedListener) {

View File

@ -23,7 +23,7 @@ import android.widget.Toast
import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import io.neoterm.R import io.neoterm.R
import io.neoterm.customize.NeoTermPath import io.neoterm.preference.NeoTermPath
import io.neoterm.customize.pm.NeoPackageManager import io.neoterm.customize.pm.NeoPackageManager
import io.neoterm.preference.NeoPreference import io.neoterm.preference.NeoPreference
import io.neoterm.ui.pm.adapter.PackageAdapter import io.neoterm.ui.pm.adapter.PackageAdapter

View File

@ -4,10 +4,12 @@ import android.content.Context
import android.widget.Toast import android.widget.Toast
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.color.ColorSchemeManager
import io.neoterm.preference.NeoTermPath
import io.neoterm.customize.font.FontManager import io.neoterm.customize.font.FontManager
import io.neoterm.preference.NeoPreference import io.neoterm.preference.NeoPreference
import io.neoterm.view.BasicViewClient import io.neoterm.view.BasicViewClient
import io.neoterm.view.ExtraKeysView
import io.neoterm.view.TerminalView import io.neoterm.view.TerminalView
import java.io.File import java.io.File
@ -15,14 +17,21 @@ import java.io.File
* @author kiva * @author kiva
*/ */
object TerminalUtils { object TerminalUtils {
fun setupTerminalView(terminalView: TerminalView, terminalViewClient: BasicViewClient? = null) { fun setupTerminalView(terminalView: TerminalView?, terminalViewClient: BasicViewClient? = null) {
terminalView.textSize = NeoPreference.loadInt(NeoPreference.KEY_FONT_SIZE, 30) terminalView?.textSize = NeoPreference.loadInt(NeoPreference.KEY_FONT_SIZE, 30)
terminalView.setTypeface(FontManager.getCurrentFont().getTypeFace()) terminalView?.setTypeface(FontManager.getCurrentFont().getTypeFace())
if (terminalViewClient != null) { if (terminalViewClient != null) {
terminalView.setOnKeyListener(terminalViewClient) terminalView?.setOnKeyListener(terminalViewClient)
} }
} }
fun setupExtraKeysView(extraKeysView: ExtraKeysView?) {
extraKeysView?.setTypeface(FontManager.getCurrentFont().getTypeFace())
}
fun setupTerminalSession(session: TerminalSession?) {
}
fun createSession(context: Context, executablePath: String?, arguments: Array<String>?, cwd: String?, env: Array<String>?, sessionCallback: TerminalSession.SessionChangedCallback?, systemShell: Boolean): TerminalSession { fun createSession(context: Context, executablePath: String?, arguments: Array<String>?, cwd: String?, env: Array<String>?, sessionCallback: TerminalSession.SessionChangedCallback?, systemShell: Boolean): TerminalSession {
var executablePath = executablePath var executablePath = executablePath
var arguments = arguments var arguments = arguments
@ -51,6 +60,7 @@ object TerminalUtils {
val session = TerminalSession(executablePath, cwd, arguments, val session = TerminalSession(executablePath, cwd, arguments,
env ?: NeoPreference.buildEnvironment(cwd, systemShell, executablePath), env ?: NeoPreference.buildEnvironment(cwd, systemShell, executablePath),
sessionCallback) sessionCallback)
setupTerminalSession(session)
return session return session
} }
} }

View File

@ -25,5 +25,8 @@ class BasicSessionCallback(var terminalView: TerminalView) : TerminalSession.Ses
} }
override fun onColorsChanged(session: TerminalSession?) { override fun onColorsChanged(session: TerminalSession?) {
if (session != null) {
terminalView.onScreenUpdated()
}
} }
} }

View File

@ -1,6 +1,7 @@
package io.neoterm.view; package io.neoterm.view;
import android.content.Context; import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.Gravity; import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
@ -15,10 +16,10 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import io.neoterm.customize.NeoTermPath;
import io.neoterm.customize.font.FontManager;
import io.neoterm.customize.eks.EksConfig; import io.neoterm.customize.eks.EksConfig;
import io.neoterm.customize.eks.EksConfigParser; import io.neoterm.customize.eks.EksConfigParser;
import io.neoterm.customize.font.FontManager;
import io.neoterm.preference.NeoTermPath;
import io.neoterm.utils.FileUtils; import io.neoterm.utils.FileUtils;
import io.neoterm.view.eks.ControlButton; import io.neoterm.view.eks.ControlButton;
import io.neoterm.view.eks.ExtraButton; import io.neoterm.view.eks.ExtraButton;
@ -60,15 +61,15 @@ public final class ExtraKeysView extends LinearLayout {
"define / false\n" + "define / false\n" +
"define | false\n"; "define | false\n";
public static final int NORMAL_TEXT_COLOR = 0xFFFFFFFF; public static int NORMAL_TEXT_COLOR = 0xFFFFFFFF;
public static final int SELECTED_TEXT_COLOR = 0xFF80DEEA; public static int SELECTED_TEXT_COLOR = 0xFF80DEEA;
private List<ExtraButton> builtinExtraKeys; private List<ExtraButton> builtinExtraKeys;
private List<ExtraButton> userDefinedExtraKeys; private List<ExtraButton> userDefinedExtraKeys;
private LinearLayout lineOne; private LinearLayout lineOne;
private LinearLayout lineTwo; private LinearLayout lineTwo;
private Typeface typeface;
public ExtraKeysView(Context context, AttributeSet attrs) { public ExtraKeysView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@ -185,7 +186,7 @@ public final class ExtraKeysView extends LinearLayout {
button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle);
} }
button.setTypeface(FontManager.INSTANCE.getCurrentFont().getTypeFace()); button.setTypeface(typeface);
button.setText(extraButton.buttonText); button.setText(extraButton.buttonText);
button.setTextColor(NORMAL_TEXT_COLOR); button.setTextColor(NORMAL_TEXT_COLOR);
button.setAllCaps(false); button.setAllCaps(false);
@ -201,4 +202,13 @@ public final class ExtraKeysView extends LinearLayout {
contentView.addView(button); contentView.addView(button);
} }
public void setTextColor(int textColor) {
NORMAL_TEXT_COLOR = textColor;
updateButtons();
}
public void setTypeface(Typeface typeface) {
this.typeface = typeface;
updateButtons();
}
} }

View File

@ -132,7 +132,7 @@ final class TerminalRenderer {
currentCharIndex += charsForCodePoint; currentCharIndex += charsForCodePoint;
while (currentCharIndex < charsUsedInLine && WcWidth.width(line, currentCharIndex) <= 0) { while (currentCharIndex < charsUsedInLine && WcWidth.width(line, currentCharIndex) <= 0) {
// Eat combining chars so that they are treated as part of the last non-combining code point, // Eat combining chars so that they are treated as part of the last non-combining code point,
// instead of e.g. being considered inside the cursor in the next run. // instead of e.g. being considered inside the cursorColor in the next run.
currentCharIndex += Character.isHighSurrogate(line[currentCharIndex]) ? 2 : 1; currentCharIndex += Character.isHighSurrogate(line[currentCharIndex]) ? 2 : 1;
} }
} }
@ -189,7 +189,7 @@ final class TerminalRenderer {
} }
if (backColor != palette[TextStyle.COLOR_INDEX_BACKGROUND]) { if (backColor != palette[TextStyle.COLOR_INDEX_BACKGROUND]) {
// Only draw non-default background. // Only draw non-default backgroundColor.
mTextPaint.setColor(backColor); mTextPaint.setColor(backColor);
canvas.drawRect(left, y - mFontLineSpacingAndAscent + mFontAscent, right, y, mTextPaint); canvas.drawRect(left, y - mFontLineSpacingAndAscent + mFontAscent, right, y, mTextPaint);
} }

View File

@ -61,5 +61,8 @@ class TermSessionChangedCallback : TerminalSession.SessionChangedCallback {
} }
override fun onColorsChanged(session: TerminalSession?) { override fun onColorsChanged(session: TerminalSession?) {
if (session != null) {
termView?.onScreenUpdated()
}
} }
} }

View File

@ -22,9 +22,9 @@ class TermTab(title: CharSequence) : Tab(title) {
var viewClient: TermViewClient? = null var viewClient: TermViewClient? = null
var toolbar: Toolbar? = null var toolbar: Toolbar? = null
fun changeColorScheme(colorScheme: NeoColorScheme?) { fun updateColorScheme() {
ColorSchemeManager.applyColorScheme(termSession?.emulator, colorScheme) ColorSchemeManager.applyColorScheme(viewClient?.termView, viewClient?.extraKeysView,
viewClient?.extraKeysView?.setBackgroundColor(Color.parseColor(colorScheme?.background)) ColorSchemeManager.getCurrentColorScheme())
} }
fun cleanup() { fun cleanup() {

View File

@ -2,15 +2,14 @@ package io.neoterm.view.tab
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v7.widget.Toolbar
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import de.mrapp.android.tabswitcher.Tab import de.mrapp.android.tabswitcher.Tab
import de.mrapp.android.tabswitcher.TabSwitcher import de.mrapp.android.tabswitcher.TabSwitcher
import de.mrapp.android.tabswitcher.TabSwitcherDecorator import de.mrapp.android.tabswitcher.TabSwitcherDecorator
import io.neoterm.R import io.neoterm.R
import io.neoterm.customize.color.ColorSchemeManager
import io.neoterm.preference.NeoPreference import io.neoterm.preference.NeoPreference
import io.neoterm.ui.NeoTermActivity import io.neoterm.ui.NeoTermActivity
import io.neoterm.utils.TerminalUtils import io.neoterm.utils.TerminalUtils
@ -49,13 +48,18 @@ class TermTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
if (view == null) { if (view == null) {
return return
} }
TerminalUtils.setupTerminalView(view) TerminalUtils.setupTerminalView(view)
TerminalUtils.setupExtraKeysView(extraKeysView)
ColorSchemeManager.applyColorScheme(view, extraKeysView, ColorSchemeManager.getCurrentColorScheme())
context.fullScreenToggleButton.setStatus(NeoPreference.loadBoolean(R.string.key_ui_fullscreen, false)) context.fullScreenToggleButton.setStatus(NeoPreference.loadBoolean(R.string.key_ui_fullscreen, false))
if (tab is TermTab) { if (tab is TermTab) {
val termTab = tab val termTab = tab
// 复用前一次的 TermSession TerminalUtils.setupTerminalSession(termTab.termSession)
// 复用前一次的 TermSessionCallback
termTab.sessionCallback?.termView = view termTab.sessionCallback?.termView = view
termTab.sessionCallback?.termTab = termTab termTab.sessionCallback?.termTab = termTab

View File

@ -22,7 +22,7 @@
q0 -3, 3 -3" q0 -3, 3 -3"
/> />
<!-- Block cursor. --> <!-- BlcursorColorrsor. -->
<path android:fillColor="#000" <path android:fillColor="#000"
android:pathData="M14,14 android:pathData="M14,14
l5,0 l5,0

View File

@ -22,7 +22,7 @@
q0 -3, 3 -3" q0 -3, 3 -3"
/> />
<!-- Block cursor. --> <!-- BlcursorColorrsor. -->
<path android:fillColor="#000" <path android:fillColor="#000"
android:pathData="M14,14 android:pathData="M14,14
l5,0 l5,0