diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3895a8d..39e52fc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,10 +30,10 @@ - diff --git a/app/src/main/java/com/agronick/launcher/Container.kt b/app/src/main/java/com/agronick/launcher/Container.kt index c23febf..ed3ff30 100644 --- a/app/src/main/java/com/agronick/launcher/Container.kt +++ b/app/src/main/java/com/agronick/launcher/Container.kt @@ -1,7 +1,6 @@ package com.agronick.launcher import android.graphics.Canvas -import android.util.Log import util.geometry.Circle import util.geometry.Vector2 import java.util.* @@ -126,7 +125,6 @@ class Container(appList: List, density: Float) { left -= appCircleSize + appCircleMargin } val top = (row * (appCircleSize * 2) + row * appCircleMargin).toFloat() - Log.d(tag, "${left} ${top}") return Pair(left, top) } diff --git a/app/src/main/java/com/agronick/launcher/MainActivity.kt b/app/src/main/java/com/agronick/launcher/MainActivity.kt index 7473a4a..5cba71f 100644 --- a/app/src/main/java/com/agronick/launcher/MainActivity.kt +++ b/app/src/main/java/com/agronick/launcher/MainActivity.kt @@ -11,10 +11,8 @@ import android.view.Window import androidx.core.view.GestureDetectorCompat -var TAG = "main" class MainActivity : Activity(), GestureDetector.OnGestureListener { - private var wasScrolling = false private lateinit var mDetector: GestureDetectorCompat private lateinit var mainView: MainView @@ -47,7 +45,7 @@ class MainActivity : Activity(), GestureDetector.OnGestureListener { } else if (mainView.reorderer != null) { mainView.handleLongPress(event) return true - } else if (wasScrolling && event.action == MotionEvent.ACTION_UP) { + } else if (mainView.wasScrolling && event.action == MotionEvent.ACTION_UP) { mainView.checkOverPanLimit() return true } else { @@ -116,10 +114,8 @@ class MainActivity : Activity(), GestureDetector.OnGestureListener { distanceX: Float, distanceY: Float ): Boolean { - mainView.offsetLeft -= distanceX - mainView.offsetTop -= distanceY - mainView.prepareInvalidate() - wasScrolling = true + mainView.handleScroll(distanceX, distanceY) + mainView.wasScrolling = true return true } diff --git a/app/src/main/java/com/agronick/launcher/MainView.kt b/app/src/main/java/com/agronick/launcher/MainView.kt index ab5f647..9e9626a 100644 --- a/app/src/main/java/com/agronick/launcher/MainView.kt +++ b/app/src/main/java/com/agronick/launcher/MainView.kt @@ -4,6 +4,7 @@ import android.animation.AnimatorSet import android.animation.ValueAnimator import android.content.Context import android.graphics.Canvas +import android.util.Log import android.view.HapticFeedbackConstants import android.view.MotionEvent import android.view.View @@ -23,6 +24,29 @@ class MainView(context: Context, appList: List) : View(context) { private var edgeLimit = 100000f var allHidden = false + var scrollEndFn: (() -> Unit)? = null + var wasScrolling = false + set(value: Boolean) { + if (!wasScrolling) { + Log.e(StaticValues.tag, "ScrollEndFn without scroll") + } + if (scrollEndFn != null) { + scrollEndFn!!() + scrollEndFn = null + } + field = value + } + + private val STATE_NONE = 0 + private val STATE_REORDERING = 1 + private val STATE_OPENING = 2 + + private fun getActiveState(): Int { + if (reorderer != null) return STATE_REORDERING + if (openingApp != null) return STATE_OPENING + return STATE_NONE + } + var openingApp: App? = null init { @@ -33,6 +57,13 @@ class MainView(context: Context, appList: List) : View(context) { var reorderer: Reorderer? = null + fun handleScroll(distanceX: Float, distanceY: Float) { + if (getActiveState() != STATE_NONE) return + offsetLeft -= distanceX + offsetTop -= distanceY + prepareInvalidate() + } + fun resetReorderEdgeTimer() { edgeTimer?.cancel() } @@ -62,22 +93,31 @@ class MainView(context: Context, appList: List) : View(context) { } fun handleLongPress(event: MotionEvent) { + val state = getActiveState() + if (state == STATE_OPENING) return val offset = getRelativePosition(Pair(event.x, event.y)) - if (reorderer != null) { + if (state == STATE_REORDERING) { if (event.action == MotionEvent.ACTION_UP) { - reorderer!!.onStopReorder( - when (container.getLimit(offsetLeft, offsetTop, canvasSize)) { - Pair(offsetLeft, offsetTop) -> container.getAppAtPoint( - Vector2( - offset.x, - offset.y + val scrollEndEvent = { + reorderer!!.onStopReorder( + when (container.getLimit(offsetLeft, offsetTop, canvasSize)) { + Pair(offsetLeft, offsetTop) -> container.getAppAtPoint( + Vector2( + offset.x, + offset.y + ) ) - ) - else -> null - } - ) - reorderer = null - resetReorderEdgeTimer() + else -> null + } + ) + reorderer = null + resetReorderEdgeTimer() + } + if (wasScrolling) { + scrollEndFn = scrollEndEvent + } else { + scrollEndEvent() + } } else { reorderer!!.onMove(offset) val newOffsets = @@ -89,11 +129,12 @@ class MainView(context: Context, appList: List) : View(context) { } prepareInvalidate() } - } else { + } else if (state == STATE_NONE) { val app = container.getAppAtPoint(Vector2(offset.x, offset.y)) if (app != null) { post { - reorderer = Reorderer(container, app, ::prepareInvalidate) + reorderer = + Reorderer(container, app, ::prepareInvalidate, container.appCircleSize) performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK) } } @@ -127,11 +168,15 @@ class MainView(context: Context, appList: List) : View(context) { duration = StaticValues.durationOpen playTogether(*animators.toTypedArray()) start() + doOnEnd { wasScrolling = false } } + } else { + wasScrolling = false } } fun handleClick(x: Float, y: Float) { + if (getActiveState() != STATE_NONE) return val offset = getRelativePosition(Pair(x, y)) val app = container.getAppAtPoint(offset) if (app != null && app.pkgInfo.activityName != null) { @@ -140,6 +185,8 @@ class MainView(context: Context, appList: List) : View(context) { } fun setupOpenAnim(app: App) { + if (getActiveState() != STATE_NONE) return + val face = container.lastCircle ?: return openingApp = app @@ -171,6 +218,7 @@ class MainView(context: Context, appList: List) : View(context) { doOnEnd { postDelayed({ onPackageClick?.let { it1 -> it1(app.pkgInfo) } + openingApp = null }, 200) } start() diff --git a/app/src/main/java/com/agronick/launcher/PreferenceManager.kt b/app/src/main/java/com/agronick/launcher/PreferenceManager.kt index 6b0f19f..b4c1aa4 100644 --- a/app/src/main/java/com/agronick/launcher/PreferenceManager.kt +++ b/app/src/main/java/com/agronick/launcher/PreferenceManager.kt @@ -60,8 +60,8 @@ object PreferenceManager { fun swap(pinfo1: PInfo, pinfo2: PInfo) { // Swap in array - appOrder[pinfo1.order!!] = pinfo2.pname!! - appOrder[pinfo2.order!!] = pinfo1.pname!! + appOrder[pinfo1.order!!] = pinfo2.pname ?: "" + appOrder[pinfo2.order!!] = pinfo1.pname ?: "" // Swap on objects val temp = pinfo1.order diff --git a/app/src/main/java/com/agronick/launcher/Reorderer.kt b/app/src/main/java/com/agronick/launcher/Reorderer.kt index 10d6d53..90fc63d 100644 --- a/app/src/main/java/com/agronick/launcher/Reorderer.kt +++ b/app/src/main/java/com/agronick/launcher/Reorderer.kt @@ -9,7 +9,8 @@ import util.geometry.Vector2 class Reorderer( private val container: Container, private var app: App, - val invalidate: () -> Unit + val invalidate: () -> Unit, + val defaultCircleSize: Int ) { private var suppressedAppCopy: App = app.copy() private var lastPosition = HashSet() @@ -68,7 +69,7 @@ class Reorderer( animateAppPosition(app, overApp.left, overApp.top) PreferenceManager.swap(app.pkgInfo, overApp.pkgInfo) } - ValueAnimator.ofInt((suppressedAppCopy.size * 1.4).toInt(), suppressedAppCopy.size) + ValueAnimator.ofInt((suppressedAppCopy.size * 1.4).toInt(), defaultCircleSize) .apply { duration = StaticValues.durationRise addUpdateListener { animator -> diff --git a/app/src/main/java/com/agronick/launcher/StaticValues.kt b/app/src/main/java/com/agronick/launcher/StaticValues.kt index 31c3eb1..f4769c3 100644 --- a/app/src/main/java/com/agronick/launcher/StaticValues.kt +++ b/app/src/main/java/com/agronick/launcher/StaticValues.kt @@ -7,5 +7,6 @@ class StaticValues { val durationRise = 300L val durationSwap = 300L val durationOpen = 600L + val tag = "Flattery" } } \ No newline at end of file