Skip to content

Commit

Permalink
fix: a bunch of bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
agronick committed Dec 17, 2023
1 parent 822827b commit b8a865f
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 74 deletions.
1 change: 1 addition & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions app/src/main/java/com/agronick/launcher/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import util.geometry.Vector2
class App(val pkgInfo: PInfo, var size: Int) {
var left = 0.0f
var top = 0.0f
var drawLast = false
var hidden = false
var assignedPos: Pair<Int, Int>? = null
private var lastCircle: Circle? = null
Expand Down Expand Up @@ -102,11 +103,17 @@ class App(val pkgInfo: PInfo, var size: Int) {
val circle = lastCircle
if (circle != null) {
return CircleCircleIntersection(
Circle(point, 3.0f),
circle,
Circle(point, 3.0f)
).type == CircleCircleIntersection.Type.ECCENTRIC_CONTAINED
).type.let {
it == CircleCircleIntersection.Type.ECCENTRIC_CONTAINED
}
}
return false
}

override fun toString(): String {
return pkgInfo.pname ?: "Unmapped"
}

}
12 changes: 10 additions & 2 deletions app/src/main/java/com/agronick/launcher/AppListProvider.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.agronick.launcher

import android.content.Context
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONException
import org.json.JSONObject
import timber.log.Timber
import java.io.File
Expand All @@ -14,7 +16,7 @@ import java.io.FileWriter
class AppListProvider(appList: List<PInfo>, context: Context) {

val positions = HashMap<Int, HashMap<Int, PInfo?>>().withDefault { HashMap() }
val filePath = "${context.dataDir}/appPositions.json"
val filePath = "${context.dataDir}/appPositions2.json"
val mapping = appList.map {
it.asKey() to it
}.toMap().toMutableMap()
Expand All @@ -29,7 +31,12 @@ class AppListProvider(appList: List<PInfo>, context: Context) {
}
val file = FileReader(filePath)
file.readText().let {
val json = JSONObject(it)
val json = try {
JSONObject(it)
} catch (e: JSONException) {
Timber.e("JSON corrupted")
return
}
json.keys().forEach { rowKey ->
val rowInt = rowKey.toInt()
val row = json.getJSONObject(rowKey)
Expand Down Expand Up @@ -77,6 +84,7 @@ class AppListProvider(appList: List<PInfo>, context: Context) {
}
}

@OptIn(DelicateCoroutinesApi::class)
fun save() {
GlobalScope.launch(Dispatchers.IO) {
val jsonObject = JSONObject()
Expand Down
88 changes: 41 additions & 47 deletions app/src/main/java/com/agronick/launcher/Container.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import kotlin.math.roundToInt
import kotlin.math.sqrt

class Container(val appList: AppListProvider, density: Float) {
private val rows: List<List<List<App>>>
val appCircleSize = (StaticValues.normalAppSize * density).roundToInt()
val appCircleMargin = (StaticValues.margin * density).roundToInt()
private val iterate: List<App>
private val flatAppList: List<App>
var lastCircle: Circle? = null

var topLimit = 0f
Expand All @@ -22,8 +21,7 @@ class Container(val appList: AppListProvider, density: Float) {

private var equalizerOffset = 1.1f

init {
/*
init {/*
Tries to set up a rough circle shape
Rows are stored using the outer array index as y pos and inner array as x pos
The middle array holds up to 2 items, one to be drawn at positive y and one at negative y
Expand All @@ -36,56 +34,46 @@ class Container(val appList: AppListProvider, density: Float) {
val appDiam = appRadius * 2
val appRadiusSquared = appRadius * appRadius
val pkgIterator = appList.getPkgIterator()
rows = 0.rangeTo(floor(appRadius).toInt()).mapNotNull outer@{ row ->
// Pythagorean theorem - row length at each level
val rowDiam =
((if (row == 0) appDiam else (sqrt(appRadiusSquared - (row * row)) * 2) - 1)).roundToInt()
val rowGroup = (0..(
if (row == 0) 0 else 1)
).mapNotNull middle@{ sect ->
val cols = (0..rowDiam).mapNotNull inner@{ col ->

flatAppList = sequence {
0.rangeTo(floor(appRadius).toInt()).forEach { row ->
// Pythagorean theorem - row length at each level
val rowDiam = (
if (row == 0) {
appDiam
} else {
(sqrt(appRadiusSquared - (row * row)) * 2) - 1
}
).roundToInt()
(0..kotlin.math.min(row, 1)).forEach { sect ->
(0..rowDiam).forEach { col ->
if (pkgIterator.hasMore()) {
return@inner App(
val maybeNegativeRow = if (sect == 0) {
row
} else {
-row
}
yield(App(
pkgIterator.get(
row, if (sect == 0) {
col
} else {
-col
}
) ?: PInfo.getBlank(),
appCircleSize
)
maybeNegativeRow, col
) ?: PInfo.getBlank(), appCircleSize
).apply {
assignedPos = Pair(maybeNegativeRow, col)
})
}
return@inner null
}
return@middle cols.ifEmpty { null }
}
return@outer rowGroup.ifEmpty { null }
}

}
}.toList()

appList.save()

iterate = sequence {
rows.forEachIndexed { rowCount, parts ->
parts.getOrNull(0)?.forEachIndexed { colCount, app ->
yield(app.apply {
assignedPos = Pair(rowCount, colCount)
})
}
parts.getOrNull(1)?.forEachIndexed { colCount, app ->
yield(app.apply {
assignedPos = Pair(-rowCount, colCount)
})
}
}
}.toList()
position()
}


private fun position() {
iterate.forEach { app ->
flatAppList.forEach { app ->
val positions = calcPositions(app.assignedPos!!.first, app.assignedPos!!.second)
app.left = positions.first
app.top = positions.second
Expand All @@ -109,7 +97,14 @@ class Container(val appList: AppListProvider, density: Float) {
}

fun draw(canvas: Canvas) {
iterate.forEach {
flatAppList.filter {
return@filter if (it.drawLast) {
true
} else {
it.drawNormal(canvas)
false
}
}.forEach {
it.drawNormal(canvas)
}
}
Expand All @@ -135,7 +130,7 @@ class Container(val appList: AppListProvider, density: Float) {
}

fun getAppAtPoint(point: Vector2, toIgnore: HashSet<App>? = null): App? {
return iterate.find {
return flatAppList.find {
(if (toIgnore != null) !toIgnore.contains(it) else true) && it.intersects(
point
)
Expand All @@ -145,11 +140,10 @@ class Container(val appList: AppListProvider, density: Float) {
fun prepare(offsetLeft: Float, offsetTop: Float, size: Float) {
lastCircle = Circle(
Vector2(
-offsetLeft,
-offsetTop
), ceil(size * 0.5).toFloat()
-offsetLeft, -offsetTop
), ceil(size * 0.5f)
)
iterate.forEach {
flatAppList.forEach {
it.prepare(lastCircle!!)
}
}
Expand Down
46 changes: 25 additions & 21 deletions app/src/main/java/com/agronick/launcher/MainView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ package com.agronick.launcher

import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.view.HapticFeedbackConstants
import android.view.MotionEvent
import android.view.View
import androidx.core.animation.doOnEnd
import timber.log.Timber
import util.geometry.Vector2
import java.util.*
import java.util.Timer
import java.util.TimerTask

@SuppressLint("ViewConstructor")
class MainView(context: Context, appList: List<PInfo>) : View(context) {
private var edgeTimer: Timer? = null
private var density: Float = context.resources.displayMetrics.density
Expand Down Expand Up @@ -45,13 +49,6 @@ class MainView(context: Context, appList: List<PInfo>) : 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()
}
Expand Down Expand Up @@ -88,12 +85,19 @@ class MainView(context: Context, appList: List<PInfo>) : View(context) {
if (event.action == MotionEvent.ACTION_UP) {
reorderer!!.onStopReorder(
when (container.getLimit(offsetLeft, offsetTop, canvasSize)) {
Pair(offsetLeft, offsetTop) -> container.getAppAtPoint(
Vector2(
offset.x,
offset.y
)
)
Pair(offsetLeft, offsetTop) -> {
Timber.i("Looking up what is at ${offset.x} ${offset.y} to end reorder")
container.getAppAtPoint(
Vector2(
offset.x,
offset.y
),
reorderer!!.lastPosition
)?.also {
Timber.i("Found ${it.pkgInfo.pname} at ${it.left} ${it.top} to swap with")
}
}

else -> null
}
)
Expand All @@ -111,10 +115,11 @@ class MainView(context: Context, appList: List<PInfo>) : View(context) {
prepareInvalidate()
}
} else if (state == STATE_NONE) {
val app = container.getAppAtPoint(Vector2(offset.x, offset.y))
if (app != null) {
Timber.i("Looking up what is at ${offset.x} ${offset.y} to start reorder")
container.getAppAtPoint(Vector2(offset.x, offset.y))?.let {
Timber.i("Going to recorder ${it.pkgInfo.pname} at ${it.left} ${it.top}")
post {
reorderer = Reorderer(container, app, ::prepareInvalidate)
reorderer = Reorderer(container, it, ::prepareInvalidate)
performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
}
}
Expand Down Expand Up @@ -212,10 +217,9 @@ class MainView(context: Context, appList: List<PInfo>) : View(context) {
fun getRelativePosition(point: Pair<Float, Float>? = null): Vector2 {
val halfSize = canvasSize * 0.5f
val pos = Vector2(halfSize + offsetLeft, halfSize + offsetTop)
if (point != null) {
return Vector2(point.first - pos.x, point.second - pos.y)
}
return pos
return point?.let {
Vector2(it.first - pos.x, it.second - pos.y)
} ?: pos
}

fun prepareInvalidate() {
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/java/com/agronick/launcher/Reorderer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.agronick.launcher
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import androidx.core.animation.doOnEnd
import timber.log.Timber
import util.geometry.Circle
import util.geometry.Vector2

Expand All @@ -12,11 +13,12 @@ class Reorderer(
val invalidate: () -> Unit,
) {
private var suppressedAppCopy: App = app.copy()
private var lastPosition = HashSet<App>()
var lastPosition = HashSet<App>()
private val defaultCircleSize = container.appCircleSize
private val appList = container.appList

init {
app.drawLast = true
lastPosition.add(app)
suppressedAppCopy.hidden = true
ValueAnimator.ofInt(app.size, (app.size * 1.4).toInt())
Expand Down Expand Up @@ -57,6 +59,7 @@ class Reorderer(
playTogether(xAnim, yAnim)
doOnEnd {
lastPosition.remove(app)
app.drawLast = false
}
start()
}
Expand All @@ -66,7 +69,9 @@ class Reorderer(
if (overApp == null) {
animateAppPosition(app, suppressedAppCopy.left, suppressedAppCopy.top)
} else {
Timber.i("Sending ${overApp} to ${suppressedAppCopy.left} ${suppressedAppCopy.top}")
animateAppPosition(overApp, suppressedAppCopy.left, suppressedAppCopy.top)
Timber.i("Sending ${app} to ${overApp.left} ${overApp.top}")
animateAppPosition(app, overApp.left, overApp.top)
appList.swap(app, overApp)
appList.save()
Expand All @@ -93,5 +98,4 @@ class Reorderer(
}
return null
}

}

0 comments on commit b8a865f

Please sign in to comment.