add: file sorting
This commit is contained in:
@@ -9,8 +9,8 @@ android {
|
||||
applicationId "com.stardust.scriptdroid"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 23
|
||||
versionCode 205
|
||||
versionName "3.0.0 Alpha6"
|
||||
versionCode 206
|
||||
versionName "3.0.0 Alpha7"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
ndk {
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.stardust.scriptdroid.script;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/23.
|
||||
*/
|
||||
|
||||
public abstract class ScriptFileList {
|
||||
|
||||
private static ScriptFileList impl;
|
||||
|
||||
public static void setImpl(ScriptFileList list) {
|
||||
impl = list;
|
||||
}
|
||||
|
||||
public static ScriptFileList getImpl() {
|
||||
return impl;
|
||||
}
|
||||
|
||||
public abstract void add(ScriptFile scriptFile);
|
||||
|
||||
public abstract ScriptFile get(int i);
|
||||
|
||||
public abstract void remove(int i);
|
||||
|
||||
public abstract void rename(int position, String newName, boolean renameFile);
|
||||
|
||||
public abstract int size();
|
||||
|
||||
public boolean deleteFromFileSystem(int i) {
|
||||
if (i < 0 || i >= size())
|
||||
return false;
|
||||
File file = get(i);
|
||||
remove(i);
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
public abstract boolean containsPath(String path);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package com.stardust.scriptdroid.script;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.scriptdroid.App;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/23.
|
||||
*/
|
||||
|
||||
public class SharedPrefScriptFileList extends ScriptFileList {
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private static final String SP_KEY_SCRIPT_NAME = "script_name";
|
||||
private static final String SP_KEY_SCRIPT_PATH = "script_path";
|
||||
|
||||
private static ScriptFileList instance = new SharedPrefScriptFileList(App.getApp());
|
||||
|
||||
private SharedPreferences mSharedPreferences;
|
||||
private List<String> mScriptPath;
|
||||
private List<String> mScriptName;
|
||||
|
||||
public static ScriptFileList getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public SharedPrefScriptFileList(Context context) {
|
||||
mSharedPreferences = context.getSharedPreferences("SharedPrefScriptFileList", Context.MODE_PRIVATE);
|
||||
readFromSharedPref();
|
||||
}
|
||||
|
||||
|
||||
private void readFromSharedPref() {
|
||||
Type type = new TypeToken<List<String>>() {
|
||||
}.getType();
|
||||
mScriptName = GSON.fromJson(mSharedPreferences.getString(SP_KEY_SCRIPT_NAME, ""), type);
|
||||
mScriptPath = GSON.fromJson(mSharedPreferences.getString(SP_KEY_SCRIPT_PATH, ""), type);
|
||||
if (mScriptName == null || mScriptPath == null || mScriptName.size() != mScriptPath.size()) {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
mScriptName = new ArrayList<>();
|
||||
mScriptPath = new ArrayList<>();
|
||||
syncWithSharedPref();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ScriptFile scriptFile) {
|
||||
mScriptName.add(scriptFile.getSimplifiedName());
|
||||
mScriptPath.add(scriptFile.getSimplifiedPath());
|
||||
syncWithSharedPref();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptFile get(int i) {
|
||||
return new ScriptFile(mScriptPath.get(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(int i) {
|
||||
mScriptName.remove(i);
|
||||
mScriptPath.remove(i);
|
||||
syncWithSharedPref();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rename(int position, String newName, boolean renameFile) {
|
||||
mScriptName.set(position, newName);
|
||||
if (renameFile) {
|
||||
String newPath = PFile.renameWithoutExtensionAndReturnNewPath(mScriptPath.get(position), newName);
|
||||
mScriptPath.set(position, newPath);
|
||||
}
|
||||
syncWithSharedPref();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return mScriptPath.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsPath(String path) {
|
||||
return mScriptPath.contains(path);
|
||||
}
|
||||
|
||||
protected void syncWithSharedPref() {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putString(SP_KEY_SCRIPT_NAME, GSON.toJson(mScriptName));
|
||||
editor.putString(SP_KEY_SCRIPT_PATH, GSON.toJson(mScriptPath));
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class StorageFileProvider {
|
||||
if (scriptFiles == null) {
|
||||
return Observable.empty();
|
||||
} else {
|
||||
FileSorter.sort(scriptFiles);
|
||||
FileSorter.sort(scriptFiles, FileSorter.NAME);
|
||||
mScriptFileCache.put(dir.getPath(), scriptFiles);
|
||||
return Observable.fromArray(scriptFiles);
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
|
||||
public void loadFile(final File file) {
|
||||
setProgress(true);
|
||||
// TODO: 2017/9/29 handle error
|
||||
Observable.fromCallable(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
@@ -346,20 +347,22 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
|
||||
@JavascriptInterface
|
||||
public void setStringFromJs(String text) {
|
||||
if (mStringFromJs != null) {
|
||||
mStringFromJs.onNext(text);
|
||||
mStringFromJs.onComplete();
|
||||
mStringFromJs = null;
|
||||
if (mStringFromJs == null) {
|
||||
return;
|
||||
}
|
||||
mStringFromJs.onNext(text);
|
||||
mStringFromJs.onComplete();
|
||||
mStringFromJs = null;
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public void setIntFromJs(int i) {
|
||||
if (mIntFromJs != null) {
|
||||
mIntFromJs.onNext(i);
|
||||
mIntFromJs.onComplete();
|
||||
mIntFromJs = null;
|
||||
if (mIntFromJs == null) {
|
||||
return;
|
||||
}
|
||||
mIntFromJs.onNext(i);
|
||||
mIntFromJs.onComplete();
|
||||
mIntFromJs = null;
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@@ -371,26 +374,28 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
|
||||
@JavascriptInterface
|
||||
public void onTextChange() {
|
||||
if (mCallback != null) {
|
||||
mWebView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCallback.onChange();
|
||||
}
|
||||
});
|
||||
if (mCallback == null) {
|
||||
return;
|
||||
}
|
||||
mWebView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCallback.onChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public void updateCodeCompletion(final int fromLine, final int fromCh, final int toLine, final int toCh, final String[] list) {
|
||||
if (mCallback != null) {
|
||||
mWebView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCallback.updateCodeCompletion(fromLine, fromCh, toLine, toCh, list);
|
||||
}
|
||||
});
|
||||
if (mCallback == null) {
|
||||
return;
|
||||
}
|
||||
mWebView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCallback.updateCodeCompletion(fromLine, fromCh, toLine, toCh, list);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -459,7 +464,7 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(WebView view, int newProgress) {
|
||||
mProgressBar.setVisibility(newProgress == 100 ? VISIBLE : GONE);
|
||||
mProgressBar.setVisibility(newProgress == 100 ? GONE : VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.stardust.scriptdroid.ui.floating;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.enhancedfloaty.FloatyService;
|
||||
import com.stardust.enhancedfloaty.ResizableFloaty;
|
||||
import com.stardust.enhancedfloaty.ResizableFloatyWindow;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.scriptdroid.ui.edit.EditActivity_;
|
||||
import com.stardust.scriptdroid.ui.edit.EditorView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
import static com.stardust.scriptdroid.ui.edit.EditorView.EXTRA_NAME;
|
||||
import static com.stardust.scriptdroid.ui.edit.EditorView.EXTRA_PATH;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/9/29.
|
||||
*/
|
||||
|
||||
public class EditorFloaty implements ResizableFloaty {
|
||||
|
||||
private Intent mIntent;
|
||||
|
||||
@BindView(R.id.resizer)
|
||||
View mResizeIcon;
|
||||
@BindView(R.id.move_cursor)
|
||||
View mMoveIcon;
|
||||
|
||||
private ResizableFloatyWindow mWindow;
|
||||
|
||||
public EditorFloaty(Intent intent) {
|
||||
mIntent = intent;
|
||||
}
|
||||
|
||||
public static void floatingEdit(Context context, Intent intent) {
|
||||
FloatyService.addWindow(new ResizableFloatyWindow(new EditorFloaty(intent)));
|
||||
context.startService(new Intent(context, FloatyService.class));
|
||||
}
|
||||
|
||||
public static void floatingEdit(Context context, String path) {
|
||||
floatingEdit(context, null, path);
|
||||
}
|
||||
|
||||
public static void floatingEdit(Context context, String name, String path) {
|
||||
floatingEdit(context, new Intent(context, EditActivity_.class)
|
||||
.putExtra(EXTRA_PATH, path)
|
||||
.putExtra(EXTRA_NAME, name));
|
||||
}
|
||||
|
||||
public static void floatingEdit(Context context, ScriptFile file) {
|
||||
floatingEdit(context, file.getSimplifiedName(), file.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View inflateView(FloatyService floatyService, ResizableFloatyWindow resizableFloatyWindow) {
|
||||
mWindow = resizableFloatyWindow;
|
||||
View v = View.inflate(new ContextThemeWrapper(floatyService, R.style.AppTheme), R.layout.floating_editor, null);
|
||||
setUpViews(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
private void setUpViews(View v) {
|
||||
EditorView editorView = (EditorView) v.findViewById(R.id.editor_view);
|
||||
editorView.handleIntent(mIntent);
|
||||
ButterKnife.bind(this, v);
|
||||
}
|
||||
|
||||
@OnClick(R.id.move_or_resize)
|
||||
void showOrHideMoveAndResizeIcon() {
|
||||
if (mResizeIcon.getVisibility() == View.VISIBLE) {
|
||||
mResizeIcon.setVisibility(View.GONE);
|
||||
mMoveIcon.setVisibility(View.GONE);
|
||||
} else {
|
||||
mResizeIcon.setVisibility(View.VISIBLE);
|
||||
mMoveIcon.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.close)
|
||||
void close() {
|
||||
mWindow.close();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getResizerView(View view) {
|
||||
return view.findViewById(R.id.resizer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getMoveCursorView(View view) {
|
||||
return view.findViewById(R.id.move_cursor);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import com.stardust.scriptdroid.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.tool.SimpleObserver;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.floating.EditorFloaty;
|
||||
import com.stardust.scriptdroid.ui.main.FloatingActionMenu;
|
||||
import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
|
||||
import com.stardust.util.BackPressedHandler;
|
||||
@@ -56,7 +57,8 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
|
||||
mScriptFileList.setOnScriptFileClickListener(new ScriptListView.OnScriptFileClickListener() {
|
||||
@Override
|
||||
public void onScriptFileClick(View view, ScriptFile file) {
|
||||
Scripts.edit(file);
|
||||
//Scripts.edit(file);
|
||||
EditorFloaty.floatingEdit(getContext(), file);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -112,6 +114,10 @@ public class MyScriptListFragment extends ViewPagerFragment implements BackPress
|
||||
mFloatingActionMenu.collapse();
|
||||
return true;
|
||||
}
|
||||
if(mScriptFileList.canGoBack()){
|
||||
mScriptFileList.goBack();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@@ -23,16 +24,24 @@ import com.stardust.scriptdroid.script.StorageFileProvider;
|
||||
import com.stardust.scriptdroid.tool.SimpleObserver;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
|
||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||
import com.stardust.scriptdroid.ui.viewmodel.ScriptList;
|
||||
import com.stardust.widget.BindableViewHolder;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.ObservableSource;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Action;
|
||||
import io.reactivex.functions.BiConsumer;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.functions.Function;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
@@ -46,14 +55,14 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
void onScriptFileClick(View view, ScriptFile file);
|
||||
}
|
||||
|
||||
private ScriptList mScriptList = new ScriptList();
|
||||
private RecyclerView mScriptListView;
|
||||
private ScriptListAdapter mScriptListAdapter = new ScriptListAdapter();
|
||||
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
|
||||
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
|
||||
private ScriptFile mCurrentDirectory;
|
||||
private OnScriptFileClickListener mOnScriptFileClickListener;
|
||||
private ScriptFile mSelectedScriptFile;
|
||||
private StorageFileProvider mStorageFileProvider;
|
||||
private boolean mDirSortMenuShowing = false;
|
||||
|
||||
public ScriptListView(Context context) {
|
||||
super(context);
|
||||
@@ -78,6 +87,16 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
mOnScriptFileClickListener = onScriptFileClickListener;
|
||||
}
|
||||
|
||||
|
||||
public boolean canGoBack() {
|
||||
return !mCurrentDirectory.equals(mStorageFileProvider.getInitialDirectory());
|
||||
}
|
||||
|
||||
public void goBack() {
|
||||
mCurrentDirectory = mCurrentDirectory.getParentFile();
|
||||
loadScriptList();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setOnRefreshListener(this);
|
||||
mScriptListView = new RecyclerView(getContext());
|
||||
@@ -95,7 +114,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
@Override
|
||||
public int getSpanSize(int position) {
|
||||
//For directories
|
||||
if (position >= 1 && position <= mDirectories.size()) {
|
||||
if (position >= 1 && position <= mScriptList.directoryCount()) {
|
||||
return 1;
|
||||
}
|
||||
//For files and category
|
||||
@@ -107,24 +126,30 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
|
||||
|
||||
private void loadScriptList() {
|
||||
mScriptFiles.clear();
|
||||
mDirectories.clear();
|
||||
mScriptList.clear();
|
||||
mStorageFileProvider.getDirectoryScriptFiles(mCurrentDirectory)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new SimpleObserver<ScriptFile>() {
|
||||
|
||||
.collectInto(mScriptList, new BiConsumer<ScriptList, ScriptFile>() {
|
||||
@Override
|
||||
public void onNext(@io.reactivex.annotations.NonNull ScriptFile file) {
|
||||
if (file.isFile()) {
|
||||
mScriptFiles.add(file);
|
||||
} else {
|
||||
mDirectories.add(file);
|
||||
}
|
||||
public void accept(ScriptList list, ScriptFile file) throws Exception {
|
||||
list.add(file);
|
||||
}
|
||||
|
||||
})
|
||||
.observeOn(Schedulers.computation())
|
||||
.doOnSuccess(new Consumer<ScriptList>() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
public void accept(@NonNull ScriptList list) throws Exception {
|
||||
Log.d("SSS", "before sort:" + Thread.currentThread());
|
||||
list.sort();
|
||||
Log.d("SSS", "after sort:" + Thread.currentThread());
|
||||
}
|
||||
})
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<ScriptList>() {
|
||||
@Override
|
||||
public void accept(@NonNull ScriptList list) throws Exception {
|
||||
Log.d("SSS", "notifyDataSetChanged:" + Thread.currentThread());
|
||||
mScriptList = list;
|
||||
mScriptListAdapter.notifyDataSetChanged();
|
||||
setRefreshing(false);
|
||||
}
|
||||
@@ -166,16 +191,54 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
case R.id.open_by_other_apps:
|
||||
Scripts.openByOtherApps(mSelectedScriptFile);
|
||||
break;
|
||||
case R.id.action_sort_by_date:
|
||||
sort(ScriptList.SORT_TYPE_DATE, mDirSortMenuShowing);
|
||||
break;
|
||||
case R.id.action_sort_by_type:
|
||||
sort(ScriptList.SORT_TYPE_TYPE, mDirSortMenuShowing);
|
||||
break;
|
||||
case R.id.action_sort_by_name:
|
||||
sort(ScriptList.SORT_TYPE_NAME, mDirSortMenuShowing);
|
||||
break;
|
||||
case R.id.action_sort_by_size:
|
||||
sort(ScriptList.SORT_TYPE_SIZE, mDirSortMenuShowing);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sort(final int sortType, final boolean isDir) {
|
||||
setRefreshing(true);
|
||||
Observable.fromCallable(new Callable<ScriptList>() {
|
||||
@Override
|
||||
public ScriptList call() throws Exception {
|
||||
if (isDir) {
|
||||
mScriptList.sortDir(sortType);
|
||||
} else {
|
||||
mScriptList.sortFile(sortType);
|
||||
}
|
||||
return mScriptList;
|
||||
}
|
||||
})
|
||||
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<ScriptList>() {
|
||||
@Override
|
||||
public void accept(@NonNull ScriptList o) throws Exception {
|
||||
mScriptListAdapter.notifyDataSetChanged();
|
||||
setRefreshing(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
// mStorageFileProvider.unregisterDirectoryChangeListener(this);
|
||||
// mStorageFileProvider.unregisterDirectoryChangeListener(this);
|
||||
}
|
||||
|
||||
private class ScriptListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
@@ -202,23 +265,23 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
|
||||
if (position == 0 || position == mDirectories.size() + 1) {
|
||||
if (position == 0 || position == mScriptList.directoryCount() + 1) {
|
||||
bindableViewHolder.bind(position == 0, position);
|
||||
return;
|
||||
}
|
||||
if (position <= mDirectories.size()) {
|
||||
bindableViewHolder.bind(mDirectories.get(position - 1), position);
|
||||
if (position <= mScriptList.directoryCount()) {
|
||||
bindableViewHolder.bind(mScriptList.getDir(position - 1), position);
|
||||
return;
|
||||
}
|
||||
bindableViewHolder.bind(mScriptFiles.get(position - mDirectories.size() - 2), position);
|
||||
bindableViewHolder.bind(mScriptList.getFile(position - mScriptList.directoryCount() - 2), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0 || position == mDirectories.size() + 1) {
|
||||
if (position == 0 || position == mScriptList.directoryCount() + 1) {
|
||||
return VIEW_TYPE_CATEGORY;
|
||||
}
|
||||
if (position <= mDirectories.size()) {
|
||||
if (position <= mScriptList.directoryCount()) {
|
||||
return VIEW_TYPE_DIRECTORY;
|
||||
}
|
||||
return VIEW_TYPE_FILE;
|
||||
@@ -226,7 +289,7 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mScriptFiles.size() + mDirectories.size() + 2;
|
||||
return mScriptList.count() + 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,6 +401,11 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
@BindView(R.id.sort)
|
||||
ImageView mSort;
|
||||
|
||||
@BindView(R.id.order)
|
||||
ImageView mSortOrder;
|
||||
|
||||
private boolean mIsDir;
|
||||
|
||||
CategoryViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
@@ -346,11 +414,22 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
@Override
|
||||
public void bind(Boolean isDirCategory, int position) {
|
||||
mTitle.setText(isDirCategory ? R.string.text_directory : R.string.text_file);
|
||||
mIsDir = isDirCategory;
|
||||
}
|
||||
|
||||
@OnClick(R.id.order)
|
||||
void changeSortOrder() {
|
||||
|
||||
if (mIsDir) {
|
||||
mSortOrder.setImageResource(mScriptList.isDirSortedAscending() ?
|
||||
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
|
||||
mScriptList.setDirSortedAscending(!mScriptList.isDirSortedAscending());
|
||||
sort(mScriptList.getDirSortType(), mIsDir);
|
||||
} else {
|
||||
mSortOrder.setImageResource(mScriptList.isFileSortedAscending() ?
|
||||
R.drawable.ic_ascending_order : R.drawable.ic_descending_order);
|
||||
mScriptList.setFileSortedAscending(!mScriptList.isFileSortedAscending());
|
||||
sort(mScriptList.getFileSortType(), mIsDir);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.sort)
|
||||
@@ -358,7 +437,9 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
||||
PopupMenu popupMenu = new PopupMenu(getContext(), mSort);
|
||||
popupMenu.inflate(R.menu.menu_sort_options);
|
||||
popupMenu.setOnMenuItemClickListener(ScriptListView.this);
|
||||
mDirSortMenuShowing = mIsDir;
|
||||
popupMenu.show();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.stardust.scriptdroid.ui.viewmodel;
|
||||
|
||||
import com.stardust.scriptdroid.script.ScriptFile;
|
||||
import com.stardust.util.FileSorter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/9/30.
|
||||
*/
|
||||
|
||||
public class ScriptList {
|
||||
|
||||
public static final int SORT_TYPE_NAME = 0x10;
|
||||
public static final int SORT_TYPE_TYPE = 0x20;
|
||||
public static final int SORT_TYPE_SIZE = 0x30;
|
||||
public static final int SORT_TYPE_DATE = 0x40;
|
||||
|
||||
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
|
||||
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
|
||||
private int mDirSortType = SORT_TYPE_NAME;
|
||||
private boolean mDirSortedAscending;
|
||||
private boolean mFileSortedAscending;
|
||||
private int mFileSortType = SORT_TYPE_NAME;
|
||||
|
||||
public boolean isDirSortedAscending() {
|
||||
return mDirSortedAscending;
|
||||
}
|
||||
|
||||
public boolean isFileSortedAscending() {
|
||||
return mFileSortedAscending;
|
||||
}
|
||||
|
||||
public int getDirSortType() {
|
||||
return mDirSortType;
|
||||
}
|
||||
|
||||
public int getFileSortType() {
|
||||
return mFileSortType;
|
||||
}
|
||||
|
||||
public void setDirSortedAscending(boolean dirSortedAscending) {
|
||||
mDirSortedAscending = dirSortedAscending;
|
||||
}
|
||||
|
||||
public void setFileSortedAscending(boolean fileSortedAscending) {
|
||||
mFileSortedAscending = fileSortedAscending;
|
||||
}
|
||||
|
||||
private Comparator<File> getComparator(int sortType) {
|
||||
switch (sortType) {
|
||||
case SORT_TYPE_NAME:
|
||||
return FileSorter.NAME;
|
||||
case SORT_TYPE_DATE:
|
||||
return FileSorter.DATE;
|
||||
case SORT_TYPE_SIZE:
|
||||
return FileSorter.SIZE;
|
||||
case SORT_TYPE_TYPE:
|
||||
return FileSorter.TYPE;
|
||||
}
|
||||
throw new IllegalArgumentException("unknown type " + sortType);
|
||||
}
|
||||
|
||||
public int directoryCount() {
|
||||
return mDirectories.size();
|
||||
}
|
||||
|
||||
public int fileCount() {
|
||||
return mScriptFiles.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mScriptFiles.clear();
|
||||
mDirectories.clear();
|
||||
}
|
||||
|
||||
public void add(ScriptFile file) {
|
||||
if (file.isFile()) {
|
||||
mScriptFiles.add(file);
|
||||
} else {
|
||||
mDirectories.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptFile getDir(int i) {
|
||||
return mDirectories.get(i);
|
||||
}
|
||||
|
||||
public ScriptFile getFile(int i) {
|
||||
return mScriptFiles.get(i);
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return mScriptFiles.size() + mDirectories.size();
|
||||
}
|
||||
|
||||
public void sortDir(int sortType) {
|
||||
mDirSortType = sortType;
|
||||
FileSorter.sort(mDirectories, getComparator(sortType), mDirSortedAscending);
|
||||
}
|
||||
|
||||
public void sortFile(int sortType) {
|
||||
mFileSortType = sortType;
|
||||
FileSorter.sort(mScriptFiles, getComparator(sortType), mFileSortedAscending);
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
FileSorter.sort(mDirectories, getComparator(mDirSortType), mDirSortedAscending);
|
||||
FileSorter.sort(mScriptFiles, getComparator(mFileSortType), mFileSortedAscending);
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
|
||||
settings.setJavaScriptEnabled(true);
|
||||
settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
||||
settings.setDomStorageEnabled(true);
|
||||
settings.setDisplayZoomControls(false);
|
||||
mWebView.setWebViewClient(new MyWebViewClient());
|
||||
mWebView.setWebChromeClient(new MyWebChromeClient());
|
||||
}
|
||||
|
||||
60
app/src/main/res/layout/floating_editor.xml
Normal file
60
app/src/main/res/layout/floating_editor.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout 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="wrap_content">
|
||||
|
||||
<com.stardust.scriptdroid.ui.edit.EditorView_
|
||||
android:id="@+id/editor_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.stardust.widget.ToolbarMenuItem
|
||||
android:id="@+id/close"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_close_white_48dp"
|
||||
app:text="@string/text_close"/>
|
||||
|
||||
<com.stardust.widget.ToolbarMenuItem
|
||||
android:id="@+id/move_or_resize"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_settings_ethernet_white_24dp"
|
||||
app:text="@string/text_adjust"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/resizer"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/circle_cool_black"
|
||||
android:padding="6dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_resizer"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/move_cursor"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@drawable/circle_cool_black"
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_move_cursor"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -2,18 +2,18 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:checkable="true"
|
||||
android:id="@+id/action_sort_by_name"
|
||||
android:title="@string/text_name"/>
|
||||
<item
|
||||
android:checkable="true"
|
||||
android:id="@+id/action_sort_by_date"
|
||||
android:title="@string/text_time"
|
||||
/>
|
||||
<item
|
||||
android:checkable="true"
|
||||
android:id="@+id/action_sort_by_size"
|
||||
android:title="@string/text_size"
|
||||
/>
|
||||
<item
|
||||
android:checkable="true"
|
||||
android:id="@+id/action_sort_by_type"
|
||||
android:title="@string/text_type"
|
||||
/>
|
||||
</menu>
|
||||
@@ -279,6 +279,8 @@
|
||||
<string name="text_refactor">重构</string>
|
||||
<string name="text_select_variable">选择变量</string>
|
||||
<string name="text_show_type">显示变量类型</string>
|
||||
<string name="text_close">关闭</string>
|
||||
<string name="text_adjust">调整</string>
|
||||
|
||||
|
||||
<string-array name="record_control_keys">
|
||||
|
||||
@@ -2,6 +2,15 @@ package com.stardust.scriptdroid;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Action;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.functions.Function;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
@@ -17,11 +26,33 @@ public class ExampleUnitTest {
|
||||
// TODO: 2017/7/4 细节 三天 7.18
|
||||
// TODO: 2017/7/4 写文档 两天 7.20
|
||||
// TODO: 2017/7/4 发布 3.0.0 Beta 7.22
|
||||
// TODO: 2017/9/30 想象真是美好。
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
System.out.println("SOS".hashCode());
|
||||
Observable.fromCallable(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
System.out.println(Thread.currentThread());
|
||||
return "";
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.newThread())
|
||||
.doOnComplete(new Action() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
System.out.println(Thread.currentThread());
|
||||
}
|
||||
})
|
||||
.observeOn(Schedulers.newThread())
|
||||
.subscribe(new Consumer<String>() {
|
||||
@Override
|
||||
public void accept(@NonNull String s) throws Exception {
|
||||
System.out.println(Thread.currentThread());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user