diff --git a/CHANGELOG.md b/CHANGELOG.md index 49a42fd..c36eab0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ Change Log ========== +Version 1.4.0 *(2017-11-09)* +---------------------------- + +* Project rewritten in Kotlin. +* Organization of base classes improved +* Fixed bugs in Sample app + Version 1.3.0 *(2017-11-03)* ---------------------------- @@ -11,8 +18,8 @@ Version 1.3.0 *(2017-11-03)* Version 1.2.0 *(2017-02-16)* ---------------------------- - * New curves added: BernoullisBowProgressView, BernoullisSharpProgressView, XProgressView, RoundScribbleProgressView, ScribbleProgressView - * colorAccent is now being used as default line color + * New curves added: `BernoullisBowProgressView`, `BernoullisSharpProgressView`, `XProgressView`, `RoundScribbleProgressView`, `ScribbleProgressView` + * `colorAccent` is now being used as default line color Version 1.1.1 *(2017-01-26)* ---------------------------- @@ -22,19 +29,19 @@ Version 1.1.1 *(2017-01-26)* Version 1.1.0 *(2017-01-26)* ---------------------------- - * Abstract functions getGraphX() and getGraphY() now receive value of getT() + * Abstract functions `getGraphX()` and `getGraphY()` now receive value of `getT()` Version 1.0.2 *(2017-01-24)* ---------------------------- - * Fix: Added OnSaveState for Roulette curves - * Fix: Precision is being saved OnSaveState for all curves + * Fix: Added `onSaveState` for Roulette curves + * Fix: Precision is being saved `onSaveState` for all curves Version 1.0.1 *(2017-01-23)* ---------------------------- - * Fix: Crash on `setColor(int color)` in BaseCurveProgressBar, when called from constructor. + * Fix: Crash on `setColor(int color)` in `BaseCurveProgressBar`, when called from constructor. Version 1.0.0 *(2017-01-23)* diff --git a/README.md b/README.md index 80c5d70..cf635fd 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.3.0' + compile 'com.github.vlad1m1r990:Lemniscate:1.4.0' } Usage diff --git a/build.gradle b/build.gradle index f93d608..856ff97 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.1.51' repositories { jcenter() google() } dependencies { classpath 'com.android.tools.build:gradle:3.0.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/lemniscate/build.gradle b/lemniscate/build.gradle index 4ffcf16..98419cd 100644 --- a/lemniscate/build.gradle +++ b/lemniscate/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' android { compileSdkVersion 26 @@ -7,8 +8,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 26 - versionCode 130 - versionName "1.3.0" + versionCode 140 + versionName "1.4.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -27,5 +28,9 @@ dependencies { compile 'com.android.support:appcompat-v7:26.1.0' testCompile 'junit:junit:4.12' - testCompile 'org.mockito:mockito-core:1.10.19' + testCompile 'org.mockito:mockito-core:2.11.0' + compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" +} +repositories { + mavenCentral() } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.java deleted file mode 100644 index f8ac251..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -public class BernoullisBowProgressView extends BaseCurveProgressView { - - public BernoullisBowProgressView(Context context) { - super(context); - } - - public BernoullisBowProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public BernoullisBowProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @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))); - } - - @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/BernoullisBowProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.kt new file mode 100644 index 0000000..1e06405 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisBowProgressView.kt @@ -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 + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView + +class BernoullisBowProgressView : BaseCurveProgressView { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + (viewSize.size.toDouble() * 0.75 * Math.sin(t) * Math.cos(t) / (1 + Math.pow(Math.cos(t), 6.0))).toFloat() + + override fun getGraphX(t: Double): Float = + (viewSize.size.toDouble() * 0.75 * Math.cos(t) / (1 + Math.pow(Math.cos(t), 6.0))).toFloat() + +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.java deleted file mode 100644 index 27ac889..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -public class BernoullisProgressView extends BaseCurveProgressView { - - public BernoullisProgressView(Context context) { - super(context); - } - - public BernoullisProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public BernoullisProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - public float getGraphY(double t){ - return (float) ((viewSize.getSize() / 2 * Math.sin(t) * 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/BernoullisProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.kt new file mode 100644 index 0000000..94821b5 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisProgressView.kt @@ -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 + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView + +class BernoullisProgressView : BaseCurveProgressView { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + ((viewSize.size / 2).toDouble() * Math.sin(t) * Math.cos(t) / (1 + Math.pow(Math.sin(t), 2.0))).toFloat() + + override fun getGraphX(t: Double): Float = + (viewSize.size / 2 * Math.cos(t) / (1 + Math.pow(Math.sin(t), 2.0))).toFloat() + +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.java deleted file mode 100644 index eb9443b..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -public class BernoullisSharpProgressView extends BaseCurveProgressView { - - public BernoullisSharpProgressView(Context context) { - super(context); - } - - public BernoullisSharpProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public BernoullisSharpProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - public float getGraphY(double t){ - return (float) ((viewSize.getSize() * Math.sin(t) * 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/BernoullisSharpProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.kt new file mode 100644 index 0000000..ef4ebc1 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/BernoullisSharpProgressView.kt @@ -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 + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView + +class BernoullisSharpProgressView : BaseCurveProgressView { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + (viewSize.size.toDouble() * Math.sin(t) * Math.cos(t) / (1 + Math.pow(Math.cos(t), 2.0))).toFloat() + + override fun getGraphX(t: Double): Float = + (viewSize.size * Math.cos(t) / (1 + Math.pow(Math.cos(t), 2.0))).toFloat() + +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.java deleted file mode 100644 index 0f0f47d..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -public class GeronosProgressView extends BaseCurveProgressView { - - public GeronosProgressView(Context context) { - super(context); - } - - public GeronosProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public GeronosProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - public float getGraphY(double t) { - return (float) (viewSize.getSize() / 2 * Math.sin(t) * Math.cos(t)); - } - - @Override - public float getGraphX(double t) { - return (float) (viewSize.getSize() / 2 * Math.sin(t)); - } -} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.kt new file mode 100644 index 0000000..af561c9 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/GeronosProgressView.kt @@ -0,0 +1,39 @@ +/* + * 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 + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView + +class GeronosProgressView : BaseCurveProgressView { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + ((viewSize.size / 2).toDouble() * Math.sin(t) * Math.cos(t)).toFloat() + + + override fun getGraphX(t: Double): Float = + (viewSize.size / 2 * Math.sin(t)).toFloat() + +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.java deleted file mode 100644 index 24a3fd5..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * 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; - -import android.animation.TimeInterpolator; -import android.animation.ValueAnimator; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.AttributeSet; -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; - -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(); - - private ValueAnimator valueAnimator; - private TimeInterpolator interpolator = new LinearInterpolator(); - - public BaseCurveProgressView(Context context) { - super(context); - init(); - } - - public BaseCurveProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - - init(); - - TypedArray curveAttributes = context.getTheme().obtainStyledAttributes( - attrs, - R.styleable.BaseCurveProgressView, - 0, 0); - - TypedArray colorAccentAttributes = context.obtainStyledAttributes(attrs, new int[] { R.attr.colorAccent }); - - try { - 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 { - curveAttributes.recycle(); - colorAccentAttributes.recycle(); - } - } - - public BaseCurveProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - 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∈[-viewSize.getHeight()/2, viewSize.getHeight()/2]. - */ - 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∈[-viewSize.getWidth()/2, viewSize.getWidth()/2]. - */ - public abstract float getGraphX(double t); - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - recreatePoints(); - drawState.addPointsToPath(points.getPoints(), curveSettings, viewSize); - canvas.drawPath(drawState.getPath(), curveSettings.getPaint()); - } - - private void recreatePoints() { - points.clear(); - createNewPoints(); - } - - 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) { - lineLengthToDraw = addPointsToCurve( - points.isEmpty() ? animationSettings.getStartingPointOnCurve() : 0, - lineLengthToDraw - ); - } - } - - private int getLineLengthToDraw() { - return Math.round(curveSettings.getPrecision() * drawState.getCurrentLineLength()); - } - - private int addPointsToCurve(Integer start, int remainingPoints) { - for (int i = start; i < curveSettings.getPrecision(); i++) { - - points.addPoint(getPoint(i)); - - if (--remainingPoints == 0) { - return remainingPoints; - } - } - return remainingPoints; - } - - 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 defaultSize = getResources().getDimension(R.dimen.lemniscate_preferred_height) * viewSize.getSizeMultiplier(); - - int xPadding = getPaddingLeft() + getPaddingRight(); - int yPadding = getPaddingTop() + getPaddingBottom(); - - int viewSize = getMaxViewSquareSize( - getMeasuredHeight(), - getMeasuredWidth(), - xPadding, - yPadding - ); - - this.viewSize.setSize( - getViewDimension( - MeasureSpec.getMode(widthMeasureSpec), - viewSize, - defaultSize - ) - ); - - 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); - } - - 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 { - return defaultSize; - } - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - animateLemniscate(); - } - - private void animateLemniscate() { - 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) { - animationSettings.setStartingPointOnCurve((Integer) animation.getAnimatedValue()); - drawState.recalculateLineLength(curveSettings.getLineLength()); - invalidate(); - } - }); - valueAnimator.start(); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - valueAnimator.end(); - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - BaseCurveSavedState ss = new BaseCurveSavedState(superState); - ss.curveSettings = curveSettings; - ss.animationSettings = animationSettings; - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - if(!(state instanceof BaseCurveSavedState)) { - super.onRestoreInstanceState(state); - return; - } - - BaseCurveSavedState ss = (BaseCurveSavedState)state; - super.onRestoreInstanceState(ss.getSuperState()); - - 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); - } - - public BaseCurveSavedState(Parcel in) { - super(in); - 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.writeParcelable(this.curveSettings, flags); - out.writeParcelable(this.animationSettings, flags); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public BaseCurveSavedState createFromParcel(Parcel in) { - return new BaseCurveSavedState(in); - } - public BaseCurveSavedState[] newArray(int size) { - return new BaseCurveSavedState[size]; - } - }; - } - - - public void setLineMinLength(float lineMinLength) { - curveSettings.getLineLength().setLineMinLength(lineMinLength); - } - - public void setLineMaxLength(float lineMaxLength) { - curveSettings.getLineLength().setLineMaxLength(lineMaxLength); - } - - public void setColor(int color) { - curveSettings.setColor(color); - } - - public void setDuration(int duration) { - animationSettings.setDuration(duration); - if(valueAnimator != null) valueAnimator.setDuration(duration); - } - - public void setHasHole(boolean hasHole) { - curveSettings.setHasHole(hasHole); - } - - public void setStrokeWidth(float strokeWidth) { - curveSettings.setStrokeWidth(strokeWidth); - } - - public float getStrokeWidth() { - return curveSettings.getStrokeWidth(); - } - - public float getLineMinLength() { - return curveSettings.getLineLength().getLineMinLength(); - } - - public float getLineMaxLength() { - return curveSettings.getLineLength().getLineMaxLength(); - } - - public boolean hasHole() { - return curveSettings.hasHole(); - } - - public int getColor() { - return curveSettings.getColor(); - } - - public long getDuration() { - return animationSettings.getDuration(); - } - - public int getPrecision() { - return curveSettings.getPrecision(); - } - - public void setPrecision(int precision) { - curveSettings.setPrecision(precision); - animateLemniscate(); - invalidate(); - } - - /** - * @param i ∈ [0, mPrecision) - * @return function is putting i∈[0, curveSettings.getPrecision()) points between [0, 2π] - */ - protected double getT(int i) { - return i*2*Math.PI/curveSettings.getPrecision(); - } -} \ No newline at end of file diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.kt new file mode 100644 index 0000000..30ff6e3 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/BaseCurveProgressView.kt @@ -0,0 +1,316 @@ +/* + * 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 + +import android.animation.ValueAnimator +import android.content.Context +import android.graphics.Canvas +import android.os.Parcel +import android.os.Parcelable +import android.util.AttributeSet +import android.view.View +import android.view.animation.LinearInterpolator +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.base.settings.AnimationSettings +import com.vlad1m1r.lemniscate.base.settings.CurveSettings +import com.vlad1m1r.lemniscate.sample.lemniscate.R + +abstract class BaseCurveProgressView : View, IBaseCurveProgressView{ + + protected var curveSettings: CurveSettings = CurveSettings() + protected var viewSize = ViewSize() + private var animationSettings = AnimationSettings() + private var drawState = DrawState() + private var points = Points() + + private var valueAnimator: ValueAnimator? = null + private val interpolator = LinearInterpolator() + + private val lineLengthToDraw: Int + get() = Math.round(curveSettings.precision * drawState.currentLineLength) + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { + + val curveAttributes = context.theme.obtainStyledAttributes( + attrs, + R.styleable.BaseCurveProgressView, + 0, 0) + + val colorAccentAttributes = context.obtainStyledAttributes(attrs, intArrayOf(R.attr.colorAccent)) + + try { + val colorAccent = colorAccentAttributes.getColor(0, 0) + + curveSettings.lineLength.lineMaxLength = curveAttributes.getFloat(R.styleable.BaseCurveProgressView_maxLineLength, 0.8f) + curveSettings.lineLength.lineMinLength = curveAttributes.getFloat(R.styleable.BaseCurveProgressView_minLineLength, 0.4f) + + curveSettings.color = curveAttributes.getColor(R.styleable.BaseCurveProgressView_lineColor, colorAccent) + curveSettings.hasHole = curveAttributes.getBoolean(R.styleable.BaseCurveProgressView_hasHole, false) + curveSettings.strokeWidth = curveAttributes.getDimension(R.styleable.BaseCurveProgressView_strokeWidth, resources.getDimension(R.dimen.lemniscate_stroke_width)) + curveSettings.precision = curveAttributes.getInteger(R.styleable.BaseCurveProgressView_precision, 200) + + animationSettings.duration = curveAttributes.getInteger(R.styleable.BaseCurveProgressView_duration, 1000) + } finally { + curveAttributes.recycle() + colorAccentAttributes.recycle() + } + } + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + /** + * 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∈[-viewSize.getHeight()/2, viewSize.getHeight()/2]. + */ + abstract fun getGraphY(t: Double): Float + + /** + * 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∈[-viewSize.getWidth()/2, viewSize.getWidth()/2]. + */ + abstract fun getGraphX(t: Double): Float + + /** + * @param i ∈ [0, mPrecision) + * @return function is putting i∈[0, curveSettings.getPrecision()) points between [0, 2π] + */ + protected open fun getT(i: Int): Double { + return i.toDouble() * 2.0 * Math.PI / curveSettings.precision + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + recreatePoints() + drawState.addPointsToPath(points.getPoints(), curveSettings, viewSize) + canvas.drawPath(drawState.path, curveSettings.paint) + } + + private fun recreatePoints() { + points.clear() + createNewPoints() + } + + private fun createNewPoints() { + var lineLengthToDraw = lineLengthToDraw + + // 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) { + lineLengthToDraw = addPointsToCurve( + if (points.isEmpty) animationSettings.startingPointOnCurve else 0, + lineLengthToDraw + ) + } + } + + private fun addPointsToCurve(start: Int, remainingPoints: Int): Int { + var remainingPoints = remainingPoints + for (i in start until curveSettings.precision) { + + points.addPoint(getPoint(i)) + + if (--remainingPoints == 0) { + return remainingPoints + } + } + return remainingPoints + } + + private fun getPoint(i: Int): Point { + return Point( + getGraphX(getT(i)), + getGraphY(getT(i)), + curveSettings.strokeWidth, + viewSize.size + ) + } + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + + val defaultSize = resources.getDimension(R.dimen.lemniscate_preferred_height) * viewSize.sizeMultiplier + + val xPadding = paddingLeft + paddingRight + val yPadding = paddingTop + paddingBottom + + val viewSize = getMaxViewSquareSize( + measuredHeight, + measuredWidth, + xPadding, + yPadding + ) + + this.viewSize.size = getViewDimension( + View.MeasureSpec.getMode(widthMeasureSpec), + viewSize.toFloat(), + defaultSize + ) + + setMeasuredDimension(Math.round(this.viewSize.size + xPadding), Math.round(this.viewSize.size + yPadding)) + } + + private fun getMaxViewSquareSize(height: Int, width: Int, xPadding: Int, yPadding: Int): Int { + return Math.min(height - yPadding, width - xPadding) + } + + private fun getViewDimension(mode: Int, viewSize: Float, defaultSize: Float): Float { + return if (mode == View.MeasureSpec.EXACTLY) { + viewSize + } else if (mode == View.MeasureSpec.AT_MOST) { + Math.min(defaultSize, viewSize) + } else { + defaultSize + } + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + animateLemniscate() + } + + private fun animateLemniscate() { + if (valueAnimator != null) valueAnimator!!.end() + valueAnimator = ValueAnimator.ofInt(curveSettings.precision - 1, 0) + valueAnimator!!.duration = animationSettings.duration.toLong() + valueAnimator!!.repeatCount = -1 + valueAnimator!!.repeatMode = ValueAnimator.RESTART + valueAnimator!!.interpolator = interpolator + valueAnimator!!.addUpdateListener { animation -> + animationSettings.startingPointOnCurve = animation.animatedValue as Int + drawState.recalculateLineLength(curveSettings.lineLength) + invalidate() + } + valueAnimator!!.start() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + valueAnimator!!.end() + } + + public override fun onSaveInstanceState(): Parcelable { + val superState = super.onSaveInstanceState() + val ss = BaseCurveSavedState(superState) + ss.curveSettings = curveSettings + ss.animationSettings = animationSettings + return ss + } + + public override fun onRestoreInstanceState(state: Parcelable) { + if (state !is BaseCurveSavedState) { + super.onRestoreInstanceState(state) + return + } + + super.onRestoreInstanceState(state.superState) + + this.curveSettings = state.curveSettings + this.animationSettings = state.animationSettings + } + + override fun getStrokeWidth() = curveSettings.strokeWidth + + override fun setStrokeWidth(strokeWidth: Float) { + curveSettings.strokeWidth = strokeWidth + } + + override fun getLineMaxLength() = curveSettings.lineLength.lineMaxLength + + override fun setLineMaxLength(lineMaxLength: Float) { + curveSettings.lineLength.lineMaxLength = lineMaxLength + } + + override fun getLineMinLength() = curveSettings.lineLength.lineMinLength + + override fun setLineMinLength(lineMinLength: Float) { + curveSettings.lineLength.lineMinLength = lineMinLength + } + + override fun getColor() = curveSettings.color + + override fun setColor(color: Int) { + curveSettings.color = color + } + + override fun getDuration() = animationSettings.duration + + override fun setDuration(duration: Int) { + animationSettings.duration = duration + if (valueAnimator != null) valueAnimator!!.duration = duration.toLong() + } + + override fun getPrecision() = curveSettings.precision + + override fun setPrecision(precision: Int) { + curveSettings.precision = precision + animateLemniscate() + invalidate() + } + + override fun getSizeMultiplier() = viewSize.sizeMultiplier + + override fun setSizeMultiplier(multiplier: Float) { + viewSize.sizeMultiplier = multiplier + requestLayout() + invalidate() + } + + override fun hasHole() = curveSettings.hasHole + + override fun setHasHole(hasHole: Boolean) { + curveSettings.hasHole = hasHole + } + + protected class BaseCurveSavedState : View.BaseSavedState { + internal lateinit var curveSettings: CurveSettings + internal lateinit var animationSettings: AnimationSettings + + constructor(superState: Parcelable) : super(superState) + + constructor(`in`: Parcel) : super(`in`) { + this.curveSettings = `in`.readParcelable(CurveSettings::class.java.classLoader) + this.animationSettings = `in`.readParcelable(AnimationSettings::class.java.classLoader) + } + + override fun writeToParcel(out: Parcel, flags: Int) { + super.writeToParcel(out, flags) + out.writeParcelable(this.curveSettings, flags) + out.writeParcelable(this.animationSettings, flags) + } + + + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(`in`: Parcel): BaseCurveSavedState { + return BaseCurveSavedState(`in`) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + } +} \ No newline at end of file diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/IBaseCurveProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/IBaseCurveProgressView.kt new file mode 100644 index 0000000..273727c --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/IBaseCurveProgressView.kt @@ -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 + +interface IBaseCurveProgressView { + fun getStrokeWidth(): Float + fun setStrokeWidth(strokeWidth: Float) + + fun getLineMaxLength(): Float + fun setLineMaxLength(lineMaxLength: Float) + + fun getLineMinLength(): Float + fun setLineMinLength(lineMinLength: Float) + + fun getColor(): Int + fun setColor(color: Int) + + fun getDuration(): Int + fun setDuration(duration: Int) + + fun getPrecision(): Int + fun setPrecision(precision: Int) + + fun getSizeMultiplier(): Float + fun setSizeMultiplier(multiplier: Float) + + fun hasHole(): Boolean + fun setHasHole(hasHole: Boolean) +} \ 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 deleted file mode 100644 index a4b1ff0..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/AnimationSettings.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 deleted file mode 100644 index 27a3252..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/CurveSettings.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 deleted file mode 100644 index 73e8d31..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/DrawState.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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/DrawState.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/DrawState.kt new file mode 100644 index 0000000..f4cc395 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/DrawState.kt @@ -0,0 +1,95 @@ +/* + * 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.base.settings.CurveSettings + +import com.vlad1m1r.lemniscate.utils.CurveUtils + +class DrawState { + private val STEP_SIZE = 0.001f + + val path = Path() + + private var isExpanding = true + var currentLineLength: Float = 0.toFloat() + private set + + private fun addPairOfPointsToPath(start: Point?, end: Point?) { + 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) + } + } + + fun addPointsToPath(listOfPoints: List, curveSettings: CurveSettings, viewSize: ViewSize) { + resetPath() + + val holeSize = curveSettings.strokeWidth + + //adds points to path and creates hole if curveSettings.hasHole() + for (i in listOfPoints.indices) { + var start: Point? = listOfPoints[i] + var end: Point? = null + + + if (listOfPoints.size > i + 1) + end = listOfPoints[i + 1] + + if (curveSettings.hasHole) { + if (start != null && end != null && start.x > end.x) { + start = CurveUtils.checkPointForHole(start, holeSize, viewSize.size) + end = CurveUtils.checkPointForHole(end, holeSize, viewSize.size) + } + } + + addPairOfPointsToPath(start, end) + } + } + + private fun resetPath() { + path.reset() + } + + fun recalculateLineLength(lineLength: LineLength) { + if (lineLength.lineMinLength < lineLength.lineMaxLength) { + if (currentLineLength < lineLength.lineMinLength) { + currentLineLength = lineLength.lineMinLength + } + if (currentLineLength > lineLength.lineMaxLength) { + currentLineLength = lineLength.lineMaxLength + } + + if (currentLineLength < lineLength.lineMaxLength && isExpanding) { + currentLineLength += STEP_SIZE + } else if (currentLineLength > lineLength.lineMinLength && !isExpanding) { + currentLineLength -= STEP_SIZE + } else if (currentLineLength >= lineLength.lineMaxLength) { + isExpanding = false + } else if (currentLineLength <= lineLength.lineMinLength) { + isExpanding = true + } + } else { + currentLineLength = lineLength.lineMaxLength + } + } +} 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 deleted file mode 100644 index 464a09a..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/LineLength.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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/LineLength.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/LineLength.kt new file mode 100644 index 0000000..af67eb0 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/LineLength.kt @@ -0,0 +1,66 @@ +/* + * 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 + +class LineLength : Parcelable { + + var lineMinLength = 0.4f + set(value) { + if (value > 0 && value <= 1) { + field = value + } else { + throw IllegalArgumentException() + } + } + + var lineMaxLength = 0.8f + set(value) { + if (value > 0 && value <= 1) { + field = value + } else { + throw IllegalArgumentException() + } + } + + constructor() + + protected constructor(`in`: Parcel) { + this.lineMinLength = `in`.readFloat() + this.lineMaxLength = `in`.readFloat() + } + + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeFloat(this.lineMinLength) + dest.writeFloat(this.lineMaxLength) + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): LineLength { + return LineLength(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } +} 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.kt similarity index 51% rename from lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.java rename to lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.kt index d887678..1b24ded 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Point.kt @@ -13,31 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.vlad1m1r.lemniscate.base.models; +package com.vlad1m1r.lemniscate.base.models -public class Point { - private float x; - private float y; +class Point(x: Float, y: Float, strokeWidth: Float, viewSize: Float) { + val x: Float + val y: Float - public Point(float x, float y, float strokeWidth, float viewSize) { - this.x = translateToPositiveCoordinates(x, strokeWidth, viewSize); - this.y = translateToPositiveCoordinates(y, strokeWidth, viewSize); + init { + this.x = translateToPositiveCoordinates(x, strokeWidth, viewSize) + this.y = translateToPositiveCoordinates(y, strokeWidth, viewSize) } - public float x() { - return x; + private fun compensateForStrokeWidth(coordinate: Float, strokeWidth: Float, viewSize: Float): Float { + val ratio = viewSize / (viewSize + 2 * strokeWidth) + return coordinate * ratio + strokeWidth * ratio } - 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); + private fun translateToPositiveCoordinates(coordinate: Float, strokeWidth: Float, viewSize: Float): Float { + return compensateForStrokeWidth(coordinate + viewSize / 2, strokeWidth, viewSize) } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.kt similarity index 59% rename from lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.java rename to lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.kt index 9c2d910..62d95d3 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.kt @@ -13,26 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.vlad1m1r.lemniscate.base.models; +package com.vlad1m1r.lemniscate.base.models -public class ViewSize { +import java.util.* - private float size; - private float sizeMultiplier = 1; +class Points { + private val points = ArrayList() - public float getSize() { - return size; - } + val isEmpty: Boolean + get() = points.isEmpty() - public void setSize(float size) { - this.size = size; + fun getPoints(): ArrayList { + return points.clone() as ArrayList } - public float getSizeMultiplier() { - return sizeMultiplier; + fun addPoint(point: Point) { + points.add(point) } - public void setSizeMultiplier(float sizeMultiplier) { - this.sizeMultiplier = sizeMultiplier; + fun clear() { + points.clear() } } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.kt similarity index 56% rename from lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.java rename to lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.kt index 2225fac..c27d04d 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/Points.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/models/ViewSize.kt @@ -13,26 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.vlad1m1r.lemniscate.base.models; +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(); - } +class ViewSize { + var size: Float = 0.toFloat() + var sizeMultiplier = 1f } diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/settings/AnimationSettings.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/settings/AnimationSettings.kt new file mode 100644 index 0000000..775ac0c --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/settings/AnimationSettings.kt @@ -0,0 +1,51 @@ +/* + * 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.settings + +import android.os.Parcel +import android.os.Parcelable + +class AnimationSettings : Parcelable { + + var startingPointOnCurve = 0 + var duration: Int = 1000 + + constructor() + + protected constructor(`in`: Parcel) { + this.startingPointOnCurve = `in`.readInt() + this.duration = `in`.readInt() + } + + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(this.startingPointOnCurve) + dest.writeInt(this.duration) + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(source: Parcel): AnimationSettings { + return AnimationSettings(source) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/settings/CurveSettings.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/settings/CurveSettings.kt new file mode 100644 index 0000000..9b57943 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/base/settings/CurveSettings.kt @@ -0,0 +1,77 @@ +/* + * 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.settings + +import android.graphics.Paint +import android.os.Parcel +import android.os.Parcelable +import com.vlad1m1r.lemniscate.base.models.LineLength + +open class CurveSettings (val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG), var lineLength: LineLength = LineLength()) : Parcelable { + + init { + paint.style = Paint.Style.STROKE + paint.strokeCap = Paint.Cap.ROUND + } + + var precision = 200 + var strokeWidth: Float = 0.toFloat() + set(value) { + if (value >= 0) { + field = value + this.paint.strokeWidth = value + } else { + throw IllegalArgumentException("\'strokeWidth\' must be positive!") + } + } + + var color: Int = 0 + set(value) { + field = value + paint.color = value + } + var hasHole = false + + protected constructor(`in`: Parcel) : this() { + this.precision = `in`.readInt() + this.strokeWidth = `in`.readFloat() + this.color = `in`.readInt() + this.lineLength = `in`.readParcelable(LineLength::class.java.classLoader) + this.hasHole = `in`.readByte().toInt() != 0 + } + + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(this.precision) + dest.writeFloat(this.strokeWidth) + dest.writeInt(this.color) + dest.writeParcelable(this.lineLength, flags) + dest.writeByte(if (this.hasHole) 1.toByte() else 0.toByte()) + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(source: Parcel): CurveSettings { + return CurveSettings(source) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.java deleted file mode 100644 index 0426671..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.funny; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -public class CannabisProgressView extends BaseCurveProgressView { - - public CannabisProgressView(Context context) { - super(context); - } - - public CannabisProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public CannabisProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - 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 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/CannabisProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.kt new file mode 100644 index 0000000..ecfd0c0 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/CannabisProgressView.kt @@ -0,0 +1,47 @@ +/* + * 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.funny + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView + +class CannabisProgressView : BaseCurveProgressView { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + (((-viewSize.size / 6).toDouble() + * 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.size / 4).toFloat() + + override fun getGraphX(t: Double): Float = + ((viewSize.size / 6).toDouble() + * (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)).toFloat() +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.java deleted file mode 100644 index 74f6020..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.funny; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -public class HeartProgressView extends BaseCurveProgressView { - - public HeartProgressView(Context context) { - super(context); - } - - public HeartProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public HeartProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - 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 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/funny/HeartProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.kt new file mode 100644 index 0000000..de9aa9a --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/funny/HeartProgressView.kt @@ -0,0 +1,42 @@ +/* + * 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.funny + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView + +class HeartProgressView : BaseCurveProgressView { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + (-viewSize.size / 34 * (13 * Math.cos(t) + - 5 * Math.cos(2 * t) + - 2 * Math.cos(3 * t) + - Math.cos(4 * t))).toFloat() + + override fun getGraphX(t: Double): Float = + ((viewSize.size / 34).toDouble() + * 16.0 * Math.pow(Math.sin(t), 3.0)).toFloat() + +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.java deleted file mode 100644 index e1430ad..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.other; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -public class XProgressView extends BaseCurveProgressView { - - public XProgressView(Context context) { - super(context); - } - - public XProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public XProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - public float getGraphY(double t) { - return (float) ( - viewSize.getSize() - * 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 - public void setHasHole(boolean hasHole) { - super.setHasHole(false); - } -} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.kt new file mode 100644 index 0000000..9945a9b --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/other/XProgressView.kt @@ -0,0 +1,45 @@ +/* + * 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.other + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView + +class XProgressView : BaseCurveProgressView { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + (viewSize.size.toDouble() + * Math.sin(t) + * Math.cos(t)).toFloat() + + override fun getGraphX(t: Double): Float = + (viewSize.size.toDouble() + * Math.abs(Math.sin(t)) + * Math.cos(t)).toFloat() + + override fun setHasHole(hasHole: Boolean) { + super.setHasHole(false) + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.java deleted file mode 100644 index 19e69a1..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.roulette; - -import android.content.Context; -import android.content.res.TypedArray; -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 { - - public BaseRouletteProgressView(Context context) { - super(context); - } - - public BaseRouletteProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - TypedArray rouletteCurveAttributes = context.getTheme().obtainStyledAttributes( - attrs, - R.styleable.RouletteCurveProgressView, - 0, 0); - - try { - 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 { - rouletteCurveAttributes.recycle(); - } - } - - public BaseRouletteProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public float getRadiusFixed() { - return curveSettings.getRadiusFixed(); - } - - public void setRadiusFixed(float radiusFixed) { - curveSettings.setRadiusFixed(radiusFixed); - recalculateConstants(); - } - - public float getRadiusMoving() { - return curveSettings.getRadiusMoving(); - } - - public void setRadiusMoving(float radiusMoving) { - curveSettings.setRadiusMoving(radiusMoving); - recalculateConstants(); - } - - public float getDistanceFromCenter() { - return curveSettings.getDistanceFromCenter(); - } - - public void setDistanceFromCenter(float distanceFromCenter) { - curveSettings.setDistanceFromCenter(distanceFromCenter); - recalculateConstants(); - } - - public float getNumberOfCycles() { - return curveSettings.getNumberOfCycles(); - } - - public void setNumberOfCycles(float numberOfCycles) { - curveSettings.setNumberOfCycles(numberOfCycles); - } - - protected void recalculateConstants() {} - - @Override - protected RouletteCurveSettings getCurveSettings() { - return new RouletteCurveSettings(); - } - - @Override - public void setHasHole(boolean hasHole) { - super.setHasHole(false); - } - - @Override - 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/BaseRouletteProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.kt new file mode 100644 index 0000000..7461e90 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/BaseRouletteProgressView.kt @@ -0,0 +1,132 @@ +/* + * 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.roulette + +import android.content.Context +import android.os.Parcel +import android.os.Parcelable +import android.util.AttributeSet +import android.view.View + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView +import com.vlad1m1r.lemniscate.roulette.settings.RouletteCurveSettings +import com.vlad1m1r.lemniscate.sample.lemniscate.R + +abstract class BaseRouletteProgressView : BaseCurveProgressView { + + protected var rouletteCurveSettings: RouletteCurveSettings = RouletteCurveSettings() + + var radiusFixed: Float + get() = rouletteCurveSettings.radiusFixed + set(radiusFixed) { + rouletteCurveSettings.radiusFixed = radiusFixed + recalculateConstants() + } + + var radiusMoving: Float + get() = rouletteCurveSettings.radiusMoving + set(radiusMoving) { + rouletteCurveSettings.radiusMoving = radiusMoving + recalculateConstants() + } + + var distanceFromCenter: Float + get() = rouletteCurveSettings.distanceFromCenter + set(distanceFromCenter) { + rouletteCurveSettings.distanceFromCenter = distanceFromCenter + recalculateConstants() + } + + var numberOfCycles: Float + get() = rouletteCurveSettings.numberOfCycles + set(numberOfCycles) { + rouletteCurveSettings.numberOfCycles = numberOfCycles + } + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { + val rouletteCurveAttributes = context.theme.obtainStyledAttributes( + attrs, + R.styleable.RouletteCurveProgressView, + 0, 0) + + try { + radiusFixed = rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_radiusFixed, rouletteCurveSettings.radiusFixed) + radiusMoving = rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_radiusMoving, rouletteCurveSettings.radiusMoving) + distanceFromCenter = rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_distanceFromCenter, rouletteCurveSettings.distanceFromCenter) + numberOfCycles = rouletteCurveAttributes.getFloat(R.styleable.RouletteCurveProgressView_numberOfCycles, rouletteCurveSettings.numberOfCycles) + } finally { + rouletteCurveAttributes.recycle() + } + } + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + protected open fun recalculateConstants() {} + + override fun setHasHole(hasHole: Boolean) { + super.setHasHole(false) + } + + override fun getT(i: Int): Double { + return i.toDouble() * rouletteCurveSettings.numberOfCycles.toDouble() * 2.0 * Math.PI / curveSettings.precision + } + + override fun onSaveInstanceState(): Parcelable { + val superState = super.onSaveInstanceState() + val ss = RouletteCurveSavedState(superState) + ss.rouletteCurveSettings = rouletteCurveSettings + return ss + } + + override fun onRestoreInstanceState(state: Parcelable) { + if (state !is RouletteCurveSavedState) { + super.onRestoreInstanceState(state) + return + } + super.onRestoreInstanceState(state.superState) + + this.rouletteCurveSettings = state.rouletteCurveSettings + } + + protected class RouletteCurveSavedState : View.BaseSavedState { + internal lateinit var rouletteCurveSettings: RouletteCurveSettings + + constructor(superState: Parcelable) : super(superState) + + constructor(`in`: Parcel) : super(`in`) { + this.rouletteCurveSettings = `in`.readParcelable(RouletteCurveSettings::class.java.classLoader) + } + + override fun writeToParcel(out: Parcel, flags: Int) { + super.writeToParcel(out, flags) + out.writeParcelable(this.rouletteCurveSettings, flags) + } + + + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(`in`: Parcel): RouletteCurveSavedState { + return RouletteCurveSavedState(`in`) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.java deleted file mode 100644 index c10602f..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.roulette; - -import android.content.Context; -import android.util.AttributeSet; - -public class EpitrochoidProgressView extends BaseRouletteProgressView { - - public EpitrochoidProgressView(Context context) { - super(context); - } - - public EpitrochoidProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public EpitrochoidProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - private double radiusSum; - private double sizeFactor; - - @Override - public float getGraphY(double t) { - //y = (mRadiusFixed + mRadiusMoving) sin(t) - mDistanceFromCenter sin(((mRadiusFixed+mRadiusMoving)/mRadiusMoving)*t) - return (float) (viewSize.getSize() / sizeFactor - * (radiusSum * Math.sin(t) - curveSettings.getDistanceFromCenter() * Math.sin((radiusSum / curveSettings.getRadiusMoving()) * t))); - } - - @Override - public float getGraphX(double t) { - //x = (mRadiusFixed + mRadiusMoving) cos(t) + mRadiusMoving cos(((mRadiusFixed+mRadiusMoving)/mRadiusMoving)*t), - return (float) (viewSize.getSize() / sizeFactor - * (radiusSum * Math.cos(t) - curveSettings.getDistanceFromCenter() * Math.cos((radiusSum / curveSettings.getRadiusMoving()) * t))); - } - - @Override - protected void recalculateConstants() { - radiusSum = curveSettings.getRadiusFixed() + curveSettings.getRadiusMoving(); - sizeFactor = 2 * (radiusSum + curveSettings.getDistanceFromCenter()); - } -} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.kt new file mode 100644 index 0000000..ef4c2d1 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/EpitrochoidProgressView.kt @@ -0,0 +1,46 @@ +/* + * 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.roulette + +import android.content.Context +import android.util.AttributeSet + +class EpitrochoidProgressView : BaseRouletteProgressView { + + private var radiusSum: Float = 0.toFloat() + private var sizeFactor: Float = 0.toFloat() + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + //y = (mRadiusFixed + mRadiusMoving) sin(t) - mDistanceFromCenter sin(((mRadiusFixed+mRadiusMoving)/mRadiusMoving)*t) + (viewSize.size / sizeFactor * (radiusSum * Math.sin(t) - rouletteCurveSettings.distanceFromCenter * Math.sin(radiusSum / rouletteCurveSettings.radiusMoving * t))).toFloat() + + + override fun getGraphX(t: Double): Float = + //x = (mRadiusFixed + mRadiusMoving) cos(t) + mRadiusMoving cos(((mRadiusFixed+mRadiusMoving)/mRadiusMoving)*t), + (viewSize.size / sizeFactor * (radiusSum * Math.cos(t) - rouletteCurveSettings.distanceFromCenter * Math.cos(radiusSum / rouletteCurveSettings.radiusMoving * t))).toFloat() + + override fun recalculateConstants() { + radiusSum = rouletteCurveSettings.radiusFixed + rouletteCurveSettings.radiusMoving + sizeFactor = 2 * (radiusSum + rouletteCurveSettings.distanceFromCenter) + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.java deleted file mode 100644 index 7c8739c..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.roulette; - -import android.content.Context; -import android.util.AttributeSet; - -public class HypotrochoidProgressView extends BaseRouletteProgressView { - - // radiusFixed = 5, radiusMoving=3, distanceFromCenter=5, numberOfCycles = 3 to get pentagram - - public HypotrochoidProgressView(Context context) { - super(context); - } - - public HypotrochoidProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public HypotrochoidProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - private double radiusDiff; - private double sizeFactor; - - @Override - public float getGraphY(double t) { - //y = (mRadiusFixed - mRadiusMoving) sin(t) - mRadiusMoving sin(((mRadiusFixed-mRadiusMoving)/mRadiusMoving)*t) - return (float) (viewSize.getSize() / sizeFactor - * (radiusDiff * Math.sin(t) + curveSettings.getDistanceFromCenter() * Math.sin(radiusDiff / curveSettings.getRadiusMoving() * t))); - } - - @Override - public float getGraphX(double t) { - //x = (mRadiusFixed - mRadiusMoving) cos(t) + mRadiusMoving 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/HypotrochoidProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.kt new file mode 100644 index 0000000..f07fe37 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/HypotrochoidProgressView.kt @@ -0,0 +1,51 @@ +/* + * 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.roulette + +import android.content.Context +import android.util.AttributeSet + +class HypotrochoidProgressView : BaseRouletteProgressView { + + private var radiusDiff: Float = 0.toFloat() + private var sizeFactor: Float = 0.toFloat() + + // radiusFixed = 5, radiusMoving=3, distanceFromCenter=5, numberOfCycles = 3 to get pentagram + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} + + override fun getGraphY(t: Double): Float = + //y = (mRadiusFixed - mRadiusMoving) sin(t) - mRadiusMoving sin(((mRadiusFixed-mRadiusMoving)/mRadiusMoving)*t) + (viewSize.size / sizeFactor * (radiusDiff * Math.sin(t) + rouletteCurveSettings.distanceFromCenter * Math.sin(radiusDiff / rouletteCurveSettings.radiusMoving * t))).toFloat() + + override fun getGraphX(t: Double): Float = + //x = (mRadiusFixed - mRadiusMoving) cos(t) + mRadiusMoving cos(((mRadiusFixed-mRadiusMoving)/mRadiusMoving)*t), + (viewSize.size / sizeFactor * (radiusDiff * Math.cos(t) - rouletteCurveSettings.distanceFromCenter * Math.cos(radiusDiff / rouletteCurveSettings.radiusMoving * t))).toFloat() + + override fun setHasHole(hasHole: Boolean) { + super.setHasHole(false) + } + + override fun recalculateConstants() { + radiusDiff = rouletteCurveSettings.radiusFixed - rouletteCurveSettings.radiusMoving + sizeFactor = 2 * (radiusDiff + rouletteCurveSettings.distanceFromCenter) + } +} 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 deleted file mode 100644 index 427fdb5..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/models/RouletteCurveSettings.java +++ /dev/null @@ -1,92 +0,0 @@ -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/roulette/scribble/RoundScribbleProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/scribble/RoundScribbleProgressView.kt new file mode 100644 index 0000000..f653976 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/scribble/RoundScribbleProgressView.kt @@ -0,0 +1,49 @@ +/* + * 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.roulette.scribble + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.roulette.BaseRouletteProgressView + +class RoundScribbleProgressView : BaseRouletteProgressView { + + private var radiusSum: Float = 0.toFloat() + private var sizeFactor: Float = 0.toFloat() + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + (viewSize.size / sizeFactor * (radiusSum * Math.cos(t) - rouletteCurveSettings.distanceFromCenter * Math.sin(radiusSum / rouletteCurveSettings.radiusMoving * t))).toFloat() + + override fun getGraphX(t: Double): Float = + (viewSize.size / sizeFactor * (radiusSum * Math.cos(t) - rouletteCurveSettings.distanceFromCenter * Math.cos(radiusSum / rouletteCurveSettings.radiusMoving * t))).toFloat() + + override fun setHasHole(hasHole: Boolean) { + super.setHasHole(false) + } + + override fun recalculateConstants() { + radiusSum = rouletteCurveSettings.radiusFixed + rouletteCurveSettings.radiusMoving + sizeFactor = 2 * (radiusSum + rouletteCurveSettings.distanceFromCenter) + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/scribble/ScribbleProgressView.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/scribble/ScribbleProgressView.kt new file mode 100644 index 0000000..96ce58e --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/scribble/ScribbleProgressView.kt @@ -0,0 +1,51 @@ +/* + * 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.roulette.scribble + +import android.content.Context +import android.util.AttributeSet + +import com.vlad1m1r.lemniscate.roulette.BaseRouletteProgressView + +class ScribbleProgressView : BaseRouletteProgressView { + + private var radiusSum: Float = 0.toFloat() + private var sizeFactor: Float = 0.toFloat() + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun getGraphY(t: Double): Float = + (viewSize.size / sizeFactor * (radiusSum * Math.sin(t) - rouletteCurveSettings.distanceFromCenter * Math.cos(radiusSum / rouletteCurveSettings.radiusMoving * t))).toFloat() + + + override fun getGraphX(t: Double): Float = + (viewSize.size / sizeFactor * (radiusSum * Math.cos(t) - rouletteCurveSettings.distanceFromCenter * Math.cos(radiusSum / rouletteCurveSettings.radiusMoving * t))).toFloat() + + + override fun setHasHole(hasHole: Boolean) { + super.setHasHole(false) + } + + override fun recalculateConstants() { + radiusSum = rouletteCurveSettings.radiusFixed + rouletteCurveSettings.radiusMoving + sizeFactor = 2 * (radiusSum + rouletteCurveSettings.distanceFromCenter) + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/settings/RouletteCurveSettings.kt b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/settings/RouletteCurveSettings.kt new file mode 100644 index 0000000..6fe5588 --- /dev/null +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/roulette/settings/RouletteCurveSettings.kt @@ -0,0 +1,57 @@ +package com.vlad1m1r.lemniscate.roulette.settings + +import android.os.Parcel +import android.os.Parcelable + +class RouletteCurveSettings : Parcelable { + + /** + * Radius of the non-moving circle + */ + var radiusFixed = 3f + /** + * Radius of the moving circle + */ + var radiusMoving = 1f + /** + * Distance from the center of the moving circle + */ + var distanceFromCenter = 1f + /** + * Curve will be drawn on interval [0, 2*numberOfCycles*π] before repeating + */ + var numberOfCycles = 1f + + constructor() + + protected constructor(`in`: Parcel) { + this.radiusFixed = `in`.readFloat() + this.radiusMoving = `in`.readFloat() + this.distanceFromCenter = `in`.readFloat() + this.numberOfCycles = `in`.readFloat() + } + + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeFloat(this.radiusFixed) + dest.writeFloat(this.radiusMoving) + dest.writeFloat(this.distanceFromCenter) + dest.writeFloat(this.numberOfCycles) + } + + companion object { + + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(source: Parcel): RouletteCurveSettings { + return RouletteCurveSettings(source) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + } +} diff --git a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/RoundScribbleProgressView.java b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/RoundScribbleProgressView.java deleted file mode 100644 index e00d6a4..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/RoundScribbleProgressView.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.scribble; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.roulette.BaseRouletteProgressView; - -public class RoundScribbleProgressView extends BaseRouletteProgressView { - - public RoundScribbleProgressView(Context context) { - super(context); - } - - public RoundScribbleProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public RoundScribbleProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - private double radiusSum; - private double sizeFactor; - - @Override - public float getGraphY(double t) { - return (float) (viewSize.getSize() / sizeFactor - * (radiusSum * Math.cos(t) - curveSettings.getDistanceFromCenter() * Math.sin((radiusSum / curveSettings.getRadiusMoving()) * t))); - } - - @Override - 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 deleted file mode 100644 index 451bf22..0000000 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/scribble/ScribbleProgressView.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.scribble; - -import android.content.Context; -import android.util.AttributeSet; - -import com.vlad1m1r.lemniscate.roulette.BaseRouletteProgressView; - -public class ScribbleProgressView extends BaseRouletteProgressView { - - public ScribbleProgressView(Context context) { - super(context); - } - - public ScribbleProgressView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ScribbleProgressView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - private double radiusSum; - private double sizeFactor; - - @Override - public float getGraphY(double t) { - return (float) (viewSize.getSize() / sizeFactor - * (radiusSum * Math.sin(t) - curveSettings.getDistanceFromCenter() * Math.cos((radiusSum / curveSettings.getRadiusMoving()) * t))); - } - - @Override - 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.kt similarity index 66% rename from lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.java rename to lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.kt index 6169e03..6d1c9f3 100644 --- a/lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.java +++ b/lemniscate/src/main/java/com/vlad1m1r/lemniscate/utils/CurveUtils.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.vlad1m1r.lemniscate.utils; +package com.vlad1m1r.lemniscate.utils -import com.vlad1m1r.lemniscate.base.models.Point; +import com.vlad1m1r.lemniscate.base.models.Point -public class CurveUtils { +object CurveUtils { /** * @param point is being checked if it's inside hole @@ -26,12 +26,11 @@ public class CurveUtils { * @param viewSize size of view * @return if point is in hole returns null, otherwise returns point */ - public static Point checkPointForHole(Point point, float holeSize, float viewSize) { - if(point != null && - Math.abs(point.x() - viewSize / 2) < holeSize && - Math.abs(point.y() - viewSize / 2) < holeSize) { - return null; - } - return point; + fun checkPointForHole(point: Point?, holeSize: Float, viewSize: Float): Point? { + return if (point != null && + Math.abs(point.x - viewSize / 2) < holeSize && + Math.abs(point.y - viewSize / 2) < holeSize) { + null + } else point } } diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.java b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.java deleted file mode 100644 index f0cd237..0000000 --- a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.vlad1m1r.lemniscate; - -public class TestConstants { - public static double DELTA = 1e-15; -} diff --git a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.kt b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.kt new file mode 100644 index 0000000..42dc95c --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/TestConstants.kt @@ -0,0 +1,5 @@ +package com.vlad1m1r.lemniscate + +object TestConstants { + const val DELTA: Float = 2-126f +} 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 deleted file mode 100644 index 9148602..0000000 --- a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/CurveSettingsTest.java +++ /dev/null @@ -1,47 +0,0 @@ -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/CurveSettingsTest.kt b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/CurveSettingsTest.kt new file mode 100644 index 0000000..e5183d6 --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/CurveSettingsTest.kt @@ -0,0 +1,46 @@ +package com.vlad1m1r.lemniscate.base.models + +import android.graphics.Paint +import com.vlad1m1r.lemniscate.TestConstants +import com.vlad1m1r.lemniscate.base.settings.CurveSettings +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class CurveSettingsTest { + + private lateinit var curveSettings: CurveSettings + + @Mock + lateinit var paint: Paint + + @Before + fun setUp() { + val lineLength = LineLength() + curveSettings = CurveSettings(paint, lineLength) + } + + @Test + fun setStrokeWidth() { + curveSettings.strokeWidth = 10f + assertEquals(10.0f, curveSettings.strokeWidth, TestConstants.DELTA) + verify(paint).strokeWidth = 10f + } + + @Test(expected = IllegalArgumentException::class) + fun setStrokeWidthException() { + curveSettings.strokeWidth = -1f + } + + @Test + fun setColor() { + curveSettings.color = 123 + assertEquals(123, curveSettings.color.toLong()) + verify(paint).color = 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 deleted file mode 100644 index d6c2f6d..0000000 --- a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/LineLengthTest.java +++ /dev/null @@ -1,42 +0,0 @@ -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/LineLengthTest.kt b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/LineLengthTest.kt new file mode 100644 index 0000000..0c2da6b --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/LineLengthTest.kt @@ -0,0 +1,39 @@ +package com.vlad1m1r.lemniscate.base.models + +import com.vlad1m1r.lemniscate.TestConstants +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class LineLengthTest { + + private lateinit var lineLength: LineLength + + @Before + fun setUp() { + lineLength = LineLength() + } + + @Test + fun getLineMaxLength() { + lineLength.lineMaxLength = 0.9f + assertEquals(0.9f, lineLength.lineMaxLength, TestConstants.DELTA) + + } + + @Test(expected = IllegalArgumentException::class) + fun getLineMaxLengthException() { + lineLength.lineMaxLength = 1.1f + } + + @Test + fun setLineMinLength() { + lineLength.lineMinLength = 0.1f + assertEquals(0.1f, lineLength.lineMinLength, TestConstants.DELTA) + } + + @Test(expected = IllegalArgumentException::class) + fun setLineMinLengthException() { + lineLength.lineMaxLength = -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 deleted file mode 100644 index c80c303..0000000 --- a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/PointTest.java +++ /dev/null @@ -1,16 +0,0 @@ -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/base/models/PointTest.kt b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/PointTest.kt new file mode 100644 index 0000000..2e5406c --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/base/models/PointTest.kt @@ -0,0 +1,14 @@ +package com.vlad1m1r.lemniscate.base.models + +import com.vlad1m1r.lemniscate.TestConstants +import org.junit.Assert.assertEquals +import org.junit.Test + +class PointTest { + @Test + fun testIfPointsAreTranslated() { + val point = Point(0f, 30f, 30f, 270f) + assertEquals(135.0f, point.x, TestConstants.DELTA) + assertEquals(159.545455f, 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 deleted file mode 100644 index 915fc09..0000000 --- a/lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.java +++ /dev/null @@ -1,26 +0,0 @@ -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/lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.kt b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.kt new file mode 100644 index 0000000..076190c --- /dev/null +++ b/lemniscate/src/test/java/com/vlad1m1r/lemniscate/utils/CurveUtilsTest.kt @@ -0,0 +1,21 @@ +package com.vlad1m1r.lemniscate.utils + +import com.vlad1m1r.lemniscate.base.models.Point +import org.junit.Assert.assertNull +import org.junit.Assert.assertSame +import org.junit.Test + +class CurveUtilsTest { + + @Test + fun checkPointForHole() { + val viewSize = 100f + val strokeWidth = 10f + val point = Point(5f, 0f, 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 9000d54..1fc1b27 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 26 @@ -8,8 +10,8 @@ android { applicationId "com.vlad1m1r.lemniscate.sample" minSdkVersion 14 targetSdkVersion 26 - versionCode 110 - versionName "1.1.0" + versionCode 120 + versionName "1.2.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -26,6 +28,7 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:26.1.0' + compile 'me.relex:circleindicator:1.2.2@aar' testCompile 'junit:junit:4.12' compile project(':lemniscate') } diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/CurveData.kt b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/CurveData.kt new file mode 100644 index 0000000..1c0acea --- /dev/null +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/CurveData.kt @@ -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.sample + +import android.os.Parcel +import android.os.Parcelable + +class CurveData(var precision: Int = 200, + var strokeWidth: Float = 10f, + var sizeMultiplier: Float = 1f, + var lineMinLength: Float = 0.4f, + var lineMaxLength: Float = 0.8f, + var color: Int = 0, + var duration: Int = 1000, + var hasHole: Boolean = false, + var radiusFixed: Float = 4f, + var radiusMoving: Float = 1f, + var distanceFromCenter: Float = 3f, + var numberOfCycles: Int = 1) : Parcelable { + + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(this.precision) + dest.writeFloat(this.strokeWidth) + dest.writeFloat(this.sizeMultiplier) + dest.writeFloat(this.lineMinLength) + dest.writeFloat(this.lineMaxLength) + dest.writeInt(this.color) + dest.writeInt(this.duration) + dest.writeByte(if (this.hasHole) 1.toByte() else 0.toByte()) + dest.writeFloat(this.radiusFixed) + dest.writeFloat(this.radiusMoving) + dest.writeFloat(this.distanceFromCenter) + dest.writeInt(this.numberOfCycles) + } + + protected constructor(`in`: Parcel) : this() { + this.precision = `in`.readInt() + this.strokeWidth = `in`.readFloat() + this.sizeMultiplier = `in`.readFloat() + this.lineMinLength = `in`.readFloat() + this.lineMaxLength = `in`.readFloat() + this.color = `in`.readInt() + this.duration = `in`.readInt() + this.hasHole = `in`.readByte().toInt() != 0 + this.radiusFixed = `in`.readFloat() + this.radiusMoving = `in`.readFloat() + this.distanceFromCenter = `in`.readFloat() + this.numberOfCycles = `in`.readInt() + } + + companion object { + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(source: Parcel): CurveData { + return CurveData(source) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + } +} diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.java b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.java deleted file mode 100644 index 5bff05f..0000000 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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.sample; - -import android.content.Context; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.vlad1m1r.lemniscate.BernoullisBowProgressView; -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; -import com.vlad1m1r.lemniscate.funny.HeartProgressView; -import com.vlad1m1r.lemniscate.other.XProgressView; -import com.vlad1m1r.lemniscate.roulette.EpitrochoidProgressView; -import com.vlad1m1r.lemniscate.roulette.HypotrochoidProgressView; -import com.vlad1m1r.lemniscate.scribble.RoundScribbleProgressView; -import com.vlad1m1r.lemniscate.scribble.ScribbleProgressView; - -public class FragmentCurve extends Fragment { - - private static final String KEY_POSITION = "position"; - - public interface OnViewCreated { - void onViewShown(int position, BaseCurveProgressView baseCurveProgressView); - void onViewPrepared(int position, BaseCurveProgressView baseCurveProgressView); - } - - private OnViewCreated listener; - - private BaseCurveProgressView baseCurveProgressView; - - private TextView curveName; - private LinearLayout layoutViewHolder; - - private int mPosition; - - public static FragmentCurve getInstance(int position) { - FragmentCurve fragmentCurve = new FragmentCurve(); - fragmentCurve.setPosition(position); - fragmentCurve.setRetainInstance(true); - return fragmentCurve; - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if(savedInstanceState != null && savedInstanceState.containsKey(KEY_POSITION)) - mPosition = savedInstanceState.getInt(KEY_POSITION); - - if(baseCurveProgressView == null) { - baseCurveProgressView = getViewForPosition(mPosition); - baseCurveProgressView.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, - LinearLayout.LayoutParams.WRAP_CONTENT)); - } - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_curve, container, false); - - curveName = root.findViewById(R.id.textCurveName); - layoutViewHolder = root.findViewById(R.id.layoutViewHolder); - - if(baseCurveProgressView.getParent() != null) { - ((ViewGroup) baseCurveProgressView.getParent()).removeView(baseCurveProgressView); - } - layoutViewHolder.addView(baseCurveProgressView); - - curveName.setText(baseCurveProgressView.getClass().getSimpleName()); - - return root; - } - - private BaseCurveProgressView getViewForPosition(int position) { - switch (position) { - case 0: return new BernoullisProgressView(getContext()); - case 1: return new GeronosProgressView(getContext()); - case 2: return new BernoullisBowProgressView(getContext()); - case 3: return new BernoullisSharpProgressView(getContext()); - - case 4: return new EpitrochoidProgressView(getContext()); - case 5: return new HypotrochoidProgressView(getContext()); - - case 6: return new XProgressView(getContext()); - - case 7: return new RoundScribbleProgressView(getContext()); - case 8: return new ScribbleProgressView(getContext()); - - case 9: return new CannabisProgressView(getContext()); - case 10: return new HeartProgressView(getContext()); - default: return new BernoullisProgressView(getContext()); - } - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - listener = (OnViewCreated) context; - } - - @Override - public void onResume() { - super.onResume(); - if(listener != null) listener.onViewPrepared(mPosition, baseCurveProgressView); - } - - @Override - public void onDetach() { - listener = null; - super.onDetach(); - } - - @Override - public void setUserVisibleHint(boolean isVisibleToUser) { - super.setUserVisibleHint(isVisibleToUser); - if(listener != null) listener.onViewShown(mPosition, baseCurveProgressView); - } - - public int getPosition() { - return mPosition; - } - - public void setPosition(int position) { - this.mPosition = position; - } - - - @Override - public void onSaveInstanceState(Bundle outState) { - outState.putInt(KEY_POSITION, mPosition); - super.onSaveInstanceState(outState); - } -} diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.kt b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.kt new file mode 100644 index 0000000..8b79254 --- /dev/null +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentCurve.kt @@ -0,0 +1,146 @@ +/* + * 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.sample + +import android.content.Context +import android.os.Bundle +import android.support.v4.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.TextView + +import com.vlad1m1r.lemniscate.BernoullisBowProgressView +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 +import com.vlad1m1r.lemniscate.funny.HeartProgressView +import com.vlad1m1r.lemniscate.other.XProgressView +import com.vlad1m1r.lemniscate.roulette.EpitrochoidProgressView +import com.vlad1m1r.lemniscate.roulette.HypotrochoidProgressView +import com.vlad1m1r.lemniscate.roulette.scribble.RoundScribbleProgressView +import com.vlad1m1r.lemniscate.roulette.scribble.ScribbleProgressView + +class FragmentCurve : Fragment() { + + private var listener: OnViewCreated? = null + + private var baseCurveProgressView: BaseCurveProgressView? = null + + private lateinit var curveName: TextView + private lateinit var layoutViewHolder: LinearLayout + + private var position: Int = 0 + + interface OnViewCreated { + fun onViewShown(position: Int, baseCurveProgressView: BaseCurveProgressView?) + fun onViewPrepared(position: Int, baseCurveProgressView: BaseCurveProgressView?) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (savedInstanceState != null && savedInstanceState.containsKey(KEY_POSITION)) + position = savedInstanceState.getInt(KEY_POSITION) + + if (baseCurveProgressView == null) { + baseCurveProgressView = getViewForPosition(position) + baseCurveProgressView!!.id = position + baseCurveProgressView!!.layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT) + } + } + + override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { + val root = inflater!!.inflate(R.layout.fragment_curve, container, false) as ViewGroup + + curveName = root.findViewById(R.id.textCurveName) + layoutViewHolder = root.findViewById(R.id.layoutViewHolder) + + if (baseCurveProgressView!!.parent != null) { + (baseCurveProgressView!!.parent as ViewGroup).removeView(baseCurveProgressView) + } + layoutViewHolder.addView(baseCurveProgressView) + + curveName.text = baseCurveProgressView!!.javaClass.simpleName + + return root + } + + private fun getViewForPosition(position: Int): BaseCurveProgressView { + when (position) { + 0 -> return BernoullisProgressView(context) + 1 -> return GeronosProgressView(context) + 2 -> return BernoullisBowProgressView(context) + 3 -> return BernoullisSharpProgressView(context) + + 4 -> return EpitrochoidProgressView(context) + 5 -> return HypotrochoidProgressView(context) + + 6 -> return XProgressView(context) + + 7 -> return RoundScribbleProgressView(context) + 8 -> return ScribbleProgressView(context) + + 9 -> return CannabisProgressView(context) + 10 -> return HeartProgressView(context) + else -> return BernoullisProgressView(context) + } + } + + override fun onAttach(context: Context?) { + super.onAttach(context) + listener = context as OnViewCreated? + } + + override fun onResume() { + super.onResume() + if (listener != null) listener!!.onViewPrepared(position, baseCurveProgressView) + } + + override fun onDetach() { + listener = null + super.onDetach() + } + + override fun setUserVisibleHint(isVisibleToUser: Boolean) { + super.setUserVisibleHint(isVisibleToUser) + if (listener != null) listener!!.onViewShown(position, baseCurveProgressView) + } + + + override fun onSaveInstanceState(outState: Bundle?) { + outState!!.putInt(KEY_POSITION, position) + super.onSaveInstanceState(outState) + } + + companion object { + + private val KEY_POSITION = "position" + + fun getInstance(position: Int): FragmentCurve { + val fragmentCurve = FragmentCurve() + fragmentCurve.position = position + fragmentCurve.retainInstance = true + return fragmentCurve + } + } +} diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.java b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.java deleted file mode 100644 index 20fac1a..0000000 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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.sample; - -import android.content.res.Resources; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.support.v4.content.ContextCompat; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.SeekBar; -import android.widget.TextView; - -import com.vlad1m1r.lemniscate.BernoullisBowProgressView; -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 { - - 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 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 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); - 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(); - - return root; - } - - private void setupViews() { - seekBarStrokeWidth.setMax(50); - seekBarStrokeWidth.setProgress((int) strokeWidth); - seekBarStrokeWidth.setOnSeekBarChangeListener(this); - - seekBarStrokeLengthMax.setMax(99); - seekBarStrokeLengthMax.setProgress(Math.round(100 * lineMaxLength) - 1); - seekBarStrokeLengthMax.setOnSeekBarChangeListener(this); - - seekBarSizeMultiplier.setMax(15); - seekBarSizeMultiplier.setProgress(5); - seekBarSizeMultiplier.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); - - checkBoxHasHole.setOnCheckedChangeListener(this); - - checkBoxHasHole.setChecked(hasHole); - - seekBarPrecision.setMax(990); - seekBarPrecision.setProgress(precision); - seekBarPrecision.setOnSeekBarChangeListener(this); - - seekBarA.setMax(10); - seekBarA.setProgress((int)a-1); - seekBarA.setOnSeekBarChangeListener(this); - - seekBarB.setMax(10); - seekBarB.setProgress((int)b-1); - seekBarB.setOnSeekBarChangeListener(this); - - seekBarD.setMax(10); - seekBarD.setProgress((int)d-1); - seekBarD.setOnSeekBarChangeListener(this); - - seekBarNumberOfCycles.setMax(5); - seekBarNumberOfCycles.setProgress(numberOfCycles-1); - seekBarNumberOfCycles.setOnSeekBarChangeListener(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) { - this.baseCurveProgressView = baseCurveProgressView; - - //Checkbox - if (this.baseCurveProgressView instanceof BernoullisProgressView || - this.baseCurveProgressView instanceof GeronosProgressView || - this.baseCurveProgressView instanceof BernoullisBowProgressView || - this.baseCurveProgressView instanceof BernoullisSharpProgressView) { - checkBoxHasHole.setEnabled(true); - } else { - checkBoxHasHole.setEnabled(false); - } - - //Roulette params - if(this.baseCurveProgressView instanceof BaseRouletteProgressView) { - seekBarA.setEnabled(true); - seekBarB.setEnabled(true); - seekBarD.setEnabled(true); - seekBarNumberOfCycles.setEnabled(true); - } else { - seekBarA.setEnabled(false); - seekBarB.setEnabled(false); - seekBarD.setEnabled(false); - seekBarNumberOfCycles.setEnabled(false); - } - - invalidateView(this.baseCurveProgressView); - updateValues(); - } - - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean fromUser) { - switch (seekBar.getId()) { - case R.id.seekBarStrokeWidth: - strokeWidth = dpToPx(i/3.f); - break; - case R.id.seekBarMaxLineLength: - if (i < seekBarStrokeLengthMin.getProgress()) { - seekBarStrokeLengthMax.setProgress(seekBarStrokeLengthMin.getProgress()); - } else lineMaxLength = (i + 1) / 100.f; - break; - case R.id.seekBarMinLineLength: - if (i > seekBarStrokeLengthMax.getProgress()) { - seekBarStrokeLengthMin.setProgress(seekBarStrokeLengthMax.getProgress()); - } else lineMinLength = (i + 1) / 100.f; - break; - case R.id.seekBarSizeMultiplier: - sizeMultiplier = (i + 5) / 10.0f; - break; - case R.id.seekBarAnimationDuration: - duration = (i + 1) * 10; - break; - case R.id.seekBarPrecision: - precision = i + 10; - break; - case R.id.seekBarA: - a = i + 1; - break; - case R.id.seekBarB: - b = i + 1; - break; - case R.id.seekBarD: - d = i + 1; - break; - case R.id.seekBarNumberOfCycles: - numberOfCycles = i + 1; - break; - } - invalidateView(baseCurveProgressView); - updateValues(); - } - - private void updateValues() { - 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(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; - baseRouletteProgressView.setRadiusFixed(a); - baseRouletteProgressView.setRadiusMoving(b); - baseRouletteProgressView.setDistanceFromCenter(d); - - baseRouletteProgressView.setNumberOfCycles(numberOfCycles); - } - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - switch (buttonView.getId()) { - case R.id.checkBoxHasHole: - hasHole = isChecked; - break; - } - invalidateView(baseCurveProgressView); - } - - public void applySettings(BaseCurveProgressView baseCurveProgressView) { - invalidateView(baseCurveProgressView); - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.viewColor1: - color = ContextCompat.getColor(getContext(), R.color.picker_color_1); - break; - case R.id.viewColor2: - color = ContextCompat.getColor(getContext(), R.color.picker_color_2); - break; - case R.id.viewColor3: - color = ContextCompat.getColor(getContext(), R.color.picker_color_3); - break; - case R.id.viewColor4: - color = ContextCompat.getColor(getContext(), R.color.picker_color_4); - break; - case R.id.viewColor5: - color = ContextCompat.getColor(getContext(), R.color.picker_color_5); - break; - case R.id.viewColor6: - color = ContextCompat.getColor(getContext(), R.color.picker_color_6); - break; - } - invalidateView(baseCurveProgressView); - } -} diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.kt b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.kt new file mode 100644 index 0000000..2316d48 --- /dev/null +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/FragmentSettings.kt @@ -0,0 +1,229 @@ +/* + * 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.sample + +import android.content.res.Resources +import android.os.Bundle +import android.support.v4.app.Fragment +import android.support.v4.content.ContextCompat +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.CompoundButton +import android.widget.SeekBar + +import com.vlad1m1r.lemniscate.BernoullisBowProgressView +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 +import kotlinx.android.synthetic.main.fragment_settings.* + +class FragmentSettings : Fragment(), SeekBar.OnSeekBarChangeListener, CompoundButton.OnCheckedChangeListener, View.OnClickListener { + + private lateinit var curveData: CurveData + private var baseCurveProgressView: BaseCurveProgressView? = null + + override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater!!.inflate(R.layout.fragment_settings, container, false) + } + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + curveData = if(savedInstanceState != null && savedInstanceState.containsKey("curve_data")) { + savedInstanceState.getParcelable("curve_data") + } else { + CurveData(color = ContextCompat.getColor(context, R.color.picker_color_1)) + } + + setupViews() + } + + private fun setupViews() { + seekBarStrokeWidth.max = 50 + seekBarStrokeWidth.progress = curveData.strokeWidth.toInt() + seekBarStrokeWidth.setOnSeekBarChangeListener(this) + + seekBarMaxLineLength!!.max = 99 + seekBarMaxLineLength!!.progress = Math.round(100 * curveData.lineMaxLength) - 1 + seekBarMaxLineLength!!.setOnSeekBarChangeListener(this) + + seekBarSizeMultiplier!!.max = 15 + seekBarSizeMultiplier!!.progress = 5 + seekBarSizeMultiplier!!.setOnSeekBarChangeListener(this) + + seekBarMinLineLength!!.max = 99 + seekBarMinLineLength!!.progress = Math.round(100 * curveData.lineMinLength) - 1 + seekBarMinLineLength!!.setOnSeekBarChangeListener(this) + + seekBarAnimationDuration!!.max = 199 + seekBarAnimationDuration!!.progress = curveData.duration / 10 - 1 + seekBarAnimationDuration!!.setOnSeekBarChangeListener(this) + + checkBoxHasHole!!.setOnCheckedChangeListener(this) + + checkBoxHasHole!!.isChecked = curveData.hasHole + + seekBarPrecision!!.max = 990 + seekBarPrecision!!.progress = curveData.precision + seekBarPrecision!!.setOnSeekBarChangeListener(this) + + seekBarA!!.max = 10 + seekBarA!!.progress = (curveData.radiusFixed - 1).toInt() + seekBarA!!.setOnSeekBarChangeListener(this) + + seekBarB!!.max = 10 + seekBarB!!.progress = (curveData.radiusMoving - 1).toInt() + seekBarB!!.setOnSeekBarChangeListener(this) + + seekBarD!!.max = 10 + seekBarD!!.progress = (curveData.distanceFromCenter - 1).toInt() + seekBarD!!.setOnSeekBarChangeListener(this) + + seekBarNumberOfCycles!!.max = 5 + seekBarNumberOfCycles!!.progress = curveData.numberOfCycles - 1 + seekBarNumberOfCycles!!.setOnSeekBarChangeListener(this) + + viewColor1!!.setOnClickListener(this) + viewColor2!!.setOnClickListener(this) + viewColor3!!.setOnClickListener(this) + viewColor4!!.setOnClickListener(this) + viewColor5!!.setOnClickListener(this) + viewColor6!!.setOnClickListener(this) + } + + fun setBaseCurveProgressView(baseCurveProgressView: BaseCurveProgressView) { + this.baseCurveProgressView = baseCurveProgressView + + //Checkbox + checkBoxHasHole!!.isEnabled = this.baseCurveProgressView is BernoullisProgressView || + this.baseCurveProgressView is GeronosProgressView || + this.baseCurveProgressView is BernoullisBowProgressView || + this.baseCurveProgressView is BernoullisSharpProgressView + + //Roulette params + if (this.baseCurveProgressView is BaseRouletteProgressView) { + seekBarA!!.isEnabled = true + seekBarB!!.isEnabled = true + seekBarD!!.isEnabled = true + seekBarNumberOfCycles!!.isEnabled = true + } else { + seekBarA!!.isEnabled = false + seekBarB!!.isEnabled = false + seekBarD!!.isEnabled = false + seekBarNumberOfCycles!!.isEnabled = false + } + + invalidateView(this.baseCurveProgressView) + updateValues() + } + + override fun onProgressChanged(seekBar: SeekBar, i: Int, fromUser: Boolean) { + when (seekBar.id) { + R.id.seekBarStrokeWidth -> curveData.strokeWidth = resources.dpToPx(i / 3f) + R.id.seekBarMaxLineLength -> if (i < seekBarMinLineLength!!.progress) { + seekBarMaxLineLength!!.progress = seekBarMinLineLength!!.progress + } else + curveData.lineMaxLength = (i + 1) / 100f + R.id.seekBarMinLineLength -> if (i > seekBarMaxLineLength!!.progress) { + seekBarMinLineLength!!.progress = seekBarMaxLineLength!!.progress + } else + curveData.lineMinLength = (i + 1) / 100f + R.id.seekBarSizeMultiplier -> curveData.sizeMultiplier = (i + 5) / 10.0f + R.id.seekBarAnimationDuration -> curveData.duration = (i + 1) * 10 + R.id.seekBarPrecision -> curveData.precision = i + 10 + R.id.seekBarA -> curveData.radiusFixed = (i + 1).toFloat() + R.id.seekBarB -> curveData.radiusMoving = (i + 1).toFloat() + R.id.seekBarD -> curveData.distanceFromCenter = (i + 1).toFloat() + R.id.seekBarNumberOfCycles -> curveData.numberOfCycles = i + 1 + } + invalidateView(baseCurveProgressView) + updateValues() + } + + private fun updateValues() { + textStrokeWidth!!.text = curveData.strokeWidth.toString() + textMaxLineLength!!.text = String.format(resources.getString(R.string.format_percentage), (curveData.lineMaxLength * 100).toInt()) + textMinLineLength!!.text = String.format(resources.getString(R.string.format_percentage), (curveData.lineMinLength * 100).toInt()) + textSizeMultiplier!!.text = curveData.sizeMultiplier.toString() + textAnimationDuration!!.text = String.format(resources.getString(R.string.format_ms), curveData.duration) + textPrecision!!.text = String.format(resources.getString(R.string.format_points), curveData.precision) + } + + private fun invalidateView(baseCurveProgressView: BaseCurveProgressView?) { + if (baseCurveProgressView != null) { + baseCurveProgressView.setPrecision(curveData.precision) + baseCurveProgressView.setStrokeWidth(curveData.strokeWidth) + baseCurveProgressView.setLineMaxLength(curveData.lineMaxLength) + baseCurveProgressView.setLineMinLength(curveData.lineMinLength) + baseCurveProgressView.setDuration(curveData.duration) + baseCurveProgressView.setHasHole(curveData.hasHole) + baseCurveProgressView.setColor(curveData.color) + baseCurveProgressView.setSizeMultiplier(curveData.sizeMultiplier) + + if (baseCurveProgressView is BaseRouletteProgressView) { + val baseRouletteProgressView = baseCurveProgressView as BaseRouletteProgressView? + baseRouletteProgressView!!.radiusFixed = curveData.radiusFixed + baseRouletteProgressView.radiusMoving = curveData.radiusMoving + baseRouletteProgressView.distanceFromCenter = curveData.distanceFromCenter + + baseRouletteProgressView.numberOfCycles = curveData.numberOfCycles.toFloat() + } + } + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + + } + + override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) { + when (buttonView.id) { + R.id.checkBoxHasHole -> curveData.hasHole = isChecked + } + invalidateView(baseCurveProgressView) + } + + fun applySettings(baseCurveProgressView: BaseCurveProgressView) { + invalidateView(baseCurveProgressView) + } + + override fun onClick(v: View) { + when (v.id) { + R.id.viewColor1 -> curveData.color = ContextCompat.getColor(context, R.color.picker_color_1) + R.id.viewColor2 -> curveData.color = ContextCompat.getColor(context, R.color.picker_color_2) + R.id.viewColor3 -> curveData.color = ContextCompat.getColor(context, R.color.picker_color_3) + R.id.viewColor4 -> curveData.color = ContextCompat.getColor(context, R.color.picker_color_4) + R.id.viewColor5 -> curveData.color = ContextCompat.getColor(context, R.color.picker_color_5) + R.id.viewColor6 -> curveData.color = ContextCompat.getColor(context, R.color.picker_color_6) + } + invalidateView(baseCurveProgressView) + } + + override fun onSaveInstanceState(outState: Bundle?) { + super.onSaveInstanceState(outState) + outState?.putParcelable("curve_data", curveData) + } +} + +fun Resources.dpToPx(dp: Float): Float { + return dp * this.displayMetrics.density +} diff --git a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.java b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.java deleted file mode 100644 index d7e4439..0000000 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.sample; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentStatePagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.view.Menu; -import android.view.MenuItem; - -import com.vlad1m1r.lemniscate.base.BaseCurveProgressView; - -import static com.vlad1m1r.lemniscate.sample.R.id.viewPager; - -public class MainActivity extends AppCompatActivity implements FragmentCurve.OnViewCreated{ - - private static final int NUM_PAGES = 11; - - private FragmentSettings fragmentSettings; - private ViewPager pager; - - private CurvesPagerAdapter pagerAdapter; - private Toolbar toolbar; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - 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(pager != null && pager.getCurrentItem() == position) fragmentSettings.setBaseCurveProgressView(baseCurveProgressView); - } - - @Override - public void onViewPrepared(int position, BaseCurveProgressView baseCurveProgressView) { - if(pager != null && pager.getCurrentItem() == position) fragmentSettings.setBaseCurveProgressView(baseCurveProgressView); - else fragmentSettings.applySettings(baseCurveProgressView); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_main_activity, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - switch (item.getItemId()) { - case R.id.action_github: - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_github))); - startActivity(browserIntent); - return true; - case R.id.action_presentation: - startActivity(new Intent(this, PresentationActivity.class)); - return true; - } - - 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/MainActivity.kt b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.kt new file mode 100644 index 0000000..fb5de33 --- /dev/null +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/MainActivity.kt @@ -0,0 +1,103 @@ +/* + * 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.sample + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.support.v4.app.Fragment +import android.support.v4.app.FragmentManager +import android.support.v4.app.FragmentStatePagerAdapter +import android.support.v4.view.ViewPager +import android.support.v7.app.AppCompatActivity +import android.support.v7.widget.Toolbar +import android.view.Menu +import android.view.MenuItem + +import com.vlad1m1r.lemniscate.base.BaseCurveProgressView +import me.relex.circleindicator.CircleIndicator + + + +class MainActivity : AppCompatActivity(), FragmentCurve.OnViewCreated { + private val NUM_PAGES = 11 + + private lateinit var fragmentSettings: FragmentSettings + private lateinit var pager: ViewPager + + private lateinit var pagerAdapter: CurvesPagerAdapter + private lateinit var toolbar: Toolbar + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + toolbar = findViewById(R.id.toolbar) + setSupportActionBar(toolbar) + fragmentSettings = supportFragmentManager.findFragmentById(R.id.fragment_settings) as FragmentSettings + pager = findViewById(R.id.viewPager) + pagerAdapter = CurvesPagerAdapter(supportFragmentManager) + val indicator = findViewById(R.id.indicator) + pager.adapter = pagerAdapter + indicator.setViewPager(pager) + + } + + override fun onViewShown(position: Int, baseCurveProgressView: BaseCurveProgressView?) { + if (pager.currentItem == position) fragmentSettings.setBaseCurveProgressView(baseCurveProgressView!!) + } + + override fun onViewPrepared(position: Int, baseCurveProgressView: BaseCurveProgressView?) { + if (pager.currentItem == position) + fragmentSettings.setBaseCurveProgressView(baseCurveProgressView!!) + else + fragmentSettings.applySettings(baseCurveProgressView!!) + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.menu_main_activity, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + + when (item.itemId) { + R.id.action_github -> { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_github))) + startActivity(browserIntent) + return true + } + R.id.action_presentation -> { + startActivity(Intent(this, PresentationActivity::class.java)) + return true + } + } + return super.onOptionsItemSelected(item) + } + + private inner class CurvesPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { + + override fun getItem(position: Int): Fragment { + return FragmentCurve.getInstance(position) + } + + override fun getCount(): Int { + 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 deleted file mode 100644 index f7f583d..0000000 --- a/sample/src/main/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.sample; - -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; - -public class PresentationActivity extends AppCompatActivity { - - private Toolbar toolbar; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_presentation); - 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/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.kt b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.kt new file mode 100644 index 0000000..2ea9012 --- /dev/null +++ b/sample/src/main/java/com/vlad1m1r/lemniscate/sample/PresentationActivity.kt @@ -0,0 +1,37 @@ +/* + * 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.sample + +import android.os.Bundle +import android.support.v7.app.AppCompatActivity +import android.support.v7.widget.Toolbar + +class PresentationActivity : AppCompatActivity() { + + private lateinit var toolbar: Toolbar + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_presentation) + toolbar = findViewById(R.id.toolbar) + setSupportActionBar(toolbar) + supportActionBar?.setTitle(R.string.screen_presentation) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + } +} + diff --git a/sample/src/main/res/drawable/indicator.xml b/sample/src/main/res/drawable/indicator.xml new file mode 100644 index 0000000..4550cfc --- /dev/null +++ b/sample/src/main/res/drawable/indicator.xml @@ -0,0 +1,6 @@ + + + + diff --git a/sample/src/main/res/drawable/indicator_selected.xml b/sample/src/main/res/drawable/indicator_selected.xml new file mode 100644 index 0000000..debf4f8 --- /dev/null +++ b/sample/src/main/res/drawable/indicator_selected.xml @@ -0,0 +1,6 @@ + + + + diff --git a/sample/src/main/res/drawable/shadow.xml b/sample/src/main/res/drawable/shadow.xml new file mode 100644 index 0000000..f7b9413 --- /dev/null +++ b/sample/src/main/res/drawable/shadow.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/sample/src/main/res/layout-land/activity_main.xml b/sample/src/main/res/layout-land/activity_main.xml new file mode 100644 index 0000000..c434bc6 --- /dev/null +++ b/sample/src/main/res/layout-land/activity_main.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index 7866a1d..1851553 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -1,29 +1,52 @@ - - + - + + + + + + + android:background="@color/divider" /> - + android:layout_height="wrap_content"> + + + + + diff --git a/sample/src/main/res/values/colors.xml b/sample/src/main/res/values/colors.xml index 0cf6349..c507792 100644 --- a/sample/src/main/res/values/colors.xml +++ b/sample/src/main/res/values/colors.xml @@ -7,6 +7,8 @@ #212121 #757575 #BDBDBD + #33888888 + #00FFFFFF #4A148C #E91E63