Implement bottom row docking
This commit is contained in:
parent
1c67a8f097
commit
05c9644037
7 changed files with 71 additions and 24 deletions
|
@ -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) {
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
|||
"",
|
||||
"",
|
||||
null,
|
||||
false,
|
||||
appLauncher.drawable
|
||||
)
|
||||
|
||||
|
|
|
@ -266,6 +266,7 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
|||
"",
|
||||
"",
|
||||
null,
|
||||
false,
|
||||
appWidget.widgetPreviewImage,
|
||||
appWidget.providerInfo,
|
||||
appWidget.activityInfo,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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<Int>?) {
|
||||
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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue