Feature: FontManager

This commit is contained in:
zt515
2017-07-03 01:28:05 +08:00
parent 249df0a34e
commit d4c1e8e0fb
17 changed files with 214 additions and 50 deletions

View File

@ -34,7 +34,7 @@
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar" />
<activity <activity
android:name=".ui.customization.CustomizationActivity" android:name=".ui.customization.CustomizationActivity"
android:label="@string/pref_ui_customization" android:label="@string/customization_settings"
android:theme="@style/Theme.AppCompat.NoActionBar" android:theme="@style/Theme.AppCompat.NoActionBar"
android:windowSoftInputMode="adjustResize|stateHidden" /> android:windowSoftInputMode="adjustResize|stateHidden" />
<activity <activity

View File

@ -1,8 +1,8 @@
package io.neoterm package io.neoterm
import android.app.Application import android.app.Application
import io.neoterm.customize.color.ColorSchemeManager
import io.neoterm.customize.font.FontManager import io.neoterm.customize.font.FontManager
import io.neoterm.preference.NeoPreference
/** /**
* @author kiva * @author kiva
@ -10,7 +10,7 @@ import io.neoterm.preference.NeoPreference
class App : Application() { class App : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
ColorSchemeManager.init(this)
FontManager.init(this) FontManager.init(this)
NeoPreference.init(this)
} }
} }

View File

@ -12,8 +12,11 @@ object NeoTermPath {
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 EKS_PATH = "$USR_PATH/share/eks" 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 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 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"

View File

@ -1,11 +1,18 @@
package io.neoterm.customize.color package io.neoterm.customize.color
import android.content.Context
import io.neoterm.backend.TerminalEmulator import io.neoterm.backend.TerminalEmulator
import io.neoterm.customize.NeoTermPath
import java.io.File
/** /**
* @author kiva * @author kiva
*/ */
object ColorSchemeManager { object ColorSchemeManager {
fun init(context: Context) {
File(NeoTermPath.COLORS_PATH).mkdirs()
}
fun applyColorScheme(emulator: TerminalEmulator?, colorScheme: NeoColorScheme?) { fun applyColorScheme(emulator: TerminalEmulator?, colorScheme: NeoColorScheme?) {
if (emulator != null && colorScheme != null) { if (emulator != null && colorScheme != null) {
colorScheme.applyLocal(emulator) colorScheme.applyLocal(emulator)

View File

@ -2,17 +2,38 @@ 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.customize.NeoTermPath
import io.neoterm.preference.NeoPreference
import io.neoterm.utils.FileUtils
import java.io.File
/** /**
* @author kiva * @author kiva
*/ */
object FontManager { object FontManager {
private val DEFAULT_FONT_NAME = "UbuntuMono"
private lateinit var DEFAULT_FONT: NeoFont private lateinit var DEFAULT_FONT: NeoFont
private lateinit var fonts: MutableList<String> private lateinit var fonts: MutableMap<String, NeoFont>
fun init(context: Context) { fun init(context: Context) {
fonts = mutableListOf() File(NeoTermPath.FONT_PATH).mkdirs()
DEFAULT_FONT = NeoFont(Typeface.createFromAsset(context.assets, "font.ttf")) fonts = mutableMapOf()
val defaultFontFile = fontFile(DEFAULT_FONT_NAME)
if (!defaultFontFile.exists()) {
if (!extractDefaultFont(context, defaultFontFile)) {
DEFAULT_FONT = loadDefaultFontFromAsset(context)
fonts.put(DEFAULT_FONT_NAME, DEFAULT_FONT)
return
}
}
if (!refreshFontList()) {
DEFAULT_FONT = loadDefaultFontFromAsset(context)
fonts.put(DEFAULT_FONT_NAME, DEFAULT_FONT)
}
} }
fun getDefaultFont(): NeoFont { fun getDefaultFont(): NeoFont {
@ -20,6 +41,71 @@ object FontManager {
} }
fun getCurrentFont(): NeoFont { fun getCurrentFont(): NeoFont {
return getDefaultFont() return fonts[getCurrentFontName()]!!
}
fun setCurrentFont(fontName: String) {
NeoPreference.store(R.string.key_customization_font, fontName)
}
fun getCurrentFontName(): String {
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)
}
return currentFontName
}
fun getFont(fontName: String): NeoFont {
return if (fonts.containsKey(fontName)) fonts[fontName]!! else getCurrentFont()
}
fun getFontNames(): List<String> {
val list = ArrayList<String>()
list += fonts.keys
return list
}
fun refreshFontList(): Boolean {
fonts.clear()
fonts.put("Android Monospace", NeoFont(Typeface.MONOSPACE))
fonts.put("Android Sans Serif", NeoFont(Typeface.SANS_SERIF))
fonts.put("Android Serif", NeoFont(Typeface.SERIF))
val fontDir = File(NeoTermPath.FONT_PATH)
for (file in fontDir.listFiles({ pathname -> pathname.name.endsWith(".ttf") })) {
val fontName = fontName(file)
val font = NeoFont(file)
fonts.put(fontName, font)
}
if (fonts.containsKey(DEFAULT_FONT_NAME)) {
DEFAULT_FONT = fonts[DEFAULT_FONT_NAME]!!
return true
}
return false
}
private fun loadDefaultFontFromAsset(context: Context): NeoFont {
return NeoFont(Typeface.createFromAsset(context.assets, "$DEFAULT_FONT_NAME.ttf"))
}
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
} catch (e: Exception) {
return false
}
}
private fun fontFile(fontName: String): File {
return File("${NeoTermPath.FONT_PATH}/$fontName.ttf")
}
private fun fontName(fontFile: File): String {
return fontFile.nameWithoutExtension
} }
} }

View File

@ -1,13 +1,31 @@
package io.neoterm.customize.font package io.neoterm.customize.font
import android.graphics.Typeface import android.graphics.Typeface
import io.neoterm.view.TerminalView import java.io.File
/** /**
* @author kiva * @author kiva
*/ */
class NeoFont(val typeface: Typeface) { class NeoFont {
fun applyLocal(terminalView: TerminalView?) { private var fontFile: File? = null
terminalView?.setTypeface(typeface) private var typeface: Typeface? = null
constructor(fontFile: File) {
this.fontFile = fontFile
}
constructor(typeface: Typeface) {
this.typeface = typeface
}
fun getTypeFace(): Typeface? {
if (typeface == null && fontFile == null) {
return null
}
if (typeface == null) {
typeface = Typeface.createFromFile(fontFile)
}
return typeface
} }
} }

View File

@ -50,6 +50,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
NeoPreference.init(this)
NeoPermission.initAppPermission(this, NeoPermission.REQUEST_APP_PERMISSION) NeoPermission.initAppPermission(this, NeoPermission.REQUEST_APP_PERMISSION)
val fullscreen = NeoPreference.loadBoolean(R.string.key_ui_fullscreen, false) val fullscreen = NeoPreference.loadBoolean(R.string.key_ui_fullscreen, false)

View File

@ -4,9 +4,14 @@ 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
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
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.NeoTermPath
import io.neoterm.customize.font.FontManager
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
@ -35,6 +40,26 @@ class CustomizationActivity: AppCompatActivity() {
session = TerminalUtils.createSession(this, "${NeoTermPath.USR_PATH}/bin/applets/echo", session = TerminalUtils.createSession(this, "${NeoTermPath.USR_PATH}/bin/applets/echo",
arrayOf("echo", "Hello NeoTerm."), null, null, sessionCallback, false) arrayOf("echo", "Hello NeoTerm."), null, null, sessionCallback, false)
terminalView.attachSession(session) terminalView.attachSession(session)
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())
FontManager.setCurrentFont(fontName)
}
})
}
private fun setupSpinner(id: Int, data: List<String>, selected: String, listener: AdapterView.OnItemSelectedListener) {
val spinner = findViewById(id) as Spinner
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, data)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter
spinner.onItemSelectedListener = listener
spinner.setSelection(if (data.contains(selected)) data.indexOf(selected) else 0)
} }
override fun onDestroy() { override fun onDestroy() {

View File

@ -17,7 +17,7 @@ import java.io.File
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().typeface) terminalView.setTypeface(FontManager.getCurrentFont().getTypeFace())
if (terminalViewClient != null) { if (terminalViewClient != null) {
terminalView.setOnKeyListener(terminalViewClient) terminalView.setOnKeyListener(terminalViewClient)
} }

View File

@ -185,7 +185,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(FontManager.INSTANCE.getCurrentFont().getTypeFace());
button.setText(extraButton.buttonText); button.setText(extraButton.buttonText);
button.setTextColor(NORMAL_TEXT_COLOR); button.setTextColor(NORMAL_TEXT_COLOR);
button.setAllCaps(false); button.setAllCaps(false);

View File

@ -20,28 +20,42 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_margin="@dimen/text_margin" android:layout_margin="@dimen/text_margin"
android:orientation="horizontal"> android:orientation="vertical">
<Button <LinearLayout
style="?buttonBarButtonStyle" android:layout_width="match_parent"
android:layout_width="0dp" android:layout_height="wrap_content"
android:layout_height="match_parent" android:layout_marginBottom="@dimen/text_margin"
android:layout_weight="1.0" android:orientation="horizontal">
android:text="@string/pref_customization_font" />
<Button <TextView
style="?buttonBarButtonStyle" android:layout_width="wrap_content"
android:layout_width="0dp" android:layout_height="wrap_content"
android:layout_height="match_parent" android:text="@string/pref_customization_font" />
android:layout_weight="1.0"
android:text="@string/pref_customization_color_scheme" /> <Spinner
android:id="@+id/custom_font_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pref_customization_color_scheme" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin" />
</LinearLayout>
<Button
style="?buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:text="@string/pref_customization_eks" />
</LinearLayout> </LinearLayout>
<RelativeLayout <RelativeLayout

View File

@ -19,8 +19,8 @@
<string name="pref_package_source">软件源</string> <string name="pref_package_source">软件源</string>
<string name="pref_ui_close_tab_anim_next_tab">向下切换窗口</string> <string name="pref_ui_close_tab_anim_next_tab">向下切换窗口</string>
<string name="pref_ui_close_tab_anim_next_tab_desc">关闭当前窗口时切换到下一个窗口而不是上一个</string> <string name="pref_ui_close_tab_anim_next_tab_desc">关闭当前窗口时切换到下一个窗口而不是上一个</string>
<string name="pref_ui_customization_desc">字体 &amp; 主题 &amp; 拓展键盘</string> <string name="customization_settings_desc">字体,主题,拓展键盘</string>
<string name="pref_ui_customization">个性化</string> <string name="customization_settings">个性化</string>
<string name="pref_ui_fullscreen">全屏</string> <string name="pref_ui_fullscreen">全屏</string>
<string name="pref_ui_hide_toolbar">隐藏标题栏</string> <string name="pref_ui_hide_toolbar">隐藏标题栏</string>
<string name="pref_ui_hide_toolbar_desc">键盘显示时隐藏标题栏</string> <string name="pref_ui_hide_toolbar_desc">键盘显示时隐藏标题栏</string>
@ -47,7 +47,7 @@
<string name="package_details">软件包: %s\n版本: %s\n依赖: %s\n占用空间: %s\n描述: %s\n主页: %s</string> <string name="package_details">软件包: %s\n版本: %s\n依赖: %s\n占用空间: %s\n描述: %s\n主页: %s</string>
<string name="package_list_empty">软件包列表为空,请检查你的软件源</string> <string name="package_list_empty">软件包列表为空,请检查你的软件源</string>
<string name="menu_refresh_list">刷新</string> <string name="menu_refresh_list">刷新</string>
<string name="menu_update">更新 &amp; 刷新</string> <string name="menu_update">更新 刷新</string>
<string-array name="pref_general_program_selection_entries"> <string-array name="pref_general_program_selection_entries">
<item>只使用 NeoTerm</item> <item>只使用 NeoTerm</item>
@ -63,4 +63,7 @@
<item>输入…</item> <item>输入…</item>
</string-array> </string-array>
<string name="pref_customization_eks">拓展键盘</string> <string name="pref_customization_eks">拓展键盘</string>
<string name="general_settings_desc">响铃振动Shell</string>
<string name="ui_settings_desc">全屏,标题栏,快捷键盘</string>
<string name="package_settings_desc">源,更新,升级</string>
</resources> </resources>

View File

@ -8,11 +8,12 @@
<string name="key_ui_fullscreen" translatable="false">neoterm_ui_fullscreen</string> <string name="key_ui_fullscreen" translatable="false">neoterm_ui_fullscreen</string>
<string name="key_ui_hide_toolbar" translatable="false">neoterm_ui_hide_toolbar</string> <string name="key_ui_hide_toolbar" translatable="false">neoterm_ui_hide_toolbar</string>
<string name="key_ui_font" translatable="false">neoterm_ui_font</string>
<string name="key_ui_color_scheme" translatable="false">neoterm_ui_color_scheme</string>
<string name="key_ui_next_tab_anim" translatable="false">neoterm_ui_next_tab_anim</string> <string name="key_ui_next_tab_anim" translatable="false">neoterm_ui_next_tab_anim</string>
<string name="key_ui_suggestions" translatable="false">neoterm_ui_suggestions</string> <string name="key_ui_suggestions" translatable="false">neoterm_ui_suggestions</string>
<string name="key_ui_wide_char_weigh_explicit" translatable="false">neoterm_ui_wide_char_explicit</string> <string name="key_ui_wide_char_weigh_explicit" translatable="false">neoterm_ui_wide_char_explicit</string>
<string name="key_package_source" translatable="false">neoterm_package_source</string> <string name="key_package_source" translatable="false">neoterm_package_source</string>
<string name="key_customization_font" translatable="false">neoterm_ui_font</string>
<string name="key_customization_color_scheme" translatable="false">neoterm_ui_color_scheme</string>
</resources> </resources>

View File

@ -10,8 +10,13 @@
<string name="about">About</string> <string name="about">About</string>
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="general_settings">General Settings</string> <string name="general_settings">General Settings</string>
<string name="general_settings_desc">Bell, Vibrate, Shell</string>
<string name="ui_settings">UI Settings</string> <string name="ui_settings">UI Settings</string>
<string name="ui_settings_desc">FullScreen, Title Bar, Suggestions</string>
<string name="package_settings">Package Settings</string> <string name="package_settings">Package Settings</string>
<string name="package_settings_desc">Source, Updates, Upgrades</string>
<string name="customization_settings_desc">Font, ColorScheme, ExtraKeys</string>
<string name="customization_settings">Customization</string>
<string name="installer_message">Installing</string> <string name="installer_message">Installing</string>
<string name="installer_install_zsh_manually">You may install zsh and setup suggestions by executing: ~/install-zsh.sh</string> <string name="installer_install_zsh_manually">You may install zsh and setup suggestions by executing: ~/install-zsh.sh</string>
@ -26,8 +31,6 @@
<string name="pref_general_shell_desc">Which shell should we use when login</string> <string name="pref_general_shell_desc">Which shell should we use when login</string>
<string name="pref_general_program_selection">Program Selection</string> <string name="pref_general_program_selection">Program Selection</string>
<string name="pref_general_program_selection_desc">When both Neo Term and your Android OS have a program, which one should we choose?</string> <string name="pref_general_program_selection_desc">When both Neo Term and your Android OS have a program, which one should we choose?</string>
<string name="pref_ui_customization_desc">Font &amp; ColorScheme &amp; ExtraKeys</string>
<string name="pref_ui_customization">Customization</string>
<string name="pref_ui_fullscreen">Full Screen</string> <string name="pref_ui_fullscreen">Full Screen</string>
<string name="pref_ui_hide_toolbar">Hide Toolbar</string> <string name="pref_ui_hide_toolbar">Hide Toolbar</string>
<string name="pref_ui_hide_toolbar_desc">Hide toolbar when keyboard is showing</string> <string name="pref_ui_hide_toolbar_desc">Hide toolbar when keyboard is showing</string>
@ -54,7 +57,7 @@
<string name="package_details">Package: %s\nVersion: %s\nDepends: %s\nInstalled Size: %s\nDescription: %s\nHome Page: %s</string> <string name="package_details">Package: %s\nVersion: %s\nDepends: %s\nInstalled Size: %s\nDescription: %s\nHome Page: %s</string>
<string name="package_list_empty">Package list is empty, please check out your source.</string> <string name="package_list_empty">Package list is empty, please check out your source.</string>
<string name="menu_refresh_list">Refresh</string> <string name="menu_refresh_list">Refresh</string>
<string name="menu_update">Update &amp; Refresh</string> <string name="menu_update">Update, Refresh</string>
<string-array name="pref_general_shell_entries" translatable="false"> <string-array name="pref_general_shell_entries" translatable="false">
<item>sh</item> <item>sh</item>

View File

@ -3,6 +3,7 @@
<Preference <Preference
android:icon="@drawable/ic_general_white_36dp" android:icon="@drawable/ic_general_white_36dp"
android:summary="@string/general_settings_desc"
android:title="@string/general_settings"> android:title="@string/general_settings">
<intent <intent
android:targetClass="io.neoterm.ui.settings.GeneralSettingsActivity" android:targetClass="io.neoterm.ui.settings.GeneralSettingsActivity"
@ -11,14 +12,25 @@
<Preference <Preference
android:icon="@drawable/ic_ui_white_36dp" android:icon="@drawable/ic_ui_white_36dp"
android:summary="@string/ui_settings_desc"
android:title="@string/ui_settings"> android:title="@string/ui_settings">
<intent <intent
android:targetClass="io.neoterm.ui.settings.UISettingsActivity" android:targetClass="io.neoterm.ui.settings.UISettingsActivity"
android:targetPackage="io.neoterm" /> android:targetPackage="io.neoterm" />
</Preference> </Preference>
<Preference
android:icon="@drawable/ic_customization_white_36dp"
android:summary="@string/customization_settings_desc"
android:title="@string/customization_settings">
<intent
android:targetClass="io.neoterm.ui.customization.CustomizationActivity"
android:targetPackage="io.neoterm" />
</Preference>
<Preference <Preference
android:icon="@drawable/ic_apps_white_36dp" android:icon="@drawable/ic_apps_white_36dp"
android:summary="@string/package_settings_desc"
android:title="@string/package_settings"> android:title="@string/package_settings">
<intent <intent
android:targetClass="io.neoterm.ui.pm.PackageManagerActivity" android:targetClass="io.neoterm.ui.pm.PackageManagerActivity"

View File

@ -1,14 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:summary="@string/pref_ui_customization_desc"
android:title="@string/pref_ui_customization">
<intent
android:targetClass="io.neoterm.ui.customization.CustomizationActivity"
android:targetPackage="io.neoterm" />
</Preference>
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="@string/key_ui_fullscreen" android:key="@string/key_ui_fullscreen"