Add: Sample Script Tab, EMCAScript Guide

This commit is contained in:
hyb1996
2017-03-14 16:59:45 +08:00
parent e81b661974
commit 85affed538
129 changed files with 7046 additions and 297 deletions

View File

@@ -36,9 +36,14 @@ public abstract class Fragment extends android.support.v4.app.Fragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mView = createView(inflater, container, savedInstanceState);
afterCreateView();
return mView;
}
protected void afterCreateView() {
}
@Nullable
public abstract View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState);

View File

@@ -17,6 +17,7 @@ import com.squareup.leakcanary.LeakCanary;
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
import com.stardust.scriptdroid.tool.ViewTool;
import com.stardust.scriptdroid.ui.error.ErrorReportActivity;
import com.stardust.theme.ThemeColor;
import com.stardust.theme.ThemeColorManager;
import com.stardust.util.CrashHandler;
import com.stardust.util.StateObserver;
@@ -48,6 +49,7 @@ public class App extends Application {
public void onCreate() {
super.onCreate();
ThemeColorManager.setDefaultThemeColor(new ThemeColor(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorPrimaryDark), getResources().getColor(R.color.colorAccent)));
ThemeColorManager.init(this);
if (LeakCanary.isInAnalyzerProcess(this)) {
return;

View File

@@ -13,6 +13,7 @@ public class Pref {
public static final String SAMPLE_SCRIPTS_COPIED = "SAMPLE_SCRIPTS_COPIED";
private static final String KEY_MAX_TEXT_LENGTH_FOR_CODE_COMPLETION = "KEY_MAX_TEXT_LENGTH_FOR_CODE_COMPLETION";
public static final String KEY_DRAWER_HEADER_IMAGE_PATH = "KEY_DRAWER_HEADER_IMAGE_PATH";
public static final String KEY_APP_BAR_IMAGE_PATH = "KEY_APP_BAR_IMAGE_PATH";
public static SharedPreferences def() {
return PreferenceManager.getDefaultSharedPreferences(App.getApp());
@@ -53,4 +54,8 @@ public class Pref {
return 2000;
}
}
public static boolean isFirstUsing() {
return getDisposableBoolean("isFirstUsing", true);
}
}

View File

@@ -10,7 +10,7 @@ import com.stardust.scriptdroid.droid.runtime.ScriptStopException;
import com.stardust.scriptdroid.droid.script.JavaScriptEngine;
import com.stardust.scriptdroid.droid.script.RhinoJavaScriptEngine;
import com.stardust.scriptdroid.droid.script.ScriptExecuteActivity;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import java.io.File;
import java.io.FileNotFoundException;

View File

@@ -1,6 +1,5 @@
package com.stardust.scriptdroid.droid.runtime;
import android.accessibilityservice.AccessibilityService;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -11,12 +10,10 @@ import android.graphics.Rect;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.automator.AccessibilityEventCommandHost;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.droid.runtime.action.ActionTarget;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
@@ -28,7 +25,7 @@ import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.runtime.action.Action;
import com.stardust.scriptdroid.droid.runtime.action.ActionFactory;
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import com.stardust.scriptdroid.tool.Shell;
import com.stardust.scriptdroid.ui.console.ConsoleActivity;
import com.stardust.view.accessibility.AccessibilityServiceUtils;

View File

@@ -7,7 +7,6 @@ import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import com.bezyapps.floatieslibrary.Floaty;
import com.stardust.automator.AccessibilityEventCommandHost;
import com.stardust.automator.ActionArgument;
import com.stardust.automator.UiGlobalSelector;

View File

@@ -2,7 +2,7 @@ package com.stardust.scriptdroid.droid.script;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.BuildConfig;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import java.io.IOException;
import java.util.HashMap;

View File

@@ -6,7 +6,7 @@ import android.content.SharedPreferences;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import java.lang.reflect.Type;
import java.util.ArrayList;

View File

@@ -1,6 +1,9 @@
package com.stardust.scriptdroid.external.floating_window;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.view.View;
import com.stardust.scriptdroid.App;
@@ -16,8 +19,32 @@ import com.stardust.view.ResizableFloaty;
public class FloatingWindowManger {
public static void showFloatingWindow() {
if (!HoverMenuService.isServiceRunning())
App.getApp().startService(new Intent(App.getApp(), HoverMenuService.class));
if (!HoverMenuService.isServiceRunning()) {
if (!hasFloatingWindowPermission()) {
goToFloatingWindowPermissionSetting();
} else {
HoverMenuService.startService(App.getApp());
}
}
}
public static void goToFloatingWindowPermissionSetting() {
String packageName = App.getApp().getPackageName();
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + packageName));
} else {
intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + packageName));
}
App.getApp().startActivity(intent);
}
private static boolean hasFloatingWindowPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return Settings.canDrawOverlays(App.getApp());
}
return true;
}
public static boolean isFloatingWindowShowing() {

View File

@@ -77,7 +77,7 @@ public class HoverMenuAdapter implements io.mattcarroll.hover.HoverMenuAdapter {
private View getTabViewInner(int index) {
String menuItemId = mTabIds.get(index);
if (ID_MAIN.equals(menuItemId)) {
return createTabView(R.drawable.ic_android_eat_js);
return createTabView(R.drawable.ic_android_eat_js_100);
} else if (ID_RECORD.equals(menuItemId)) {
return createTabView(R.drawable.ic_video_record);
} else if (ID_SCRIPT_LIST.equals(menuItemId)) {

View File

@@ -7,13 +7,15 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.stardust.hover.HoverMenuBuilder;
import com.stardust.hover.SimpleHoverMenuTransitionListener;
import com.stardust.hover.WindowHoverMenu;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.floating_window.view.FloatingLayoutBoundsView;
import com.stardust.scriptdroid.external.floating_window.view.FloatingLayoutHierarchyView;
import com.stardust.scriptdroid.layout_inspector.LayoutInspector;
@@ -35,31 +37,50 @@ import io.mattcarroll.hover.defaulthovermenu.window.WindowViewController;
public class HoverMenuService extends Service {
public static class ServiceStateChangedEvent {
ServiceStateChangedEvent(boolean state) {
this.state = state;
}
public boolean state;
}
public static final String MESSAGE_SHOW_AND_EXPAND_MENU = "MESSAGE_SHOW_AND_EXPAND_MENU";
public static final String MESSAGE_SHOW_LAYOUT_HIERARCHY = "MESSAGE_SHOW_LAYOUT_HIERARCHY";
public static final String MESSAGE_SHOW_LAYOUT_BOUNDS = "MESSAGE_SHOW_LAYOUT_BOUNDS";
public static final String MESSAGE_COLLAPSE_MENU = "MESSAGE_COLLAPSE_MENU";
public static final String MESSAGE_MENU_COLLAPSING = "MESSAGE_MENU_COLLAPSING";
private static WeakReference<HoverMenuService> service;
private static WeakReference<HoverMenuService> service = new WeakReference<>(null);
private static boolean sIsRunning;
public static void startService(Context context) {
context.startService(new Intent(context, HoverMenuService.class));
setIsRunning(true);
}
public static boolean isServiceRunning() {
return service != null && service.get() != null;
return sIsRunning;
}
public static void stopService() {
if (isServiceRunning()) {
if (isServiceRunning() && service.get() != null) {
service.get().stopSelf();
setIsRunning(false);
}
}
private static void setIsRunning(boolean isRunning) {
sIsRunning = isRunning;
EventBus.getDefault().post(new ServiceStateChangedEvent(sIsRunning));
}
private static final String TAG = "HoverMenuService";
private static final String PREF_FILE = "hover_menu";
private static final String PREF_HOVER_MENU_VISUAL_STATE = "hover_menu_visual_state";
private boolean mIsRunning;
private SharedPreferences mPrefs;
private WindowViewController mWindowViewController;
@@ -80,14 +101,21 @@ public class HoverMenuService extends Service {
@Override
public void onCreate() {
super.onCreate();
if (isServiceRunning()) {
if (service.get() != null) {
stopSelf();
} else {
service = new WeakReference<>(this);
return;
}
service = new WeakReference<>(this);
EventBus.getDefault().register(this);
mPrefs = getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
initViews();
try {
initViews();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show();
FloatingWindowManger.goToFloatingWindowPermissionSetting();
stopService();
}
}
private void initViews() {
@@ -138,18 +166,16 @@ public class HoverMenuService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!mIsRunning) {
mIsRunning = true;
mWindowHoverMenu.show();
}
mWindowHoverMenu.show();
return START_STICKY;
}
@Override
public void onDestroy() {
mWindowHoverMenu.hide();
mIsRunning = false;
if (isServiceRunning() && service.get() == this)
EventBus.getDefault().unregister(this);
setIsRunning(false);
if (service.get() == this)
service.clear();
}
@@ -167,14 +193,14 @@ public class HoverMenuService extends Service {
public void onMessageEvent(MessageEvent event) {
switch (event.message) {
case MESSAGE_SHOW_AND_EXPAND_MENU:
mWindowHoverMenu.show();
showView(mWindowHoverMenu.getHoverMenuView());
break;
case MESSAGE_SHOW_LAYOUT_HIERARCHY:
mWindowHoverMenu.hide();
mWindowHoverMenu.getHoverMenuView().setVisibility(View.GONE);
showView(mFloatingLayoutHierarchyView);
break;
case MESSAGE_SHOW_LAYOUT_BOUNDS:
mWindowHoverMenu.hide();
mWindowHoverMenu.getHoverMenuView().setVisibility(View.GONE);
showView(mFloatingLayoutBoundsView);
break;
case MESSAGE_COLLAPSE_MENU:

View File

@@ -2,11 +2,13 @@ package com.stardust.scriptdroid.external.floating_window.content;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.widget.Toast;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.Droid;
import com.stardust.scriptdroid.external.floating_window.HoverMenuService;
import com.stardust.scriptdroid.layout_inspector.LayoutInspector;
import com.stardust.util.MessageEvent;
@@ -59,6 +61,15 @@ public class MainMenuNavigatorContent implements NavigatorContent {
}
}
@ViewBinding.Click(R.id.stop_all_running_scripts)
private void stopAllRunningScripts() {
int n = Droid.getInstance().stopAll();
if (n > 0)
Toast.makeText(mView.getContext(), String.format(mView.getContext().getString(R.string.text_already_stop_n_scripts), n), Toast.LENGTH_SHORT).show();
else
Toast.makeText(mView.getContext(), R.string.text_no_running_script, Toast.LENGTH_SHORT).show();
}
@NonNull
@Override
public View getView() {

View File

@@ -15,6 +15,7 @@ import android.widget.TextView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.layout_inspector.NodeInfo;
import com.stardust.scriptdroid.tool.ViewTool;
import com.stardust.widget.LevelBeamView;
import java.util.Collections;
import java.util.List;

View File

@@ -0,0 +1,15 @@
package com.stardust.scriptdroid.sample;
/**
* Created by Stardust on 2017/3/13.
*/
public class Sample {
public String name;
public String path;
public Sample(String name, String path) {
this.name = name;
this.path = path;
}
}

View File

@@ -1,16 +1,21 @@
package com.stardust.scriptdroid.file;
package com.stardust.scriptdroid.sample;
import android.content.Context;
import android.content.res.AssetManager;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
import com.stardust.scriptdroid.tool.FileUtils;
import com.stardust.util.MapEntries;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
@@ -19,12 +24,12 @@ import java.util.Map;
public class SampleFileManager {
private static final Map<String, Integer> SAMPLES = new MapEntries<>(new LinkedHashMap<String, Integer>())
.entry("sample_open_running_services.js", R.string.text_sample_open_running_services)
.entry("sample_qq_hongbao.js", R.string.text_sample_qq_hongbao)
.entry("sample_simple_calculator.js", R.string.text_sample_simple_calculator)
.entry("sample_force_qq_chat.js", R.string.text_sample_for_qq_chat)
.entry("sample_wechat_scan.js", R.string.text_sample_wechat_scan)
.entry("sample_alipay_scan.js", R.string.text_sample_alipay_scan)
.entry("sample/自动操作/sample_open_running_services.js", R.string.text_sample_open_running_services)
.entry("sample/自动操作/sample_qq_hongbao.js", R.string.text_sample_qq_hongbao)
.entry("sample/自动操作/sample_simple_calculator.js", R.string.text_sample_simple_calculator)
.entry("sample/自动操作/sample_force_qq_chat.js", R.string.text_sample_for_qq_chat)
.entry("sample/自动操作/sample_wechat_scan.js", R.string.text_sample_wechat_scan)
.entry("sample/自动操作/sample_alipay_scan.js", R.string.text_sample_alipay_scan)
.map();
private static SampleFileManager instance = new SampleFileManager();
@@ -64,4 +69,29 @@ public class SampleFileManager {
return failCount;
}
public List<SampleGroup> getSamplesFromAssets(AssetManager assets, String path) {
List<SampleGroup> sampleGroups = new ArrayList<>();
try {
String[] groups = assets.list(path);
for (String groupName : groups) {
sampleGroups.add(getSampleGroupFromAssets(assets, groupName, path + "/" + groupName));
}
return sampleGroups;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private SampleGroup getSampleGroupFromAssets(AssetManager assets, String groupName, String path) {
SampleGroup group = new SampleGroup(groupName);
try {
String[] samples = assets.list(path);
for (String sample : samples) {
group.add(new Sample(FileUtils.getNameWithoutExtension(sample), path + "/" + sample));
}
return group;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,28 @@
package com.stardust.scriptdroid.sample;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/3/13.
*/
public class SampleGroup {
public String name;
public List<Sample> sampleList;
public SampleGroup(String name) {
this(name, new ArrayList<Sample>());
}
public SampleGroup(String name, List<Sample> samples) {
this.name = name;
sampleList = samples;
}
public void add(Sample sample){
sampleList.add(sample);
}
}

View File

@@ -5,12 +5,15 @@ import android.widget.Toast;
import com.stardust.scriptdroid.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/2/3.
*/
public interface BackPressedHandler {
void onBackPressed();
boolean onBackPressed();
class DoublePressExit implements BackPressedHandler {
@@ -28,13 +31,33 @@ public interface BackPressedHandler {
}
@Override
public void onBackPressed() {
public boolean onBackPressed() {
if (System.currentTimeMillis() - mLastPressedMillis < mDoublePressInterval) {
mActivity.finish();
} else {
mLastPressedMillis = System.currentTimeMillis();
Toast.makeText(mActivity, R.string.text_press_again_to_exit, Toast.LENGTH_SHORT).show();
}
return true;
}
}
class Observer implements BackPressedHandler {
private List<BackPressedHandler> mBackPressedHandlers = new ArrayList<>();
@Override
public boolean onBackPressed() {
for (BackPressedHandler handler : mBackPressedHandlers) {
if (handler.onBackPressed()) {
return true;
}
}
return false;
}
public void registerHandler(BackPressedHandler handler) {
mBackPressedHandlers.add(handler);
}
}
}

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.file;
package com.stardust.scriptdroid.tool;
import android.content.Context;
import android.database.Cursor;
@@ -211,4 +211,32 @@ public class FileUtils {
}
}
public static String getNameWithoutExtension(String fileName) {
int a = fileName.lastIndexOf('/');
if (a < 0)
a = fileName.lastIndexOf('\\');
int b = fileName.lastIndexOf('.');
if (a < 0)
a = -1;
if (b < 0)
b = fileName.length();
fileName = fileName.substring(a + 1, b);
return fileName;
}
public static File copyAssetToTmpFile(Context context, String path) {
String extension = getExtension(path);
String name = getNameWithoutExtension(path);
if(name.length() < 5){
name += name.hashCode();
}
try {
File tmpFile = File.createTempFile(name, "." + extension, context.getCacheDir());
copyAsset(path, tmpFile.getPath());
return tmpFile;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -4,11 +4,13 @@ import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.stardust.scriptdroid.R;
import com.stardust.theme.ThemeColorManager;
import com.stardust.theme.app.ThemeColorAppCompatActivity;
import java.util.ArrayList;
@@ -22,7 +24,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
* Created by Stardust on 2017/1/23.
*/
public class BaseActivity extends ThemeColorAppCompatActivity {
public class BaseActivity extends AppCompatActivity {
protected static final int PERMISSION_REQUEST_CODE = 11186;
@@ -31,6 +33,14 @@ public class BaseActivity extends ThemeColorAppCompatActivity {
super.onCreate(savedInstanceState);
}
@Override
protected void onStart() {
super.onStart();
if ((getWindow().getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0) {
ThemeColorManager.addActivityStatusBar(this);
}
}
@SuppressWarnings("unchecked")
public <T extends View> T $(int resId) {
return (T) findViewById(resId);

View File

@@ -17,6 +17,7 @@ import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.droid.Droid;
import com.stardust.scriptdroid.tool.FileUtils;
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity;
import com.stardust.scriptdroid.ui.edit.sidemenu.EditSideMenuFragment;
import com.stardust.scriptdroid.ui.edit.sidemenu.FunctionListRecyclerView;
@@ -68,6 +69,15 @@ public class EditActivity extends Editor920Activity {
editFile(context, null, path);
}
public static void editAssetFile(Context context, String name, String path) {
context.startActivity(new Intent(context, EditActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra("fromAssets", true)
.putExtra("path", path)
.putExtra("name", name));
}
public static void editFile(Context context, String name, String path) {
context.startActivity(new Intent(context, EditActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -81,6 +91,7 @@ public class EditActivity extends Editor920Activity {
private DrawerLayout mDrawerLayout;
private EditorDelegate mEditorDelegate;
private SparseArray<ToolbarMenuItem> mMenuMap;
private boolean mReadOnly = false;
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -125,7 +136,13 @@ public class EditActivity extends Editor920Activity {
if (path == null) {
finish();
} else {
mFile = new File(path);
if (getIntent().getBooleanExtra("fromAssets", false)) {
mReadOnly = true;
//TODO 优化
mFile = FileUtils.copyAssetToTmpFile(this, path);
} else {
mFile = new File(path);
}
if (mName == null) {
mName = mFile.getName();
}
@@ -150,7 +167,8 @@ public class EditActivity extends Editor920Activity {
.setOnFunctionClickListener(new FunctionListRecyclerView.OnFunctionClickListener() {
@Override
public void onClick(FunctionListRecyclerView.Function function, int position) {
insertText(function.name);
if (!mReadOnly)
insertText(function.name);
mDrawerLayout.closeDrawer(GravityCompat.END);
}
});
@@ -161,25 +179,30 @@ public class EditActivity extends Editor920Activity {
mEditorDelegate = new EditorDelegate(0, mFile, 0, null);
final EditorView editorView = (EditorView) findViewById(R.id.editor);
mEditorDelegate.setEditorView(editorView);
editorView.getEditText().setReadOnly(mReadOnly);
InputMethodEnhanceBar inputMethodEnhanceBar = (InputMethodEnhanceBar) findViewById(R.id.input_method_enhance_bar);
inputMethodEnhanceBar.setEditTextBridge(new InputMethodEnhanceBar.EditTextBridge() {
@Override
public void appendText(CharSequence text) {
insertText(text);
}
if (mReadOnly) {
inputMethodEnhanceBar.setVisibility(View.GONE);
} else {
inputMethodEnhanceBar.setEditTextBridge(new InputMethodEnhanceBar.EditTextBridge() {
@Override
public void appendText(CharSequence text) {
insertText(text);
}
@Override
public void backspace(int count) {
@Override
public void backspace(int count) {
}
}
@Override
public TextView getEditText() {
return editorView.getEditText();
}
@Override
public TextView getEditText() {
return editorView.getEditText();
}
});
});
}
}
}
@@ -264,7 +287,7 @@ public class EditActivity extends Editor920Activity {
@Override
public void finish() {
if (mEditorDelegate.isChanged()) {
if (!mReadOnly && mEditorDelegate.isChanged()) {
showExitConfirmDialog();
} else {
super.finish();
@@ -304,4 +327,5 @@ public class EditActivity extends Editor920Activity {
super.onDestroy();
unregisterReceiver(mOnRunFinishedReceiver);
}
}

View File

@@ -11,13 +11,16 @@ import android.view.ViewGroup;
import com.stardust.app.Fragment;
import com.stardust.scriptdroid.external.floating_window.FloatingWindowManger;
import com.stardust.scriptdroid.external.floating_window.HoverMenuService;
import com.stardust.view.ViewBinding;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.console.ConsoleActivity;
import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity;
import com.stardust.view.ViewBinder;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
/**
* Created by Stardust on 2017/2/4.
*/
@@ -35,6 +38,12 @@ public class EditSideMenuFragment extends Fragment {
private SwitchCompat mFloatingWindowSwitch;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
@Nullable
@Override
public View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@@ -73,7 +82,7 @@ public class EditSideMenuFragment extends Fragment {
@ViewBinding.Click(R.id.syntax_and_api)
private void startSyntaxHelpActivity() {
HelpCatalogueActivity.showCatalogue(getActivity());
HelpCatalogueActivity.showMainCatalogue(getActivity());
}
@ViewBinding.Click(R.id.console)
@@ -100,4 +109,15 @@ public class EditSideMenuFragment extends Fragment {
return this;
}
@Subscribe
public void onHoverMenuServiceStateChanged(HoverMenuService.ServiceStateChangedEvent event) {
mFloatingWindowSwitch.setChecked(event.state);
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}

View File

@@ -12,7 +12,7 @@ import android.widget.TextView;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import com.stardust.widget.ExpandableRecyclerView;
import java.text.Collator;

View File

@@ -7,7 +7,7 @@ import android.os.Bundle;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.widget.CommonMarkdownView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import java.io.IOException;
@@ -17,6 +17,8 @@ import java.io.IOException;
public class DocumentationActivity extends BaseActivity {
private CommonMarkdownView mCommonMarkdownView;
public static void openDocumentation(Context context, String title, String assetPath) {
context.startActivity(new Intent(context, DocumentationActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -37,22 +39,22 @@ public class DocumentationActivity extends BaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleIntent();
handleIntent(getIntent());
setUpUI();
}
private void handleIntent() {
mTitle = getIntent().getStringExtra("title");
String path = getIntent().getStringExtra("path");
if (path == null) {
int rawId = getIntent().getIntExtra("resId", 0);
mDocumentation = FileUtils.readString(getResources().openRawResource(rawId));
} else {
private void handleIntent(Intent intent) {
mTitle = intent.getStringExtra("title");
String path = intent.getStringExtra("path");
int rawId = intent.getIntExtra("resId", 0);
if (path != null) {
try {
mDocumentation = FileUtils.readString(getAssets().open("help/documentation/" + path + ".md"));
mDocumentation = FileUtils.readString(getAssets().open("help/" + path));
} catch (IOException e) {
e.printStackTrace();
}
} else if (rawId != 0) {
mDocumentation = FileUtils.readString(getResources().openRawResource(rawId));
}
}
@@ -63,12 +65,21 @@ public class DocumentationActivity extends BaseActivity {
}
private void loadDocument() {
CommonMarkdownView markdownView = $(R.id.markdown);
mCommonMarkdownView = $(R.id.markdown);
try {
markdownView.loadMarkdown(mDocumentation);
mCommonMarkdownView.loadMarkdown(mDocumentation);
} catch (Exception e) {
e.printStackTrace();
markdownView.setText(R.string.text_load_failed);
mCommonMarkdownView.setText(R.string.text_load_failed);
}
}
@Override
public void onBackPressed() {
if (mCommonMarkdownView.canGoBack()) {
mCommonMarkdownView.goBack();
} else {
super.onBackPressed();
}
}

View File

@@ -17,11 +17,12 @@ import com.stardust.scriptdroid.ui.BaseActivity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import org.json.JSONObject;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
@@ -33,14 +34,17 @@ import java.util.Map;
public class HelpCatalogueActivity extends BaseActivity {
public static void showCatalogue(Context context, String catalogue) {
public static void showCatalogue(Context context, String title, String catalogue) {
context.startActivity(new Intent(context, HelpCatalogueActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra("title", title)
.putExtra("catalogue", catalogue));
}
public static void showCatalogue(Context context) {
showCatalogue(context, "main");
public static void showMainCatalogue(Context context) {
context.startActivity(new Intent(context, HelpCatalogueActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
private static final Map<String, List<Item>> CATALOGUES;
@@ -49,8 +53,8 @@ public class HelpCatalogueActivity extends BaseActivity {
String title;
String summary;
private String catalogue;
private String documentation;
private String type;
private String path;
Item(String title, String summary) {
this.title = title;
@@ -61,29 +65,25 @@ public class HelpCatalogueActivity extends BaseActivity {
this(title, null);
}
Item catalogue(String catalogue) {
this.catalogue = catalogue;
return this;
}
Item documentation(String documentation) {
this.documentation = documentation;
return this;
}
void redirect(Context context) {
if (documentation != null) {
DocumentationActivity.openDocumentation(context, title, documentation);
} else if (catalogue != null) {
showCatalogue(context, catalogue);
} else {
DocumentationActivity.openDocumentation(context, title, title);
switch (type) {
case "markdown":
DocumentationActivity.openDocumentation(context, title, path + "/" + title + ".md");
break;
case "catalogue":
showCatalogue(context, title, title);
break;
case "html":
LocalWebViewActivity.openAssetsHtml(context, title, path + "/" + title + ".html");
break;
}
}
}
List<Item> mItems;
private RecyclerView mRecyclerView;
private String mTitle;
private View.OnClickListener mOnItemClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -105,12 +105,15 @@ public class HelpCatalogueActivity extends BaseActivity {
String catalogue = getIntent().getStringExtra("catalogue");
if (catalogue == null)
catalogue = "main";
mTitle = getIntent().getStringExtra("title");
if (mTitle == null)
mTitle = getString(R.string.text_help);
mItems = CATALOGUES.get(catalogue);
}
private void setUpUI() {
setContentView(R.layout.activity_help);
setToolbarAsBack(getString(R.string.text_help));
setToolbarAsBack(mTitle);
setUpRecyclerView();
}

View File

@@ -0,0 +1,77 @@
package com.stardust.scriptdroid.ui.help;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.webkit.WebView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.tool.FileUtils;
import com.stardust.scriptdroid.ui.BaseActivity;
import java.io.IOException;
/**
* Created by Stardust on 2017/3/14.
*/
public class LocalWebViewActivity extends BaseActivity {
// TODO: 2017/3/14 缓存asset
private String mTitle;
private String mHtml;
private WebView mWebView;
public static void openAssetsHtml(Context context, String title, String path) {
context.startActivity(new Intent(context, LocalWebViewActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra("title", title)
.putExtra("path", path));
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleIntent(getIntent());
setUpUI();
}
private void handleIntent(Intent intent) {
mTitle = intent.getStringExtra("title");
String path = intent.getStringExtra("path");
if (path != null)
try {
mHtml = FileUtils.readString(getAssets().open("help/" + path));
} catch (IOException e) {
e.printStackTrace();
mHtml = getString(R.string.text_load_failed);
}
}
private void setUpUI() {
setContentView(R.layout.activity_local_webview);
setToolbarAsBack(mTitle);
loadHtml();
}
private void loadHtml() {
mWebView = $(R.id.webView);
try {
mWebView.loadDataWithBaseURL(null, mHtml, "text/html", "utf-8", null);
} catch (Exception e) {
e.printStackTrace();
mWebView.loadDataWithBaseURL(null, getString(R.string.text_load_failed), "text/html", "utf-8", null);
}
}
@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
}

View File

@@ -2,22 +2,23 @@ package com.stardust.scriptdroid.ui.main;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.text.InputType;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -33,25 +34,29 @@ import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
import com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchNotification;
import com.stardust.scriptdroid.file.SampleFileManager;
import com.stardust.scriptdroid.record.inputevent.InputEventRecorder;
import com.stardust.scriptdroid.record.inputevent.InputEventToJsRecorder;
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
import com.stardust.scriptdroid.tool.ImageSelector;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.my_script_list.MyScriptListFragment;
import com.stardust.scriptdroid.ui.main.sample_list.SampleScriptListFragment;
import com.stardust.scriptdroid.ui.settings.SettingsActivity;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.MessageEvent;
import com.stardust.view.ViewBinding;
import com.stardust.widget.SlidingUpPanel;
import com.stardust.scriptdroid.BuildConfig;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.file.FileUtils;
import com.stardust.scriptdroid.tool.FileUtils;
import com.stardust.scriptdroid.tool.BackPressedHandler;
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
import com.stardust.view.ViewBinder;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
@@ -59,30 +64,29 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
private static final String EXTRA_ACTION = "EXTRA_ACTION";
public static final String ACTION_NOTIFY_SCRIPT_LIST_CHANGE = "ACTION_NOTIFY_SCRIPT_LIST_CHANGE";
private static final String ACTION_ON_ACTION_RECORD_STOPPED = "ACTION_ON_ACTION_RECORD_STOPPED";
private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT";
private static final String ACTION_ON_ROOT_RECORD_STOPPED = "ACTION_ON_ROOT_RECORD_STOPPED";
private SlidingUpPanel mAddFilePanel;
private ScriptListRecyclerView mScriptListRecyclerView;
private ScriptFileList mScriptFileList;
private MyScriptListFragment mMyScriptListFragment;
private SampleScriptListFragment mSampleScriptListFragment;
private DrawerLayout mDrawerLayout;
private Receiver mReceiver;
private OnActivityResultDelegate.Manager mManager = new OnActivityResultDelegate.Manager();
private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setUpUI();
checkPermissions();
registerReceivers();
registerBackPressHandler();
handleIntent(getIntent());
}
private void registerReceivers() {
mReceiver = new Receiver();
registerReceiver(mReceiver, new IntentFilter(ACTION_NOTIFY_SCRIPT_LIST_CHANGE));
private void registerBackPressHandler() {
mBackPressObserver.registerHandler(new BackPressedHandler.DoublePressExit(this));
}
private void checkPermissions() {
@@ -119,20 +123,33 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
private void addScriptFile(String name, String path) {
mScriptFileList.add(new ScriptFile(name, path));
mScriptListRecyclerView.getAdapter().notifyItemInserted(mScriptFileList.size() - 1);
EventBus.getDefault().post(new MessageEvent(MyScriptListFragment.MESSAGE_SCRIPT_FILE_ADDED));
}
private void setUpUI() {
mDrawerLayout = (DrawerLayout) View.inflate(this, R.layout.activity_main, null);
setContentView(mDrawerLayout);
SlideMenuFragment.setFragment(this, R.id.fragment_slide_menu);
setUpFragment();
mAddFilePanel = $(R.id.bottom_menu);
setUpToolbar();
setUpTabLayout();
setUpDrawerHeader();
setUpScriptList();
ViewBinder.bind(this);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
private void setUpFragment() {
SlideMenuFragment.setFragment(this, R.id.fragment_slide_menu);
mMyScriptListFragment = new MyScriptListFragment();
mScriptFileList = SharedPrefScriptFileList.getInstance();
mSampleScriptListFragment = new SampleScriptListFragment();
}
private void setUpTabLayout() {
TabLayout tabLayout = $(R.id.tab);
ViewPager viewPager = $(R.id.viewpager);
viewPager.setAdapter(new FragmentPagerAdapter());
tabLayout.setupWithViewPager(viewPager);
}
@SuppressLint("SetTextI18n")
@@ -143,13 +160,18 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
if (path != null) {
setDrawerHeaderImage(path);
}
path = Pref.def().getString(Pref.KEY_APP_BAR_IMAGE_PATH, null);
if (path != null) {
setAppBarImage(path);
}
$(R.id.drawer).setFitsSystemWindows(false);
}
private void setDrawerHeaderImage(String path) {
Drawable d = BitmapDrawable.createFromPath(path);
if (d != null)
if (d != null) {
((ImageView) $(R.id.drawer_header_img)).setImageDrawable(d);
}
}
private void setUpToolbar() {
@@ -163,11 +185,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
mDrawerLayout.addDrawerListener(drawerToggle);
}
private void setUpScriptList() {
mScriptListRecyclerView = $(R.id.script_list);
mScriptFileList = SharedPrefScriptFileList.getInstance();
mScriptListRecyclerView.setScriptFileList(mScriptFileList);
}
@ViewBinding.Click(R.id.add)
private void showAddFilePanel() {
@@ -201,7 +218,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
}
}
addScriptFile(name, path);
new ScriptFileOperation.Edit().operate(mScriptListRecyclerView, mScriptFileList, mScriptFileList.size() - 1);
new ScriptFileOperation.Edit().operate(mMyScriptListFragment.getScriptListRecyclerView(), mScriptFileList, mScriptFileList.size() - 1);
} else {
Snackbar.make(mDrawerLayout, R.string.text_file_create_fail, Snackbar.LENGTH_LONG).show();
}
@@ -257,15 +274,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
}).select();
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
SampleFileManager.getInstance().copySampleScriptFileIfNeeded();
mScriptListRecyclerView.getAdapter().notifyDataSetChanged();
}
}
@Override
public void onFileSelection(@NonNull FileChooserDialog dialog, @NonNull File file) {
addScriptFile(file.getPath());
@@ -323,23 +331,21 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
}
private BackPressedHandler mBackPressedHandler = new BackPressedHandler.DoublePressExit(this);
@Override
public void onBackPressed() {
if (mScriptListRecyclerView.getScriptFileOperationPopupMenu().isShowing()) {
mScriptListRecyclerView.getScriptFileOperationPopupMenu().dismiss();
} else if (mAddFilePanel.isShowing()) {
if (mAddFilePanel.isShowing()) {
mAddFilePanel.dismiss();
} else if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(Gravity.START);
} else {
mBackPressedHandler.onBackPressed();
mBackPressObserver.onBackPressed();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
@Override
@@ -363,14 +369,43 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
context.startActivity(intent);
}
private class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_NOTIFY_SCRIPT_LIST_CHANGE)) {
mScriptListRecyclerView.getAdapter().notifyDataSetChanged();
public void OnAppBarClick(View view) {
new ImageSelector(this, mManager, new ImageSelector.ImageSelectorCallback() {
@Override
public void onImageSelected(String path) {
Pref.def().edit().putString(Pref.KEY_APP_BAR_IMAGE_PATH, path).apply();
setAppBarImage(path);
}
}).select();
}
private void setAppBarImage(String path) {
Drawable d = BitmapDrawable.createFromPath(path);
if (d != null) {
$(R.id.app_bar).setBackground(d);
}
}
private class FragmentPagerAdapter extends android.support.v4.app.FragmentPagerAdapter {
FragmentPagerAdapter() {
super(MainActivity.this.getSupportFragmentManager());
}
@Override
public Fragment getItem(int position) {
return position == 0 ? mMyScriptListFragment : mSampleScriptListFragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
return getString(position == 0 ? R.string.text_my_script : R.string.text_sample_script);
}
}
}

View File

@@ -11,10 +11,10 @@ import android.view.View;
import android.view.ViewGroup;
import com.stardust.app.Fragment;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.Droid;
import com.stardust.scriptdroid.external.floating_window.FloatingWindowManger;
import com.stardust.scriptdroid.external.floating_window.HoverMenuService;
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
import com.stardust.scriptdroid.ui.console.ConsoleActivity;
@@ -22,6 +22,9 @@ import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity;
import com.stardust.view.ViewBinder;
import com.stardust.view.ViewBinding;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
/**
* Created by Stardust on 2017/1/30.
@@ -35,7 +38,13 @@ public class SlideMenuFragment extends Fragment {
activity.getSupportFragmentManager().beginTransaction().replace(viewId, fragment).commit();
}
private SwitchCompat mAutoOperateServiceSwitch, mAssistServiceSwitch;
private SwitchCompat mAutoOperateServiceSwitch, mFloatingWindowSwitch;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
@Nullable
@Override
@@ -61,12 +70,12 @@ public class SlideMenuFragment extends Fragment {
mAutoOperateServiceSwitch.setChecked(AccessibilityWatchDogService.isEnable());
}
}, 450);
mAssistServiceSwitch.setChecked(FloatingWindowManger.isFloatingWindowShowing());
mFloatingWindowSwitch.setChecked(FloatingWindowManger.isFloatingWindowShowing());
}
private void setUpSwitchCompat() {
mAutoOperateServiceSwitch = $(R.id.sw_auto_operate_service);
mAssistServiceSwitch = $(R.id.sw_floating_window);
mFloatingWindowSwitch = $(R.id.sw_floating_window);
}
@@ -77,7 +86,7 @@ public class SlideMenuFragment extends Fragment {
@ViewBinding.Click(R.id.syntax_and_api)
private void startSyntaxHelpActivity() {
HelpCatalogueActivity.showCatalogue(getActivity());
HelpCatalogueActivity.showMainCatalogue(getActivity());
}
@ViewBinding.Click(R.id.auto_operate_service)
@@ -105,7 +114,7 @@ public class SlideMenuFragment extends Fragment {
@ViewBinding.Click(R.id.floating_window)
private void toggleAssistServiceSwitch() {
mAssistServiceSwitch.toggle();
mFloatingWindowSwitch.toggle();
}
@@ -121,6 +130,12 @@ public class SlideMenuFragment extends Fragment {
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe
public void onHoverMenuServiceStateChanged(HoverMenuService.ServiceStateChangedEvent event) {
mFloatingWindowSwitch.setChecked(event.state);
}
}

View File

@@ -0,0 +1,99 @@
package com.stardust.scriptdroid.ui.main.my_script_list;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.stardust.app.Fragment;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
import com.stardust.scriptdroid.tool.BackPressedHandler;
import com.stardust.util.MessageEvent;
import com.stardust.widget.SimpleAdapterDataObserver;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
/**
* Created by Stardust on 2017/3/13.
*/
public class MyScriptListFragment extends Fragment implements BackPressedHandler {
public static final String MESSAGE_SCRIPT_FILE_ADDED = "MESSAGE_SCRIPT_FILE_ADDED";
private ScriptListRecyclerView mScriptListRecyclerView;
private ScriptFileList mScriptFileList;
private View mNoScriptHint;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
@Nullable
@Override
public View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_script_list, container, false);
return view;
}
@Override
public void onStart() {
super.onStart();
init();
}
private void init() {
setUpScriptList();
}
private void setUpScriptList() {
mScriptListRecyclerView = $(R.id.script_list);
mScriptFileList = SharedPrefScriptFileList.getInstance();
mNoScriptHint = $(R.id.hint_no_script);
mScriptListRecyclerView.getAdapter().registerAdapterDataObserver(new SimpleAdapterDataObserver() {
@Override
public void onSomethingChanged() {
if (mScriptListRecyclerView.getAdapter().getItemCount() == 0) {
mNoScriptHint.setVisibility(View.VISIBLE);
} else {
mNoScriptHint.setVisibility(View.GONE);
}
}
});
mScriptListRecyclerView.setScriptFileList(mScriptFileList);
}
@Override
public boolean onBackPressed() {
if (mScriptListRecyclerView.getScriptFileOperationPopupMenu().isShowing()) {
mScriptListRecyclerView.getScriptFileOperationPopupMenu().dismiss();
return true;
}
return false;
}
public ScriptListRecyclerView getScriptListRecyclerView() {
return mScriptListRecyclerView;
}
@Subscribe
public void onMessageEvent(MessageEvent event) {
if (event.message.equals(MESSAGE_SCRIPT_FILE_ADDED)) {
mScriptListRecyclerView.getAdapter().notifyItemInserted(mScriptFileList.size() - 1);
}
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.ui.main;
package com.stardust.scriptdroid.ui.main.my_script_list;
import android.content.Context;
import android.os.Environment;
@@ -14,15 +14,12 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.tool.ViewTool;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperationPopupMenu;
import com.stardust.scriptdroid.tool.ClassTool;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -182,6 +179,11 @@ public class ScriptListRecyclerView extends ThemeColorRecyclerView {
public int getItemCount() {
return mScriptFileList.size();
}
@Override
public void registerAdapterDataObserver(AdapterDataObserver observer) {
super.registerAdapterDataObserver(observer);
}
}
private class ViewHolder extends RecyclerView.ViewHolder {

View File

@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import com.afollestad.materialdialogs.MaterialDialog;
@@ -13,16 +12,12 @@ import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.external.shortcut.Shortcut;
import com.stardust.scriptdroid.external.shortcut.ShortcutActivity;
import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.scriptdroid.ui.main.ScriptListRecyclerView;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/1/23.
*/

View File

@@ -0,0 +1,34 @@
package com.stardust.scriptdroid.ui.main.sample_list;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.stardust.app.Fragment;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.sample.SampleFileManager;
/**
* Created by Stardust on 2017/3/13.
*/
public class SampleScriptListFragment extends Fragment {
private SampleScriptListRecyclerView mSampleScriptListRecyclerView;
@Nullable
@Override
public View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_sample_script_list, container, false);
}
@Override
protected void afterCreateView() {
mSampleScriptListRecyclerView = $(R.id.script_list);
mSampleScriptListRecyclerView.setSamples(SampleFileManager.getInstance().getSamplesFromAssets(getContext().getAssets(), "sample"));
}
}

View File

@@ -0,0 +1,166 @@
package com.stardust.scriptdroid.ui.main.sample_list;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.bignerdranch.expandablerecyclerview.ChildViewHolder;
import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter;
import com.bignerdranch.expandablerecyclerview.ParentViewHolder;
import com.bignerdranch.expandablerecyclerview.model.Parent;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.sample.Sample;
import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.widget.LevelBeamView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/3/13.
*/
public class SampleScriptListRecyclerView extends RecyclerView {
private OnClickListener mOnItemClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
SampleViewHolder viewHolder = (SampleViewHolder) getChildViewHolder(v);
viewSample(viewHolder.getChild());
}
};
private Adapter mAdapter;
private List<SampleGroup> mSampleGroups = new ArrayList<>();
public SampleScriptListRecyclerView(Context context) {
super(context);
init();
}
public SampleScriptListRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SampleScriptListRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public void setSamples(List<com.stardust.scriptdroid.sample.SampleGroup> samples) {
mSampleGroups.clear();
for (com.stardust.scriptdroid.sample.SampleGroup sampleGroup : samples) {
mSampleGroups.add(new SampleGroup(sampleGroup));
}
mAdapter = new Adapter(mSampleGroups);
setAdapter(mAdapter);
}
private void init() {
setLayoutManager(new LinearLayoutManager(getContext()));
addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL));
}
private void viewSample(Sample sample) {
EditActivity.editAssetFile(getContext(), sample.name, sample.path);
}
private class SampleGroup implements Parent<Sample> {
private com.stardust.scriptdroid.sample.SampleGroup mSampleGroup;
SampleGroup(com.stardust.scriptdroid.sample.SampleGroup sampleGroup) {
mSampleGroup = sampleGroup;
}
String getGroupName() {
return mSampleGroup.name;
}
@Override
public List<Sample> getChildList() {
return mSampleGroup.sampleList;
}
@Override
public boolean isInitiallyExpanded() {
return false;
}
}
private class SampleViewHolder extends ChildViewHolder<Sample> {
TextView name;
SampleViewHolder(@NonNull View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
((LevelBeamView) itemView.findViewById(R.id.level)).setLevel(2);
itemView.setOnClickListener(mOnItemClickListener);
}
void bind(Sample sample) {
name.setText(sample.name);
}
}
private class SampleGroupViewHolder extends ParentViewHolder<SampleGroup, Sample> {
TextView name;
SampleGroupViewHolder(@NonNull View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
((LevelBeamView) itemView.findViewById(R.id.level)).setLevel(0);
}
void bind(SampleGroup group) {
name.setText(group.getGroupName());
}
}
private class Adapter extends ExpandableRecyclerAdapter<SampleGroup, Sample, SampleGroupViewHolder, SampleViewHolder> {
public Adapter(@NonNull List<SampleGroup> parentList) {
super(parentList);
}
@NonNull
@Override
public SampleGroupViewHolder onCreateParentViewHolder(@NonNull ViewGroup parentViewGroup, int viewType) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.sample_recycler_view_group, parentViewGroup, false);
return new SampleGroupViewHolder(view);
}
@NonNull
@Override
public SampleViewHolder onCreateChildViewHolder(@NonNull ViewGroup childViewGroup, int viewType) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.sample_recycler_view_item, childViewGroup, false);
return new SampleViewHolder(view);
}
@Override
public void onBindParentViewHolder(@NonNull SampleGroupViewHolder parentViewHolder, int parentPosition, @NonNull SampleGroup parent) {
parentViewHolder.bind(parent);
}
@Override
public void onBindChildViewHolder(@NonNull SampleViewHolder childViewHolder, int parentPosition, int childPosition, @NonNull Sample child) {
childViewHolder.bind(child);
}
}
}

View File

@@ -10,7 +10,8 @@ import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;
import com.stardust.scriptdroid.file.SampleFileManager;
import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.sample.SampleFileManager;
import com.stardust.scriptdroid.tool.IntentTool;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.error.IssueReportActivity;
@@ -106,15 +107,13 @@ public class SettingsActivity extends BaseActivity {
ColorSelectActivity.startColorSelect(getActivity(), getString(R.string.mt_color_picker_title), COLOR_ITEMS);
}
})
.entry(getString(R.string.text_re_import_samples), new Runnable() {
.entry(getString(R.string.text_reset_background), new Runnable() {
@Override
public void run() {
int failCount = SampleFileManager.getInstance().copySampleScriptFile();
if (failCount <= 0) {
Toast.makeText(getActivity(), R.string.text_re_import_succeed, Toast.LENGTH_SHORT).show();
notifyScriptListChanged();
} else
Toast.makeText(getActivity(), R.string.text_fail, Toast.LENGTH_SHORT).show();
Pref.def().edit().putString(Pref.KEY_APP_BAR_IMAGE_PATH, null)
.putString(Pref.KEY_DRAWER_HEADER_IMAGE_PATH, null)
.apply();
Toast.makeText(getActivity(), R.string.text_restart_app_to_apply, Toast.LENGTH_SHORT).show();
}
})
.entry(getString(R.string.text_issue_report), new Runnable() {
@@ -146,10 +145,6 @@ public class SettingsActivity extends BaseActivity {
.map();
}
private void notifyScriptListChanged() {
getActivity().sendBroadcast(new Intent(MainActivity.ACTION_NOTIFY_SCRIPT_LIST_CHANGE));
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
Runnable action = ACTION_MAP.get(preference.getTitle().toString());

View File

@@ -0,0 +1,29 @@
package com.stardust.util;
import android.content.Context;
import android.content.res.AssetManager;
import com.stardust.scriptdroid.tool.FileUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Stardust on 2017/3/14.
*/
public class AssetsCache {
private Map<String, String> mCache = new HashMap<>();
public String read(AssetManager manager, String path) throws IOException {
String str = mCache.get(path);
if (str == null) {
str = FileUtils.readString(manager.open(path));
mCache.put(path, str);
}
return str;
}
}

View File

@@ -1,16 +1,24 @@
package com.stardust.widget;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import java.util.Collection;
import java.util.Collections;
/**
* Created by Stardust on 2017/3/5.
*/
@@ -18,7 +26,11 @@ import org.commonmark.renderer.html.HtmlRenderer;
public class CommonMarkdownView extends WebView {
private Parser mParser = Parser.builder().build();
private HtmlRenderer mHtmlRender = HtmlRenderer.builder().build();
private HtmlRenderer mHtmlRender = HtmlRenderer.builder()
.extensions(Collections.singleton(new HeadingAnchorExtension.Builder().build()))
.build();
private String mMarkdownHtml;
public CommonMarkdownView(Context context) {
super(context);
@@ -41,16 +53,35 @@ public class CommonMarkdownView extends WebView {
public void onPageFinished(WebView view, String url) {
loadUrl("javascript:document.body.style.margin=\"12%\"; void 0");
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(request.getUrl()));
return true;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)));
return true;
}
});
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CommonMarkdownView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public void loadMarkdown(String markdown) {
String html = renderMarkdown(markdown);
mMarkdownHtml = renderMarkdown(markdown);
loadHtml(mMarkdownHtml);
}
private void loadHtml(String html) {
loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
}
@@ -66,4 +97,11 @@ public class CommonMarkdownView extends WebView {
private void setText(String text) {
loadDataWithBaseURL(null, text, "text/plain", "utf-8", null);
}
}
public void goBack() {
super.goBack();
if (!canGoBack() && mMarkdownHtml != null) {
loadHtml(mMarkdownHtml);
}
}
}

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.layout_inspector.view;
package com.stardust.widget;
import android.content.Context;
import android.graphics.Canvas;

View File

@@ -0,0 +1,35 @@
package com.stardust.widget;
import android.support.v7.widget.RecyclerView;
/**
* Created by Stardust on 2017/3/14.
*/
public class SimpleAdapterDataObserver extends RecyclerView.AdapterDataObserver {
public void onChanged() {
onSomethingChanged();
}
public void onItemRangeChanged(int positionStart, int itemCount) {
onSomethingChanged();
}
public void onItemRangeInserted(int positionStart, int itemCount) {
onSomethingChanged();
}
public void onItemRangeRemoved(int positionStart, int itemCount) {
onSomethingChanged();
}
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
onSomethingChanged();
}
public void onSomethingChanged() {
}
}