feat: functions keyboard
This commit is contained in:
@@ -92,7 +92,6 @@ dependencies {
|
|||||||
exclude group: 'com.afollestad.material-dialogs'
|
exclude group: 'com.afollestad.material-dialogs'
|
||||||
exclude group: 'com.android.support'
|
exclude group: 'com.android.support'
|
||||||
})
|
})
|
||||||
//
|
|
||||||
compile 'com.github.hyb1996:android-multi-level-listview:1.1'
|
compile 'com.github.hyb1996:android-multi-level-listview:1.1'
|
||||||
compile 'de.psdev.licensesdialog:licensesdialog:1.8.1'
|
compile 'de.psdev.licensesdialog:licensesdialog:1.8.1'
|
||||||
compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'
|
compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'
|
||||||
|
|||||||
1036
app/src/main/assets/indices/all.json
Normal file
1036
app/src/main/assets/indices/all.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
|||||||
|
package com.stardust.scriptdroid.model.indices;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Module {
|
||||||
|
|
||||||
|
@SerializedName("properties")
|
||||||
|
|
||||||
|
private List<Property> mProperties = new ArrayList<>();
|
||||||
|
|
||||||
|
@SerializedName("url")
|
||||||
|
private String mUrl;
|
||||||
|
@SerializedName("name")
|
||||||
|
private String mName;
|
||||||
|
@SerializedName("summary")
|
||||||
|
private String mSummary;
|
||||||
|
|
||||||
|
public List<Property> getProperties() {
|
||||||
|
return mProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties(List<Property> properties) {
|
||||||
|
mProperties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
mUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
mName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSummary() {
|
||||||
|
return mSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSummary(String summary) {
|
||||||
|
mSummary = summary;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.stardust.scriptdroid.model.indices;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.functions.Consumer;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Modules {
|
||||||
|
|
||||||
|
private static final Type MODULE_LIST_TYPE = new TypeToken<List<Module>>() {
|
||||||
|
|
||||||
|
}.getType();
|
||||||
|
private static final String MODULES_JSON_PATH = "indices/all.json";
|
||||||
|
private static Modules sInstance = new Modules();
|
||||||
|
|
||||||
|
private List<Module> mModules;
|
||||||
|
|
||||||
|
private List<Module> loadModulesFrom(InputStream inputStream) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
return gson.fromJson(new InputStreamReader(inputStream), MODULE_LIST_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<List<Module>> getModules(Context context) {
|
||||||
|
if (mModules != null)
|
||||||
|
return Observable.just(mModules);
|
||||||
|
return Observable.fromCallable(() -> loadModulesFrom(context.getAssets().open(MODULES_JSON_PATH)))
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doOnNext(modules -> mModules = modules);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Modules getInstance() {
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.stardust.scriptdroid.model.indices;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Property {
|
||||||
|
|
||||||
|
@SerializedName("url")
|
||||||
|
private String mUrl;
|
||||||
|
|
||||||
|
@SerializedName("key")
|
||||||
|
private String mKey;
|
||||||
|
|
||||||
|
@SerializedName("summary")
|
||||||
|
private String mSummary;
|
||||||
|
|
||||||
|
@SerializedName("global")
|
||||||
|
private boolean mGlobal;
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
mUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
mKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSummary() {
|
||||||
|
return mSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSummary(String summary) {
|
||||||
|
mSummary = summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGlobal() {
|
||||||
|
return mGlobal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGlobal(boolean global) {
|
||||||
|
mGlobal = global;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.stardust.scriptdroid.tool;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InputMethodTool {
|
||||||
|
|
||||||
|
public static void dismissInputMethod(Context context, View view) {
|
||||||
|
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
if (imm == null)
|
||||||
|
return;
|
||||||
|
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.stardust.scriptdroid.ui.edit;
|
package com.stardust.scriptdroid.ui.edit;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -8,6 +9,7 @@ import android.preference.PreferenceManager;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
import android.support.v4.widget.DrawerLayout;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -21,15 +23,20 @@ import com.stardust.autojs.script.JavaScriptFileSource;
|
|||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
import com.stardust.scriptdroid.Pref;
|
import com.stardust.scriptdroid.Pref;
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
|
import com.stardust.scriptdroid.model.indices.Module;
|
||||||
|
import com.stardust.scriptdroid.model.indices.Property;
|
||||||
import com.stardust.scriptdroid.model.script.Scripts;
|
import com.stardust.scriptdroid.model.script.Scripts;
|
||||||
import com.stardust.scriptdroid.ui.doc.ManualDialog;
|
import com.stardust.scriptdroid.ui.doc.ManualDialog;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletions;
|
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletions;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletionBar;
|
import com.stardust.scriptdroid.ui.edit.completion.CodeCompletionBar;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhancedBarColors;
|
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhancedBarColors;
|
||||||
import com.stardust.scriptdroid.ui.edit.completion.Symbols;
|
import com.stardust.scriptdroid.ui.edit.completion.Symbols;
|
||||||
|
import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardHelper;
|
||||||
|
import com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardView;
|
||||||
import com.stardust.scriptdroid.ui.log.LogActivity_;
|
import com.stardust.scriptdroid.ui.log.LogActivity_;
|
||||||
import com.stardust.scriptdroid.ui.widget.EWebView;
|
import com.stardust.scriptdroid.ui.widget.EWebView;
|
||||||
import com.stardust.scriptdroid.ui.widget.ToolbarMenuItem;
|
import com.stardust.scriptdroid.ui.widget.ToolbarMenuItem;
|
||||||
|
import com.stardust.util.BackPressedHandler;
|
||||||
import com.stardust.widget.ViewSwitcher;
|
import com.stardust.widget.ViewSwitcher;
|
||||||
|
|
||||||
import org.androidannotations.annotations.AfterViews;
|
import org.androidannotations.annotations.AfterViews;
|
||||||
@@ -50,7 +57,7 @@ import static com.stardust.scriptdroid.model.script.Scripts.ACTION_ON_EXECUTION_
|
|||||||
* Created by Stardust on 2017/9/28.
|
* Created by Stardust on 2017/9/28.
|
||||||
*/
|
*/
|
||||||
@EViewGroup(R.layout.editor_view)
|
@EViewGroup(R.layout.editor_view)
|
||||||
public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintClickListener {
|
public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintClickListener, FunctionsKeyboardView.ClickCallback {
|
||||||
|
|
||||||
public static final String EXTRA_PATH = "Still Love Eating 17.4.5";
|
public static final String EXTRA_PATH = "Still Love Eating 17.4.5";
|
||||||
public static final String EXTRA_NAME = "Still love you 17.6.29 But....(ಥ_ಥ)";
|
public static final String EXTRA_NAME = "Still love you 17.6.29 But....(ಥ_ಥ)";
|
||||||
@@ -77,8 +84,11 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
@ViewById(R.id.symbol_bar)
|
@ViewById(R.id.symbol_bar)
|
||||||
CodeCompletionBar mSymbolBar;
|
CodeCompletionBar mSymbolBar;
|
||||||
|
|
||||||
@ViewById(R.id.functions)
|
@ViewById(R.id.properties)
|
||||||
ImageView mFunctions;
|
ImageView mShowFunctionsButton;
|
||||||
|
|
||||||
|
@ViewById(R.id.functions_keyboard)
|
||||||
|
FunctionsKeyboardView mFunctionsKeyboard;
|
||||||
|
|
||||||
@ViewById(R.id.docs)
|
@ViewById(R.id.docs)
|
||||||
EWebView mEWebView;
|
EWebView mEWebView;
|
||||||
@@ -94,6 +104,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
|
|
||||||
private ScriptExecution mScriptExecution;
|
private ScriptExecution mScriptExecution;
|
||||||
private boolean mTextChanged = false;
|
private boolean mTextChanged = false;
|
||||||
|
private FunctionsKeyboardHelper mFunctionsKeyboardHelper;
|
||||||
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@@ -129,12 +140,18 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
protected void onAttachedToWindow() {
|
protected void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
getContext().registerReceiver(mOnRunFinishedReceiver, new IntentFilter(ACTION_ON_EXECUTION_FINISHED));
|
getContext().registerReceiver(mOnRunFinishedReceiver, new IntentFilter(ACTION_ON_EXECUTION_FINISHED));
|
||||||
|
if (getContext() instanceof BackPressedHandler.HostActivity) {
|
||||||
|
((BackPressedHandler.HostActivity) getContext()).getBackPressedObserver().registerHandler(mFunctionsKeyboardHelper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
getContext().unregisterReceiver(mOnRunFinishedReceiver);
|
getContext().unregisterReceiver(mOnRunFinishedReceiver);
|
||||||
|
if (getContext() instanceof BackPressedHandler.HostActivity) {
|
||||||
|
((BackPressedHandler.HostActivity) getContext()).getBackPressedObserver().unregisterHandler(mFunctionsKeyboardHelper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
@@ -182,12 +199,23 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
void init() {
|
void init() {
|
||||||
setUpEditor();
|
setUpEditor();
|
||||||
setUpInputMethodEnhancedBar();
|
setUpInputMethodEnhancedBar();
|
||||||
|
setUpFunctionsKeyboard();
|
||||||
setMenuItemStatus(R.id.save, false);
|
setMenuItemStatus(R.id.save, false);
|
||||||
mEWebView.getWebView().getSettings().setDisplayZoomControls(true);
|
mEWebView.getWebView().getSettings().setDisplayZoomControls(true);
|
||||||
mEWebView.getWebView().loadUrl(Pref.getDocumentationUrl() + "index.html");
|
mEWebView.getWebView().loadUrl(Pref.getDocumentationUrl() + "index.html");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpFunctionsKeyboard() {
|
||||||
|
mFunctionsKeyboardHelper = FunctionsKeyboardHelper.with((Activity) getContext())
|
||||||
|
.setContent(mEditor)
|
||||||
|
.setFunctionsTrigger(mShowFunctionsButton)
|
||||||
|
.setFunctionsView(mFunctionsKeyboard)
|
||||||
|
.setEditView(mEditor.getWebView())
|
||||||
|
.build();
|
||||||
|
mFunctionsKeyboard.setClickCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void setUpInputMethodEnhancedBar() {
|
private void setUpInputMethodEnhancedBar() {
|
||||||
mSymbolBar.setCodeCompletions(Symbols.getSymbols());
|
mSymbolBar.setCodeCompletions(Symbols.getSymbols());
|
||||||
mCodeCompletionBar.setOnHintClickListener(this);
|
mCodeCompletionBar.setOnHintClickListener(this);
|
||||||
@@ -226,13 +254,9 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
int textColor = InputMethodEnhancedBarColors.getTextColor(theme);
|
int textColor = InputMethodEnhancedBarColors.getTextColor(theme);
|
||||||
mCodeCompletionBar.setTextColor(textColor);
|
mCodeCompletionBar.setTextColor(textColor);
|
||||||
mSymbolBar.setTextColor(textColor);
|
mSymbolBar.setTextColor(textColor);
|
||||||
mFunctions.setColorFilter(textColor);
|
mShowFunctionsButton.setColorFilter(textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Click(R.id.functions)
|
|
||||||
void showFunctionList() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Click(R.id.run)
|
@Click(R.id.run)
|
||||||
public void runAndSaveFileIfNeeded() {
|
public void runAndSaveFileIfNeeded() {
|
||||||
@@ -369,7 +393,6 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
public void onHintClick(CodeCompletions completions, int pos) {
|
public void onHintClick(CodeCompletions completions, int pos) {
|
||||||
if (completions.shouldBeInserted()) {
|
if (completions.shouldBeInserted()) {
|
||||||
mEditor.insert(completions.getHints().get(pos));
|
mEditor.insert(completions.getHints().get(pos));
|
||||||
showFunctionList();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mEditor.replace(completions.getHints().get(pos), completions.getFrom().line, completions.getFrom().ch,
|
mEditor.replace(completions.getHints().get(pos), completions.getFrom().line, completions.getFrom().ch,
|
||||||
@@ -381,9 +404,14 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
String url = completions.getUrltAt(pos);
|
String url = completions.getUrltAt(pos);
|
||||||
if (url == null)
|
if (url == null)
|
||||||
return;
|
return;
|
||||||
|
showManual(url, completions.getHints().get(pos));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showManual(String url, String title) {
|
||||||
String absUrl = Pref.getDocumentationUrl() + url;
|
String absUrl = Pref.getDocumentationUrl() + url;
|
||||||
new ManualDialog(getContext())
|
new ManualDialog(getContext())
|
||||||
.title(completions.getHints().get(pos))
|
.title(title)
|
||||||
.url(absUrl)
|
.url(absUrl)
|
||||||
.pinToLeft(v -> {
|
.pinToLeft(v -> {
|
||||||
mEWebView.getWebView().loadUrl(absUrl);
|
mEWebView.getWebView().loadUrl(absUrl);
|
||||||
@@ -391,4 +419,28 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
|||||||
})
|
})
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModuleLongClick(Module module) {
|
||||||
|
showManual(module.getUrl(), module.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPropertyClick(Module m, Property property) {
|
||||||
|
if (property.isGlobal()) {
|
||||||
|
mEditor.insert(property.getKey());
|
||||||
|
} else {
|
||||||
|
mEditor.insert(m.getName() + "." + property.getKey());
|
||||||
|
}
|
||||||
|
mFunctionsKeyboardHelper.hideFunctionsLayout(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPropertyLongClick(Module m, Property property) {
|
||||||
|
if (TextUtils.isEmpty(property.getUrl())) {
|
||||||
|
showManual(m.getUrl(), property.getKey());
|
||||||
|
} else {
|
||||||
|
showManual(property.getUrl(), property.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
package com.stardust.scriptdroid.ui.edit.keyboard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import com.stardust.util.BackPressedHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://github.com/dss886/Android-FunctionsInputDetector
|
||||||
|
*/
|
||||||
|
public class FunctionsKeyboardHelper implements BackPressedHandler {
|
||||||
|
|
||||||
|
private static final String SHARE_PREFERENCE_NAME = "FunctionsKeyboardHelper";
|
||||||
|
private static final String SHARE_PREFERENCE_SOFT_INPUT_HEIGHT = "soft_input_height";
|
||||||
|
private Activity mActivity;
|
||||||
|
private InputMethodManager mInputManager;
|
||||||
|
private SharedPreferences mPreferences;
|
||||||
|
private View mFunctionsLayout;
|
||||||
|
private View mEditView;
|
||||||
|
private View mContentView;
|
||||||
|
|
||||||
|
private FunctionsKeyboardHelper(Activity activity) {
|
||||||
|
mActivity = activity;
|
||||||
|
mInputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
mPreferences = activity.getSharedPreferences(SHARE_PREFERENCE_NAME, Context.MODE_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FunctionsKeyboardHelper with(Activity activity) {
|
||||||
|
return new FunctionsKeyboardHelper(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionsKeyboardHelper setContent(View contentView) {
|
||||||
|
mContentView = contentView;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSoftKeyboardShown() {
|
||||||
|
if (mFunctionsLayout.isShown()) {
|
||||||
|
lockContentHeight();
|
||||||
|
hideFunctionsLayout(false);
|
||||||
|
mEditView.postDelayed(FunctionsKeyboardHelper.this::unlockContentHeightDelayed, 200L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
public FunctionsKeyboardHelper setEditView(View editView) {
|
||||||
|
mEditView = editView;
|
||||||
|
mEditView.requestFocus();
|
||||||
|
editView.setOnTouchListener((v, event) -> {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN)
|
||||||
|
onSoftKeyboardShown();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public FunctionsKeyboardHelper setFunctionsTrigger(View triggerButton) {
|
||||||
|
triggerButton.setOnClickListener(v -> {
|
||||||
|
if (mFunctionsLayout.isShown()) {
|
||||||
|
lockContentHeight();
|
||||||
|
hideFunctionsLayout(true);
|
||||||
|
unlockContentHeightDelayed();
|
||||||
|
} else {
|
||||||
|
if (isSoftInputShown()) {
|
||||||
|
lockContentHeight();
|
||||||
|
showFunctionsLayout();
|
||||||
|
unlockContentHeightDelayed();
|
||||||
|
} else {
|
||||||
|
showFunctionsLayout();//两者都没显示,直接显示表情布局
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionsKeyboardHelper setFunctionsView(View FunctionsView) {
|
||||||
|
mFunctionsLayout = FunctionsView;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionsKeyboardHelper build() {
|
||||||
|
mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN |
|
||||||
|
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||||
|
hideSoftInput();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showFunctionsLayout() {
|
||||||
|
int softInputHeight = getSupportSoftInputHeight();
|
||||||
|
if (softInputHeight == 0) {
|
||||||
|
softInputHeight = mPreferences.getInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, 400);
|
||||||
|
}
|
||||||
|
hideSoftInput();
|
||||||
|
mFunctionsLayout.getLayoutParams().height = softInputHeight;
|
||||||
|
mFunctionsLayout.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void hideFunctionsLayout(boolean showSoftInput) {
|
||||||
|
if (mFunctionsLayout.isShown()) {
|
||||||
|
mFunctionsLayout.setVisibility(View.GONE);
|
||||||
|
if (showSoftInput) {
|
||||||
|
showSoftInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void lockContentHeight() {
|
||||||
|
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mContentView.getLayoutParams();
|
||||||
|
params.height = mContentView.getHeight();
|
||||||
|
params.weight = 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void unlockContentHeightDelayed() {
|
||||||
|
mEditView.postDelayed(() -> ((LinearLayout.LayoutParams) mContentView.getLayoutParams()).weight = 1.0F, 200L);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showSoftInput() {
|
||||||
|
mEditView.requestFocus();
|
||||||
|
mEditView.post(() -> mInputManager.showSoftInput(mEditView, InputMethodManager.SHOW_FORCED));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void hideSoftInput() {
|
||||||
|
mInputManager.hideSoftInputFromWindow(mEditView.getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isSoftInputShown() {
|
||||||
|
return getSupportSoftInputHeight() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSupportSoftInputHeight() {
|
||||||
|
Rect r = new Rect();
|
||||||
|
mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
||||||
|
int screenHeight = mActivity.getWindow().getDecorView().getRootView().getHeight();
|
||||||
|
int softInputHeight = screenHeight - r.bottom;
|
||||||
|
if (Build.VERSION.SDK_INT >= 20) {
|
||||||
|
// When SDK Level >= 20 (Android L), the softInputHeight will contain the height of softButtonsBar (if has)
|
||||||
|
softInputHeight = softInputHeight - getSoftKeyButtonsHeight();
|
||||||
|
}
|
||||||
|
if (softInputHeight > 0) {
|
||||||
|
mPreferences.edit().putInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, softInputHeight).apply();
|
||||||
|
}
|
||||||
|
return softInputHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||||
|
private int getSoftKeyButtonsHeight() {
|
||||||
|
DisplayMetrics metrics = new DisplayMetrics();
|
||||||
|
mActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||||
|
int usableHeight = metrics.heightPixels;
|
||||||
|
mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
|
||||||
|
int realHeight = metrics.heightPixels;
|
||||||
|
if (realHeight > usableHeight) {
|
||||||
|
return realHeight - usableHeight;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getKeyBoardHeight() {
|
||||||
|
return mPreferences.getInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onBackPressed(Activity activity) {
|
||||||
|
if (mFunctionsLayout.isShown()) {
|
||||||
|
hideFunctionsLayout(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,306 @@
|
|||||||
|
package com.stardust.scriptdroid.ui.edit.keyboard;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v7.widget.DividerItemDecoration;
|
||||||
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.stardust.scriptdroid.R;
|
||||||
|
import com.stardust.scriptdroid.model.indices.Module;
|
||||||
|
import com.stardust.scriptdroid.model.indices.Modules;
|
||||||
|
import com.stardust.scriptdroid.model.indices.Property;
|
||||||
|
import com.stardust.scriptdroid.ui.widget.GridDividerDecoration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FunctionsKeyboardView extends FrameLayout {
|
||||||
|
|
||||||
|
public interface ClickCallback {
|
||||||
|
void onModuleLongClick(Module module);
|
||||||
|
|
||||||
|
void onPropertyClick(Module m, Property property);
|
||||||
|
|
||||||
|
void onPropertyLongClick(Module m, Property property);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int SPAN_COUNT = 4;
|
||||||
|
@BindView(R.id.module_list)
|
||||||
|
RecyclerView mModulesView;
|
||||||
|
|
||||||
|
@BindView(R.id.properties)
|
||||||
|
RecyclerView mPropertiesView;
|
||||||
|
|
||||||
|
private List<Module> mModules;
|
||||||
|
private Map<Module, List<Integer>> mSpanSizes = new HashMap<>();
|
||||||
|
private Module mSelectedModule;
|
||||||
|
private View mSelectedModuleView;
|
||||||
|
private Paint mPaint;
|
||||||
|
private ClickCallback mClickCallback;
|
||||||
|
|
||||||
|
public FunctionsKeyboardView(@NonNull Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionsKeyboardView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionsKeyboardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public FunctionsKeyboardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClickCallback(ClickCallback clickCallback) {
|
||||||
|
mClickCallback = clickCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
inflate(getContext(), R.layout.functions_keyboard_view, this);
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
initModulesView();
|
||||||
|
initPropertiesView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPropertiesView() {
|
||||||
|
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), SPAN_COUNT);
|
||||||
|
mPropertiesView.setLayoutManager(gridLayoutManager);
|
||||||
|
mPropertiesView.setAdapter(new PropertiesAdapter());
|
||||||
|
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSpanSize(int position) {
|
||||||
|
return mSpanSizes.get(mSelectedModule).get(position);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Drawable divider = ContextCompat.getDrawable(getContext(), R.drawable.divider_functions_view);
|
||||||
|
GridDividerDecoration dividerItemDecoration = new GridDividerDecoration(getContext(), divider);
|
||||||
|
mPropertiesView.addItemDecoration(dividerItemDecoration);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSpanSizes(Module module) {
|
||||||
|
if (mSpanSizes.containsKey(module))
|
||||||
|
return;
|
||||||
|
if (getMeasuredWidth() == 0)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
List<Integer> spanSizes = new ArrayList<>();
|
||||||
|
//初始化spanSizes列表
|
||||||
|
for (Property property : mSelectedModule.getProperties()) {
|
||||||
|
int width = Math.max(getTextWidth(property.getKey()), getTextWidth(property.getSummary()));
|
||||||
|
int spanSize = (int) Math.ceil(width / ((double) getMeasuredWidth() / 4));
|
||||||
|
spanSizes.add(Math.min(spanSize, 2));
|
||||||
|
}
|
||||||
|
//遍历这个列表,调整spanSize。例如以下这种情况时:
|
||||||
|
// [] [] []
|
||||||
|
// [ ] [] []
|
||||||
|
// [] [] [] []
|
||||||
|
//把第一行的第三个元素的spanSize设置为2
|
||||||
|
int column = 0;
|
||||||
|
for (int i = 0; i < spanSizes.size(); i++) {
|
||||||
|
int spanSize = spanSizes.get(i);
|
||||||
|
if (spanSize + column > SPAN_COUNT) {
|
||||||
|
spanSizes.set(i - 1, 2);
|
||||||
|
column = spanSize;
|
||||||
|
} else {
|
||||||
|
column += spanSize;
|
||||||
|
}
|
||||||
|
if (column == 4) {
|
||||||
|
column = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSpanSizes.put(module, spanSizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDisplayText(Property property) {
|
||||||
|
if (TextUtils.isEmpty(property.getSummary()))
|
||||||
|
return property.getKey();
|
||||||
|
return property.getKey() + "\n" + property.getSummary();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTextWidth(String text) {
|
||||||
|
if (mPaint == null) {
|
||||||
|
mPaint = new Paint();
|
||||||
|
mPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.textSize_item_property));
|
||||||
|
}
|
||||||
|
Rect r = new Rect();
|
||||||
|
mPaint.getTextBounds(text, 0, text.length(), r);
|
||||||
|
return r.width();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initModulesView() {
|
||||||
|
mModulesView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayout.HORIZONTAL, false));
|
||||||
|
mModulesView.setAdapter(new ModulesAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadModules() {
|
||||||
|
Modules.getInstance().getModules(getContext())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(modules -> {
|
||||||
|
mModules = modules;
|
||||||
|
if (modules.size() > 0) {
|
||||||
|
setSelectedModule(modules.get(0), null);
|
||||||
|
}
|
||||||
|
mModulesView.getAdapter().notifyDataSetChanged();
|
||||||
|
mPropertiesView.getAdapter().notifyDataSetChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setSelectedModule(Module module, @Nullable View moduleView) {
|
||||||
|
mSelectedModule = module;
|
||||||
|
if (mSelectedModuleView != null) {
|
||||||
|
mSelectedModuleView.setSelected(false);
|
||||||
|
}
|
||||||
|
mSelectedModuleView = moduleView;
|
||||||
|
if (mSelectedModuleView != null)
|
||||||
|
mSelectedModuleView.setSelected(true);
|
||||||
|
initSpanSizes(mSelectedModule);
|
||||||
|
mPropertiesView.getAdapter().notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
if (mModules == null)
|
||||||
|
loadModules();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ModuleViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
|
||||||
|
private TextView mTextView;
|
||||||
|
private Module mModule;
|
||||||
|
|
||||||
|
ModuleViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
mTextView = (TextView) itemView;
|
||||||
|
mTextView.setOnClickListener(v -> {
|
||||||
|
if (mModule == null)
|
||||||
|
return;
|
||||||
|
setSelectedModule(mModule, mTextView);
|
||||||
|
});
|
||||||
|
mTextView.setOnLongClickListener(v -> {
|
||||||
|
if (mClickCallback != null) {
|
||||||
|
mClickCallback.onModuleLongClick(mModule);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void bind(Module module) {
|
||||||
|
mModule = module;
|
||||||
|
mTextView.setText(module.getSummary());
|
||||||
|
mTextView.setSelected(module == mSelectedModule);
|
||||||
|
if (module == mSelectedModule) {
|
||||||
|
mSelectedModuleView = mTextView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class PropertyViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
private TextView mTextView;
|
||||||
|
private Property mProperty;
|
||||||
|
|
||||||
|
PropertyViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
mTextView = (TextView) itemView;
|
||||||
|
mTextView.setOnLongClickListener(v -> {
|
||||||
|
if (mClickCallback != null) {
|
||||||
|
mClickCallback.onPropertyLongClick(mSelectedModule, mProperty);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
mTextView.setOnClickListener(v -> {
|
||||||
|
if (mClickCallback != null) {
|
||||||
|
mClickCallback.onPropertyClick(mSelectedModule, mProperty);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(Property property) {
|
||||||
|
mProperty = property;
|
||||||
|
mTextView.setText(getDisplayText(property));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ModulesAdapter extends RecyclerView.Adapter<ModuleViewHolder> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
return new ModuleViewHolder(LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_module, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(ModuleViewHolder holder, int position) {
|
||||||
|
holder.bind(mModules.get(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mModules == null ? 0 : mModules.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PropertiesAdapter extends RecyclerView.Adapter<PropertyViewHolder> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
return new PropertyViewHolder(LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_property, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(PropertyViewHolder holder, int position) {
|
||||||
|
holder.bind(mSelectedModule.getProperties().get(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mSelectedModule == null ? 0 : mSelectedModule.getProperties().size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
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.model.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) {
|
|
||||||
FloatyWindowManger.addWindow(context, new ResizableFloatyWindow(new EditorFloaty(intent)));
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,6 @@ import com.stardust.scriptdroid.model.script.Scripts;
|
|||||||
import com.stardust.scriptdroid.storage.file.StorageFileProvider;
|
import com.stardust.scriptdroid.storage.file.StorageFileProvider;
|
||||||
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
|
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
|
||||||
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||||
import com.stardust.scriptdroid.ui.floating.EditorFloaty;
|
|
||||||
import com.stardust.scriptdroid.ui.viewmodel.ScriptList;
|
import com.stardust.scriptdroid.ui.viewmodel.ScriptList;
|
||||||
import com.stardust.scriptdroid.ui.widget.BindableViewHolder;
|
import com.stardust.scriptdroid.ui.widget.BindableViewHolder;
|
||||||
|
|
||||||
@@ -229,10 +228,6 @@ public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLa
|
|||||||
.show();
|
.show();
|
||||||
notifyOperated();
|
notifyOperated();
|
||||||
break;
|
break;
|
||||||
case R.id.floating_edit:
|
|
||||||
EditorFloaty.floatingEdit(getContext(), mSelectedScriptFile);
|
|
||||||
notifyOperated();
|
|
||||||
break;
|
|
||||||
case R.id.create_shortcut:
|
case R.id.create_shortcut:
|
||||||
new ScriptOperations(getContext(), this)
|
new ScriptOperations(getContext(), this)
|
||||||
.createShortcut(mSelectedScriptFile);
|
.createShortcut(mSelectedScriptFile);
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package com.stardust.scriptdroid.ui.widget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ItemDecoration implementation that applies and inset margin
|
||||||
|
* around each child of the RecyclerView. It also draws item dividers
|
||||||
|
* that are expected from a vertical list implementation, such as
|
||||||
|
* ListView.
|
||||||
|
*/
|
||||||
|
public class GridDividerDecoration extends RecyclerView.ItemDecoration {
|
||||||
|
|
||||||
|
|
||||||
|
private Drawable mDivider;
|
||||||
|
private int mInsets;
|
||||||
|
|
||||||
|
public GridDividerDecoration(Context context, Drawable divider) {
|
||||||
|
mDivider = divider;
|
||||||
|
mInsets = divider.getIntrinsicWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
||||||
|
drawVertical(c, parent);
|
||||||
|
drawHorizontal(c, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw dividers at each expected grid interval
|
||||||
|
*/
|
||||||
|
public void drawVertical(Canvas c, RecyclerView parent) {
|
||||||
|
if (parent.getChildCount() == 0) return;
|
||||||
|
|
||||||
|
final int childCount = parent.getChildCount();
|
||||||
|
|
||||||
|
for (int i = 0; i < childCount; i++) {
|
||||||
|
final View child = parent.getChildAt(i);
|
||||||
|
final RecyclerView.LayoutParams params =
|
||||||
|
(RecyclerView.LayoutParams) child.getLayoutParams();
|
||||||
|
|
||||||
|
final int left = child.getLeft() - params.leftMargin - mInsets;
|
||||||
|
final int right = child.getRight() + params.rightMargin + mInsets;
|
||||||
|
final int top = child.getBottom() + params.bottomMargin + mInsets;
|
||||||
|
final int bottom = top + mDivider.getIntrinsicHeight();
|
||||||
|
mDivider.setBounds(left, top, right, bottom);
|
||||||
|
mDivider.draw(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw dividers to the right of each child view
|
||||||
|
*/
|
||||||
|
public void drawHorizontal(Canvas c, RecyclerView parent) {
|
||||||
|
final int childCount = parent.getChildCount();
|
||||||
|
|
||||||
|
for (int i = 0; i < childCount; i++) {
|
||||||
|
final View child = parent.getChildAt(i);
|
||||||
|
final RecyclerView.LayoutParams params =
|
||||||
|
(RecyclerView.LayoutParams) child.getLayoutParams();
|
||||||
|
|
||||||
|
final int left = child.getRight() + params.rightMargin + mInsets;
|
||||||
|
final int right = left + mDivider.getIntrinsicWidth();
|
||||||
|
final int top = child.getTop() - params.topMargin - mInsets;
|
||||||
|
final int bottom = child.getBottom() + params.bottomMargin + mInsets;
|
||||||
|
mDivider.setBounds(left, top, right, bottom);
|
||||||
|
mDivider.draw(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||||
|
//We can supply forced insets for each item view here in the Rect
|
||||||
|
outRect.set(mInsets, mInsets, mInsets, mInsets);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
app/src/main/res/drawable/bg_item_module.xml
Normal file
15
app/src/main/res/drawable/bg_item_module.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_selected="true">
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#e5e5e5"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#ffffff"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
15
app/src/main/res/drawable/bg_item_property.xml
Normal file
15
app/src/main/res/drawable/bg_item_property.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#e5e5e5"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<solid android:color="@android:color/transparent"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
11
app/src/main/res/drawable/divider_functions_view.xml
Normal file
11
app/src/main/res/drawable/divider_functions_view.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<size
|
||||||
|
android:width="1dp"
|
||||||
|
android:height="1dp"/>
|
||||||
|
|
||||||
|
<solid android:color="@color/divider_functions_keyboard"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
android:layout_alignParentBottom="true"/>
|
android:layout_alignParentBottom="true"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/functions"
|
android:id="@+id/properties"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
@@ -156,9 +156,16 @@
|
|||||||
android:layout_above="@+id/symbol_bar"
|
android:layout_above="@+id/symbol_bar"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_toRightOf="@+id/functions"/>
|
android:layout_toRightOf="@+id/properties"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<com.stardust.scriptdroid.ui.edit.keyboard.FunctionsKeyboardView
|
||||||
|
android:id="@+id/functions_keyboard"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.stardust.scriptdroid.ui.widget.EWebView
|
<com.stardust.scriptdroid.ui.widget.EWebView
|
||||||
@@ -166,8 +173,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="start"/>
|
android:layout_gravity="start"/>
|
||||||
|
|
||||||
</android.support.v4.widget.DrawerLayout>
|
</android.support.v4.widget.DrawerLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
30
app/src/main/res/layout/functions_keyboard_view.xml
Normal file
30
app/src/main/res/layout/functions_keyboard_view.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/divider_functions_keyboard"/>
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/properties"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="#fafafa"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/divider_functions_keyboard"/>
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/module_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"/>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
12
app/src/main/res/layout/item_module.xml
Normal file
12
app/src/main/res/layout/item_module.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:background="@drawable/bg_item_module"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingLeft="12dp"
|
||||||
|
android:paddingRight="12dp"
|
||||||
|
android:textColor="#616161"
|
||||||
|
android:textSize="16sp">
|
||||||
|
|
||||||
|
</TextView>
|
||||||
10
app/src/main/res/layout/item_property.xml
Normal file
10
app/src/main/res/layout/item_property.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:background="@drawable/bg_item_property"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="#414141"
|
||||||
|
android:textSize="@dimen/textSize_item_property">
|
||||||
|
|
||||||
|
</TextView>
|
||||||
@@ -9,4 +9,5 @@
|
|||||||
<color name="color_j">#99CC99</color>
|
<color name="color_j">#99CC99</color>
|
||||||
<color name="prefTextColorSecondary">#9DA0A2</color>
|
<color name="prefTextColorSecondary">#9DA0A2</color>
|
||||||
<color name="prefTextColorPrimary">#282C2F</color>
|
<color name="prefTextColorPrimary">#282C2F</color>
|
||||||
|
<color name="divider_functions_keyboard">#f0f0f0</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -7,4 +7,6 @@
|
|||||||
<dimen name="script_and_folder_list_divider_left_margin">0dp</dimen>
|
<dimen name="script_and_folder_list_divider_left_margin">0dp</dimen>
|
||||||
<dimen name="script_and_folder_list_divider_right_margin">0dp</dimen>
|
<dimen name="script_and_folder_list_divider_right_margin">0dp</dimen>
|
||||||
<dimen name="fab_margin">16dp</dimen>
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
|
<dimen name="padding_item_property">8dp</dimen>
|
||||||
|
<dimen name="textSize_item_property">14sp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user