Draw page indicators on the bottom

This commit is contained in:
Ensar Sarajčić 2023-07-20 12:09:15 +02:00
parent efb46dc0d6
commit 9906ef05af
2 changed files with 45 additions and 4 deletions

View File

@ -24,6 +24,7 @@ import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import androidx.customview.widget.ExploreByTouchHelper import androidx.customview.widget.ExploreByTouchHelper
import com.google.android.material.math.MathUtils
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isSPlus import com.simplemobiletools.commons.helpers.isSPlus
@ -37,6 +38,7 @@ import com.simplemobiletools.launcher.models.HomeScreenGridItem
import kotlinx.android.synthetic.main.activity_main.view.* import kotlinx.android.synthetic.main.activity_main.view.*
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.floor import kotlin.math.floor
import kotlin.math.max
import kotlin.math.min import kotlin.math.min
class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : RelativeLayout(context, attrs, defStyle) { class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : RelativeLayout(context, attrs, defStyle) {
@ -54,8 +56,13 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
private var iconMargin = (context.resources.getDimension(R.dimen.icon_side_margin) * 5 / columnCount).toInt() private var iconMargin = (context.resources.getDimension(R.dimen.icon_side_margin) * 5 / columnCount).toInt()
private var labelSideMargin = context.resources.getDimension(R.dimen.small_margin).toInt() private var labelSideMargin = context.resources.getDimension(R.dimen.small_margin).toInt()
private var roundedCornerRadius = context.resources.getDimension(R.dimen.activity_margin) private var roundedCornerRadius = context.resources.getDimension(R.dimen.activity_margin)
private var pageIndicatorRadius = context.resources.getDimension(R.dimen.page_indicator_dot_radius)
private var pageIndicatorStrokeWidth = context.resources.getDimension(R.dimen.page_indicator_stroke_width)
private var pageIndicatorMargin = context.resources.getDimension(R.dimen.page_indicator_margin)
private var textPaint: TextPaint private var textPaint: TextPaint
private var dragShadowCirclePaint: Paint private var dragShadowCirclePaint: Paint
private var emptyPageIndicatorPaint: Paint
private var currentPageIndicatorPaint: Paint
private var draggedItem: HomeScreenGridItem? = null private var draggedItem: HomeScreenGridItem? = null
private var resizedWidget: HomeScreenGridItem? = null private var resizedWidget: HomeScreenGridItem? = null
private var isFirstDraw = true private var isFirstDraw = true
@ -98,6 +105,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
style = Paint.Style.STROKE style = Paint.Style.STROKE
} }
emptyPageIndicatorPaint = Paint(dragShadowCirclePaint).apply {
strokeWidth = context.resources.getDimension(R.dimen.page_indicator_stroke_width)
}
currentPageIndicatorPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = context.resources.getColor(R.color.hint_white)
style = Paint.Style.FILL
}
val sideMargin = context.resources.getDimension(R.dimen.normal_margin).toInt() val sideMargin = context.resources.getDimension(R.dimen.normal_margin).toInt()
sideMargins.apply { sideMargins.apply {
top = context.statusBarHeight top = context.statusBarHeight
@ -167,6 +182,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
if (item.type == ITEM_TYPE_WIDGET) { if (item.type == ITEM_TYPE_WIDGET) {
appWidgetHost.deleteAppWidgetId(item.widgetId) appWidgetHost.deleteAppWidgetId(item.widgetId)
} }
} }
} }
@ -635,7 +651,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
1 - pageChangeAnimLeftPercentage 1 - pageChangeAnimLeftPercentage
} }
fun handleDrawing(item: HomeScreenGridItem, xFactor: Float) { fun handleItemDrawing(item: HomeScreenGridItem, xFactor: Float) {
if (item.id != draggedItem?.id) { if (item.id != draggedItem?.id) {
val drawableX = cellXCoords[item.left] + iconMargin + extraXMargin + sideMargins.left + (width * xFactor).toInt() val drawableX = cellXCoords[item.left] + iconMargin + extraXMargin + sideMargins.left + (width * xFactor).toInt()
@ -673,14 +689,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
return@forEach return@forEach
} }
handleDrawing(item, currentXFactor) handleItemDrawing(item, currentXFactor)
} }
gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.docked }.forEach { item -> gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.docked }.forEach { item ->
if (item.outOfBounds()) { if (item.outOfBounds()) {
return@forEach return@forEach
} }
handleDrawing(item, 0f) handleItemDrawing(item, 0f)
} }
if (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f) { if (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f) {
gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == lastPage && !it.docked }.forEach { item -> gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == lastPage && !it.docked }.forEach { item ->
@ -688,7 +704,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
return@forEach return@forEach
} }
handleDrawing(item, lastXFactor) handleItemDrawing(item, lastXFactor)
} }
} }
@ -704,6 +720,28 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
} }
} }
// Only draw page indicators when there is a need for it
if (getMaxPage() > 0 || currentPage > 0) {
val pageCount = max(getMaxPage(), currentPage) + 1
val pageIndicatorsRequiredWidth = pageCount * pageIndicatorRadius * 2 + pageCount * (pageIndicatorMargin - 1)
val usableWidth = getFakeWidth()
val pageIndicatorsStart = (usableWidth - pageIndicatorsRequiredWidth) / 2 + sideMargins.left
var currentPageIndicatorLeft = pageIndicatorsStart
val pageIndicatorY = cellYCoords[rowCount - 1].toFloat() + sideMargins.top + extraYMargin + iconMargin
val pageIndicatorStep = pageIndicatorRadius * 2 + pageIndicatorMargin
// Draw empty page indicators
for (page in 0 until pageCount) {
canvas.drawCircle(currentPageIndicatorLeft + pageIndicatorRadius, pageIndicatorY, pageIndicatorRadius, emptyPageIndicatorPaint)
currentPageIndicatorLeft += pageIndicatorStep
}
// Draw current page indicator on exact position
val currentIndicatorRangeStart = pageIndicatorsStart + lastPage * pageIndicatorStep
val currentIndicatorRangeEnd = pageIndicatorsStart + currentPage * pageIndicatorStep
val currentIndicatorPosition = MathUtils.lerp(currentIndicatorRangeStart, currentIndicatorRangeEnd, 1 - pageChangeAnimLeftPercentage)
canvas.drawCircle(currentIndicatorPosition + pageIndicatorRadius, pageIndicatorY, pageIndicatorRadius, currentPageIndicatorPaint)
}
if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) { if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) {
if (draggedItem!!.type == ITEM_TYPE_ICON || draggedItem!!.type == ITEM_TYPE_SHORTCUT) { if (draggedItem!!.type == ITEM_TYPE_ICON || draggedItem!!.type == ITEM_TYPE_SHORTCUT) {
// draw a circle under the current cell // draw a circle under the current cell

View File

@ -6,4 +6,7 @@
<dimen name="icon_side_margin">10dp</dimen> <dimen name="icon_side_margin">10dp</dimen>
<dimen name="resize_frame_dot_radius">8dp</dimen> <dimen name="resize_frame_dot_radius">8dp</dimen>
<dimen name="move_gesture_threshold">5dp</dimen> <dimen name="move_gesture_threshold">5dp</dimen>
<dimen name="page_indicator_dot_radius">4dp</dimen>
<dimen name="page_indicator_stroke_width">1dp</dimen>
<dimen name="page_indicator_margin">4dp</dimen>
</resources> </resources>