From 79d047c8523b8b2db28920cab88626990e5a6e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 13 Jul 2023 14:32:43 +0200 Subject: [PATCH] Add settings for configuring home screen grid size This closes #60 --- .../launcher/activities/MainActivity.kt | 21 ++++--- .../launcher/activities/SettingsActivity.kt | 58 +++++++++++++++++- .../launcher/extensions/Context.kt | 16 +++++ .../launcher/helpers/Config.kt | 16 +++++ .../launcher/helpers/Constants.kt | 8 +++ .../launcher/views/HomeScreenGrid.kt | 55 ++++++++++++----- .../launcher/views/MyAppWidgetResizeFrame.kt | 12 ++-- app/src/main/res/layout/activity_settings.xml | 59 +++++++++++++++++++ 8 files changed, 216 insertions(+), 29 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 e6be5e6..2aaa5f0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -152,8 +152,8 @@ class MainActivity : SimpleActivity(), FlingListener { } } - for (checkedYCell in 0 until COLUMN_COUNT) { - for (checkedXCell in 0 until ROW_COUNT - 1) { + for (checkedYCell in 0 until getHomeColumnCount()) { + for (checkedXCell in 0 until getHomeRowCount() - 1) { val wantedCell = Pair(checkedXCell, checkedYCell) if (!occupiedCells.contains(wantedCell)) { return Rect(wantedCell.first, wantedCell.second, wantedCell.first, wantedCell.second) @@ -208,6 +208,11 @@ class MainActivity : SimpleActivity(), FlingListener { if (window.navigationBarColor != resources.getColor(R.color.semitransparent_navigation)) { window.navigationBarColor = Color.TRANSPARENT } + + home_screen_grid?.resizeGrid( + newRowCount = getHomeRowCount(), + newColumnCount = getHomeColumnCount() + ) } override fun onStop() { @@ -469,7 +474,7 @@ class MainActivity : SimpleActivity(), FlingListener { mLongPressedIcon = gridItem val anchorY = if (isOnAllAppsFragment || gridItem.type == ITEM_TYPE_WIDGET) { y - } else if (gridItem.top == ROW_COUNT - 1) { + } else if (gridItem.top == getHomeRowCount() - 1) { home_screen_grid.sideMargins.top + (gridItem.top * home_screen_grid.cellHeight.toFloat()) } else { (gridItem.top * home_screen_grid.cellHeight.toFloat()) @@ -699,7 +704,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, getHomeRowCount() - 1, 0, getHomeRowCount() - 1, defaultDialerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(dialerIcon) } } catch (e: Exception) { @@ -709,7 +714,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, getHomeRowCount() - 1, 1, getHomeRowCount() - 1, defaultSMSMessengerPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(SMSMessengerIcon) } } catch (e: Exception) { @@ -721,7 +726,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, getHomeRowCount() - 1, 2, getHomeRowCount() - 1, defaultBrowserPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(browserIcon) } } catch (e: Exception) { @@ -732,7 +737,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, getHomeRowCount() - 1, 3, getHomeRowCount() - 1, storePackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(storeIcon) } } @@ -745,7 +750,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, getHomeRowCount() - 1, 4, getHomeRowCount() - 1, defaultCameraPackage, "", title, ITEM_TYPE_ICON, "", -1, "", "", null) homeScreenGridItems.add(cameraIcon) } } catch (e: Exception) { diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/SettingsActivity.kt index a611fe5..3f70e9c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/SettingsActivity.kt @@ -2,13 +2,21 @@ package com.simplemobiletools.launcher.activities import android.content.Intent import android.os.Bundle +import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.NavigationIcon import com.simplemobiletools.commons.helpers.isTiramisuPlus import com.simplemobiletools.commons.models.FAQItem +import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.launcher.BuildConfig import com.simplemobiletools.launcher.R import com.simplemobiletools.launcher.extensions.config +import com.simplemobiletools.launcher.extensions.getHomeColumnCount +import com.simplemobiletools.launcher.extensions.getHomeRowCount +import com.simplemobiletools.launcher.helpers.MAX_COLUMN_COUNT +import com.simplemobiletools.launcher.helpers.MAX_ROW_COUNT +import com.simplemobiletools.launcher.helpers.MIN_COLUMN_COUNT +import com.simplemobiletools.launcher.helpers.MIN_ROW_COUNT import kotlinx.android.synthetic.main.activity_settings.* import java.util.* import kotlin.system.exitProcess @@ -32,11 +40,13 @@ class SettingsActivity : SimpleActivity() { setupPurchaseThankYou() setupCustomizeColors() setupUseEnglish() + setupHomeRowCount() + setupHomeColumnCount() setupLanguage() setupManageHiddenIcons() updateTextColors(settings_holder) - arrayOf(settings_color_customization_section_label, settings_general_settings_label).forEach { + arrayOf(settings_color_customization_section_label, settings_general_settings_label, settings_home_screen_label).forEach { it.setTextColor(getProperPrimaryColor()) } } @@ -82,6 +92,52 @@ class SettingsActivity : SimpleActivity() { } } + private fun setupHomeRowCount() { + val currentRowCount = getHomeRowCount() + settings_home_screen_row_count.text = currentRowCount.toString() + settings_home_screen_row_count_holder.setOnClickListener { + val items = ArrayList() + for (i in MIN_ROW_COUNT..MAX_ROW_COUNT) { + items.add(RadioItem(i, resources.getQuantityString(R.plurals.column_counts, i, i))) + } + + RadioGroupDialog(this, items, currentRowCount) { + val newRowCount = it as Int + if (currentRowCount != newRowCount) { + if (portrait) { + config.portraitHomeRowCount = newRowCount + } else { + config.landscapeHomeRowCount = newRowCount + } + setupHomeRowCount() + } + } + } + } + + private fun setupHomeColumnCount() { + val currentColumnCount = getHomeColumnCount() + settings_home_screen_column_count.text = currentColumnCount.toString() + settings_home_screen_column_count_holder.setOnClickListener { + val items = ArrayList() + for (i in MIN_COLUMN_COUNT..MAX_COLUMN_COUNT) { + items.add(RadioItem(i, resources.getQuantityString(R.plurals.column_counts, i, i))) + } + + RadioGroupDialog(this, items, currentColumnCount) { + val newColumnCount = it as Int + if (currentColumnCount != newColumnCount) { + if (portrait) { + config.portraitHomeColumnCount = newColumnCount + } else { + config.landscapeHomeColumnCount = newColumnCount + } + setupHomeColumnCount() + } + } + } + } + private fun setupLanguage() { settings_language.text = Locale.getDefault().displayLanguage settings_language_holder.beVisibleIf(isTiramisuPlus()) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Context.kt index 72aa0e4..4c855ff 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Context.kt @@ -31,6 +31,22 @@ fun Context.getColumnCount(): Int { } } +fun Context.getHomeRowCount(): Int { + return if (portrait) { + config.portraitHomeRowCount + } else { + config.landscapeHomeRowCount + } +} + +fun Context.getHomeColumnCount(): Int { + return if (portrait) { + config.portraitHomeColumnCount + } else { + config.landscapeHomeColumnCount + } +} + fun Context.getDrawableForPackageName(packageName: String): Drawable? { var drawable: Drawable? = null try { diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Config.kt index 338a009..59a34bb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Config.kt @@ -11,4 +11,20 @@ class Config(context: Context) : BaseConfig(context) { var wasHomeScreenInit: Boolean get() = prefs.getBoolean(WAS_HOME_SCREEN_INIT, false) set(wasHomeScreenInit) = prefs.edit().putBoolean(WAS_HOME_SCREEN_INIT, wasHomeScreenInit).apply() + + var portraitHomeColumnCount: Int + get() = prefs.getInt(PORTRAIT_HOME_COLUMN_COUNT, COLUMN_COUNT) + set(portraitHomeColumnCount) = prefs.edit().putInt(PORTRAIT_HOME_COLUMN_COUNT, portraitHomeColumnCount).apply() + + var landscapeHomeColumnCount: Int + get() = prefs.getInt(LANDSCAPE_HOME_COLUMN_COUNT, COLUMN_COUNT) + set(landscapeHomeColumnCount) = prefs.edit().putInt(LANDSCAPE_HOME_COLUMN_COUNT, landscapeHomeColumnCount).apply() + + var portraitHomeRowCount: Int + get() = prefs.getInt(PORTRAIT_HOME_ROW_COUNT, ROW_COUNT) + set(portraitHomeRowCount) = prefs.edit().putInt(PORTRAIT_HOME_ROW_COUNT, portraitHomeRowCount).apply() + + var landscapeHomeRowCount: Int + get() = prefs.getInt(LANDSCAPE_HOME_ROW_COUNT, ROW_COUNT) + set(landscapeHomeRowCount) = prefs.edit().putInt(LANDSCAPE_HOME_ROW_COUNT, landscapeHomeRowCount).apply() } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt index 299c883..79341ec 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt @@ -5,10 +5,18 @@ const val WIDGET_LIST_ITEMS_HOLDER = 1 // shared prefs const val WAS_HOME_SCREEN_INIT = "was_home_screen_init" +const val PORTRAIT_HOME_ROW_COUNT = "portrait_home_row_count" +const val LANDSCAPE_HOME_ROW_COUNT = "landscape_home_row_count" +const val PORTRAIT_HOME_COLUMN_COUNT = "portrait_home_column_count" +const val LANDSCAPE_HOME_COLUMN_COUNT = "landscape_home_column_count" // default home screen grid size const val ROW_COUNT = 6 const val COLUMN_COUNT = 5 +const val MIN_ROW_COUNT = 2 +const val MAX_ROW_COUNT = 15 +const val MIN_COLUMN_COUNT = 2 +const val MAX_COLUMN_COUNT = 15 const val UNINSTALL_APP_REQUEST_CODE = 50 const val REQUEST_CONFIGURE_WIDGET = 51 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 b75324c..9fc6140 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -23,10 +23,14 @@ import com.simplemobiletools.commons.helpers.isSPlus import com.simplemobiletools.launcher.R import com.simplemobiletools.launcher.activities.MainActivity import com.simplemobiletools.launcher.extensions.getDrawableForPackageName +import com.simplemobiletools.launcher.extensions.getHomeColumnCount +import com.simplemobiletools.launcher.extensions.getHomeRowCount import com.simplemobiletools.launcher.extensions.homeScreenGridItemsDB import com.simplemobiletools.launcher.helpers.* import com.simplemobiletools.launcher.models.HomeScreenGridItem import kotlinx.android.synthetic.main.activity_main.view.* +import kotlin.math.max +import kotlin.math.min class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : RelativeLayout(context, attrs, defStyle) { constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0) @@ -41,9 +45,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel private var isFirstDraw = true private var iconSize = 0 - // let's use a 6x5 grid for now with 1 special row at the bottom, prefilled with default apps - private var cellXCoords = ArrayList(COLUMN_COUNT) - private var cellYCoords = ArrayList(ROW_COUNT) + private var columnCount = context.getHomeColumnCount() + private var rowCount = context.getHomeRowCount() + private var cellXCoords = ArrayList(columnCount) + private var cellYCoords = ArrayList(rowCount) var cellWidth = 0 var cellHeight = 0 @@ -106,6 +111,16 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } } + fun resizeGrid(newRowCount: Int, newColumnCount: Int) { + if (columnCount != newColumnCount || rowCount != newRowCount){ + rowCount = newRowCount + columnCount = newColumnCount + cellXCoords = ArrayList(columnCount) + cellYCoords = ArrayList(rowCount) + invalidate() + } + } + fun removeAppIcon(item: HomeScreenGridItem) { ensureBackgroundThread { removeItemFromHomeScreen(item) @@ -521,11 +536,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 }.forEach { item -> + if (item.outOfBounds()) { + return@forEach + } + if (item.id != draggedItem?.id) { val drawableX = cellXCoords[item.left] + iconMargin + sideMargins.left // icons at the bottom are drawn at the bottom of the grid and they have no label - if (item.top == ROW_COUNT - 1) { + if (item.top == context.getHomeRowCount() - 1) { val drawableY = cellYCoords[item.top] + cellHeight - iconSize - iconMargin * 2 + sideMargins.top item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize) } else { @@ -569,7 +588,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel val gridCells = getClosestGridCells(center) if (gridCells != null) { val shadowX = cellXCoords[gridCells.first] + iconMargin.toFloat() + iconSize / 2 + sideMargins.left - val shadowY = if (gridCells.second == ROW_COUNT - 1) { + val shadowY = if (gridCells.second == context.getHomeRowCount() - 1) { cellYCoords[gridCells.second] + cellHeight - iconSize / 2 - iconMargin * 2 } else { cellYCoords[gridCells.second] + iconSize @@ -621,14 +640,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel } private fun fillCellSizes() { - cellWidth = getFakeWidth() / COLUMN_COUNT - cellHeight = getFakeHeight() / ROW_COUNT - iconSize = cellWidth - 2 * iconMargin - for (i in 0 until COLUMN_COUNT) { + cellWidth = getFakeWidth() / context.getHomeColumnCount() + cellHeight = getFakeHeight() / context.getHomeRowCount() + iconSize = min(cellWidth, cellHeight) - 2 * iconMargin + for (i in 0 until context.getHomeColumnCount()) { cellXCoords.add(i, i * cellWidth) } - for (i in 0 until ROW_COUNT) { + for (i in 0 until context.getHomeRowCount()) { cellYCoords.add(i, i * cellHeight) } @@ -669,15 +688,15 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel if (rect.left < 0) { rect.right -= rect.left rect.left = 0 - } else if (rect.right > COLUMN_COUNT - 1) { - val diff = rect.right - COLUMN_COUNT + 1 + } else if (rect.right > context.getHomeColumnCount() - 1) { + val diff = rect.right - context.getHomeColumnCount() + 1 rect.right -= diff rect.left -= diff } // do not allow placing widgets at the bottom row, that is for pinned default apps - if (rect.bottom >= ROW_COUNT - 1) { - val diff = rect.bottom - ROW_COUNT + 2 + if (rect.bottom >= context.getHomeRowCount() - 1) { + val diff = rect.bottom - context.getHomeRowCount() + 2 rect.bottom -= diff rect.top -= diff } @@ -687,6 +706,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? { for (gridItem in gridItems) { + if (gridItem.outOfBounds()) { + continue + } + 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) { @@ -706,4 +729,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel return null } + + private fun HomeScreenGridItem.outOfBounds(): Boolean { + return (left >= cellXCoords.size || right >= cellXCoords.size || top >= cellYCoords.size || bottom >= cellYCoords.size) + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/MyAppWidgetResizeFrame.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/MyAppWidgetResizeFrame.kt index 40f3f31..3a70590 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/MyAppWidgetResizeFrame.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/MyAppWidgetResizeFrame.kt @@ -10,9 +10,9 @@ import android.view.MotionEvent import android.widget.RelativeLayout import com.simplemobiletools.launcher.R import com.simplemobiletools.launcher.extensions.getCellCount -import com.simplemobiletools.launcher.helpers.COLUMN_COUNT +import com.simplemobiletools.launcher.extensions.getHomeColumnCount +import com.simplemobiletools.launcher.extensions.getHomeRowCount import com.simplemobiletools.launcher.helpers.MAX_CLICK_DURATION -import com.simplemobiletools.launcher.helpers.ROW_COUNT import com.simplemobiletools.launcher.models.HomeScreenGridItem @SuppressLint("ViewConstructor") @@ -76,8 +76,8 @@ class MyAppWidgetResizeFrame(context: Context, attrs: AttributeSet, defStyle: In it.provider.className == gridItem.className } ?: return - minResizeWidthCells = Math.min(COLUMN_COUNT, context.getCellCount(providerInfo.minResizeWidth)) - minResizeHeightCells = Math.min(ROW_COUNT, context.getCellCount(providerInfo.minResizeHeight)) + minResizeWidthCells = Math.min(context.getHomeColumnCount(), context.getCellCount(providerInfo.minResizeWidth)) + minResizeHeightCells = Math.min(context.getHomeRowCount(), context.getCellCount(providerInfo.minResizeHeight)) redrawFrame() occupiedCells.clear() @@ -224,7 +224,7 @@ class MyAppWidgetResizeFrame(context: Context, attrs: AttributeSet, defStyle: In } } - if (wantedBottomCellY == ROW_COUNT - 1) { + if (wantedBottomCellY == context.getHomeRowCount() - 1) { areAllCellsFree = false } @@ -322,7 +322,7 @@ class MyAppWidgetResizeFrame(context: Context, attrs: AttributeSet, defStyle: In } } - if (wantedBottomCellY == ROW_COUNT - 1) { + if (wantedBottomCellY == context.getHomeRowCount() - 1) { areAllCellsFree = false } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index fe6b1e2..551f214 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -135,6 +135,65 @@ android:text="@string/manage_hidden_icons" /> + + + + + + + + + + + + + + + + + + + +