diff --git a/app/src/main/assets/editor/theme/dark_plus.json b/app/src/main/assets/editor/theme/dark_plus.json index 9eb65e27..6ad962b9 100644 --- a/app/src/main/assets/editor/theme/dark_plus.json +++ b/app/src/main/assets/editor/theme/dark_plus.json @@ -4,11 +4,10 @@ "colors": { "editor.background": "#1E1E1E", "editor.foreground": "#D4D4D4", - "editor.inactiveSelectionBackground": "#3A3D41", - "editorIndentGuide.background": "#404040", - "editor.selectionHighlightBackground": "#ADD6FF26", + "lineNumber.foreground": "#404040", "imeBar.background": "#dd1e1e1e", - "imeBar.foreground": "#f1f1f1" + "imeBar.foreground": "#f1f1f1", + "editor.selectionHighlightBackground": "#ADD6FF26" }, "tokenColors": [ { diff --git a/app/src/main/assets/editor/theme/light_plus.json b/app/src/main/assets/editor/theme/light_plus.json new file mode 100644 index 00000000..86554ba1 --- /dev/null +++ b/app/src/main/assets/editor/theme/light_plus.json @@ -0,0 +1,537 @@ +{ + "name": "Quiet Light", + "tokenColors": [ + { + "settings": { + "background": "#F5F5F5", + "foreground": "#333333" + } + }, + { + "scope": [ + "meta.embedded", + "source.groovy.embedded" + ], + "settings": { + "background": "#F5F5F5", + "foreground": "#333333" + } + }, + { + "name": "Comments", + "scope": [ + "comment", + "punctuation.definition.comment" + ], + "settings": { + "fontStyle": "italic", + "foreground": "#AAAAAA" + } + }, + { + "name": "Comments: Preprocessor", + "scope": "comment.block.preprocessor", + "settings": { + "fontStyle": "", + "foreground": "#AAAAAA" + } + }, + { + "name": "Comments: Documentation", + "scope": [ + "comment.documentation", + "comment.block.documentation" + ], + "settings": { + "foreground": "#448C27" + } + }, + { + "name": "Invalid - Deprecated", + "scope": "invalid.deprecated", + "settings": { + "background": "#96000014" + } + }, + { + "name": "Invalid - Illegal", + "scope": "invalid.illegal", + "settings": { + "background": "#96000014", + "foreground": "#660000" + } + }, + { + "name": "Operators", + "scope": "keyword.operator", + "settings": { + "foreground": "#777777" + } + }, + { + "name": "Keywords", + "scope": [ + "keyword", + "storage" + ], + "settings": { + "foreground": "#4B83CD" + } + }, + { + "name": "Types", + "scope": [ + "storage.type", + "support.type" + ], + "settings": { + "foreground": "#7A3E9D" + } + }, + { + "name": "Language Constants", + "scope": [ + "constant.language", + "support.constant", + "variable.language" + ], + "settings": { + "foreground": "#AB6526" + } + }, + { + "name": "Variables", + "scope": [ + "variable", + "support.variable" + ], + "settings": { + "foreground": "#7A3E9D" + } + }, + { + "name": "Functions", + "scope": [ + "entity.name.function", + "support.function" + ], + "settings": { + "fontStyle": "bold", + "foreground": "#AA3731" + } + }, + { + "name": "Classes", + "scope": [ + "entity.name.type", + "entity.other.inherited-class", + "support.class" + ], + "settings": { + "fontStyle": "bold", + "foreground": "#7A3E9D" + } + }, + { + "name": "Exceptions", + "scope": "entity.name.exception", + "settings": { + "foreground": "#660000" + } + }, + { + "name": "Sections", + "scope": "entity.name.section", + "settings": { + "fontStyle": "bold" + } + }, + { + "name": "Numbers, Characters", + "scope": [ + "constant.numeric", + "constant.character", + "constant" + ], + "settings": { + "foreground": "#AB6526" + } + }, + { + "name": "Strings", + "scope": "string", + "settings": { + "foreground": "#448C27" + } + }, + { + "name": "Strings: Escape Sequences", + "scope": "constant.character.escape", + "settings": { + "foreground": "#777777" + } + }, + { + "name": "Strings: Regular Expressions", + "scope": "string.regexp", + "settings": { + "foreground": "#4B83CD" + } + }, + { + "name": "Strings: Symbols", + "scope": "constant.other.symbol", + "settings": { + "foreground": "#AB6526" + } + }, + { + "name": "Punctuation", + "scope": "punctuation", + "settings": { + "foreground": "#777777" + } + }, + { + "name": "Embedded Source", + "scope": [ + "string source", + "text source" + ], + "settings": { + "background": "#EAEBE6" + } + }, + { + "name": "-----------------------------------", + "settings": {} + }, + { + "name": "HTML: Doctype Declaration", + "scope": [ + "meta.tag.sgml.doctype", + "meta.tag.sgml.doctype string", + "meta.tag.sgml.doctype entity.name.tag", + "meta.tag.sgml punctuation.definition.tag.html" + ], + "settings": { + "foreground": "#AAAAAA" + } + }, + { + "name": "HTML: Tags", + "scope": [ + "meta.tag", + "punctuation.definition.tag.html", + "punctuation.definition.tag.begin.html", + "punctuation.definition.tag.end.html" + ], + "settings": { + "foreground": "#91B3E0" + } + }, + { + "name": "HTML: Tag Names", + "scope": "entity.name.tag", + "settings": { + "foreground": "#4B83CD" + } + }, + { + "name": "HTML: Attribute Names", + "scope": [ + "meta.tag entity.other.attribute-name", + "entity.other.attribute-name.html" + ], + "settings": { + "fontStyle": "italic", + "foreground": "#8190A0" + } + }, + { + "name": "HTML: Entities", + "scope": [ + "constant.character.entity", + "punctuation.definition.entity" + ], + "settings": { + "foreground": "#AB6526" + } + }, + { + "name": "-----------------------------------", + "settings": {} + }, + { + "name": "CSS: Selectors", + "scope": [ + "meta.selector", + "meta.selector entity", + "meta.selector entity punctuation", + "entity.name.tag.css" + ], + "settings": { + "foreground": "#7A3E9D" + } + }, + { + "name": "CSS: Property Names", + "scope": [ + "meta.property-name", + "support.type.property-name" + ], + "settings": { + "foreground": "#AB6526" + } + }, + { + "name": "CSS: Property Values", + "scope": [ + "meta.property-value", + "meta.property-value constant.other", + "support.constant.property-value" + ], + "settings": { + "foreground": "#448C27" + } + }, + { + "name": "CSS: Important Keyword", + "scope": "keyword.other.important", + "settings": { + "fontStyle": "bold" + } + }, + { + "name": "-----------------------------------", + "settings": {} + }, + { + "name": "Markup: Changed", + "scope": "markup.changed", + "settings": { + "background": "#FFFFDD", + "foreground": "#000000" + } + }, + { + "name": "Markup: Deletion", + "scope": "markup.deleted", + "settings": { + "background": "#FFDDDD", + "foreground": "#000000" + } + }, + { + "name": "Markup: Emphasis", + "scope": "markup.italic", + "settings": { + "fontStyle": "italic" + } + }, + { + "name": "Markup: Error", + "scope": "markup.error", + "settings": { + "background": "#96000014", + "foreground": "#660000" + } + }, + { + "name": "Markup: Insertion", + "scope": "markup.inserted", + "settings": { + "background": "#DDFFDD", + "foreground": "#000000" + } + }, + { + "name": "Markup: Link", + "scope": "meta.link", + "settings": { + "foreground": "#4B83CD" + } + }, + { + "name": "Markup: Output", + "scope": [ + "markup.output", + "markup.raw" + ], + "settings": { + "foreground": "#777777" + } + }, + { + "name": "Markup: Prompt", + "scope": "markup.prompt", + "settings": { + "foreground": "#777777" + } + }, + { + "name": "Markup: Heading", + "scope": "markup.heading", + "settings": { + "foreground": "#AA3731" + } + }, + { + "name": "Markup: Strong", + "scope": "markup.bold", + "settings": { + "fontStyle": "bold" + } + }, + { + "name": "Markup: Traceback", + "scope": "markup.traceback", + "settings": { + "foreground": "#660000" + } + }, + { + "name": "Markup: Underline", + "scope": "markup.underline", + "settings": { + "fontStyle": "underline" + } + }, + { + "name": "Markup Quote", + "scope": "markup.quote", + "settings": { + "foreground": "#7A3E9D" + } + }, + { + "name": "Markup Lists", + "scope": "markup.list", + "settings": { + "foreground": "#4B83CD" + } + }, + { + "name": "Markup Styling", + "scope": [ + "markup.bold", + "markup.italic" + ], + "settings": { + "foreground": "#448C27" + } + }, + { + "name": "Markup Inline", + "scope": "markup.inline.raw", + "settings": { + "fontStyle": "", + "foreground": "#AB6526" + } + }, + { + "name": "-----------------------------------", + "settings": {} + }, + { + "name": "Extra: Diff Range", + "scope": [ + "meta.diff.range", + "meta.diff.index", + "meta.separator" + ], + "settings": { + "background": "#DDDDFF", + "foreground": "#434343" + } + }, + { + "name": "Extra: Diff From", + "scope": "meta.diff.header.from-file", + "settings": { + "background": "#FFDDDD", + "foreground": "#434343" + } + }, + { + "name": "Extra: Diff To", + "scope": "meta.diff.header.to-file", + "settings": { + "background": "#DDFFDD", + "foreground": "#434343" + } + }, + { + "name": "JSX: Tags", + "scope": [ + "punctuation.definition.tag.js", + "punctuation.definition.tag.begin.js", + "punctuation.definition.tag.end.js" + ], + "settings": { + "foreground": "#91B3E0" + } + }, + { + "name": "JSX: InnerText", + "scope": "meta.jsx.children.js", + "settings": { + "foreground": "#333333ff" + } + } + ], + "colors": { + "imeBar.background": "#ddf0f1f2", + "imeBar.foreground": "#222327", + "lineNumber.foreground": "#9DA39A", + "editor.background": "#F5F5F5", + "editor.foreground": "#000000", + "focusBorder": "#A6B39B", + "pickerGroup.foreground": "#A6B39B", + "pickerGroup.border": "#749351", + "list.activeSelectionForeground": "#6c6c6c", + "list.focusBackground": "#CADEB9", + "list.hoverBackground": "#e0e0e0", + "list.activeSelectionBackground": "#c4d9b1", + "list.inactiveSelectionBackground": "#d3dbcd", + "list.highlightForeground": "#9769dc", + "selection.background": "#C9D0D9", + "editorWhitespace.foreground": "#AAAAAA", + "editor.lineHighlightBackground": "#E4F6D4", + "editor.selectionBackground": "#C9D0D9", + "panel.background": "#F5F5F5", + "sideBar.background": "#F2F2F2", + "sideBarSectionHeader.background": "#ede8ef", + "editorLineNumber.foreground": "#9DA39A", + "editorCursor.foreground": "#54494B", + "inputOption.activeBorder": "#adafb7", + "dropdown.background": "#F5F5F5", + "editor.findMatchBackground": "#BF9CAC", + "editor.findMatchHighlightBackground": "#edc9d8", + "peekViewEditor.matchHighlightBackground": "#C2DFE3", + "peekViewTitle.background": "#F2F8FC", + "peekViewEditor.background": "#F2F8FC", + "peekViewResult.background": "#F2F8FC", + "peekView.border": "#705697", + "peekViewResult.matchHighlightBackground": "#93C6D6", + "statusBar.background": "#705697", + "statusBar.noFolderBackground": "#705697", + "statusBar.debuggingBackground": "#705697", + "activityBar.background": "#EDEDF5", + "activityBar.foreground": "#705697", + "activityBarBadge.background": "#705697", + "titleBar.activeBackground": "#c4b7d7", + "button.background": "#705697", + "notification.background": "#442e66", + "editorGroup.dropBackground": "#C9D0D988", + "inputValidation.infoBorder": "#4ec1e5", + "inputValidation.infoBackground": "#f2fcff", + "inputValidation.warningBackground": "#fffee2", + "inputValidation.warningBorder": "#ffe055", + "inputValidation.errorBackground": "#ffeaea", + "inputValidation.errorBorder": "#f1897f", + "errorForeground": "#f1897f", + "badge.background": "#705697AA", + "progressBar.background": "#705697" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/Pref.java b/app/src/main/java/com/stardust/scriptdroid/Pref.java index 2bc6a087..aeeb30b7 100644 --- a/app/src/main/java/com/stardust/scriptdroid/Pref.java +++ b/app/src/main/java/com/stardust/scriptdroid/Pref.java @@ -19,6 +19,8 @@ public class Pref { private static final String KEY_FIRST_SHOW_AD = "En, Today is 17.7.7, but, I'm still love you so...."; private static final String KEY_LAST_SHOW_AD_MILLIS = "But... it seems that...you will not come back any more..."; private static final String KEY_FLOATING_MENU_SHOWN = "17.10.28 I have idea of what you think...maybe...I'm overthinking..."; + private static final String KEY_EDITOR_THEME = "editor.theme"; + private static SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { @@ -147,4 +149,12 @@ public class Pref { public static void setFloatingMenuShown(boolean checked) { def().edit().putBoolean(KEY_FLOATING_MENU_SHOWN, checked).apply(); } + + public static String getCurrentTheme() { + return def().getString(KEY_EDITOR_THEME, null); + } + + public static void setCurrentTheme(String theme) { + def().edit().putString(KEY_EDITOR_THEME, theme).apply(); + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorColors.java b/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorColors.java index d7ddee7e..8f8a66bc 100644 --- a/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorColors.java +++ b/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorColors.java @@ -12,8 +12,8 @@ public class EditorColors { private String mEditorForeground; @SerializedName("editor.inactiveSelectionBackground") private String mEditorInactiveSelectionBackground; - @SerializedName("editorIndentGuide.background") - private String mEditorIndentGuideBackground; + @SerializedName("lineNumber.foreground") + private String mLineNumberForeground; @SerializedName("editor.selectionHighlightBackground") private String mEditorSelectionHighlightBackground; @SerializedName("imeBar.background") @@ -45,12 +45,12 @@ public class EditorColors { mEditorInactiveSelectionBackground = editorInactiveSelectionBackground; } - public String getEditorIndentGuideBackground() { - return mEditorIndentGuideBackground; + public String getLineNumberForeground() { + return mLineNumberForeground; } - public void setEditorIndentGuideBackground(String editorIndentGuideBackground) { - mEditorIndentGuideBackground = editorIndentGuideBackground; + public void setLineNumberForeground(String lineNumberForeground) { + mLineNumberForeground = lineNumberForeground; } public String getEditorSelectionHighlightBackground() { diff --git a/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorTheme.java b/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorTheme.java index fbfd94bb..7c7c0c24 100644 --- a/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorTheme.java +++ b/app/src/main/java/com/stardust/scriptdroid/model/editor/EditorTheme.java @@ -1,8 +1,6 @@ package com.stardust.scriptdroid.model.editor; -import android.graphics.Color; - import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.SerializedName; @@ -11,8 +9,6 @@ import java.io.Reader; import java.util.Collections; import java.util.List; -import static org.mozilla.javascript.Token.*; - public class EditorTheme { private static Gson sGson; diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditorView.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditorView.java index 51199ded..07661df2 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditorView.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditorView.java @@ -16,6 +16,7 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Toast; +import com.afollestad.materialdialogs.MaterialDialog; import com.stardust.autojs.engine.JavaScriptEngine; import com.stardust.autojs.execution.ScriptExecution; import com.stardust.pio.PFiles; @@ -34,6 +35,7 @@ import com.stardust.scriptdroid.ui.edit.editor.CodeEditor; import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardHelper; import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardView; import com.stardust.scriptdroid.ui.edit.theme.Theme; +import com.stardust.scriptdroid.ui.edit.theme.Themes; import com.stardust.scriptdroid.ui.log.LogActivity_; import com.stardust.scriptdroid.ui.widget.EWebView; import com.stardust.scriptdroid.ui.widget.ToolbarMenuItem; @@ -46,6 +48,7 @@ import org.androidannotations.annotations.EViewGroup; import org.androidannotations.annotations.ViewById; import java.io.File; +import java.util.List; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -224,7 +227,9 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC setMenuItemStatus(R.id.save, false); mDocsWebView.getWebView().getSettings().setDisplayZoomControls(true); mDocsWebView.getWebView().loadUrl(Pref.getDocumentationUrl() + "index.html"); - + Themes.getCurrent(getContext()). + observeOn(AndroidSchedulers.mainThread()) + .subscribe(this::setTheme); } private void setUpFunctionsKeyboard() { @@ -267,6 +272,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC mCodeCompletionBar.setTextColor(textColor); mSymbolBar.setTextColor(textColor); mShowFunctionsButton.setColorFilter(textColor); + invalidate(); } public boolean onBackPressed() { @@ -371,7 +377,30 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC } public void selectEditorTheme() { + mEditor.setProgress(true); + Themes.getAllThemes(getContext()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(themes -> { + mEditor.setProgress(false); + selectEditorTheme(themes); + }); + } + private void selectEditorTheme(List themes) { + int i = themes.indexOf(mEditorTheme); + if (i < 0) { + i = 0; + } + new MaterialDialog.Builder(getContext()) + .title(R.string.text_editor_theme) + .items(themes) + .itemsCallbackSingleChoice(i, (dialog, itemView, which, text) -> { + setTheme(themes.get(which)); + Themes.setCurrent(themes.get(which).getName()); + return true; + }) + .show(); } public CodeEditor getEditor() { diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java index 686a9b89..7268f426 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java @@ -79,12 +79,11 @@ public class CodeEditText extends AppCompatEditText { if (mScrollView == null) { mScrollView = (HVScrollView) getParent(); } - // 根据行号计算左边距padding + // 根据行号计算左边距padding 留出绘制行号的空间 String max = Integer.toString(getLineCount()); - float lineNumberSize = getPaint().measureText(max) + 20; - if (getPaddingLeft() != lineNumberSize) { - setPadding((int) lineNumberSize, 0, 0, 0); - invalidate(); + float gutterWidth = getPaint().measureText(max) + 20; + if (getPaddingLeft() != gutterWidth) { + setPadding((int) gutterWidth, 0, 0, 0); } super.onDraw(canvas); // 画文字 @@ -92,7 +91,6 @@ public class CodeEditText extends AppCompatEditText { canvas.translate(0, getExtendedPaddingTop()); drawText(canvas); canvas.restore(); - } // 绘制文本着色 diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java index 70e047ab..12aa5061 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditor.java @@ -138,9 +138,11 @@ public class CodeEditor extends HVScrollView { public void setTheme(Theme theme) { mTheme = theme; - mJavaScriptHighlighter.setTheme(theme); setBackgroundColor(mTheme.getBackgroundColor()); - + mJavaScriptHighlighter.setTheme(theme); + mJavaScriptHighlighter.updateTokens(mCodeEditText.getText().toString()); + mCodeEditText.setTheme(mTheme); + invalidate(); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/JavaScriptHighlighter.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/JavaScriptHighlighter.java index 6a5f24cb..677b9eb5 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/JavaScriptHighlighter.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/JavaScriptHighlighter.java @@ -81,7 +81,7 @@ public class JavaScriptHighlighter implements SimpleTextWatcher.AfterTextChanged mTheme = theme; } - private void updateTokens(String sourceString) { + public void updateTokens(String sourceString) { final int id = mRunningHighlighterId.incrementAndGet(); mExecutorService.execute(() -> { try { diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/theme/Theme.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/theme/Theme.java index 5e582ff1..a8a110f5 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/theme/Theme.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/theme/Theme.java @@ -1,22 +1,14 @@ package com.stardust.scriptdroid.ui.edit.theme; import android.graphics.Color; -import android.util.SparseArray; import android.util.SparseIntArray; -import com.google.gson.Gson; import com.stardust.scriptdroid.model.editor.EditorTheme; import com.stardust.scriptdroid.model.editor.TokenColor; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.Token; - import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; -import java.util.Map; - -import static org.mozilla.javascript.Token.*; /** * Created by Stardust on 2018/2/16. @@ -25,19 +17,21 @@ import static org.mozilla.javascript.Token.*; public class Theme { - private int mBackgroundColor; - private int mForegroundColor; - private int mLineNumberColor; + private int mBackgroundColor = Color.WHITE; + private int mForegroundColor = Color.BLACK; + private int mLineNumberColor = Color.GRAY; private SparseIntArray mTokenColors = new SparseIntArray(); - private int mImeBarBackgroundColor; - private int mImeBarForegroundColor; + private int mImeBarBackgroundColor = 0xDDFFFFFF; + private int mImeBarForegroundColor = Color.WHITE; + private EditorTheme mEditorTheme; public Theme(EditorTheme theme) { - mBackgroundColor = Color.parseColor(theme.getEditorColors().getEditorBackground()); - mForegroundColor = Color.parseColor(theme.getEditorColors().getEditorForeground()); - mLineNumberColor = Color.parseColor(theme.getEditorColors().getEditorIndentGuideBackground()); - mImeBarBackgroundColor = Color.parseColor(theme.getEditorColors().getImeBackgroundColor()); - mImeBarForegroundColor = Color.parseColor(theme.getEditorColors().getImeForegroundColor()); + mEditorTheme = theme; + mBackgroundColor = parseColor(theme.getEditorColors().getEditorBackground(), mBackgroundColor); + mForegroundColor = parseColor(theme.getEditorColors().getEditorForeground(), mForegroundColor); + mLineNumberColor = parseColor(theme.getEditorColors().getLineNumberForeground(), mLineNumberColor); + mImeBarBackgroundColor = parseColor(theme.getEditorColors().getImeBackgroundColor(), mImeBarBackgroundColor); + mImeBarForegroundColor = parseColor(theme.getEditorColors().getImeForegroundColor(), mImeBarForegroundColor); for (TokenColor tokenColor : theme.getTokenColors()) { String foregroundStr = tokenColor.getSettings().getForeground(); @@ -50,6 +44,20 @@ public class Theme { } } + private int parseColor(String color, int defaultValue) { + if (color == null) + return defaultValue; + try { + return Color.parseColor(color); + } catch (Exception ignored) { + return defaultValue; + } + } + + public String getName() { + return mEditorTheme.getName(); + } + private void setTokenColor(String scope, int foreground) { for (int token : TokenMapping.getTokensForScope(scope)) { mTokenColors.put(token, foreground); @@ -111,4 +119,19 @@ public class Theme { public void setImeBarForegroundColor(int imeBarForegroundColor) { mImeBarForegroundColor = imeBarForegroundColor; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Theme theme = (Theme) o; + + return mEditorTheme.getName() != null ? mEditorTheme.getName().equals(theme.mEditorTheme.getName()) : theme.mEditorTheme.getName() == null; + } + + public String toString() { + return getName(); + } + } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/theme/Themes.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/theme/Themes.java new file mode 100644 index 00000000..ecae3d5d --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/theme/Themes.java @@ -0,0 +1,99 @@ +package com.stardust.scriptdroid.ui.edit.theme; + +import android.content.Context; + +import com.stardust.pio.UncheckedIOException; +import com.stardust.scriptdroid.Pref; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import io.reactivex.Observable; +import io.reactivex.Single; +import io.reactivex.schedulers.Schedulers; +import io.reactivex.subjects.PublishSubject; + +/** + * Created by Stardust on 2018/2/22. + */ + +public class Themes { + + + private static final String ASSETS_THEMES_PATH = "editor/theme"; + private static final String DEFAULT_THEME = "Quiet Light"; + + private static List sThemes; + private static Theme sDefaultTheme; + + public static Observable> getAllThemes(Context context) { + if (sThemes != null) { + return Observable.just(sThemes); + } + PublishSubject> subject = PublishSubject.create(); + getAllThemesInner(context) + .subscribeOn(Schedulers.io()) + .subscribe(themes -> { + setThemes(themes); + subject.onNext(sThemes); + subject.onComplete(); + }, Throwable::printStackTrace); + return subject; + } + + public static Observable getDefault(Context context) { + if (sDefaultTheme != null) + return Observable.just(sDefaultTheme); + return getAllThemes(context) + .map(themes -> sDefaultTheme); + } + + private synchronized static void setThemes(List themes) { + if (sThemes != null) + return; + sThemes = Collections.unmodifiableList(themes); + for (Theme theme : sThemes) { + if (DEFAULT_THEME.equals(theme.getName())) { + sDefaultTheme = theme; + return; + } + } + sDefaultTheme = sThemes.get(0); + } + + private static Observable> getAllThemesInner(Context context) { + if (sThemes != null) { + return Observable.just(sThemes); + } + try { + return Observable.fromArray(context.getAssets().list(ASSETS_THEMES_PATH)) + .map(file -> context.getAssets().open(ASSETS_THEMES_PATH + "/" + file)) + .map(stream -> Theme.fromJson(new InputStreamReader(stream))) + .collectInto((List) new ArrayList(), List::add) + .toObservable(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public static Observable getCurrent(Context context) { + String currentTheme = Pref.getCurrentTheme(); + if (currentTheme == null) + return getDefault(context); + return getAllThemes(context) + .map(themes -> { + for (Theme theme : themes) { + if (currentTheme.equals(theme.getName())) + return theme; + } + return themes.get(0); + }); + } + + public static void setCurrent(String name) { + Pref.setCurrentTheme(name); + } +} diff --git a/app/src/main/res/drawable/code_edit_text_cursor.xml b/app/src/main/res/drawable/code_edit_text_cursor.xml index be6967b7..7b1e796c 100644 --- a/app/src/main/res/drawable/code_edit_text_cursor.xml +++ b/app/src/main/res/drawable/code_edit_text_cursor.xml @@ -2,7 +2,7 @@ - + diff --git a/app/src/main/res/menu/menu_editor.xml b/app/src/main/res/menu/menu_editor.xml index 7a08d49d..d40aa974 100644 --- a/app/src/main/res/menu/menu_editor.xml +++ b/app/src/main/res/menu/menu_editor.xml @@ -86,13 +86,13 @@