From b0ca17cea2f0ed4d7951714267cfecb0826c8c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Tue, 18 Jul 2023 17:34:16 +0200 Subject: [PATCH 01/18] Implement multiple panes for home screen grid This closes #47 --- .../launcher/activities/MainActivity.kt | 37 ++++++++--- .../launcher/databases/AppsDatabase.kt | 9 ++- .../launcher/fragments/AllAppsFragment.kt | 1 + .../launcher/fragments/WidgetsFragment.kt | 1 + .../launcher/interfaces/FlingListener.kt | 4 ++ .../interfaces/HomeScreenGridItemsDao.kt | 4 +- .../launcher/models/HomeScreenGridItem.kt | 3 +- .../launcher/views/HomeScreenGrid.kt | 63 +++++++++++++++++-- 8 files changed, 103 insertions(+), 19 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt index 0dadc51..c3e9e5b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -50,6 +50,7 @@ import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.view.* import kotlinx.android.synthetic.main.all_apps_fragment.view.* import kotlinx.android.synthetic.main.widgets_fragment.view.* +import kotlin.math.abs class MainActivity : SimpleActivity(), FlingListener { private val ANIMATION_DURATION = 150L @@ -118,6 +119,7 @@ class MainActivity : SimpleActivity(), FlingListener { rect.top, rect.right, rect.bottom, + 0, item.shortcutInfo!!.`package`, "", label, @@ -641,11 +643,20 @@ class MainActivity : SimpleActivity(), FlingListener { return true } - if (velocityY > 0) { - flingListener.onFlingDown() - } else { - flingListener.onFlingUp() + if (abs(velocityY) > abs(velocityX)) { + if (velocityY > 0) { + flingListener.onFlingDown() + } else { + flingListener.onFlingUp() + } + } else if (abs(velocityX) > abs(velocityY)) { + if (velocityX > 0) { + flingListener.onFlingRight() + } else { + flingListener.onFlingLeft() + } } + return true } @@ -676,6 +687,14 @@ class MainActivity : SimpleActivity(), FlingListener { } } + override fun onFlingRight() { + home_screen_grid.prevPage(redraw = true) + } + + override fun onFlingLeft() { + home_screen_grid.nextPage(redraw = true) + } + @SuppressLint("WrongConstant") fun getAllAppLaunchers(): ArrayList { val hiddenIcons = hiddenIconsDB.getHiddenIcons().map { @@ -722,7 +741,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultDialerPackage = (getSystemService(Context.TELECOM_SERVICE) as TelecomManager).defaultDialerPackage appLaunchers.firstOrNull { it.packageName == defaultDialerPackage }?.apply { val dialerIcon = - HomeScreenGridItem(null, 0, ROW_COUNT - 1, 0, ROW_COUNT - 1, defaultDialerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 0, ROW_COUNT - 1, 0, ROW_COUNT - 1, 0, defaultDialerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(dialerIcon) } } catch (e: Exception) { @@ -732,7 +751,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultSMSMessengerPackage = Telephony.Sms.getDefaultSmsPackage(this) appLaunchers.firstOrNull { it.packageName == defaultSMSMessengerPackage }?.apply { val SMSMessengerIcon = - HomeScreenGridItem(null, 1, ROW_COUNT - 1, 1, ROW_COUNT - 1, defaultSMSMessengerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 1, ROW_COUNT - 1, 1, ROW_COUNT - 1, 0, defaultSMSMessengerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(SMSMessengerIcon) } } catch (e: Exception) { @@ -744,7 +763,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultBrowserPackage = resolveInfo!!.activityInfo.packageName appLaunchers.firstOrNull { it.packageName == defaultBrowserPackage }?.apply { val browserIcon = - HomeScreenGridItem(null, 2, ROW_COUNT - 1, 2, ROW_COUNT - 1, defaultBrowserPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 2, ROW_COUNT - 1, 2, ROW_COUNT - 1, 0, defaultBrowserPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(browserIcon) } } catch (e: Exception) { @@ -755,7 +774,7 @@ class MainActivity : SimpleActivity(), FlingListener { val storePackage = potentialStores.firstOrNull { isPackageInstalled(it) && appLaunchers.map { it.packageName }.contains(it) } if (storePackage != null) { appLaunchers.firstOrNull { it.packageName == storePackage }?.apply { - val storeIcon = HomeScreenGridItem(null, 3, ROW_COUNT - 1, 3, ROW_COUNT - 1, storePackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + val storeIcon = HomeScreenGridItem(null, 3, ROW_COUNT - 1, 3, ROW_COUNT - 1, 0, storePackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(storeIcon) } } @@ -768,7 +787,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultCameraPackage = resolveInfo!!.activityInfo.packageName appLaunchers.firstOrNull { it.packageName == defaultCameraPackage }?.apply { val cameraIcon = - HomeScreenGridItem(null, 4, ROW_COUNT - 1, 4, ROW_COUNT - 1, defaultCameraPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 4, ROW_COUNT - 1, 4, ROW_COUNT - 1, 0, defaultCameraPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(cameraIcon) } } catch (e: Exception) { diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt index de46cc2..f6e85d9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt @@ -15,7 +15,7 @@ import com.simplemobiletools.launcher.models.AppLauncher import com.simplemobiletools.launcher.models.HiddenIcon import com.simplemobiletools.launcher.models.HomeScreenGridItem -@Database(entities = [AppLauncher::class, HomeScreenGridItem::class, HiddenIcon::class], version = 4) +@Database(entities = [AppLauncher::class, HomeScreenGridItem::class, HiddenIcon::class], version = 5) @TypeConverters(Converters::class) abstract class AppsDatabase : RoomDatabase() { @@ -36,6 +36,7 @@ abstract class AppsDatabase : RoomDatabase() { .addMigrations(MIGRATION_1_2) .addMigrations(MIGRATION_2_3) .addMigrations(MIGRATION_3_4) + .addMigrations(MIGRATION_4_5) .build() } } @@ -64,5 +65,11 @@ abstract class AppsDatabase : RoomDatabase() { database.execSQL("CREATE UNIQUE INDEX `index_hidden_icons_id` ON `hidden_icons` (`id`)") } } + + private val MIGRATION_4_5 = object : Migration(4, 5) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE home_screen_grid_items ADD COLUMN page INTEGER NOT NULL DEFAULT 0") + } + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt index fe4a5d5..d4b4214 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt @@ -198,6 +198,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment -1, -1, -1, + 0, appLauncher.packageName, appLauncher.activityName, appLauncher.title, diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt index 189906a..eb6c8ba 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt @@ -250,6 +250,7 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment -1, -1, -1, + 0, appWidget.appPackageName, "", "", diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/FlingListener.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/FlingListener.kt index 3b5dd09..b9dd60e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/FlingListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/FlingListener.kt @@ -4,4 +4,8 @@ interface FlingListener { fun onFlingUp() fun onFlingDown() + + fun onFlingRight() + + fun onFlingLeft() } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt index 1eda528..7abd805 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt @@ -23,8 +23,8 @@ interface HomeScreenGridItemsDao { @Query("UPDATE home_screen_grid_items SET title = :title WHERE id = :id") fun updateItemTitle(title: String, id: Long): Int - @Query("UPDATE home_screen_grid_items SET `left` = :left, `top` = :top, `right` = :right, `bottom` = :bottom WHERE id = :id") - fun updateItemPosition(left: Int, top: Int, right: Int, bottom: Int, id: Long) + @Query("UPDATE home_screen_grid_items SET `left` = :left, `top` = :top, `right` = :right, `bottom` = :bottom, `page` = :page WHERE id = :id") + fun updateItemPosition(left: Int, top: Int, right: Int, bottom: Int, page: Int, id: Long) @Query("DELETE FROM home_screen_grid_items WHERE id = :id") fun deleteById(id: Long) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt index 935f1ed..0d4b38c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt @@ -15,6 +15,7 @@ data class HomeScreenGridItem( @ColumnInfo(name = "top") var top: Int, @ColumnInfo(name = "right") var right: Int, @ColumnInfo(name = "bottom") var bottom: Int, + @ColumnInfo(name = "page") var page: Int, @ColumnInfo(name = "package_name") var packageName: String, @ColumnInfo(name = "activity_name") var activityName: String, // needed at apps that create multiple icons at install, not just the launcher @ColumnInfo(name = "title") var title: String, @@ -31,7 +32,7 @@ data class HomeScreenGridItem( @Ignore var widthCells: Int = 1, @Ignore var heightCells: Int = 1 ) { - constructor() : this(null, -1, -1, -1, -1, "", "", "", ITEM_TYPE_ICON, "", -1, "", "", null, null, null, null, 1, 1) + constructor() : this(null, -1, -1, -1, -1, 0, "", "", "", ITEM_TYPE_ICON, "", -1, "", "", null, null, null, null, 1, 1) fun getWidthInCells() = if (right == -1 || left == -1) { widthCells diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index d87a4fd..b98196d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -13,6 +13,7 @@ import android.text.StaticLayout import android.text.TextPaint import android.text.TextUtils import android.util.AttributeSet +import android.util.Log import android.util.Size import android.util.SizeF import android.view.View @@ -51,6 +52,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel var cellWidth = 0 var cellHeight = 0 + private var currentPage = 0 + private var pageChangeEnabled = true + // apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides var sideMargins = Rect() @@ -165,6 +169,11 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } draggedItemCurrentCoords = Pair(x, y) + if (x > right - sideMargins.right) { + nextOrAdditionalPage() + } else if (x < left + 2 * sideMargins.left) { + prevPage() + } redrawGrid() } @@ -210,7 +219,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel item.bottom = cellsRect.bottom updateWidgetPositionAndSize(widgetView, item) ensureBackgroundThread { - context.homeScreenGridItemsDB.updateItemPosition(cellsRect.left, cellsRect.top, cellsRect.right, cellsRect.bottom, item.id!!) + context.homeScreenGridItemsDB.updateItemPosition(cellsRect.left, cellsRect.top, cellsRect.right, cellsRect.bottom, item.page, item.id!!) } } @@ -249,7 +258,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel // check if the destination cell is empty var areAllCellsEmpty = true val wantedCell = Pair(xIndex, yIndex) - gridItems.forEach { item -> + gridItems.filter { it.page == currentPage }.forEach { item -> for (xCell in item.left..item.right) { for (yCell in item.top..item.bottom) { val cell = Pair(xCell, yCell) @@ -272,9 +281,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel top = yIndex right = xIndex bottom = yIndex + page = currentPage ensureBackgroundThread { - context.homeScreenGridItemsDB.updateItemPosition(left, top, right, bottom, id!!) + context.homeScreenGridItemsDB.updateItemPosition(left, top, right, bottom, page, id!!) } } redrawIcons = true @@ -286,6 +296,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel yIndex, xIndex, yIndex, + currentPage, draggedItem!!.packageName, draggedItem!!.activityName, draggedItem!!.title, @@ -372,6 +383,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel top = widgetRect.top right = widgetRect.right bottom = widgetRect.bottom + page = currentPage } ensureBackgroundThread { @@ -383,7 +395,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel bindWidget(widgetItem, false) } } else { - context.homeScreenGridItemsDB.updateItemPosition(widgetItem.left, widgetItem.top, widgetItem.right, widgetItem.bottom, widgetItem.id!!) + context.homeScreenGridItemsDB.updateItemPosition( + widgetItem.left, + widgetItem.top, + widgetItem.right, + widgetItem.bottom, + currentPage, + widgetItem.id!! + ) val widgetView = widgetViews.firstOrNull { it.tag == widgetItem.widgetId } if (widgetView != null) { post { @@ -398,6 +417,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel right = widgetItem.right top = widgetItem.top bottom = widgetItem.bottom + page = widgetItem.page } } } @@ -529,7 +549,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel fillCellSizes() } - gridItems.filter { it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT }.forEach { item -> + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage }.forEach { item -> if (item.id != draggedItem?.id) { val drawableX = cellXCoords[item.left] + iconMargin + sideMargins.left @@ -563,7 +583,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } if (isFirstDraw) { - gridItems.filter { it.type == ITEM_TYPE_WIDGET }.forEach { item -> + gridItems.filter { it.type == ITEM_TYPE_WIDGET && it.page == currentPage }.forEach { item -> bindWidget(item, true) } } @@ -771,4 +791,35 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } + + private fun getMaxPage() = gridItems.map { it.page }.max() + + private fun nextOrAdditionalPage(redraw: Boolean = false) { + if (currentPage < getMaxPage() + 1 && pageChangeEnabled) { + currentPage++ + handlePageChange(redraw) + } + } + + fun nextPage(redraw: Boolean = false) { + if (currentPage < getMaxPage() && pageChangeEnabled) { + currentPage++ + handlePageChange(redraw) + } + } + + fun prevPage(redraw: Boolean = false) { + if (currentPage > 0 && pageChangeEnabled) { + currentPage-- + handlePageChange(redraw) + } + } + + private fun handlePageChange(redraw: Boolean = false) { + pageChangeEnabled = false + if (redraw) { + redrawGrid() + } + postDelayed({ pageChangeEnabled = true }, 700L) + } } From 468b89bc21ad733236a0f7c8b74264027d507363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Tue, 18 Jul 2023 18:04:59 +0200 Subject: [PATCH 02/18] Add basic page change animations --- .../launcher/views/HomeScreenGrid.kt | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index b98196d..50d8ebb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -1,5 +1,8 @@ package com.simplemobiletools.launcher.views +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.ValueAnimator import android.annotation.SuppressLint import android.appwidget.AppWidgetHostView import android.appwidget.AppWidgetManager @@ -13,7 +16,6 @@ import android.text.StaticLayout import android.text.TextPaint import android.text.TextUtils import android.util.AttributeSet -import android.util.Log import android.util.Size import android.util.SizeF import android.view.View @@ -52,7 +54,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel var cellWidth = 0 var cellHeight = 0 + private var lastPage = 0 private var currentPage = 0 + private var animPercentage = 0f private var pageChangeEnabled = true // apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides @@ -549,9 +553,20 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel fillCellSizes() } - gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage }.forEach { item -> + val currentXFactor = if (currentPage > lastPage) { + animPercentage + } else { + -animPercentage + } + val lastXFactor = if (currentPage > lastPage) { + animPercentage - 1 + } else { + 1 - animPercentage + } + + fun handleDrawing(item: HomeScreenGridItem, xFactor: Float) { if (item.id != draggedItem?.id) { - val drawableX = cellXCoords[item.left] + iconMargin + sideMargins.left + val drawableX = cellXCoords[item.left] + iconMargin + sideMargins.left + (width * xFactor).toInt() // icons at the bottom are drawn at the bottom of the grid and they have no label if (item.top == ROW_COUNT - 1) { @@ -562,7 +577,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize) if (item.id != draggedItem?.id && item.title.isNotEmpty()) { - val textX = cellXCoords[item.left].toFloat() + labelSideMargin + sideMargins.left + val textX = cellXCoords[item.left].toFloat() + labelSideMargin + sideMargins.left + width * xFactor val textY = cellYCoords[item.top] + iconSize * 1.5f + labelSideMargin + sideMargins.top val staticLayout = StaticLayout.Builder .obtain(item.title, 0, item.title.length, textPaint, cellWidth - 2 * labelSideMargin) @@ -582,6 +597,15 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage }.forEach { item -> + handleDrawing(item, currentXFactor) + } + if (animPercentage > 0f && animPercentage < 1f) { + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == lastPage }.forEach { item -> + handleDrawing(item, lastXFactor) + } + } + if (isFirstDraw) { gridItems.filter { it.type == ITEM_TYPE_WIDGET && it.page == currentPage }.forEach { item -> bindWidget(item, true) @@ -796,6 +820,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private fun nextOrAdditionalPage(redraw: Boolean = false) { if (currentPage < getMaxPage() + 1 && pageChangeEnabled) { + lastPage = currentPage currentPage++ handlePageChange(redraw) } @@ -803,6 +828,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel fun nextPage(redraw: Boolean = false) { if (currentPage < getMaxPage() && pageChangeEnabled) { + lastPage = currentPage currentPage++ handlePageChange(redraw) } @@ -810,6 +836,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel fun prevPage(redraw: Boolean = false) { if (currentPage > 0 && pageChangeEnabled) { + lastPage = currentPage currentPage-- handlePageChange(redraw) } @@ -820,6 +847,26 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel if (redraw) { redrawGrid() } - postDelayed({ pageChangeEnabled = true }, 700L) + postDelayed({ pageChangeEnabled = true }, PAGE_CHANGE_BLOCKING_DURATION) + ValueAnimator.ofFloat(1f, 0f) + .apply { + addUpdateListener { + animPercentage = it.animatedValue as Float + redrawGrid() + } + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + super.onAnimationEnd(animation) + animPercentage = 0f + redrawGrid() + } + }) + start() + } + } + + companion object { + private const val ANIMATION_DURATION = 700L + private const val PAGE_CHANGE_BLOCKING_DURATION = ANIMATION_DURATION + 200L } } From 1d0f814e9f0b4601e5a8bb6bd4d10a91e0a346da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Tue, 18 Jul 2023 18:06:31 +0200 Subject: [PATCH 03/18] Update anim percentage for clarity --- .../launcher/views/HomeScreenGrid.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 50d8ebb..8855c5a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -56,7 +56,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private var lastPage = 0 private var currentPage = 0 - private var animPercentage = 0f + private var pageChangeAnimLeftPercentage = 0f private var pageChangeEnabled = true // apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides @@ -554,14 +554,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } val currentXFactor = if (currentPage > lastPage) { - animPercentage + pageChangeAnimLeftPercentage } else { - -animPercentage + -pageChangeAnimLeftPercentage } val lastXFactor = if (currentPage > lastPage) { - animPercentage - 1 + pageChangeAnimLeftPercentage - 1 } else { - 1 - animPercentage + 1 - pageChangeAnimLeftPercentage } fun handleDrawing(item: HomeScreenGridItem, xFactor: Float) { @@ -600,7 +600,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage }.forEach { item -> handleDrawing(item, currentXFactor) } - if (animPercentage > 0f && animPercentage < 1f) { + if (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f) { gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == lastPage }.forEach { item -> handleDrawing(item, lastXFactor) } @@ -851,13 +851,13 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel ValueAnimator.ofFloat(1f, 0f) .apply { addUpdateListener { - animPercentage = it.animatedValue as Float + pageChangeAnimLeftPercentage = it.animatedValue as Float redrawGrid() } addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { super.onAnimationEnd(animation) - animPercentage = 0f + pageChangeAnimLeftPercentage = 0f redrawGrid() } }) From 9dc9e90e0e03bff2b6ea742d764a59558567edec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Tue, 18 Jul 2023 18:22:20 +0200 Subject: [PATCH 04/18] Add animations for widgets --- .../launcher/views/HomeScreenGrid.kt | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 8855c5a..17407dc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -493,7 +493,26 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } private fun updateWidgetPositionAndSize(widgetView: AppWidgetHostView, item: HomeScreenGridItem): Size { - widgetView.x = calculateWidgetX(item.left) + var x = calculateWidgetX(item.left) + width * item.page - width * lastPage + if (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f && (item.page == currentPage || item.page == lastPage)) { + val xFactor = if (currentPage > lastPage) { + pageChangeAnimLeftPercentage + } else { + -pageChangeAnimLeftPercentage + } + val lastXFactor = if (currentPage > lastPage) { + pageChangeAnimLeftPercentage - 1 + } else { + 1 - pageChangeAnimLeftPercentage + } + if (item.page == currentPage) { + x += width * xFactor + } + if (item.page == lastPage) { + x += width * lastXFactor + } + } + widgetView.x = x widgetView.y = calculateWidgetY(item.top) val widgetWidth = item.getWidthInCells() * cellWidth val widgetHeight = item.getHeightInCells() * cellHeight @@ -607,9 +626,15 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } if (isFirstDraw) { - gridItems.filter { it.type == ITEM_TYPE_WIDGET && it.page == currentPage }.forEach { item -> + gridItems.filter { it.type == ITEM_TYPE_WIDGET }.forEach { item -> bindWidget(item, true) } + } else { + gridItems.filter { it.type == ITEM_TYPE_WIDGET }.forEach { item -> + widgetViews.firstOrNull { it.tag == item.widgetId }?.also { + updateWidgetPositionAndSize(it, item) + } + } } if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) { @@ -858,6 +883,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel override fun onAnimationEnd(animation: Animator) { super.onAnimationEnd(animation) pageChangeAnimLeftPercentage = 0f + lastPage = currentPage redrawGrid() } }) From f0eb1254a36cd9df1d8ee451635d5173cf2d4177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Tue, 18 Jul 2023 18:25:40 +0200 Subject: [PATCH 05/18] Fix occupied position calculation for offpage items --- .../com/simplemobiletools/launcher/views/HomeScreenGrid.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 17407dc..d7d01e5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -367,7 +367,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } var areAllCellsEmpty = true - gridItems.filter { it.id != draggedItem?.id }.forEach { item -> + gridItems.filter { it.id != draggedItem?.id && it.page == currentPage }.forEach { item -> for (xCell in item.left..item.right) { for (yCell in item.top..item.bottom) { val cell = Pair(xCell, yCell) @@ -764,7 +764,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? { - for (gridItem in gridItems) { + for (gridItem in gridItems.filter { it.page == currentPage }) { if (gridItem.type == ITEM_TYPE_ICON || gridItem.type == ITEM_TYPE_SHORTCUT) { val rect = getClickableRect(gridItem) if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) { From d4b131ab2368237093facf50503df01b418696d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 19 Jul 2023 15:45:29 +0200 Subject: [PATCH 06/18] Increase page change area and introduce delay to prevent accidental page changes --- .../launcher/views/HomeScreenGrid.kt | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index d7d01e5..a50b0fb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -56,6 +56,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private var lastPage = 0 private var currentPage = 0 + private var pageChangeLastArea = PageChangeArea.MIDDLE + private var pageChangeLastAreaEntryTime = 0L private var pageChangeAnimLeftPercentage = 0f private var pageChangeEnabled = true @@ -173,14 +175,36 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } draggedItemCurrentCoords = Pair(x, y) - if (x > right - sideMargins.right) { - nextOrAdditionalPage() - } else if (x < left + 2 * sideMargins.left) { - prevPage() + if (x > right - sideMargins.right - cellWidth / 2) { + doWithPageChangeDelay(PageChangeArea.RIGHT) { + nextOrAdditionalPage() + } + } else if (x < left + sideMargins.left + cellWidth / 2) { + doWithPageChangeDelay(PageChangeArea.LEFT) { + prevPage() + } + } else { + clearPageChangeFlags() } redrawGrid() } + private fun clearPageChangeFlags() { + pageChangeLastArea = PageChangeArea.MIDDLE + pageChangeLastAreaEntryTime = 0 + } + + private fun doWithPageChangeDelay(needed: PageChangeArea, pageChangeFunction: () -> Boolean) { + if (pageChangeLastArea != needed) { + pageChangeLastArea = needed + pageChangeLastAreaEntryTime = System.currentTimeMillis() + } else if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { + if (pageChangeFunction()) { + clearPageChangeFlags() + } + } + } + // figure out at which cell was the item dropped, if it is empty fun itemDraggingStopped() { widgetViews.forEach { @@ -843,28 +867,37 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private fun getMaxPage() = gridItems.map { it.page }.max() - private fun nextOrAdditionalPage(redraw: Boolean = false) { + private fun nextOrAdditionalPage(redraw: Boolean = false): Boolean { if (currentPage < getMaxPage() + 1 && pageChangeEnabled) { lastPage = currentPage currentPage++ handlePageChange(redraw) + return true } + + return false } - fun nextPage(redraw: Boolean = false) { + fun nextPage(redraw: Boolean = false): Boolean { if (currentPage < getMaxPage() && pageChangeEnabled) { lastPage = currentPage currentPage++ handlePageChange(redraw) + return true } + + return false } - fun prevPage(redraw: Boolean = false) { + fun prevPage(redraw: Boolean = false): Boolean { if (currentPage > 0 && pageChangeEnabled) { lastPage = currentPage currentPage-- handlePageChange(redraw) + return true } + + return false } private fun handlePageChange(redraw: Boolean = false) { @@ -894,5 +927,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel companion object { private const val ANIMATION_DURATION = 700L private const val PAGE_CHANGE_BLOCKING_DURATION = ANIMATION_DURATION + 200L + private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L + + private enum class PageChangeArea { + LEFT, + MIDDLE, + RIGHT + } } } From 374276222053565c29e5ee2961fd1555281fa922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 19 Jul 2023 16:09:27 +0200 Subject: [PATCH 07/18] Handle pages in shortcut pin request --- .../launcher/activities/MainActivity.kt | 27 ++++++++++--------- .../launcher/views/HomeScreenGrid.kt | 16 ++++++++++- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt index c3e9e5b..7a72b2c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -112,14 +112,14 @@ class MainActivity : SimpleActivity(), FlingListener { val shortcutId = item.shortcutInfo?.id!! val label = item.shortcutInfo?.shortLabel?.toString() ?: item.shortcutInfo?.longLabel?.toString() ?: "" val icon = launcherApps.getShortcutIconDrawable(item.shortcutInfo!!, resources.displayMetrics.densityDpi) - val rect = findFirstEmptyCell() ?: return@ensureBackgroundThread + val (page, rect) = findFirstEmptyCell() val gridItem = HomeScreenGridItem( null, rect.left, rect.top, rect.right, rect.bottom, - 0, + page, item.shortcutInfo!!.`package`, "", label, @@ -137,7 +137,7 @@ class MainActivity : SimpleActivity(), FlingListener { try { item.accept() - home_screen_grid.storeAndShowGridItem(gridItem) + home_screen_grid.storeAndShowGridItem(gridItem, navigateToPage = true) } catch (ignored: IllegalStateException) { } } @@ -152,27 +152,30 @@ class MainActivity : SimpleActivity(), FlingListener { } } - private fun findFirstEmptyCell(): Rect? { + private fun findFirstEmptyCell(): Pair { val gridItems = homeScreenGridItemsDB.getAllItems() as ArrayList - val occupiedCells = ArrayList>() + val maxPage = gridItems.map { it.page }.max() + val occupiedCells = ArrayList>() gridItems.forEach { item -> for (xCell in item.left..item.right) { for (yCell in item.top..item.bottom) { - occupiedCells.add(Pair(xCell, yCell)) + occupiedCells.add(Triple(item.page, xCell, yCell)) } } } - for (checkedYCell in 0 until COLUMN_COUNT) { - for (checkedXCell in 0 until ROW_COUNT - 1) { - val wantedCell = Pair(checkedXCell, checkedYCell) - if (!occupiedCells.contains(wantedCell)) { - return Rect(wantedCell.first, wantedCell.second, wantedCell.first, wantedCell.second) + for (page in 0 until maxPage) { + for (checkedYCell in 0 until COLUMN_COUNT) { + for (checkedXCell in 0 until ROW_COUNT - 1) { + val wantedCell = Triple(page, checkedXCell, checkedYCell) + if (!occupiedCells.contains(wantedCell)) { + return Pair(page, Rect(wantedCell.first, wantedCell.second, wantedCell.first, wantedCell.second)) + } } } } - return null + return Pair(maxPage + 1, Rect(0, 0, 0, 0)) } override fun onStart() { diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index a50b0fb..4ab808f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -368,10 +368,13 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } - fun storeAndShowGridItem(item: HomeScreenGridItem) { + fun storeAndShowGridItem(item: HomeScreenGridItem, navigateToPage: Boolean = false) { val newId = context.homeScreenGridItemsDB.insert(item) item.id = newId gridItems.add(item) + if (navigateToPage) { + skipToPage(item.page) + } redrawGrid() } @@ -900,6 +903,17 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel return false } + private fun skipToPage(targetPage: Int): Boolean { + if (targetPage < getMaxPage() + 1) { + lastPage = currentPage + currentPage = targetPage + handlePageChange() + return true + } + + return false + } + private fun handlePageChange(redraw: Boolean = false) { pageChangeEnabled = false if (redraw) { From 6ac3d0f86c0a7d4d41e98add55497a197b81140c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 19 Jul 2023 16:30:21 +0200 Subject: [PATCH 08/18] Fix shortcut pin intent handling --- .../launcher/activities/MainActivity.kt | 34 +++++++++++++------ .../launcher/views/HomeScreenGrid.kt | 9 ++--- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt index 7a72b2c..2dc524d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -101,6 +101,25 @@ class MainActivity : SimpleActivity(), FlingListener { fragment.beVisible() } + handleIntentAction(intent) + + home_screen_grid.itemClickListener = { + performItemClick(it) + } + + home_screen_grid.itemLongClickListener = { + performItemLongClick(home_screen_grid.getClickableRect(it).left.toFloat(), it) + } + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + if (intent != null) { + handleIntentAction(intent) + } + } + + private fun handleIntentAction(intent: Intent) { if (intent.action == LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT) { val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps val item = launcherApps.getPinItemRequest(intent) @@ -132,24 +151,19 @@ class MainActivity : SimpleActivity(), FlingListener { icon ) + runOnUiThread { + home_screen_grid.skipToPage(page) + } // delay showing the shortcut both to let the user see adding it in realtime and hackily avoid concurrent modification exception at HomeScreenGrid Thread.sleep(2000) try { item.accept() - home_screen_grid.storeAndShowGridItem(gridItem, navigateToPage = true) + home_screen_grid.storeAndShowGridItem(gridItem) } catch (ignored: IllegalStateException) { } } } - - home_screen_grid.itemClickListener = { - performItemClick(it) - } - - home_screen_grid.itemLongClickListener = { - performItemLongClick(home_screen_grid.getClickableRect(it).left.toFloat(), it) - } } private fun findFirstEmptyCell(): Pair { @@ -169,7 +183,7 @@ class MainActivity : SimpleActivity(), FlingListener { for (checkedXCell in 0 until ROW_COUNT - 1) { val wantedCell = Triple(page, checkedXCell, checkedYCell) if (!occupiedCells.contains(wantedCell)) { - return Pair(page, Rect(wantedCell.first, wantedCell.second, wantedCell.first, wantedCell.second)) + return Pair(page, Rect(wantedCell.second, wantedCell.third, wantedCell.second, wantedCell.third)) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 4ab808f..ddb38ac 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -368,13 +368,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } - fun storeAndShowGridItem(item: HomeScreenGridItem, navigateToPage: Boolean = false) { + fun storeAndShowGridItem(item: HomeScreenGridItem) { val newId = context.homeScreenGridItemsDB.insert(item) item.id = newId gridItems.add(item) - if (navigateToPage) { - skipToPage(item.page) - } redrawGrid() } @@ -903,8 +900,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel return false } - private fun skipToPage(targetPage: Int): Boolean { - if (targetPage < getMaxPage() + 1) { + fun skipToPage(targetPage: Int): Boolean { + if (currentPage != targetPage && targetPage < getMaxPage() + 1) { lastPage = currentPage currentPage = targetPage handlePageChange() From 05c96440377df0ccd759edb11b3ec2a339678c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 19 Jul 2023 17:26:36 +0200 Subject: [PATCH 09/18] Implement bottom row docking --- .../launcher/activities/MainActivity.kt | 11 +++-- .../launcher/databases/AppsDatabase.kt | 13 +++++- .../launcher/fragments/AllAppsFragment.kt | 1 + .../launcher/fragments/WidgetsFragment.kt | 1 + .../interfaces/HomeScreenGridItemsDao.kt | 4 +- .../launcher/models/HomeScreenGridItem.kt | 19 +++++++- .../launcher/views/HomeScreenGrid.kt | 46 +++++++++++++------ 7 files changed, 71 insertions(+), 24 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt index 23e911b..f0d4661 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -148,6 +148,7 @@ class MainActivity : SimpleActivity(), FlingListener { "", shortcutId, icon.toBitmap(), + false, icon ) @@ -764,7 +765,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultDialerPackage = (getSystemService(Context.TELECOM_SERVICE) as TelecomManager).defaultDialerPackage appLaunchers.firstOrNull { it.packageName == defaultDialerPackage }?.apply { val dialerIcon = - HomeScreenGridItem(null, 0, config.homeRowCount - 1, 0, config.homeRowCount - 1, 0, defaultDialerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 0, config.homeRowCount - 1, 0, config.homeRowCount - 1, 0, defaultDialerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) homeScreenGridItems.add(dialerIcon) } } catch (e: Exception) { @@ -774,7 +775,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultSMSMessengerPackage = Telephony.Sms.getDefaultSmsPackage(this) appLaunchers.firstOrNull { it.packageName == defaultSMSMessengerPackage }?.apply { val SMSMessengerIcon = - HomeScreenGridItem(null, 1, config.homeRowCount - 1, 1, config.homeRowCount - 1, 0, defaultSMSMessengerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 1, config.homeRowCount - 1, 1, config.homeRowCount - 1, 0, defaultSMSMessengerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) homeScreenGridItems.add(SMSMessengerIcon) } } catch (e: Exception) { @@ -786,7 +787,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultBrowserPackage = resolveInfo!!.activityInfo.packageName appLaunchers.firstOrNull { it.packageName == defaultBrowserPackage }?.apply { val browserIcon = - HomeScreenGridItem(null, 2, config.homeRowCount - 1, 2, config.homeRowCount - 1, 0, defaultBrowserPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 2, config.homeRowCount - 1, 2, config.homeRowCount - 1, 0, defaultBrowserPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) homeScreenGridItems.add(browserIcon) } } catch (e: Exception) { @@ -797,7 +798,7 @@ class MainActivity : SimpleActivity(), FlingListener { val storePackage = potentialStores.firstOrNull { isPackageInstalled(it) && appLaunchers.map { it.packageName }.contains(it) } if (storePackage != null) { appLaunchers.firstOrNull { it.packageName == storePackage }?.apply { - val storeIcon = HomeScreenGridItem(null, 3, config.homeRowCount - 1, 3, config.homeRowCount - 1, 0, storePackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + val storeIcon = HomeScreenGridItem(null, 3, config.homeRowCount - 1, 3, config.homeRowCount - 1, 0, storePackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) homeScreenGridItems.add(storeIcon) } } @@ -810,7 +811,7 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultCameraPackage = resolveInfo!!.activityInfo.packageName appLaunchers.firstOrNull { it.packageName == defaultCameraPackage }?.apply { val cameraIcon = - HomeScreenGridItem(null, 4, config.homeRowCount - 1, 4, config.homeRowCount - 1, 0, defaultCameraPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) + HomeScreenGridItem(null, 4, config.homeRowCount - 1, 4, config.homeRowCount - 1, 0, defaultCameraPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) homeScreenGridItems.add(cameraIcon) } } catch (e: Exception) { diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt index f6e85d9..e655487 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt @@ -7,6 +7,7 @@ import androidx.room.RoomDatabase import androidx.room.TypeConverters import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase +import com.simplemobiletools.launcher.extensions.config import com.simplemobiletools.launcher.helpers.Converters import com.simplemobiletools.launcher.interfaces.AppLaunchersDao import com.simplemobiletools.launcher.interfaces.HiddenIconsDao @@ -15,7 +16,7 @@ import com.simplemobiletools.launcher.models.AppLauncher import com.simplemobiletools.launcher.models.HiddenIcon import com.simplemobiletools.launcher.models.HomeScreenGridItem -@Database(entities = [AppLauncher::class, HomeScreenGridItem::class, HiddenIcon::class], version = 5) +@Database(entities = [AppLauncher::class, HomeScreenGridItem::class, HiddenIcon::class], version = 6) @TypeConverters(Converters::class) abstract class AppsDatabase : RoomDatabase() { @@ -37,6 +38,7 @@ abstract class AppsDatabase : RoomDatabase() { .addMigrations(MIGRATION_2_3) .addMigrations(MIGRATION_3_4) .addMigrations(MIGRATION_4_5) + .addMigrations(MIGRATION_5_6.withContext(context)) .build() } } @@ -71,5 +73,14 @@ abstract class AppsDatabase : RoomDatabase() { database.execSQL("ALTER TABLE home_screen_grid_items ADD COLUMN page INTEGER NOT NULL DEFAULT 0") } } + + private val MIGRATION_5_6 = object { + fun withContext(context: Context) = object : Migration(5, 6) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE home_screen_grid_items ADD COLUMN docked INTEGER NOT NULL DEFAULT 0") + database.execSQL("UPDATE home_screen_grid_items SET docked = 1 WHERE page = 0 AND type != 1 AND top = ?", arrayOf(context.config.homeRowCount - 1)) + } + } + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt index d4b4214..ff2bf46 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt @@ -208,6 +208,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment "", "", null, + false, appLauncher.drawable ) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt index 07b5afc..1053144 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/WidgetsFragment.kt @@ -266,6 +266,7 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment "", "", null, + false, appWidget.widgetPreviewImage, appWidget.providerInfo, appWidget.activityInfo, diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt index 7abd805..592e895 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/interfaces/HomeScreenGridItemsDao.kt @@ -23,8 +23,8 @@ interface HomeScreenGridItemsDao { @Query("UPDATE home_screen_grid_items SET title = :title WHERE id = :id") fun updateItemTitle(title: String, id: Long): Int - @Query("UPDATE home_screen_grid_items SET `left` = :left, `top` = :top, `right` = :right, `bottom` = :bottom, `page` = :page WHERE id = :id") - fun updateItemPosition(left: Int, top: Int, right: Int, bottom: Int, page: Int, id: Long) + @Query("UPDATE home_screen_grid_items SET `left` = :left, `top` = :top, `right` = :right, `bottom` = :bottom, `page` = :page, `docked` = :docked WHERE id = :id") + fun updateItemPosition(left: Int, top: Int, right: Int, bottom: Int, page: Int, docked: Boolean, id: Long) @Query("DELETE FROM home_screen_grid_items WHERE id = :id") fun deleteById(id: Long) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt index 0d4b38c..c87acab 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/models/HomeScreenGridItem.kt @@ -25,6 +25,7 @@ data class HomeScreenGridItem( @ColumnInfo(name = "intent") var intent: String, // used at static and dynamic shortcuts on click @ColumnInfo(name = "shortcut_id") var shortcutId: String, // used at pinned shortcuts at startLauncher call @ColumnInfo(name = "icon") var icon: Bitmap? = null, // store images of pinned shortcuts, those cannot be retrieved after creating + @ColumnInfo(name = "docked") var docked: Boolean = false, // special flag, meaning that page, top and bottom don't matter for this item, it is always at the bottom of the screen @Ignore var drawable: Drawable? = null, @Ignore var providerInfo: AppWidgetProviderInfo? = null, // used at widgets @@ -32,7 +33,7 @@ data class HomeScreenGridItem( @Ignore var widthCells: Int = 1, @Ignore var heightCells: Int = 1 ) { - constructor() : this(null, -1, -1, -1, -1, 0, "", "", "", ITEM_TYPE_ICON, "", -1, "", "", null, null, null, null, 1, 1) + constructor() : this(null, -1, -1, -1, -1, 0, "", "", "", ITEM_TYPE_ICON, "", -1, "", "", null, false, null, null, null, 1, 1) fun getWidthInCells() = if (right == -1 || left == -1) { widthCells @@ -46,5 +47,21 @@ data class HomeScreenGridItem( bottom - top + 1 } + fun getDockAdjustedTop(rowCount: Int): Int { + return if (!docked) { + top + } else { + rowCount - 1 + } + } + + fun getDockAdjustedBottom(rowCount: Int): Int { + return if (!docked) { + bottom + } else { + rowCount - 1 + } + } + fun getItemIdentifier() = "$packageName/$activityName" } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 2d68305..9f9a666 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -272,7 +272,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } updateWidgetPositionAndSize(widgetView, item) ensureBackgroundThread { - context.homeScreenGridItemsDB.updateItemPosition(item.left, item.top, item.right, item.bottom, item.page, item.id!!) + context.homeScreenGridItemsDB.updateItemPosition(item.left, item.top, item.right, item.bottom, item.page, false, item.id!!) } } @@ -311,9 +311,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel // check if the destination cell is empty var areAllCellsEmpty = true val wantedCell = Pair(xIndex, yIndex) - gridItems.filter { it.page == currentPage }.forEach { item -> + gridItems.filter { it.page == currentPage || it.docked }.forEach { item -> for (xCell in item.left..item.right) { - for (yCell in item.top..item.bottom) { + for (yCell in item.getDockAdjustedTop(rowCount)..item.getDockAdjustedBottom(rowCount)) { val cell = Pair(xCell, yCell) val isAnyCellOccupied = wantedCell == cell if (isAnyCellOccupied) { @@ -335,9 +335,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel right = xIndex bottom = yIndex page = currentPage + docked = yIndex == rowCount - 1 ensureBackgroundThread { - context.homeScreenGridItemsDB.updateItemPosition(left, top, right, bottom, page, id!!) + context.homeScreenGridItemsDB.updateItemPosition(left, top, right, bottom, page, docked, id!!) } } redrawIcons = true @@ -359,6 +360,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel "", "", draggedItem!!.icon, + yIndex == rowCount - 1, draggedItem!!.drawable, draggedItem!!.providerInfo, draggedItem!!.activityInfo @@ -416,9 +418,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } var areAllCellsEmpty = true - gridItems.filter { it.id != draggedItem?.id && it.page == currentPage }.forEach { item -> + gridItems.filter { it.id != draggedItem?.id && (it.page == currentPage || it.docked) }.forEach { item -> for (xCell in item.left..item.right) { - for (yCell in item.top..item.bottom) { + for (yCell in item.getDockAdjustedTop(rowCount)..item.getDockAdjustedBottom(rowCount)) { val cell = Pair(xCell, yCell) val isAnyCellOccupied = widgetTargetCells.contains(cell) if (isAnyCellOccupied) { @@ -454,6 +456,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel widgetItem.right, widgetItem.bottom, currentPage, + false, widgetItem.id!! ) val widgetView = widgetViews.firstOrNull { it.tag == widgetItem.widgetId } @@ -636,8 +639,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel if (item.id != draggedItem?.id) { val drawableX = cellXCoords[item.left] + iconMargin + extraXMargin + sideMargins.left + (width * xFactor).toInt() - if (item.top == rowCount - 1) { - val drawableY = cellYCoords[item.top] + cellHeight - iconMargin - iconSize + sideMargins.top + if (item.docked) { + val drawableY = cellYCoords[rowCount - 1] + cellHeight - iconMargin - iconSize + sideMargins.top item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize) } else { @@ -665,15 +668,26 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } - gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage }.forEach { item -> + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage && !it.docked }.forEach { item -> if (item.outOfBounds()) { return@forEach } handleDrawing(item, currentXFactor) } + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.docked }.forEach { item -> + if (item.outOfBounds()) { + return@forEach + } + + handleDrawing(item, 0f) + } if (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f) { - gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == lastPage }.forEach { item -> + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == lastPage && !it.docked }.forEach { item -> + if (item.outOfBounds()) { + return@forEach + } + handleDrawing(item, lastXFactor) } } @@ -799,8 +813,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } val clickableLeft = cellXCoords[item.left] + sideMargins.left + extraXMargin - val clickableTop = if (item.top == rowCount - 1) { - cellYCoords[item.top] + cellHeight - iconSize - iconMargin + val clickableTop = if (item.docked) { + cellYCoords[item.getDockAdjustedTop(rowCount)] + cellHeight - iconSize - iconMargin } else { cellYCoords[item.top] - iconMargin + extraYMargin } + sideMargins.top @@ -833,7 +847,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? { - for (gridItem in gridItems.filter { it.page == currentPage }) { + for (gridItem in gridItems.filter { it.page == currentPage || it.docked }) { if (gridItem.outOfBounds()) { continue } @@ -867,7 +881,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } private fun HomeScreenGridItem.outOfBounds(): Boolean { - return (left >= cellXCoords.size || right >= cellXCoords.size || top >= cellYCoords.size || bottom >= cellYCoords.size) + return (left >= cellXCoords.size || right >= cellXCoords.size || (!docked && (top >= cellYCoords.size - 1 || bottom >= cellYCoords.size - 1))) } private inner class HomeScreenGridTouchHelper(host: View) : ExploreByTouchHelper(host) { @@ -882,7 +896,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } override fun getVisibleVirtualViews(virtualViewIds: MutableList?) { - val sorted = gridItems.sortedBy { it.top * 100 + it.left } + val sorted = gridItems.sortedBy { + it.getDockAdjustedTop(rowCount) * 100 + it.left + } sorted.forEachIndexed { index, homeScreenGridItem -> virtualViewIds?.add(index, homeScreenGridItem.id?.toInt() ?: index) } From 1448c8a98901794e54451694e859b096248aa3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 11:20:53 +0200 Subject: [PATCH 10/18] Combine migrations to keep database version at 5 --- .../launcher/databases/AppsDatabase.kt | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt index e655487..1754cd6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/databases/AppsDatabase.kt @@ -7,7 +7,6 @@ import androidx.room.RoomDatabase import androidx.room.TypeConverters import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase -import com.simplemobiletools.launcher.extensions.config import com.simplemobiletools.launcher.helpers.Converters import com.simplemobiletools.launcher.interfaces.AppLaunchersDao import com.simplemobiletools.launcher.interfaces.HiddenIconsDao @@ -16,7 +15,7 @@ import com.simplemobiletools.launcher.models.AppLauncher import com.simplemobiletools.launcher.models.HiddenIcon import com.simplemobiletools.launcher.models.HomeScreenGridItem -@Database(entities = [AppLauncher::class, HomeScreenGridItem::class, HiddenIcon::class], version = 6) +@Database(entities = [AppLauncher::class, HomeScreenGridItem::class, HiddenIcon::class], version = 5) @TypeConverters(Converters::class) abstract class AppsDatabase : RoomDatabase() { @@ -38,7 +37,6 @@ abstract class AppsDatabase : RoomDatabase() { .addMigrations(MIGRATION_2_3) .addMigrations(MIGRATION_3_4) .addMigrations(MIGRATION_4_5) - .addMigrations(MIGRATION_5_6.withContext(context)) .build() } } @@ -71,15 +69,8 @@ abstract class AppsDatabase : RoomDatabase() { private val MIGRATION_4_5 = object : Migration(4, 5) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE home_screen_grid_items ADD COLUMN page INTEGER NOT NULL DEFAULT 0") - } - } - - private val MIGRATION_5_6 = object { - fun withContext(context: Context) = object : Migration(5, 6) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("ALTER TABLE home_screen_grid_items ADD COLUMN docked INTEGER NOT NULL DEFAULT 0") - database.execSQL("UPDATE home_screen_grid_items SET docked = 1 WHERE page = 0 AND type != 1 AND top = ?", arrayOf(context.config.homeRowCount - 1)) - } + database.execSQL("ALTER TABLE home_screen_grid_items ADD COLUMN docked INTEGER NOT NULL DEFAULT 0") + database.execSQL("UPDATE home_screen_grid_items SET docked = 1 WHERE page = 0 AND type != 1 AND top = 5") } } } From efb46dc0d65e97216025b8f496c5c5059272eab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 11:29:10 +0200 Subject: [PATCH 11/18] Fix max page calculation in HomeScreenGrid to consider only visible items --- .../com/simplemobiletools/launcher/views/HomeScreenGrid.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 9f9a666..3b02e6b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -941,7 +941,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } - private fun getMaxPage() = gridItems.map { it.page }.max() + private fun getMaxPage() = gridItems.filter { !it.docked && !it.outOfBounds() }.maxOfOrNull { it.page } ?: 0 private fun nextOrAdditionalPage(redraw: Boolean = false): Boolean { if (currentPage < getMaxPage() + 1 && pageChangeEnabled) { From 9906ef05af8a176ff1ae5598a30bac71eb28a24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 12:09:15 +0200 Subject: [PATCH 12/18] Draw page indicators on the bottom --- .../launcher/views/HomeScreenGrid.kt | 46 +++++++++++++++++-- app/src/main/res/values/dimens.xml | 3 ++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 3b02e6b..d0e061c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -24,6 +24,7 @@ import androidx.core.graphics.drawable.toDrawable import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.customview.widget.ExploreByTouchHelper +import com.google.android.material.math.MathUtils import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.ensureBackgroundThread 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 kotlin.math.abs import kotlin.math.floor +import kotlin.math.max import kotlin.math.min 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 labelSideMargin = context.resources.getDimension(R.dimen.small_margin).toInt() 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 dragShadowCirclePaint: Paint + private var emptyPageIndicatorPaint: Paint + private var currentPageIndicatorPaint: Paint private var draggedItem: HomeScreenGridItem? = null private var resizedWidget: HomeScreenGridItem? = null private var isFirstDraw = true @@ -98,6 +105,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel 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() sideMargins.apply { top = context.statusBarHeight @@ -167,6 +182,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel if (item.type == ITEM_TYPE_WIDGET) { appWidgetHost.deleteAppWidgetId(item.widgetId) } + } } @@ -635,7 +651,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel 1 - pageChangeAnimLeftPercentage } - fun handleDrawing(item: HomeScreenGridItem, xFactor: Float) { + fun handleItemDrawing(item: HomeScreenGridItem, xFactor: Float) { if (item.id != draggedItem?.id) { 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 } - 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 -> if (item.outOfBounds()) { return@forEach } - handleDrawing(item, 0f) + handleItemDrawing(item, 0f) } 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 -> @@ -688,7 +704,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel 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!!.type == ITEM_TYPE_ICON || draggedItem!!.type == ITEM_TYPE_SHORTCUT) { // draw a circle under the current cell diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 1b0c39a..ef22951 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -6,4 +6,7 @@ 10dp 8dp 5dp + 4dp + 1dp + 4dp From 35fe1da420d05cd76030b53c4bb8e0fb2f698734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 12:09:28 +0200 Subject: [PATCH 13/18] Navigate to previous page if current one is empty --- .../simplemobiletools/launcher/views/HomeScreenGrid.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index d0e061c..f7ffda3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -169,6 +169,11 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } gridItems.removeIf { it.id == item.id } + if (currentPage > getMaxPage()) { + post { + prevPage() + } + } redrawGrid() } } @@ -529,6 +534,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } else { removeItemFromHomeScreen(item) } + + if (currentPage > getMaxPage()) { + prevPage(redraw = true) + } } } } From 8794f7ca23bfd5679787ca8f4af578c382a3b0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 12:40:28 +0200 Subject: [PATCH 14/18] Decrease move gesture sensitivity --- .../launcher/activities/MainActivity.kt | 101 ++++++++++++++++-- .../launcher/views/HomeScreenGrid.kt | 2 +- app/src/main/res/values/dimens.xml | 2 +- 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt index f0d4661..e8c72af 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -93,7 +93,7 @@ class MainActivity : SimpleActivity(), FlingListener { mScreenHeight = realScreenSize.y mAllAppsFragmentY = mScreenHeight mWidgetsFragmentY = mScreenHeight - mMoveGestureThreshold = resources.getDimension(R.dimen.move_gesture_threshold).toInt() + mMoveGestureThreshold = resources.getDimensionPixelSize(R.dimen.move_gesture_threshold) arrayOf(all_apps_fragment as MyFragment, widgets_fragment as MyFragment).forEach { fragment -> fragment.setupFragment(this) @@ -338,7 +338,7 @@ class MainActivity : SimpleActivity(), FlingListener { home_screen_grid.draggedItemMoved(event.x.toInt(), event.y.toInt()) } - if (mTouchDownY != -1 && !mIgnoreMoveEvents) { + if (hasFingerMoved && !mIgnoreMoveEvents) { val diffY = mTouchDownY - event.y if (isWidgetsFragmentExpanded()) { @@ -384,7 +384,7 @@ class MainActivity : SimpleActivity(), FlingListener { // some devices ACTION_MOVE keeps triggering for the whole long press duration, but we are interested in real moves only, when coords change private fun hasFingerMoved(event: MotionEvent) = mTouchDownX != -1 && mTouchDownY != -1 && - (Math.abs(mTouchDownX - event.x) > mMoveGestureThreshold) || (Math.abs(mTouchDownY - event.y) > mMoveGestureThreshold) + ((Math.abs(mTouchDownX - event.x) > mMoveGestureThreshold) || (Math.abs(mTouchDownY - event.y) > mMoveGestureThreshold)) private fun refetchLaunchers() { val launchers = getAllAppLaunchers() @@ -765,7 +765,24 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultDialerPackage = (getSystemService(Context.TELECOM_SERVICE) as TelecomManager).defaultDialerPackage appLaunchers.firstOrNull { it.packageName == defaultDialerPackage }?.apply { val dialerIcon = - HomeScreenGridItem(null, 0, config.homeRowCount - 1, 0, config.homeRowCount - 1, 0, defaultDialerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) + HomeScreenGridItem( + null, + 0, + config.homeRowCount - 1, + 0, + config.homeRowCount - 1, + 0, + defaultDialerPackage, + "", + title, + ITEM_TYPE_ICON, + "", + -1, + "", + "", + null, + true + ) homeScreenGridItems.add(dialerIcon) } } catch (e: Exception) { @@ -775,7 +792,24 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultSMSMessengerPackage = Telephony.Sms.getDefaultSmsPackage(this) appLaunchers.firstOrNull { it.packageName == defaultSMSMessengerPackage }?.apply { val SMSMessengerIcon = - HomeScreenGridItem(null, 1, config.homeRowCount - 1, 1, config.homeRowCount - 1, 0, defaultSMSMessengerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) + HomeScreenGridItem( + null, + 1, + config.homeRowCount - 1, + 1, + config.homeRowCount - 1, + 0, + defaultSMSMessengerPackage, + "", + title, + ITEM_TYPE_ICON, + "", + -1, + "", + "", + null, + true + ) homeScreenGridItems.add(SMSMessengerIcon) } } catch (e: Exception) { @@ -787,7 +821,24 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultBrowserPackage = resolveInfo!!.activityInfo.packageName appLaunchers.firstOrNull { it.packageName == defaultBrowserPackage }?.apply { val browserIcon = - HomeScreenGridItem(null, 2, config.homeRowCount - 1, 2, config.homeRowCount - 1, 0, defaultBrowserPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) + HomeScreenGridItem( + null, + 2, + config.homeRowCount - 1, + 2, + config.homeRowCount - 1, + 0, + defaultBrowserPackage, + "", + title, + ITEM_TYPE_ICON, + "", + -1, + "", + "", + null, + true + ) homeScreenGridItems.add(browserIcon) } } catch (e: Exception) { @@ -798,7 +849,24 @@ class MainActivity : SimpleActivity(), FlingListener { val storePackage = potentialStores.firstOrNull { isPackageInstalled(it) && appLaunchers.map { it.packageName }.contains(it) } if (storePackage != null) { appLaunchers.firstOrNull { it.packageName == storePackage }?.apply { - val storeIcon = HomeScreenGridItem(null, 3, config.homeRowCount - 1, 3, config.homeRowCount - 1, 0, storePackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) + val storeIcon = HomeScreenGridItem( + null, + 3, + config.homeRowCount - 1, + 3, + config.homeRowCount - 1, + 0, + storePackage, + "", + title, + ITEM_TYPE_ICON, + "", + -1, + "", + "", + null, + true + ) homeScreenGridItems.add(storeIcon) } } @@ -811,7 +879,24 @@ class MainActivity : SimpleActivity(), FlingListener { val defaultCameraPackage = resolveInfo!!.activityInfo.packageName appLaunchers.firstOrNull { it.packageName == defaultCameraPackage }?.apply { val cameraIcon = - HomeScreenGridItem(null, 4, config.homeRowCount - 1, 4, config.homeRowCount - 1, 0, defaultCameraPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null, true) + HomeScreenGridItem( + null, + 4, + config.homeRowCount - 1, + 4, + config.homeRowCount - 1, + 0, + defaultCameraPackage, + "", + title, + ITEM_TYPE_ICON, + "", + -1, + "", + "", + null, + true + ) homeScreenGridItems.add(cameraIcon) } } catch (e: Exception) { diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index f7ffda3..7a425c2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -1060,7 +1060,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel companion object { private const val ANIMATION_DURATION = 700L - private const val PAGE_CHANGE_BLOCKING_DURATION = ANIMATION_DURATION + 200L + private const val PAGE_CHANGE_BLOCKING_DURATION = ANIMATION_DURATION private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L private enum class PageChangeArea { diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index ef22951..233b20b 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -5,7 +5,7 @@ 140dp 10dp 8dp - 5dp + 20dp 4dp 1dp 4dp From 1b0dc44ca856d9091a3b8f76ea26f28a201d6652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 13:35:22 +0200 Subject: [PATCH 15/18] Reduce delay for page changes --- .../com/simplemobiletools/launcher/views/HomeScreenGrid.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 7a425c2..90fdd78 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -1039,7 +1039,6 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel if (redraw) { redrawGrid() } - postDelayed({ pageChangeEnabled = true }, PAGE_CHANGE_BLOCKING_DURATION) ValueAnimator.ofFloat(1f, 0f) .apply { addUpdateListener { @@ -1050,6 +1049,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel override fun onAnimationEnd(animation: Animator) { super.onAnimationEnd(animation) pageChangeAnimLeftPercentage = 0f + pageChangeEnabled = true lastPage = currentPage redrawGrid() } @@ -1059,8 +1059,6 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } companion object { - private const val ANIMATION_DURATION = 700L - private const val PAGE_CHANGE_BLOCKING_DURATION = ANIMATION_DURATION private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L private enum class PageChangeArea { From 43925279093926a65b0e7d27ba7319423dec5368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 13:48:36 +0200 Subject: [PATCH 16/18] Improve behavior for dragging icons offpage --- .../launcher/views/HomeScreenGrid.kt | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 90fdd78..395cb2e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -23,6 +23,7 @@ import android.widget.RelativeLayout import androidx.core.graphics.drawable.toDrawable import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat +import androidx.core.view.postDelayed import androidx.customview.widget.ExploreByTouchHelper import com.google.android.material.math.MathUtils import com.simplemobiletools.commons.extensions.* @@ -90,6 +91,22 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null var itemLongClickListener: ((HomeScreenGridItem) -> Unit)? = null + private val checkAndExecuteDelayedPageChange: Runnable = Runnable { + if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { + when (pageChangeLastArea) { + PageChangeArea.RIGHT -> { + nextOrAdditionalPage(true) + } + PageChangeArea.LEFT -> { + prevPage(true) + } + else -> { + clearPageChangeFlags() + } + } + } + } + init { ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this)) @@ -234,12 +251,18 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private fun clearPageChangeFlags() { pageChangeLastArea = PageChangeArea.MIDDLE pageChangeLastAreaEntryTime = 0 + removeCallbacks(checkAndExecuteDelayedPageChange) + } + + private fun schedulePageChange() { + pageChangeLastAreaEntryTime = System.currentTimeMillis() + postDelayed(checkAndExecuteDelayedPageChange, PAGE_CHANGE_HOLD_THRESHOLD) } private fun doWithPageChangeDelay(needed: PageChangeArea, pageChangeFunction: () -> Boolean) { if (pageChangeLastArea != needed) { pageChangeLastArea = needed - pageChangeLastAreaEntryTime = System.currentTimeMillis() + schedulePageChange() } else if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { if (pageChangeFunction()) { clearPageChangeFlags() @@ -1051,6 +1074,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel pageChangeAnimLeftPercentage = 0f pageChangeEnabled = true lastPage = currentPage + schedulePageChange() redrawGrid() } }) From 2038e9dcf1944ca48b0cbd2276eadc30c3c3d5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 20 Jul 2023 13:52:37 +0200 Subject: [PATCH 17/18] Remove unused strokeWidth field from HomeScreenGrid --- .../com/simplemobiletools/launcher/views/HomeScreenGrid.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index 395cb2e..c53ff3c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -58,7 +58,6 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private var labelSideMargin = context.resources.getDimension(R.dimen.small_margin).toInt() 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 dragShadowCirclePaint: Paint From 0a76968091aaa34c3bb10b8f62cd98a92b9a818d Mon Sep 17 00:00:00 2001 From: Tibor Kaputa Date: Thu, 20 Jul 2023 15:36:53 +0200 Subject: [PATCH 18/18] minor code style update --- .../launcher/views/HomeScreenGrid.kt | 44 ++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index c53ff3c..9b0da12 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -23,7 +23,6 @@ import android.widget.RelativeLayout import androidx.core.graphics.drawable.toDrawable import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat -import androidx.core.view.postDelayed import androidx.customview.widget.ExploreByTouchHelper import com.google.android.material.math.MathUtils import com.simplemobiletools.commons.extensions.* @@ -93,15 +92,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private val checkAndExecuteDelayedPageChange: Runnable = Runnable { if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { when (pageChangeLastArea) { - PageChangeArea.RIGHT -> { - nextOrAdditionalPage(true) - } - PageChangeArea.LEFT -> { - prevPage(true) - } - else -> { - clearPageChangeFlags() - } + PageChangeArea.RIGHT -> nextOrAdditionalPage(true) + PageChangeArea.LEFT -> prevPage(true) + else -> clearPageChangeFlags() } } } @@ -203,7 +196,6 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel if (item.type == ITEM_TYPE_WIDGET) { appWidgetHost.deleteAppWidgetId(item.widgetId) } - } } @@ -715,13 +707,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } - gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage && !it.docked }.forEach { item -> - if (item.outOfBounds()) { - return@forEach - } + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == currentPage && !it.docked } + .forEach { item -> + if (item.outOfBounds()) { + return@forEach + } - handleItemDrawing(item, currentXFactor) - } + handleItemDrawing(item, currentXFactor) + } gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.docked }.forEach { item -> if (item.outOfBounds()) { return@forEach @@ -730,13 +723,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel handleItemDrawing(item, 0f) } 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 -> - if (item.outOfBounds()) { - return@forEach - } + gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) && it.page == lastPage && !it.docked } + .forEach { item -> + if (item.outOfBounds()) { + return@forEach + } - handleItemDrawing(item, lastXFactor) - } + handleItemDrawing(item, lastXFactor) + } } if (isFirstDraw) { @@ -916,7 +910,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? { - for (gridItem in gridItems.filter { it.page == currentPage || it.docked }) { + for (gridItem in gridItems.filter { it.page == currentPage || it.docked }) { if (gridItem.outOfBounds()) { continue } @@ -950,7 +944,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } private fun HomeScreenGridItem.outOfBounds(): Boolean { - return (left >= cellXCoords.size || right >= cellXCoords.size || (!docked && (top >= cellYCoords.size - 1 || bottom >= cellYCoords.size - 1))) + return (left >= cellXCoords.size || right >= cellXCoords.size || (!docked && (top >= cellYCoords.size - 1 || bottom >= cellYCoords.size - 1))) } private inner class HomeScreenGridTouchHelper(host: View) : ExploreByTouchHelper(host) {