mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
- Removed unused libraries
- Added about page with licenses to open source libraries
This commit is contained in:
+6
-9
@@ -29,7 +29,8 @@ android {
|
||||
disable "VectorPath",
|
||||
"NestedWeights",
|
||||
"UnusedResources",
|
||||
"ContentDescription"
|
||||
"ContentDescription",
|
||||
"SmallSp"
|
||||
}
|
||||
|
||||
buildFeatures.viewBinding true
|
||||
@@ -59,7 +60,7 @@ android {
|
||||
stringfog.enable false
|
||||
}
|
||||
release {
|
||||
minifyEnabled false
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
stringfog.enable true
|
||||
@@ -75,9 +76,8 @@ android {
|
||||
}
|
||||
|
||||
stringfog {
|
||||
def isRelease = getGradle().getStartParameter().getTaskRequests().toString().contains("release")
|
||||
key 'WVV0aGMwaEFZVzVFVW05SlJFbGtaUT09'
|
||||
enable false
|
||||
enable true
|
||||
implementation 'com.github.megatronking.stringfog.xor.StringFogImpl'
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ dependencies {
|
||||
|
||||
// AndroidX
|
||||
implementation 'androidx.annotation:annotation:1.2.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
|
||||
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
|
||||
implementation 'androidx.drawerlayout:drawerlayout:1.1.1'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
@@ -121,9 +121,6 @@ dependencies {
|
||||
|
||||
// Local projects
|
||||
implementation project(':treeview')
|
||||
implementation project(':spinkit')
|
||||
implementation project(':slidr')
|
||||
implementation project(':javadocparser')
|
||||
implementation project(':lsp')
|
||||
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
Vendored
+16
-2
@@ -1,4 +1,5 @@
|
||||
-keepattributes SourceFile, LineNumberTable
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-renamesourcefileattribute FuckYou
|
||||
-obfuscationdictionary dictionary.txt
|
||||
-packageobfuscationdictionary dictionary.txt
|
||||
@@ -8,10 +9,16 @@
|
||||
-dontwarn
|
||||
-dontnote
|
||||
|
||||
-dontwarn sun.misc.**
|
||||
-dontwarn android.arch.**
|
||||
-dontwarn android.lifecycle.**
|
||||
-keep class android.arch.** { *; }
|
||||
-keep class android.lifecycle.** { *; }
|
||||
-keep class com.google.gson.examples.android.model.** { <fields>; }
|
||||
-keep class * extends com.google.gson.TypeAdapter
|
||||
-keep class * implements com.google.gson.TypeAdapterFactory
|
||||
-keep class * implements com.google.gson.JsonSerializer
|
||||
-keep class * implements com.google.gson.JsonDeserializer
|
||||
|
||||
-dontwarn androidx.arch.**
|
||||
-dontwarn androidx.lifecycle.**
|
||||
@@ -19,10 +26,17 @@
|
||||
-keep class androidx.lifecycle.** { *; }
|
||||
|
||||
-keepclasseswithmembernames,includedescriptorclasses class * { native <methods>; }
|
||||
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
|
||||
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep class * extends com.bumptech.glide.module.AppGlideModule { <init>(...); }
|
||||
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder { *** rewind(); }
|
||||
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@com.google.gson.annotations.SerializedName <fields>;
|
||||
}
|
||||
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder { *** rewind(); }
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<application
|
||||
tools:ignore="UnusedAttribute"
|
||||
android:name=".app.StudioApp"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
@@ -44,6 +45,10 @@
|
||||
android:name=".PreferencesActivity"
|
||||
android:configChanges="orientation|screenSize">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".AboutActivity"
|
||||
android:configChanges="orientation|screenSize|uiMode">
|
||||
</activity>
|
||||
<service
|
||||
android:name="com.itsaky.androidide.services.IDEService"
|
||||
android:exported="false">
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
[
|
||||
{
|
||||
"name": "AndroidX Libraries",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/androidx/androidx"
|
||||
},
|
||||
{
|
||||
"name": "Material Components for Android",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/material-components/material-components-android"
|
||||
},
|
||||
{
|
||||
"name": "Gson",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/google/gson"
|
||||
},
|
||||
{
|
||||
"name": "Guava",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/google/guava"
|
||||
},
|
||||
{
|
||||
"name": "ANTLR4",
|
||||
"license": "The 3-Clause BSD License",
|
||||
"url": "https://github.com/antlr/antlr4"
|
||||
},
|
||||
{
|
||||
"name": "Glide",
|
||||
"license": "BSD, part MIT and Apache 2.0",
|
||||
"url": "https://github.com/bumptech/glide"
|
||||
},
|
||||
{
|
||||
"name": "Android UtilCode",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/Blankj/AndroidUtilCode"
|
||||
},
|
||||
{
|
||||
"name": "UnicornFilePicker",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/abhishekti7/UnicornFilePicker"
|
||||
},
|
||||
{
|
||||
"name": "QuickAction",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/piruin/quickaction"
|
||||
},
|
||||
{
|
||||
"name": "XmlToJson",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/smart-fun/XmlToJson"
|
||||
},
|
||||
{
|
||||
"name": "AndroidTreeView",
|
||||
"license": "Apache License 2.0",
|
||||
"url": "https://github.com/bmelnychuk/AndroidTreeView"
|
||||
},
|
||||
{
|
||||
"name": "CodeEditor",
|
||||
"license": "GPL-3.0 License",
|
||||
"url": "https://github.com/Rosemoe/CodeEditor"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.itsaky.androidide;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import com.itsaky.androidide.app.StudioActivity;
|
||||
import com.itsaky.androidide.databinding.ActivityAboutBinding;
|
||||
import com.itsaky.androidide.fragments.sheets.OptionsListFragment;
|
||||
import com.itsaky.androidide.models.License;
|
||||
import com.itsaky.androidide.tasks.TaskExecutor;
|
||||
import com.itsaky.androidide.tasks.callables.LicenseReader;
|
||||
import java.util.List;
|
||||
|
||||
public class AboutActivity extends StudioActivity {
|
||||
|
||||
private ActivityAboutBinding binding;
|
||||
|
||||
@Override
|
||||
protected View bindLayout() {
|
||||
binding = ActivityAboutBinding.inflate(getLayoutInflater());
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
binding.items.footerText.setText(getFooter());
|
||||
|
||||
new TaskExecutor().executeAsync(new LicenseReader(this), __ -> {
|
||||
setupLicenses(__);
|
||||
});
|
||||
}
|
||||
|
||||
private void setupLicenses(List<License> licenses) {
|
||||
if(licenses == null || licenses.size() <= 0) {
|
||||
binding.items.licenses.setText(getString(R.string.msg_about_no_licenses));
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(License license : licenses) {
|
||||
sb.append("\u2022 ");
|
||||
sb.append(license.name);
|
||||
sb.append("\n");
|
||||
sb.append(getString(R.string.msg_about_licensed_under, license.license));
|
||||
sb.append("\n");
|
||||
sb.append(getString(R.string.msg_about_license_source, license.url));
|
||||
sb.append("\n\n");
|
||||
}
|
||||
binding.items.licenses.setText(sb);
|
||||
}
|
||||
}
|
||||
|
||||
private String getFooter() {
|
||||
final String arch = android.os.Build.SUPPORTED_ABIS[0];
|
||||
try {
|
||||
final String version = getPackageManager().getPackageInfo("com.itsaky.androidide", 0).versionName;
|
||||
return getString(R.string.about_footer, version, arch);
|
||||
} catch (Throwable th) {
|
||||
return getString(R.string.about_footer_alternate, arch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1121,6 +1121,7 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
if(i >= 0 && !mBinding.tabs.getTabAt(i).isSelected())
|
||||
mBinding.tabs.getTabAt(i).select();
|
||||
mBinding.editorDrawerLayout.closeDrawer(GravityCompat.END);
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1521,5 +1522,7 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
DidCloseTextDocumentParams p = new DidCloseTextDocumentParams();
|
||||
p.textDocument = id;
|
||||
didClose(p);
|
||||
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ public class PreferencesActivity extends StudioActivity {
|
||||
setSupportActionBar(binding.toolbar);
|
||||
getSupportActionBar().setTitle(R.string.ide_preferences);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
|
||||
loadFragment(getPrefsFragment());
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SymbolInputAdapter extends RecyclerView.Adapter<SymbolInputAdapter.
|
||||
if(symbols == null || symbols[position] == null) return;
|
||||
final Symbol symbol = symbols[position];
|
||||
holder.binding.symbol.setText(symbol.label);
|
||||
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(holder.binding.symbol, 16, 27, 1, TypedValue.COMPLEX_UNIT_SP);
|
||||
// TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(holder.binding.symbol, 16, 27, 1, TypedValue.COMPLEX_UNIT_SP);
|
||||
holder.binding.symbol.setOnClickListener(__ -> channel.insertSymbol(symbol.commit, symbol.offset));
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.github.ybq.android.spinkit.style.Circle;
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.app.StudioActivity;
|
||||
import com.itsaky.androidide.databinding.LayoutFiletreeItemBinding;
|
||||
@@ -60,7 +59,6 @@ public class FileTreeViewHolder extends TreeNode.BaseNodeViewHolder<File> {
|
||||
}
|
||||
|
||||
public void setLoading() {
|
||||
chevron.setImageDrawable(new Circle());
|
||||
chevron.getDrawable().setColorFilter(ContextCompat.getColor(context, R.color.secondaryLightColor), PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,8 @@ public class StudioApp extends MultiDexApplication
|
||||
|
||||
public static final String TELEGRAM_GROUP_URL = "https://t.me/androidide_discussions";
|
||||
public static final String SUGGESTIONS_URL = "https://github.com/itsaky/AndroidIDE";
|
||||
|
||||
public static final String WEBSITE = "https://androidide.com";
|
||||
|
||||
private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
|
||||
|
||||
@Override
|
||||
@@ -338,6 +339,7 @@ public class StudioApp extends MultiDexApplication
|
||||
return new File(getFilesDir(), "framework");
|
||||
}
|
||||
|
||||
@SuppressLint("SdCardPath")
|
||||
public File getIDEDataDir() {
|
||||
return Environment.mkdirIfNotExits(new File("/data/data/com.itsaky.androidide/files"));
|
||||
}
|
||||
@@ -489,4 +491,12 @@ public class StudioApp extends MultiDexApplication
|
||||
open.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(open);
|
||||
}
|
||||
|
||||
public void openWebsite() {
|
||||
Intent open = new Intent();
|
||||
open.setAction(Intent.ACTION_VIEW);
|
||||
open.setData(Uri.parse(StudioApp.WEBSITE));
|
||||
open.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(open);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,13 +310,14 @@ public class EditorFragment extends BaseFragment implements EditorEventListener
|
||||
@Override
|
||||
public void afterDelete(CodeEditor editor, CharSequence content, int startLine, int startColumn, int endLine, int endColumn, CharSequence deletedContent) {
|
||||
isModified = true;
|
||||
requestSignature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterInsert(CodeEditor editor, CharSequence content, int startLine, int startColumn, int endLine, int endColumn, CharSequence insertedContent) {
|
||||
isModified = true;
|
||||
|
||||
if(getFile() != null && getFile().getName().endsWith(".java")) {
|
||||
if(getFile() != null && getFile().getName().endsWith(EXT_XML)) {
|
||||
boolean isOpen = false;
|
||||
try {
|
||||
isOpen = editor.getText().charAt(editor.getCursor().getLeft() - 2) == '<';
|
||||
@@ -326,10 +327,7 @@ public class EditorFragment extends BaseFragment implements EditorEventListener
|
||||
}
|
||||
}
|
||||
|
||||
char c = insertedContent.charAt(0);
|
||||
if(c == '(' || c == ',') {
|
||||
requestSignature();
|
||||
}
|
||||
requestSignature();
|
||||
}
|
||||
|
||||
private void requestSignature() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.itsaky.androidide.fragments.preferences;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.text.Spannable;
|
||||
@@ -13,13 +14,13 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import com.blankj.utilcode.util.ResourceUtils;
|
||||
import com.blankj.utilcode.util.ThrowableUtils;
|
||||
import com.blankj.utilcode.util.SizeUtils;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.AboutActivity;
|
||||
import com.itsaky.androidide.app.StudioApp;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import com.blankj.utilcode.util.SizeUtils;
|
||||
|
||||
public class IDEPreferences extends BasePreferenceFragment {
|
||||
|
||||
@@ -35,6 +36,7 @@ public class IDEPreferences extends BasePreferenceFragment {
|
||||
public static final String KEY_TELEGRAM = "idepref_telegram";
|
||||
public static final String KEY_ISSUES = "idepref_issues";
|
||||
public static final String KEY_CHANGELOG = "idepref_changelog";
|
||||
public static final String KEY_ABOUT = "idepref_about";
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedState, String rootKey) {
|
||||
@@ -48,7 +50,8 @@ public class IDEPreferences extends BasePreferenceFragment {
|
||||
final Preference telegram = new Preference(getContext());
|
||||
final Preference issueTracker = new Preference(getContext());
|
||||
final Preference changelog = new Preference(getContext());
|
||||
|
||||
final Preference about = new Preference(getContext());
|
||||
|
||||
appearance.setKey(KEY_APPEARANCE);
|
||||
appearance.setIconSpaceReserved(false);
|
||||
appearance.setFragment(getAppearanceFrag().getClass().getName());
|
||||
@@ -81,17 +84,24 @@ public class IDEPreferences extends BasePreferenceFragment {
|
||||
changelog.setIconSpaceReserved(false);
|
||||
changelog.setTitle(R.string.pref_changelog);
|
||||
changelog.setSummary(R.string.pref_changelog_summary);
|
||||
|
||||
about.setKey(KEY_ABOUT);
|
||||
about.setIconSpaceReserved(false);
|
||||
about.setTitle(R.string.idepref_about_title);
|
||||
// about.setSummary(R.string.pref_changelog_summary);
|
||||
|
||||
screen.addPreference(editor);
|
||||
screen.addPreference(build);
|
||||
screen.addPreference(issueTracker);
|
||||
screen.addPreference(telegram);
|
||||
screen.addPreference(changelog);
|
||||
screen.addPreference(about);
|
||||
|
||||
final Preference.OnPreferenceClickListener listener = getListener();
|
||||
issueTracker.setOnPreferenceClickListener(listener);
|
||||
telegram.setOnPreferenceClickListener(listener);
|
||||
changelog.setOnPreferenceClickListener(listener);
|
||||
about.setOnPreferenceClickListener(listener);
|
||||
}
|
||||
|
||||
private AppearancePreferences getAppearanceFrag() {
|
||||
@@ -161,7 +171,9 @@ public class IDEPreferences extends BasePreferenceFragment {
|
||||
StudioApp.getInstance().openTelegramGroup();
|
||||
} else if(key.equals(KEY_ISSUES)) {
|
||||
StudioApp.getInstance().openIssueTracker();
|
||||
}
|
||||
} else if(key.equals(KEY_ABOUT)) {
|
||||
startActivity(new Intent(getContext(), AboutActivity.class));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
+6
-5
@@ -13,16 +13,13 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.MotionEvent;
|
||||
import android.graphics.Rect;
|
||||
import com.r0adkll.slidr.model.SlidrInterface;
|
||||
import com.r0adkll.slidr.Slidr;
|
||||
import com.r0adkll.slidr.model.SlidrConfig;
|
||||
import com.r0adkll.slidr.model.SlidrPosition;
|
||||
|
||||
public abstract class BaseBottomSheetFragment extends BottomSheetDialogFragment {
|
||||
|
||||
protected Dialog mDialog;
|
||||
private LayoutSheetBinding binding;
|
||||
protected boolean shadowEnabled = true;
|
||||
protected boolean titleEnabled = true;
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
@@ -78,7 +75,7 @@ public abstract class BaseBottomSheetFragment extends BottomSheetDialogFragment
|
||||
}
|
||||
|
||||
protected boolean shouldHideTitle() {
|
||||
return false;
|
||||
return !titleEnabled;
|
||||
}
|
||||
|
||||
protected String getTitle() {
|
||||
@@ -88,6 +85,10 @@ public abstract class BaseBottomSheetFragment extends BottomSheetDialogFragment
|
||||
public void setShowShadow(boolean enabled) {
|
||||
this.shadowEnabled = enabled;
|
||||
}
|
||||
|
||||
public void setShowTitle(boolean enabled) {
|
||||
this.titleEnabled = enabled;
|
||||
}
|
||||
|
||||
protected void onShow() {}
|
||||
protected abstract void bind(LinearLayout container);
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.widget.TextView;
|
||||
import com.blankj.utilcode.util.ThrowableUtils;
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.models.LogLine;
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
public class LogSheet extends BaseBottomSheetFragment {
|
||||
|
||||
@@ -51,6 +52,7 @@ public class LogSheet extends BaseBottomSheetFragment {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
protected TextView createLogTextView(LogLine line) {
|
||||
TextView text = new TextView(getContext());
|
||||
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
|
||||
@@ -16,6 +16,8 @@ public class OptionsListFragment extends BaseBottomSheetFragment {
|
||||
private RecyclerView mList;
|
||||
private OnOptionsClickListener listener;
|
||||
private final List<SheetOption> mOptions = new ArrayList<>();
|
||||
|
||||
protected boolean dismissOnItemClick = true;
|
||||
|
||||
@Override
|
||||
protected void bind(LinearLayout container) {
|
||||
@@ -28,7 +30,12 @@ public class OptionsListFragment extends BaseBottomSheetFragment {
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
mList.setAdapter(new OptionsSheetAdapter(mOptions, __ -> { dismiss(); if(listener != null) listener.onOptionsClick(__);}));
|
||||
mList.setAdapter(new OptionsSheetAdapter(mOptions, __ -> {
|
||||
if(dismissOnItemClick)
|
||||
dismiss();
|
||||
if(listener != null)
|
||||
listener.onOptionsClick(__);
|
||||
}));
|
||||
}
|
||||
|
||||
public OptionsListFragment setOnOptionsClickListener(OnOptionsClickListener listener) {
|
||||
@@ -52,6 +59,11 @@ public class OptionsListFragment extends BaseBottomSheetFragment {
|
||||
mOptions.remove(option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsListFragment setDismissOnItemClick(boolean dissmiss) {
|
||||
this.dismissOnItemClick = dissmiss;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTitle() {
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import com.github.ybq.android.spinkit.style.FoldingCube;
|
||||
import com.itsaky.androidide.databinding.LayoutProgressSheetBinding;
|
||||
import com.blankj.utilcode.util.SizeUtils;
|
||||
import android.widget.RelativeLayout;
|
||||
@@ -13,7 +12,7 @@ import android.widget.RelativeLayout;
|
||||
public class ProgressSheet extends BaseBottomSheetFragment {
|
||||
|
||||
private LayoutProgressSheetBinding binding;
|
||||
private Drawable drawable = new FoldingCube();
|
||||
private Drawable drawable = null;
|
||||
private String message = "";
|
||||
private String subMessage = "";
|
||||
private boolean subMessageEnabled = false;
|
||||
|
||||
@@ -44,7 +44,7 @@ public class TextSheetFragment extends BaseBottomSheetFragment {
|
||||
@Override
|
||||
protected void onShow() {
|
||||
super.onShow();
|
||||
setToEditor(SpannableString.valueOf(getOutputBuilder()));
|
||||
editor.setText(getOutputBuilder());
|
||||
}
|
||||
|
||||
private Void scrollToBottom() {
|
||||
|
||||
+2
-29
@@ -48,6 +48,7 @@ import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import com.itsaky.lsp.DidChangeWatchedFilesParams;
|
||||
import com.itsaky.lsp.SignatureHelp;
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
public class JavaLanguageServer implements ShellServer.Callback {
|
||||
|
||||
@@ -136,6 +137,7 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
return server;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
protected void sendInit() {
|
||||
InitializeParams p = new InitializeParams();
|
||||
p.rootUri = new File(project.getProjectPath()).toURI();
|
||||
@@ -267,41 +269,12 @@ public class JavaLanguageServer implements ShellServer.Callback {
|
||||
|
||||
@Override
|
||||
public void output(CharSequence charSequence) {
|
||||
writeOut(charSequence.toString());
|
||||
}
|
||||
|
||||
private BufferedOutputStream os;
|
||||
private BufferedOutputStream os1;
|
||||
|
||||
private void writeOut(String data) {
|
||||
try {
|
||||
if(os == null) {
|
||||
os = new BufferedOutputStream(new FileOutputStream(new File(FileUtil.getExternalStorageDir(), "ide_xlog/out.txt"), true));
|
||||
}
|
||||
os.write(data.getBytes());
|
||||
os.flush();
|
||||
} catch (Throwable th) {
|
||||
logger.e(ThrowableUtils.getFullStackTrace(th));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeOut2(String data) {
|
||||
try {
|
||||
if(os1 == null) {
|
||||
os1 = new BufferedOutputStream(new FileOutputStream(new File(FileUtil.getExternalStorageDir(), "ide_xlog/verbose.txt"), true));
|
||||
}
|
||||
os1.write(data.getBytes());
|
||||
os1.flush();
|
||||
} catch (Throwable th) {
|
||||
logger.e(ThrowableUtils.getFullStackTrace(th));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called on UI Thread, do not perform time consuming or networking tasks
|
||||
*/
|
||||
private void onServerOut(String line) {
|
||||
writeOut2(line + "\n");
|
||||
if(line.contains(CONTENT_LENGTH)) line = line.substring(0, line.lastIndexOf(CONTENT_LENGTH));
|
||||
if(this.client == null) return;
|
||||
try {
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.itsaky.lsp.TextEdit;
|
||||
import io.github.rosemoe.editor.text.Cursor;
|
||||
import io.github.rosemoe.editor.widget.CodeEditor;
|
||||
import java.util.List;
|
||||
import com.itsaky.androidide.language.java.manager.JavaCharacter;
|
||||
|
||||
public class CompletionItemWrapper implements SuggestItem, Comparable {
|
||||
|
||||
@@ -58,12 +59,21 @@ public class CompletionItemWrapper implements SuggestItem, Comparable {
|
||||
try {
|
||||
final Cursor cursor = editor.getCursor();
|
||||
if(cursor.isSelected()) return;
|
||||
final int length = getInsertLength();
|
||||
final int line = cursor.getLeftLine();
|
||||
int col = cursor.getLeftColumn();
|
||||
while(true) {
|
||||
col--;
|
||||
if(col == 0)
|
||||
break;
|
||||
if(!JavaCharacter.isJavaIdentifierPart(editor.getText().charAt(line, col)))
|
||||
break;
|
||||
}
|
||||
col++;
|
||||
String text = getInsertText();
|
||||
final boolean shiftLeft = text.contains("$0");
|
||||
final boolean atEnd = text.endsWith("$0");
|
||||
text = text.replace("$0", "");
|
||||
editor.getText().delete(cursor.getLeftLine(), cursor.getLeftColumn() - length, cursor.getLeftLine(), cursor.getLeftColumn());
|
||||
editor.getText().delete(line, col, line, cursor.getLeftColumn());
|
||||
cursor.onCommitText(text);
|
||||
|
||||
if(shiftLeft && !atEnd) {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.itsaky.androidide.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class License {
|
||||
@SerializedName("name")
|
||||
public String name;
|
||||
|
||||
@SerializedName("license")
|
||||
public String license;
|
||||
|
||||
@SerializedName("url")
|
||||
public String url;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public class LogLine {
|
||||
if(s == null || s.trim().length() > 1) {
|
||||
return DEBUG;
|
||||
}
|
||||
char c = s.toLowerCase().charAt(0);
|
||||
char c = s.toLowerCase(Locale.US).charAt(0);
|
||||
if(c == 'w') {
|
||||
return WARNING;
|
||||
} else if(c == 'e') {
|
||||
|
||||
@@ -15,6 +15,9 @@ import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import com.itsaky.lsp.Position;
|
||||
|
||||
public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
|
||||
@@ -30,7 +33,7 @@ public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
this.isFirst = true;
|
||||
|
||||
builtinTypes = new ArrayList<>();
|
||||
|
||||
|
||||
builtinTypes.add(JavaLexer.BOOLEAN);
|
||||
builtinTypes.add(JavaLexer.BYTE);
|
||||
builtinTypes.add(JavaLexer.CHAR);
|
||||
@@ -154,6 +157,11 @@ public class JavaLexerImpl extends BaseJavaLexer implements Lexer {
|
||||
type = TokenType.STRING_LITERAL;
|
||||
colors.addIfNeeded(line, column, EditorColorScheme.LITERAL);
|
||||
wasClassName = false;
|
||||
|
||||
Position start = new Position(line, column);
|
||||
Position end = new Position(line, column + currentToken.getText().length());
|
||||
colors.addStringRange(line, new Range(start, end));
|
||||
|
||||
addHexColorIfPresent();
|
||||
break;
|
||||
case JavaLexer.LPAREN :
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Token implements Serializable {
|
||||
|
||||
@@ -76,9 +77,9 @@ public class Token implements Serializable {
|
||||
@Override
|
||||
public String toString() {
|
||||
if (pairValue == 0) {
|
||||
return String.format("%s (%d, %d) %d", type, line, column, length);
|
||||
return String.format(Locale.US, "%s (%d, %d) %d", type, line, column, length);
|
||||
} else {
|
||||
return String.format("%s (%d, %d) (%d) %d", type, line, column, length, pairValue);
|
||||
return String.format(Locale.US, "%s (%d, %d) (%d) %d", type, line, column, length, pairValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.itsaky.androidide.tasks.callables;
|
||||
|
||||
import android.content.Context;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.itsaky.androidide.models.License;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class LicenseReader implements Callable<List<License>> {
|
||||
|
||||
private final Context ctx;
|
||||
|
||||
public LicenseReader(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<License> call() throws Exception {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(ctx.getAssets().open("licenses.json")));
|
||||
String line;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
TypeToken<List<License>> token = new TypeToken<List<License>>(){};
|
||||
return new Gson().fromJson(sb.toString(), token.getType());
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import android.graphics.Color;
|
||||
public class TooltipLayout extends LinearLayout {
|
||||
|
||||
private final float dp8;
|
||||
private final Path path;
|
||||
private final Paint paint;
|
||||
|
||||
public TooltipLayout (Context ctx) {
|
||||
this(ctx, null);
|
||||
@@ -25,14 +27,20 @@ public class TooltipLayout extends LinearLayout {
|
||||
super(ctx, attrs, style);
|
||||
|
||||
dp8 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
|
||||
path = new Path();
|
||||
|
||||
paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setColor(Color.parseColor("#424242"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
final float midX = width / 2;
|
||||
Path path = new Path();
|
||||
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(width, 0);
|
||||
path.lineTo(width, height - dp8);
|
||||
@@ -42,10 +50,6 @@ public class TooltipLayout extends LinearLayout {
|
||||
path.lineTo(0, height - dp8);
|
||||
path.close();
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setColor(Color.parseColor("#424242"));
|
||||
canvas.drawPath(path, paint);
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.List;
|
||||
|
||||
import io.github.rosemoe.editor.annotations.Experimental;
|
||||
import io.github.rosemoe.struct.BlockLinkedList;
|
||||
import io.github.rosemoe.editor.widget.CodeEditor;
|
||||
|
||||
/**
|
||||
* This class saves the text content for editor and maintains line widths
|
||||
@@ -45,6 +46,8 @@ public class Content implements CharSequence {
|
||||
private UndoManager mUndoManager;
|
||||
private Cursor mCursor;
|
||||
private LineRemoveListener mLineListener;
|
||||
|
||||
private final CodeEditor editor;
|
||||
|
||||
/**
|
||||
* Use a BlockLinkedList instead of ArrayList.
|
||||
@@ -60,8 +63,8 @@ public class Content implements CharSequence {
|
||||
/**
|
||||
* This constructor will create a Content object with no text
|
||||
*/
|
||||
public Content() {
|
||||
this(null);
|
||||
public Content(CodeEditor editor) {
|
||||
this(editor, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,10 +73,11 @@ public class Content implements CharSequence {
|
||||
*
|
||||
* @param src The source of Content
|
||||
*/
|
||||
public Content(CharSequence src) {
|
||||
public Content(CodeEditor editor, CharSequence src) {
|
||||
if (src == null) {
|
||||
src = "";
|
||||
}
|
||||
this.editor = editor;
|
||||
mTextLength = 0;
|
||||
mNestedBatchEdit = 0;
|
||||
if (!useBlock)
|
||||
@@ -607,7 +611,7 @@ public class Content implements CharSequence {
|
||||
* @return sub sequence of this Content
|
||||
*/
|
||||
public Content subContent(int startLine, int startColumn, int endLine, int endColumn) {
|
||||
Content c = new Content();
|
||||
Content c = new Content(this.editor);
|
||||
c.setUndoEnabled(false);
|
||||
if (startLine == endLine) {
|
||||
c.insert(0, 0, mLines.get(startLine).subSequence(startColumn, endColumn));
|
||||
@@ -691,7 +695,7 @@ public class Content implements CharSequence {
|
||||
*/
|
||||
public Cursor getCursor() {
|
||||
if (mCursor == null) {
|
||||
mCursor = new Cursor(this);
|
||||
mCursor = new Cursor(this.editor, this);
|
||||
}
|
||||
return mCursor;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import io.github.rosemoe.editor.interfaces.EditorLanguage;
|
||||
import io.github.rosemoe.editor.util.IntPair;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import io.github.rosemoe.editor.widget.CodeEditor;
|
||||
|
||||
/**
|
||||
* @author Rose
|
||||
@@ -35,6 +36,8 @@ public final class Cursor {
|
||||
private EditorLanguage mLanguage;
|
||||
private int mTabWidth;
|
||||
|
||||
private final CodeEditor editor;
|
||||
|
||||
private final List<Character> pairs;
|
||||
|
||||
/**
|
||||
@@ -42,7 +45,8 @@ public final class Cursor {
|
||||
*
|
||||
* @param content Target content
|
||||
*/
|
||||
public Cursor(Content content) {
|
||||
public Cursor(CodeEditor editor, Content content) {
|
||||
this.editor = editor;
|
||||
mContent = content;
|
||||
mIndexer = new CachedIndexer(content);
|
||||
mLeft = new CharPosition().zero();
|
||||
@@ -269,7 +273,12 @@ public final class Cursor {
|
||||
&& text.charAt(0) == mContent.charAt(getLeftLine(), getLeftColumn())
|
||||
&& pairs.contains(text.charAt(0))) {
|
||||
|
||||
set(getLeftLine(), getLeftColumn() + 1);
|
||||
// Moving the cursor to right through editor is instant
|
||||
// If we don't really have an instance of the editor, fall back to 'less efficient' method
|
||||
if(this.editor != null)
|
||||
this.editor.moveSelectionRight();
|
||||
else
|
||||
set(getLeftLine(), getLeftColumn() + 1);
|
||||
} else {
|
||||
if (mAutoIndentEnabled && text.length() != 0 && applyAutoIndent) {
|
||||
char first = text.charAt(0);
|
||||
@@ -311,18 +320,8 @@ public final class Cursor {
|
||||
* @return Generated space string
|
||||
*/
|
||||
private String createIndent(int p) {
|
||||
int tab = 0;
|
||||
int space;
|
||||
// if (mLanguage.useTab()) {
|
||||
// tab = p / mTabWidth;
|
||||
// space = p % mTabWidth;
|
||||
// } else {
|
||||
space = p;
|
||||
// }
|
||||
int space = p;
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < tab; i++) {
|
||||
s.append('\t');
|
||||
}
|
||||
for (int i = 0; i < space; i++) {
|
||||
s.append(' ');
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import io.github.rosemoe.editor.struct.Span;
|
||||
import io.github.rosemoe.editor.widget.EditorColorScheme;
|
||||
import java.util.HashMap;
|
||||
import io.github.rosemoe.editor.struct.HexColor;
|
||||
import java.util.Map;
|
||||
import com.itsaky.lsp.Range;
|
||||
|
||||
/**
|
||||
* The result of analysis
|
||||
@@ -37,6 +39,8 @@ public class TextAnalyzeResult {
|
||||
protected List<NavigationItem> mLabels;
|
||||
protected Span mLast;
|
||||
protected int mSuppressSwitch = Integer.MAX_VALUE;
|
||||
|
||||
private final Map<Integer, List<Range>> stringMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Create a new result
|
||||
@@ -47,6 +51,22 @@ public class TextAnalyzeResult {
|
||||
mBlocks = new ArrayList<>(1024);
|
||||
mHexColor = new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<Integer, List<Range>> getStringMap() {
|
||||
return stringMap;
|
||||
}
|
||||
|
||||
public void addStringRange(int line, Range range) {
|
||||
if(stringMap.containsKey(line)) {
|
||||
List<Range> ranges = stringMap.get(line);
|
||||
ranges.add(range);
|
||||
stringMap.put(line, ranges);
|
||||
} else {
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
ranges.add(range);
|
||||
stringMap.put(line, ranges);
|
||||
}
|
||||
}
|
||||
|
||||
public void addHexColor(HexColor index, int color) {
|
||||
mHexColor.put(index, color);
|
||||
|
||||
@@ -262,6 +262,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
|
||||
private Map<HexColor, Integer> mLineColors;
|
||||
private Map<Range, Diagnostic> mDiagnostics;
|
||||
private Map<Integer, List<Range>> stringMap;
|
||||
|
||||
private File currentFile;
|
||||
|
||||
@@ -597,6 +598,10 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
diags = new HashMap<>();
|
||||
this.mDiagnostics = diags;
|
||||
}
|
||||
|
||||
public void setStringMap(Map<Integer, List<Range>> map) {
|
||||
this.stringMap = map;
|
||||
}
|
||||
|
||||
public CodeEditor setLineColors(HashMap<HexColor, Integer> map) {
|
||||
this.mLineColors = map;
|
||||
@@ -3703,7 +3708,7 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
String t = text.toString();
|
||||
t = t.replace("\t", " ");
|
||||
|
||||
mText = new Content(t);
|
||||
mText = new Content(this, t);
|
||||
mCursor = mText.getCursor();
|
||||
mCursor.setAutoIndent(mAutoIndentEnabled);
|
||||
mCursor.setLanguage(mLanguage);
|
||||
@@ -4421,7 +4426,8 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
exitSelectModeIfNeeded();
|
||||
|
||||
// Auto completion
|
||||
if (isAutoCompletionEnabled()) {
|
||||
// Trigger only when autocompletion is enabled and cursor is not in a string token
|
||||
if (isAutoCompletionEnabled() && !isInString()) {
|
||||
if ((mConnection.mComposingLine == -1 || mCompletionOnComposing) && endColumn != 0 && startLine == endLine) {
|
||||
int end = endColumn;
|
||||
while (endColumn > 0) {
|
||||
@@ -4461,6 +4467,20 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInString() {
|
||||
final int line = getCursor().getLeftLine();
|
||||
final int column = getCursor().getLeftColumn();
|
||||
if(stringMap == null || stringMap.isEmpty() || !stringMap.containsKey(line)) return false;
|
||||
List<Range> strings = stringMap.get(line);
|
||||
if(strings == null || strings.isEmpty()) return false;
|
||||
for(int i=0;i<strings.size();i++) {
|
||||
Range r = strings.get(i);
|
||||
if(r.start.character <= column && column <= r.end.character)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void notifyChanged() {
|
||||
if (getFile() != null && getFile().getName().endsWith(".java") && jlsRequestor != null) {
|
||||
TextDocumentContentChangeEvent event = new TextDocumentContentChangeEvent();
|
||||
@@ -4566,6 +4586,9 @@ public class CodeEditor extends View implements ContentListener, TextAnalyzer.Ca
|
||||
if(mSpanner.getResult().getHexColors().size() > 0) {
|
||||
setLineColors(mSpanner.getResult().getHexColors());
|
||||
}
|
||||
if(mSpanner.getResult().getStringMap().size() > 0) {
|
||||
setStringMap(mSpanner.getResult().getStringMap());
|
||||
}
|
||||
if (mHighlightCurrentBlock) {
|
||||
mCursorPosition = findCursorBlock();
|
||||
}
|
||||
|
||||
@@ -66,13 +66,12 @@ public class SymbolChannel {
|
||||
&& text.charAt(0) == mEditor.getText().charAt(cur.getLeftLine(), cur.getLeftColumn())
|
||||
&& pairs.contains(text.charAt(0))) {
|
||||
mEditor.moveSelectionRight();
|
||||
}
|
||||
|
||||
mEditor.getText().insert(cur.getRightLine(), cur.getRightColumn(), text);
|
||||
|
||||
mEditor.notifyExternalCursorChange();
|
||||
if (selectionOffset != text.length()) {
|
||||
mEditor.setSelection(cur.getRightLine(), cur.getRightColumn() - (text.length() - selectionOffset));
|
||||
} else {
|
||||
mEditor.getText().insert(cur.getRightLine(), cur.getRightColumn(), text);
|
||||
mEditor.notifyExternalCursorChange();
|
||||
if (selectionOffset != text.length()) {
|
||||
mEditor.setSelection(cur.getRightLine(), cur.getRightColumn() - (text.length() - selectionOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M22,6C22,4.9 21.1,4 20,4H4C2.9,4 2,4.9 2,6V18C2,19.1 2.9,20 4,20H20C21.1,20 22,19.1 22,18V6M20,6L12,11L4,6H20M20,18H4V8L12,13L20,8V18Z"/>
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,2A10,10 0,0 0,2 12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0,0 0,12 2Z"/>
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12A10,10 0,0 0,12 22A10,10 0,0 0,22 12A10,10 0,0 0,12 2Z"/>
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.motion.widget.MotionLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutDescription="@xml/motion_about">
|
||||
|
||||
<View
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:id="@+id/icon_anchor"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="200dp"
|
||||
android:background="@color/primaryDarkColor"/>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon_anchor"
|
||||
android:id="@+id/icon_container"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="-28dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:cardBackgroundColor="@color/primaryLightColor"
|
||||
app:cardCornerRadius="5dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:src="@mipmap/ic_launcher"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/icon"/>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<TextView
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon_container"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textStyle="bold"
|
||||
android:textSize="30sp"
|
||||
android:textColor="@color/primaryTextColor"
|
||||
android:layout_marginBottom="4dp"/>
|
||||
|
||||
<TextView
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/about_subtitle"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/secondaryTextColor"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/subtitle"
|
||||
android:id="@+id/about_scroller">
|
||||
|
||||
<include android:id="@+id/items" layout="@layout/layout_about_items"/>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.constraintlayout.motion.widget.MotionLayout>
|
||||
@@ -2,6 +2,7 @@
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/editor_drawerLayout"
|
||||
@@ -308,7 +309,8 @@
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"/>
|
||||
android:paddingBottom="4dp"
|
||||
tools:ignore="MissingConstraints"/>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_view"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="center"
|
||||
android:id="@+id/appbar"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:background="?attr/colorPrimaryDark"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Behavior">
|
||||
|
||||
<RelativeLayout
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~ Copyright 2020-2021 Rosemoe
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
@@ -35,13 +19,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp">
|
||||
android:paddingStart="4dp"
|
||||
android:paddingEnd="4dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Medium Text"
|
||||
android:textColor="#FF000000"
|
||||
android:id="@+id/result_item_label"
|
||||
android:textSize="16sp"/>
|
||||
@@ -49,10 +32,9 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Small Text"
|
||||
android:id="@+id/result_item_desc"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginLeft="8dp"/>
|
||||
android:layout_marginStart="8dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/bg_ripple"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon_github"
|
||||
android:layout_height="22dp"
|
||||
android:layout_width="22dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_centerVertical="true"
|
||||
app:srcCompat="@drawable/ic_github"/>
|
||||
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/primaryTextColor"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_toEndOf="@id/icon_github"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/user_suggestions"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/bg_ripple"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon_telegram"
|
||||
android:layout_height="22dp"
|
||||
android:layout_width="22dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_centerVertical="true"
|
||||
app:srcCompat="@drawable/ic_telegram"/>
|
||||
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/primaryTextColor"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_toEndOf="@id/icon_telegram"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/discussions_on_telegram"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/bg_ripple"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon_email"
|
||||
android:layout_height="22dp"
|
||||
android:layout_width="22dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_centerVertical="true"
|
||||
app:srcCompat="@drawable/ic_email"/>
|
||||
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/primaryTextColor"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_toEndOf="@id/icon_email"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/about_option_email"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/bg_ripple"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon_website"
|
||||
android:layout_height="22dp"
|
||||
android:layout_width="22dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_centerVertical="true"
|
||||
app:srcCompat="@drawable/ic_website"/>
|
||||
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/primaryTextColor"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_toEndOf="@id/icon_website"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/about_option_website"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Developers"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<View
|
||||
android:background="?android:attr/dividerVertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="\u2022 Akash Yadav\n\u2022 Marvin Stelter"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/secondaryTextColor_lighter"
|
||||
android:autoLink="all"
|
||||
android:linksClickable="true"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Open source licenses"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<View
|
||||
android:background="?android:attr/dividerVertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textColor="@color/secondaryTextColor_lighter"
|
||||
android:text="AndroidIDE uses open source libraries. You can find the source and the license of the libraries used by clicking on below links."
|
||||
android:layout_marginBottom="4dp"
|
||||
android:textSize="14sp"
|
||||
android:autoLink="all"
|
||||
android:linksClickable="true"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:id="@+id/licenses"
|
||||
android:textColor="@color/secondaryTextColor_lighter"
|
||||
android:textSize="14sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/footer_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textColor="@color/secondaryTextColor"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="RelativeOverlap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/list_container">
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="Overdraw"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -14,7 +16,8 @@
|
||||
android:id="@+id/diagnostics"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingStart="16dp"/>
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="UnusedAttribute"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -8,7 +10,7 @@
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:gravity="top|left"
|
||||
android:gravity="top|start"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
@@ -25,7 +27,6 @@
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Text"
|
||||
android:textSize="15sp"
|
||||
android:id="@+id/title"
|
||||
android:textColor="@color/primaryTextColor"/>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardBackgroundColor="@color/primaryLightColor"
|
||||
@@ -74,6 +75,7 @@
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<ImageView
|
||||
tools:ignore="UnusedAttribute"
|
||||
app:srcCompat="@drawable/ic_file_delete"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="match_parent"
|
||||
@@ -97,6 +99,7 @@
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:visibility="gone"
|
||||
android:enabled="false"
|
||||
android:id="@+id/confirmDeleteContainer">
|
||||
|
||||
@@ -1,76 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~ Copyright 2020-2021 Rosemoe
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
|
||||
|
||||
<LinearLayout
|
||||
<HorizontalScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
android:layout_width="wrap_content"
|
||||
android:fillViewport="true">
|
||||
|
||||
<HorizontalScrollView
|
||||
<LinearLayout
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content">
|
||||
android:layout_width="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_height="match_parent"
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
android:text="@string/selectAll"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_select_all"/>
|
||||
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/selectAll"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_select_all"/>
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/copy"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_copy"/>
|
||||
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/copy"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_copy"/>
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/paste"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_paste"/>
|
||||
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/paste"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_paste"/>
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/cut"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_cut"/>
|
||||
|
||||
<Button
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/cut"
|
||||
android:textColor="#FF000000"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/panel_btn_cut"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="msg_about_license_source">Source and License: %s</string>
|
||||
<string name="msg_about_licensed_under">Licensed under %s</string>
|
||||
<string name="msg_about_no_licenses">Failed to load licenses</string>
|
||||
<string name="about_option_email">Email</string>
|
||||
<string name="about_option_website">Website</string>
|
||||
<string name="about_footer_alternate">AndroidIDE v\u2022 %s</string>
|
||||
<string name="about_footer">AndroidIDE %1$s for %2$s</string>
|
||||
<string name="about_subtitle">Simply, an IDE for Android</string>
|
||||
<string name="view_diags">Diagnostics</string>
|
||||
<string name="diagnostic_position">Start: %s, %s End: %s, %s</string>
|
||||
<string name="diagnostic_error">ERROR</string>
|
||||
@@ -11,11 +19,11 @@
|
||||
<string name="msg_failed_get_changelog">Failed to read changelog!</string>
|
||||
<string name="pref_changelog">Changelog</string>
|
||||
<string name="pref_changelog_summary">What\'s new in this version?</string>
|
||||
<string name="msg_getting_daemom_status">Getting Daemon status, please wait...</string>
|
||||
<string name="msg_indexing_success">Indexing success! Starting services...</string>
|
||||
<string name="msg_getting_daemom_status">Getting Daemon status, please wait…</string>
|
||||
<string name="msg_indexing_success">Indexing success! Starting services…</string>
|
||||
<string name="msg_indexing_failed">Index failed!</string>
|
||||
<string name="msg_indexing">Indexing: %s</string>
|
||||
<string name="msg_daemons_force_stopping">Gradle build process is running. Killing daemons...</string>
|
||||
<string name="msg_daemons_force_stopping">Gradle build process is running. Killing daemons…</string>
|
||||
<string name="msg_daemons_stopped">Gradle Daemons Stopped</string>
|
||||
<string name="recreate_completion_services">Recreate services</string>
|
||||
<string name="gradle_daemon_status">Gradle daemon status</string>
|
||||
@@ -57,6 +65,7 @@
|
||||
<string name="msg_install_gradle">Currently installed gradle version will be DELETE PEEMANENTLY!\n\nPlease enter full path of the zip file which contains Gradle distribution.</string>
|
||||
<string name="reset">Reset</string>
|
||||
<string name="title_change_text_size">Editor font size</string>
|
||||
<string name="idepref_about_title">About AndroidIDE</string>
|
||||
<string name="idepref_build_clearCache_title">Clear Gradle caches</string>
|
||||
<string name="idepref_build_clearCache_summary">Clear Gradle caches directory. This will delete all dependencies downloaded by Gradle. Required files will be downloaded again in next build.</string>
|
||||
<string name="idepref_build_choosegradle_title">Choose Gradle version</string>
|
||||
@@ -126,7 +135,7 @@
|
||||
<string name="msg_file_exists">File already exists!</string>
|
||||
<string name="msg_invalid_name">Invalid Name!</string>
|
||||
<string name="text_create">Create</string>
|
||||
<string name="msg_can_contain_slashes">You can use forward slashes (\'/\') to define a relative path to this folder. This will create directories if they do not already exist and will save time in creating multiple directories.</string>
|
||||
<string name="msg_can_contain_slashes">If the path contains File separator (\'/\'), then the required (parent) directories will be created if they don\'t exist.</string>
|
||||
<string name="folder_name">Folder Name</string>
|
||||
<string name="file_name">File Name</string>
|
||||
<string name="new_name">New name</string>
|
||||
@@ -191,7 +200,7 @@
|
||||
<string name="template_empty">Empty project</string>
|
||||
<string name="template_navigation_drawer">Navigation drawer project</string>
|
||||
<string name="unknown_type">Unknown type</string>
|
||||
<string name="app_name">Android IDE</string>
|
||||
<string name="app_name">AndroidIDE</string>
|
||||
<string name="build">Build</string>
|
||||
<string name="build_debug">assembleDebug</string>
|
||||
<string name="build_output">Build output</string>
|
||||
@@ -232,7 +241,7 @@
|
||||
<string name="nothing_here">Nothing here …</string>
|
||||
|
||||
<item name="paste" type="string">Paste</item>
|
||||
<item name="copy" type="string">Copy</item>
|
||||
<item name="copy" type="string" tools:override="true">Copy</item>
|
||||
<item name="selectAll" type="string" formatted="true">Select All</item>
|
||||
<item name="saveToProject" type="string" translatable="false" >Project</item>
|
||||
<item name="cut" type="string">Cut</item>
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MotionScene
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<Transition
|
||||
app:constraintSetEnd="@+id/end"
|
||||
app:constraintSetStart="@+id/start"
|
||||
app:duration="500">
|
||||
|
||||
<OnSwipe
|
||||
app:dragDirection="dragUp"
|
||||
app:touchAnchorId="@id/about_scroller"/>
|
||||
|
||||
</Transition>
|
||||
|
||||
<ConstraintSet
|
||||
android:id="@+id/start">
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:id="@+id/icon_anchor"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="200dp"/>
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon_anchor"
|
||||
android:id="@+id/icon_container"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="-28dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"/>
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon_container"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"/>
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<Constraint
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/subtitle"
|
||||
android:id="@+id/about_scroller"/>
|
||||
|
||||
</ConstraintSet>
|
||||
|
||||
<ConstraintSet
|
||||
android:id="@+id/end">
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:id="@+id/icon_anchor"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="200dp"/>
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon_anchor"
|
||||
android:id="@+id/icon_container"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="-28dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"/>
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon_container"
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<Constraint
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<Constraint
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/subtitle"
|
||||
android:id="@+id/about_scroller"/>
|
||||
|
||||
</ConstraintSet>
|
||||
|
||||
</MotionScene>
|
||||
@@ -1 +0,0 @@
|
||||
/build
|
||||
@@ -1,33 +0,0 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdk
|
||||
buildToolsVersion rootProject.ext.buildTools
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.minSdk
|
||||
targetSdkVersion rootProject.ext.targetSdk
|
||||
versionCode rootProject.ext.versionCode
|
||||
versionName rootProject.ext.versionName
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in C:/tools/adt-bundle-windows-x86_64-20131030/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.itsaky.androidide.javadoc" >
|
||||
</manifest>
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.itsaky.androidide.javadoc.tags.Tag;
|
||||
|
||||
/**
|
||||
* This Javadoc object holds the parsed information.
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class JavaDoc {
|
||||
|
||||
private String summary;
|
||||
private String description;
|
||||
private List<Tag> tags;
|
||||
|
||||
public JavaDoc(final String summary, final String description, final List<Tag> tags) {
|
||||
this.summary = summary;
|
||||
this.description = description;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* The summary is either defined by the new tag {(at)summary ...} or the first sentence of the textual description.
|
||||
*
|
||||
* @return the summary of the textual description
|
||||
*/
|
||||
public String getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Javadoc description is the whole text until the first tag.
|
||||
*
|
||||
* @return the complete textual description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all parsed {@link Tag}s
|
||||
*
|
||||
* @return a list of all tags
|
||||
*/
|
||||
public List<Tag> getTags() {
|
||||
return tags == null ? Collections.emptyList() : tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a list of all tags from the given class.
|
||||
*
|
||||
* @param tagClass a class to filter the output
|
||||
* @return a list of tags from the given class
|
||||
*/
|
||||
public <T extends Tag> List<T> getTags(final Class<T> tagClass) {
|
||||
return tags == null ? Collections.emptyList() : tags.stream()
|
||||
.filter(tagClass::isInstance)
|
||||
.map(tagClass::cast)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("JavaDoc [summary=%s, description=%s, tags=%s]", summary, description, tags);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc;
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static java.util.stream.Stream.concat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.itsaky.androidide.javadoc.exception.DuplicateTagException;
|
||||
import com.itsaky.androidide.javadoc.tags.Tag;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public final class JavaDocParser {
|
||||
|
||||
private List<Tag> tags = new ArrayList<>();
|
||||
private Map<String, String> replacements = new HashMap<>();
|
||||
|
||||
public JavaDoc parse(final String javaDocString) {
|
||||
String summary = "";
|
||||
String description = "";
|
||||
List<Tag> parsedTags = new ArrayList<>();
|
||||
|
||||
if (javaDocString != null && !javaDocString.isEmpty()) {
|
||||
final String rawDescription = parseDescription(javaDocString);
|
||||
|
||||
summary = performReplacements(parseSummary(rawDescription));
|
||||
description = performReplacements(rawDescription);
|
||||
parsedTags = parseTags(javaDocString);
|
||||
}
|
||||
|
||||
return new JavaDoc(summary, description, parsedTags);
|
||||
}
|
||||
|
||||
private String parseSummary(final String description) {
|
||||
if (description.isEmpty()) {
|
||||
return "";
|
||||
} else if (description.contains("@summary")) {
|
||||
Pattern summaryPattern = Pattern.compile("\\{@summary ([^{}]+)}([\\s.,:;-])?");
|
||||
Matcher summaryMatcher = summaryPattern.matcher(description);
|
||||
|
||||
if (summaryMatcher.find()) {
|
||||
return summaryMatcher.group(1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
} else {
|
||||
if (description.contains(".")) {
|
||||
return description.substring(0, description.indexOf('.') + 1);
|
||||
} else {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String parseDescription(final String javaDocString) {
|
||||
String[] lines = javaDocString.split("\n");
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String line : lines) {
|
||||
if (line.trim().startsWith("@")) {
|
||||
break;
|
||||
}
|
||||
stringBuilder.append(line).append("\n");
|
||||
}
|
||||
return stringBuilder.toString().trim();
|
||||
}
|
||||
|
||||
private List<Tag> parseTags(final String javaDocString) {
|
||||
List<Tag> tagList = new ArrayList<>();
|
||||
|
||||
Stream<String> tagNamesStream = tags.stream()
|
||||
.map(tag -> tag.getTagName())
|
||||
.map(tag -> String.format("@%s", tag));
|
||||
|
||||
String allTagNames = concat(tagNamesStream, Stream.of("[^{]@\\S+"))
|
||||
.collect(joining("|", "(?=", "|$)"));
|
||||
|
||||
for (Tag tag : tags) {
|
||||
Pattern pattern = Pattern.compile(tag.createPattern(allTagNames), Pattern.DOTALL);
|
||||
Matcher matcher = pattern.matcher(javaDocString);
|
||||
|
||||
int start = 0;
|
||||
while (matcher.find(start)) {
|
||||
Tag currentTag;
|
||||
try {
|
||||
currentTag = tag.getClass().newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
currentTag = tag;
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (String segmentName : tag.getSegmentNames()) {
|
||||
currentTag.putValue(segmentName, performReplacements(matcher.group(segmentName)));
|
||||
}
|
||||
|
||||
tagList.add(currentTag);
|
||||
start = matcher.end();
|
||||
}
|
||||
}
|
||||
|
||||
return tagList;
|
||||
}
|
||||
|
||||
private String performReplacements(final String input) {
|
||||
String convertedString = input;
|
||||
for (Entry<String, String> replacement : replacements.entrySet()) {
|
||||
convertedString = convertedString.replaceAll(replacement.getKey(), replacement.getValue());
|
||||
}
|
||||
return convertedString.trim();
|
||||
}
|
||||
|
||||
void addReplacement(final String regex, final String replacement){
|
||||
Objects.requireNonNull(regex, "The given regex must not be null!");
|
||||
Objects.requireNonNull(replacement, "The given replacement must not be null!");
|
||||
|
||||
if (regex.isEmpty()) {
|
||||
throw new IllegalArgumentException("The given regex must not be empty!");
|
||||
}
|
||||
|
||||
replacements.put(regex, replacement);
|
||||
}
|
||||
|
||||
void addTag(final Tag tag) {
|
||||
Objects.requireNonNull(tag, "The given tag must not be null!");
|
||||
if (tags.stream().anyMatch(t -> t.getClass().equals(tag.getClass()))){
|
||||
throw new DuplicateTagException(tag);
|
||||
}
|
||||
tags.add(tag);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.itsaky.androidide.javadoc.tags.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class JavaDocParserBuilder {
|
||||
|
||||
private static final String BASE_INLINE_PATTERN = "\\{@%s ([^\\{\\}]+)\\}([\\s.,:;-])?";
|
||||
private static final String INLINE_SUMMARY_PATTERN = String.format(BASE_INLINE_PATTERN, "summary");
|
||||
private static final String INLINE_CODE_PATTERN = String.format(BASE_INLINE_PATTERN, "code");
|
||||
private static final String INLINE_LINK_PATTERN = String.format(BASE_INLINE_PATTERN, "link");
|
||||
private static final String INLINE_LINKPLAIN_PATTERN = String.format(BASE_INLINE_PATTERN, "linkplain");
|
||||
private static final String INLINE_LITERAL_PATTERN = String.format(BASE_INLINE_PATTERN, "literal");
|
||||
private static final String INLINE_VALUE_PATTERN = String.format(BASE_INLINE_PATTERN, "value");
|
||||
|
||||
private JavaDocParser javaDocParser;
|
||||
|
||||
private JavaDocParserBuilder() {
|
||||
this.javaDocParser = new JavaDocParser();
|
||||
|
||||
Stream.of(new AuthorTag(),
|
||||
new CategoryTag(),
|
||||
new DeprecatedTag(),
|
||||
new ExceptionTag(),
|
||||
new ParamTag(),
|
||||
new ReturnTag(),
|
||||
new SeeTag(),
|
||||
new SinceTag(),
|
||||
new ThrowsTag(),
|
||||
new VersionTag())
|
||||
.forEach(javaDocParser::addTag);
|
||||
}
|
||||
|
||||
public static JavaDocParserBuilder withBasicTags() {
|
||||
return new JavaDocParserBuilder();
|
||||
}
|
||||
|
||||
public <T extends Tag> JavaDocParserBuilder withCustomTag(final T tag) {
|
||||
javaDocParser.addTag(tag);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaDocParserBuilder withOutputType(final OutputType outputType) {
|
||||
javaDocParser.addReplacement(INLINE_SUMMARY_PATTERN, "$1$2");
|
||||
if (OutputType.ASCIIDOC.equals(outputType) || OutputType.MARKDOWN.equals(outputType)) {
|
||||
javaDocParser.addReplacement(INLINE_CODE_PATTERN, "`$1`$2");
|
||||
javaDocParser.addReplacement(INLINE_LINK_PATTERN, "$1$2");
|
||||
javaDocParser.addReplacement(INLINE_LINKPLAIN_PATTERN, "$1$2");
|
||||
javaDocParser.addReplacement(INLINE_LITERAL_PATTERN, "_$1_$2");
|
||||
javaDocParser.addReplacement(INLINE_VALUE_PATTERN, "`$1`$2");
|
||||
} else if (OutputType.HTML.equals(outputType)) {
|
||||
javaDocParser.addReplacement(INLINE_CODE_PATTERN, "<code>$1</code>$2");
|
||||
javaDocParser.addReplacement(INLINE_LINK_PATTERN, "$1$2");
|
||||
javaDocParser.addReplacement(INLINE_LINKPLAIN_PATTERN, "$1$2");
|
||||
javaDocParser.addReplacement(INLINE_LITERAL_PATTERN, "<i>$1</i>$2");
|
||||
javaDocParser.addReplacement(INLINE_VALUE_PATTERN, "<pre>$1</pre>$2");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaDocParserBuilder withReplacement(final String regex, final String replacement) {
|
||||
javaDocParser.addReplacement(regex, replacement);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaDocParser build() {
|
||||
return javaDocParser;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public enum OutputType {
|
||||
|
||||
|
||||
ASCIIDOC,
|
||||
HTML,
|
||||
MARKDOWN,
|
||||
PLAIN;
|
||||
|
||||
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.exception;
|
||||
|
||||
import com.itsaky.androidide.javadoc.tags.Tag;
|
||||
|
||||
/**
|
||||
* A exception that is thrown if more than one tags of one type should be registered within one parser.
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class DuplicateTagException extends RuntimeException {
|
||||
|
||||
public static final long serialVersionUID = 1l;
|
||||
|
||||
public DuplicateTagException(final Tag tag){
|
||||
super(String.format("The parser contains a tag '@%s'.", tag.getTagName()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCBAHA
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class AuthorTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "author";
|
||||
|
||||
private static final String NAME_TEXT = "nameText";
|
||||
|
||||
public AuthorTag() {
|
||||
super(TAG_NAME, NAME_TEXT);
|
||||
}
|
||||
|
||||
public String getAuthorName() {
|
||||
return getValues().get(NAME_TEXT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class CategoryTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "category";
|
||||
|
||||
private static final String CATEGORY_NAME = "categoryName";
|
||||
|
||||
public CategoryTag() {
|
||||
super(TAG_NAME, CATEGORY_NAME);
|
||||
}
|
||||
|
||||
public String getCategoryName() {
|
||||
return getValues().get(CATEGORY_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#deprecated
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class DeprecatedTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "deprecated";
|
||||
|
||||
private static final String DEPRECATED_TEXT = "deprecatedText";
|
||||
|
||||
public DeprecatedTag() {
|
||||
super(TAG_NAME, DEPRECATED_TEXT);
|
||||
}
|
||||
|
||||
public String getDeprecatedNote() {
|
||||
return getValues().get(DEPRECATED_TEXT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCEAHH
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class ExceptionTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "exception";
|
||||
|
||||
private static final String CLASS_NAME = "className";
|
||||
private static final String DESCRIPTION = "description";
|
||||
|
||||
public ExceptionTag() {
|
||||
super(TAG_NAME, CLASS_NAME, DESCRIPTION);
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return getValues().get(CLASS_NAME);
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return getValues().get(DESCRIPTION);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHJECF
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class ParamTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "param";
|
||||
|
||||
private static final String PARAMETER_NAME = "parameterName";
|
||||
private static final String DESCRIPTION = "description";
|
||||
|
||||
public ParamTag() {
|
||||
super(TAG_NAME, PARAMETER_NAME, DESCRIPTION);
|
||||
}
|
||||
|
||||
public String getParamName() {
|
||||
return getValues().get(PARAMETER_NAME);
|
||||
}
|
||||
|
||||
public String getParamDescription() {
|
||||
return getValues().get(DESCRIPTION);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* A PatternTag can be used to define a custom {@link java.util.regex.Pattern}. For this free kind of tag, more methods have to be implemented.
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public abstract class PatternTag extends Tag {
|
||||
|
||||
private String name;
|
||||
private String pattern;
|
||||
|
||||
public PatternTag(final String name, final String pattern) {
|
||||
this.name = name;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public String getTagName() {
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createPattern(final String allTagNames) {
|
||||
return "@" + name + pattern + "\\s*" + allTagNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Tag [name=%s, pattern=%s]", name, pattern);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCDBGG
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class ReturnTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "return";
|
||||
|
||||
private static final String DESCRIPTION = "description";
|
||||
|
||||
public ReturnTag() {
|
||||
super(TAG_NAME, DESCRIPTION);
|
||||
}
|
||||
|
||||
public String getDesrcription() {
|
||||
return getValues().get(DESCRIPTION);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDDIEDI
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class SeeTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "see";
|
||||
|
||||
private static final String REFERENCE = "reference";
|
||||
|
||||
public SeeTag() {
|
||||
super(TAG_NAME, REFERENCE);
|
||||
}
|
||||
|
||||
public String getReference() {
|
||||
return getValues().get(REFERENCE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHGJGD
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class SinceTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "since";
|
||||
|
||||
private static final String SINCE_TEXT = "sinceText";
|
||||
|
||||
public SinceTag() {
|
||||
super(TAG_NAME, SINCE_TEXT);
|
||||
}
|
||||
|
||||
public String getSinceText() {
|
||||
return getValues().get(SINCE_TEXT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public abstract class StructuredTag extends Tag {
|
||||
|
||||
private String name;
|
||||
private List<String> segmentNames;
|
||||
private TreeMap<String, String> values = new TreeMap<>();
|
||||
|
||||
public StructuredTag(final String name, final String... segmentNames) {
|
||||
this.name = name;
|
||||
this.segmentNames = Arrays.asList(segmentNames);
|
||||
for (String segmentName : segmentNames) {
|
||||
values.put(segmentName, "");
|
||||
}
|
||||
}
|
||||
|
||||
public String getTagName() {
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
public List<String> getSegmentNames() {
|
||||
return segmentNames == null ? Collections.emptyList() : segmentNames;
|
||||
}
|
||||
|
||||
public Map<String, String> getValues() {
|
||||
return values == null ? new HashMap<String, String>() : values;
|
||||
}
|
||||
|
||||
public void putValue(final String segmentName, final String segmentValue) {
|
||||
if (values.containsKey(segmentName)) {
|
||||
values.put(segmentName, segmentValue != null ? segmentValue : "");
|
||||
}
|
||||
}
|
||||
|
||||
public String createPattern(final String allTagNames) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String segmentName : getSegmentNames()) {
|
||||
sb.append("\\s+?(?<" + segmentName + ">.+?)");
|
||||
}
|
||||
return "@" + name + sb.toString() + "\\s*" + allTagNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Tag [name=%s, values=%s]", name, values);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base class for all internal Javadoc tags.
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public abstract class Tag {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return the Javadoc tag name
|
||||
*/
|
||||
public abstract String getTagName();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return all names of segments that can be read
|
||||
*/
|
||||
public abstract List<String> getSegmentNames();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param segmentName the segment name for which the value should be saved
|
||||
* @param value the value that was parsed for the segment
|
||||
*/
|
||||
public abstract void putValue(final String segmentName, final String value);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param allTagNames the list of all patterns will be calculated on the fly and describes the end of a sinlge tag
|
||||
* @return the complete pattern string for this tag
|
||||
*/
|
||||
public abstract String createPattern(final String allTagNames);
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCHAHD
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class ThrowsTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "throws";
|
||||
|
||||
private static final String CLASS_NAME = "className";
|
||||
private static final String DESCRIPTION = "description";
|
||||
|
||||
public ThrowsTag() {
|
||||
super(TAG_NAME, CLASS_NAME, DESCRIPTION);
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return getValues().get(CLASS_NAME);
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return getValues().get(DESCRIPTION);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.javadoc.tags;
|
||||
|
||||
/**
|
||||
* https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCHBAE
|
||||
*
|
||||
* @author chhorz
|
||||
*
|
||||
*/
|
||||
public class VersionTag extends StructuredTag {
|
||||
|
||||
private static final String TAG_NAME = "version";
|
||||
|
||||
private static final String VERSION_TEXT = "versionText";
|
||||
|
||||
public VersionTag() {
|
||||
super(TAG_NAME, VERSION_TEXT);
|
||||
}
|
||||
|
||||
public String getVersionText() {
|
||||
return getValues().get(VERSION_TEXT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
include ':app'
|
||||
include ':treeview'
|
||||
include ':spinkit'
|
||||
include ':slidr'
|
||||
include ':javadocparser'
|
||||
include ':lsp'
|
||||
|
||||
rootProject.name = "Android IDE"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/build
|
||||
@@ -1,29 +0,0 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdk
|
||||
buildToolsVersion rootProject.ext.buildTools
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.minSdk
|
||||
targetSdkVersion rootProject.ext.targetSdk
|
||||
versionCode rootProject.ext.versionCode
|
||||
versionName rootProject.ext.versionName
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
}
|
||||
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/ybq/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -1,4 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.r0adkll.slidr">
|
||||
<application />
|
||||
</manifest>
|
||||
@@ -1,67 +0,0 @@
|
||||
package com.r0adkll.slidr;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.app.Activity;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.ColorInt;
|
||||
|
||||
import com.r0adkll.slidr.widget.SliderPanel;
|
||||
|
||||
|
||||
class ColorPanelSlideListener implements SliderPanel.OnPanelSlideListener {
|
||||
|
||||
private final Activity activity;
|
||||
private final int primaryColor;
|
||||
private final int secondaryColor;
|
||||
private final ArgbEvaluator evaluator = new ArgbEvaluator();
|
||||
|
||||
|
||||
ColorPanelSlideListener(Activity activity, @ColorInt int primaryColor, @ColorInt int secondaryColor) {
|
||||
this.activity = activity;
|
||||
this.primaryColor = primaryColor;
|
||||
this.secondaryColor = secondaryColor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int state) {
|
||||
// Unused.
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClosed() {
|
||||
activity.finish();
|
||||
activity.overridePendingTransition(0, 0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onOpened() {
|
||||
// Unused.
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSlideChange(float percent) {
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && areColorsValid()){
|
||||
int newColor = (int) evaluator.evaluate(percent, getPrimaryColor(), getSecondaryColor());
|
||||
activity.getWindow().setStatusBarColor(newColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected int getPrimaryColor() {
|
||||
return primaryColor;
|
||||
}
|
||||
|
||||
|
||||
protected int getSecondaryColor() {
|
||||
return secondaryColor;
|
||||
}
|
||||
|
||||
|
||||
protected boolean areColorsValid() {
|
||||
return getPrimaryColor() != -1 && getSecondaryColor() != -1;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package com.r0adkll.slidr;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.r0adkll.slidr.model.SlidrConfig;
|
||||
|
||||
|
||||
class ConfigPanelSlideListener extends ColorPanelSlideListener {
|
||||
|
||||
private final SlidrConfig config;
|
||||
|
||||
|
||||
ConfigPanelSlideListener(@NonNull Activity activity, @NonNull SlidrConfig config) {
|
||||
super(activity, -1, -1);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int state) {
|
||||
if(config.getListener() != null){
|
||||
config.getListener().onSlideStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClosed() {
|
||||
if(config.getListener() != null){
|
||||
if(config.getListener().onSlideClosed()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.onClosed();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onOpened() {
|
||||
if(config.getListener() != null){
|
||||
config.getListener().onSlideOpened();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSlideChange(float percent) {
|
||||
super.onSlideChange(percent);
|
||||
if(config.getListener() != null){
|
||||
config.getListener().onSlideChange(percent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getPrimaryColor() {
|
||||
return config.getPrimaryColor();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getSecondaryColor() {
|
||||
return config.getSecondaryColor();
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package com.r0adkll.slidr;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import android.view.View;
|
||||
|
||||
import com.r0adkll.slidr.model.SlidrConfig;
|
||||
import com.r0adkll.slidr.widget.SliderPanel;
|
||||
|
||||
|
||||
class FragmentPanelSlideListener implements SliderPanel.OnPanelSlideListener {
|
||||
|
||||
private final View view;
|
||||
private final SlidrConfig config;
|
||||
|
||||
|
||||
FragmentPanelSlideListener(@NonNull View view, @NonNull SlidrConfig config) {
|
||||
this.view = view;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int state) {
|
||||
if (config.getListener() != null) {
|
||||
config.getListener().onSlideStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClosed() {
|
||||
if (config.getListener() != null) {
|
||||
if(config.getListener().onSlideClosed()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that we are attached to a FragmentActivity
|
||||
if (view.getContext() instanceof FragmentActivity) {
|
||||
final FragmentActivity activity = (FragmentActivity) view.getContext();
|
||||
if (activity.getSupportFragmentManager().getBackStackEntryCount() == 0) {
|
||||
activity.finish();
|
||||
activity.overridePendingTransition(0, 0);
|
||||
} else {
|
||||
activity.getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpened() {
|
||||
if (config.getListener() != null) {
|
||||
config.getListener().onSlideOpened();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSlideChange(float percent) {
|
||||
if (config.getListener() != null) {
|
||||
config.getListener().onSlideChange(percent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package com.r0adkll.slidr;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.r0adkll.slidr.model.SlidrConfig;
|
||||
import com.r0adkll.slidr.model.SlidrInterface;
|
||||
import com.r0adkll.slidr.widget.SliderPanel;
|
||||
|
||||
|
||||
/**
|
||||
* This attacher class is used to attach the sliding mechanism to any {@link android.app.Activity}
|
||||
* that lets the user slide (or swipe) the activity away as a form of back or up action. The action
|
||||
* causes {@link android.app.Activity#finish()} to be called.
|
||||
*/
|
||||
public final class Slidr {
|
||||
|
||||
/**
|
||||
* Attach a slideable mechanism to an activity that adds the slide to dismiss functionality
|
||||
*
|
||||
* @param activity the activity to attach the slider to
|
||||
* @return a {@link com.r0adkll.slidr.model.SlidrInterface} that allows
|
||||
* the user to lock/unlock the sliding mechanism for whatever purpose.
|
||||
*/
|
||||
@NonNull
|
||||
public static SlidrInterface attach(@NonNull Activity activity) {
|
||||
return attach(activity, -1, -1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attach a slideable mechanism to an activity that adds the slide to dismiss functionality
|
||||
* and allows for the statusbar to transition between colors
|
||||
*
|
||||
* @param activity the activity to attach the slider to
|
||||
* @param statusBarColor1 the primaryDark status bar color of the interface that this will slide back to
|
||||
* @param statusBarColor2 the primaryDark status bar color of the activity this is attaching to that will transition
|
||||
* back to the statusBarColor1 color
|
||||
* @return a {@link com.r0adkll.slidr.model.SlidrInterface} that allows
|
||||
* the user to lock/unlock the sliding mechanism for whatever purpose.
|
||||
*/
|
||||
@NonNull
|
||||
public static SlidrInterface attach(@NonNull Activity activity, @ColorInt int statusBarColor1,
|
||||
@ColorInt int statusBarColor2) {
|
||||
|
||||
// Setup the slider panel and attach it to the decor
|
||||
final SliderPanel panel = attachSliderPanel(activity, null);
|
||||
|
||||
// Set the panel slide listener for when it becomes closed or opened
|
||||
panel.setOnPanelSlideListener(new ColorPanelSlideListener(activity, statusBarColor1, statusBarColor2));
|
||||
|
||||
// Return the lock interface
|
||||
return panel.getDefaultInterface();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attach a slider mechanism to an activity based on the passed {@link com.r0adkll.slidr.model.SlidrConfig}
|
||||
*
|
||||
* @param activity the activity to attach the slider to
|
||||
* @param config the slider configuration to make
|
||||
* @return a {@link com.r0adkll.slidr.model.SlidrInterface} that allows
|
||||
* the user to lock/unlock the sliding mechanism for whatever purpose.
|
||||
*/
|
||||
@NonNull
|
||||
public static SlidrInterface attach(@NonNull Activity activity, @NonNull SlidrConfig config) {
|
||||
|
||||
// Setup the slider panel and attach it to the decor
|
||||
final SliderPanel panel = attachSliderPanel(activity, config);
|
||||
|
||||
// Set the panel slide listener for when it becomes closed or opened
|
||||
panel.setOnPanelSlideListener(new ConfigPanelSlideListener(activity, config));
|
||||
|
||||
// Return the lock interface
|
||||
return panel.getDefaultInterface();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attach a new {@link SliderPanel} to the root of the activity's content
|
||||
*/
|
||||
@NonNull
|
||||
private static SliderPanel attachSliderPanel(@NonNull Activity activity, @NonNull SlidrConfig config) {
|
||||
// Hijack the decorview
|
||||
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
||||
View oldScreen = decorView.getChildAt(0);
|
||||
decorView.removeViewAt(0);
|
||||
|
||||
// Setup the slider panel and attach it to the decor
|
||||
SliderPanel panel = new SliderPanel(activity, oldScreen, config);
|
||||
panel.setId(R.id.slidable_panel);
|
||||
oldScreen.setId(R.id.slidable_content);
|
||||
panel.addView(oldScreen);
|
||||
decorView.addView(panel, 0);
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attach a slider mechanism to a fragment view replacing an internal view
|
||||
*
|
||||
* @param oldScreen the view within a fragment to replace
|
||||
* @param config the slider configuration to attach with
|
||||
* @return a {@link com.r0adkll.slidr.model.SlidrInterface} that allows
|
||||
* the user to lock/unlock the sliding mechanism for whatever purpose.
|
||||
*/
|
||||
@NonNull
|
||||
public static SlidrInterface replace(@NonNull final View oldScreen, @NonNull final SlidrConfig config) {
|
||||
ViewGroup parent = (ViewGroup) oldScreen.getParent();
|
||||
ViewGroup.LayoutParams params = oldScreen.getLayoutParams();
|
||||
parent.removeView(oldScreen);
|
||||
|
||||
// Setup the slider panel and attach it
|
||||
final SliderPanel panel = new SliderPanel(oldScreen.getContext(), oldScreen, config);
|
||||
panel.setId(R.id.slidable_panel);
|
||||
oldScreen.setId(R.id.slidable_content);
|
||||
|
||||
panel.addView(oldScreen);
|
||||
parent.addView(panel, 0, params);
|
||||
|
||||
// Set the panel slide listener for when it becomes closed or opened
|
||||
panel.setOnPanelSlideListener(new FragmentPanelSlideListener(oldScreen, config));
|
||||
|
||||
// Return the lock interface
|
||||
return panel.getDefaultInterface();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,318 +0,0 @@
|
||||
package com.r0adkll.slidr.model;
|
||||
|
||||
|
||||
import android.graphics.Color;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.customview.widget.ViewDragHelper;
|
||||
|
||||
|
||||
/**
|
||||
* This class contains the configuration information for all the options available in
|
||||
* this library
|
||||
*/
|
||||
public class SlidrConfig {
|
||||
|
||||
private int colorPrimary = -1;
|
||||
private int colorSecondary = -1;
|
||||
private float touchSize = -1f;
|
||||
private float sensitivity = 1f;
|
||||
private int scrimColor = Color.BLACK;
|
||||
private float scrimStartAlpha = 0.8f;
|
||||
private float scrimEndAlpha = 0f;
|
||||
private float velocityThreshold = 5f;
|
||||
private float distanceThreshold = 0.25f;
|
||||
private boolean edgeOnly = false;
|
||||
private float edgeSize = 0.18f;
|
||||
|
||||
private SlidrPosition position = SlidrPosition.LEFT;
|
||||
private SlidrListener listener;
|
||||
|
||||
|
||||
private SlidrConfig() {
|
||||
// Unused.
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
*
|
||||
* Getters
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the primary color that the slider will interpolate. That is this color is the color
|
||||
* of the status bar of the Activity you are returning to
|
||||
*
|
||||
* @return the primary status bar color
|
||||
*/
|
||||
public int getPrimaryColor(){
|
||||
return colorPrimary;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the secondary color that the slider will interpolatel That is the color of the Activity
|
||||
* that you are making slidable
|
||||
*
|
||||
* @return the secondary status bar color
|
||||
*/
|
||||
public int getSecondaryColor(){
|
||||
return colorSecondary;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the color of the background scrim
|
||||
*
|
||||
* @return the scrim color integer
|
||||
*/
|
||||
@ColorInt
|
||||
public int getScrimColor(){
|
||||
return scrimColor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get teh start alpha value for when the activity is not swiped at all
|
||||
*
|
||||
* @return the start alpha value (0.0 to 1.0)
|
||||
*/
|
||||
public float getScrimStartAlpha(){
|
||||
return scrimStartAlpha;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the end alpha value for when the user almost swipes the activity off the screen
|
||||
*
|
||||
* @return the end alpha value (0.0 to 1.0)
|
||||
*/
|
||||
public float getScrimEndAlpha(){
|
||||
return scrimEndAlpha;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the position of the slidable mechanism for this configuration. This is the position on
|
||||
* the screen that the user can swipe the activity away from
|
||||
*
|
||||
* @return the slider position
|
||||
*/
|
||||
public SlidrPosition getPosition(){
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the touch 'width' to be used in the gesture detection. This value should incorporate with
|
||||
* the device's touch slop
|
||||
*
|
||||
* @return the touch area size
|
||||
*/
|
||||
public float getTouchSize(){
|
||||
return touchSize;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the velocity threshold at which the slide action is completed regardless of offset
|
||||
* distance of the drag
|
||||
*
|
||||
* @return the velocity threshold
|
||||
*/
|
||||
public float getVelocityThreshold(){
|
||||
return velocityThreshold;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get at what % of the screen is the minimum viable distance the activity has to be dragged
|
||||
* in-order to be slinged off the screen
|
||||
*
|
||||
* @return the distant threshold as a percentage of the screen size (width or height)
|
||||
*/
|
||||
public float getDistanceThreshold(){
|
||||
return distanceThreshold;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the touch sensitivity set in the {@link ViewDragHelper} when
|
||||
* creating it.
|
||||
*
|
||||
* @return the touch sensitivity
|
||||
*/
|
||||
public float getSensitivity(){
|
||||
return sensitivity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the slidr listener set by the user to respond to certain events in the sliding
|
||||
* mechanism.
|
||||
*
|
||||
* @return the slidr listener
|
||||
*/
|
||||
public SlidrListener getListener(){
|
||||
return listener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Has the user configured slidr to only catch at the edge of the screen ?
|
||||
*
|
||||
* @return true if is edge capture only
|
||||
*/
|
||||
public boolean isEdgeOnly() {
|
||||
return edgeOnly;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the size of the edge field that is catchable
|
||||
*
|
||||
* @see #isEdgeOnly()
|
||||
* @return the size of the edge that is grabable
|
||||
*/
|
||||
public float getEdgeSize(float size) {
|
||||
return edgeSize * size;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
*
|
||||
* Setters
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
public void setColorPrimary(int colorPrimary) {
|
||||
this.colorPrimary = colorPrimary;
|
||||
}
|
||||
|
||||
|
||||
public void setColorSecondary(int colorSecondary) {
|
||||
this.colorSecondary = colorSecondary;
|
||||
}
|
||||
|
||||
|
||||
public void setTouchSize(float touchSize) {
|
||||
this.touchSize = touchSize;
|
||||
}
|
||||
|
||||
|
||||
public void setSensitivity(float sensitivity) {
|
||||
this.sensitivity = sensitivity;
|
||||
}
|
||||
|
||||
|
||||
public void setScrimColor(@ColorInt int scrimColor) {
|
||||
this.scrimColor = scrimColor;
|
||||
}
|
||||
|
||||
|
||||
public void setScrimStartAlpha(float scrimStartAlpha) {
|
||||
this.scrimStartAlpha = scrimStartAlpha;
|
||||
}
|
||||
|
||||
|
||||
public void setScrimEndAlpha(float scrimEndAlpha) {
|
||||
this.scrimEndAlpha = scrimEndAlpha;
|
||||
}
|
||||
|
||||
|
||||
public void setVelocityThreshold(float velocityThreshold) {
|
||||
this.velocityThreshold = velocityThreshold;
|
||||
}
|
||||
|
||||
|
||||
public void setDistanceThreshold(float distanceThreshold) {
|
||||
this.distanceThreshold = distanceThreshold;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The Builder for this configuration class. This is the only way to create a
|
||||
* configuration
|
||||
*/
|
||||
public static class Builder{
|
||||
|
||||
private SlidrConfig config;
|
||||
|
||||
public Builder(){
|
||||
config = new SlidrConfig();
|
||||
}
|
||||
|
||||
public Builder primaryColor(@ColorInt int color){
|
||||
config.colorPrimary = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder secondaryColor(@ColorInt int color){
|
||||
config.colorSecondary = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder position(SlidrPosition position){
|
||||
config.position = position;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder touchSize(float size){
|
||||
config.touchSize = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder sensitivity(float sensitivity){
|
||||
config.sensitivity = sensitivity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder scrimColor(@ColorInt int color){
|
||||
config.scrimColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder scrimStartAlpha(@FloatRange(from = 0.0, to = 1.0) float alpha){
|
||||
config.scrimStartAlpha = alpha;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder scrimEndAlpha(@FloatRange(from = 0.0, to = 1.0) float alpha){
|
||||
config.scrimEndAlpha = alpha;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder velocityThreshold(float threshold){
|
||||
config.velocityThreshold = threshold;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder distanceThreshold(@FloatRange(from = .1f, to = .9f) float threshold){
|
||||
config.distanceThreshold = threshold;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder edge(boolean flag){
|
||||
config.edgeOnly = flag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder edgeSize(@FloatRange(from = 0f, to = 1f) float edgeSize){
|
||||
config.edgeSize = edgeSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder listener(SlidrListener listener){
|
||||
config.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SlidrConfig build(){
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.r0adkll.slidr.model;
|
||||
|
||||
|
||||
public interface SlidrInterface {
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.r0adkll.slidr.model;
|
||||
|
||||
import androidx.customview.widget.ViewDragHelper;
|
||||
|
||||
/**
|
||||
* This listener interface is for receiving events from the sliding panel such as state changes
|
||||
* and slide progress
|
||||
*/
|
||||
public interface SlidrListener {
|
||||
|
||||
/**
|
||||
* This is called when the {@link ViewDragHelper} calls it's
|
||||
* state change callback.
|
||||
*
|
||||
* @see ViewDragHelper#STATE_IDLE
|
||||
* @see ViewDragHelper#STATE_DRAGGING
|
||||
* @see ViewDragHelper#STATE_SETTLING
|
||||
*
|
||||
* @param state the {@link ViewDragHelper} state
|
||||
*/
|
||||
void onSlideStateChanged(int state);
|
||||
|
||||
void onSlideChange(float percent);
|
||||
|
||||
void onSlideOpened();
|
||||
|
||||
/**
|
||||
* @return <code>true</code> than event was processed in the callback.
|
||||
*/
|
||||
boolean onSlideClosed();
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.r0adkll.slidr.model;
|
||||
|
||||
|
||||
public class SlidrListenerAdapter implements SlidrListener {
|
||||
|
||||
@Override
|
||||
public void onSlideStateChanged(int state) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlideChange(float percent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlideOpened() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSlideClosed() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.r0adkll.slidr.model;
|
||||
|
||||
|
||||
public enum SlidrPosition {
|
||||
|
||||
LEFT,
|
||||
RIGHT,
|
||||
TOP,
|
||||
BOTTOM,
|
||||
VERTICAL,
|
||||
HORIZONTAL
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,124 +0,0 @@
|
||||
package com.r0adkll.slidr.widget;
|
||||
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.view.View;
|
||||
|
||||
import com.r0adkll.slidr.model.SlidrPosition;
|
||||
|
||||
|
||||
final class ScrimRenderer {
|
||||
|
||||
private final View rootView;
|
||||
private final View decorView;
|
||||
private final Rect dirtyRect;
|
||||
|
||||
|
||||
ScrimRenderer(@NonNull View rootView, @NonNull View decorView) {
|
||||
this.rootView = rootView;
|
||||
this.decorView = decorView;
|
||||
dirtyRect = new Rect();
|
||||
}
|
||||
|
||||
|
||||
void render(Canvas canvas, SlidrPosition position, Paint paint) {
|
||||
switch (position) {
|
||||
case LEFT:
|
||||
renderLeft(canvas, paint);
|
||||
break;
|
||||
case RIGHT:
|
||||
renderRight(canvas, paint);
|
||||
break;
|
||||
case TOP:
|
||||
renderTop(canvas, paint);
|
||||
break;
|
||||
case BOTTOM:
|
||||
renderBottom(canvas, paint);
|
||||
break;
|
||||
case VERTICAL:
|
||||
renderVertical(canvas, paint);
|
||||
break;
|
||||
case HORIZONTAL:
|
||||
renderHorizontal(canvas, paint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rect getDirtyRect(SlidrPosition position) {
|
||||
switch (position) {
|
||||
case LEFT:
|
||||
dirtyRect.set(0, 0, decorView.getLeft(), rootView.getMeasuredHeight());
|
||||
break;
|
||||
case RIGHT:
|
||||
dirtyRect.set(decorView.getRight(), 0, rootView.getMeasuredWidth(), rootView.getMeasuredHeight());
|
||||
break;
|
||||
case TOP:
|
||||
dirtyRect.set(0, 0, rootView.getMeasuredWidth(), decorView.getTop());
|
||||
break;
|
||||
case BOTTOM:
|
||||
dirtyRect.set(0, decorView.getBottom(), rootView.getMeasuredWidth(), rootView.getMeasuredHeight());
|
||||
break;
|
||||
case VERTICAL:
|
||||
if (decorView.getTop() > 0) {
|
||||
dirtyRect.set(0, 0, rootView.getMeasuredWidth(), decorView.getTop());
|
||||
}
|
||||
else {
|
||||
dirtyRect.set(0, decorView.getBottom(), rootView.getMeasuredWidth(), rootView.getMeasuredHeight());
|
||||
}
|
||||
break;
|
||||
case HORIZONTAL:
|
||||
if (decorView.getLeft() > 0) {
|
||||
dirtyRect.set(0, 0, decorView.getLeft(), rootView.getMeasuredHeight());
|
||||
}
|
||||
else {
|
||||
dirtyRect.set(decorView.getRight(), 0, rootView.getMeasuredWidth(), rootView.getMeasuredHeight());
|
||||
}
|
||||
break;
|
||||
}
|
||||
return dirtyRect;
|
||||
}
|
||||
|
||||
|
||||
private void renderLeft(Canvas canvas, Paint paint) {
|
||||
canvas.drawRect(0, 0, decorView.getLeft(), rootView.getMeasuredHeight(), paint);
|
||||
}
|
||||
|
||||
|
||||
private void renderRight(Canvas canvas, Paint paint) {
|
||||
canvas.drawRect(decorView.getRight(), 0, rootView.getMeasuredWidth(), rootView.getMeasuredHeight(), paint);
|
||||
}
|
||||
|
||||
|
||||
private void renderTop(Canvas canvas, Paint paint) {
|
||||
canvas.drawRect(0, 0, rootView.getMeasuredWidth(), decorView.getTop(), paint);
|
||||
}
|
||||
|
||||
|
||||
private void renderBottom(Canvas canvas, Paint paint) {
|
||||
canvas.drawRect(0, decorView.getBottom(), rootView.getMeasuredWidth(), rootView.getMeasuredHeight(), paint);
|
||||
}
|
||||
|
||||
|
||||
private void renderVertical(Canvas canvas, Paint paint) {
|
||||
if (decorView.getTop() > 0) {
|
||||
renderTop(canvas, paint);
|
||||
}
|
||||
else {
|
||||
renderBottom(canvas, paint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void renderHorizontal(Canvas canvas, Paint paint) {
|
||||
if (decorView.getLeft() > 0) {
|
||||
renderLeft(canvas, paint);
|
||||
}
|
||||
else {
|
||||
renderRight(canvas, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,782 +0,0 @@
|
||||
package com.r0adkll.slidr.widget;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.ViewGroupCompat;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.r0adkll.slidr.model.SlidrConfig;
|
||||
import com.r0adkll.slidr.util.ViewDragHelper;
|
||||
import com.r0adkll.slidr.model.SlidrInterface;
|
||||
|
||||
|
||||
public class SliderPanel extends FrameLayout {
|
||||
|
||||
private static final int MIN_FLING_VELOCITY = 400; // dips per second
|
||||
|
||||
private int screenWidth;
|
||||
private int screenHeight;
|
||||
|
||||
private View decorView;
|
||||
private ViewDragHelper dragHelper;
|
||||
private OnPanelSlideListener listener;
|
||||
private Paint scrimPaint;
|
||||
private ScrimRenderer scrimRenderer;
|
||||
|
||||
private boolean isLocked = false;
|
||||
private boolean isEdgeTouched = false;
|
||||
private int edgePosition;
|
||||
|
||||
private SlidrConfig config;
|
||||
|
||||
|
||||
public SliderPanel(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
|
||||
public SliderPanel(Context context, View decorView, SlidrConfig config){
|
||||
super(context);
|
||||
this.decorView = decorView;
|
||||
this.config = (config == null ? new SlidrConfig.Builder().build() : config);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
boolean interceptForDrag;
|
||||
|
||||
if(isLocked){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(config.isEdgeOnly()) {
|
||||
isEdgeTouched = canDragFromEdge(ev);
|
||||
}
|
||||
|
||||
// Fix for pull request #13 and issue #12
|
||||
try {
|
||||
interceptForDrag = dragHelper.shouldInterceptTouchEvent(ev);
|
||||
} catch (Exception e) {
|
||||
interceptForDrag = false;
|
||||
}
|
||||
|
||||
return interceptForDrag && !isLocked;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(isLocked){
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
dragHelper.processTouchEvent(event);
|
||||
}catch (IllegalArgumentException e){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void computeScroll() {
|
||||
super.computeScroll();
|
||||
if(dragHelper.continueSettling(true)){
|
||||
ViewCompat.postInvalidateOnAnimation(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
scrimRenderer.render(canvas, config.getPosition(), scrimPaint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the panel slide listener that gets called based on slider changes
|
||||
* @param listener callback implementation
|
||||
*/
|
||||
public void setOnPanelSlideListener(OnPanelSlideListener listener){
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the default {@link SlidrInterface} from which to control the panel with after attachment
|
||||
*/
|
||||
public SlidrInterface getDefaultInterface() {
|
||||
return defaultSlidrInterface;
|
||||
}
|
||||
|
||||
|
||||
private final SlidrInterface defaultSlidrInterface = new SlidrInterface() {
|
||||
|
||||
|
||||
@Override
|
||||
public void lock() {
|
||||
SliderPanel.this.lock();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void unlock() {
|
||||
SliderPanel.this.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The drag helper callback interface for the Left position
|
||||
*/
|
||||
private final ViewDragHelper.Callback leftCallback = new ViewDragHelper.Callback() {
|
||||
|
||||
@Override
|
||||
public boolean tryCaptureView(View child, int pointerId) {
|
||||
boolean edgeCase = !config.isEdgeOnly() || dragHelper.isEdgeTouched(edgePosition, pointerId);
|
||||
return child.getId() == decorView.getId() && edgeCase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionHorizontal(View child, int left, int dx) {
|
||||
return clamp(left, 0, screenWidth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewHorizontalDragRange(View child) {
|
||||
return screenWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewReleased(View releasedChild, float xvel, float yvel) {
|
||||
super.onViewReleased(releasedChild, xvel, yvel);
|
||||
|
||||
int left = releasedChild.getLeft();
|
||||
int settleLeft = 0;
|
||||
int leftThreshold = (int) (getWidth() * config.getDistanceThreshold());
|
||||
boolean isVerticalSwiping = Math.abs(yvel) > config.getVelocityThreshold();
|
||||
|
||||
if(xvel > 0){
|
||||
|
||||
if(Math.abs(xvel) > config.getVelocityThreshold() && !isVerticalSwiping){
|
||||
settleLeft = screenWidth;
|
||||
}else if(left > leftThreshold){
|
||||
settleLeft = screenWidth;
|
||||
}
|
||||
|
||||
}else if(xvel == 0){
|
||||
if(left > leftThreshold){
|
||||
settleLeft = screenWidth;
|
||||
}
|
||||
}
|
||||
|
||||
dragHelper.settleCapturedViewAt(settleLeft, releasedChild.getTop());
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
||||
super.onViewPositionChanged(changedView, left, top, dx, dy);
|
||||
float percent = 1f - ((float)left / (float) screenWidth);
|
||||
|
||||
if(listener != null) listener.onSlideChange(percent);
|
||||
|
||||
// Update the dimmer alpha
|
||||
applyScrim(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDragStateChanged(int state) {
|
||||
super.onViewDragStateChanged(state);
|
||||
if(listener != null) listener.onStateChanged(state);
|
||||
switch (state){
|
||||
case ViewDragHelper.STATE_IDLE:
|
||||
if(decorView.getLeft() == 0){
|
||||
// State Open
|
||||
if(listener != null) listener.onOpened();
|
||||
}else{
|
||||
// State Closed
|
||||
if(listener != null) listener.onClosed();
|
||||
}
|
||||
break;
|
||||
case ViewDragHelper.STATE_DRAGGING:
|
||||
|
||||
break;
|
||||
case ViewDragHelper.STATE_SETTLING:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The drag helper callbacks for dragging the slidr attachment from the right of the screen
|
||||
*/
|
||||
private final ViewDragHelper.Callback rightCallback = new ViewDragHelper.Callback() {
|
||||
@Override
|
||||
public boolean tryCaptureView(View child, int pointerId) {
|
||||
boolean edgeCase = !config.isEdgeOnly() || dragHelper.isEdgeTouched(edgePosition, pointerId);
|
||||
return child.getId() == decorView.getId() && edgeCase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionHorizontal(View child, int left, int dx) {
|
||||
return clamp(left, -screenWidth, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewHorizontalDragRange(View child) {
|
||||
return screenWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewReleased(View releasedChild, float xvel, float yvel) {
|
||||
super.onViewReleased(releasedChild, xvel, yvel);
|
||||
|
||||
int left = releasedChild.getLeft();
|
||||
int settleLeft = 0;
|
||||
int leftThreshold = (int) (getWidth() * config.getDistanceThreshold());
|
||||
boolean isVerticalSwiping = Math.abs(yvel) > config.getVelocityThreshold();
|
||||
|
||||
if(xvel < 0){
|
||||
|
||||
if(Math.abs(xvel) > config.getVelocityThreshold() && !isVerticalSwiping){
|
||||
settleLeft = -screenWidth;
|
||||
}else if(left < -leftThreshold){
|
||||
settleLeft = -screenWidth;
|
||||
}
|
||||
|
||||
}else if(xvel == 0){
|
||||
if(left < -leftThreshold){
|
||||
settleLeft = -screenWidth;
|
||||
}
|
||||
}
|
||||
|
||||
dragHelper.settleCapturedViewAt(settleLeft, releasedChild.getTop());
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
||||
super.onViewPositionChanged(changedView, left, top, dx, dy);
|
||||
float percent = 1f - ((float)Math.abs(left) / (float) screenWidth);
|
||||
|
||||
if(listener != null) listener.onSlideChange(percent);
|
||||
|
||||
// Update the dimmer alpha
|
||||
applyScrim(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDragStateChanged(int state) {
|
||||
super.onViewDragStateChanged(state);
|
||||
if(listener != null) listener.onStateChanged(state);
|
||||
switch (state){
|
||||
case ViewDragHelper.STATE_IDLE:
|
||||
if(decorView.getLeft() == 0){
|
||||
// State Open
|
||||
if(listener != null) listener.onOpened();
|
||||
}else{
|
||||
// State Closed
|
||||
if(listener != null) listener.onClosed();
|
||||
}
|
||||
break;
|
||||
case ViewDragHelper.STATE_DRAGGING:
|
||||
|
||||
break;
|
||||
case ViewDragHelper.STATE_SETTLING:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The drag helper callbacks for dragging the slidr attachment from the top of the screen
|
||||
*/
|
||||
private final ViewDragHelper.Callback topCallback = new ViewDragHelper.Callback() {
|
||||
@Override
|
||||
public boolean tryCaptureView(View child, int pointerId) {
|
||||
return child.getId() == decorView.getId() && (!config.isEdgeOnly() || isEdgeTouched);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionVertical(View child, int top, int dy) {
|
||||
return clamp(top, 0, screenHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewVerticalDragRange(View child) {
|
||||
return screenHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewReleased(View releasedChild, float xvel, float yvel) {
|
||||
super.onViewReleased(releasedChild, xvel, yvel);
|
||||
|
||||
int top = releasedChild.getTop();
|
||||
int settleTop = 0;
|
||||
int topThreshold = (int) (getHeight() * config.getDistanceThreshold());
|
||||
boolean isSideSwiping = Math.abs(xvel) > config.getVelocityThreshold();
|
||||
|
||||
if(yvel > 0){
|
||||
if(Math.abs(yvel) > config.getVelocityThreshold() && !isSideSwiping){
|
||||
settleTop = screenHeight;
|
||||
}else if(top > topThreshold){
|
||||
settleTop = screenHeight;
|
||||
}
|
||||
}else if(yvel == 0){
|
||||
if(top > topThreshold){
|
||||
settleTop = screenHeight;
|
||||
}
|
||||
}
|
||||
|
||||
dragHelper.settleCapturedViewAt(releasedChild.getLeft(), settleTop);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
||||
super.onViewPositionChanged(changedView, left, top, dx, dy);
|
||||
float percent = 1f - ((float)Math.abs(top) / (float) screenHeight);
|
||||
|
||||
if(listener != null) listener.onSlideChange(percent);
|
||||
|
||||
// Update the dimmer alpha
|
||||
applyScrim(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDragStateChanged(int state) {
|
||||
super.onViewDragStateChanged(state);
|
||||
if(listener != null) listener.onStateChanged(state);
|
||||
switch (state){
|
||||
case ViewDragHelper.STATE_IDLE:
|
||||
if(decorView.getTop() == 0){
|
||||
// State Open
|
||||
if(listener != null) listener.onOpened();
|
||||
}else{
|
||||
// State Closed
|
||||
if(listener != null) listener.onClosed();
|
||||
}
|
||||
break;
|
||||
case ViewDragHelper.STATE_DRAGGING:
|
||||
|
||||
break;
|
||||
case ViewDragHelper.STATE_SETTLING:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The drag helper callbacks for dragging the slidr attachment from the bottom of hte screen
|
||||
*/
|
||||
private final ViewDragHelper.Callback bottomCallback = new ViewDragHelper.Callback() {
|
||||
@Override
|
||||
public boolean tryCaptureView(View child, int pointerId) {
|
||||
return child.getId() == decorView.getId() && (!config.isEdgeOnly() || isEdgeTouched);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionVertical(View child, int top, int dy) {
|
||||
return clamp(top, -screenHeight, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewVerticalDragRange(View child) {
|
||||
return screenHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewReleased(View releasedChild, float xvel, float yvel) {
|
||||
super.onViewReleased(releasedChild, xvel, yvel);
|
||||
|
||||
int top = releasedChild.getTop();
|
||||
int settleTop = 0;
|
||||
int topThreshold = (int) (getHeight() * config.getDistanceThreshold());
|
||||
boolean isSideSwiping = Math.abs(xvel) > config.getVelocityThreshold();
|
||||
|
||||
if(yvel < 0){
|
||||
if(Math.abs(yvel) > config.getVelocityThreshold() && !isSideSwiping){
|
||||
settleTop = -screenHeight;
|
||||
}else if(top < -topThreshold){
|
||||
settleTop = -screenHeight;
|
||||
}
|
||||
}else if(yvel == 0){
|
||||
if(top < -topThreshold){
|
||||
settleTop = -screenHeight;
|
||||
}
|
||||
}
|
||||
|
||||
dragHelper.settleCapturedViewAt(releasedChild.getLeft(), settleTop);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
||||
super.onViewPositionChanged(changedView, left, top, dx, dy);
|
||||
float percent = 1f - ((float)Math.abs(top) / (float) screenHeight);
|
||||
|
||||
if(listener != null) listener.onSlideChange(percent);
|
||||
|
||||
// Update the dimmer alpha
|
||||
applyScrim(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDragStateChanged(int state) {
|
||||
super.onViewDragStateChanged(state);
|
||||
if(listener != null) listener.onStateChanged(state);
|
||||
switch (state){
|
||||
case ViewDragHelper.STATE_IDLE:
|
||||
if(decorView.getTop() == 0){
|
||||
// State Open
|
||||
if(listener != null) listener.onOpened();
|
||||
}else{
|
||||
// State Closed
|
||||
if(listener != null) listener.onClosed();
|
||||
}
|
||||
break;
|
||||
case ViewDragHelper.STATE_DRAGGING:
|
||||
|
||||
break;
|
||||
case ViewDragHelper.STATE_SETTLING:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The drag helper callbacks for dragging the slidr attachment in both vertical directions
|
||||
*/
|
||||
private final ViewDragHelper.Callback verticalCallback = new ViewDragHelper.Callback() {
|
||||
@Override
|
||||
public boolean tryCaptureView(View child, int pointerId) {
|
||||
return child.getId() == decorView.getId() && (!config.isEdgeOnly() || isEdgeTouched);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionVertical(View child, int top, int dy) {
|
||||
return clamp(top, -screenHeight, screenHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewVerticalDragRange(View child) {
|
||||
return screenHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewReleased(View releasedChild, float xvel, float yvel) {
|
||||
super.onViewReleased(releasedChild, xvel, yvel);
|
||||
|
||||
int top = releasedChild.getTop();
|
||||
int settleTop = 0;
|
||||
int topThreshold = (int) (getHeight() * config.getDistanceThreshold());
|
||||
boolean isSideSwiping = Math.abs(xvel) > config.getVelocityThreshold();
|
||||
|
||||
if(yvel > 0){
|
||||
|
||||
// Being slinged down
|
||||
if(Math.abs(yvel) > config.getVelocityThreshold() && !isSideSwiping){
|
||||
settleTop = screenHeight;
|
||||
}else if(top > topThreshold){
|
||||
settleTop = screenHeight;
|
||||
}
|
||||
|
||||
}else if(yvel < 0){
|
||||
// Being slinged up
|
||||
if(Math.abs(yvel) > config.getVelocityThreshold() && !isSideSwiping){
|
||||
settleTop = -screenHeight;
|
||||
}else if(top < -topThreshold){
|
||||
settleTop = -screenHeight;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
if(top > topThreshold){
|
||||
settleTop = screenHeight;
|
||||
}else if(top < -topThreshold){
|
||||
settleTop = -screenHeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dragHelper.settleCapturedViewAt(releasedChild.getLeft(), settleTop);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
||||
super.onViewPositionChanged(changedView, left, top, dx, dy);
|
||||
float percent = 1f - ((float)Math.abs(top) / (float) screenHeight);
|
||||
|
||||
if(listener != null) listener.onSlideChange(percent);
|
||||
|
||||
// Update the dimmer alpha
|
||||
applyScrim(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDragStateChanged(int state) {
|
||||
super.onViewDragStateChanged(state);
|
||||
if(listener != null) listener.onStateChanged(state);
|
||||
switch (state){
|
||||
case ViewDragHelper.STATE_IDLE:
|
||||
if(decorView.getTop() == 0){
|
||||
// State Open
|
||||
if(listener != null) listener.onOpened();
|
||||
}else{
|
||||
// State Closed
|
||||
if(listener != null) listener.onClosed();
|
||||
}
|
||||
break;
|
||||
case ViewDragHelper.STATE_DRAGGING:
|
||||
|
||||
break;
|
||||
case ViewDragHelper.STATE_SETTLING:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The drag helper callbacks for dragging the slidr attachment in both horizontal directions
|
||||
*/
|
||||
private final ViewDragHelper.Callback horizontalCallback = new ViewDragHelper.Callback() {
|
||||
@Override
|
||||
public boolean tryCaptureView(View child, int pointerId) {
|
||||
boolean edgeCase = !config.isEdgeOnly() || dragHelper.isEdgeTouched(edgePosition, pointerId);
|
||||
return child.getId() == decorView.getId() && edgeCase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionHorizontal(View child, int left, int dx) {
|
||||
return clamp(left, -screenWidth, screenWidth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewHorizontalDragRange(View child) {
|
||||
return screenWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewReleased(View releasedChild, float xvel, float yvel) {
|
||||
super.onViewReleased(releasedChild, xvel, yvel);
|
||||
|
||||
int left = releasedChild.getLeft();
|
||||
int settleLeft = 0;
|
||||
int leftThreshold = (int) (getWidth() * config.getDistanceThreshold());
|
||||
boolean isVerticalSwiping = Math.abs(yvel) > config.getVelocityThreshold();
|
||||
|
||||
if(xvel > 0){
|
||||
|
||||
if(Math.abs(xvel) > config.getVelocityThreshold() && !isVerticalSwiping){
|
||||
settleLeft = screenWidth;
|
||||
}else if(left > leftThreshold){
|
||||
settleLeft = screenWidth;
|
||||
}
|
||||
|
||||
}else if(xvel < 0){
|
||||
|
||||
if(Math.abs(xvel) > config.getVelocityThreshold() && !isVerticalSwiping){
|
||||
settleLeft = -screenWidth;
|
||||
}else if(left < -leftThreshold){
|
||||
settleLeft = -screenWidth;
|
||||
}
|
||||
|
||||
}else{
|
||||
if(left > leftThreshold){
|
||||
settleLeft = screenWidth;
|
||||
}else if(left < -leftThreshold){
|
||||
settleLeft = -screenWidth;
|
||||
}
|
||||
}
|
||||
|
||||
dragHelper.settleCapturedViewAt(settleLeft, releasedChild.getTop());
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
||||
super.onViewPositionChanged(changedView, left, top, dx, dy);
|
||||
float percent = 1f - ((float)Math.abs(left) / (float) screenWidth);
|
||||
|
||||
if(listener != null) listener.onSlideChange(percent);
|
||||
|
||||
// Update the dimmer alpha
|
||||
applyScrim(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDragStateChanged(int state) {
|
||||
super.onViewDragStateChanged(state);
|
||||
if(listener != null) listener.onStateChanged(state);
|
||||
switch (state){
|
||||
case ViewDragHelper.STATE_IDLE:
|
||||
if(decorView.getLeft() == 0){
|
||||
// State Open
|
||||
if(listener != null) listener.onOpened();
|
||||
}else{
|
||||
// State Closed
|
||||
if(listener != null) listener.onClosed();
|
||||
}
|
||||
break;
|
||||
case ViewDragHelper.STATE_DRAGGING:
|
||||
|
||||
break;
|
||||
case ViewDragHelper.STATE_SETTLING:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private void init(){
|
||||
setWillNotDraw(false);
|
||||
screenWidth = getResources().getDisplayMetrics().widthPixels;
|
||||
|
||||
final float density = getResources().getDisplayMetrics().density;
|
||||
final float minVel = MIN_FLING_VELOCITY * density;
|
||||
|
||||
ViewDragHelper.Callback callback;
|
||||
switch (config.getPosition()){
|
||||
case LEFT:
|
||||
callback = leftCallback;
|
||||
edgePosition = ViewDragHelper.EDGE_LEFT;
|
||||
break;
|
||||
case RIGHT:
|
||||
callback = rightCallback;
|
||||
edgePosition = ViewDragHelper.EDGE_RIGHT;
|
||||
break;
|
||||
case TOP:
|
||||
callback = topCallback;
|
||||
edgePosition = ViewDragHelper.EDGE_TOP;
|
||||
break;
|
||||
case BOTTOM:
|
||||
callback = bottomCallback;
|
||||
edgePosition = ViewDragHelper.EDGE_BOTTOM;
|
||||
break;
|
||||
case VERTICAL:
|
||||
callback = verticalCallback;
|
||||
edgePosition = ViewDragHelper.EDGE_TOP | ViewDragHelper.EDGE_BOTTOM;
|
||||
break;
|
||||
case HORIZONTAL:
|
||||
callback = horizontalCallback;
|
||||
edgePosition = ViewDragHelper.EDGE_LEFT | ViewDragHelper.EDGE_RIGHT;
|
||||
break;
|
||||
default:
|
||||
callback = leftCallback;
|
||||
edgePosition = ViewDragHelper.EDGE_LEFT;
|
||||
}
|
||||
|
||||
dragHelper = ViewDragHelper.create(this, config.getSensitivity(), callback);
|
||||
dragHelper.setMinVelocity(minVel);
|
||||
dragHelper.setEdgeTrackingEnabled(edgePosition);
|
||||
|
||||
ViewGroupCompat.setMotionEventSplittingEnabled(this, false);
|
||||
|
||||
// Setup the dimmer view
|
||||
scrimPaint = new Paint();
|
||||
scrimPaint.setColor(config.getScrimColor());
|
||||
scrimPaint.setAlpha(toAlpha(config.getScrimStartAlpha()));
|
||||
scrimRenderer = new ScrimRenderer(this, decorView);
|
||||
|
||||
/*
|
||||
* This is so we can get the height of the view and
|
||||
* ignore the system navigation that would be included if we
|
||||
* retrieved this value from the DisplayMetrics
|
||||
*/
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
screenHeight = getHeight();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void lock(){
|
||||
dragHelper.abort();
|
||||
isLocked = true;
|
||||
}
|
||||
|
||||
|
||||
private void unlock(){
|
||||
dragHelper.abort();
|
||||
isLocked = false;
|
||||
}
|
||||
|
||||
|
||||
private boolean canDragFromEdge(MotionEvent ev) {
|
||||
float x = ev.getX();
|
||||
float y = ev.getY();
|
||||
|
||||
switch (config.getPosition()) {
|
||||
case LEFT:
|
||||
return x < config.getEdgeSize(getWidth());
|
||||
case RIGHT:
|
||||
return x > getWidth() - config.getEdgeSize(getWidth());
|
||||
case BOTTOM:
|
||||
return y > getHeight() - config.getEdgeSize(getHeight());
|
||||
case TOP:
|
||||
return y < config.getEdgeSize(getHeight());
|
||||
case HORIZONTAL:
|
||||
return x < config.getEdgeSize(getWidth()) || x > getWidth() - config.getEdgeSize(getWidth());
|
||||
case VERTICAL:
|
||||
return y < config.getEdgeSize(getHeight()) || y > getHeight() - config.getEdgeSize(getHeight());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void applyScrim(float percent){
|
||||
float alpha = (percent * (config.getScrimStartAlpha() - config.getScrimEndAlpha())) + config.getScrimEndAlpha();
|
||||
scrimPaint.setAlpha(toAlpha(alpha));
|
||||
invalidate(scrimRenderer.getDirtyRect(config.getPosition()));
|
||||
}
|
||||
|
||||
|
||||
private static int clamp(int value, int min, int max){
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
|
||||
private static int toAlpha(float percentage) {
|
||||
return (int) (percentage * 255);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The panel sliding interface that gets called
|
||||
* whenever the panel is closed or opened
|
||||
*/
|
||||
public interface OnPanelSlideListener{
|
||||
void onStateChanged(int state);
|
||||
void onClosed();
|
||||
void onOpened();
|
||||
void onSlideChange(float percent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item name="slidable_panel" type="id" />
|
||||
<item name="slidable_content" type="id" />
|
||||
</resources>
|
||||
@@ -1 +0,0 @@
|
||||
/build
|
||||
@@ -1,25 +0,0 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdk
|
||||
buildToolsVersion rootProject.ext.buildTools
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.minSdk
|
||||
targetSdkVersion rootProject.ext.targetSdk
|
||||
versionCode rootProject.ext.versionCode
|
||||
versionName rootProject.ext.versionName
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/ybq/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -1 +0,0 @@
|
||||
<manifest package="com.github.ybq.android.spinkit" />
|
||||
@@ -1,121 +0,0 @@
|
||||
package com.github.ybq.android.spinkit;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.github.ybq.android.spinkit.sprite.Sprite;
|
||||
|
||||
/**
|
||||
* Created by ybq.
|
||||
*/
|
||||
public class SpinKitView extends ProgressBar {
|
||||
|
||||
private Style mStyle;
|
||||
private int mColor;
|
||||
private Sprite mSprite;
|
||||
|
||||
public SpinKitView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SpinKitView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.SpinKitViewStyle);
|
||||
}
|
||||
|
||||
public SpinKitView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, R.style.SpinKitView);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public SpinKitView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpinKitView, defStyleAttr,
|
||||
defStyleRes);
|
||||
mStyle = Style.values()[a.getInt(R.styleable.SpinKitView_SpinKit_Style, 0)];
|
||||
mColor = a.getColor(R.styleable.SpinKitView_SpinKit_Color, Color.WHITE);
|
||||
a.recycle();
|
||||
init();
|
||||
setIndeterminate(true);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
Sprite sprite = SpriteFactory.create(mStyle);
|
||||
sprite.setColor(mColor);
|
||||
setIndeterminateDrawable(sprite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndeterminateDrawable(Drawable d) {
|
||||
if (!(d instanceof Sprite)) {
|
||||
throw new IllegalArgumentException("this d must be instanceof Sprite");
|
||||
}
|
||||
setIndeterminateDrawable((Sprite) d);
|
||||
}
|
||||
|
||||
public void setIndeterminateDrawable(Sprite d) {
|
||||
super.setIndeterminateDrawable(d);
|
||||
mSprite = d;
|
||||
if (mSprite.getColor() == 0) {
|
||||
|
||||
mSprite.setColor(mColor);
|
||||
}
|
||||
onSizeChanged(getWidth(), getHeight(), getWidth(), getHeight());
|
||||
if (getVisibility() == VISIBLE) {
|
||||
|
||||
mSprite.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sprite getIndeterminateDrawable() {
|
||||
return mSprite;
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
this.mColor = color;
|
||||
if (mSprite != null) {
|
||||
|
||||
mSprite.setColor(color);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unscheduleDrawable(Drawable who) {
|
||||
super.unscheduleDrawable(who);
|
||||
if (who instanceof Sprite) {
|
||||
|
||||
((Sprite) who).stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasWindowFocus) {
|
||||
super.onWindowFocusChanged(hasWindowFocus);
|
||||
if (hasWindowFocus) {
|
||||
if (mSprite != null && getVisibility() == VISIBLE) {
|
||||
|
||||
mSprite.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenStateChanged(int screenState) {
|
||||
super.onScreenStateChanged(screenState);
|
||||
if (screenState == View.SCREEN_STATE_OFF) {
|
||||
|
||||
if (mSprite != null) {
|
||||
|
||||
mSprite.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.github.ybq.android.spinkit;
|
||||
|
||||
import com.github.ybq.android.spinkit.sprite.Sprite;
|
||||
import com.github.ybq.android.spinkit.style.ChasingDots;
|
||||
import com.github.ybq.android.spinkit.style.Circle;
|
||||
import com.github.ybq.android.spinkit.style.CubeGrid;
|
||||
import com.github.ybq.android.spinkit.style.DoubleBounce;
|
||||
import com.github.ybq.android.spinkit.style.FadingCircle;
|
||||
import com.github.ybq.android.spinkit.style.FoldingCube;
|
||||
import com.github.ybq.android.spinkit.style.MultiplePulse;
|
||||
import com.github.ybq.android.spinkit.style.MultiplePulseRing;
|
||||
import com.github.ybq.android.spinkit.style.Pulse;
|
||||
import com.github.ybq.android.spinkit.style.PulseRing;
|
||||
import com.github.ybq.android.spinkit.style.RotatingCircle;
|
||||
import com.github.ybq.android.spinkit.style.RotatingPlane;
|
||||
import com.github.ybq.android.spinkit.style.ThreeBounce;
|
||||
import com.github.ybq.android.spinkit.style.WanderingCubes;
|
||||
import com.github.ybq.android.spinkit.style.Wave;
|
||||
|
||||
/**
|
||||
* Created by ybq.
|
||||
*/
|
||||
public class SpriteFactory {
|
||||
|
||||
public static Sprite create(Style style) {
|
||||
Sprite sprite = null;
|
||||
switch (style) {
|
||||
case ROTATING_PLANE:
|
||||
sprite = new RotatingPlane();
|
||||
break;
|
||||
case DOUBLE_BOUNCE:
|
||||
sprite = new DoubleBounce();
|
||||
break;
|
||||
case WAVE:
|
||||
sprite = new Wave();
|
||||
break;
|
||||
case WANDERING_CUBES:
|
||||
sprite = new WanderingCubes();
|
||||
break;
|
||||
case PULSE:
|
||||
sprite = new Pulse();
|
||||
break;
|
||||
case CHASING_DOTS:
|
||||
sprite = new ChasingDots();
|
||||
break;
|
||||
case THREE_BOUNCE:
|
||||
sprite = new ThreeBounce();
|
||||
break;
|
||||
case CIRCLE:
|
||||
sprite = new Circle();
|
||||
break;
|
||||
case CUBE_GRID:
|
||||
sprite = new CubeGrid();
|
||||
break;
|
||||
case FADING_CIRCLE:
|
||||
sprite = new FadingCircle();
|
||||
break;
|
||||
case FOLDING_CUBE:
|
||||
sprite = new FoldingCube();
|
||||
break;
|
||||
case ROTATING_CIRCLE:
|
||||
sprite = new RotatingCircle();
|
||||
break;
|
||||
case MULTIPLE_PULSE:
|
||||
sprite = new MultiplePulse();
|
||||
break;
|
||||
case PULSE_RING:
|
||||
sprite = new PulseRing();
|
||||
break;
|
||||
case MULTIPLE_PULSE_RING:
|
||||
sprite = new MultiplePulseRing();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return sprite;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.github.ybq.android.spinkit;
|
||||
|
||||
/**
|
||||
* Created by ybq.
|
||||
*/
|
||||
public enum Style {
|
||||
|
||||
ROTATING_PLANE(0),
|
||||
DOUBLE_BOUNCE(1),
|
||||
WAVE(2),
|
||||
WANDERING_CUBES(3),
|
||||
PULSE(4),
|
||||
CHASING_DOTS(5),
|
||||
THREE_BOUNCE(6),
|
||||
CIRCLE(7),
|
||||
CUBE_GRID(8),
|
||||
FADING_CIRCLE(9),
|
||||
FOLDING_CUBE(10),
|
||||
ROTATING_CIRCLE(11),
|
||||
MULTIPLE_PULSE(12),
|
||||
PULSE_RING(13),
|
||||
MULTIPLE_PULSE_RING(14);
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private int value;
|
||||
|
||||
Style(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.github.ybq.android.spinkit.animation;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
|
||||
import com.github.ybq.android.spinkit.sprite.Sprite;
|
||||
|
||||
/**
|
||||
* Created by ybq.
|
||||
*/
|
||||
public class AnimationUtils {
|
||||
|
||||
public static void start(Animator animator) {
|
||||
if (animator != null && !animator.isStarted()) {
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void stop(Animator animator) {
|
||||
if (animator != null && !animator.isRunning()) {
|
||||
animator.end();
|
||||
}
|
||||
}
|
||||
|
||||
public static void start(Sprite... sprites) {
|
||||
for (Sprite sprite : sprites) {
|
||||
sprite.start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void stop(Sprite... sprites) {
|
||||
for (Sprite sprite : sprites) {
|
||||
sprite.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isRunning(Sprite... sprites) {
|
||||
for (Sprite sprite : sprites) {
|
||||
if (sprite.isRunning()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isRunning(ValueAnimator animator) {
|
||||
return animator != null && animator.isRunning();
|
||||
}
|
||||
|
||||
public static boolean isStarted(ValueAnimator animator) {
|
||||
return animator != null && animator.isStarted();
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.github.ybq.android.spinkit.animation;
|
||||
|
||||
import android.util.Property;
|
||||
|
||||
/**
|
||||
* An implementation of {@link android.util.Property} to be used specifically with fields of type
|
||||
* <code>float</code>. This type-specific subclass enables performance benefit by allowing
|
||||
* calls to a {@link #set(Object, Float) set()} function that takes the primitive
|
||||
* <code>float</code> type and avoids autoboxing and other overhead associated with the
|
||||
* <code>Float</code> class.
|
||||
*
|
||||
* @param <T> The class on which the Property is declared.
|
||||
*/
|
||||
public abstract class FloatProperty<T> extends Property<T, Float> {
|
||||
|
||||
public FloatProperty(String name) {
|
||||
super(Float.class, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* A type-specific override of the {@link #set(Object, Float)} that is faster when dealing
|
||||
* with fields of type <code>float</code>.
|
||||
*/
|
||||
public abstract void setValue(T object, float value);
|
||||
|
||||
@Override
|
||||
final public void set(T object, Float value) {
|
||||
setValue(object, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.github.ybq.android.spinkit.animation;
|
||||
|
||||
import android.util.Property;
|
||||
|
||||
/**
|
||||
* An implementation of {@link android.util.Property} to be used specifically with fields of type
|
||||
* <code>int</code>. This type-specific subclass enables performance benefit by allowing
|
||||
* calls to a {@link #set(Object, Integer) set()} function that takes the primitive
|
||||
* <code>int</code> type and avoids autoboxing and other overhead associated with the
|
||||
* <code>Integer</code> class.
|
||||
*
|
||||
* @param <T> The class on which the Property is declared.
|
||||
*/
|
||||
public abstract class IntProperty<T> extends Property<T, Integer> {
|
||||
|
||||
public IntProperty(String name) {
|
||||
super(Integer.class, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* A type-specific override of the {@link #set(Object, Integer)} that is faster when dealing
|
||||
* with fields of type <code>int</code>.
|
||||
*/
|
||||
public abstract void setValue(T object, int value);
|
||||
|
||||
@Override
|
||||
final public void set(T object, Integer value) {
|
||||
setValue(object, value);
|
||||
}
|
||||
|
||||
}
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
package com.github.ybq.android.spinkit.animation;
|
||||
|
||||
import android.animation.Keyframe;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.util.Log;
|
||||
import android.util.Property;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.github.ybq.android.spinkit.animation.interpolator.KeyFrameInterpolator;
|
||||
import com.github.ybq.android.spinkit.sprite.Sprite;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by ybq.
|
||||
*/
|
||||
public class SpriteAnimatorBuilder {
|
||||
|
||||
private static final String TAG = "SpriteAnimatorBuilder";
|
||||
private Sprite sprite;
|
||||
private Interpolator interpolator;
|
||||
private int repeatCount = Animation.INFINITE;
|
||||
private long duration = 2000;
|
||||
private int startFrame = 0;
|
||||
private Map<String, FrameData> fds = new HashMap<>();
|
||||
|
||||
|
||||
class FrameData<T> {
|
||||
public FrameData(float[] fractions, Property property, T[] values) {
|
||||
this.fractions = fractions;
|
||||
this.property = property;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
float[] fractions;
|
||||
Property property;
|
||||
T[] values;
|
||||
}
|
||||
|
||||
class IntFrameData extends FrameData<Integer> {
|
||||
|
||||
public IntFrameData(float[] fractions, Property property, Integer[] values) {
|
||||
super(fractions, property, values);
|
||||
}
|
||||
}
|
||||
|
||||
class FloatFrameData extends FrameData<Float> {
|
||||
|
||||
public FloatFrameData(float[] fractions, Property property, Float[] values) {
|
||||
super(fractions, property, values);
|
||||
}
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder(Sprite sprite) {
|
||||
this.sprite = sprite;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder scale(float fractions[], Float... scale) {
|
||||
holder(fractions, Sprite.SCALE, scale);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder alpha(float fractions[], Integer... alpha) {
|
||||
holder(fractions, Sprite.ALPHA, alpha);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public SpriteAnimatorBuilder scaleX(float fractions[], Float... scaleX) {
|
||||
holder(fractions, Sprite.SCALE, scaleX);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder scaleY(float fractions[], Float... scaleY) {
|
||||
holder(fractions, Sprite.SCALE_Y, scaleY);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder rotateX(float fractions[], Integer... rotateX) {
|
||||
holder(fractions, Sprite.ROTATE_X, rotateX);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder rotateY(float fractions[], Integer... rotateY) {
|
||||
holder(fractions, Sprite.ROTATE_Y, rotateY);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public SpriteAnimatorBuilder translateX(float fractions[], Integer... translateX) {
|
||||
holder(fractions, Sprite.TRANSLATE_X, translateX);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public SpriteAnimatorBuilder translateY(float fractions[], Integer... translateY) {
|
||||
holder(fractions, Sprite.TRANSLATE_Y, translateY);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public SpriteAnimatorBuilder rotate(float fractions[], Integer... rotate) {
|
||||
holder(fractions, Sprite.ROTATE, rotate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder translateXPercentage(float fractions[], Float... translateXPercentage) {
|
||||
holder(fractions, Sprite.TRANSLATE_X_PERCENTAGE, translateXPercentage);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder translateYPercentage(float[] fractions, Float... translateYPercentage) {
|
||||
holder(fractions, Sprite.TRANSLATE_Y_PERCENTAGE, translateYPercentage);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void holder(float[] fractions, Property property, Float[] values) {
|
||||
ensurePair(fractions.length, values.length);
|
||||
fds.put(property.getName(), new FloatFrameData(fractions, property, values));
|
||||
}
|
||||
|
||||
|
||||
private void holder(float[] fractions, Property property, Integer[] values) {
|
||||
ensurePair(fractions.length, values.length);
|
||||
fds.put(property.getName(), new IntFrameData(fractions, property, values));
|
||||
}
|
||||
|
||||
private void ensurePair(int fractionsLength, int valuesLength) {
|
||||
if (fractionsLength != valuesLength) {
|
||||
throw new IllegalStateException(String.format(
|
||||
Locale.getDefault(),
|
||||
"The fractions.length must equal values.length, " +
|
||||
"fraction.length[%d], values.length[%d]",
|
||||
fractionsLength,
|
||||
valuesLength));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SpriteAnimatorBuilder interpolator(Interpolator interpolator) {
|
||||
this.interpolator = interpolator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder easeInOut(float... fractions) {
|
||||
interpolator(KeyFrameInterpolator.easeInOut(
|
||||
fractions
|
||||
));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public SpriteAnimatorBuilder duration(long duration) {
|
||||
this.duration = duration;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public SpriteAnimatorBuilder repeatCount(int repeatCount) {
|
||||
this.repeatCount = repeatCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpriteAnimatorBuilder startFrame(int startFrame) {
|
||||
if (startFrame < 0) {
|
||||
Log.w(TAG, "startFrame should always be non-negative");
|
||||
startFrame = 0;
|
||||
}
|
||||
this.startFrame = startFrame;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ObjectAnimator build() {
|
||||
|
||||
PropertyValuesHolder[] holders = new PropertyValuesHolder[fds.size()];
|
||||
int i = 0;
|
||||
for (Map.Entry<String, FrameData> fd : fds.entrySet()) {
|
||||
FrameData data = fd.getValue();
|
||||
Keyframe[] keyframes = new Keyframe[data.fractions.length];
|
||||
float[] fractions = data.fractions;
|
||||
float startF = fractions[startFrame];
|
||||
for (int j = startFrame; j < (startFrame + data.values.length); j++) {
|
||||
int key = j - startFrame;
|
||||
int vk = j % data.values.length;
|
||||
float fraction = fractions[vk] - startF;
|
||||
if (fraction < 0) {
|
||||
fraction = fractions[fractions.length - 1] + fraction;
|
||||
}
|
||||
if (data instanceof IntFrameData) {
|
||||
keyframes[key] = Keyframe.ofInt(fraction, (Integer) data.values[vk]);
|
||||
} else if (data instanceof FloatFrameData) {
|
||||
keyframes[key] = Keyframe.ofFloat(fraction, (Float) data.values[vk]);
|
||||
} else {
|
||||
keyframes[key] = Keyframe.ofObject(fraction, data.values[vk]);
|
||||
}
|
||||
}
|
||||
holders[i] = PropertyValuesHolder.ofKeyframe(data.property, keyframes);
|
||||
i++;
|
||||
}
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(sprite,
|
||||
holders);
|
||||
animator.setDuration(duration);
|
||||
animator.setRepeatCount(repeatCount);
|
||||
animator.setInterpolator(interpolator);
|
||||
return animator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.github.ybq.android.spinkit.animation.interpolator;
|
||||
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* Created by ybq.
|
||||
*/
|
||||
public class Ease {
|
||||
public static Interpolator inOut() {
|
||||
return PathInterpolatorCompat.create(0.42f, 0f, 0.58f, 1f);
|
||||
}
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
package com.github.ybq.android.spinkit.animation.interpolator;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* Created by ybq.
|
||||
*/
|
||||
public class KeyFrameInterpolator implements Interpolator {
|
||||
|
||||
private TimeInterpolator interpolator;
|
||||
private float[] fractions;
|
||||
|
||||
|
||||
public static KeyFrameInterpolator easeInOut(float... fractions) {
|
||||
KeyFrameInterpolator interpolator = new KeyFrameInterpolator(Ease.inOut());
|
||||
interpolator.setFractions(fractions);
|
||||
return interpolator;
|
||||
}
|
||||
|
||||
public static KeyFrameInterpolator pathInterpolator(float controlX1, float controlY1,
|
||||
float controlX2, float controlY2,
|
||||
float... fractions) {
|
||||
KeyFrameInterpolator interpolator = new KeyFrameInterpolator(PathInterpolatorCompat.create(controlX1, controlY1, controlX2, controlY2));
|
||||
interpolator.setFractions(fractions);
|
||||
return interpolator;
|
||||
}
|
||||
|
||||
public KeyFrameInterpolator(TimeInterpolator interpolator, float... fractions) {
|
||||
this.interpolator = interpolator;
|
||||
this.fractions = fractions;
|
||||
}
|
||||
|
||||
public void setFractions(float... fractions) {
|
||||
this.fractions = fractions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getInterpolation(float input) {
|
||||
if (fractions.length > 1) {
|
||||
for (int i = 0; i < fractions.length - 1; i++) {
|
||||
float start = fractions[i];
|
||||
float end = fractions[i + 1];
|
||||
float duration = end - start;
|
||||
if (input >= start && input <= end) {
|
||||
input = (input - start) / duration;
|
||||
return start + (interpolator.getInterpolation(input)
|
||||
* duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
return interpolator.getInterpolation(input);
|
||||
}
|
||||
}
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ybq.android.spinkit.animation.interpolator;
|
||||
|
||||
import android.graphics.Path;
|
||||
import android.os.Build;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* Helper for creating path-based {@link Interpolator} instances. On API 21 or newer, the
|
||||
* platform implementation will be used and on older platforms a compatible alternative
|
||||
* implementation will be used.
|
||||
*/
|
||||
public class PathInterpolatorCompat {
|
||||
|
||||
private PathInterpolatorCompat() {
|
||||
// prevent instantiation
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link Interpolator} for an arbitrary {@link Path}. The {@link Path}
|
||||
* must begin at {@code (0, 0)} and end at {@code (1, 1)}. The x-coordinate along the
|
||||
* {@link Path} is the input value and the output is the y coordinate of the line at that
|
||||
* point. This means that the Path must conform to a function {@code y = f(x)}.
|
||||
* <p>
|
||||
* The {@link Path} must not have gaps in the x direction and must not
|
||||
* loop back on itself such that there can be two points sharing the same x coordinate.
|
||||
*
|
||||
* @param path the {@link Path} to use to make the line representing the {@link Interpolator}
|
||||
* @return the {@link Interpolator} representing the {@link Path}
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static Interpolator create(Path path) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return PathInterpolatorCompatApi21.create(path);
|
||||
}
|
||||
return PathInterpolatorCompatBase.create(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link Interpolator} for a quadratic Bezier curve. The end points
|
||||
* {@code (0, 0)} and {@code (1, 1)} are assumed.
|
||||
*
|
||||
* @param controlX the x coordinate of the quadratic Bezier control point
|
||||
* @param controlY the y coordinate of the quadratic Bezier control point
|
||||
* @return the {@link Interpolator} representing the quadratic Bezier curve
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static Interpolator create(float controlX, float controlY) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return PathInterpolatorCompatApi21.create(controlX, controlY);
|
||||
}
|
||||
return PathInterpolatorCompatBase.create(controlX, controlY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link Interpolator} for a cubic Bezier curve. The end points
|
||||
* {@code (0, 0)} and {@code (1, 1)} are assumed.
|
||||
*
|
||||
* @param controlX1 the x coordinate of the first control point of the cubic Bezier
|
||||
* @param controlY1 the y coordinate of the first control point of the cubic Bezier
|
||||
* @param controlX2 the x coordinate of the second control point of the cubic Bezier
|
||||
* @param controlY2 the y coordinate of the second control point of the cubic Bezier
|
||||
* @return the {@link Interpolator} representing the cubic Bezier curve
|
||||
*/
|
||||
public static Interpolator create(float controlX1, float controlY1,
|
||||
float controlX2, float controlY2) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return PathInterpolatorCompatApi21.create(controlX1, controlY1, controlX2, controlY2);
|
||||
}
|
||||
return PathInterpolatorCompatBase.create(controlX1, controlY1, controlX2, controlY2);
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ybq.android.spinkit.animation.interpolator;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Path;
|
||||
import android.os.Build;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
/**
|
||||
* API 21+ implementation for path interpolator compatibility.
|
||||
*/
|
||||
class PathInterpolatorCompatApi21 {
|
||||
|
||||
private PathInterpolatorCompatApi21() {
|
||||
// prevent instantiation
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Interpolator create(Path path) {
|
||||
return new PathInterpolator(path);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Interpolator create(float controlX, float controlY) {
|
||||
return new PathInterpolator(controlX, controlY);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Interpolator create(float controlX1, float controlY1,
|
||||
float controlX2, float controlY2) {
|
||||
return new PathInterpolator(controlX1, controlY1, controlX2, controlY2);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user