Feature: Customize color schemes
This commit is contained in:
28
app/src/main/assets/colors/dracula.color
Normal file
28
app/src/main/assets/colors/dracula.color
Normal 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
|
||||
|
26
app/src/main/assets/colors/material.color
Normal file
26
app/src/main/assets/colors/material.color
Normal 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
|
21
app/src/main/assets/colors/solarized-dark.color
Normal file
21
app/src/main/assets/colors/solarized-dark.color
Normal 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
|
||||
|
20
app/src/main/assets/colors/solarized-light.color
Normal file
20
app/src/main/assets/colors/solarized-light.color
Normal 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
|
@ -10,6 +10,7 @@ import io.neoterm.customize.font.FontManager
|
||||
class App : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
// ensure that we can access these any time
|
||||
ColorSchemeManager.init(this)
|
||||
FontManager.init(this)
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ public final class TerminalBuffer {
|
||||
*
|
||||
* @param newColumns The number of columns 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) {
|
||||
// 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.
|
||||
int shiftDownOfTopRow = mScreenRows - newRows;
|
||||
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--) {
|
||||
if (cursor[1] >= i) break;
|
||||
int r = externalToInternalRow(i);
|
||||
@ -204,7 +204,7 @@ public final class TerminalBuffer {
|
||||
|
||||
TerminalRow oldLine = oldLines[internalOldRow];
|
||||
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()) {
|
||||
skippedBlankLines++;
|
||||
continue;
|
||||
@ -224,7 +224,7 @@ public final class TerminalBuffer {
|
||||
int lastNonSpaceIndex = 0;
|
||||
boolean justToCursor = false;
|
||||
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();
|
||||
if (cursorAtThisRow) justToCursor = true;
|
||||
} else {
|
||||
@ -287,7 +287,7 @@ public final class TerminalBuffer {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import java.util.Properties;
|
||||
public final class TerminalColorScheme {
|
||||
|
||||
/** 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.
|
||||
0xff000000, // black
|
||||
0xffcd0000, // dim red
|
||||
@ -66,14 +66,20 @@ public final class TerminalColorScheme {
|
||||
}
|
||||
|
||||
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) {
|
||||
Properties prop = new Properties();
|
||||
prop.put("foreground", foreground);
|
||||
prop.put("background", background);
|
||||
prop.put("cursor", cursor);
|
||||
if (foreground != null) {
|
||||
prop.put("foreground", foreground);
|
||||
}
|
||||
if (background != null) {
|
||||
prop.put("background", background);
|
||||
}
|
||||
if (cursor != null) {
|
||||
prop.put("cursor", cursor);
|
||||
}
|
||||
for (int i : color.keySet()) {
|
||||
prop.put("color" + i, color.get(i));
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public final class TerminalColors {
|
||||
* <p/>
|
||||
* 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 {
|
||||
int skipInitial, skipBetween;
|
||||
if (c.charAt(0) == '#') {
|
||||
|
@ -91,25 +91,25 @@ public final class TerminalEmulator {
|
||||
/** Needs to be large enough to contain reasonable OSC 52 pastes. */
|
||||
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_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
|
||||
* setting. The cursor cannot move outside of the margins. When DECOM is reset, the home cursor position is at the
|
||||
* upper-left corner of the screen. The starting point for line numbers is independent of the margins. The cursor
|
||||
* 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 cursorColor
|
||||
* can move outside of the margins."
|
||||
*/
|
||||
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
|
||||
* the cursor 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
|
||||
* characters received when the cursor is at the right border of the page replace characters already 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 cursorColor is at the end of the scrolling region. If the DECAWM function is reset, then graphic
|
||||
* 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;
|
||||
/** 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_APPLICATION_KEYPAD = 1 << 5;
|
||||
/** DECSET 1000 - if to report mouse press&release events. */
|
||||
@ -130,7 +130,7 @@ public final class TerminalEmulator {
|
||||
private String mTitle;
|
||||
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 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
|
||||
* where the cursor 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
|
||||
* 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 cursorColor not moving but this flag will be set. When outputting another character
|
||||
* this will move to the next line.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
// Note that Terminal.app only colors on new cells, in e.g.
|
||||
// printf "\033[41m\t\r\033[42m\tXX\033[0m\n"
|
||||
// the first cells are created with a red background, but when tabbing over
|
||||
// them again with a green background they are not overwritten.
|
||||
// the first cells are created with a red backgroundColor, but when tabbing over
|
||||
// them again with a green backgroundColor they are not overwritten.
|
||||
mCursorCol = nextTabStop(1);
|
||||
break;
|
||||
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
|
||||
// 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.
|
||||
// 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 leftSource = Math.min(getArg(1, 1, true) - 1 + effectiveLeftMargin, mColumns);
|
||||
// Inclusive, so do not subtract one:
|
||||
@ -756,7 +756,7 @@ public final class TerminalEmulator {
|
||||
case ESC_CSI_ARGS_SPACE:
|
||||
int arg = getArg0(0);
|
||||
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) {
|
||||
case 0: // Blinking block.
|
||||
case 1: // Blinking block.
|
||||
@ -837,9 +837,9 @@ public final class TerminalEmulator {
|
||||
// k1=F1 function key
|
||||
|
||||
// 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
|
||||
// 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
|
||||
|
||||
// #4 is "shift arrow left":
|
||||
@ -1038,8 +1038,8 @@ public final class TerminalEmulator {
|
||||
case 7: // Wrap-around bit, not specific action.
|
||||
case 8: // Auto-repeat Keys (DECARM). Do not implement.
|
||||
case 9: // X10 mouse reporting - outdated. Do not implement.
|
||||
case 12: // Control cursor blinking - ignore.
|
||||
case 25: // Hide/show cursor - no action needed, renderer will check with isShowingCursor().
|
||||
case 12: // Control cursorColor blinking - ignore.
|
||||
case 25: // Hide/show cursorColor - no action needed, renderer will check with isShowingCursor().
|
||||
case 40: // Allow 80 => 132 Mode, ignore.
|
||||
case 45: // TODO: Reverse wrap-around. Implement???
|
||||
case 66: // Application keypad (DECNKM).
|
||||
@ -1060,7 +1060,7 @@ public final class TerminalEmulator {
|
||||
case 1015:
|
||||
case 1034: // Interpret "meta" key, sets eighth bit.
|
||||
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)
|
||||
saveCursor();
|
||||
else
|
||||
@ -1069,8 +1069,8 @@ public final class TerminalEmulator {
|
||||
case 47:
|
||||
case 1047:
|
||||
case 1049: {
|
||||
// Set: Save cursor as in DECSC and use Alternate Screen Buffer, clearing it first.
|
||||
// Reset: Use Normal Screen Buffer and restore cursor as in DECRC.
|
||||
// Set: Save cursorColor as in DECSC and use Alternate Screen Buffer, clearing it first.
|
||||
// Reset: Use Normal Screen Buffer and restore cursorColor as in DECRC.
|
||||
TerminalBuffer newScreen = setting ? mAltBuffer : mMainBuffer;
|
||||
if (newScreen != mScreen) {
|
||||
boolean resized = !(newScreen.mColumns == mColumns && newScreen.mScreenRows == mRows);
|
||||
@ -1081,7 +1081,7 @@ public final class TerminalEmulator {
|
||||
int row = mSavedStateMain.mSavedCursorRow;
|
||||
restoreCursor();
|
||||
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;
|
||||
mCursorRow = row;
|
||||
}
|
||||
@ -1139,7 +1139,7 @@ public final class TerminalEmulator {
|
||||
|
||||
// * modifyCursorKeys (parameter=2):
|
||||
// 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 0 to use the old/obsolete behavior.
|
||||
// - 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));
|
||||
}
|
||||
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();
|
||||
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();
|
||||
break;
|
||||
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() {
|
||||
SavedScreenState state = (mScreen == mMainBuffer) ? mSavedStateMain : mSavedStateAlt;
|
||||
state.mSavedCursorRow = mCursorRow;
|
||||
@ -1318,7 +1318,7 @@ public final class TerminalEmulator {
|
||||
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() {
|
||||
SavedScreenState state = (mScreen == mMainBuffer) ? mSavedStateMain : mSavedStateAlt;
|
||||
setCursorRowCol(state.mSavedCursorRow, state.mSavedCursorCol);
|
||||
@ -1400,7 +1400,7 @@ public final class TerminalEmulator {
|
||||
blockClear(0, 0, mColumns, mCursorRow);
|
||||
blockClear(0, mCursorRow, mCursorCol + 1);
|
||||
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..
|
||||
blockClear(0, 0, mColumns, mRows);
|
||||
break;
|
||||
@ -1412,10 +1412,10 @@ public final class TerminalEmulator {
|
||||
break;
|
||||
case 'K': // "CSI{n}K" - Erase in line (EL).
|
||||
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);
|
||||
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);
|
||||
break;
|
||||
case 2: // Erase all of the line.
|
||||
@ -1449,8 +1449,8 @@ public final class TerminalEmulator {
|
||||
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
|
||||
// cursor 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.
|
||||
// cursorColor and the right margin, then DCH only deletes the remaining characters.
|
||||
// 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
|
||||
// attributes at the right margin. DCH has no effect outside the scrolling margins."
|
||||
mAboutToAutoWrap = false;
|
||||
@ -1555,7 +1555,7 @@ public final class TerminalEmulator {
|
||||
break;
|
||||
case 6: // Cursor position report (CPR):
|
||||
// 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));
|
||||
break;
|
||||
default:
|
||||
@ -1573,7 +1573,7 @@ public final class TerminalEmulator {
|
||||
// Also require that top + 2 <= bottom.
|
||||
mTopMargin = Math.max(0, Math.min(getArg0(1) - 1, mRows - 2));
|
||||
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);
|
||||
}
|
||||
break;
|
||||
@ -1582,10 +1582,10 @@ public final class TerminalEmulator {
|
||||
// Set left and right margins (DECSLRM - http://www.vt100.net/docs/vt510-rm/DECSLRM).
|
||||
mLeftMargin = Math.min(getArg0(1) - 1, mColumns - 2);
|
||||
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);
|
||||
} else {
|
||||
// Save cursor (ANSI.SYS), available only when DECLRMM is disabled.
|
||||
// Save cursorColor (ANSI.SYS), available only when DECLRMM is disabled.
|
||||
saveCursor();
|
||||
}
|
||||
break;
|
||||
@ -1632,7 +1632,7 @@ public final class TerminalEmulator {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'u': // Restore cursor (ANSI.SYS).
|
||||
case 'u': // Restore cursorColor (ANSI.SYS).
|
||||
restoreCursor();
|
||||
break;
|
||||
case ' ':
|
||||
@ -1697,7 +1697,7 @@ public final class TerminalEmulator {
|
||||
} else if (code >= 30 && code <= 37) {
|
||||
mForeColor = code - 30;
|
||||
} 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
|
||||
// "5;$INDEX" to set an indexed color.
|
||||
if (i + 2 > mArgIndex) continue;
|
||||
@ -1734,15 +1734,15 @@ public final class TerminalEmulator {
|
||||
} else {
|
||||
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;
|
||||
} else if (code >= 40 && code <= 47) { // Set background color.
|
||||
} else if (code >= 40 && code <= 47) { // Set backgroundColor color.
|
||||
mBackColor = code - 40;
|
||||
} else if (code == 49) { // Set default background color.
|
||||
} else if (code == 49) { // Set default backgroundColor color.
|
||||
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;
|
||||
} 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;
|
||||
} else {
|
||||
if (LOG_ESCAPE_SEQUENCES)
|
||||
@ -1842,9 +1842,9 @@ public final class TerminalEmulator {
|
||||
if (endOfInput) break;
|
||||
}
|
||||
break;
|
||||
case 10: // Set foreground color.
|
||||
case 11: // Set background color.
|
||||
case 12: // Set cursor color.
|
||||
case 10: // Set foregroundColor color.
|
||||
case 11: // Set backgroundColor color.
|
||||
case 12: // Set cursorColor color.
|
||||
int specialIndex = TextStyle.COLOR_INDEX_FOREGROUND + (value - 10);
|
||||
int lastSemiIndex = 0;
|
||||
for (int charIndex = 0; ; charIndex++) {
|
||||
@ -1910,9 +1910,9 @@ public final class TerminalEmulator {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 110: // Reset foreground color.
|
||||
case 111: // Reset background color.
|
||||
case 112: // Reset cursor color.
|
||||
case 110: // Reset foregroundColor color.
|
||||
case 111: // Reset backgroundColor color.
|
||||
case 112: // Reset cursorColor color.
|
||||
mColors.reset(TextStyle.COLOR_INDEX_FOREGROUND + (value - 110));
|
||||
mSession.onColorsChanged();
|
||||
break;
|
||||
@ -1949,7 +1949,7 @@ public final class TerminalEmulator {
|
||||
// http://www.vt100.net/docs/vt510-rm/LNM
|
||||
break;
|
||||
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
|
||||
break;
|
||||
default:
|
||||
@ -2210,7 +2210,7 @@ public final class TerminalEmulator {
|
||||
}
|
||||
}
|
||||
} 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.
|
||||
return;
|
||||
}
|
||||
@ -2241,7 +2241,7 @@ public final class TerminalEmulator {
|
||||
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) {
|
||||
setCursorPosition(col, mCursorRow);
|
||||
}
|
||||
@ -2294,6 +2294,11 @@ public final class TerminalEmulator {
|
||||
mSession.onColorsChanged();
|
||||
}
|
||||
|
||||
public void setColorScheme(TerminalColorScheme colorScheme) {
|
||||
mColors.reset(colorScheme);
|
||||
mSession.onColorsChanged();
|
||||
}
|
||||
|
||||
public String getSelectedText(int x1, int y1, int x2, int y2) {
|
||||
return mScreen.getSelectedText(x1, y1, x2, y2);
|
||||
}
|
||||
@ -2325,7 +2330,7 @@ public final class TerminalEmulator {
|
||||
|
||||
/** http://www.vt100.net/docs/vt510-rm/DECSC */
|
||||
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 mSavedEffect, mSavedForeColor, mSavedBackColor;
|
||||
int mSavedDecFlags;
|
||||
|
@ -2,15 +2,15 @@ package io.neoterm.backend;
|
||||
|
||||
/**
|
||||
* <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}.
|
||||
* </p>
|
||||
* <p>
|
||||
* The bit layout is:
|
||||
* </p>
|
||||
* - 16 flags (11 currently used).
|
||||
* - 24 for foreground color (only 9 first bits if a color index).
|
||||
* - 24 for background color (only 9 first bits if a color index).
|
||||
* - 24 for foregroundColor 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 {
|
||||
|
||||
@ -31,19 +31,19 @@ public final class TextStyle {
|
||||
public final static int CHARACTER_ATTRIBUTE_PROTECTED = 1 << 7;
|
||||
/** Dim colors. Also known as faint or half intensity. */
|
||||
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;
|
||||
/** 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;
|
||||
|
||||
public final static int COLOR_INDEX_FOREGROUND = 256;
|
||||
public final static int COLOR_INDEX_BACKGROUND = 257;
|
||||
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;
|
||||
|
||||
/** 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);
|
||||
|
||||
static long encode(int foreColor, int backColor, int effect) {
|
||||
|
@ -1,25 +1,120 @@
|
||||
package io.neoterm.customize.color
|
||||
|
||||
import android.content.Context
|
||||
import io.neoterm.backend.TerminalEmulator
|
||||
import io.neoterm.customize.NeoTermPath
|
||||
import io.neoterm.R
|
||||
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.FileOutputStream
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
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) {
|
||||
File(NeoTermPath.COLORS_PATH).mkdirs()
|
||||
}
|
||||
colors = mutableMapOf()
|
||||
|
||||
fun applyColorScheme(emulator: TerminalEmulator?, colorScheme: NeoColorScheme?) {
|
||||
if (emulator != null && colorScheme != null) {
|
||||
colorScheme.applyLocal(emulator)
|
||||
val defaultColorFile = colorFile(DEFAULT_COLOR_NAME)
|
||||
if (!defaultColorFile.exists()) {
|
||||
if (extractDefaultColor(context, defaultColorFile)) {
|
||||
DEFAULT_COLOR = DefaultColorScheme
|
||||
colors[DEFAULT_COLOR.colorName] = DEFAULT_COLOR
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!refreshColorList()) {
|
||||
DEFAULT_COLOR = DefaultColorScheme
|
||||
colors[DEFAULT_COLOR.colorName] = DEFAULT_COLOR
|
||||
}
|
||||
}
|
||||
|
||||
fun applyGlobalColorScheme(colorScheme: NeoColorScheme?) {
|
||||
colorScheme?.applyGlobal()
|
||||
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)
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package io.neoterm.customize.color
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
object DefaultColorScheme : NeoColorScheme("Default") {
|
||||
init {
|
||||
foregroundColor = "#ffffff"
|
||||
backgroundColor = "#14181c"
|
||||
cursorColor = "#a9aaa9"
|
||||
}
|
||||
}
|
@ -2,24 +2,101 @@ package io.neoterm.customize.color
|
||||
|
||||
import io.neoterm.backend.TerminalColorScheme
|
||||
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
|
||||
*/
|
||||
open class NeoColorScheme {
|
||||
var foreground: String? = null
|
||||
var background: String? = null
|
||||
var cursor: String? = null
|
||||
open class NeoColorScheme(val colorName: String) {
|
||||
companion object {
|
||||
private const val COLOR_PREFIX = "color"
|
||||
|
||||
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()
|
||||
|
||||
fun applyGlobal() {
|
||||
TerminalColors.COLOR_SCHEME.updateWith(foreground, background, cursor, color)
|
||||
fun setColor(type: Int, color: String) {
|
||||
this.color[type] = color
|
||||
}
|
||||
|
||||
fun applyLocal(emulator: TerminalEmulator) {
|
||||
fun applyColors(view: TerminalView, extraKeysView: ExtraKeysView?) {
|
||||
validateColors()
|
||||
val scheme = TerminalColorScheme()
|
||||
scheme.updateWith(foreground, background, cursor, color)
|
||||
emulator.mColors.reset(scheme)
|
||||
scheme.updateWith(foregroundColor, backgroundColor, cursorColor, color)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package io.neoterm.customize.eks
|
||||
|
||||
import android.util.Log
|
||||
import io.neoterm.customize.NeoTermPath
|
||||
import io.neoterm.preference.NeoTermPath
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
import java.io.File
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.neoterm.customize.eks
|
||||
|
||||
import android.content.Context
|
||||
import io.neoterm.customize.eks.builtin.BuiltinEksKeys
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
|
||||
/**
|
||||
@ -32,4 +34,9 @@ object EksKeysManager {
|
||||
|
||||
this.EKS_KEYS[program] = eksKey
|
||||
}
|
||||
|
||||
fun init(context: Context) {
|
||||
BuiltinEksKeys.registerAll()
|
||||
EksConfigLoader.loadDefinedConfigs()
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
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.utils.FileUtils
|
||||
import java.io.File
|
||||
|
@ -3,7 +3,7 @@ package io.neoterm.customize.font
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import io.neoterm.R
|
||||
import io.neoterm.customize.NeoTermPath
|
||||
import io.neoterm.preference.NeoTermPath
|
||||
import io.neoterm.preference.NeoPreference
|
||||
import io.neoterm.utils.FileUtils
|
||||
import java.io.File
|
||||
@ -52,7 +52,7 @@ object FontManager {
|
||||
var currentFontName = NeoPreference.loadString(R.string.key_customization_font, DEFAULT_FONT_NAME)
|
||||
if (!fonts.containsKey(currentFontName)) {
|
||||
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
|
||||
}
|
||||
@ -92,10 +92,11 @@ object FontManager {
|
||||
private fun extractDefaultFont(context: Context, defaultFontFile: File): Boolean {
|
||||
try {
|
||||
val assets = context.assets
|
||||
val ttfInput = assets.open("$DEFAULT_FONT_NAME.ttf")
|
||||
FileUtils.writeFile(defaultFontFile, ttfInput)
|
||||
ttfInput.close()
|
||||
return true
|
||||
val input = assets.open("$DEFAULT_FONT_NAME.ttf")
|
||||
return input.use {
|
||||
FileUtils.writeFile(defaultFontFile, it)
|
||||
true
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
return false
|
||||
}
|
||||
|
@ -22,10 +22,9 @@ import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import io.neoterm.BuildConfig;
|
||||
import io.neoterm.R;
|
||||
import io.neoterm.backend.EmulatorDebug;
|
||||
import io.neoterm.customize.NeoTermPath;
|
||||
import io.neoterm.preference.NeoTermPath;
|
||||
import io.neoterm.utils.FileUtils;
|
||||
|
||||
public final class BaseFileInstaller {
|
||||
|
@ -29,16 +29,14 @@ object NeoPermission {
|
||||
AlertDialog.Builder(context).setMessage("需要存储权限来访问存储设备上的文件")
|
||||
.setPositiveButton(android.R.string.ok, { _: DialogInterface, _: Int ->
|
||||
ActivityCompat.requestPermissions(context,
|
||||
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.RECEIVE_BOOT_COMPLETED),
|
||||
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
|
||||
requestCode)
|
||||
})
|
||||
.show()
|
||||
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(context,
|
||||
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.RECEIVE_BOOT_COMPLETED),
|
||||
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
|
||||
requestCode)
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import android.content.SharedPreferences
|
||||
import android.preference.PreferenceManager
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.customize.NeoTermPath
|
||||
import io.neoterm.services.NeoTermService
|
||||
import io.neoterm.utils.FileUtils
|
||||
import java.io.File
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.neoterm.customize
|
||||
package io.neoterm.preference
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import io.neoterm.BuildConfig
|
||||
@ -9,17 +9,17 @@ import io.neoterm.BuildConfig
|
||||
object NeoTermPath {
|
||||
@SuppressLint("SdCardPath")
|
||||
const val ROOT_PATH = "/data/data/io.neoterm/files"
|
||||
const val USR_PATH = "$ROOT_PATH/usr"
|
||||
const val HOME_PATH = "$ROOT_PATH/home"
|
||||
const val USR_PATH = "${ROOT_PATH}/usr"
|
||||
const val HOME_PATH = "${ROOT_PATH}/home"
|
||||
|
||||
const val CUSTOM_PATH = "$HOME_PATH/.neoterm"
|
||||
const val EKS_PATH = "$CUSTOM_PATH/eks"
|
||||
const val EKS_DEFAULT_FILE = "$EKS_PATH/default.eks"
|
||||
const val FONT_PATH = "$CUSTOM_PATH/font"
|
||||
const val COLORS_PATH = "$CUSTOM_PATH/color"
|
||||
const val CUSTOM_PATH = "${HOME_PATH}/.neoterm"
|
||||
const val EKS_PATH = "${CUSTOM_PATH}/eks"
|
||||
const val EKS_DEFAULT_FILE = "${EKS_PATH}/default.eks"
|
||||
const val FONT_PATH = "${CUSTOM_PATH}/font"
|
||||
const val COLORS_PATH = "${CUSTOM_PATH}/color"
|
||||
|
||||
const val SOURCE_FILE = "$USR_PATH/etc/apt/sources.list"
|
||||
const val PACKAGE_LIST_DIR = "$USR_PATH/var/lib/apt/lists"
|
||||
const val SOURCE_FILE = "${USR_PATH}/etc/apt/sources.list"
|
||||
const val PACKAGE_LIST_DIR = "${USR_PATH}/var/lib/apt/lists"
|
||||
|
||||
private const val RELEASE_SOURCE = "https://mirrors.geekpie.org/neoterm"
|
||||
private const val DEBUG_SOURCE = "http://192.243.117.135"
|
||||
@ -31,6 +31,6 @@ object NeoTermPath {
|
||||
init {
|
||||
DEFAULT_SOURCE = if (BuildConfig.DEBUG) DEBUG_SOURCE else RELEASE_SOURCE
|
||||
SERVER_BASE_URL = DEFAULT_SOURCE
|
||||
SERVER_BOOT_URL = "$SERVER_BASE_URL/boot"
|
||||
SERVER_BOOT_URL = "${SERVER_BASE_URL}/boot"
|
||||
}
|
||||
}
|
@ -10,15 +10,11 @@ import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import android.support.v4.content.WakefulBroadcastReceiver
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.EmulatorDebug
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.customize.NeoTermPath
|
||||
import io.neoterm.preference.NeoPreference
|
||||
import io.neoterm.ui.NeoTermActivity
|
||||
import io.neoterm.utils.TerminalUtils
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
|
@ -17,8 +17,11 @@ import android.widget.ImageButton
|
||||
import de.mrapp.android.tabswitcher.*
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.customize.color.ColorSchemeManager
|
||||
import io.neoterm.customize.eks.EksConfigLoader
|
||||
import io.neoterm.customize.eks.EksKeysManager
|
||||
import io.neoterm.customize.eks.builtin.BuiltinEksKeys
|
||||
import io.neoterm.customize.font.FontManager
|
||||
import io.neoterm.customize.setup.BaseFileInstaller
|
||||
import io.neoterm.preference.NeoPermission
|
||||
import io.neoterm.preference.NeoPreference
|
||||
@ -50,6 +53,8 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
ColorSchemeManager.init(this)
|
||||
FontManager.init(this)
|
||||
NeoPreference.init(this)
|
||||
NeoPermission.initAppPermission(this, NeoPermission.REQUEST_APP_PERMISSION)
|
||||
|
||||
@ -151,8 +156,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
|
||||
|
||||
private fun initShortcutKeys() {
|
||||
Thread {
|
||||
BuiltinEksKeys.registerAll()
|
||||
EksConfigLoader.loadDefinedConfigs()
|
||||
EksKeysManager.init(this)
|
||||
}.start()
|
||||
}
|
||||
|
||||
@ -250,6 +254,13 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (key == getString(R.string.key_ui_fullscreen)) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package io.neoterm.ui.customization
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
@ -13,13 +14,15 @@ import android.widget.Spinner
|
||||
import android.widget.Toast
|
||||
import io.neoterm.R
|
||||
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.utils.FileUtils
|
||||
import io.neoterm.utils.MediaUtils
|
||||
import io.neoterm.utils.TerminalUtils
|
||||
import io.neoterm.view.BasicSessionCallback
|
||||
import io.neoterm.view.BasicViewClient
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
import io.neoterm.view.TerminalView
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
@ -32,6 +35,7 @@ class CustomizationActivity : AppCompatActivity() {
|
||||
lateinit var viewClient: BasicViewClient
|
||||
lateinit var sessionCallback: BasicSessionCallback
|
||||
lateinit var session: TerminalSession
|
||||
lateinit var extraKeysView: ExtraKeysView
|
||||
|
||||
val REQUEST_SELECT_FONT = 22222
|
||||
val REQUEST_SELECT_COLOR = 22223
|
||||
@ -39,11 +43,17 @@ class CustomizationActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
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
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
terminalView = findViewById(R.id.terminal_view) as TerminalView
|
||||
extraKeysView = findViewById(R.id.custom_extra_keys) as ExtraKeysView
|
||||
viewClient = BasicViewClient(terminalView)
|
||||
sessionCallback = BasicSessionCallback(terminalView)
|
||||
TerminalUtils.setupTerminalView(terminalView, viewClient)
|
||||
@ -68,16 +78,33 @@ class CustomizationActivity : AppCompatActivity() {
|
||||
|
||||
private fun setupSpinners() {
|
||||
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 onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
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) {
|
||||
|
@ -23,7 +23,7 @@ import android.widget.Toast
|
||||
import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
import io.neoterm.R
|
||||
import io.neoterm.customize.NeoTermPath
|
||||
import io.neoterm.preference.NeoTermPath
|
||||
import io.neoterm.customize.pm.NeoPackageManager
|
||||
import io.neoterm.preference.NeoPreference
|
||||
import io.neoterm.ui.pm.adapter.PackageAdapter
|
||||
|
@ -4,10 +4,12 @@ import android.content.Context
|
||||
import android.widget.Toast
|
||||
import io.neoterm.R
|
||||
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.preference.NeoPreference
|
||||
import io.neoterm.view.BasicViewClient
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
import io.neoterm.view.TerminalView
|
||||
import java.io.File
|
||||
|
||||
@ -15,14 +17,21 @@ import java.io.File
|
||||
* @author kiva
|
||||
*/
|
||||
object TerminalUtils {
|
||||
fun setupTerminalView(terminalView: TerminalView, terminalViewClient: BasicViewClient? = null) {
|
||||
terminalView.textSize = NeoPreference.loadInt(NeoPreference.KEY_FONT_SIZE, 30)
|
||||
terminalView.setTypeface(FontManager.getCurrentFont().getTypeFace())
|
||||
fun setupTerminalView(terminalView: TerminalView?, terminalViewClient: BasicViewClient? = null) {
|
||||
terminalView?.textSize = NeoPreference.loadInt(NeoPreference.KEY_FONT_SIZE, 30)
|
||||
terminalView?.setTypeface(FontManager.getCurrentFont().getTypeFace())
|
||||
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 {
|
||||
var executablePath = executablePath
|
||||
var arguments = arguments
|
||||
@ -51,6 +60,7 @@ object TerminalUtils {
|
||||
val session = TerminalSession(executablePath, cwd, arguments,
|
||||
env ?: NeoPreference.buildEnvironment(cwd, systemShell, executablePath),
|
||||
sessionCallback)
|
||||
setupTerminalSession(session)
|
||||
return session
|
||||
}
|
||||
}
|
@ -25,5 +25,8 @@ class BasicSessionCallback(var terminalView: TerminalView) : TerminalSession.Ses
|
||||
}
|
||||
|
||||
override fun onColorsChanged(session: TerminalSession?) {
|
||||
if (session != null) {
|
||||
terminalView.onScreenUpdated()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.neoterm.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
@ -15,10 +16,10 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
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.EksConfigParser;
|
||||
import io.neoterm.customize.font.FontManager;
|
||||
import io.neoterm.preference.NeoTermPath;
|
||||
import io.neoterm.utils.FileUtils;
|
||||
import io.neoterm.view.eks.ControlButton;
|
||||
import io.neoterm.view.eks.ExtraButton;
|
||||
@ -60,15 +61,15 @@ public final class ExtraKeysView extends LinearLayout {
|
||||
"define / false\n" +
|
||||
"define | false\n";
|
||||
|
||||
public static final int NORMAL_TEXT_COLOR = 0xFFFFFFFF;
|
||||
public static final int SELECTED_TEXT_COLOR = 0xFF80DEEA;
|
||||
public static int NORMAL_TEXT_COLOR = 0xFFFFFFFF;
|
||||
public static int SELECTED_TEXT_COLOR = 0xFF80DEEA;
|
||||
|
||||
private List<ExtraButton> builtinExtraKeys;
|
||||
private List<ExtraButton> userDefinedExtraKeys;
|
||||
|
||||
private LinearLayout lineOne;
|
||||
private LinearLayout lineTwo;
|
||||
|
||||
private Typeface typeface;
|
||||
|
||||
public ExtraKeysView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@ -185,7 +186,7 @@ public final class ExtraKeysView extends LinearLayout {
|
||||
button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle);
|
||||
}
|
||||
|
||||
button.setTypeface(FontManager.INSTANCE.getCurrentFont().getTypeFace());
|
||||
button.setTypeface(typeface);
|
||||
button.setText(extraButton.buttonText);
|
||||
button.setTextColor(NORMAL_TEXT_COLOR);
|
||||
button.setAllCaps(false);
|
||||
@ -201,4 +202,13 @@ public final class ExtraKeysView extends LinearLayout {
|
||||
contentView.addView(button);
|
||||
}
|
||||
|
||||
public void setTextColor(int textColor) {
|
||||
NORMAL_TEXT_COLOR = textColor;
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
public void setTypeface(Typeface typeface) {
|
||||
this.typeface = typeface;
|
||||
updateButtons();
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ final class TerminalRenderer {
|
||||
currentCharIndex += charsForCodePoint;
|
||||
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,
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@ -189,7 +189,7 @@ final class TerminalRenderer {
|
||||
}
|
||||
|
||||
if (backColor != palette[TextStyle.COLOR_INDEX_BACKGROUND]) {
|
||||
// Only draw non-default background.
|
||||
// Only draw non-default backgroundColor.
|
||||
mTextPaint.setColor(backColor);
|
||||
canvas.drawRect(left, y - mFontLineSpacingAndAscent + mFontAscent, right, y, mTextPaint);
|
||||
}
|
||||
|
@ -61,5 +61,8 @@ class TermSessionChangedCallback : TerminalSession.SessionChangedCallback {
|
||||
}
|
||||
|
||||
override fun onColorsChanged(session: TerminalSession?) {
|
||||
if (session != null) {
|
||||
termView?.onScreenUpdated()
|
||||
}
|
||||
}
|
||||
}
|
@ -22,9 +22,9 @@ class TermTab(title: CharSequence) : Tab(title) {
|
||||
var viewClient: TermViewClient? = null
|
||||
var toolbar: Toolbar? = null
|
||||
|
||||
fun changeColorScheme(colorScheme: NeoColorScheme?) {
|
||||
ColorSchemeManager.applyColorScheme(termSession?.emulator, colorScheme)
|
||||
viewClient?.extraKeysView?.setBackgroundColor(Color.parseColor(colorScheme?.background))
|
||||
fun updateColorScheme() {
|
||||
ColorSchemeManager.applyColorScheme(viewClient?.termView, viewClient?.extraKeysView,
|
||||
ColorSchemeManager.getCurrentColorScheme())
|
||||
}
|
||||
|
||||
fun cleanup() {
|
||||
|
@ -2,15 +2,14 @@ package io.neoterm.view.tab
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import de.mrapp.android.tabswitcher.Tab
|
||||
import de.mrapp.android.tabswitcher.TabSwitcher
|
||||
import de.mrapp.android.tabswitcher.TabSwitcherDecorator
|
||||
import io.neoterm.R
|
||||
import io.neoterm.customize.color.ColorSchemeManager
|
||||
import io.neoterm.preference.NeoPreference
|
||||
import io.neoterm.ui.NeoTermActivity
|
||||
import io.neoterm.utils.TerminalUtils
|
||||
@ -49,13 +48,18 @@ class TermTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
|
||||
if (view == null) {
|
||||
return
|
||||
}
|
||||
|
||||
TerminalUtils.setupTerminalView(view)
|
||||
TerminalUtils.setupExtraKeysView(extraKeysView)
|
||||
ColorSchemeManager.applyColorScheme(view, extraKeysView, ColorSchemeManager.getCurrentColorScheme())
|
||||
context.fullScreenToggleButton.setStatus(NeoPreference.loadBoolean(R.string.key_ui_fullscreen, false))
|
||||
|
||||
if (tab is TermTab) {
|
||||
val termTab = tab
|
||||
|
||||
// 复用前一次的 TermSession
|
||||
TerminalUtils.setupTerminalSession(termTab.termSession)
|
||||
|
||||
// 复用前一次的 TermSessionCallback
|
||||
termTab.sessionCallback?.termView = view
|
||||
termTab.sessionCallback?.termTab = termTab
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
q0 -3, 3 -3"
|
||||
/>
|
||||
|
||||
<!-- Block cursor. -->
|
||||
<!-- BlcursorColorrsor. -->
|
||||
<path android:fillColor="#000"
|
||||
android:pathData="M14,14
|
||||
l5,0
|
||||
|
@ -22,7 +22,7 @@
|
||||
q0 -3, 3 -3"
|
||||
/>
|
||||
|
||||
<!-- Block cursor. -->
|
||||
<!-- BlcursorColorrsor. -->
|
||||
<path android:fillColor="#000"
|
||||
android:pathData="M14,14
|
||||
l5,0
|
||||
|
Reference in New Issue
Block a user