From 9031014a6e0e8bdc668c340e4905212f4e989f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladimir=20Jovanovi=C4=87?= Date: Sun, 8 Oct 2017 23:06:26 +0200 Subject: [PATCH] Optimization and cleanup -Total cleanup of base the classes -Reorganisation of the code -Some changes in usage of the library --- .gitignore | 1 + README.md | 10 +- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 0 lemniscate/build.gradle | 16 +- .../lemniscate/ExampleInstrumentedTest.java | 26 - .../lemniscate/BernoullisBowProgressView.java | 11 +- .../lemniscate/BernoullisProgressView.java | 12 +- .../BernoullisSharpProgressView.java | 11 +- .../lemniscate/GeronosProgressView.java | 8 +- .../base/BaseCurveProgressView.java | 493 ++++++------------ .../base/models/AnimationSettings.java | 72 +++ .../lemniscate/base/models/CurveSettings.java | 130 +++++ .../lemniscate/base/models/DrawState.java | 104 ++++ .../lemniscate/base/models/LineLength.java | 80 +++ .../lemniscate/base/models/Point.java | 43 ++ .../lemniscate/base/models/Points.java | 38 ++ .../lemniscate/base/models/ViewSize.java | 38 ++ .../funny/CannabisProgressView.java | 23 +- .../lemniscate/funny/HeartProgressView.java | 17 +- .../lemniscate/other/XProgressView.java | 19 +- .../roulette/BaseRouletteProgressView.java | 131 +---- .../roulette/EpitrochoidProgressView.java | 20 +- .../roulette/HypotrochoidProgressView.java | 21 +- .../models/RouletteCurveSettings.java | 92 ++++ .../scribble/RoundScribbleProgressView.java | 21 +- .../scribble/ScribbleProgressView.java | 21 +- .../vlad1m1r/lemniscate/utils/CurveUtils.java | 34 +- lemniscate/src/main/res/values/attrs.xml | 2 - .../vlad1m1r/lemniscate/ExampleUnitTest.java | 17 - .../vlad1m1r/lemniscate/TestConstants.java | 5 + .../base/models/CurveSettingsTest.java | 47 ++ .../base/models/LineLengthTest.java | 42 ++ .../lemniscate/base/models/PointTest.java | 16 + .../lemniscate/utils/CurveUtilsTest.java | 26 + sample/build.gradle | 14 +- .../sample/ExampleInstrumentedTest.java | 26 - .../lemniscate/sample/FragmentCurve.java | 31 +- .../lemniscate/sample/FragmentSettings.java | 335 +++++------- .../lemniscate/sample/MainActivity.java | 59 ++- .../sample/PresentationActivity.java | 10 +- .../res/drawable-hdpi/ic_action_github.png | Bin .../drawable-hdpi/ic_action_presentation.png | Bin .../res/drawable-mdpi/ic_action_github.png | Bin .../drawable-mdpi/ic_action_presentation.png | Bin .../res/drawable-xhdpi/ic_action_github.png | Bin .../drawable-xhdpi/ic_action_presentation.png | Bin .../res/drawable-xxhdpi/ic_action_github.png | Bin .../ic_action_presentation.png | Bin .../res/drawable-xxxhdpi/ic_action_github.png | Bin .../ic_action_presentation.png | Bin .../res/layout-land/activity_presentation.xml | 90 ++-- .../main/res/layout/activity_presentation.xml | 90 ++-- .../src/main/res/layout/fragment_settings.xml | 69 +-- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../lemniscate/sample/ExampleUnitTest.java | 17 - 61 files changed, 1357 insertions(+), 1039 deletions(-) mode change 100755 => 100644 gradlew delete mode 100644 lemniscate/src/androidTest/java/com/vlad1m1r/lemniscate/ExampleInstrumentedTest.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/AnimationSettings.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/CurveSettings.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/DrawState.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/LineLength.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.java create mode 100644 lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/models/RouletteCurveSettings.java delete mode 100644 lemniscate/src/test/java/com/vlad1m1r/lemniscate/ExampleUnitTest.java create mode 100644 lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.java create mode 100644 lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/CurveSettingsTest.java create mode 100644 lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/LineLengthTest.java create mode 100644 lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/PointTest.java create mode 100644 lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.java delete mode 100644 sample/src/androidTest/java/com/vlad1m1r/lemniscate/sample/ExampleInstrumentedTest.java mode change 100755 => 100644 sample/src/main/res/drawable-hdpi/ic_action_github.png mode change 100755 => 100644 sample/src/main/res/drawable-hdpi/ic_action_presentation.png mode change 100755 => 100644 sample/src/main/res/drawable-mdpi/ic_action_github.png mode change 100755 => 100644 sample/src/main/res/drawable-mdpi/ic_action_presentation.png mode change 100755 => 100644 sample/src/main/res/drawable-xhdpi/ic_action_github.png mode change 100755 => 100644 sample/src/main/res/drawable-xhdpi/ic_action_presentation.png mode change 100755 => 100644 sample/src/main/res/drawable-xxhdpi/ic_action_github.png mode change 100755 => 100644 sample/src/main/res/drawable-xxhdpi/ic_action_presentation.png mode change 100755 => 100644 sample/src/main/res/drawable-xxxhdpi/ic_action_github.png mode change 100755 => 100644 sample/src/main/res/drawable-xxxhdpi/ic_action_presentation.png mode change 100755 => 100644 sample/src/main/res/mipmap-hdpi/ic_launcher.png mode change 100755 => 100644 sample/src/main/res/mipmap-mdpi/ic_launcher.png mode change 100755 => 100644 sample/src/main/res/mipmap-xhdpi/ic_launcher.png mode change 100755 => 100644 sample/src/main/res/mipmap-xxhdpi/ic_launcher.png mode change 100755 => 100644 sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 sample/src/test/java/com/vlad1m1r/lemniscate/sample/ExampleUnitTest.java diff --git a/.gitignore b/.gitignore index f6b286c..650f395 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ captures/ # Intellij *.iml .idea/workspace.xml +.idea/ # Keystore files *.jks diff --git a/README.md b/README.md index 5098b64..e9cc5fe 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Add to your module's build.gradle: and to your app build.gradle: dependencies { - compile 'com.github.vlad1m1r990:Lemniscate:1.2.0' + compile 'com.github.vlad1m1r990:Lemniscate:1.3.0' } Usage @@ -48,8 +48,6 @@ Example of usage: app:duration="1000" app:hasHole="false" app:lineColor="@color/colorPrimary" - app:lineLength="0.6" - app:lineLengthChangeable="true" app:maxLineLength="0.8" app:minLineLength="0.4" app:sizeMultiplier="1" @@ -59,10 +57,8 @@ Example of usage: * **duration** (int) - duration of one animation cycle in millisecondes * **lineColor** (color) - color of the line -* **lineLengthChangeable** (boolean) - if true, the line length will oscillate between maxLineLength and minLineLength -* **lineLength** (float) - length of line (in percentage; 1.0 is full length, 0.5 is half of length) if **lineLengthChangeable** is false -* **maxLineLength** (float) - max length of line (in percentage; 1.0 is full length, 0.5 is half of length) if **lineLengthChangeable** is true -* **minLineLength** (float) - min length of line (in percentage; 1.0 is full length, 0.5 is half of length) if **lineLengthChangeable** is true +* **maxLineLength** (float) - max length of line (in percentage; 1.0 is full length, 0.5 is half of length) +* **minLineLength** (float) - min length of line (in percentage; 1.0 is full length, 0.5 is half of length) * **sizeMultiplier** (float) - default size of view will be multiplied with that number * **strokeWidth** (dimension) - width of line * **precision** (int) - number of points in curve calculated in one cycle diff --git a/build.gradle b/build.gradle index d0aa704..f93d608 100644 --- a/build.gradle +++ b/build.gradle @@ -3,9 +3,10 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.2' + classpath 'com.android.tools.build:gradle:3.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -15,6 +16,7 @@ buildscript { allprojects { repositories { jcenter() + google() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 348503b..a2cc20d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Mar 23 13:44:03 CET 2017 +#Wed Oct 25 23:03:04 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 diff --git a/lemniscate/build.gradle b/lemniscate/build.gradle index d35f53d..4ffcf16 100644 --- a/lemniscate/build.gradle +++ b/lemniscate/build.gradle @@ -1,14 +1,14 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + compileSdkVersion 26 + buildToolsVersion "26.0.2" defaultConfig { - minSdkVersion 11 - targetSdkVersion 25 - versionCode 120 - versionName "1.2.0" + minSdkVersion 14 + targetSdkVersion 26 + versionCode 130 + versionName "1.3.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -24,6 +24,8 @@ dependencies { androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:appcompat-v7:26.1.0' + testCompile 'junit:junit:4.12' + testCompile 'org.mockito:mockito-core:1.10.19' } diff --git a/lemniscate/src/androidTest/java/com/vlad1m1r/lemniscate/ExampleInstrumentedTest.java b/lemniscate/src/androidTest/java/com/vlad1m1r/lemniscate/ExampleInstrumentedTest.java deleted file mode 100644 index 26c9ec2..0000000 --- a/lemniscate/src/androidTest/java/com/vlad1m1r/lemniscate/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.vlad1m1r.lemniscate; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumentation test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.vlad1m1r.lemniscate.sample.lemniscate.test", appContext.getPackageName()); - } -} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.java index ad45b6e..f8ac251 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.java @@ -21,7 +21,6 @@ import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - public class BernoullisBowProgressView extends BaseCurveProgressView { public BernoullisBowProgressView(Context context) { @@ -36,11 +35,13 @@ public BernoullisBowProgressView(Context context, AttributeSet attrs, int defSty super(context, attrs, defStyleAttr); } - public double getGraphY(double t){ - return (mLemniscateParamY * 1.5 * Math.sin(t) * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 6)); + @Override + public float getGraphY(double t){ + return (float) ((viewSize.getSize() * 0.75 * Math.sin(t) * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 6))); } - public double getGraphX(double t){ - return (mLemniscateParamX * 1.5 * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 6)); + @Override + public float getGraphX(double t){ + return (float) ((viewSize.getSize() * 0.75 * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 6))); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.java index 34b1456..27ac889 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.java @@ -21,8 +21,6 @@ import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - - public class BernoullisProgressView extends BaseCurveProgressView { public BernoullisProgressView(Context context) { @@ -37,11 +35,13 @@ public BernoullisProgressView(Context context, AttributeSet attrs, int defStyleA super(context, attrs, defStyleAttr); } - public double getGraphY(double t){ - return (mLemniscateParamY * Math.sin(t) * Math.cos(t)) / (1 + Math.pow(Math.sin(t), 2)); + @Override + public float getGraphY(double t){ + return (float) ((viewSize.getSize() / 2 * Math.sin(t) * Math.cos(t)) / (1 + Math.pow(Math.sin(t), 2))); } - public double getGraphX(double t){ - return (mLemniscateParamX * Math.cos(t)) / (1 + Math.pow(Math.sin(t), 2)); + @Override + public float getGraphX(double t){ + return (float) ((viewSize.getSize() / 2 * Math.cos(t)) / (1 + Math.pow(Math.sin(t), 2))); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.java index fa8bad2..eb9443b 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.java @@ -21,7 +21,6 @@ import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - public class BernoullisSharpProgressView extends BaseCurveProgressView { public BernoullisSharpProgressView(Context context) { @@ -36,11 +35,13 @@ public BernoullisSharpProgressView(Context context, AttributeSet attrs, int defS super(context, attrs, defStyleAttr); } - public double getGraphY(double t){ - return (mLemniscateParamY * 2 * Math.sin(t) * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 2)); + @Override + public float getGraphY(double t){ + return (float) ((viewSize.getSize() * Math.sin(t) * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 2))); } - public double getGraphX(double t){ - return (mLemniscateParamX * 2 * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 2)); + @Override + public float getGraphX(double t){ + return (float) ((viewSize.getSize() * Math.cos(t)) / (1 + Math.pow(Math.cos(t), 2))); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.java index 985efc3..0f0f47d 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.java @@ -36,12 +36,12 @@ public GeronosProgressView(Context context, AttributeSet attrs, int defStyleAttr } @Override - public double getGraphY(double t) { - return mLemniscateParamX * Math.sin(t) * Math.cos(t); + public float getGraphY(double t) { + return (float) (viewSize.getSize() / 2 * Math.sin(t) * Math.cos(t)); } @Override - public double getGraphX(double t) { - return mLemniscateParamX * Math.sin(t); + public float getGraphX(double t) { + return (float) (viewSize.getSize() / 2 * Math.sin(t)); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.java index 3ccd306..24a3fd5 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.java @@ -21,109 +21,30 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; import android.os.Parcel; import android.os.Parcelable; -import android.support.annotation.Nullable; import android.util.AttributeSet; -import android.util.Pair; import android.view.View; import android.view.animation.LinearInterpolator; +import com.vlad1m1r.lemniscate.base.models.AnimationSettings; +import com.vlad1m1r.lemniscate.base.models.CurveSettings; +import com.vlad1m1r.lemniscate.base.models.DrawState; +import com.vlad1m1r.lemniscate.base.models.Point; +import com.vlad1m1r.lemniscate.base.models.Points; +import com.vlad1m1r.lemniscate.base.models.ViewSize; import com.vlad1m1r.lemniscate.sample.lemniscate.R; -import com.vlad1m1r.lemniscate.utils.CurveUtils; -import java.util.ArrayList; +public abstract class BaseCurveProgressView extends View { -public abstract class BaseCurveProgressView extends View { + protected T curveSettings; + protected AnimationSettings animationSettings = new AnimationSettings(); + protected DrawState drawState = new DrawState(); + protected ViewSize viewSize = new ViewSize(); + protected Points points = new Points(); - - /** - * This means that on every animation step curve will become shorter (or longer depending on mIsExpanding) - * for mPrecision * STEP_SIZE - */ - protected static float STEP_SIZE = 0.001f; - - /** - * Number of points drawn in one full cycle - */ - protected int mPrecision = 200; - - protected float mStrokeWidth = getResources().getDimension(R.dimen.lemniscate_stroke_width); - - /** - * Default size of view will be multiplied with this number - */ - protected float mSizeMultiplier = 1; - - protected double mLemniscateParamX, mLemniscateParamY; - - /** - * If length is fixed (mIsLineLengthChangeable == false) than line length will always be - * equal to this value - */ - protected float mLineLength = 0.6f; - - /** - * If length is not fixed than it will be changing between these values - */ - protected float mLineMinLength = 0.4f, mLineMaxLength = 0.8f; - - /** - * If true, the line length will oscillate between mLineMinLength and mLineMaxLength - */ - protected boolean mIsLineLengthChangeable = true; - - /** - * Line color - */ - protected int mColor = Color.GRAY; - - /** - * duration of one cycle of animation in milliseconds - */ - protected long mDuration = 1000; - - - /** - * creates illusion that line is going under itself - * should be used when line is longer than 600 - */ - protected boolean mHasHole = false; - - /** - * point from which animation will start - */ - protected int mStart = 0; - - - protected Paint mPaint; - - /** - * Width of full view without padding - */ - protected float mViewWidth; - /** - * Height of full view without padding - */ - protected float mViewHeight; - protected ValueAnimator mValueAnimator; - - /** - * interpolator of animation - */ - protected TimeInterpolator mInterpolator = new LinearInterpolator(); - - /** - * is line in shrinking or expanding phase - */ - protected boolean mIsExpanding = true; - - - private final Path mPath = new Path(); - private final ArrayList> mListOfPoints = new ArrayList<>(); + private ValueAnimator valueAnimator; + private TimeInterpolator interpolator = new LinearInterpolator(); public BaseCurveProgressView(Context context) { super(context); @@ -132,32 +53,30 @@ public BaseCurveProgressView(Context context) { public BaseCurveProgressView(Context context, AttributeSet attrs) { super(context, attrs); - TypedArray a = context.getTheme().obtainStyledAttributes( + + init(); + + TypedArray curveAttributes = context.getTheme().obtainStyledAttributes( attrs, R.styleable.BaseCurveProgressView, 0, 0); - TypedArray b = context.obtainStyledAttributes(attrs, new int[] { R.attr.colorAccent }); + TypedArray colorAccentAttributes = context.obtainStyledAttributes(attrs, new int[] { R.attr.colorAccent }); try { - int colorAccent = b.getColor(0, 0); - - setLineMinLength(a.getFloat(R.styleable.BaseCurveProgressView_minLineLength, mLineMinLength)); - setLineMaxLength(a.getFloat(R.styleable.BaseCurveProgressView_maxLineLength, mLineMaxLength)); - setLineLength(a.getFloat(R.styleable.BaseCurveProgressView_lineLength, mLineLength)); - setIsLineLengthChangeable(a.getBoolean(R.styleable.BaseCurveProgressView_lineLengthChangeable, true)); - setColor(a.getColor(R.styleable.BaseCurveProgressView_lineColor, colorAccent)); - setDuration(a.getInteger(R.styleable.BaseCurveProgressView_duration, 1000)); - setHasHole(a.getBoolean(R.styleable.BaseCurveProgressView_hasHole, false)); - setStrokeWidth(a.getDimension(R.styleable.BaseCurveProgressView_strokeWidth, getResources().getDimension(R.dimen.lemniscate_stroke_width))); - setSizeMultiplier(a.getFloat(R.styleable.BaseCurveProgressView_sizeMultiplier, 1)); - setPrecision(a.getInteger(R.styleable.BaseCurveProgressView_precision, mPrecision)); + int colorAccent = colorAccentAttributes.getColor(0, 0); + + setLineMinLength(curveAttributes.getFloat(R.styleable.BaseCurveProgressView_minLineLength, 0.4f)); + setLineMaxLength(curveAttributes.getFloat(R.styleable.BaseCurveProgressView_maxLineLength, 0.8f)); + setColor(curveAttributes.getColor(R.styleable.BaseCurveProgressView_lineColor, colorAccent)); + setDuration(curveAttributes.getInteger(R.styleable.BaseCurveProgressView_duration, 1000)); + setHasHole(curveAttributes.getBoolean(R.styleable.BaseCurveProgressView_hasHole, false)); + setStrokeWidth(curveAttributes.getDimension(R.styleable.BaseCurveProgressView_strokeWidth, getResources().getDimension(R.dimen.lemniscate_stroke_width))); + setPrecision(curveAttributes.getInteger(R.styleable.BaseCurveProgressView_precision, 200)); } finally { - a.recycle(); - b.recycle(); + curveAttributes.recycle(); + colorAccentAttributes.recycle(); } - - init(); } public BaseCurveProgressView(Context context, AttributeSet attrs, int defStyleAttr) { @@ -165,156 +84,123 @@ public BaseCurveProgressView(Context context, AttributeSet attrs, int defStyleAt init(); } - private void init() { - mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mPaint.setColor(mColor); - mPaint.setStyle(Paint.Style.STROKE); - mPaint.setStrokeWidth(mStrokeWidth); - mPaint.setStrokeCap(Paint.Cap.ROUND); + protected void init() { + curveSettings = getCurveSettings(); + } + + protected T getCurveSettings() { + return (T) new CurveSettings(); } /** * This method should return values of y for t∈[0, upper limit of getT() function]. * We should use parametric representation of curve for y. * Curve should be closed and periodic on interval that returns getT(). - * Resulting value should satisfy y∈[-mLemniscateParamY, mLemniscateParamY]. + * Resulting value should satisfy y∈[-viewSize.getHeight()/2, viewSize.getHeight()/2]. */ - public abstract double getGraphY(double t); + public abstract float getGraphY(double t); /** * This method should return values of x for t∈[0, upper limit of getT() function]. * We should use parametric representation of curve for x. * Curve should be closed and periodic on interval that returns getT(). - * Resulting value should satisfy x∈[-mLemniscateParamX, upper limit of getT() function]. + * Resulting value should satisfy x∈[-viewSize.getWidth()/2, viewSize.getWidth()/2]. */ - public abstract double getGraphX(double t); + public abstract float getGraphX(double t); @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - //TODO: mListOfPoints should be removed and everything should be done just with @param mPath - - createListOfPoints(); - addPointsToPath(); + recreatePoints(); + drawState.addPointsToPath(points.getPoints(), curveSettings, viewSize); + canvas.drawPath(drawState.getPath(), curveSettings.getPaint()); + } - canvas.drawPath(mPath, mPaint); + private void recreatePoints() { + points.clear(); + createNewPoints(); } - private void createListOfPoints() { - int lineLengthToDraw = Math.round(mPrecision * mLineLength); - boolean firstPass = true; - mListOfPoints.clear(); + private void createNewPoints() { + int lineLengthToDraw = getLineLengthToDraw(); // creates points from mStart till mLineLength points is created, or till mPrecision is reached in first pass // if there is more points to be created goes to second pass while (lineLengthToDraw > 0) { - if(firstPass) { - lineLengthToDraw = getPointsOnCurve(mListOfPoints, mStart, lineLengthToDraw); - firstPass = false; - } else { - lineLengthToDraw = getPointsOnCurve(mListOfPoints, 0, lineLengthToDraw); - } + lineLengthToDraw = addPointsToCurve( + points.isEmpty() ? animationSettings.getStartingPointOnCurve() : 0, + lineLengthToDraw + ); } } - private void addPointsToPath() { - mPath.reset(); - - float holeSize = mStrokeWidth; //Math.max(mStrokeWidth, 10); - - //adds points to path and creates hole if mHasHole - for (int i = 0; i < mListOfPoints.size(); i++) { - Pair start = mListOfPoints.get(i); - Pair end = null; - - - if(mListOfPoints.size() > i + 1) - end = mListOfPoints.get(i + 1); - - if(mHasHole) { - if(start!= null && end != null && start.first > end.first) { - start = CurveUtils.checkPointForHole(start, holeSize, mViewHeight, mViewWidth); - end = CurveUtils.checkPointForHole(end, holeSize, mViewHeight, mViewWidth); - } - } - CurveUtils.addPointsToPath(start, end, mPath); - } + private int getLineLengthToDraw() { + return Math.round(curveSettings.getPrecision() * drawState.getCurrentLineLength()); } - private int getPointsOnCurve(ArrayList> list, @Nullable Integer start, int leftPoints) { - for (int i = start != null ? start : 0; i < mPrecision; i++) { + private int addPointsToCurve(Integer start, int remainingPoints) { + for (int i = start; i < curveSettings.getPrecision(); i++) { - // translates points to positive coordinates - double x = getGraphX(getT(i)) + mLemniscateParamX; - double y = getGraphY(getT(i)) + mLemniscateParamY; + points.addPoint(getPoint(i)); - addPointToList(list, x, y); - - //removes number of points left to draw and checks is there any to be drawn - leftPoints--; - if (leftPoints == 0) { - return leftPoints; + if (--remainingPoints == 0) { + return remainingPoints; } } - return leftPoints; + return remainingPoints; } - private void addPointToList(ArrayList> list, double x, double y) { - - //finds smallest ratio for which curve should be resized because of stroke width - float ratio = mViewHeight/(mViewHeight + 2 * mStrokeWidth); - - //move every point for ratio - x = x * ratio; - y = y * ratio; - - //moves points so that curve is centered - x = x + mStrokeWidth * ratio; - y = y + mStrokeWidth * ratio; - - list.add(new Pair<>((float) x, (float) y)); + private Point getPoint(int i) { + return new Point( + getGraphX(getT(i)), + getGraphY(getT(i)), + curveSettings.getStrokeWidth(), + viewSize.getSize() + ); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - float desiredWidth = getResources().getDimension(R.dimen.lemniscate_preferred_width) * mSizeMultiplier; - float desiredHeight = getResources().getDimension(R.dimen.lemniscate_preferred_height) * mSizeMultiplier; + float defaultSize = getResources().getDimension(R.dimen.lemniscate_preferred_height) * viewSize.getSizeMultiplier(); - int xPad = getPaddingLeft() + getPaddingRight(); - int yPad = getPaddingTop() + getPaddingBottom(); + int xPadding = getPaddingLeft() + getPaddingRight(); + int yPadding = getPaddingTop() + getPaddingBottom(); - int viewSize = Math.min(getMeasuredHeight() - yPad, getMeasuredWidth() - xPad); + int viewSize = getMaxViewSquareSize( + getMeasuredHeight(), + getMeasuredWidth(), + xPadding, + yPadding + ); - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int heightMode = MeasureSpec.getMode(heightMeasureSpec); + this.viewSize.setSize( + getViewDimension( + MeasureSpec.getMode(widthMeasureSpec), + viewSize, + defaultSize + ) + ); - if (widthMode == MeasureSpec.EXACTLY) { - mViewWidth = viewSize; - } else if (widthMode == MeasureSpec.AT_MOST) { - mViewWidth = Math.min(desiredWidth, viewSize); - } else { - mViewWidth = desiredWidth; - } + setMeasuredDimension(Math.round(this.viewSize.getSize() + xPadding), Math.round(this.viewSize.getSize() + yPadding)); + } + + private static int getMaxViewSquareSize(int height, int width, int xPadding, int yPadding) { + return Math.min(height - yPadding, width - xPadding); + } - if (heightMode == MeasureSpec.EXACTLY) { - mViewHeight = viewSize; - } else if (heightMode == MeasureSpec.AT_MOST) { - //Can't be bigger than... - mViewHeight = Math.min(desiredHeight, viewSize); + private static float getViewDimension(int mode, float viewSize, float defaultSize) { + if (mode == MeasureSpec.EXACTLY) { + return viewSize; + } else if (mode == MeasureSpec.AT_MOST) { + return Math.min(defaultSize, viewSize); } else { - mViewHeight = desiredHeight; + return defaultSize; } - - mLemniscateParamX = mViewWidth/2; - mLemniscateParamY = mViewHeight/2; - - setMeasuredDimension(Math.round(mViewWidth + xPad), Math.round(mViewHeight + yPad)); } - @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); @@ -327,61 +213,35 @@ protected void onAttachedToWindow() { } private void animateLemniscate() { - if(mValueAnimator != null) mValueAnimator.end(); - mValueAnimator = ValueAnimator.ofInt(mPrecision, 0); - mValueAnimator.setDuration(mDuration); - mValueAnimator.setRepeatCount(-1); - mValueAnimator.setRepeatMode(ValueAnimator.RESTART); - mValueAnimator.setInterpolator(mInterpolator); - mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + if(valueAnimator != null) valueAnimator.end(); + valueAnimator = ValueAnimator.ofInt(curveSettings.getPrecision() - 1, 0); + valueAnimator.setDuration(animationSettings.getDuration()); + valueAnimator.setRepeatCount(-1); + valueAnimator.setRepeatMode(ValueAnimator.RESTART); + valueAnimator.setInterpolator(interpolator); + valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - mStart = (Integer) animation.getAnimatedValue(); - recalculateLineLength(); + animationSettings.setStartingPointOnCurve((Integer) animation.getAnimatedValue()); + drawState.recalculateLineLength(curveSettings.getLineLength()); invalidate(); } }); - mValueAnimator.start(); - } - - private void recalculateLineLength() { - if (mIsLineLengthChangeable && mLineMinLength < mLineMaxLength) { - if (mLineLength < mLineMinLength) mLineLength = mLineMinLength; - if (mLineLength > mLineMaxLength) mLineLength = mLineMaxLength; - if (mLineLength < mLineMaxLength && mIsExpanding) { - mLineLength+=STEP_SIZE; - } else if (mLineLength > mLineMinLength && !mIsExpanding) { - mLineLength-=STEP_SIZE; - } else if (mLineLength >= mLineMaxLength) { - mIsExpanding = false; - } else if (mLineLength <= mLineMinLength) { - mIsExpanding = true; - } - } + valueAnimator.start(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - mValueAnimator.end(); + valueAnimator.end(); } @Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); - BaseCurveSavedState ss = new BaseCurveSavedState(superState); - - ss.strokeWidth = this.mStrokeWidth; - ss.sizeMultiplier = this.mSizeMultiplier; - ss.lineLength = this.mLineLength; - ss.lineMinLength = this.mLineMinLength; - ss.lineMaxLength = this.mLineMaxLength; - ss.isLineLengthChangeable = this.mIsLineLengthChangeable; - ss.color = this.mColor; - ss.duration = this.mDuration; - ss.hasHole = this.mHasHole; - ss.precision = this.mPrecision; - + BaseCurveSavedState ss = new BaseCurveSavedState(superState); + ss.curveSettings = curveSettings; + ss.animationSettings = animationSettings; return ss; } @@ -392,33 +252,23 @@ public void onRestoreInstanceState(Parcelable state) { return; } - BaseCurveSavedState ss = (BaseCurveSavedState)state; + BaseCurveSavedState ss = (BaseCurveSavedState)state; super.onRestoreInstanceState(ss.getSuperState()); - //end - - setStrokeWidth(ss.strokeWidth); - setSizeMultiplier(ss.sizeMultiplier); - setLineLength(ss.lineLength); - setLineMinLength(ss.lineMinLength); - setLineMaxLength(ss.lineMaxLength); - setIsLineLengthChangeable(ss.isLineLengthChangeable); - setColor(ss.color); - setDuration((int)ss.duration); - setHasHole(ss.hasHole); - setPrecision(ss.precision); - } - - protected static class BaseCurveSavedState extends BaseSavedState { - float strokeWidth; - float sizeMultiplier; - float lineLength; - float lineMinLength; - float lineMaxLength; - boolean isLineLengthChangeable; - int color; - long duration; - boolean hasHole; - int precision; + + this.curveSettings = ss.curveSettings; + this.animationSettings = ss.animationSettings; + } + + public void setSizeMultiplier(float multiplier) { + this.viewSize.setSizeMultiplier(multiplier); + requestLayout(); + invalidate(); + } + + protected static class BaseCurveSavedState extends BaseSavedState { + T curveSettings; + AnimationSettings animationSettings; + public BaseCurveSavedState(Parcelable superState) { super(superState); @@ -426,31 +276,16 @@ public BaseCurveSavedState(Parcelable superState) { public BaseCurveSavedState(Parcel in) { super(in); - this.strokeWidth = in.readFloat(); - this.sizeMultiplier = in.readFloat(); - this.lineLength = in.readFloat(); - this.lineMinLength = in.readFloat(); - this.lineMaxLength = in.readFloat(); - this.isLineLengthChangeable = in.readByte() != 0; - this.color = in.readInt(); - this.duration = in.readLong(); - this.hasHole = in.readByte() != 0; - this.precision = in.readInt(); + ClassLoader classLoader = this.curveSettings.getClass().getClassLoader(); + this.curveSettings = in.readParcelable(classLoader); + this.animationSettings = in.readParcelable(AnimationSettings.class.getClassLoader()); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); - out.writeFloat(this.strokeWidth); - out.writeFloat(this.sizeMultiplier); - out.writeFloat(this.lineLength); - out.writeFloat(this.lineMinLength); - out.writeFloat(this.lineMaxLength); - out.writeByte((byte) (isLineLengthChangeable ? 1 : 0)); - out.writeInt(this.color); - out.writeLong(this.duration); - out.writeByte((byte) (hasHole ? 1 : 0)); - out.writeInt(this.precision); + out.writeParcelable(this.curveSettings, flags); + out.writeParcelable(this.animationSettings, flags); } public static final Parcelable.Creator CREATOR = @@ -466,99 +301,69 @@ public BaseCurveSavedState[] newArray(int size) { public void setLineMinLength(float lineMinLength) { - if (lineMinLength > 0 && lineMinLength <= 1) mLineMinLength = lineMinLength; + curveSettings.getLineLength().setLineMinLength(lineMinLength); } public void setLineMaxLength(float lineMaxLength) { - if (lineMaxLength > 0 && lineMaxLength <= 1) mLineMaxLength = lineMaxLength; - } - - public void setLineLength(float lineLength) { - if (lineLength > 0 && lineLength <= 1) mLineLength = lineLength; - } - - public void setIsLineLengthChangeable(boolean lineLengthChangeable) { - mIsLineLengthChangeable = lineLengthChangeable; - } - - public void setInterpolator(TimeInterpolator interpolator) { - mInterpolator = interpolator; + curveSettings.getLineLength().setLineMaxLength(lineMaxLength); } public void setColor(int color) { - mColor = color; - if(mPaint != null) mPaint.setColor(mColor); + curveSettings.setColor(color); } public void setDuration(int duration) { - mDuration = duration; - if(mValueAnimator != null) mValueAnimator.setDuration(mDuration); + animationSettings.setDuration(duration); + if(valueAnimator != null) valueAnimator.setDuration(duration); } public void setHasHole(boolean hasHole) { - mHasHole = hasHole; + curveSettings.setHasHole(hasHole); } public void setStrokeWidth(float strokeWidth) { - if(strokeWidth > 0) { - mStrokeWidth = strokeWidth; - if (mPaint != null) mPaint.setStrokeWidth(mStrokeWidth); - } - } - - public void setSizeMultiplier(float sizeMultiplier) { - mSizeMultiplier = sizeMultiplier; - requestLayout(); - invalidate(); + curveSettings.setStrokeWidth(strokeWidth); } public float getStrokeWidth() { - return mStrokeWidth; + return curveSettings.getStrokeWidth(); } public float getLineMinLength() { - return mLineMinLength; - } - - public float getLineLength() { - return mLineLength; + return curveSettings.getLineLength().getLineMinLength(); } public float getLineMaxLength() { - return mLineMaxLength; - } - - public boolean isHasHole() { - return mHasHole; + return curveSettings.getLineLength().getLineMaxLength(); } - public boolean isLineLengthChangeable() { - return mIsLineLengthChangeable; + public boolean hasHole() { + return curveSettings.hasHole(); } public int getColor() { - return mColor; + return curveSettings.getColor(); } public long getDuration() { - return mDuration; + return animationSettings.getDuration(); } public int getPrecision() { - return mPrecision; + return curveSettings.getPrecision(); } public void setPrecision(int precision) { - mPrecision = precision; + curveSettings.setPrecision(precision); animateLemniscate(); invalidate(); } /** * @param i ∈ [0, mPrecision) - * @return function is putting i∈[0, mPrecision) points between [0, 2π] + * @return function is putting i∈[0, curveSettings.getPrecision()) points between [0, 2π] */ protected double getT(int i) { - return i*2*Math.PI/mPrecision; + return i*2*Math.PI/curveSettings.getPrecision(); } } \ No newline at end of file diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/AnimationSettings.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/AnimationSettings.java new file mode 100644 index 0000000..a4b1ff0 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/AnimationSettings.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 Vladimir Jovanovic + * + * 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.vlad1m1r.lemniscate.base.models; + +import android.os.Parcel; +import android.os.Parcelable; + +public class AnimationSettings implements Parcelable { + + private int startingPointOnCurve = 0; + private long duration = 1000; + + public AnimationSettings() { + } + + protected AnimationSettings(Parcel in) { + this.startingPointOnCurve = in.readInt(); + this.duration = in.readLong(); + } + + public int getStartingPointOnCurve() { + return startingPointOnCurve; + } + + public void setStartingPointOnCurve(int startingPointOnCurve) { + this.startingPointOnCurve = startingPointOnCurve; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public AnimationSettings createFromParcel(Parcel source) { + return new AnimationSettings(source); + } + + @Override + public AnimationSettings[] newArray(int size) { + return new AnimationSettings[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(this.startingPointOnCurve); + dest.writeLong(this.duration); + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/CurveSettings.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/CurveSettings.java new file mode 100644 index 0000000..27a3252 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/CurveSettings.java @@ -0,0 +1,130 @@ +/* + * Copyright 2016 Vladimir Jovanovic + * + * 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.vlad1m1r.lemniscate.base.models; + +import android.graphics.Paint; +import android.os.Parcel; +import android.os.Parcelable; + +public class CurveSettings implements Parcelable { + + private final Paint paint; + private int precision = 200; + private float strokeWidth; + private int color; + private LineLength lineLength; + private boolean hasHole = false; + + public CurveSettings(Paint paint, LineLength lineLength) { + this.paint = paint; + this.lineLength = lineLength; + } + + public CurveSettings() { + this(new Paint( + Paint.ANTI_ALIAS_FLAG){{ + setStyle(Paint.Style.STROKE); + setStrokeCap(Paint.Cap.ROUND); + }}, + new LineLength() + ); + } + + protected CurveSettings(Parcel in) { + this(); + this.precision = in.readInt(); + this.strokeWidth = in.readFloat(); + this.color = in.readInt(); + this.lineLength = in.readParcelable(LineLength.class.getClassLoader()); + this.hasHole = in.readByte() != 0; + } + + public int getPrecision() { + return precision; + } + + public void setPrecision(int precision) { + this.precision = precision; + } + + public float getStrokeWidth() { + return strokeWidth; + } + + public void setStrokeWidth(float strokeWidth) { + if (strokeWidth >= 0) { + this.strokeWidth = strokeWidth; + this.paint.setStrokeWidth(this.strokeWidth); + } else { + throw new IllegalArgumentException("\'strokeWidth\' must be positive!"); + } + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + paint.setColor(this.color); + } + + public LineLength getLineLength() { + return lineLength; + } + + public void setLineLength(LineLength lineLength) { + this.lineLength = lineLength; + } + + public boolean hasHole() { + return hasHole; + } + + public void setHasHole(boolean hasHole) { + this.hasHole = hasHole; + } + + public Paint getPaint() { + return paint; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public CurveSettings createFromParcel(Parcel source) { + return new CurveSettings(source); + } + + @Override + public CurveSettings[] newArray(int size) { + return new CurveSettings[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(this.precision); + dest.writeFloat(this.strokeWidth); + dest.writeInt(this.color); + dest.writeParcelable(this.lineLength, flags); + dest.writeByte(this.hasHole ? (byte) 1 : (byte) 0); + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/DrawState.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/DrawState.java new file mode 100644 index 0000000..73e8d31 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/DrawState.java @@ -0,0 +1,104 @@ +/* + * Copyright 2016 Vladimir Jovanovic + * + * 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.vlad1m1r.lemniscate.base.models; + +import android.graphics.Path; + +import com.vlad1m1r.lemniscate.utils.CurveUtils; + +import java.util.List; + +public class DrawState { + + public static float STEP_SIZE = 0.001f; + private final Path path = new Path(); + + private boolean isExpanding = true; + private float currentLineLength; + + public float getCurrentLineLength() { + return currentLineLength; + } + + public Path getPath() { + return path; + } + + + private void addPairOfPointsToPath(Point start, Point end) { + if (start != null && end != null) { + path.moveTo(start.x(), start.y()); + path.quadTo(start.x(), start.y(), end.x(), end.y()); + } else if (start != null) { + path.moveTo(start.x(), start.y()); + path.lineTo(start.x(), start.y()); + } else if (end != null) { + path.moveTo(end.x(), end.y()); + } + } + + public void addPointsToPath(List listOfPoints, CurveSettings curveSettings, ViewSize viewSize) { + resetPath(); + + float holeSize = curveSettings.getStrokeWidth(); //Math.max(mStrokeWidth, 10); + + //adds points to path and creates hole if mHasHole + for (int i = 0; i < listOfPoints.size(); i++) { + Point start = listOfPoints.get(i); + Point end = null; + + + if(listOfPoints.size() > i + 1) + end = listOfPoints.get(i + 1); + + if(curveSettings.hasHole()) { + if(start!= null && end != null && start.x() > end.x()) { + start = CurveUtils.checkPointForHole(start, holeSize, viewSize.getSize()); + end = CurveUtils.checkPointForHole(end, holeSize, viewSize.getSize()); + } + } + + addPairOfPointsToPath(start, end); + } + } + + private void resetPath() { + path.reset(); + } + + public void recalculateLineLength(LineLength lineLength) { + if (lineLength.getLineMinLength() < lineLength.getLineMaxLength()) { + if (currentLineLength < lineLength.getLineMinLength()) { + currentLineLength = lineLength.getLineMinLength(); + } + if (currentLineLength > lineLength.getLineMaxLength()) { + currentLineLength = lineLength.getLineMaxLength(); + } + + if (currentLineLength < lineLength.getLineMaxLength() && isExpanding) { + currentLineLength += STEP_SIZE; + } else if (currentLineLength > lineLength.getLineMinLength() && !isExpanding) { + currentLineLength -= STEP_SIZE; + } else if (currentLineLength >= lineLength.getLineMaxLength()) { + isExpanding = false; + } else if (currentLineLength <= lineLength.getLineMinLength()) { + isExpanding = true; + } + } else { + currentLineLength = lineLength.getLineMaxLength(); + } + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/LineLength.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/LineLength.java new file mode 100644 index 0000000..464a09a --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/LineLength.java @@ -0,0 +1,80 @@ +/* + * Copyright 2016 Vladimir Jovanovic + * + * 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.vlad1m1r.lemniscate.base.models; + +import android.os.Parcel; +import android.os.Parcelable; + +public class LineLength implements Parcelable { + + private float lineMinLength = 0.4f; + private float lineMaxLength = 0.8f; + + public LineLength() { + } + + protected LineLength(Parcel in) { + this.lineMinLength = in.readFloat(); + this.lineMaxLength = in.readFloat(); + } + + public float getLineMinLength() { + return lineMinLength; + } + + public void setLineMinLength(float lineMinLength) { + if (lineMinLength > 0 && lineMinLength <= 1) { + this.lineMinLength = lineMinLength; + } else { + throw new IllegalArgumentException(); + } + } + + public float getLineMaxLength() { + return lineMaxLength; + } + + public void setLineMaxLength(float lineMaxLength) { + if (lineMaxLength > 0 && lineMaxLength <= 1) { + this.lineMaxLength = lineMaxLength; + } else { + throw new IllegalArgumentException(); + } + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LineLength createFromParcel(Parcel source) { + return new LineLength(source); + } + + @Override + public LineLength[] newArray(int size) { + return new LineLength[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeFloat(this.lineMinLength); + dest.writeFloat(this.lineMaxLength); + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.java new file mode 100644 index 0000000..d887678 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.java @@ -0,0 +1,43 @@ +/* + * Copyright 2016 Vladimir Jovanovic + * + * 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.vlad1m1r.lemniscate.base.models; + +public class Point { + private float x; + private float y; + + public Point(float x, float y, float strokeWidth, float viewSize) { + this.x = translateToPositiveCoordinates(x, strokeWidth, viewSize); + this.y = translateToPositiveCoordinates(y, strokeWidth, viewSize); + } + + public float x() { + return x; + } + + public float y() { + return y; + } + + private float compensateForStrokeWidth(float coordinate, float strokeWidth, float viewSize) { + final float ratio = viewSize/(viewSize + 2 * strokeWidth); + return coordinate * ratio + strokeWidth * ratio; + } + + private float translateToPositiveCoordinates(float coordinate, float strokeWidth, float viewSize) { + return compensateForStrokeWidth(coordinate + viewSize/2, strokeWidth, viewSize); + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.java new file mode 100644 index 0000000..2225fac --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Vladimir Jovanovic + * + * 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.vlad1m1r.lemniscate.base.models; + +import java.util.ArrayList; + +public class Points { + private final ArrayList points = new ArrayList<>(); + + public ArrayList getPoints() { + return (ArrayList) points.clone(); + } + + public void addPoint(Point point) { + points.add(point); + } + + public void clear() { + points.clear(); + } + + public boolean isEmpty() { + return points.isEmpty(); + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.java new file mode 100644 index 0000000..9c2d910 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Vladimir Jovanovic + * + * 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.vlad1m1r.lemniscate.base.models; + +public class ViewSize { + + private float size; + private float sizeMultiplier = 1; + + public float getSize() { + return size; + } + + public void setSize(float size) { + this.size = size; + } + + public float getSizeMultiplier() { + return sizeMultiplier; + } + + public void setSizeMultiplier(float sizeMultiplier) { + this.sizeMultiplier = sizeMultiplier; + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.java index be13954..0426671 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.java @@ -36,12 +36,27 @@ public CannabisProgressView(Context context, AttributeSet attrs, int defStyleAtt } @Override - public double getGraphY(double t) { - return -mLemniscateParamY/3 * Math.sin(t) * (Math.sin(t) + 1) * (9/10f * Math.cos(8*t) + 1) * (1/10f * Math.cos(24*t) + 1) * (1/10f * Math.cos(200*t) + 9/10f) + mLemniscateParamY/2; + public float getGraphY(double t) { + return (float) ( + -viewSize.getSize() / 6 + * Math.sin(t) + * (Math.sin(t) + 1) + * (9 / 10f * Math.cos(8 * t) + 1) + * (1 / 10f * Math.cos(24 * t) + 1) + * (1 / 10f * Math.cos(200 * t) + 9 / 10f) + + viewSize.getSize() / 4 + ); } @Override - public double getGraphX(double t) { - return mLemniscateParamX/3 * (Math.sin(t) + 1) * Math.cos(t) * (9/10f * Math.cos(8*t) + 1) * (1/10f * Math.cos(24*t) + 1) * (1/10f * Math.cos(200*t) + 9/10f); + public float getGraphX(double t) { + return (float) ( + viewSize.getSize() / 6 + * (Math.sin(t) + 1) + * Math.cos(t) + * (9 / 10f * Math.cos(8 * t) + 1) + * (1 / 10f * Math.cos(24 * t) + 1) + * (1 / 10f * Math.cos(200 * t) + 9 / 10f) + ); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.java index 09b3e69..74f6020 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.java @@ -36,12 +36,21 @@ public HeartProgressView(Context context, AttributeSet attrs, int defStyleAttr) } @Override - public double getGraphY(double t) { - return -mLemniscateParamY/17 * (13 * Math.cos(t) - 5 * Math.cos(2*t) - 2 * Math.cos(3*t) - Math.cos(4*t)); + public float getGraphY(double t) { + return (float) ( + -viewSize.getSize() / 34 + * (13 * Math.cos(t) + - 5 * Math.cos(2 * t) + - 2 * Math.cos(3 * t) + - Math.cos(4 * t)) + ); } @Override - public double getGraphX(double t) { - return mLemniscateParamX/17 * 16 * Math.pow(Math.sin(t), 3); + public float getGraphX(double t) { + return (float) ( + viewSize.getSize() / 34 + * 16 * Math.pow(Math.sin(t), 3) + ); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.java index 4dfe093..e1430ad 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.java @@ -21,7 +21,6 @@ import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - public class XProgressView extends BaseCurveProgressView { public XProgressView(Context context) { @@ -36,12 +35,22 @@ public XProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } - public double getGraphY(double t){ - return (mLemniscateParamY * 2 * Math.sin(t) * Math.cos(t)); + @Override + public float getGraphY(double t) { + return (float) ( + viewSize.getSize() + * Math.sin(t) + * Math.cos(t) + ); } - public double getGraphX(double t){ - return (mLemniscateParamX * 2 * Math.abs(Math.sin(t)) * Math.cos(t)); + @Override + public float getGraphX(double t) { + return (float) ( + viewSize.getSize() + * Math.abs(Math.sin(t)) + * Math.cos(t) + ); } @Override diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.java index c222135..19e69a1 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.java @@ -18,33 +18,13 @@ import android.content.Context; import android.content.res.TypedArray; -import android.os.Parcel; -import android.os.Parcelable; import android.util.AttributeSet; import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; +import com.vlad1m1r.lemniscate.roulette.models.RouletteCurveSettings; import com.vlad1m1r.lemniscate.sample.lemniscate.R; -public abstract class BaseRouletteProgressView extends BaseCurveProgressView { - - /** - * Radius of the non-moving circle - */ - protected float mRadiusFixed = 3f; - /** - * Radius of the moving circle - */ - protected float mRadiusMoving = 1f; - /** - * Distance from the center of the moving circle - */ - protected float mDistanceFromCenter = 1f; - - /** - * Curve will be drawn on interval [0, 2*mNumberOfCycles*π] before repeating - */ - protected float mNumberOfCycles = 1; - +public abstract class BaseRouletteProgressView extends BaseCurveProgressView { public BaseRouletteProgressView(Context context) { super(context); @@ -52,18 +32,18 @@ public BaseRouletteProgressView(Context context) { public BaseRouletteProgressView(Context context, AttributeSet attrs) { super(context, attrs); - TypedArray a = context.getTheme().obtainStyledAttributes( + TypedArray rouletteCurveAttributes = context.getTheme().obtainStyledAttributes( attrs, R.styleable.RouletteCurveProgressView, 0, 0); try { - setRadiusFixed(a.getFloat(R.styleable.RouletteCurveProgressView_radiusFixed, mRadiusFixed)); - setRadiusMoving(a.getFloat(R.styleable.RouletteCurveProgressView_radiusMoving, mRadiusMoving)); - setDistanceFromCenter(a.getFloat(R.styleable.RouletteCurveProgressView_distanceFromCenter, mDistanceFromCenter)); - setNumberOfCycles(a.getFloat(R.styleable.RouletteCurveProgressView_numberOfCycles, mNumberOfCycles)); + setRadiusFixed(rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_radiusFixed, curveSettings.getRadiusFixed())); + setRadiusMoving(rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_radiusMoving, curveSettings.getRadiusMoving())); + setDistanceFromCenter(rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_distanceFromCenter, curveSettings.getDistanceFromCenter())); + setNumberOfCycles(rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_numberOfCycles, curveSettings.getNumberOfCycles())); } finally { - a.recycle(); + rouletteCurveAttributes.recycle(); } } @@ -72,113 +52,54 @@ public BaseRouletteProgressView(Context context, AttributeSet attrs, int defStyl } public float getRadiusFixed() { - return mRadiusFixed; + return curveSettings.getRadiusFixed(); } public void setRadiusFixed(float radiusFixed) { - this.mRadiusFixed = radiusFixed; + curveSettings.setRadiusFixed(radiusFixed); + recalculateConstants(); } public float getRadiusMoving() { - return mRadiusMoving; + return curveSettings.getRadiusMoving(); } public void setRadiusMoving(float radiusMoving) { - this.mRadiusMoving = radiusMoving; + curveSettings.setRadiusMoving(radiusMoving); + recalculateConstants(); } public float getDistanceFromCenter() { - return mDistanceFromCenter; + return curveSettings.getDistanceFromCenter(); } public void setDistanceFromCenter(float distanceFromCenter) { - this.mDistanceFromCenter = distanceFromCenter; + curveSettings.setDistanceFromCenter(distanceFromCenter); + recalculateConstants(); } public float getNumberOfCycles() { - return mNumberOfCycles; + return curveSettings.getNumberOfCycles(); } public void setNumberOfCycles(float numberOfCycles) { - this.mNumberOfCycles = numberOfCycles; + curveSettings.setNumberOfCycles(numberOfCycles); } - @Override - public void setHasHole(boolean hasHole) { - super.setHasHole(false); - } + protected void recalculateConstants() {} @Override - public double getT(int i) { - return i * mNumberOfCycles * 2 * Math.PI / mPrecision; + protected RouletteCurveSettings getCurveSettings() { + return new RouletteCurveSettings(); } @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - RouletteCurveSavedState ss = new RouletteCurveSavedState(superState); - - ss.radiusFixed = this.mRadiusFixed; - ss.radiusMoving = this.mRadiusMoving; - ss.distanceFromCenter = this.mDistanceFromCenter; - ss.numberOfCycles = this.mNumberOfCycles; - - return ss; + public void setHasHole(boolean hasHole) { + super.setHasHole(false); } @Override - public void onRestoreInstanceState(Parcelable state) { - if(!(state instanceof RouletteCurveSavedState)) { - super.onRestoreInstanceState(state); - return; - } - - RouletteCurveSavedState ss = (RouletteCurveSavedState)state; - super.onRestoreInstanceState(ss.getSuperState()); - //end - - setRadiusFixed(ss.radiusFixed); - setRadiusMoving(ss.radiusMoving); - setDistanceFromCenter(ss.distanceFromCenter); - setNumberOfCycles(ss.numberOfCycles); - } - - static class RouletteCurveSavedState extends BaseCurveProgressView.BaseCurveSavedState { - - float radiusFixed; - float radiusMoving; - float distanceFromCenter; - float numberOfCycles; - - RouletteCurveSavedState(Parcelable superState) { - super(superState); - } - - private RouletteCurveSavedState(Parcel in) { - super(in); - this.radiusFixed = in.readFloat(); - this.radiusMoving = in.readFloat(); - this.distanceFromCenter = in.readFloat(); - this.numberOfCycles = in.readFloat(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeFloat(this.radiusFixed); - out.writeFloat(this.radiusMoving); - out.writeFloat(this.distanceFromCenter); - out.writeFloat(this.numberOfCycles); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public RouletteCurveSavedState createFromParcel(Parcel in) { - return new RouletteCurveSavedState(in); - } - public RouletteCurveSavedState[] newArray(int size) { - return new RouletteCurveSavedState[size]; - } - }; + public double getT(int i) { + return i * curveSettings.getNumberOfCycles() * 2 * Math.PI / curveSettings.getPrecision(); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.java index 73d9d26..c10602f 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.java @@ -21,8 +21,6 @@ public class EpitrochoidProgressView extends BaseRouletteProgressView { - // mRadiusFixed = 5, mRadiusMoving=3, mDistanceFromCenter=5, mNumberOfCycles = 3 to get pentagram - public EpitrochoidProgressView(Context context) { super(context); } @@ -35,20 +33,26 @@ public EpitrochoidProgressView(Context context, AttributeSet attrs, int defStyle super(context, attrs, defStyleAttr); } + private double radiusSum; + private double sizeFactor; + @Override - public double getGraphY(double t) { + public float getGraphY(double t) { //y = (mRadiusFixed + mRadiusMoving) sin(t) - mDistanceFromCenter sin(((mRadiusFixed+mRadiusMoving)/mRadiusMoving)*t) - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter + mRadiusMoving))*((mRadiusFixed + mRadiusMoving)*Math.sin(t) - mDistanceFromCenter *Math.sin(((mRadiusFixed + mRadiusMoving)/ mRadiusMoving)*t)); + return (float) (viewSize.getSize() / sizeFactor + * (radiusSum * Math.sin(t) - curveSettings.getDistanceFromCenter() * Math.sin((radiusSum / curveSettings.getRadiusMoving()) * t))); } @Override - public double getGraphX(double t) { + public float getGraphX(double t) { //x = (mRadiusFixed + mRadiusMoving) cos(t) + mRadiusMoving cos(((mRadiusFixed+mRadiusMoving)/mRadiusMoving)*t), - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter + mRadiusMoving))*((mRadiusFixed + mRadiusMoving)*Math.cos(t) - mDistanceFromCenter *Math.cos(((mRadiusFixed + mRadiusMoving)/ mRadiusMoving)*t)); + return (float) (viewSize.getSize() / sizeFactor + * (radiusSum * Math.cos(t) - curveSettings.getDistanceFromCenter() * Math.cos((radiusSum / curveSettings.getRadiusMoving()) * t))); } @Override - public void setHasHole(boolean hasHole) { - super.setHasHole(false); + protected void recalculateConstants() { + radiusSum = curveSettings.getRadiusFixed() + curveSettings.getRadiusMoving(); + sizeFactor = 2 * (radiusSum + curveSettings.getDistanceFromCenter()); } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.java index 508550d..7c8739c 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.java @@ -21,7 +21,7 @@ public class HypotrochoidProgressView extends BaseRouletteProgressView { - // mRadiusFixed = 5, mRadiusMoving=3, mDistanceFromCenter=5, mNumberOfCycles = 3 to get pentagram + // radiusFixed = 5, radiusMoving=3, distanceFromCenter=5, numberOfCycles = 3 to get pentagram public HypotrochoidProgressView(Context context) { super(context); @@ -35,20 +35,31 @@ public HypotrochoidProgressView(Context context, AttributeSet attrs, int defStyl super(context, attrs, defStyleAttr); } + private double radiusDiff; + private double sizeFactor; + @Override - public double getGraphY(double t) { + public float getGraphY(double t) { //y = (mRadiusFixed - mRadiusMoving) sin(t) - mRadiusMoving sin(((mRadiusFixed-mRadiusMoving)/mRadiusMoving)*t) - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter - mRadiusMoving))*((mRadiusFixed - mRadiusMoving)*Math.sin(t) + mDistanceFromCenter *Math.sin(((mRadiusFixed - mRadiusMoving)/ mRadiusMoving)*t)); + return (float) (viewSize.getSize() / sizeFactor + * (radiusDiff * Math.sin(t) + curveSettings.getDistanceFromCenter() * Math.sin(radiusDiff / curveSettings.getRadiusMoving() * t))); } @Override - public double getGraphX(double t) { + public float getGraphX(double t) { //x = (mRadiusFixed - mRadiusMoving) cos(t) + mRadiusMoving cos(((mRadiusFixed-mRadiusMoving)/mRadiusMoving)*t), - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter - mRadiusMoving))*((mRadiusFixed - mRadiusMoving)*Math.cos(t) - mDistanceFromCenter *Math.cos(((mRadiusFixed - mRadiusMoving)/ mRadiusMoving)*t)); + return (float) (viewSize.getSize() / sizeFactor + * (radiusDiff * Math.cos(t) - curveSettings.getDistanceFromCenter() * Math.cos(radiusDiff / curveSettings.getRadiusMoving() * t))); } @Override public void setHasHole(boolean hasHole) { super.setHasHole(false); } + + @Override + protected void recalculateConstants() { + radiusDiff = curveSettings.getRadiusFixed() - curveSettings.getRadiusMoving(); + sizeFactor = 2 * (radiusDiff + curveSettings.getDistanceFromCenter()); + } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/models/RouletteCurveSettings.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/models/RouletteCurveSettings.java new file mode 100644 index 0000000..427fdb5 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/models/RouletteCurveSettings.java @@ -0,0 +1,92 @@ +package com.vlad1m1r.lemniscate.roulette.models; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.vlad1m1r.lemniscate.base.models.CurveSettings; + +public class RouletteCurveSettings extends CurveSettings implements Parcelable { + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public RouletteCurveSettings createFromParcel(Parcel source) { + return new RouletteCurveSettings(source); + } + + @Override + public RouletteCurveSettings[] newArray(int size) { + return new RouletteCurveSettings[size]; + } + }; + /** + * Radius of the non-moving circle + */ + private float radiusFixed = 3f; + /** + * Radius of the moving circle + */ + private float radiusMoving = 1f; + /** + * Distance from the center of the moving circle + */ + private float distanceFromCenter = 1f; + /** + * Curve will be drawn on interval [0, 2*numberOfCycles*π] before repeating + */ + private float numberOfCycles = 1; + + public RouletteCurveSettings() { + } + + protected RouletteCurveSettings(Parcel in) { + this.radiusFixed = in.readFloat(); + this.radiusMoving = in.readFloat(); + this.distanceFromCenter = in.readFloat(); + this.numberOfCycles = in.readFloat(); + } + + public float getRadiusFixed() { + return radiusFixed; + } + + public void setRadiusFixed(float radiusFixed) { + this.radiusFixed = radiusFixed; + } + + public float getRadiusMoving() { + return radiusMoving; + } + + public void setRadiusMoving(float radiusMoving) { + this.radiusMoving = radiusMoving; + } + + public float getDistanceFromCenter() { + return distanceFromCenter; + } + + public void setDistanceFromCenter(float distanceFromCenter) { + this.distanceFromCenter = distanceFromCenter; + } + + public float getNumberOfCycles() { + return numberOfCycles; + } + + public void setNumberOfCycles(float numberOfCycles) { + this.numberOfCycles = numberOfCycles; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeFloat(this.radiusFixed); + dest.writeFloat(this.radiusMoving); + dest.writeFloat(this.distanceFromCenter); + dest.writeFloat(this.numberOfCycles); + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/RoundScribbleProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/RoundScribbleProgressView.java index 70ec650..e00d6a4 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/RoundScribbleProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/RoundScribbleProgressView.java @@ -23,8 +23,6 @@ public class RoundScribbleProgressView extends BaseRouletteProgressView { - // mRadiusFixed = 5, mRadiusMoving=3, mDistanceFromCenter=5, mNumberOfCycles = 3 to get pentagram - public RoundScribbleProgressView(Context context) { super(context); } @@ -37,18 +35,29 @@ public RoundScribbleProgressView(Context context, AttributeSet attrs, int defSty super(context, attrs, defStyleAttr); } + private double radiusSum; + private double sizeFactor; + @Override - public double getGraphY(double t) { - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter + mRadiusMoving)) * ((mRadiusFixed + mRadiusMoving)*Math.cos(t) - mDistanceFromCenter *Math.sin(((mRadiusFixed + mRadiusMoving)/ mRadiusMoving)*t)); + public float getGraphY(double t) { + return (float) (viewSize.getSize() / sizeFactor + * (radiusSum * Math.cos(t) - curveSettings.getDistanceFromCenter() * Math.sin((radiusSum / curveSettings.getRadiusMoving()) * t))); } @Override - public double getGraphX(double t) { - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter + mRadiusMoving))*((mRadiusFixed + mRadiusMoving)*Math.cos(t) - mDistanceFromCenter *Math.cos(((mRadiusFixed + mRadiusMoving)/ mRadiusMoving)*t)); + public float getGraphX(double t) { + return (float) (viewSize.getSize() / sizeFactor + * (radiusSum * Math.cos(t) - curveSettings.getDistanceFromCenter() * Math.cos((radiusSum / curveSettings.getRadiusMoving()) * t))); } @Override public void setHasHole(boolean hasHole) { super.setHasHole(false); } + + @Override + protected void recalculateConstants() { + radiusSum = curveSettings.getRadiusFixed() + curveSettings.getRadiusMoving(); + sizeFactor = 2 * (radiusSum + curveSettings.getDistanceFromCenter()); + } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/ScribbleProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/ScribbleProgressView.java index 4a72a57..451bf22 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/ScribbleProgressView.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/ScribbleProgressView.java @@ -23,8 +23,6 @@ public class ScribbleProgressView extends BaseRouletteProgressView { - // mRadiusFixed = 5, mRadiusMoving=3, mDistanceFromCenter=5, mNumberOfCycles = 3 to get pentagram - public ScribbleProgressView(Context context) { super(context); } @@ -37,18 +35,29 @@ public ScribbleProgressView(Context context, AttributeSet attrs, int defStyleAtt super(context, attrs, defStyleAttr); } + private double radiusSum; + private double sizeFactor; + @Override - public double getGraphY(double t) { - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter + mRadiusMoving)) * ((mRadiusFixed + mRadiusMoving)*Math.sin(t) - mDistanceFromCenter *Math.cos(((mRadiusFixed + mRadiusMoving)/ mRadiusMoving)*t)); + public float getGraphY(double t) { + return (float) (viewSize.getSize() / sizeFactor + * (radiusSum * Math.sin(t) - curveSettings.getDistanceFromCenter() * Math.cos((radiusSum / curveSettings.getRadiusMoving()) * t))); } @Override - public double getGraphX(double t) { - return mLemniscateParamY/((mRadiusFixed + mDistanceFromCenter + mRadiusMoving))*((mRadiusFixed + mRadiusMoving)*Math.cos(t) - mDistanceFromCenter *Math.cos(((mRadiusFixed + mRadiusMoving)/ mRadiusMoving)*t)); + public float getGraphX(double t) { + return (float) (viewSize.getSize() / sizeFactor + * (radiusSum * Math.cos(t) - curveSettings.getDistanceFromCenter() * Math.cos((radiusSum / curveSettings.getRadiusMoving()) * t))); } @Override public void setHasHole(boolean hasHole) { super.setHasHole(false); } + + @Override + protected void recalculateConstants() { + radiusSum = curveSettings.getRadiusFixed() + curveSettings.getRadiusMoving(); + sizeFactor = 2 * (radiusSum + curveSettings.getDistanceFromCenter()); + } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.java index 73c3168..6169e03 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.java @@ -16,44 +16,20 @@ package com.vlad1m1r.lemniscate.utils; -import android.graphics.Path; -import android.util.Pair; - +import com.vlad1m1r.lemniscate.base.models.Point; public class CurveUtils { - /** - * @param start point from which line is drawn - * @param end point to which line is drawn - * @param path path on which line is drawn - * @return path with line between two points drawn on it - */ - public static Path addPointsToPath(Pair start, Pair end, Path path) { - - if(start != null && end != null) { - path.moveTo(start.first, start.second); - path.quadTo(start.first, start.second, end.first, end.second); - } - else if (start != null) { - path.moveTo(start.first, start.second); - path.lineTo(start.first, start.second); - } else if(end != null) { - path.moveTo(end.first, end.second); - } - return path; - } - /** * @param point is being checked if it's inside hole * @param holeSize size of hole - * @param viewHeight height of view - * @param viewWidth width of view + * @param viewSize size of view * @return if point is in hole returns null, otherwise returns point */ - public static Pair checkPointForHole(Pair point, float holeSize, float viewHeight, float viewWidth) { + public static Point checkPointForHole(Point point, float holeSize, float viewSize) { if(point != null && - Math.abs(point.first - viewWidth / 2) < holeSize && - Math.abs(point.second - viewHeight / 2) < holeSize) { + Math.abs(point.x() - viewSize / 2) < holeSize && + Math.abs(point.y() - viewSize / 2) < holeSize) { return null; } return point; diff --git a/lemniscate/src/main/res/values/attrs.xml b/lemniscate/src/main/res/values/attrs.xml index c88c1a4..7a804e2 100644 --- a/lemniscate/src/main/res/values/attrs.xml +++ b/lemniscate/src/main/res/values/attrs.xml @@ -3,8 +3,6 @@ - - diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/ExampleUnitTest.java b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/ExampleUnitTest.java deleted file mode 100644 index 07ec926..0000000 --- a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.vlad1m1r.lemniscate; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.java b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.java new file mode 100644 index 0000000..f0cd237 --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.java @@ -0,0 +1,5 @@ +package com.vlad1m1r.lemniscate; + +public class TestConstants { + public static double DELTA = 1e-15; +} diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/CurveSettingsTest.java b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/CurveSettingsTest.java new file mode 100644 index 0000000..9148602 --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/CurveSettingsTest.java @@ -0,0 +1,47 @@ +package com.vlad1m1r.lemniscate.base.models; + +import android.graphics.Paint; + +import com.vlad1m1r.lemniscate.TestConstants; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class CurveSettingsTest { + + private CurveSettings curveSettings; + + @Mock + Paint paint; + + @Before + public void setUp() { + curveSettings = new CurveSettings(paint, null); + } + + @Test + public void setStrokeWidth() { + curveSettings.setStrokeWidth(10); + assertEquals(10, curveSettings.getStrokeWidth(), TestConstants.DELTA); + verify(paint).setStrokeWidth(10); + } + + @Test(expected = IllegalArgumentException.class) + public void setStrokeWidthException() throws Exception { + curveSettings.setStrokeWidth(-1); + } + + @Test + public void setColor() { + curveSettings.setColor(123); + assertEquals(123, curveSettings.getColor()); + verify(paint).setColor(123); + } +} \ No newline at end of file diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/LineLengthTest.java b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/LineLengthTest.java new file mode 100644 index 0000000..d6c2f6d --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/LineLengthTest.java @@ -0,0 +1,42 @@ +package com.vlad1m1r.lemniscate.base.models; + +import com.vlad1m1r.lemniscate.TestConstants; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class LineLengthTest { + + private LineLength lineLength; + + @Before + public void setUp() { + lineLength = new LineLength(); + } + + @Test + public void getLineMaxLength() { + lineLength.setLineMaxLength(0.9f); + assertEquals(0.9f, lineLength.getLineMaxLength(), TestConstants.DELTA); + + } + + @Test(expected = IllegalArgumentException.class) + public void getLineMaxLengthException() { + lineLength.setLineMaxLength(1.1f); + } + + @Test + public void setLineMinLength(){ + lineLength.setLineMinLength(0.1f); + assertEquals(0.1f, lineLength.getLineMinLength(), TestConstants.DELTA); + } + + @Test(expected = IllegalArgumentException.class) + public void setLineMinLengthException(){ + lineLength.setLineMaxLength(-1.1f); + } + +} \ No newline at end of file diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/PointTest.java b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/PointTest.java new file mode 100644 index 0000000..c80c303 --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/PointTest.java @@ -0,0 +1,16 @@ +package com.vlad1m1r.lemniscate.base.models; + +import com.vlad1m1r.lemniscate.TestConstants; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class PointTest { + @Test + public void testIfPointsAreTranslated() { + Point point = new Point(0,30,30,270); + assertEquals(135, point.x(), TestConstants.DELTA); + assertEquals(159.5454559326172, point.y(), TestConstants.DELTA); + } +} \ No newline at end of file diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.java b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.java new file mode 100644 index 0000000..915fc09 --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.java @@ -0,0 +1,26 @@ +package com.vlad1m1r.lemniscate.utils; + +import com.vlad1m1r.lemniscate.base.models.Point; + +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +/** + * Created by vlad1m1r on 16-Oct-17. + */ +public class CurveUtilsTest { + + @Test + public void checkPointForHole() { + float viewSize = 100f; + float strokeWidth = 10f; + Point point = new Point(5,0, strokeWidth, viewSize); + + assertSame(CurveUtils.checkPointForHole(point, 1f, viewSize), point); + assertNull(CurveUtils.checkPointForHole(point, 5f, viewSize)); + assertNull(CurveUtils.checkPointForHole(null, 1f, viewSize)); + } + +} \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 52b4d2a..9000d54 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,15 +1,15 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + compileSdkVersion 26 + buildToolsVersion "26.0.2" defaultConfig { applicationId "com.vlad1m1r.lemniscate.sample" - minSdkVersion 11 - targetSdkVersion 25 - versionCode 101 - versionName "1.0.1" + minSdkVersion 14 + targetSdkVersion 26 + versionCode 110 + versionName "1.1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -25,7 +25,7 @@ dependencies { androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:appcompat-v7:26.1.0' testCompile 'junit:junit:4.12' compile project(':lemniscate') } diff --git a/sample/src/androidTest/java/com/vlad1m1r/lemniscate/sample/ExampleInstrumentedTest.java b/sample/src/androidTest/java/com/vlad1m1r/lemniscate/sample/ExampleInstrumentedTest.java deleted file mode 100644 index 0d582ae..0000000 --- a/sample/src/androidTest/java/com/vlad1m1r/lemniscate/sample/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.vlad1m1r.lemniscate.sample; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumentation test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.vlad1m1r.lemniscatetest", appContext.getPackageName()); - } -} diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.java b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.java index 00bcc4f..5bff05f 100644 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.java +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.java @@ -27,8 +27,8 @@ import android.widget.TextView; import com.vlad1m1r.lemniscate.BernoullisBowProgressView; -import com.vlad1m1r.lemniscate.BernoullisSharpProgressView; import com.vlad1m1r.lemniscate.BernoullisProgressView; +import com.vlad1m1r.lemniscate.BernoullisSharpProgressView; import com.vlad1m1r.lemniscate.GeronosProgressView; import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; import com.vlad1m1r.lemniscate.funny.CannabisProgressView; @@ -41,7 +41,6 @@ public class FragmentCurve extends Fragment { - private static final String KEY_POSITION = "position"; public interface OnViewCreated { @@ -51,10 +50,10 @@ public interface OnViewCreated { private OnViewCreated listener; - private BaseCurveProgressView mBaseCurveProgressView; + private BaseCurveProgressView baseCurveProgressView; - private TextView mCurveName; - private LinearLayout mLayoutViewHolder; + private TextView curveName; + private LinearLayout layoutViewHolder; private int mPosition; @@ -72,9 +71,9 @@ public void onCreate(@Nullable Bundle savedInstanceState) { if(savedInstanceState != null && savedInstanceState.containsKey(KEY_POSITION)) mPosition = savedInstanceState.getInt(KEY_POSITION); - if(mBaseCurveProgressView == null) { - mBaseCurveProgressView = getViewForPosition(mPosition); - mBaseCurveProgressView.setLayoutParams(new LinearLayout.LayoutParams( + if(baseCurveProgressView == null) { + baseCurveProgressView = getViewForPosition(mPosition); + baseCurveProgressView.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); } @@ -85,15 +84,15 @@ public void onCreate(@Nullable Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_curve, container, false); - mCurveName = (TextView) root.findViewById(R.id.textCurveName); - mLayoutViewHolder = (LinearLayout) root.findViewById(R.id.layoutViewHolder); + curveName = root.findViewById(R.id.textCurveName); + layoutViewHolder = root.findViewById(R.id.layoutViewHolder); - if(mBaseCurveProgressView.getParent() != null) { - ((ViewGroup) mBaseCurveProgressView.getParent()).removeView(mBaseCurveProgressView); + if(baseCurveProgressView.getParent() != null) { + ((ViewGroup) baseCurveProgressView.getParent()).removeView(baseCurveProgressView); } - mLayoutViewHolder.addView(mBaseCurveProgressView); + layoutViewHolder.addView(baseCurveProgressView); - mCurveName.setText(mBaseCurveProgressView.getClass().getSimpleName()); + curveName.setText(baseCurveProgressView.getClass().getSimpleName()); return root; } @@ -128,7 +127,7 @@ public void onAttach(Context context) { @Override public void onResume() { super.onResume(); - if(listener != null) listener.onViewPrepared(mPosition, mBaseCurveProgressView); + if(listener != null) listener.onViewPrepared(mPosition, baseCurveProgressView); } @Override @@ -140,7 +139,7 @@ public void onDetach() { @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); - if(listener != null) listener.onViewShown(mPosition, mBaseCurveProgressView); + if(listener != null) listener.onViewShown(mPosition, baseCurveProgressView); } public int getPosition() { diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.java b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.java index bb67da2..20fac1a 100644 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.java +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.java @@ -30,94 +30,77 @@ import android.widget.TextView; import com.vlad1m1r.lemniscate.BernoullisBowProgressView; -import com.vlad1m1r.lemniscate.BernoullisSharpProgressView; -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; import com.vlad1m1r.lemniscate.BernoullisProgressView; +import com.vlad1m1r.lemniscate.BernoullisSharpProgressView; import com.vlad1m1r.lemniscate.GeronosProgressView; +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; import com.vlad1m1r.lemniscate.roulette.BaseRouletteProgressView; public class FragmentSettings extends Fragment implements SeekBar.OnSeekBarChangeListener, CompoundButton.OnCheckedChangeListener, View.OnClickListener { - private BaseCurveProgressView mBaseCurveProgressView; - - private SeekBar mSeekBarStrokeWidth; - private SeekBar mSeekBarStrokeLength; - private SeekBar mSeekBarStrokeLengthMax; - private SeekBar mSeekBarStrokeLengthMin; - private CheckBox mCheckBoxChangeableLength; - private CheckBox mCheckBoxHasHole; - private SeekBar mSeekBarSizeMultiplier; - private SeekBar mSeekBarAnimationDuration; - private SeekBar mSeekBarPrecision; - - private SeekBar mSeekBarA, mSeekBarB, mSeekBarD; - private SeekBar mSeekBarNumberOfCycles; - - private TextView mTextViewStrokeWidth; - private TextView mTextViewLineLength; - private TextView mTextViewLineLengthMax; - private TextView mTextViewLineLengthMin; - private TextView mTextViewSizeMultiplier; - private TextView mTextViewAnimationDuration; - private TextView mTextViewPrecision; - - protected int mPrecision = 200; - protected float mStrokeWidth = 10; - protected float mSizeMultiplier = 1; - protected float mLineLength = 0.6f; - protected float mLineMinLength = 0.4f, mLineMaxLength = 0.8f; - protected boolean mIsLineLengthChangeable = true; - protected int mColor; - - protected long mDuration = 1000; - protected boolean mHasHole = false; - + protected int precision = 200; + protected float strokeWidth = 10; + protected float sizeMultiplier = 1; + protected float lineMinLength = 0.4f, lineMaxLength = 0.8f; + protected int color; + protected long duration = 1000; + protected boolean hasHole = false; protected float a = 4f; protected float b = 1f; protected float d = 3f; - protected int numberOfCycles = 1; - private View mViewColor1, mViewColor2, mViewColor3, mViewColor4, mViewColor5, mViewColor6; + private BaseCurveProgressView baseCurveProgressView; + private SeekBar seekBarStrokeWidth; + private SeekBar seekBarStrokeLengthMax; + private SeekBar seekBarStrokeLengthMin; + private CheckBox checkBoxHasHole; + private SeekBar seekBarSizeMultiplier; + private SeekBar seekBarAnimationDuration; + private SeekBar seekBarPrecision; + private SeekBar seekBarA, seekBarB, seekBarD; + private SeekBar seekBarNumberOfCycles; + private TextView textViewStrokeWidth; + private TextView textViewLineLengthMax; + private TextView textViewLineLengthMin; + private TextView textViewSizeMultiplier; + private TextView textViewAnimationDuration; + private TextView textViewPrecision; + private View viewColor1, viewColor2, viewColor3, viewColor4, viewColor5, viewColor6; - public static FragmentSettings getInstance(BaseCurveProgressView baseCurveProgressView) { - FragmentSettings fragmentSettings = new FragmentSettings(); - fragmentSettings.setBaseCurveProgressView(baseCurveProgressView); - return fragmentSettings; + public static float dpToPx(float dp) { + return dp * Resources.getSystem().getDisplayMetrics().density; } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_settings, container, false); - mSeekBarStrokeWidth = (SeekBar) root.findViewById(R.id.seekBarStrokeWidth); - mSeekBarStrokeLength = (SeekBar) root.findViewById(R.id.seekBarLineLength); - mSeekBarStrokeLengthMax = (SeekBar) root.findViewById(R.id.seekBarMaxLineLength); - mSeekBarStrokeLengthMin = (SeekBar) root.findViewById(R.id.seekBarMinLineLength); - mCheckBoxChangeableLength = (CheckBox) root.findViewById(R.id.checkBoxChangeableLength); - mCheckBoxHasHole = (CheckBox) root.findViewById(R.id.checkBoxHasHole); - mSeekBarSizeMultiplier = (SeekBar) root.findViewById(R.id.seekBarSizeMultiplier); - mSeekBarAnimationDuration = (SeekBar) root.findViewById(R.id.seekBarAnimationDuration); - mSeekBarPrecision = (SeekBar) root.findViewById(R.id.seekBarPrecision); - - mViewColor1 = root.findViewById(R.id.viewColor1); - mViewColor2 = root.findViewById(R.id.viewColor2); - mViewColor3 = root.findViewById(R.id.viewColor3); - mViewColor4 = root.findViewById(R.id.viewColor4); - mViewColor5 = root.findViewById(R.id.viewColor5); - mViewColor6 = root.findViewById(R.id.viewColor6); - - mSeekBarA = (SeekBar) root.findViewById(R.id.seekBarA); - mSeekBarB = (SeekBar) root.findViewById(R.id.seekBarB); - mSeekBarD = (SeekBar) root.findViewById(R.id.seekBarD); - mSeekBarNumberOfCycles = (SeekBar) root.findViewById(R.id.seekBarNumberOfCycles); - - mTextViewStrokeWidth = (TextView) root.findViewById(R.id.textStrokeWidth); - mTextViewLineLength = (TextView) root.findViewById(R.id.textLineLength); - mTextViewLineLengthMax = (TextView) root.findViewById(R.id.textMaxLineLength); - mTextViewLineLengthMin = (TextView) root.findViewById(R.id.textMinLineLength); - mTextViewSizeMultiplier = (TextView) root.findViewById(R.id.textSizeMultiplier); - mTextViewAnimationDuration = (TextView) root.findViewById(R.id.textAnimationDuration); - mTextViewPrecision = (TextView) root.findViewById(R.id.textPrecision); + seekBarStrokeWidth = root.findViewById(R.id.seekBarStrokeWidth); + seekBarStrokeLengthMax = root.findViewById(R.id.seekBarMaxLineLength); + seekBarStrokeLengthMin = root.findViewById(R.id.seekBarMinLineLength); + checkBoxHasHole = root.findViewById(R.id.checkBoxHasHole); + seekBarSizeMultiplier = root.findViewById(R.id.seekBarSizeMultiplier); + seekBarAnimationDuration = root.findViewById(R.id.seekBarAnimationDuration); + seekBarPrecision = root.findViewById(R.id.seekBarPrecision); + + viewColor1 = root.findViewById(R.id.viewColor1); + viewColor2 = root.findViewById(R.id.viewColor2); + viewColor3 = root.findViewById(R.id.viewColor3); + viewColor4 = root.findViewById(R.id.viewColor4); + viewColor5 = root.findViewById(R.id.viewColor5); + viewColor6 = root.findViewById(R.id.viewColor6); + + seekBarA = root.findViewById(R.id.seekBarA); + seekBarB = root.findViewById(R.id.seekBarB); + seekBarD = root.findViewById(R.id.seekBarD); + seekBarNumberOfCycles = root.findViewById(R.id.seekBarNumberOfCycles); + + textViewStrokeWidth = root.findViewById(R.id.textStrokeWidth); + textViewLineLengthMax = root.findViewById(R.id.textMaxLineLength); + textViewLineLengthMin = root.findViewById(R.id.textMinLineLength); + textViewSizeMultiplier = root.findViewById(R.id.textSizeMultiplier); + textViewAnimationDuration = root.findViewById(R.id.textAnimationDuration); + textViewPrecision = root.findViewById(R.id.textPrecision); setupViews(); @@ -125,97 +108,87 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, } private void setupViews() { - mSeekBarStrokeWidth.setMax(50); - mSeekBarStrokeWidth.setProgress((int) mStrokeWidth); - mSeekBarStrokeWidth.setOnSeekBarChangeListener(this); - - mSeekBarStrokeLength.setMax(99); - mSeekBarStrokeLength.setProgress(Math.round(100 * mLineLength) - 1); - mSeekBarStrokeLength.setOnSeekBarChangeListener(this); - - mSeekBarStrokeLengthMax.setMax(99); - mSeekBarStrokeLengthMax.setProgress(Math.round(100 * mLineMaxLength) - 1); - mSeekBarStrokeLengthMax.setOnSeekBarChangeListener(this); + seekBarStrokeWidth.setMax(50); + seekBarStrokeWidth.setProgress((int) strokeWidth); + seekBarStrokeWidth.setOnSeekBarChangeListener(this); - mSeekBarSizeMultiplier.setMax(15); - mSeekBarSizeMultiplier.setProgress(5); - mSeekBarSizeMultiplier.setOnSeekBarChangeListener(this); + seekBarStrokeLengthMax.setMax(99); + seekBarStrokeLengthMax.setProgress(Math.round(100 * lineMaxLength) - 1); + seekBarStrokeLengthMax.setOnSeekBarChangeListener(this); - mSeekBarStrokeLengthMin.setMax(99); - mSeekBarStrokeLengthMin.setProgress(Math.round(100 * mLineMinLength) - 1); - mSeekBarStrokeLengthMin.setOnSeekBarChangeListener(this); + seekBarSizeMultiplier.setMax(15); + seekBarSizeMultiplier.setProgress(5); + seekBarSizeMultiplier.setOnSeekBarChangeListener(this); - mSeekBarAnimationDuration.setMax(199); - mSeekBarAnimationDuration.setProgress(((int) mDuration) / 10 - 1); - mSeekBarAnimationDuration.setOnSeekBarChangeListener(this); + seekBarStrokeLengthMin.setMax(99); + seekBarStrokeLengthMin.setProgress(Math.round(100 * lineMinLength) - 1); + seekBarStrokeLengthMin.setOnSeekBarChangeListener(this); + seekBarAnimationDuration.setMax(199); + seekBarAnimationDuration.setProgress(((int) duration) / 10 - 1); + seekBarAnimationDuration.setOnSeekBarChangeListener(this); - mCheckBoxChangeableLength.setOnCheckedChangeListener(this); - mCheckBoxHasHole.setOnCheckedChangeListener(this); + checkBoxHasHole.setOnCheckedChangeListener(this); - mCheckBoxChangeableLength.setChecked(mIsLineLengthChangeable); - mCheckBoxHasHole.setChecked(mHasHole); + checkBoxHasHole.setChecked(hasHole); - mSeekBarPrecision.setMax(990); - mSeekBarPrecision.setProgress(mPrecision); - mSeekBarPrecision.setOnSeekBarChangeListener(this); + seekBarPrecision.setMax(990); + seekBarPrecision.setProgress(precision); + seekBarPrecision.setOnSeekBarChangeListener(this); - mSeekBarA.setMax(10); - mSeekBarA.setProgress((int)a-1); - mSeekBarA.setOnSeekBarChangeListener(this); + seekBarA.setMax(10); + seekBarA.setProgress((int)a-1); + seekBarA.setOnSeekBarChangeListener(this); - mSeekBarB.setMax(10); - mSeekBarB.setProgress((int)b-1); - mSeekBarB.setOnSeekBarChangeListener(this); + seekBarB.setMax(10); + seekBarB.setProgress((int)b-1); + seekBarB.setOnSeekBarChangeListener(this); - mSeekBarD.setMax(10); - mSeekBarD.setProgress((int)d-1); - mSeekBarD.setOnSeekBarChangeListener(this); + seekBarD.setMax(10); + seekBarD.setProgress((int)d-1); + seekBarD.setOnSeekBarChangeListener(this); - mSeekBarNumberOfCycles.setMax(5); - mSeekBarNumberOfCycles.setProgress(numberOfCycles-1); - mSeekBarNumberOfCycles.setOnSeekBarChangeListener(this); + seekBarNumberOfCycles.setMax(5); + seekBarNumberOfCycles.setProgress(numberOfCycles-1); + seekBarNumberOfCycles.setOnSeekBarChangeListener(this); - mColor = ContextCompat.getColor(getContext(), R.color.picker_color_1); - - mViewColor1.setOnClickListener(this); - mViewColor2.setOnClickListener(this); - mViewColor3.setOnClickListener(this); - mViewColor4.setOnClickListener(this); - mViewColor5.setOnClickListener(this); - mViewColor6.setOnClickListener(this); + color = ContextCompat.getColor(getContext(), R.color.picker_color_1); + viewColor1.setOnClickListener(this); + viewColor2.setOnClickListener(this); + viewColor3.setOnClickListener(this); + viewColor4.setOnClickListener(this); + viewColor5.setOnClickListener(this); + viewColor6.setOnClickListener(this); } public void setBaseCurveProgressView(BaseCurveProgressView baseCurveProgressView) { - mBaseCurveProgressView = baseCurveProgressView; + this.baseCurveProgressView = baseCurveProgressView; //Checkbox - if (mBaseCurveProgressView instanceof BernoullisProgressView || - mBaseCurveProgressView instanceof GeronosProgressView || - mBaseCurveProgressView instanceof BernoullisBowProgressView || - mBaseCurveProgressView instanceof BernoullisSharpProgressView) { - mCheckBoxHasHole.setEnabled(true); + if (this.baseCurveProgressView instanceof BernoullisProgressView || + this.baseCurveProgressView instanceof GeronosProgressView || + this.baseCurveProgressView instanceof BernoullisBowProgressView || + this.baseCurveProgressView instanceof BernoullisSharpProgressView) { + checkBoxHasHole.setEnabled(true); } else { - mCheckBoxHasHole.setEnabled(false); + checkBoxHasHole.setEnabled(false); } //Roulette params - if(mBaseCurveProgressView instanceof BaseRouletteProgressView) { - mSeekBarA.setEnabled(true); - mSeekBarB.setEnabled(true); - mSeekBarD.setEnabled(true); - mSeekBarNumberOfCycles.setEnabled(true); + if(this.baseCurveProgressView instanceof BaseRouletteProgressView) { + seekBarA.setEnabled(true); + seekBarB.setEnabled(true); + seekBarD.setEnabled(true); + seekBarNumberOfCycles.setEnabled(true); } else { - mSeekBarA.setEnabled(false); - mSeekBarB.setEnabled(false); - mSeekBarD.setEnabled(false); - mSeekBarNumberOfCycles.setEnabled(false); + seekBarA.setEnabled(false); + seekBarB.setEnabled(false); + seekBarD.setEnabled(false); + seekBarNumberOfCycles.setEnabled(false); } - - - invalidateView(mBaseCurveProgressView); + invalidateView(this.baseCurveProgressView); updateValues(); } @@ -223,29 +196,26 @@ public void setBaseCurveProgressView(BaseCurveProgressView baseCurveProgressView public void onProgressChanged(SeekBar seekBar, int i, boolean fromUser) { switch (seekBar.getId()) { case R.id.seekBarStrokeWidth: - mStrokeWidth = dpToPx(i / 3.f); - break; - case R.id.seekBarLineLength: - mLineLength = (i + 1) / 100.f; + strokeWidth = dpToPx(i/3.f); break; case R.id.seekBarMaxLineLength: - if (i < mSeekBarStrokeLengthMin.getProgress()) { - mSeekBarStrokeLengthMax.setProgress(mSeekBarStrokeLengthMin.getProgress()); - } else mLineMaxLength = (i + 1) / 100.f; + if (i < seekBarStrokeLengthMin.getProgress()) { + seekBarStrokeLengthMax.setProgress(seekBarStrokeLengthMin.getProgress()); + } else lineMaxLength = (i + 1) / 100.f; break; case R.id.seekBarMinLineLength: - if (i > mSeekBarStrokeLengthMax.getProgress()) { - mSeekBarStrokeLengthMin.setProgress(mSeekBarStrokeLengthMax.getProgress()); - } else mLineMinLength = (i + 1) / 100.f; + if (i > seekBarStrokeLengthMax.getProgress()) { + seekBarStrokeLengthMin.setProgress(seekBarStrokeLengthMax.getProgress()); + } else lineMinLength = (i + 1) / 100.f; break; case R.id.seekBarSizeMultiplier: - mSizeMultiplier = (i + 5) / 10.0f; + sizeMultiplier = (i + 5) / 10.0f; break; case R.id.seekBarAnimationDuration: - mDuration = (i + 1) * 10; + duration = (i + 1) * 10; break; case R.id.seekBarPrecision: - mPrecision = i + 10; + precision = i + 10; break; case R.id.seekBarA: a = i + 1; @@ -260,34 +230,29 @@ public void onProgressChanged(SeekBar seekBar, int i, boolean fromUser) { numberOfCycles = i + 1; break; } - - invalidateView(mBaseCurveProgressView); - + invalidateView(baseCurveProgressView); updateValues(); } private void updateValues() { - mTextViewStrokeWidth.setText(String.valueOf(mStrokeWidth)); - mTextViewLineLength.setText(String.format(getResources().getString(R.string.format_percentage), (int)(mLineLength * 100))); - mTextViewLineLengthMax.setText(String.format(getResources().getString(R.string.format_percentage), (int)(mLineMaxLength * 100))); - mTextViewLineLengthMin.setText(String.format(getResources().getString(R.string.format_percentage), (int)(mLineMinLength * 100))); - mTextViewSizeMultiplier.setText(String.valueOf(mSizeMultiplier)); - mTextViewAnimationDuration.setText(String.format(getResources().getString(R.string.format_ms), mDuration)); - mTextViewPrecision.setText(String.format(getResources().getString(R.string.format_points), mPrecision)); + textViewStrokeWidth.setText(String.valueOf(strokeWidth)); + textViewLineLengthMax.setText(String.format(getResources().getString(R.string.format_percentage), (int)(lineMaxLength * 100))); + textViewLineLengthMin.setText(String.format(getResources().getString(R.string.format_percentage), (int)(lineMinLength * 100))); + textViewSizeMultiplier.setText(String.valueOf(sizeMultiplier)); + textViewAnimationDuration.setText(String.format(getResources().getString(R.string.format_ms), duration)); + textViewPrecision.setText(String.format(getResources().getString(R.string.format_points), precision)); } private void invalidateView(BaseCurveProgressView baseCurveProgressView) { if (baseCurveProgressView != null) { - baseCurveProgressView.setPrecision(mPrecision); - baseCurveProgressView.setStrokeWidth(mStrokeWidth); - baseCurveProgressView.setSizeMultiplier(mSizeMultiplier); - baseCurveProgressView.setLineLength(mLineLength); - baseCurveProgressView.setLineMaxLength(mLineMaxLength); - baseCurveProgressView.setLineMinLength(mLineMinLength); - baseCurveProgressView.setIsLineLengthChangeable(mIsLineLengthChangeable); - baseCurveProgressView.setDuration((int) mDuration); - baseCurveProgressView.setHasHole(mHasHole); - baseCurveProgressView.setColor(mColor); + baseCurveProgressView.setPrecision(precision); + baseCurveProgressView.setStrokeWidth(strokeWidth); + baseCurveProgressView.setLineMaxLength(lineMaxLength); + baseCurveProgressView.setLineMinLength(lineMinLength); + baseCurveProgressView.setDuration((int) duration); + baseCurveProgressView.setHasHole(hasHole); + baseCurveProgressView.setColor(color); + baseCurveProgressView.setSizeMultiplier(sizeMultiplier); if(baseCurveProgressView instanceof BaseRouletteProgressView) { BaseRouletteProgressView baseRouletteProgressView = (BaseRouletteProgressView) baseCurveProgressView; @@ -313,22 +278,11 @@ public void onStopTrackingTouch(SeekBar seekBar) { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { switch (buttonView.getId()) { - case R.id.checkBoxChangeableLength: - mIsLineLengthChangeable = isChecked; - mSeekBarStrokeLengthMin.setEnabled(isChecked); - mSeekBarStrokeLengthMax.setEnabled(isChecked); - mSeekBarStrokeLength.setEnabled(!isChecked); - break; case R.id.checkBoxHasHole: - mHasHole = isChecked; + hasHole = isChecked; break; } - - invalidateView(mBaseCurveProgressView); - } - - public static float dpToPx(float dp) { - return dp * Resources.getSystem().getDisplayMetrics().density; + invalidateView(baseCurveProgressView); } public void applySettings(BaseCurveProgressView baseCurveProgressView) { @@ -339,25 +293,24 @@ public void applySettings(BaseCurveProgressView baseCurveProgressView) { public void onClick(View v) { switch (v.getId()) { case R.id.viewColor1: - mColor = ContextCompat.getColor(getContext(), R.color.picker_color_1); + color = ContextCompat.getColor(getContext(), R.color.picker_color_1); break; case R.id.viewColor2: - mColor = ContextCompat.getColor(getContext(), R.color.picker_color_2); + color = ContextCompat.getColor(getContext(), R.color.picker_color_2); break; case R.id.viewColor3: - mColor = ContextCompat.getColor(getContext(), R.color.picker_color_3); + color = ContextCompat.getColor(getContext(), R.color.picker_color_3); break; case R.id.viewColor4: - mColor = ContextCompat.getColor(getContext(), R.color.picker_color_4); + color = ContextCompat.getColor(getContext(), R.color.picker_color_4); break; case R.id.viewColor5: - mColor = ContextCompat.getColor(getContext(), R.color.picker_color_5); + color = ContextCompat.getColor(getContext(), R.color.picker_color_5); break; case R.id.viewColor6: - mColor = ContextCompat.getColor(getContext(), R.color.picker_color_6); + color = ContextCompat.getColor(getContext(), R.color.picker_color_6); break; } - - invalidateView(mBaseCurveProgressView); + invalidateView(baseCurveProgressView); } } diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.java b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.java index 6a2f953..d7e4439 100644 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.java +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.java @@ -36,11 +36,11 @@ public class MainActivity extends AppCompatActivity implements FragmentCurve.OnV private static final int NUM_PAGES = 11; - private FragmentSettings mFragmentSettings; - private ViewPager mPager; + private FragmentSettings fragmentSettings; + private ViewPager pager; - private CurvesPagerAdapter mPagerAdapter; - private Toolbar mToolbar; + private CurvesPagerAdapter pagerAdapter; + private Toolbar toolbar; @Override @@ -48,41 +48,24 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - mToolbar = (Toolbar) findViewById(R.id.toolbar); - setSupportActionBar(mToolbar); - - mFragmentSettings = (FragmentSettings) getSupportFragmentManager().findFragmentById(R.id.fragment_settings); - mPager = (ViewPager) findViewById(viewPager); - mPagerAdapter = new CurvesPagerAdapter(getSupportFragmentManager()); - mPager.setAdapter(mPagerAdapter); + toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + fragmentSettings = (FragmentSettings) getSupportFragmentManager().findFragmentById(R.id.fragment_settings); + pager = findViewById(viewPager); + pagerAdapter = new CurvesPagerAdapter(getSupportFragmentManager()); + pager.setAdapter(pagerAdapter); } @Override public void onViewShown(int position, BaseCurveProgressView baseCurveProgressView) { - if(mPager != null && mPager.getCurrentItem() == position) mFragmentSettings.setBaseCurveProgressView(baseCurveProgressView); + if(pager != null && pager.getCurrentItem() == position) fragmentSettings.setBaseCurveProgressView(baseCurveProgressView); } @Override public void onViewPrepared(int position, BaseCurveProgressView baseCurveProgressView) { - if(mPager != null && mPager.getCurrentItem() == position) mFragmentSettings.setBaseCurveProgressView(baseCurveProgressView); - else mFragmentSettings.applySettings(baseCurveProgressView); - } - - private class CurvesPagerAdapter extends FragmentStatePagerAdapter { - public CurvesPagerAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public Fragment getItem(int position) { - return FragmentCurve.getInstance(position); - } - - @Override - public int getCount() { - return NUM_PAGES; - } + if(pager != null && pager.getCurrentItem() == position) fragmentSettings.setBaseCurveProgressView(baseCurveProgressView); + else fragmentSettings.applySettings(baseCurveProgressView); } @Override @@ -106,4 +89,20 @@ public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } + + private class CurvesPagerAdapter extends FragmentStatePagerAdapter { + public CurvesPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + return FragmentCurve.getInstance(position); + } + + @Override + public int getCount() { + return NUM_PAGES; + } + } } diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.java b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.java index 6ef2e6b..f7f583d 100644 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.java +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.java @@ -20,20 +20,16 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; -/** - * Created by vladimirjovanovic on 1/23/17. - */ - public class PresentationActivity extends AppCompatActivity { - private Toolbar mToolbar; + private Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_presentation); - mToolbar = (Toolbar) findViewById(R.id.toolbar); - setSupportActionBar(mToolbar); + toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); getSupportActionBar().setTitle(R.string.screen_presentation); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); diff --git a/sample/src/main/res/drawable-hdpi/ic_action_github.png b/sample/src/main/res/drawable-hdpi/ic_action_github.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-hdpi/ic_action_presentation.png b/sample/src/main/res/drawable-hdpi/ic_action_presentation.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-mdpi/ic_action_github.png b/sample/src/main/res/drawable-mdpi/ic_action_github.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-mdpi/ic_action_presentation.png b/sample/src/main/res/drawable-mdpi/ic_action_presentation.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-xhdpi/ic_action_github.png b/sample/src/main/res/drawable-xhdpi/ic_action_github.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-xhdpi/ic_action_presentation.png b/sample/src/main/res/drawable-xhdpi/ic_action_presentation.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-xxhdpi/ic_action_github.png b/sample/src/main/res/drawable-xxhdpi/ic_action_github.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-xxhdpi/ic_action_presentation.png b/sample/src/main/res/drawable-xxhdpi/ic_action_presentation.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-xxxhdpi/ic_action_github.png b/sample/src/main/res/drawable-xxxhdpi/ic_action_github.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/drawable-xxxhdpi/ic_action_presentation.png b/sample/src/main/res/drawable-xxxhdpi/ic_action_presentation.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/layout-land/activity_presentation.xml b/sample/src/main/res/layout-land/activity_presentation.xml index bb5a828..e97a4fc 100644 --- a/sample/src/main/res/layout-land/activity_presentation.xml +++ b/sample/src/main/res/layout-land/activity_presentation.xml @@ -15,8 +15,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:orientation="horizontal" - android:gravity="center"> + android:gravity="center" + android:orientation="horizontal"> + app:maxLineLength="0.8" + app:minLineLength="0.8" + app:precision="80" + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> + app:maxLineLength="0.8" + app:minLineLength="0.8" + app:precision="150" + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> @@ -82,8 +78,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:orientation="horizontal" - android:gravity="center"> + android:gravity="center" + android:orientation="horizontal"> + app:maxLineLength="0.8" + app:minLineLength="0.8" + app:precision="80" + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> diff --git a/sample/src/main/res/layout/activity_presentation.xml b/sample/src/main/res/layout/activity_presentation.xml index 085660f..8c00737 100644 --- a/sample/src/main/res/layout/activity_presentation.xml +++ b/sample/src/main/res/layout/activity_presentation.xml @@ -15,8 +15,8 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" - android:orientation="vertical" - android:gravity="center"> + android:gravity="center" + android:orientation="vertical"> + app:maxLineLength="0.8" + app:minLineLength="0.8" + app:precision="80" + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> + app:maxLineLength="0.8" + app:minLineLength="0.8" + app:precision="150" + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> @@ -82,8 +78,8 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" - android:orientation="vertical" - android:gravity="center"> + android:gravity="center" + android:orientation="vertical"> + app:maxLineLength="0.8" + app:minLineLength="0.8" + app:precision="80" + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> + app:strokeWidth="5dp" /> diff --git a/sample/src/main/res/layout/fragment_settings.xml b/sample/src/main/res/layout/fragment_settings.xml index 9d01834..56ee45c 100644 --- a/sample/src/main/res/layout/fragment_settings.xml +++ b/sample/src/main/res/layout/fragment_settings.xml @@ -1,6 +1,6 @@ - @@ -105,35 +105,6 @@ android:layout_marginTop="@dimen/margin_normal" android:background="@color/divider"/> - - - - - - - - + android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" + tools:text="0.4" /> + android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" + tools:text="0.8" /> + android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" + tools:text="1.0" /> + android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" + tools:text="1000ms" /> diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher.png b/sample/src/main/res/mipmap-hdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher.png b/sample/src/main/res/mipmap-mdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/sample/src/test/java/com/vlad1m1r/lemniscate/sample/ExampleUnitTest.java b/sample/src/test/java/com/vlad1m1r/lemniscate/sample/ExampleUnitTest.java deleted file mode 100644 index 51531fa..0000000 --- a/sample/src/test/java/com/vlad1m1r/lemniscate/sample/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.vlad1m1r.lemniscate.sample; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file