feat(ui): supports debugging
This commit is contained in:
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "org.autojs.autojs"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 23
|
||||
versionCode 406
|
||||
versionName "4.0.2 Alpha2"
|
||||
versionCode 408
|
||||
versionName "4.0.2 Alpha3"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
ndk {
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
"editor.background": "#1E1E1E",
|
||||
"editor.foreground": "#D4D4D4",
|
||||
"editorLineNumber.foreground": "#404040",
|
||||
"editorBreakpoint.foreground": "#1976D2",
|
||||
"imeBar.background": "#dd1e1e1e",
|
||||
"imeBar.foreground": "#f1f1f1",
|
||||
"editor.lineHighlightBackground": "#2e2e35"
|
||||
"editor.lineHighlightBackground": "#2e2e35",
|
||||
"editor.debuggingLineBackground": "#40c4ff"
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
|
||||
@@ -499,6 +499,8 @@
|
||||
"editor.background": "#F5F5F5",
|
||||
"editor.foreground": "#000000",
|
||||
"editor.lineHighlightBackground": "#E4F6D4",
|
||||
"editor.debuggingLineBackground": "#40c4ff",
|
||||
"editorBreakpoint.foreground": "#03A9F4",
|
||||
"focusBorder": "#A6B39B",
|
||||
"pickerGroup.foreground": "#A6B39B",
|
||||
"pickerGroup.border": "#749351",
|
||||
|
||||
@@ -22,6 +22,10 @@ public class EditorColors {
|
||||
private String mImeForegroundColor;
|
||||
@SerializedName("editor.lineHighlightBackground")
|
||||
private String mLineHighlightBackground;
|
||||
@SerializedName("editorBreakpoint.foreground")
|
||||
private String mBreakpointForeground;
|
||||
@SerializedName("editor.debuggingLineBackground")
|
||||
private String mDebuggingLineBackground;
|
||||
|
||||
public String getLineHighlightBackground() {
|
||||
return mLineHighlightBackground;
|
||||
@@ -86,4 +90,20 @@ public class EditorColors {
|
||||
public void setImeForegroundColor(String imeForegroundColor) {
|
||||
mImeForegroundColor = imeForegroundColor;
|
||||
}
|
||||
|
||||
public String getBreakpointForeground() {
|
||||
return mBreakpointForeground;
|
||||
}
|
||||
|
||||
public void setBreakpointForeground(String breakpointForeground) {
|
||||
mBreakpointForeground = breakpointForeground;
|
||||
}
|
||||
|
||||
public String getDebuggingLineBackground() {
|
||||
return mDebuggingLineBackground;
|
||||
}
|
||||
|
||||
public void setDebuggingLineBackground(String debuggingLineBackground) {
|
||||
mDebuggingLineBackground = debuggingLineBackground;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,14 @@ import android.text.InputType;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.ui.build.BuildActivity;
|
||||
import org.autojs.autojs.ui.build.BuildActivity_;
|
||||
import org.autojs.autojs.ui.edit.editor.CodeEditor;
|
||||
import org.autojs.autojs.ui.log.LogActivity_;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
@@ -53,6 +55,21 @@ public class EditorMenu {
|
||||
if (onMoreOptionsSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
if(onDebugOptionsSelected(item)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onDebugOptionsSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_breakpoint:
|
||||
mEditor.addOrRemoveBreakpointAtCurrentLine();
|
||||
return true;
|
||||
case R.id.action_launch_debugger:
|
||||
mEditorView.launchDebugger();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,13 @@ import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -50,6 +53,8 @@ import org.autojs.autojs.ui.edit.keyboard.FunctionsKeyboardHelper;
|
||||
import org.autojs.autojs.ui.edit.keyboard.FunctionsKeyboardView;
|
||||
import org.autojs.autojs.ui.edit.theme.Theme;
|
||||
import org.autojs.autojs.ui.edit.theme.Themes;
|
||||
import org.autojs.autojs.ui.edit.toolbar.DebugToolbarFragment;
|
||||
import org.autojs.autojs.ui.edit.toolbar.DebugToolbarFragment_;
|
||||
import org.autojs.autojs.ui.edit.toolbar.NormalToolbarFragment;
|
||||
import org.autojs.autojs.ui.edit.toolbar.NormalToolbarFragment_;
|
||||
import org.autojs.autojs.ui.edit.toolbar.SearchToolbarFragment;
|
||||
@@ -117,6 +122,9 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (ACTION_ON_EXECUTION_FINISHED.equals(intent.getAction())) {
|
||||
mScriptExecutionId = ScriptExecution.NO_ID;
|
||||
if (mDebugging) {
|
||||
exitDebugging();
|
||||
}
|
||||
setMenuItemStatus(R.id.run, true);
|
||||
String msg = intent.getStringExtra(Scripts.EXTRA_EXCEPTION_MESSAGE);
|
||||
int line = intent.getIntExtra(Scripts.EXTRA_EXCEPTION_LINE_NUMBER, -1);
|
||||
@@ -130,8 +138,11 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private SparseBooleanArray mMenuItemStatus = new SparseBooleanArray();
|
||||
private String mRestoredText;
|
||||
private NormalToolbarFragment mNormalToolbar = new NormalToolbarFragment_();
|
||||
private boolean mDebugging = false;
|
||||
|
||||
public EditorView(Context context) {
|
||||
super(context);
|
||||
@@ -231,6 +242,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
|
||||
|
||||
private void setMenuItemStatus(int id, boolean enabled) {
|
||||
mMenuItemStatus.put(id, enabled);
|
||||
ToolbarFragment fragment = (ToolbarFragment) getActivity().getSupportFragmentManager()
|
||||
.findFragmentById(R.id.toolbar_menu);
|
||||
if (fragment == null) {
|
||||
@@ -240,6 +252,9 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getMenuItemStatus(int id, boolean defValue) {
|
||||
return mMenuItemStatus.get(id, defValue);
|
||||
}
|
||||
|
||||
@AfterViews
|
||||
void init() {
|
||||
@@ -347,6 +362,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
public void runAndSaveFileIfNeeded() {
|
||||
save().observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(s -> run());
|
||||
@@ -515,6 +531,26 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
|
||||
|
||||
public void launchDebugger() {
|
||||
DebugToolbarFragment debugToolbarFragment = DebugToolbarFragment_.builder()
|
||||
.build();
|
||||
getActivity().getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.toolbar_menu, debugToolbarFragment)
|
||||
.commit();
|
||||
mDebugging = true;
|
||||
}
|
||||
|
||||
public void exitDebugging() {
|
||||
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
|
||||
Fragment fragment = fragmentManager.findFragmentById(R.id.toolbar_menu);
|
||||
if (fragment instanceof DebugToolbarFragment) {
|
||||
((DebugToolbarFragment) fragment).detachDebugger();
|
||||
}
|
||||
showNormalToolbar();
|
||||
mEditor.setDebuggingLine(-1);
|
||||
mDebugging = false;
|
||||
}
|
||||
|
||||
private void showErrorMessage(String msg) {
|
||||
Snackbar.make(EditorView.this, getResources().getString(R.string.text_error) + ": " + msg, Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.text_detail, v -> LogActivity_.intent(getContext()).start())
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v7.widget.AppCompatEditText;
|
||||
import android.text.Editable;
|
||||
import android.text.Layout;
|
||||
@@ -31,14 +30,16 @@ import android.util.Log;
|
||||
import android.util.TimingLogger;
|
||||
import android.view.Gravity;
|
||||
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.ui.edit.theme.Theme;
|
||||
import org.autojs.autojs.ui.edit.theme.TokenMapping;
|
||||
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
import com.stardust.util.TextUtils;
|
||||
|
||||
import org.mozilla.javascript.Token;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import static org.autojs.autojs.ui.edit.editor.BracketMatching.UNMATCHED_BRACKET;
|
||||
|
||||
/**
|
||||
@@ -62,6 +63,8 @@ public class CodeEditText extends AppCompatEditText {
|
||||
private int mFirstLineForDraw = -1, mLastLineForDraw;
|
||||
private int[] mMatchingBrackets = {-1, -1};
|
||||
private int mUnmatchedBracket = -1;
|
||||
private LinkedHashMap<Integer, CodeEditor.Breakpoint> mBreakpoints = new LinkedHashMap<>();
|
||||
private int mDebuggingLine = -1;
|
||||
|
||||
|
||||
public CodeEditText(Context context) {
|
||||
@@ -87,6 +90,10 @@ public class CodeEditText extends AppCompatEditText {
|
||||
mLineHighlightPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, CodeEditor.Breakpoint> getBreakpoints() {
|
||||
return mBreakpoints;
|
||||
}
|
||||
|
||||
public void setTheme(Theme theme) {
|
||||
mTheme = theme;
|
||||
invalidate();
|
||||
@@ -101,8 +108,8 @@ public class CodeEditText extends AppCompatEditText {
|
||||
updatePaddingForGutter();
|
||||
updateLineRangeForDraw(canvas);
|
||||
|
||||
//绘制当前行高亮需要在绘制光标之前
|
||||
drawLineHighlight(canvas, mLineHighlightPaint, getCurrentLine());
|
||||
//绘制行高亮需要在绘制光标之前
|
||||
drawLineHighlights(canvas);
|
||||
|
||||
//调用super.onDraw绘制光标和选择高亮。因为字体颜色被设置为透明因此super.onDraw()绘制的字体不显示
|
||||
// TODO: 2018/2/24 优化效率。不绘制透明字体。
|
||||
@@ -118,6 +125,30 @@ public class CodeEditText extends AppCompatEditText {
|
||||
mLogger.dumpToLog();
|
||||
}
|
||||
|
||||
public int getDebuggingLine() {
|
||||
return mDebuggingLine;
|
||||
}
|
||||
|
||||
public void setDebuggingLine(int debuggingLine) {
|
||||
mDebuggingLine = debuggingLine;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void drawLineHighlights(Canvas canvas) {
|
||||
int currentLine = getCurrentLine();
|
||||
int debugHighlightLine = mDebuggingLine;
|
||||
if(debugHighlightLine != currentLine){
|
||||
//绘制当前行高亮
|
||||
mLineHighlightPaint.setColor(mTheme.getLineHighlightBackgroundColor());
|
||||
drawLineHighlight(canvas, mLineHighlightPaint, getCurrentLine());
|
||||
}
|
||||
if(debugHighlightLine != -1){
|
||||
mLineHighlightPaint.setColor(mTheme.getDebuggingLineBackgroundColor());
|
||||
drawLineHighlight(canvas, mLineHighlightPaint, debugHighlightLine);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateLineRangeForDraw(Canvas canvas) {
|
||||
Layout layout = getLayout();
|
||||
if (layout == null)
|
||||
@@ -159,15 +190,22 @@ public class CodeEditText extends AppCompatEditText {
|
||||
int scrollX = Math.max(getRealScrollX() - paddingLeft, 0);
|
||||
Paint paint = getPaint();
|
||||
int lineNumberColor = mTheme.getLineNumberColor();
|
||||
int breakPointColor = mTheme.getBreakpointColor();
|
||||
if (DEBUG)
|
||||
Log.d(LOG_TAG, "draw line: " + (mLastLineForDraw - mFirstLineForDraw + 1));
|
||||
mLogger.addSplit("before draw line");
|
||||
for (int line = mFirstLineForDraw; line <= mLastLineForDraw && line < lineCount; line++) {
|
||||
int lineBottom = layout.getLineTop(line + 1);
|
||||
int lineTop = layout.getLineTop(line);
|
||||
int lineBaseline = lineBottom - layout.getLineDescent(line);
|
||||
|
||||
//drawLineNumber
|
||||
String lineNumberText = Integer.toString(line + 1);
|
||||
// if there is a breakpoint at this line, draw highlight background for line number
|
||||
if (mBreakpoints.containsKey(line)) {
|
||||
paint.setColor(breakPointColor);
|
||||
canvas.drawRect(0, lineTop, paddingLeft - 10, lineBottom, paint);
|
||||
}
|
||||
paint.setColor(lineNumberColor);
|
||||
canvas.drawText(lineNumberText, 0, lineNumberText.length(), 10,
|
||||
lineBaseline, paint);
|
||||
@@ -225,7 +263,6 @@ public class CodeEditText extends AppCompatEditText {
|
||||
}
|
||||
int lineTop = getLayout().getLineTop(line);
|
||||
int lineBottom = getLayout().getLineTop(line + 1);
|
||||
paint.setColor(mTheme.getLineHighlightBackgroundColor());
|
||||
canvas.drawRect(0, lineTop, canvas.getWidth(), lineBottom, paint);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,15 @@ import android.util.AttributeSet;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.android.dx.util.IntList;
|
||||
import com.stardust.autojs.script.JsBeautifier;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.ui.edit.theme.Theme;
|
||||
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
import com.stardust.util.TextUtils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -53,7 +55,6 @@ public class CodeEditor extends HVScrollView {
|
||||
private JsBeautifier mJsBeautifier;
|
||||
private MaterialDialog mProcessDialog;
|
||||
|
||||
|
||||
private CharSequence mReplacement = "";
|
||||
private String mKeywords;
|
||||
private Matcher mMatcher;
|
||||
@@ -73,7 +74,7 @@ public class CodeEditor extends HVScrollView {
|
||||
private void init() {
|
||||
//setFillViewport(true);
|
||||
inflate(getContext(), R.layout.code_editor, this);
|
||||
mCodeEditText = (CodeEditText) findViewById(R.id.code_edit_text);
|
||||
mCodeEditText = findViewById(R.id.code_edit_text);
|
||||
mCodeEditText.addTextChangedListener(new AutoIndent(mCodeEditText));
|
||||
mTextViewRedoUndo = new TextViewRedoUndo(mCodeEditText);
|
||||
mJavaScriptHighlighter = new JavaScriptHighlighter(mTheme, mCodeEditText);
|
||||
@@ -260,7 +261,7 @@ public class CodeEditor extends HVScrollView {
|
||||
}
|
||||
|
||||
public void findPrev() {
|
||||
if (mMatcher != null){
|
||||
if (mMatcher != null) {
|
||||
Toast.makeText(getContext(), R.string.error_regex_find_prev, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
@@ -329,6 +330,30 @@ public class CodeEditor extends HVScrollView {
|
||||
mTextViewRedoUndo.markTextAsUnchanged();
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, Breakpoint> getBreakpoints() {
|
||||
return mCodeEditText.getBreakpoints();
|
||||
}
|
||||
|
||||
public void setDebuggingLine(int line){
|
||||
mCodeEditText.setDebuggingLine(line);
|
||||
}
|
||||
|
||||
public void addOrRemoveBreakpoint(int line) {
|
||||
LinkedHashMap<Integer, Breakpoint> breakpoints = mCodeEditText.getBreakpoints();
|
||||
if(breakpoints.remove(line) == null){
|
||||
breakpoints.put(line, new Breakpoint(line));
|
||||
}
|
||||
mCodeEditText.invalidate();
|
||||
}
|
||||
|
||||
public void addOrRemoveBreakpointAtCurrentLine() {
|
||||
int line = LayoutHelper.getLineOfChar(mCodeEditText.getLayout(), mCodeEditText.getSelectionStart());
|
||||
if (line < 0 || line >= mCodeEditText.getLayout().getLineCount())
|
||||
return;
|
||||
addOrRemoveBreakpoint(line);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
int codeWidth = getWidth() - getPaddingLeft() - getPaddingRight();
|
||||
@@ -340,4 +365,14 @@ public class CodeEditor extends HVScrollView {
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
public static class Breakpoint {
|
||||
|
||||
public int line;
|
||||
public boolean enabled = true;
|
||||
|
||||
public Breakpoint(int line) {
|
||||
this.line = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ public class Theme {
|
||||
private int mImeBarForegroundColor = Color.WHITE;
|
||||
private EditorTheme mEditorTheme;
|
||||
private int mLineHighlightBackground;
|
||||
private int mBreakpointColor;
|
||||
private int mDebuggingLineBackground;
|
||||
|
||||
public Theme(EditorTheme theme) {
|
||||
mEditorTheme = theme;
|
||||
@@ -34,6 +36,8 @@ public class Theme {
|
||||
mImeBarBackgroundColor = parseColor(theme.getEditorColors().getImeBackgroundColor(), mImeBarBackgroundColor);
|
||||
mImeBarForegroundColor = parseColor(theme.getEditorColors().getImeForegroundColor(), mImeBarForegroundColor);
|
||||
mLineHighlightBackground = parseColor(theme.getEditorColors().getLineHighlightBackground(), mLineHighlightBackground);
|
||||
mDebuggingLineBackground = parseColor(theme.getEditorColors().getDebuggingLineBackground(), mDebuggingLineBackground);
|
||||
mBreakpointColor = parseColor(theme.getEditorColors().getBreakpointForeground(), mBackgroundColor);
|
||||
|
||||
for (TokenColor tokenColor : theme.getTokenColors()) {
|
||||
String foregroundStr = tokenColor.getSettings().getForeground();
|
||||
@@ -141,4 +145,11 @@ public class Theme {
|
||||
}
|
||||
|
||||
|
||||
public int getBreakpointColor() {
|
||||
return mBreakpointColor;
|
||||
}
|
||||
|
||||
public int getDebuggingLineBackgroundColor() {
|
||||
return mDebuggingLineBackground;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,116 @@
|
||||
package org.autojs.autojs.ui.edit.toolbar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.rhino.debug.Dim;
|
||||
import com.stardust.autojs.rhino.debug.DebugCallback;
|
||||
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EFragment;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.ui.edit.EditorView;
|
||||
import org.autojs.autojs.ui.edit.editor.CodeEditor;
|
||||
import org.mozilla.javascript.ContextFactory;
|
||||
import org.mozilla.javascript.tools.debugger.Dim;
|
||||
import org.mozilla.javascript.tools.debugger.GuiCallback;
|
||||
|
||||
public class DebugToolbarFragment implements GuiCallback {
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
private Dim mDim;
|
||||
@EFragment(R.layout.fragment_debug_toolbar)
|
||||
public class DebugToolbarFragment extends ToolbarFragment implements DebugCallback {
|
||||
|
||||
public void attachDebugger(){
|
||||
mDim.attachTo(ContextFactory.getGlobal());
|
||||
private static final String LOG_TAG = "DebugToolbarFragment";
|
||||
private Dim mDim = new Dim();
|
||||
private EditorView mEditorView;
|
||||
private Handler mHandler;
|
||||
|
||||
public DebugToolbarFragment() {
|
||||
mDim.setGuiCallback(this);
|
||||
mDim.setBreak();
|
||||
mDim.attachTo(AutoJs.getInstance().getScriptEngineService(), ContextFactory.getGlobal());
|
||||
Log.d(LOG_TAG, "DebugToolbarFragment()");
|
||||
}
|
||||
|
||||
public void deattchDebugger(){
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mHandler = new Handler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mEditorView = findEditorView(view);
|
||||
mEditorView.run();
|
||||
Log.d(LOG_TAG, "onViewCreated");
|
||||
}
|
||||
|
||||
public void detachDebugger() {
|
||||
mDim.detach();
|
||||
}
|
||||
|
||||
public void breakpoint(){
|
||||
mDim.setGuiCallback(this);
|
||||
@Click(R.id.step_over)
|
||||
void stepOver() {
|
||||
mEditorView.getEditor().setDebuggingLine(-1);
|
||||
mDim.setReturnValue(Dim.STEP_OVER);
|
||||
}
|
||||
|
||||
@Click(R.id.step_into)
|
||||
void stepInto() {
|
||||
mEditorView.getEditor().setDebuggingLine(-1);
|
||||
mDim.setReturnValue(Dim.STEP_INTO);
|
||||
}
|
||||
|
||||
@Click(R.id.stop_out)
|
||||
void stepOut() {
|
||||
mEditorView.getEditor().setDebuggingLine(-1);
|
||||
mDim.setReturnValue(Dim.STEP_OUT);
|
||||
}
|
||||
|
||||
@Click(R.id.stop_script)
|
||||
void stopScript() {
|
||||
mEditorView.forceStop();
|
||||
}
|
||||
|
||||
@Click(R.id.resume_script)
|
||||
void resumeScript() {
|
||||
mEditorView.getEditor().setDebuggingLine(-1);
|
||||
mDim.setReturnValue(Dim.GO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSourceText(Dim.SourceInfo sourceInfo) {
|
||||
Log.d(LOG_TAG, "updateSourceText: url = " + sourceInfo.url() + ", source = " + sourceInfo.source());
|
||||
if (!sourceInfo.url().equals(mEditorView.getFile().toString())) {
|
||||
return;
|
||||
}
|
||||
sourceInfo.removeAllBreakpoints();
|
||||
for (CodeEditor.Breakpoint breakpoint : mEditorView.getEditor().getBreakpoints().values()) {
|
||||
int line = breakpoint.line + 1;
|
||||
if (sourceInfo.breakableLine(line)) {
|
||||
sourceInfo.breakpoint(line, breakpoint.enabled);
|
||||
Log.d(LOG_TAG, "not breakable: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterInterrupt(Dim.StackFrame stackFrame, String s, String s1) {
|
||||
|
||||
public void enterInterrupt(Dim.StackFrame stackFrame, String threadName, String s1) {
|
||||
Log.d(LOG_TAG, "enterInterrupt: threadName = " + threadName + ", url = " + stackFrame.getUrl() + ", line = " + stackFrame.getLineNumber());
|
||||
if (stackFrame.getUrl().equals(mEditorView.getFile().toString())) {
|
||||
mEditorView.getEditor().setDebuggingLine(stackFrame.getLineNumber() - 1);
|
||||
} else {
|
||||
mHandler.post(this::resumeScript);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,7 +119,26 @@ public class DebugToolbarFragment implements GuiCallback {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchNextGuiEvent() throws InterruptedException {
|
||||
public void dispatchNextGuiEvent() {
|
||||
Log.d(LOG_TAG, "dispatchNextGuiEvent");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAttachDebugger(RhinoJavaScriptEngine engine) {
|
||||
ScriptExecution execution = AutoJs.getInstance().getScriptEngineService().getScriptExecution(mEditorView.getScriptExecutionId());
|
||||
return execution != null && execution.getId() == engine.getId();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getMenuItemIds() {
|
||||
return Arrays.asList(R.id.step_over, R.id.step_into, R.id.stop_out, R.id.resume_script, R.id.stop_script);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mDim.detach();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package org.autojs.autojs.ui.edit.toolbar;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.View;
|
||||
|
||||
import org.autojs.autojs.ui.edit.EditorView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ToolbarFragment extends Fragment implements View.OnClickListener {
|
||||
@@ -16,7 +19,6 @@ public abstract class ToolbarFragment extends Fragment implements View.OnClickLi
|
||||
|
||||
private OnMenuItemClickListener mOnMenuItemClickListener;
|
||||
private List<Integer> mMenuItemIds;
|
||||
private SparseBooleanArray mMenuItemStatus = new SparseBooleanArray();
|
||||
|
||||
public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
|
||||
mOnMenuItemClickListener = listener;
|
||||
@@ -27,21 +29,32 @@ public abstract class ToolbarFragment extends Fragment implements View.OnClickLi
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
updateMenuItemStatus();
|
||||
updateMenuItemStatus(view);
|
||||
}
|
||||
|
||||
private void updateMenuItemStatus() {
|
||||
View rootView = getView();
|
||||
protected EditorView findEditorView(View view) {
|
||||
while (!(view instanceof EditorView) && view.getParent() != null) {
|
||||
view = (View) view.getParent();
|
||||
}
|
||||
if (!(view instanceof EditorView)) {
|
||||
throw new IllegalStateException("cannot find EditorView from child: " + view);
|
||||
}
|
||||
return (EditorView) view;
|
||||
}
|
||||
|
||||
|
||||
private void updateMenuItemStatus(View rootView) {
|
||||
if (rootView == null) {
|
||||
return;
|
||||
}
|
||||
EditorView editorView = findEditorView(rootView);
|
||||
if (mMenuItemIds == null) {
|
||||
mMenuItemIds = getMenuItemIds();
|
||||
}
|
||||
for (int id : mMenuItemIds) {
|
||||
View view = rootView.findViewById(id);
|
||||
view.setOnClickListener(this);
|
||||
view.setEnabled(mMenuItemStatus.get(id, view.isEnabled()));
|
||||
view.setEnabled(editorView.getMenuItemStatus(id, view.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +73,6 @@ public abstract class ToolbarFragment extends Fragment implements View.OnClickLi
|
||||
if (!mMenuItemIds.contains(id)) {
|
||||
return;
|
||||
}
|
||||
mMenuItemStatus.put(id, enabled);
|
||||
View rootView = getView();
|
||||
if (rootView == null) {
|
||||
return;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView {
|
||||
private ScriptExecutionListener mScriptExecutionListener = new SimpleScriptExecutionListener() {
|
||||
@Override
|
||||
public void onStart(final ScriptExecution execution) {
|
||||
mAdapter.notifyChildInserted(0, mRunningTaskGroup.addTask(execution));
|
||||
post(()-> mAdapter.notifyChildInserted(0, mRunningTaskGroup.addTask(execution)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,12 +78,14 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView {
|
||||
}
|
||||
|
||||
private void onFinish(ScriptExecution execution){
|
||||
final int i = mRunningTaskGroup.removeTask(execution);
|
||||
if (i >= 0) {
|
||||
mAdapter.notifyChildRemoved(0, i);
|
||||
} else {
|
||||
refresh();
|
||||
}
|
||||
post(()->{
|
||||
final int i = mRunningTaskGroup.removeTask(execution);
|
||||
if (i >= 0) {
|
||||
mAdapter.notifyChildRemoved(0, i);
|
||||
} else {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BIN
app/src/main/res/drawable-xhdpi/ic_debug.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_debug.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
app/src/main/res/drawable/ic_debug_step_into.png
Normal file
BIN
app/src/main/res/drawable/ic_debug_step_into.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable/ic_debug_step_out.png
Normal file
BIN
app/src/main/res/drawable/ic_debug_step_out.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable/ic_debug_step_over.png
Normal file
BIN
app/src/main/res/drawable/ic_debug_step_over.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
46
app/src/main/res/layout/fragment_debug_toolbar.xml
Normal file
46
app/src/main/res/layout/fragment_debug_toolbar.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/step_over"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_debug_step_over"
|
||||
app:text="@string/text_debug_step_over"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/step_into"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_debug_step_into"
|
||||
app:text="@string/text_debug_step_into"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/stop_out"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_debug_step_out"
|
||||
app:text="@string/text_debug_step_out"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/resume_script"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_play_arrow_white_48dp"
|
||||
app:text="@string/text_debug_resume_script"/>
|
||||
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/stop_script"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_close_white_48dp"
|
||||
app:text="@string/text_stop"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@@ -79,6 +79,24 @@
|
||||
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:title="@string/text_debug"
|
||||
app:showAsAction="never">
|
||||
|
||||
<menu>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_breakpoint"
|
||||
android:title="@string/text_set_breakpoint"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_launch_debugger"
|
||||
android:title="@string/text_launch_debugger"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_build_apk"
|
||||
|
||||
@@ -359,4 +359,12 @@
|
||||
<string name="key_script_dir_path">key_script_dir_path</string>
|
||||
<string name="default_value_script_dir_path">/脚本/</string>
|
||||
<string name="text_error_copy_file" formatted="true">发生错误: %s</string>
|
||||
<string name="text_debug">调试</string>
|
||||
<string name="text_set_breakpoint">断点</string>
|
||||
<string name="text_launch_debugger">启动调试</string>
|
||||
<string name="text_debug_step_out">跳出</string>
|
||||
<string name="text_debug_step_into">进入</string>
|
||||
<string name="text_debug_step_over">单步</string>
|
||||
<string name="text_debug_resume_script">继续</string>
|
||||
<string name="text_stop">停止</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user