Merge branch 'main' into feature/close-drawer-and-widgets-when-moving-to-other-apps
This commit is contained in:
commit
66c480b46d
52 changed files with 811 additions and 102 deletions
|
@ -63,7 +63,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:a9c3b63377'
|
implementation 'com.github.SimpleMobileTools:Simple-Commons:a26066d67d'
|
||||||
|
|
||||||
kapt "androidx.room:room-compiler:2.5.2"
|
kapt "androidx.room:room-compiler:2.5.2"
|
||||||
implementation "androidx.room:room-runtime:2.5.2"
|
implementation "androidx.room:room-runtime:2.5.2"
|
||||||
|
|
|
@ -47,6 +47,7 @@ import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import kotlinx.android.synthetic.main.activity_main.view.*
|
import kotlinx.android.synthetic.main.activity_main.view.*
|
||||||
import kotlinx.android.synthetic.main.all_apps_fragment.view.*
|
import kotlinx.android.synthetic.main.all_apps_fragment.view.*
|
||||||
import kotlinx.android.synthetic.main.widgets_fragment.view.*
|
import kotlinx.android.synthetic.main.widgets_fragment.view.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
class MainActivity : SimpleActivity(), FlingListener {
|
class MainActivity : SimpleActivity(), FlingListener {
|
||||||
private val ANIMATION_DURATION = 150L
|
private val ANIMATION_DURATION = 150L
|
||||||
|
@ -89,7 +90,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
mScreenHeight = realScreenSize.y
|
mScreenHeight = realScreenSize.y
|
||||||
mAllAppsFragmentY = mScreenHeight
|
mAllAppsFragmentY = mScreenHeight
|
||||||
mWidgetsFragmentY = 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 ->
|
arrayOf(all_apps_fragment as MyFragment, widgets_fragment as MyFragment).forEach { fragment ->
|
||||||
fragment.setupFragment(this)
|
fragment.setupFragment(this)
|
||||||
|
@ -97,6 +98,25 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
fragment.beVisible()
|
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) {
|
if (intent.action == LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT) {
|
||||||
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||||
val item = launcherApps.getPinItemRequest(intent)
|
val item = launcherApps.getPinItemRequest(intent)
|
||||||
|
@ -108,13 +128,14 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
val shortcutId = item.shortcutInfo?.id!!
|
val shortcutId = item.shortcutInfo?.id!!
|
||||||
val label = item.shortcutInfo?.shortLabel?.toString() ?: item.shortcutInfo?.longLabel?.toString() ?: ""
|
val label = item.shortcutInfo?.shortLabel?.toString() ?: item.shortcutInfo?.longLabel?.toString() ?: ""
|
||||||
val icon = launcherApps.getShortcutIconDrawable(item.shortcutInfo!!, resources.displayMetrics.densityDpi)
|
val icon = launcherApps.getShortcutIconDrawable(item.shortcutInfo!!, resources.displayMetrics.densityDpi)
|
||||||
val rect = findFirstEmptyCell() ?: return@ensureBackgroundThread
|
val (page, rect) = findFirstEmptyCell()
|
||||||
val gridItem = HomeScreenGridItem(
|
val gridItem = HomeScreenGridItem(
|
||||||
null,
|
null,
|
||||||
rect.left,
|
rect.left,
|
||||||
rect.top,
|
rect.top,
|
||||||
rect.right,
|
rect.right,
|
||||||
rect.bottom,
|
rect.bottom,
|
||||||
|
page,
|
||||||
item.shortcutInfo!!.`package`,
|
item.shortcutInfo!!.`package`,
|
||||||
"",
|
"",
|
||||||
label,
|
label,
|
||||||
|
@ -124,9 +145,13 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
"",
|
"",
|
||||||
shortcutId,
|
shortcutId,
|
||||||
icon.toBitmap(),
|
icon.toBitmap(),
|
||||||
|
false,
|
||||||
icon
|
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
|
// 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)
|
Thread.sleep(2000)
|
||||||
|
|
||||||
|
@ -137,37 +162,32 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
home_screen_grid.itemClickListener = {
|
|
||||||
performItemClick(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
home_screen_grid.itemLongClickListener = {
|
|
||||||
performItemLongClick(home_screen_grid.getClickableRect(it).left.toFloat(), it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findFirstEmptyCell(): Rect? {
|
private fun findFirstEmptyCell(): Pair<Int, Rect> {
|
||||||
val gridItems = homeScreenGridItemsDB.getAllItems() as ArrayList<HomeScreenGridItem>
|
val gridItems = homeScreenGridItemsDB.getAllItems() as ArrayList<HomeScreenGridItem>
|
||||||
val occupiedCells = ArrayList<Pair<Int, Int>>()
|
val maxPage = gridItems.map { it.page }.max()
|
||||||
|
val occupiedCells = ArrayList<Triple<Int, Int, Int>>()
|
||||||
gridItems.forEach { item ->
|
gridItems.forEach { item ->
|
||||||
for (xCell in item.left..item.right) {
|
for (xCell in item.left..item.right) {
|
||||||
for (yCell in item.top..item.bottom) {
|
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 (page in 0 until maxPage) {
|
||||||
for (checkedXCell in 0 until ROW_COUNT - 1) {
|
for (checkedYCell in 0 until config.homeColumnCount) {
|
||||||
val wantedCell = Pair(checkedXCell, checkedYCell)
|
for (checkedXCell in 0 until config.homeRowCount - 1) {
|
||||||
if (!occupiedCells.contains(wantedCell)) {
|
val wantedCell = Triple(page, checkedXCell, checkedYCell)
|
||||||
return Rect(wantedCell.first, wantedCell.second, wantedCell.first, wantedCell.second)
|
if (!occupiedCells.contains(wantedCell)) {
|
||||||
|
return Pair(page, Rect(wantedCell.second, wantedCell.third, wantedCell.second, wantedCell.third))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return Pair(maxPage + 1, Rect(0, 0, 0, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
@ -225,6 +245,10 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
window.navigationBarColor = Color.TRANSPARENT
|
window.navigationBarColor = Color.TRANSPARENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
home_screen_grid?.resizeGrid(
|
||||||
|
newRowCount = config.homeRowCount,
|
||||||
|
newColumnCount = config.homeColumnCount
|
||||||
|
)
|
||||||
(all_apps_fragment as? AllAppsFragment)?.onResume()
|
(all_apps_fragment as? AllAppsFragment)?.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +345,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
home_screen_grid.draggedItemMoved(event.x.toInt(), event.y.toInt())
|
home_screen_grid.draggedItemMoved(event.x.toInt(), event.y.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTouchDownY != -1 && !mIgnoreMoveEvents) {
|
if (hasFingerMoved && !mIgnoreMoveEvents) {
|
||||||
val diffY = mTouchDownY - event.y
|
val diffY = mTouchDownY - event.y
|
||||||
|
|
||||||
if (isWidgetsFragmentExpanded()) {
|
if (isWidgetsFragmentExpanded()) {
|
||||||
|
@ -367,7 +391,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
|
// 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 &&
|
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() {
|
private fun refetchLaunchers() {
|
||||||
val launchers = getAllAppLaunchers()
|
val launchers = getAllAppLaunchers()
|
||||||
|
@ -443,11 +467,12 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
}, ANIMATION_DURATION)
|
}, ANIMATION_DURATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun homeScreenLongPressed(x: Float, y: Float) {
|
fun homeScreenLongPressed(eventX: Float, eventY: Float) {
|
||||||
if (isAllAppsFragmentExpanded()) {
|
if (isAllAppsFragmentExpanded()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val (x, y) = home_screen_grid.intoViewSpaceCoords(eventX, eventY)
|
||||||
mIgnoreMoveEvents = true
|
mIgnoreMoveEvents = true
|
||||||
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
||||||
if (clickedGridItem != null) {
|
if (clickedGridItem != null) {
|
||||||
|
@ -459,8 +484,9 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
showMainLongPressMenu(x, y)
|
showMainLongPressMenu(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun homeScreenClicked(x: Float, y: Float) {
|
fun homeScreenClicked(eventX: Float, eventY: Float) {
|
||||||
home_screen_grid.hideResizeLines()
|
home_screen_grid.hideResizeLines()
|
||||||
|
val (x, y) = home_screen_grid.intoViewSpaceCoords(eventX, eventY)
|
||||||
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
||||||
if (clickedGridItem != null) {
|
if (clickedGridItem != null) {
|
||||||
performItemClick(clickedGridItem)
|
performItemClick(clickedGridItem)
|
||||||
|
@ -499,7 +525,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
mLongPressedIcon = gridItem
|
mLongPressedIcon = gridItem
|
||||||
val anchorY = if (isOnAllAppsFragment || gridItem.type == ITEM_TYPE_WIDGET) {
|
val anchorY = if (isOnAllAppsFragment || gridItem.type == ITEM_TYPE_WIDGET) {
|
||||||
y
|
y
|
||||||
} else if (gridItem.top == ROW_COUNT - 1) {
|
} else if (gridItem.top == config.homeRowCount - 1) {
|
||||||
home_screen_grid.sideMargins.top + (gridItem.top * home_screen_grid.cellHeight.toFloat())
|
home_screen_grid.sideMargins.top + (gridItem.top * home_screen_grid.cellHeight.toFloat())
|
||||||
} else {
|
} else {
|
||||||
(gridItem.top * home_screen_grid.cellHeight.toFloat())
|
(gridItem.top * home_screen_grid.cellHeight.toFloat())
|
||||||
|
@ -648,11 +674,20 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (velocityY > 0) {
|
if (abs(velocityY) > abs(velocityX)) {
|
||||||
flingListener.onFlingDown()
|
if (velocityY > 0) {
|
||||||
} else {
|
flingListener.onFlingDown()
|
||||||
flingListener.onFlingUp()
|
} else {
|
||||||
|
flingListener.onFlingUp()
|
||||||
|
}
|
||||||
|
} else if (abs(velocityX) > abs(velocityY)) {
|
||||||
|
if (velocityX > 0) {
|
||||||
|
flingListener.onFlingRight()
|
||||||
|
} else {
|
||||||
|
flingListener.onFlingLeft()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,6 +718,16 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onFlingRight() {
|
||||||
|
mIgnoreUpEvent = true
|
||||||
|
home_screen_grid.prevPage(redraw = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFlingLeft() {
|
||||||
|
mIgnoreUpEvent = true
|
||||||
|
home_screen_grid.nextPage(redraw = true)
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("WrongConstant")
|
@SuppressLint("WrongConstant")
|
||||||
fun getAllAppLaunchers(): ArrayList<AppLauncher> {
|
fun getAllAppLaunchers(): ArrayList<AppLauncher> {
|
||||||
val hiddenIcons = hiddenIconsDB.getHiddenIcons().map {
|
val hiddenIcons = hiddenIconsDB.getHiddenIcons().map {
|
||||||
|
@ -729,7 +774,24 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
val defaultDialerPackage = (getSystemService(Context.TELECOM_SERVICE) as TelecomManager).defaultDialerPackage
|
val defaultDialerPackage = (getSystemService(Context.TELECOM_SERVICE) as TelecomManager).defaultDialerPackage
|
||||||
appLaunchers.firstOrNull { it.packageName == defaultDialerPackage }?.apply {
|
appLaunchers.firstOrNull { it.packageName == defaultDialerPackage }?.apply {
|
||||||
val dialerIcon =
|
val dialerIcon =
|
||||||
HomeScreenGridItem(null, 0, ROW_COUNT - 1, 0, ROW_COUNT - 1, 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)
|
homeScreenGridItems.add(dialerIcon)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -739,7 +801,24 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
val defaultSMSMessengerPackage = Telephony.Sms.getDefaultSmsPackage(this)
|
val defaultSMSMessengerPackage = Telephony.Sms.getDefaultSmsPackage(this)
|
||||||
appLaunchers.firstOrNull { it.packageName == defaultSMSMessengerPackage }?.apply {
|
appLaunchers.firstOrNull { it.packageName == defaultSMSMessengerPackage }?.apply {
|
||||||
val SMSMessengerIcon =
|
val SMSMessengerIcon =
|
||||||
HomeScreenGridItem(null, 1, ROW_COUNT - 1, 1, ROW_COUNT - 1, 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)
|
homeScreenGridItems.add(SMSMessengerIcon)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -751,7 +830,24 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
val defaultBrowserPackage = resolveInfo!!.activityInfo.packageName
|
val defaultBrowserPackage = resolveInfo!!.activityInfo.packageName
|
||||||
appLaunchers.firstOrNull { it.packageName == defaultBrowserPackage }?.apply {
|
appLaunchers.firstOrNull { it.packageName == defaultBrowserPackage }?.apply {
|
||||||
val browserIcon =
|
val browserIcon =
|
||||||
HomeScreenGridItem(null, 2, ROW_COUNT - 1, 2, ROW_COUNT - 1, 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)
|
homeScreenGridItems.add(browserIcon)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -762,7 +858,24 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
val storePackage = potentialStores.firstOrNull { isPackageInstalled(it) && appLaunchers.map { it.packageName }.contains(it) }
|
val storePackage = potentialStores.firstOrNull { isPackageInstalled(it) && appLaunchers.map { it.packageName }.contains(it) }
|
||||||
if (storePackage != null) {
|
if (storePackage != null) {
|
||||||
appLaunchers.firstOrNull { it.packageName == storePackage }?.apply {
|
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,
|
||||||
|
config.homeRowCount - 1,
|
||||||
|
3,
|
||||||
|
config.homeRowCount - 1,
|
||||||
|
0,
|
||||||
|
storePackage,
|
||||||
|
"",
|
||||||
|
title,
|
||||||
|
ITEM_TYPE_ICON,
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
)
|
||||||
homeScreenGridItems.add(storeIcon)
|
homeScreenGridItems.add(storeIcon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -775,7 +888,24 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
val defaultCameraPackage = resolveInfo!!.activityInfo.packageName
|
val defaultCameraPackage = resolveInfo!!.activityInfo.packageName
|
||||||
appLaunchers.firstOrNull { it.packageName == defaultCameraPackage }?.apply {
|
appLaunchers.firstOrNull { it.packageName == defaultCameraPackage }?.apply {
|
||||||
val cameraIcon =
|
val cameraIcon =
|
||||||
HomeScreenGridItem(null, 4, ROW_COUNT - 1, 4, ROW_COUNT - 1, 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)
|
homeScreenGridItems.add(cameraIcon)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -12,6 +12,9 @@ import com.simplemobiletools.launcher.BuildConfig
|
||||||
import com.simplemobiletools.launcher.R
|
import com.simplemobiletools.launcher.R
|
||||||
import com.simplemobiletools.launcher.extensions.config
|
import com.simplemobiletools.launcher.extensions.config
|
||||||
import com.simplemobiletools.launcher.helpers.MAX_COLUMN_COUNT
|
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 kotlinx.android.synthetic.main.activity_settings.*
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
@ -38,11 +41,13 @@ class SettingsActivity : SimpleActivity() {
|
||||||
setupAlwaysNavigateToHomeScreen()
|
setupAlwaysNavigateToHomeScreen()
|
||||||
setupDrawerColumnCount()
|
setupDrawerColumnCount()
|
||||||
setupDrawerSearchBar()
|
setupDrawerSearchBar()
|
||||||
|
setupHomeRowCount()
|
||||||
|
setupHomeColumnCount()
|
||||||
setupLanguage()
|
setupLanguage()
|
||||||
setupManageHiddenIcons()
|
setupManageHiddenIcons()
|
||||||
updateTextColors(settings_holder)
|
updateTextColors(settings_holder)
|
||||||
|
|
||||||
arrayOf(settings_color_customization_section_label, settings_general_settings_label, settings_drawer_settings_label).forEach {
|
arrayOf(settings_color_customization_section_label, settings_general_settings_label, settings_drawer_settings_label, settings_home_screen_label).forEach {
|
||||||
it.setTextColor(getProperPrimaryColor())
|
it.setTextColor(getProperPrimaryColor())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,6 +129,44 @@ class SettingsActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupHomeRowCount() {
|
||||||
|
val currentRowCount = config.homeRowCount
|
||||||
|
settings_home_screen_row_count.text = currentRowCount.toString()
|
||||||
|
settings_home_screen_row_count_holder.setOnClickListener {
|
||||||
|
val items = ArrayList<RadioItem>()
|
||||||
|
for (i in MIN_ROW_COUNT..MAX_ROW_COUNT) {
|
||||||
|
items.add(RadioItem(i, resources.getQuantityString(R.plurals.row_counts, i, i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioGroupDialog(this, items, currentRowCount) {
|
||||||
|
val newRowCount = it as Int
|
||||||
|
if (currentRowCount != newRowCount) {
|
||||||
|
config.homeRowCount = newRowCount
|
||||||
|
setupHomeRowCount()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupHomeColumnCount() {
|
||||||
|
val currentColumnCount = config.homeColumnCount
|
||||||
|
settings_home_screen_column_count.text = currentColumnCount.toString()
|
||||||
|
settings_home_screen_column_count_holder.setOnClickListener {
|
||||||
|
val items = ArrayList<RadioItem>()
|
||||||
|
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) {
|
||||||
|
config.homeColumnCount = newColumnCount
|
||||||
|
setupHomeColumnCount()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupLanguage() {
|
private fun setupLanguage() {
|
||||||
settings_language.text = Locale.getDefault().displayLanguage
|
settings_language.text = Locale.getDefault().displayLanguage
|
||||||
settings_language_holder.beVisibleIf(isTiramisuPlus())
|
settings_language_holder.beVisibleIf(isTiramisuPlus())
|
||||||
|
|
|
@ -15,7 +15,7 @@ import com.simplemobiletools.launcher.models.AppLauncher
|
||||||
import com.simplemobiletools.launcher.models.HiddenIcon
|
import com.simplemobiletools.launcher.models.HiddenIcon
|
||||||
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
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)
|
@TypeConverters(Converters::class)
|
||||||
abstract class AppsDatabase : RoomDatabase() {
|
abstract class AppsDatabase : RoomDatabase() {
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ abstract class AppsDatabase : RoomDatabase() {
|
||||||
.addMigrations(MIGRATION_1_2)
|
.addMigrations(MIGRATION_1_2)
|
||||||
.addMigrations(MIGRATION_2_3)
|
.addMigrations(MIGRATION_2_3)
|
||||||
.addMigrations(MIGRATION_3_4)
|
.addMigrations(MIGRATION_3_4)
|
||||||
|
.addMigrations(MIGRATION_4_5)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,5 +65,13 @@ abstract class AppsDatabase : RoomDatabase() {
|
||||||
database.execSQL("CREATE UNIQUE INDEX `index_hidden_icons_id` ON `hidden_icons` (`id`)")
|
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")
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
|
0,
|
||||||
appLauncher.packageName,
|
appLauncher.packageName,
|
||||||
appLauncher.activityName,
|
appLauncher.activityName,
|
||||||
appLauncher.title,
|
appLauncher.title,
|
||||||
|
@ -207,6 +208,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
|
false,
|
||||||
appLauncher.drawable
|
appLauncher.drawable
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import com.simplemobiletools.commons.helpers.isRPlus
|
||||||
import com.simplemobiletools.launcher.R
|
import com.simplemobiletools.launcher.R
|
||||||
import com.simplemobiletools.launcher.activities.MainActivity
|
import com.simplemobiletools.launcher.activities.MainActivity
|
||||||
import com.simplemobiletools.launcher.adapters.WidgetsAdapter
|
import com.simplemobiletools.launcher.adapters.WidgetsAdapter
|
||||||
|
import com.simplemobiletools.launcher.extensions.config
|
||||||
import com.simplemobiletools.launcher.extensions.getInitialCellSize
|
import com.simplemobiletools.launcher.extensions.getInitialCellSize
|
||||||
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_SHORTCUT
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_SHORTCUT
|
||||||
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_WIDGET
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_WIDGET
|
||||||
|
@ -238,6 +239,11 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWidgetLongPressed(appWidget: AppWidget) {
|
override fun onWidgetLongPressed(appWidget: AppWidget) {
|
||||||
|
if (appWidget.heightCells > context.config.homeRowCount - 1 || appWidget.widthCells > context.config.homeColumnCount) {
|
||||||
|
context.showErrorToast(context.getString(R.string.widget_too_big))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val type = if (appWidget.isShortcut) {
|
val type = if (appWidget.isShortcut) {
|
||||||
ITEM_TYPE_SHORTCUT
|
ITEM_TYPE_SHORTCUT
|
||||||
} else {
|
} else {
|
||||||
|
@ -250,6 +256,7 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
|
0,
|
||||||
appWidget.appPackageName,
|
appWidget.appPackageName,
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -259,6 +266,7 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
|
false,
|
||||||
appWidget.widgetPreviewImage,
|
appWidget.widgetPreviewImage,
|
||||||
appWidget.providerInfo,
|
appWidget.providerInfo,
|
||||||
appWidget.activityInfo,
|
appWidget.activityInfo,
|
||||||
|
|
|
@ -13,6 +13,14 @@ class Config(context: Context) : BaseConfig(context) {
|
||||||
get() = prefs.getBoolean(WAS_HOME_SCREEN_INIT, false)
|
get() = prefs.getBoolean(WAS_HOME_SCREEN_INIT, false)
|
||||||
set(wasHomeScreenInit) = prefs.edit().putBoolean(WAS_HOME_SCREEN_INIT, wasHomeScreenInit).apply()
|
set(wasHomeScreenInit) = prefs.edit().putBoolean(WAS_HOME_SCREEN_INIT, wasHomeScreenInit).apply()
|
||||||
|
|
||||||
|
var homeColumnCount: Int
|
||||||
|
get() = prefs.getInt(HOME_COLUMN_COUNT, COLUMN_COUNT)
|
||||||
|
set(homeColumnCount) = prefs.edit().putInt(HOME_COLUMN_COUNT, homeColumnCount).apply()
|
||||||
|
|
||||||
|
var homeRowCount: Int
|
||||||
|
get() = prefs.getInt(HOME_ROW_COUNT, ROW_COUNT)
|
||||||
|
set(homeRowCount) = prefs.edit().putInt(HOME_ROW_COUNT, homeRowCount).apply()
|
||||||
|
|
||||||
var drawerColumnCount: Int
|
var drawerColumnCount: Int
|
||||||
get() = prefs.getInt(DRAWER_COLUMN_COUNT, context.resources.getInteger(R.integer.portrait_column_count))
|
get() = prefs.getInt(DRAWER_COLUMN_COUNT, context.resources.getInteger(R.integer.portrait_column_count))
|
||||||
set(drawerColumnCount) = prefs.edit().putInt(DRAWER_COLUMN_COUNT, drawerColumnCount).apply()
|
set(drawerColumnCount) = prefs.edit().putInt(DRAWER_COLUMN_COUNT, drawerColumnCount).apply()
|
||||||
|
|
|
@ -5,6 +5,8 @@ const val WIDGET_LIST_ITEMS_HOLDER = 1
|
||||||
|
|
||||||
// shared prefs
|
// shared prefs
|
||||||
const val WAS_HOME_SCREEN_INIT = "was_home_screen_init"
|
const val WAS_HOME_SCREEN_INIT = "was_home_screen_init"
|
||||||
|
const val HOME_ROW_COUNT = "home_row_count"
|
||||||
|
const val HOME_COLUMN_COUNT = "home_column_count"
|
||||||
const val DRAWER_COLUMN_COUNT = "drawer_column_count"
|
const val DRAWER_COLUMN_COUNT = "drawer_column_count"
|
||||||
const val SHOW_SEARCH_BAR = "show_search_bar"
|
const val SHOW_SEARCH_BAR = "show_search_bar"
|
||||||
const val ALWAYS_NAVIGATE_TO_HOME_SCREEN = "always_navigate_to_home_screen"
|
const val ALWAYS_NAVIGATE_TO_HOME_SCREEN = "always_navigate_to_home_screen"
|
||||||
|
@ -12,6 +14,9 @@ const val ALWAYS_NAVIGATE_TO_HOME_SCREEN = "always_navigate_to_home_screen"
|
||||||
// default home screen grid size
|
// default home screen grid size
|
||||||
const val ROW_COUNT = 6
|
const val ROW_COUNT = 6
|
||||||
const val COLUMN_COUNT = 5
|
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 MAX_COLUMN_COUNT = 15
|
||||||
|
|
||||||
const val UNINSTALL_APP_REQUEST_CODE = 50
|
const val UNINSTALL_APP_REQUEST_CODE = 50
|
||||||
|
|
|
@ -4,4 +4,8 @@ interface FlingListener {
|
||||||
fun onFlingUp()
|
fun onFlingUp()
|
||||||
|
|
||||||
fun onFlingDown()
|
fun onFlingDown()
|
||||||
|
|
||||||
|
fun onFlingRight()
|
||||||
|
|
||||||
|
fun onFlingLeft()
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ interface HomeScreenGridItemsDao {
|
||||||
@Query("UPDATE home_screen_grid_items SET title = :title WHERE id = :id")
|
@Query("UPDATE home_screen_grid_items SET title = :title WHERE id = :id")
|
||||||
fun updateItemTitle(title: String, id: Long): Int
|
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")
|
@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, id: Long)
|
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")
|
@Query("DELETE FROM home_screen_grid_items WHERE id = :id")
|
||||||
fun deleteById(id: Long)
|
fun deleteById(id: Long)
|
||||||
|
|
|
@ -15,6 +15,7 @@ data class HomeScreenGridItem(
|
||||||
@ColumnInfo(name = "top") var top: Int,
|
@ColumnInfo(name = "top") var top: Int,
|
||||||
@ColumnInfo(name = "right") var right: Int,
|
@ColumnInfo(name = "right") var right: Int,
|
||||||
@ColumnInfo(name = "bottom") var bottom: Int,
|
@ColumnInfo(name = "bottom") var bottom: Int,
|
||||||
|
@ColumnInfo(name = "page") var page: Int,
|
||||||
@ColumnInfo(name = "package_name") var packageName: String,
|
@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 = "activity_name") var activityName: String, // needed at apps that create multiple icons at install, not just the launcher
|
||||||
@ColumnInfo(name = "title") var title: String,
|
@ColumnInfo(name = "title") var title: String,
|
||||||
|
@ -24,6 +25,7 @@ data class HomeScreenGridItem(
|
||||||
@ColumnInfo(name = "intent") var intent: String, // used at static and dynamic shortcuts on click
|
@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 = "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 = "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 drawable: Drawable? = null,
|
||||||
@Ignore var providerInfo: AppWidgetProviderInfo? = null, // used at widgets
|
@Ignore var providerInfo: AppWidgetProviderInfo? = null, // used at widgets
|
||||||
|
@ -31,7 +33,7 @@ data class HomeScreenGridItem(
|
||||||
@Ignore var widthCells: Int = 1,
|
@Ignore var widthCells: Int = 1,
|
||||||
@Ignore var heightCells: 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, false, null, null, null, 1, 1)
|
||||||
|
|
||||||
fun getWidthInCells() = if (right == -1 || left == -1) {
|
fun getWidthInCells() = if (right == -1 || left == -1) {
|
||||||
widthCells
|
widthCells
|
||||||
|
@ -45,5 +47,21 @@ data class HomeScreenGridItem(
|
||||||
bottom - top + 1
|
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"
|
fun getItemIdentifier() = "$packageName/$activityName"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.simplemobiletools.launcher.views
|
package com.simplemobiletools.launcher.views
|
||||||
|
|
||||||
|
import android.animation.Animator
|
||||||
|
import android.animation.AnimatorListenerAdapter
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.appwidget.AppWidgetHostView
|
import android.appwidget.AppWidgetHostView
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
|
@ -21,35 +24,57 @@ import androidx.core.graphics.drawable.toDrawable
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||||
import androidx.customview.widget.ExploreByTouchHelper
|
import androidx.customview.widget.ExploreByTouchHelper
|
||||||
|
import com.google.android.material.math.MathUtils
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.commons.helpers.isSPlus
|
import com.simplemobiletools.commons.helpers.isSPlus
|
||||||
import com.simplemobiletools.launcher.R
|
import com.simplemobiletools.launcher.R
|
||||||
import com.simplemobiletools.launcher.activities.MainActivity
|
import com.simplemobiletools.launcher.activities.MainActivity
|
||||||
|
import com.simplemobiletools.launcher.extensions.config
|
||||||
import com.simplemobiletools.launcher.extensions.getDrawableForPackageName
|
import com.simplemobiletools.launcher.extensions.getDrawableForPackageName
|
||||||
import com.simplemobiletools.launcher.extensions.homeScreenGridItemsDB
|
import com.simplemobiletools.launcher.extensions.homeScreenGridItemsDB
|
||||||
import com.simplemobiletools.launcher.helpers.*
|
import com.simplemobiletools.launcher.helpers.*
|
||||||
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
import kotlinx.android.synthetic.main.activity_main.view.*
|
import kotlinx.android.synthetic.main.activity_main.view.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.floor
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : RelativeLayout(context, attrs, defStyle) {
|
class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : RelativeLayout(context, attrs, defStyle) {
|
||||||
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
|
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
|
||||||
|
|
||||||
private var iconMargin = context.resources.getDimension(R.dimen.icon_side_margin).toInt()
|
private var columnCount = context.config.homeColumnCount
|
||||||
|
private var rowCount = context.config.homeRowCount
|
||||||
|
private var cellXCoords = ArrayList<Int>(columnCount)
|
||||||
|
private var cellYCoords = ArrayList<Int>(rowCount)
|
||||||
|
var cellWidth = 0
|
||||||
|
var cellHeight = 0
|
||||||
|
private var extraXMargin = 0
|
||||||
|
private var extraYMargin = 0
|
||||||
|
|
||||||
|
private var iconMargin = (context.resources.getDimension(R.dimen.icon_side_margin) * 5 / columnCount).toInt()
|
||||||
private var labelSideMargin = context.resources.getDimension(R.dimen.small_margin).toInt()
|
private var labelSideMargin = context.resources.getDimension(R.dimen.small_margin).toInt()
|
||||||
private var roundedCornerRadius = context.resources.getDimension(R.dimen.activity_margin)
|
private var roundedCornerRadius = context.resources.getDimension(R.dimen.activity_margin)
|
||||||
|
private var pageIndicatorRadius = context.resources.getDimension(R.dimen.page_indicator_dot_radius)
|
||||||
|
private var pageIndicatorMargin = context.resources.getDimension(R.dimen.page_indicator_margin)
|
||||||
private var textPaint: TextPaint
|
private var textPaint: TextPaint
|
||||||
private var dragShadowCirclePaint: Paint
|
private var dragShadowCirclePaint: Paint
|
||||||
|
private var emptyPageIndicatorPaint: Paint
|
||||||
|
private var currentPageIndicatorPaint: Paint
|
||||||
private var draggedItem: HomeScreenGridItem? = null
|
private var draggedItem: HomeScreenGridItem? = null
|
||||||
private var resizedWidget: HomeScreenGridItem? = null
|
private var resizedWidget: HomeScreenGridItem? = null
|
||||||
private var isFirstDraw = true
|
private var isFirstDraw = true
|
||||||
|
private var redrawWidgets = false
|
||||||
private var iconSize = 0
|
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 lastPage = 0
|
||||||
private var cellXCoords = ArrayList<Int>(COLUMN_COUNT)
|
private var currentPage = 0
|
||||||
private var cellYCoords = ArrayList<Int>(ROW_COUNT)
|
private var pageChangeLastArea = PageChangeArea.MIDDLE
|
||||||
var cellWidth = 0
|
private var pageChangeLastAreaEntryTime = 0L
|
||||||
var cellHeight = 0
|
private var pageChangeAnimLeftPercentage = 0f
|
||||||
|
private var pageChangeEnabled = true
|
||||||
|
private var pageChangeIndicatorsAlpha = 0f
|
||||||
|
|
||||||
// apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides
|
// apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides
|
||||||
var sideMargins = Rect()
|
var sideMargins = Rect()
|
||||||
|
@ -65,6 +90,27 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null
|
var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null
|
||||||
var itemLongClickListener: ((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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val startFadingIndicators: Runnable = Runnable {
|
||||||
|
ValueAnimator.ofFloat(1f, 0f)
|
||||||
|
.apply {
|
||||||
|
addUpdateListener {
|
||||||
|
pageChangeIndicatorsAlpha = it.animatedValue as Float
|
||||||
|
redrawGrid()
|
||||||
|
}
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this))
|
ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this))
|
||||||
|
|
||||||
|
@ -75,11 +121,19 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
dragShadowCirclePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
dragShadowCirclePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
color = context.resources.getColor(R.color.light_grey_stroke)
|
color = context.resources.getColor(R.color.hint_white)
|
||||||
strokeWidth = context.resources.getDimension(R.dimen.small_margin)
|
strokeWidth = context.resources.getDimension(R.dimen.small_margin)
|
||||||
style = Paint.Style.STROKE
|
style = Paint.Style.STROKE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emptyPageIndicatorPaint = Paint(dragShadowCirclePaint).apply {
|
||||||
|
strokeWidth = context.resources.getDimension(R.dimen.page_indicator_stroke_width)
|
||||||
|
}
|
||||||
|
currentPageIndicatorPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
|
color = context.resources.getColor(R.color.white)
|
||||||
|
style = Paint.Style.FILL
|
||||||
|
}
|
||||||
|
|
||||||
val sideMargin = context.resources.getDimension(R.dimen.normal_margin).toInt()
|
val sideMargin = context.resources.getDimension(R.dimen.normal_margin).toInt()
|
||||||
sideMargins.apply {
|
sideMargins.apply {
|
||||||
top = context.statusBarHeight
|
top = context.statusBarHeight
|
||||||
|
@ -115,6 +169,19 @@ 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)
|
||||||
|
gridCenters.clear()
|
||||||
|
iconMargin = (context.resources.getDimension(R.dimen.icon_side_margin) * 5 / columnCount).toInt()
|
||||||
|
redrawWidgets = true
|
||||||
|
redrawGrid()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun removeAppIcon(item: HomeScreenGridItem) {
|
fun removeAppIcon(item: HomeScreenGridItem) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
removeItemFromHomeScreen(item)
|
removeItemFromHomeScreen(item)
|
||||||
|
@ -123,6 +190,11 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
gridItems.removeIf { it.id == item.id }
|
gridItems.removeIf { it.id == item.id }
|
||||||
|
if (currentPage > getMaxPage()) {
|
||||||
|
post {
|
||||||
|
prevPage()
|
||||||
|
}
|
||||||
|
}
|
||||||
redrawGrid()
|
redrawGrid()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,6 +225,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pageChangeIndicatorsAlpha = 1f
|
||||||
|
removeCallbacks(startFadingIndicators)
|
||||||
if (draggedItemCurrentCoords.first == -1 && draggedItemCurrentCoords.second == -1 && draggedItem != null) {
|
if (draggedItemCurrentCoords.first == -1 && draggedItemCurrentCoords.second == -1 && draggedItem != null) {
|
||||||
if (draggedItem!!.type == ITEM_TYPE_WIDGET) {
|
if (draggedItem!!.type == ITEM_TYPE_WIDGET) {
|
||||||
val draggedWidgetView = widgetViews.firstOrNull { it.tag == draggedItem?.widgetId }
|
val draggedWidgetView = widgetViews.firstOrNull { it.tag == draggedItem?.widgetId }
|
||||||
|
@ -165,9 +239,47 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
draggedItemCurrentCoords = Pair(x, y)
|
draggedItemCurrentCoords = Pair(x, y)
|
||||||
|
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()
|
redrawGrid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clearPageChangeFlags() {
|
||||||
|
pageChangeLastArea = PageChangeArea.MIDDLE
|
||||||
|
pageChangeLastAreaEntryTime = 0
|
||||||
|
removeCallbacks(checkAndExecuteDelayedPageChange)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun schedulePageChange() {
|
||||||
|
pageChangeLastAreaEntryTime = System.currentTimeMillis()
|
||||||
|
postDelayed(checkAndExecuteDelayedPageChange, PAGE_CHANGE_HOLD_THRESHOLD)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun scheduleIndicatorsFade() {
|
||||||
|
pageChangeIndicatorsAlpha = 1f
|
||||||
|
postDelayed(startFadingIndicators, PAGE_INDICATORS_FADE_DELAY)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doWithPageChangeDelay(needed: PageChangeArea, pageChangeFunction: () -> Boolean) {
|
||||||
|
if (pageChangeLastArea != needed) {
|
||||||
|
pageChangeLastArea = needed
|
||||||
|
schedulePageChange()
|
||||||
|
} 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
|
// figure out at which cell was the item dropped, if it is empty
|
||||||
fun itemDraggingStopped() {
|
fun itemDraggingStopped() {
|
||||||
widgetViews.forEach {
|
widgetViews.forEach {
|
||||||
|
@ -178,6 +290,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduleIndicatorsFade()
|
||||||
when (draggedItem!!.type) {
|
when (draggedItem!!.type) {
|
||||||
ITEM_TYPE_ICON, ITEM_TYPE_SHORTCUT -> addAppIconOrShortcut()
|
ITEM_TYPE_ICON, ITEM_TYPE_SHORTCUT -> addAppIconOrShortcut()
|
||||||
ITEM_TYPE_WIDGET -> addWidget()
|
ITEM_TYPE_WIDGET -> addWidget()
|
||||||
|
@ -207,10 +320,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
item.left = cellsRect.left
|
item.left = cellsRect.left
|
||||||
item.top = cellsRect.top
|
item.top = cellsRect.top
|
||||||
item.right = cellsRect.right
|
item.right = cellsRect.right
|
||||||
item.bottom = cellsRect.bottom
|
item.bottom = if (cellsRect.bottom > rowCount - 2) {
|
||||||
|
rowCount - 2
|
||||||
|
} else {
|
||||||
|
cellsRect.bottom
|
||||||
|
}
|
||||||
updateWidgetPositionAndSize(widgetView, item)
|
updateWidgetPositionAndSize(widgetView, item)
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
context.homeScreenGridItemsDB.updateItemPosition(cellsRect.left, cellsRect.top, cellsRect.right, cellsRect.bottom, item.id!!)
|
context.homeScreenGridItemsDB.updateItemPosition(item.left, item.top, item.right, item.bottom, item.page, false, item.id!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,9 +366,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
// check if the destination cell is empty
|
// check if the destination cell is empty
|
||||||
var areAllCellsEmpty = true
|
var areAllCellsEmpty = true
|
||||||
val wantedCell = Pair(xIndex, yIndex)
|
val wantedCell = Pair(xIndex, yIndex)
|
||||||
gridItems.forEach { item ->
|
gridItems.filter { it.page == currentPage || it.docked }.forEach { item ->
|
||||||
for (xCell in item.left..item.right) {
|
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 cell = Pair(xCell, yCell)
|
||||||
val isAnyCellOccupied = wantedCell == cell
|
val isAnyCellOccupied = wantedCell == cell
|
||||||
if (isAnyCellOccupied) {
|
if (isAnyCellOccupied) {
|
||||||
|
@ -272,9 +389,11 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
top = yIndex
|
top = yIndex
|
||||||
right = xIndex
|
right = xIndex
|
||||||
bottom = yIndex
|
bottom = yIndex
|
||||||
|
page = currentPage
|
||||||
|
docked = yIndex == rowCount - 1
|
||||||
|
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
context.homeScreenGridItemsDB.updateItemPosition(left, top, right, bottom, id!!)
|
context.homeScreenGridItemsDB.updateItemPosition(left, top, right, bottom, page, docked, id!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
redrawIcons = true
|
redrawIcons = true
|
||||||
|
@ -286,6 +405,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
yIndex,
|
yIndex,
|
||||||
xIndex,
|
xIndex,
|
||||||
yIndex,
|
yIndex,
|
||||||
|
currentPage,
|
||||||
draggedItem!!.packageName,
|
draggedItem!!.packageName,
|
||||||
draggedItem!!.activityName,
|
draggedItem!!.activityName,
|
||||||
draggedItem!!.title,
|
draggedItem!!.title,
|
||||||
|
@ -295,6 +415,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
draggedItem!!.icon,
|
draggedItem!!.icon,
|
||||||
|
yIndex == rowCount - 1,
|
||||||
draggedItem!!.drawable,
|
draggedItem!!.drawable,
|
||||||
draggedItem!!.providerInfo,
|
draggedItem!!.providerInfo,
|
||||||
draggedItem!!.activityInfo
|
draggedItem!!.activityInfo
|
||||||
|
@ -352,9 +473,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
var areAllCellsEmpty = true
|
var areAllCellsEmpty = true
|
||||||
gridItems.filter { it.id != draggedItem?.id }.forEach { item ->
|
gridItems.filter { it.id != draggedItem?.id && (it.page == currentPage || it.docked) }.forEach { item ->
|
||||||
for (xCell in item.left..item.right) {
|
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 cell = Pair(xCell, yCell)
|
||||||
val isAnyCellOccupied = widgetTargetCells.contains(cell)
|
val isAnyCellOccupied = widgetTargetCells.contains(cell)
|
||||||
if (isAnyCellOccupied) {
|
if (isAnyCellOccupied) {
|
||||||
|
@ -372,6 +493,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
top = widgetRect.top
|
top = widgetRect.top
|
||||||
right = widgetRect.right
|
right = widgetRect.right
|
||||||
bottom = widgetRect.bottom
|
bottom = widgetRect.bottom
|
||||||
|
page = currentPage
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
|
@ -383,9 +505,17 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
bindWidget(widgetItem, false)
|
bindWidget(widgetItem, false)
|
||||||
}
|
}
|
||||||
} else {
|
} 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,
|
||||||
|
false,
|
||||||
|
widgetItem.id!!
|
||||||
|
)
|
||||||
val widgetView = widgetViews.firstOrNull { it.tag == widgetItem.widgetId }
|
val widgetView = widgetViews.firstOrNull { it.tag == widgetItem.widgetId }
|
||||||
if (widgetView != null) {
|
if (widgetView != null && !widgetItem.outOfBounds()) {
|
||||||
post {
|
post {
|
||||||
widgetView.x = calculateWidgetX(widgetItem.left)
|
widgetView.x = calculateWidgetX(widgetItem.left)
|
||||||
widgetView.y = calculateWidgetY(widgetItem.top)
|
widgetView.y = calculateWidgetY(widgetItem.top)
|
||||||
|
@ -398,6 +528,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
right = widgetItem.right
|
right = widgetItem.right
|
||||||
top = widgetItem.top
|
top = widgetItem.top
|
||||||
bottom = widgetItem.bottom
|
bottom = widgetItem.bottom
|
||||||
|
page = widgetItem.page
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,6 +568,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
} else {
|
} else {
|
||||||
removeItemFromHomeScreen(item)
|
removeItemFromHomeScreen(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentPage > getMaxPage()) {
|
||||||
|
prevPage(redraw = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -469,7 +604,26 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateWidgetPositionAndSize(widgetView: AppWidgetHostView, item: HomeScreenGridItem): Size {
|
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)
|
widgetView.y = calculateWidgetY(item.top)
|
||||||
val widgetWidth = item.getWidthInCells() * cellWidth
|
val widgetWidth = item.getWidthInCells() * cellWidth
|
||||||
val widgetHeight = item.getHeightInCells() * cellHeight
|
val widgetHeight = item.getHeightInCells() * cellHeight
|
||||||
|
@ -490,9 +644,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
return Size(widgetWidth, widgetHeight)
|
return Size(widgetWidth, widgetHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateWidgetX(leftCell: Int) = leftCell * cellWidth + sideMargins.left.toFloat()
|
private fun calculateWidgetX(leftCell: Int) = cellXCoords[leftCell] + sideMargins.left.toFloat() + extraXMargin
|
||||||
|
|
||||||
private fun calculateWidgetY(topCell: Int) = topCell * cellHeight + sideMargins.top.toFloat()
|
private fun calculateWidgetY(topCell: Int) = cellYCoords[topCell] + sideMargins.top.toFloat() + extraYMargin
|
||||||
|
|
||||||
// convert stuff like 102x192 to grid cells like 0x1
|
// convert stuff like 102x192 to grid cells like 0x1
|
||||||
private fun getClosestGridCells(center: Pair<Int, Int>): Pair<Int, Int>? {
|
private fun getClosestGridCells(center: Pair<Int, Int>): Pair<Int, Int>? {
|
||||||
|
@ -529,21 +683,32 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
fillCellSizes()
|
fillCellSizes()
|
||||||
}
|
}
|
||||||
|
|
||||||
gridItems.filter { it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT }.forEach { item ->
|
val currentXFactor = if (currentPage > lastPage) {
|
||||||
if (item.id != draggedItem?.id) {
|
pageChangeAnimLeftPercentage
|
||||||
val drawableX = cellXCoords[item.left] + iconMargin + sideMargins.left
|
} else {
|
||||||
|
-pageChangeAnimLeftPercentage
|
||||||
|
}
|
||||||
|
val lastXFactor = if (currentPage > lastPage) {
|
||||||
|
pageChangeAnimLeftPercentage - 1
|
||||||
|
} else {
|
||||||
|
1 - pageChangeAnimLeftPercentage
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleItemDrawing(item: HomeScreenGridItem, xFactor: Float) {
|
||||||
|
if (item.id != draggedItem?.id) {
|
||||||
|
val drawableX = cellXCoords[item.left] + iconMargin + extraXMargin + sideMargins.left + (width * xFactor).toInt()
|
||||||
|
|
||||||
|
if (item.docked) {
|
||||||
|
val drawableY = cellYCoords[rowCount - 1] + cellHeight - iconMargin - iconSize + sideMargins.top
|
||||||
|
|
||||||
// icons at the bottom are drawn at the bottom of the grid and they have no label
|
|
||||||
if (item.top == ROW_COUNT - 1) {
|
|
||||||
val drawableY = cellYCoords[item.top] + cellHeight - iconSize - iconMargin * 2 + sideMargins.top
|
|
||||||
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
||||||
} else {
|
} else {
|
||||||
val drawableY = cellYCoords[item.top] + iconSize / 2 + sideMargins.top
|
val drawableY = cellYCoords[item.top] + iconMargin + extraYMargin + sideMargins.top
|
||||||
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
||||||
|
|
||||||
if (item.id != draggedItem?.id && item.title.isNotEmpty()) {
|
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 textY = cellYCoords[item.top].toFloat() + iconSize + iconMargin + extraYMargin + labelSideMargin + sideMargins.top
|
||||||
val staticLayout = StaticLayout.Builder
|
val staticLayout = StaticLayout.Builder
|
||||||
.obtain(item.title, 0, item.title.length, textPaint, cellWidth - 2 * labelSideMargin)
|
.obtain(item.title, 0, item.title.length, textPaint, cellWidth - 2 * labelSideMargin)
|
||||||
.setMaxLines(2)
|
.setMaxLines(2)
|
||||||
|
@ -562,29 +727,93 @@ 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
handleItemDrawing(item, 0f)
|
||||||
|
}
|
||||||
|
if (pageChangeAnimLeftPercentage > 0f) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isFirstDraw) {
|
if (isFirstDraw) {
|
||||||
gridItems.filter { it.type == ITEM_TYPE_WIDGET }.forEach { item ->
|
gridItems.filter { it.type == ITEM_TYPE_WIDGET && !it.outOfBounds() }.forEach { item ->
|
||||||
bindWidget(item, true)
|
bindWidget(item, true)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
gridItems.filter { it.type == ITEM_TYPE_WIDGET && !it.outOfBounds() }.forEach { item ->
|
||||||
|
widgetViews.firstOrNull { it.tag == item.widgetId }?.also {
|
||||||
|
updateWidgetPositionAndSize(it, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only draw page indicators when there is a need for it
|
||||||
|
if (pageChangeAnimLeftPercentage > 0f || pageChangeIndicatorsAlpha != 0f) {
|
||||||
|
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
|
||||||
|
if (pageChangeIndicatorsAlpha != 0f) {
|
||||||
|
emptyPageIndicatorPaint.alpha = (pageChangeIndicatorsAlpha * 255.0f).toInt()
|
||||||
|
} else {
|
||||||
|
emptyPageIndicatorPaint.alpha = 255
|
||||||
|
}
|
||||||
|
// 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)
|
||||||
|
if (pageChangeIndicatorsAlpha != 0f) {
|
||||||
|
currentPageIndicatorPaint.alpha = (pageChangeIndicatorsAlpha * 255.0f).toInt()
|
||||||
|
} else {
|
||||||
|
currentPageIndicatorPaint.alpha = 255
|
||||||
|
}
|
||||||
|
canvas.drawCircle(currentIndicatorPosition + pageIndicatorRadius, pageIndicatorY, pageIndicatorRadius, currentPageIndicatorPaint)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) {
|
if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) {
|
||||||
if (draggedItem!!.type == ITEM_TYPE_ICON || draggedItem!!.type == ITEM_TYPE_SHORTCUT) {
|
if (draggedItem!!.type == ITEM_TYPE_ICON || draggedItem!!.type == ITEM_TYPE_SHORTCUT) {
|
||||||
// draw a circle under the current cell
|
// draw a circle under the current cell
|
||||||
val center = gridCenters.minBy {
|
val center = gridCenters.minBy {
|
||||||
Math.abs(it.first - draggedItemCurrentCoords.first + sideMargins.left) + Math.abs(it.second - draggedItemCurrentCoords.second + sideMargins.top)
|
abs(it.first - draggedItemCurrentCoords.first + sideMargins.left) + abs(it.second - draggedItemCurrentCoords.second + sideMargins.top)
|
||||||
}
|
}
|
||||||
|
|
||||||
val gridCells = getClosestGridCells(center)
|
val gridCells = getClosestGridCells(center)
|
||||||
if (gridCells != null) {
|
if (gridCells != null) {
|
||||||
val shadowX = cellXCoords[gridCells.first] + iconMargin.toFloat() + iconSize / 2 + sideMargins.left
|
val shadowX = cellXCoords[gridCells.first] + iconMargin + iconSize / 2f + extraXMargin + sideMargins.left
|
||||||
val shadowY = if (gridCells.second == ROW_COUNT - 1) {
|
val shadowY = if (gridCells.second == rowCount - 1) {
|
||||||
cellYCoords[gridCells.second] + cellHeight - iconSize / 2 - iconMargin * 2
|
cellYCoords[gridCells.second] + cellHeight - iconMargin - iconSize / 2f
|
||||||
} else {
|
} else {
|
||||||
cellYCoords[gridCells.second] + iconSize
|
cellYCoords[gridCells.second] + iconMargin + iconSize / 2f + extraYMargin
|
||||||
} + sideMargins.top
|
} + sideMargins.top
|
||||||
|
|
||||||
canvas.drawCircle(shadowX, shadowY.toFloat(), iconSize / 2f, dragShadowCirclePaint)
|
canvas.drawCircle(shadowX, shadowY, iconSize / 2f, dragShadowCirclePaint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// show the app icon itself at dragging, move it above the finger a bit to make it visible
|
// show the app icon itself at dragging, move it above the finger a bit to make it visible
|
||||||
|
@ -602,10 +831,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
val gridCells = getClosestGridCells(center)
|
val gridCells = getClosestGridCells(center)
|
||||||
if (gridCells != null) {
|
if (gridCells != null) {
|
||||||
val widgetRect = getWidgetOccupiedRect(gridCells)
|
val widgetRect = getWidgetOccupiedRect(gridCells)
|
||||||
val leftSide = widgetRect.left * cellWidth + sideMargins.left + iconMargin.toFloat()
|
val leftSide = calculateWidgetX(widgetRect.left)
|
||||||
val topSide = widgetRect.top * cellHeight + sideMargins.top + iconMargin.toFloat()
|
val topSide = calculateWidgetY(widgetRect.top)
|
||||||
val rightSide = leftSide + draggedItem!!.getWidthInCells() * cellWidth - sideMargins.right - iconMargin.toFloat()
|
val rightSide = leftSide + draggedItem!!.getWidthInCells() * cellWidth
|
||||||
val bottomSide = topSide + draggedItem!!.getHeightInCells() * cellHeight - sideMargins.top
|
val bottomSide = topSide + draggedItem!!.getHeightInCells() * cellHeight
|
||||||
canvas.drawRoundRect(leftSide, topSide, rightSide, bottomSide, roundedCornerRadius, roundedCornerRadius, dragShadowCirclePaint)
|
canvas.drawRoundRect(leftSide, topSide, rightSide, bottomSide, roundedCornerRadius, roundedCornerRadius, dragShadowCirclePaint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,14 +859,24 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillCellSizes() {
|
private fun fillCellSizes() {
|
||||||
cellWidth = getFakeWidth() / COLUMN_COUNT
|
cellWidth = getFakeWidth() / context.config.homeColumnCount
|
||||||
cellHeight = getFakeHeight() / ROW_COUNT
|
cellHeight = getFakeHeight() / context.config.homeRowCount
|
||||||
iconSize = cellWidth - 2 * iconMargin
|
extraXMargin = if (cellWidth > cellHeight) {
|
||||||
for (i in 0 until COLUMN_COUNT) {
|
(cellWidth - cellHeight) / 2
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
extraYMargin = if (cellHeight > cellWidth) {
|
||||||
|
(cellHeight - cellWidth) / 2
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
iconSize = min(cellWidth, cellHeight) - 2 * iconMargin
|
||||||
|
for (i in 0 until context.config.homeColumnCount) {
|
||||||
cellXCoords.add(i, i * cellWidth)
|
cellXCoords.add(i, i * cellWidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i in 0 until ROW_COUNT) {
|
for (i in 0 until context.config.homeRowCount) {
|
||||||
cellYCoords.add(i, i * cellHeight)
|
cellYCoords.add(i, i * cellHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,27 +905,33 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
fillCellSizes()
|
fillCellSizes()
|
||||||
}
|
}
|
||||||
|
|
||||||
val clickableLeft = item.left * cellWidth + sideMargins.left
|
val clickableLeft = cellXCoords[item.left] + sideMargins.left + extraXMargin
|
||||||
val clickableTop = cellYCoords[item.top] + iconSize / 3 + sideMargins.top
|
val clickableTop = if (item.docked) {
|
||||||
return Rect(clickableLeft, clickableTop, clickableLeft + cellWidth, clickableTop + iconSize * 2)
|
cellYCoords[item.getDockAdjustedTop(rowCount)] + cellHeight - iconSize - iconMargin
|
||||||
|
} else {
|
||||||
|
cellYCoords[item.top] - iconMargin + extraYMargin
|
||||||
|
} + sideMargins.top
|
||||||
|
return Rect(clickableLeft, clickableTop, clickableLeft + iconSize + 2 * iconMargin, clickableTop + iconSize + 2 * iconMargin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// drag the center of the widget, not the top left corner
|
// drag the center of the widget, not the top left corner
|
||||||
private fun getWidgetOccupiedRect(item: Pair<Int, Int>): Rect {
|
private fun getWidgetOccupiedRect(item: Pair<Int, Int>): Rect {
|
||||||
val left = item.first - Math.floor((draggedItem!!.getWidthInCells() - 1) / 2.0).toInt()
|
val left = item.first - floor((draggedItem!!.getWidthInCells() - 1) / 2.0).toInt()
|
||||||
val rect = Rect(left, item.second, left + draggedItem!!.getWidthInCells() - 1, item.second + draggedItem!!.getHeightInCells() - 1)
|
val rect = Rect(left, item.second, left + draggedItem!!.getWidthInCells() - 1, item.second + draggedItem!!.getHeightInCells() - 1)
|
||||||
if (rect.left < 0) {
|
if (rect.left < 0) {
|
||||||
rect.right -= rect.left
|
rect.right -= rect.left
|
||||||
rect.left = 0
|
rect.left = 0
|
||||||
} else if (rect.right > COLUMN_COUNT - 1) {
|
} else if (rect.right > columnCount - 1) {
|
||||||
val diff = rect.right - COLUMN_COUNT + 1
|
val diff = rect.right - columnCount + 1
|
||||||
rect.right -= diff
|
rect.right -= diff
|
||||||
rect.left -= diff
|
rect.left -= diff
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not allow placing widgets at the bottom row, that is for pinned default apps
|
if (rect.top < 0) {
|
||||||
if (rect.bottom >= ROW_COUNT - 1) {
|
rect.bottom -= rect.top
|
||||||
val diff = rect.bottom - ROW_COUNT + 2
|
rect.top = 0
|
||||||
|
} else if (rect.bottom > rowCount - 2) {
|
||||||
|
val diff = rect.bottom - rowCount + 2
|
||||||
rect.bottom -= diff
|
rect.bottom -= diff
|
||||||
rect.top -= diff
|
rect.top -= diff
|
||||||
}
|
}
|
||||||
|
@ -695,7 +940,11 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? {
|
fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? {
|
||||||
for (gridItem in gridItems) {
|
for (gridItem in gridItems.filter { it.page == currentPage || it.docked }) {
|
||||||
|
if (gridItem.outOfBounds()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if (gridItem.type == ITEM_TYPE_ICON || gridItem.type == ITEM_TYPE_SHORTCUT) {
|
if (gridItem.type == ITEM_TYPE_ICON || gridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||||
val rect = getClickableRect(gridItem)
|
val rect = getClickableRect(gridItem)
|
||||||
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
|
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
|
||||||
|
@ -716,6 +965,18 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun intoViewSpaceCoords(screenSpaceX: Float, screenSpaceY: Float): Pair<Float, Float> {
|
||||||
|
val viewLocation = IntArray(2)
|
||||||
|
getLocationOnScreen(viewLocation)
|
||||||
|
val x = screenSpaceX - viewLocation[0]
|
||||||
|
val y = screenSpaceY - viewLocation[1]
|
||||||
|
return Pair(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun HomeScreenGridItem.outOfBounds(): Boolean {
|
||||||
|
return (left >= cellXCoords.size || right >= cellXCoords.size || (!docked && (top >= cellYCoords.size - 1 || bottom >= cellYCoords.size - 1)))
|
||||||
|
}
|
||||||
|
|
||||||
private inner class HomeScreenGridTouchHelper(host: View) : ExploreByTouchHelper(host) {
|
private inner class HomeScreenGridTouchHelper(host: View) : ExploreByTouchHelper(host) {
|
||||||
override fun getVirtualViewAt(x: Float, y: Float): Int {
|
override fun getVirtualViewAt(x: Float, y: Float): Int {
|
||||||
val item = isClickingGridItem(x.toInt(), y.toInt())
|
val item = isClickingGridItem(x.toInt(), y.toInt())
|
||||||
|
@ -728,7 +989,9 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getVisibleVirtualViews(virtualViewIds: MutableList<Int>?) {
|
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 ->
|
sorted.forEachIndexed { index, homeScreenGridItem ->
|
||||||
virtualViewIds?.add(index, homeScreenGridItem.id?.toInt() ?: index)
|
virtualViewIds?.add(index, homeScreenGridItem.id?.toInt() ?: index)
|
||||||
}
|
}
|
||||||
|
@ -769,6 +1032,90 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
lastPage = currentPage
|
||||||
|
currentPage++
|
||||||
|
handlePageChange(redraw)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return 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): Boolean {
|
||||||
|
if (currentPage > 0 && pageChangeEnabled) {
|
||||||
|
lastPage = currentPage
|
||||||
|
currentPage--
|
||||||
|
handlePageChange(redraw)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun skipToPage(targetPage: Int): Boolean {
|
||||||
|
if (currentPage != targetPage && targetPage < getMaxPage() + 1) {
|
||||||
|
lastPage = currentPage
|
||||||
|
currentPage = targetPage
|
||||||
|
handlePageChange()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePageChange(redraw: Boolean = false) {
|
||||||
|
pageChangeEnabled = false
|
||||||
|
pageChangeIndicatorsAlpha = 0f
|
||||||
|
removeCallbacks(startFadingIndicators)
|
||||||
|
if (redraw) {
|
||||||
|
redrawGrid()
|
||||||
|
}
|
||||||
|
ValueAnimator.ofFloat(1f, 0f)
|
||||||
|
.apply {
|
||||||
|
addUpdateListener {
|
||||||
|
pageChangeAnimLeftPercentage = it.animatedValue as Float
|
||||||
|
redrawGrid()
|
||||||
|
}
|
||||||
|
addListener(object : AnimatorListenerAdapter() {
|
||||||
|
override fun onAnimationEnd(animation: Animator) {
|
||||||
|
super.onAnimationEnd(animation)
|
||||||
|
pageChangeAnimLeftPercentage = 0f
|
||||||
|
pageChangeEnabled = true
|
||||||
|
lastPage = currentPage
|
||||||
|
schedulePageChange()
|
||||||
|
scheduleIndicatorsFade()
|
||||||
|
redrawGrid()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L
|
||||||
|
private const val PAGE_INDICATORS_FADE_DELAY = PAGE_CHANGE_HOLD_THRESHOLD + 300L
|
||||||
|
|
||||||
|
private enum class PageChangeArea {
|
||||||
|
LEFT,
|
||||||
|
MIDDLE,
|
||||||
|
RIGHT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,9 @@ import android.util.AttributeSet
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import com.simplemobiletools.launcher.R
|
import com.simplemobiletools.launcher.R
|
||||||
|
import com.simplemobiletools.launcher.extensions.config
|
||||||
import com.simplemobiletools.launcher.extensions.getCellCount
|
import com.simplemobiletools.launcher.extensions.getCellCount
|
||||||
import com.simplemobiletools.launcher.helpers.COLUMN_COUNT
|
|
||||||
import com.simplemobiletools.launcher.helpers.MAX_CLICK_DURATION
|
import com.simplemobiletools.launcher.helpers.MAX_CLICK_DURATION
|
||||||
import com.simplemobiletools.launcher.helpers.ROW_COUNT
|
|
||||||
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
|
|
||||||
@SuppressLint("ViewConstructor")
|
@SuppressLint("ViewConstructor")
|
||||||
|
@ -76,8 +75,8 @@ class MyAppWidgetResizeFrame(context: Context, attrs: AttributeSet, defStyle: In
|
||||||
it.provider.className == gridItem.className
|
it.provider.className == gridItem.className
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
minResizeWidthCells = Math.min(COLUMN_COUNT, context.getCellCount(providerInfo.minResizeWidth))
|
minResizeWidthCells = Math.min(context.config.homeColumnCount, context.getCellCount(providerInfo.minResizeWidth))
|
||||||
minResizeHeightCells = Math.min(ROW_COUNT, context.getCellCount(providerInfo.minResizeHeight))
|
minResizeHeightCells = Math.min(context.config.homeRowCount, context.getCellCount(providerInfo.minResizeHeight))
|
||||||
redrawFrame()
|
redrawFrame()
|
||||||
|
|
||||||
occupiedCells.clear()
|
occupiedCells.clear()
|
||||||
|
@ -224,7 +223,7 @@ class MyAppWidgetResizeFrame(context: Context, attrs: AttributeSet, defStyle: In
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantedBottomCellY == ROW_COUNT - 1) {
|
if (wantedBottomCellY == context.config.homeRowCount - 1) {
|
||||||
areAllCellsFree = false
|
areAllCellsFree = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +321,7 @@ class MyAppWidgetResizeFrame(context: Context, attrs: AttributeSet, defStyle: In
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantedBottomCellY == ROW_COUNT - 1) {
|
if (wantedBottomCellY == context.config.homeRowCount - 1) {
|
||||||
areAllCellsFree = false
|
areAllCellsFree = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@
|
||||||
style="@style/SettingsHolderTextViewOneLinerStyle"
|
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/ripple_bottom_corners">
|
android:background="@drawable/ripple_background">
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||||
android:id="@+id/settings_show_search_bar"
|
android:id="@+id/settings_show_search_bar"
|
||||||
|
@ -201,6 +201,65 @@
|
||||||
android:text="@string/show_search" />
|
android:text="@string/show_search" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/settings_drawer_settings_divider"
|
||||||
|
layout="@layout/divider" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/settings_home_screen_label"
|
||||||
|
style="@style/SettingsSectionLabelStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/home_screen_settings" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/settings_home_screen_row_count_holder"
|
||||||
|
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/ripple_background">
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
|
android:id="@+id/settings_home_screen_row_count_label"
|
||||||
|
style="@style/SettingsTextLabelStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/row_count" />
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
|
android:id="@+id/settings_home_screen_row_count"
|
||||||
|
style="@style/SettingsTextValueStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/settings_home_screen_row_count_label"
|
||||||
|
tools:text="3" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/settings_home_screen_column_count_holder"
|
||||||
|
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/ripple_background">
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
|
android:id="@+id/settings_home_screen_column_count_label"
|
||||||
|
style="@style/SettingsTextLabelStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/column_count" />
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
|
android:id="@+id/settings_home_screen_column_count"
|
||||||
|
style="@style/SettingsTextValueStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/settings_home_screen_column_count_label"
|
||||||
|
tools:text="3" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">لا يمكن إلغاء تثبيت بعض التطبيقات بسبب قيود النظام، ولكن يمكن إخفاء أيقوناتها لتجنب ظهورها.</string>
|
<string name="hidden_icons_placeholder">لا يمكن إلغاء تثبيت بعض التطبيقات بسبب قيود النظام، ولكن يمكن إخفاء أيقوناتها لتجنب ظهورها.</string>
|
||||||
<string name="app_drawer_settings">درج التطبيق</string>
|
<string name="app_drawer_settings">درج التطبيق</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">Някои приложения не могат да бъдат деинсталирани поради системни ограничения, но можете поне да скриете иконите им, за да не ги виждате.</string>
|
<string name="hidden_icons_placeholder">Някои приложения не могат да бъдат деинсталирани поради системни ограничения, но можете поне да скриете иконите им, за да не ги виждате.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Algunes aplicacions no es poden desinstal·lar a causa de les restriccions del sistema, però almenys podeu ocultar les seves icones per evitar que es vegin.</string>
|
<string name="hidden_icons_placeholder">Algunes aplicacions no es poden desinstal·lar a causa de les restriccions del sistema, però almenys podeu ocultar les seves icones per evitar que es vegin.</string>
|
||||||
<string name="app_drawer_settings">Calaix d\'aplicacions</string>
|
<string name="app_drawer_settings">Calaix d\'aplicacions</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Některé aplikace nelze kvůli systémovým omezením odinstalovat. Ale můžete alespoň skrýt jejich ikony, abyste je neviděli.</string>
|
<string name="hidden_icons_placeholder">Některé aplikace nelze kvůli systémovým omezením odinstalovat. Ale můžete alespoň skrýt jejich ikony, abyste je neviděli.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Einige Apps können aufgrund von Systemeinschränkungen nicht deinstalliert werden, aber du kannst zumindest ihre Symbole ausblenden, um sie nicht zu sehen.</string>
|
<string name="hidden_icons_placeholder">Einige Apps können aufgrund von Systemeinschränkungen nicht deinstalliert werden, aber du kannst zumindest ihre Symbole ausblenden, um sie nicht zu sehen.</string>
|
||||||
<string name="app_drawer_settings">App-Schublade</string>
|
<string name="app_drawer_settings">App-Schublade</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">Ορισμένες εφαρμογές δεν μπορούν να απεγκατασταθούν λόγω περιορισμών του συστήματος, αλλά μπορείτε να αποκρύψετε τα εικονίδια τους για να μην φαίνονται.</string>
|
<string name="hidden_icons_placeholder">Ορισμένες εφαρμογές δεν μπορούν να απεγκατασταθούν λόγω περιορισμών του συστήματος, αλλά μπορείτε να αποκρύψετε τα εικονίδια τους για να μην φαίνονται.</string>
|
||||||
<string name="app_drawer_settings">Συρτάρι εφαρμογών</string>
|
<string name="app_drawer_settings">Συρτάρι εφαρμογών</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Algunas aplicaciones no se pueden desinstalar debido a las restricciones del sistema, pero al menos puedes ocultar sus iconos para evitar verlas.</string>
|
<string name="hidden_icons_placeholder">Algunas aplicaciones no se pueden desinstalar debido a las restricciones del sistema, pero al menos puedes ocultar sus iconos para evitar verlas.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Mõnda rakendust ei saa süsteemipiirangute tõttu eemaldada. Selleks, et neid mitte näha, võid vähemalt nende ikoonid ära peita.</string>
|
<string name="hidden_icons_placeholder">Mõnda rakendust ei saa süsteemipiirangute tõttu eemaldada. Selleks, et neid mitte näha, võid vähemalt nende ikoonid ära peita.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Joitakin sovelluksia ei ole järjestelmärajoitusten vuoksi mahdollista poistaa, mutta voit kuitenkin piilottaa niiden kuvakkeet näkyvistä.</string>
|
<string name="hidden_icons_placeholder">Joitakin sovelluksia ei ole järjestelmärajoitusten vuoksi mahdollista poistaa, mutta voit kuitenkin piilottaa niiden kuvakkeet näkyvistä.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Certaines applications ne peuvent pas être désinstallées en raison de restrictions du système, mais vous pouvez au moins masquer leurs icônes pour éviter de les voir.</string>
|
<string name="hidden_icons_placeholder">Certaines applications ne peuvent pas être désinstallées en raison de restrictions du système, mais vous pouvez au moins masquer leurs icônes pour éviter de les voir.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Algunhas aplicacións non se poden desinstalar debido ás restricións do sistema, pero polo menos podes ocultar as súas iconas para evitar velas.</string>
|
<string name="hidden_icons_placeholder">Algunhas aplicacións non se poden desinstalar debido ás restricións do sistema, pero polo menos podes ocultar as súas iconas para evitar velas.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Neke aplikacije se ne mogu deinstalirati zbog ograničenja sustava, ali njihove ikone možeš sakriti.</string>
|
<string name="hidden_icons_placeholder">Neke aplikacije se ne mogu deinstalirati zbog ograničenja sustava, ali njihove ikone možeš sakriti.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Egyes alkalmazások rendszerkorlátozások miatt nem távolíthatók el, de legalább elrejtheti az ikonjaikat, hogy ne lássa őket.</string>
|
<string name="hidden_icons_placeholder">Egyes alkalmazások rendszerkorlátozások miatt nem távolíthatók el, de legalább elrejtheti az ikonjaikat, hogy ne lássa őket.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Beberapa aplikasi tidak dapat di-uninstal karena keterbatasan sistem, tetapi Anda masih dapat menyembunyikan ikon mereka untuk menyembunyikannya.</string>
|
<string name="hidden_icons_placeholder">Beberapa aplikasi tidak dapat di-uninstal karena keterbatasan sistem, tetapi Anda masih dapat menyembunyikan ikon mereka untuk menyembunyikannya.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Alcune applicazioni non possono essere disinstallate a causa di restrizioni di sistema, ma è possibile almeno nascondere le loro icone per evitare di vederle.</string>
|
<string name="hidden_icons_placeholder">Alcune applicazioni non possono essere disinstallate a causa di restrizioni di sistema, ma è possibile almeno nascondere le loro icone per evitare di vederle.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">חלק מהאפליקציות לא ניתנות להסרה עקב הגבלות מערכת, לפחות אתה יכול להחביא את האייקונים כדי לא לראותם במסך הבית.</string>
|
<string name="hidden_icons_placeholder">חלק מהאפליקציות לא ניתנות להסרה עקב הגבלות מערכת, לפחות אתה יכול להחביא את האייקונים כדי לא לראותם במסך הבית.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">一部のアプリはシステムの制限によりアンインストールできませんが、非表示によって表示されないようにすることはできます。</string>
|
<string name="hidden_icons_placeholder">一部のアプリはシステムの制限によりアンインストールできませんが、非表示によって表示されないようにすることはできます。</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">Some apps cannot be uninstalled due to system restrictions, but you can at least hide their icons to avoid seeing them.</string>
|
<string name="hidden_icons_placeholder">Some apps cannot be uninstalled due to system restrictions, but you can at least hide their icons to avoid seeing them.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">സിസ്റ്റം നിയന്ത്രണങ്ങൾ കാരണം ചില ആപ്പുകൾ അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല, എന്നാൽ അവ കാണാതിരിക്കാൻ നിങ്ങൾക്ക് അവയുടെ ഐക്കണുകളെങ്കിലും മറയ്ക്കാം.</string>
|
<string name="hidden_icons_placeholder">സിസ്റ്റം നിയന്ത്രണങ്ങൾ കാരണം ചില ആപ്പുകൾ അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല, എന്നാൽ അവ കാണാതിരിക്കാൻ നിങ്ങൾക്ക് അവയുടെ ഐക്കണുകളെങ്കിലും മറയ്ക്കാം.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Noen apper kan ikke avinstalleres pga. systemrestriksjoner, men du kan i det minste skjule deres ikoner for å unngå å se dem.</string>
|
<string name="hidden_icons_placeholder">Noen apper kan ikke avinstalleres pga. systemrestriksjoner, men du kan i det minste skjule deres ikoner for å unngå å se dem.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Sommige apps kunnen niet worden verwijderd van het systeem, maar hun iconen kunnen wel worden verborgen.</string>
|
<string name="hidden_icons_placeholder">Sommige apps kunnen niet worden verwijderd van het systeem, maar hun iconen kunnen wel worden verborgen.</string>
|
||||||
<string name="app_drawer_settings">App-overzicht</string>
|
<string name="app_drawer_settings">App-overzicht</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">سِسٹم پابندیاں کرکے کجھ اَیپاں اݨاینسٹال کر نہیں سکیاں، پر تسیں آئیکون لُکا سکدے او۔</string>
|
<string name="hidden_icons_placeholder">سِسٹم پابندیاں کرکے کجھ اَیپاں اݨاینسٹال کر نہیں سکیاں، پر تسیں آئیکون لُکا سکدے او۔</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Niektórych aplikacji nie można odinstalować ze względu na ograniczenia systemowe, ale możesz przynajmniej ukryć ich ikony, aby ich nie widzieć.</string>
|
<string name="hidden_icons_placeholder">Niektórych aplikacji nie można odinstalować ze względu na ograniczenia systemowe, ale możesz przynajmniej ukryć ich ikony, aby ich nie widzieć.</string>
|
||||||
<string name="app_drawer_settings">Szuflada aplikacji</string>
|
<string name="app_drawer_settings">Szuflada aplikacji</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">Alguns aplicativos não podem ser desinstalados devido a restrições do sistema, mas você pode ao menos ocultar seus ícones para evitar vê-los.</string>
|
<string name="hidden_icons_placeholder">Alguns aplicativos não podem ser desinstalados devido a restrições do sistema, mas você pode ao menos ocultar seus ícones para evitar vê-los.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">Algumas aplicações não podem ser desinstaladas mas pode ocultar os seus ícones.</string>
|
<string name="hidden_icons_placeholder">Algumas aplicações não podem ser desinstaladas mas pode ocultar os seus ícones.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Some apps cannot be uninstalled due to system restrictions, but you can at least hide their icons to avoid seeing them.</string>
|
<string name="hidden_icons_placeholder">Some apps cannot be uninstalled due to system restrictions, but you can at least hide their icons to avoid seeing them.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Некоторые приложения нельзя удалить из-за системных ограничений, но можно скрыть их значки.</string>
|
<string name="hidden_icons_placeholder">Некоторые приложения нельзя удалить из-за системных ограничений, но можно скрыть их значки.</string>
|
||||||
<string name="app_drawer_settings">Панель приложения</string>
|
<string name="app_drawer_settings">Панель приложения</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">Niektoré apky nemôžu byť odinštalované kvôli systémovým obmedzeniam, viete ich ale aspoň skryť, aby ste ich nevideli.</string>
|
<string name="hidden_icons_placeholder">Niektoré apky nemôžu byť odinštalované kvôli systémovým obmedzeniam, viete ich ale aspoň skryť, aby ste ich nevideli.</string>
|
||||||
<string name="app_drawer_settings">Zoznam apiek</string>
|
<string name="app_drawer_settings">Zoznam apiek</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Domáca obrazovka</string>
|
||||||
|
<string name="widget_too_big">Widget je príliš veľký pre súčasnú domácu obrazovku</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Določenih aplikacij zaradi sistemskih omejitev ni mogoče odstraniti, njihove ikone pa skrijete, da jih ne vidite.</string>
|
<string name="hidden_icons_placeholder">Določenih aplikacij zaradi sistemskih omejitev ni mogoče odstraniti, njihove ikone pa skrijete, da jih ne vidite.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Неке апликације се не могу деинсталирати због системских ограничења, али можете барем сакрити њихове иконе да их не видите.</string>
|
<string name="hidden_icons_placeholder">Неке апликације се не могу деинсталирати због системских ограничења, али можете барем сакрити њихове иконе да их не видите.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Vissa appar kan inte avinstalleras på grund av systembegränsningar, men du kan åtminstone dölja deras ikoner för att slippa se dem.</string>
|
<string name="hidden_icons_placeholder">Vissa appar kan inte avinstalleras på grund av systembegränsningar, men du kan åtminstone dölja deras ikoner för att slippa se dem.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Bazı uygulamalar sistem kısıtlamaları nedeniyle kaldırılamaz, ancak en azından onları görmemek için simgelerini gizleyebilirsiniz.</string>
|
<string name="hidden_icons_placeholder">Bazı uygulamalar sistem kısıtlamaları nedeniyle kaldırılamaz, ancak en azından onları görmemek için simgelerini gizleyebilirsiniz.</string>
|
||||||
<string name="app_drawer_settings">Uygulama çekmecesi</string>
|
<string name="app_drawer_settings">Uygulama çekmecesi</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">Деякі застосунки не можна видалити через системні обмеження, але ви можете принаймні приховати їх піктограми, щоб уникнути їх перегляду.</string>
|
<string name="hidden_icons_placeholder">Деякі застосунки не можна видалити через системні обмеження, але ви можете принаймні приховати їх піктограми, щоб уникнути їх перегляду.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">ⵓⵔ ⵜⵣⵔⵉⵏ ⵜⵓⵙⵙⵔⴰ ⵏ ⴽⵔⴰ ⵏ ⵜⵙⵏⵙⵉⵡⵉⵏ ⵙ ⵜⵎⵏⵜⵉⵍⵜ ⵏ ⵉⵙⵍⴳⵏⵏ ⵏ ⵓⵏⴳⵔⴰⵡ, ⵎⴰⵛⴰ ⵜⵣⵔⵉ ⵜⵓⴼⴼⵔⴰ ⵏ ⵜⵙⵓⵔⴰ ⵏⵏⵙⵏⵜ ⵃⵎⴰ ⵓⵔ ⴷ ⵜⵜⴹⵀⴰⵕⵏⵜ.</string>
|
<string name="hidden_icons_placeholder">ⵓⵔ ⵜⵣⵔⵉⵏ ⵜⵓⵙⵙⵔⴰ ⵏ ⴽⵔⴰ ⵏ ⵜⵙⵏⵙⵉⵡⵉⵏ ⵙ ⵜⵎⵏⵜⵉⵍⵜ ⵏ ⵉⵙⵍⴳⵏⵏ ⵏ ⵓⵏⴳⵔⴰⵡ, ⵎⴰⵛⴰ ⵜⵣⵔⵉ ⵜⵓⴼⴼⵔⴰ ⵏ ⵜⵙⵓⵔⴰ ⵏⵏⵙⵏⵜ ⵃⵎⴰ ⵓⵔ ⴷ ⵜⵜⴹⵀⴰⵕⵏⵜ.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
<string name="hidden_icons_placeholder">某些应用因系统限制而无法卸载, 但你至少可以隐藏它们的图标避免看见它们。</string>
|
<string name="hidden_icons_placeholder">某些应用因系统限制而无法卸载, 但你至少可以隐藏它们的图标避免看见它们。</string>
|
||||||
<string name="app_drawer_settings">应用抽屉</string>
|
<string name="app_drawer_settings">应用抽屉</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">由於系統限制,有些應用程式無法被移除,但您至少可以將它們的圖示隱藏起來,避免看到它們。</string>
|
<string name="hidden_icons_placeholder">由於系統限制,有些應用程式無法被移除,但您至少可以將它們的圖示隱藏起來,避免看到它們。</string>
|
||||||
<string name="app_drawer_settings">應用程式抽屜</string>
|
<string name="app_drawer_settings">應用程式抽屜</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
|
@ -5,5 +5,8 @@
|
||||||
<dimen name="widget_preview_size">140dp</dimen>
|
<dimen name="widget_preview_size">140dp</dimen>
|
||||||
<dimen name="icon_side_margin">10dp</dimen>
|
<dimen name="icon_side_margin">10dp</dimen>
|
||||||
<dimen name="resize_frame_dot_radius">8dp</dimen>
|
<dimen name="resize_frame_dot_radius">8dp</dimen>
|
||||||
<dimen name="move_gesture_threshold">5dp</dimen>
|
<dimen name="move_gesture_threshold">20dp</dimen>
|
||||||
|
<dimen name="page_indicator_dot_radius">6dp</dimen>
|
||||||
|
<dimen name="page_indicator_stroke_width">1dp</dimen>
|
||||||
|
<dimen name="page_indicator_margin">6dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<string name="hidden_icons_placeholder">Some apps cannot be uninstalled due to system restrictions, but you can at least hide their icons to avoid seeing them.</string>
|
<string name="hidden_icons_placeholder">Some apps cannot be uninstalled due to system restrictions, but you can at least hide their icons to avoid seeing them.</string>
|
||||||
<string name="app_drawer_settings">App drawer</string>
|
<string name="app_drawer_settings">App drawer</string>
|
||||||
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
<string name="always_navigate_to_home_screen">Always navigate to home screen on home button</string>
|
||||||
|
<string name="home_screen_settings">Home screen</string>
|
||||||
|
<string name="widget_too_big">Widget is too big for current home screen size</string>
|
||||||
<!--
|
<!--
|
||||||
Haven't found some strings? There's more at
|
Haven't found some strings? There's more at
|
||||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||||
|
|
Loading…
Reference in a new issue