mirror of
https://github.com/SimpleMobileTools/Simple-Launcher.git
synced 2025-04-19 04:17:24 +02:00
Merge pull request #103 from esensar/feature/folders
Add support for folders on home screen
This commit is contained in:
commit
f25738a40f
@ -5,6 +5,7 @@ import android.content.pm.PackageManager
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||||
import com.simplemobiletools.commons.extensions.normalizeString
|
import com.simplemobiletools.commons.extensions.normalizeString
|
||||||
|
import com.simplemobiletools.commons.extensions.viewBinding
|
||||||
import com.simplemobiletools.commons.helpers.NavigationIcon
|
import com.simplemobiletools.commons.helpers.NavigationIcon
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
||||||
@ -17,12 +18,11 @@ import com.simplemobiletools.launcher.extensions.hiddenIconsDB
|
|||||||
import com.simplemobiletools.launcher.models.HiddenIcon
|
import com.simplemobiletools.launcher.models.HiddenIcon
|
||||||
|
|
||||||
class HiddenIconsActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
class HiddenIconsActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||||
private lateinit var binding: ActivityHiddenIconsBinding
|
private val binding by viewBinding(ActivityHiddenIconsBinding::inflate)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
isMaterialActivity = true
|
isMaterialActivity = true
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityHiddenIconsBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
updateIcons()
|
updateIcons()
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ import com.simplemobiletools.launcher.extensions.*
|
|||||||
import com.simplemobiletools.launcher.fragments.MyFragment
|
import com.simplemobiletools.launcher.fragments.MyFragment
|
||||||
import com.simplemobiletools.launcher.helpers.*
|
import com.simplemobiletools.launcher.helpers.*
|
||||||
import com.simplemobiletools.launcher.interfaces.FlingListener
|
import com.simplemobiletools.launcher.interfaces.FlingListener
|
||||||
|
import com.simplemobiletools.launcher.interfaces.ItemMenuListener
|
||||||
import com.simplemobiletools.launcher.models.AppLauncher
|
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
|
||||||
@ -72,7 +73,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
private var wasJustPaused: Boolean = false
|
private var wasJustPaused: Boolean = false
|
||||||
|
|
||||||
private lateinit var mDetector: GestureDetectorCompat
|
private lateinit var mDetector: GestureDetectorCompat
|
||||||
private lateinit var binding: ActivityMainBinding
|
private val binding by viewBinding(ActivityMainBinding::inflate)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var mLastUpEvent = 0L
|
private var mLastUpEvent = 0L
|
||||||
@ -84,7 +85,6 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
useDynamicTheme = false
|
useDynamicTheme = false
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
appLaunched(BuildConfig.APPLICATION_ID)
|
appLaunched(BuildConfig.APPLICATION_ID)
|
||||||
|
|
||||||
@ -132,79 +132,6 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleIntentAction(intent: Intent) {
|
|
||||||
if (intent.action == LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT) {
|
|
||||||
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
|
||||||
val item = launcherApps.getPinItemRequest(intent)
|
|
||||||
if (item.shortcutInfo == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ensureBackgroundThread {
|
|
||||||
val shortcutId = item.shortcutInfo?.id!!
|
|
||||||
val label = item.shortcutInfo?.shortLabel?.toString() ?: item.shortcutInfo?.longLabel?.toString() ?: ""
|
|
||||||
val icon = launcherApps.getShortcutIconDrawable(item.shortcutInfo!!, resources.displayMetrics.densityDpi)
|
|
||||||
val (page, rect) = findFirstEmptyCell()
|
|
||||||
val gridItem = HomeScreenGridItem(
|
|
||||||
null,
|
|
||||||
rect.left,
|
|
||||||
rect.top,
|
|
||||||
rect.right,
|
|
||||||
rect.bottom,
|
|
||||||
page,
|
|
||||||
item.shortcutInfo!!.`package`,
|
|
||||||
"",
|
|
||||||
label,
|
|
||||||
ITEM_TYPE_SHORTCUT,
|
|
||||||
"",
|
|
||||||
-1,
|
|
||||||
shortcutId,
|
|
||||||
icon.toBitmap(),
|
|
||||||
false,
|
|
||||||
icon
|
|
||||||
)
|
|
||||||
|
|
||||||
runOnUiThread {
|
|
||||||
binding.homeScreenGrid.root.skipToPage(page)
|
|
||||||
}
|
|
||||||
// delay showing the shortcut both to let the user see adding it in realtime and hackily avoid concurrent modification exception at HomeScreenGrid
|
|
||||||
Thread.sleep(2000)
|
|
||||||
|
|
||||||
try {
|
|
||||||
item.accept()
|
|
||||||
binding.homeScreenGrid.root.storeAndShowGridItem(gridItem)
|
|
||||||
} catch (ignored: IllegalStateException) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findFirstEmptyCell(): Pair<Int, Rect> {
|
|
||||||
val gridItems = homeScreenGridItemsDB.getAllItems() as ArrayList<HomeScreenGridItem>
|
|
||||||
val maxPage = gridItems.map { it.page }.max()
|
|
||||||
val occupiedCells = ArrayList<Triple<Int, Int, Int>>()
|
|
||||||
gridItems.forEach { item ->
|
|
||||||
for (xCell in item.left..item.right) {
|
|
||||||
for (yCell in item.top..item.bottom) {
|
|
||||||
occupiedCells.add(Triple(item.page, xCell, yCell))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (page in 0 until maxPage) {
|
|
||||||
for (checkedYCell in 0 until config.homeColumnCount) {
|
|
||||||
for (checkedXCell in 0 until config.homeRowCount - 1) {
|
|
||||||
val wantedCell = Triple(page, checkedXCell, checkedYCell)
|
|
||||||
if (!occupiedCells.contains(wantedCell)) {
|
|
||||||
return Pair(page, Rect(wantedCell.second, wantedCell.third, wantedCell.second, wantedCell.third))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Pair(maxPage + 1, Rect(0, 0, 0, 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
binding.homeScreenGrid.root.appWidgetHost.startListening()
|
binding.homeScreenGrid.root.appWidgetHost.startListening()
|
||||||
@ -256,12 +183,13 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
newRowCount = config.homeRowCount,
|
newRowCount = config.homeRowCount,
|
||||||
newColumnCount = config.homeColumnCount
|
newColumnCount = config.homeColumnCount
|
||||||
)
|
)
|
||||||
|
binding.homeScreenGrid.root.updateColors()
|
||||||
binding.allAppsFragment.root.onResume()
|
binding.allAppsFragment.root.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
binding.homeScreenGrid.root.appWidgetHost?.stopListening()
|
binding.homeScreenGrid.root.appWidgetHost.stopListening()
|
||||||
wasJustPaused = false
|
wasJustPaused = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,7 +279,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
hasFingerMoved(event)
|
hasFingerMoved(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mLongPressedIcon != null && mOpenPopupMenu != null && hasFingerMoved) {
|
if (mLongPressedIcon != null && (mOpenPopupMenu != null) && hasFingerMoved) {
|
||||||
mOpenPopupMenu?.dismiss()
|
mOpenPopupMenu?.dismiss()
|
||||||
mOpenPopupMenu = null
|
mOpenPopupMenu = null
|
||||||
binding.homeScreenGrid.root.itemDraggingStarted(mLongPressedIcon!!)
|
binding.homeScreenGrid.root.itemDraggingStarted(mLongPressedIcon!!)
|
||||||
@ -422,6 +350,80 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleIntentAction(intent: Intent) {
|
||||||
|
if (intent.action == LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT) {
|
||||||
|
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||||
|
val item = launcherApps.getPinItemRequest(intent)
|
||||||
|
if (item.shortcutInfo == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val shortcutId = item.shortcutInfo?.id!!
|
||||||
|
val label = item.shortcutInfo?.shortLabel?.toString() ?: item.shortcutInfo?.longLabel?.toString() ?: ""
|
||||||
|
val icon = launcherApps.getShortcutIconDrawable(item.shortcutInfo!!, resources.displayMetrics.densityDpi)
|
||||||
|
val (page, rect) = findFirstEmptyCell()
|
||||||
|
val gridItem = HomeScreenGridItem(
|
||||||
|
null,
|
||||||
|
rect.left,
|
||||||
|
rect.top,
|
||||||
|
rect.right,
|
||||||
|
rect.bottom,
|
||||||
|
page,
|
||||||
|
item.shortcutInfo!!.`package`,
|
||||||
|
"",
|
||||||
|
label,
|
||||||
|
ITEM_TYPE_SHORTCUT,
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
shortcutId,
|
||||||
|
icon.toBitmap(),
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
icon
|
||||||
|
)
|
||||||
|
|
||||||
|
runOnUiThread {
|
||||||
|
binding.homeScreenGrid.root.skipToPage(page)
|
||||||
|
}
|
||||||
|
// delay showing the shortcut both to let the user see adding it in realtime and hackily avoid concurrent modification exception at HomeScreenGrid
|
||||||
|
Thread.sleep(2000)
|
||||||
|
|
||||||
|
try {
|
||||||
|
item.accept()
|
||||||
|
binding.homeScreenGrid.root.storeAndShowGridItem(gridItem)
|
||||||
|
} catch (ignored: IllegalStateException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findFirstEmptyCell(): Pair<Int, Rect> {
|
||||||
|
val gridItems = homeScreenGridItemsDB.getAllItems() as ArrayList<HomeScreenGridItem>
|
||||||
|
val maxPage = gridItems.map { it.page }.max()
|
||||||
|
val occupiedCells = ArrayList<Triple<Int, Int, Int>>()
|
||||||
|
gridItems.forEach { item ->
|
||||||
|
for (xCell in item.left..item.right) {
|
||||||
|
for (yCell in item.top..item.bottom) {
|
||||||
|
occupiedCells.add(Triple(item.page, xCell, yCell))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (page in 0 until maxPage) {
|
||||||
|
for (checkedYCell in 0 until config.homeColumnCount) {
|
||||||
|
for (checkedXCell in 0 until config.homeRowCount - 1) {
|
||||||
|
val wantedCell = Triple(page, checkedXCell, checkedYCell)
|
||||||
|
if (!occupiedCells.contains(wantedCell)) {
|
||||||
|
return Pair(page, Rect(wantedCell.second, wantedCell.third, wantedCell.second, wantedCell.third))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair(maxPage + 1, Rect(0, 0, 0, 0))
|
||||||
|
}
|
||||||
|
|
||||||
// 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))
|
||||||
@ -524,6 +526,9 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
if (clickedGridItem != null) {
|
if (clickedGridItem != null) {
|
||||||
performItemClick(clickedGridItem)
|
performItemClick(clickedGridItem)
|
||||||
}
|
}
|
||||||
|
if (clickedGridItem?.type != ITEM_TYPE_FOLDER) {
|
||||||
|
binding.homeScreenGrid.root.closeFolder(redraw = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun closeAppDrawer(delayed: Boolean = false) {
|
fun closeAppDrawer(delayed: Boolean = false) {
|
||||||
@ -559,20 +564,26 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun performItemClick(clickedGridItem: HomeScreenGridItem) {
|
private fun performItemClick(clickedGridItem: HomeScreenGridItem) {
|
||||||
if (clickedGridItem.type == ITEM_TYPE_ICON) {
|
when (clickedGridItem.type) {
|
||||||
launchApp(clickedGridItem.packageName, clickedGridItem.activityName)
|
ITEM_TYPE_ICON -> launchApp(clickedGridItem.packageName, clickedGridItem.activityName)
|
||||||
} else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
ITEM_TYPE_FOLDER -> openFolder(clickedGridItem)
|
||||||
val id = clickedGridItem.shortcutId
|
ITEM_TYPE_SHORTCUT -> {
|
||||||
val packageName = clickedGridItem.packageName
|
val id = clickedGridItem.shortcutId
|
||||||
val userHandle = android.os.Process.myUserHandle()
|
val packageName = clickedGridItem.packageName
|
||||||
val shortcutBounds = binding.homeScreenGrid.root.getClickableRect(clickedGridItem)
|
val userHandle = android.os.Process.myUserHandle()
|
||||||
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
val shortcutBounds = binding.homeScreenGrid.root.getClickableRect(clickedGridItem)
|
||||||
launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle)
|
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||||
|
launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun openFolder(folder: HomeScreenGridItem) {
|
||||||
|
binding.homeScreenGrid.root.openFolder(folder)
|
||||||
|
}
|
||||||
|
|
||||||
private fun performItemLongClick(x: Float, clickedGridItem: HomeScreenGridItem) {
|
private fun performItemLongClick(x: Float, clickedGridItem: HomeScreenGridItem) {
|
||||||
if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT || clickedGridItem.type == ITEM_TYPE_FOLDER) {
|
||||||
binding.mainHolder.performHapticFeedback()
|
binding.mainHolder.performHapticFeedback()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +606,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
binding.homeScreenPopupMenuAnchor.y = anchorY
|
binding.homeScreenPopupMenuAnchor.y = anchorY
|
||||||
|
|
||||||
if (mOpenPopupMenu == null) {
|
if (mOpenPopupMenu == null) {
|
||||||
mOpenPopupMenu = handleGridItemPopupMenu(binding.homeScreenPopupMenuAnchor, gridItem, isOnAllAppsFragment)
|
mOpenPopupMenu = handleGridItemPopupMenu(binding.homeScreenPopupMenuAnchor, gridItem, isOnAllAppsFragment, menuListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,52 +634,6 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleGridItemPopupMenu(anchorView: View, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean): PopupMenu {
|
|
||||||
|
|
||||||
val contextTheme = ContextThemeWrapper(this, getPopupMenuTheme())
|
|
||||||
return PopupMenu(contextTheme, anchorView, Gravity.TOP or Gravity.END).apply {
|
|
||||||
if (isQPlus()) {
|
|
||||||
setForceShowIcon(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
inflate(R.menu.menu_app_icon)
|
|
||||||
menu.findItem(R.id.rename).isVisible = gridItem.type == ITEM_TYPE_ICON && !isOnAllAppsFragment
|
|
||||||
menu.findItem(R.id.hide_icon).isVisible = gridItem.type == ITEM_TYPE_ICON && isOnAllAppsFragment
|
|
||||||
menu.findItem(R.id.resize).isVisible = gridItem.type == ITEM_TYPE_WIDGET
|
|
||||||
menu.findItem(R.id.app_info).isVisible = gridItem.type == ITEM_TYPE_ICON
|
|
||||||
menu.findItem(R.id.uninstall).isVisible = gridItem.type == ITEM_TYPE_ICON && canAppBeUninstalled(gridItem.packageName)
|
|
||||||
menu.findItem(R.id.remove).isVisible = !isOnAllAppsFragment
|
|
||||||
setOnMenuItemClickListener { item ->
|
|
||||||
resetFragmentTouches()
|
|
||||||
when (item.itemId) {
|
|
||||||
R.id.hide_icon -> hideIcon(gridItem)
|
|
||||||
R.id.rename -> renameItem(gridItem)
|
|
||||||
R.id.resize -> binding.homeScreenGrid.root.widgetLongPressed(gridItem)
|
|
||||||
R.id.app_info -> launchAppInfo(gridItem.packageName)
|
|
||||||
R.id.remove -> binding.homeScreenGrid.root.removeAppIcon(gridItem)
|
|
||||||
R.id.uninstall -> uninstallApp(gridItem.packageName)
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
setOnDismissListener {
|
|
||||||
mOpenPopupMenu = null
|
|
||||||
resetFragmentTouches()
|
|
||||||
}
|
|
||||||
|
|
||||||
var visibleMenuItems = 0
|
|
||||||
for (item in menu.iterator()) {
|
|
||||||
if (item.isVisible) {
|
|
||||||
visibleMenuItems++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val yOffset = resources.getDimension(R.dimen.long_press_anchor_button_offset_y) * (visibleMenuItems - 1)
|
|
||||||
anchorView.y -= yOffset
|
|
||||||
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resetFragmentTouches() {
|
private fun resetFragmentTouches() {
|
||||||
binding.widgetsFragment.root.apply {
|
binding.widgetsFragment.root.apply {
|
||||||
touchDownY = -1
|
touchDownY = -1
|
||||||
@ -714,6 +679,53 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val menuListener: ItemMenuListener = object : ItemMenuListener {
|
||||||
|
override fun onAnyClick() {
|
||||||
|
resetFragmentTouches()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hide(gridItem: HomeScreenGridItem) {
|
||||||
|
hideIcon(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun rename(gridItem: HomeScreenGridItem) {
|
||||||
|
renameItem(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resize(gridItem: HomeScreenGridItem) {
|
||||||
|
binding.homeScreenGrid.root.widgetLongPressed(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun appInfo(gridItem: HomeScreenGridItem) {
|
||||||
|
launchAppInfo(gridItem.packageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(gridItem: HomeScreenGridItem) {
|
||||||
|
binding.homeScreenGrid.root.removeAppIcon(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun uninstall(gridItem: HomeScreenGridItem) {
|
||||||
|
uninstallApp(gridItem.packageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss() {
|
||||||
|
mOpenPopupMenu = null
|
||||||
|
resetFragmentTouches()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeShow(menu: Menu) {
|
||||||
|
var visibleMenuItems = 0
|
||||||
|
for (item in menu.iterator()) {
|
||||||
|
if (item.isVisible) {
|
||||||
|
visibleMenuItems++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val yOffset = resources.getDimension(R.dimen.long_press_anchor_button_offset_y) * (visibleMenuItems - 1)
|
||||||
|
binding.homeScreenPopupMenuAnchor.y -= yOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class MyGestureListener(private val flingListener: FlingListener) : GestureDetector.SimpleOnGestureListener() {
|
private class MyGestureListener(private val flingListener: FlingListener) : GestureDetector.SimpleOnGestureListener() {
|
||||||
override fun onSingleTapUp(event: MotionEvent): Boolean {
|
override fun onSingleTapUp(event: MotionEvent): Boolean {
|
||||||
(flingListener as MainActivity).homeScreenClicked(event.x, event.y)
|
(flingListener as MainActivity).homeScreenClicked(event.x, event.y)
|
||||||
@ -857,7 +869,8 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
-1,
|
-1,
|
||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
homeScreenGridItems.add(dialerIcon)
|
homeScreenGridItems.add(dialerIcon)
|
||||||
}
|
}
|
||||||
@ -883,7 +896,8 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
-1,
|
-1,
|
||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
homeScreenGridItems.add(SMSMessengerIcon)
|
homeScreenGridItems.add(SMSMessengerIcon)
|
||||||
}
|
}
|
||||||
@ -911,7 +925,8 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
-1,
|
-1,
|
||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
homeScreenGridItems.add(browserIcon)
|
homeScreenGridItems.add(browserIcon)
|
||||||
}
|
}
|
||||||
@ -938,7 +953,8 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
-1,
|
-1,
|
||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
homeScreenGridItems.add(storeIcon)
|
homeScreenGridItems.add(storeIcon)
|
||||||
}
|
}
|
||||||
@ -967,7 +983,8 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||||||
-1,
|
-1,
|
||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
true
|
true,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
homeScreenGridItems.add(cameraIcon)
|
homeScreenGridItems.add(cameraIcon)
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,10 @@ import kotlin.system.exitProcess
|
|||||||
|
|
||||||
class SettingsActivity : SimpleActivity() {
|
class SettingsActivity : SimpleActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivitySettingsBinding
|
private val binding by viewBinding(ActivitySettingsBinding::inflate)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
isMaterialActivity = true
|
isMaterialActivity = true
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivitySettingsBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
updateMaterialActivityViews(binding.settingsCoordinator, binding.settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
|
updateMaterialActivityViews(binding.settingsCoordinator, binding.settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.simplemobiletools.launcher.adapters
|
||||||
|
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.iterator
|
||||||
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
|
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||||
|
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
|
import com.simplemobiletools.launcher.R
|
||||||
|
import com.simplemobiletools.launcher.activities.MainActivity
|
||||||
|
import com.simplemobiletools.launcher.databinding.ItemLauncherLabelBinding
|
||||||
|
import com.simplemobiletools.launcher.extensions.handleGridItemPopupMenu
|
||||||
|
import com.simplemobiletools.launcher.interfaces.ItemMenuListenerAdapter
|
||||||
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
|
|
||||||
|
class FolderIconsAdapter(
|
||||||
|
activity: BaseSimpleActivity, var items: MutableList<HomeScreenGridItem>, private val iconPadding: Int,
|
||||||
|
recyclerView: MyRecyclerView, itemClick: (Any) -> Unit
|
||||||
|
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
|
||||||
|
|
||||||
|
override fun getActionMenuId() = 0
|
||||||
|
|
||||||
|
override fun actionItemPressed(id: Int) {}
|
||||||
|
|
||||||
|
override fun getSelectableItemCount() = itemCount
|
||||||
|
|
||||||
|
override fun getIsItemSelectable(position: Int) = false
|
||||||
|
|
||||||
|
override fun getItemSelectionKey(position: Int) = items.getOrNull(position)?.id?.toInt()
|
||||||
|
|
||||||
|
override fun getItemKeyPosition(key: Int) = items.indexOfFirst { it.id?.toInt() == key }
|
||||||
|
|
||||||
|
override fun onActionModeCreated() {}
|
||||||
|
|
||||||
|
override fun onActionModeDestroyed() {}
|
||||||
|
|
||||||
|
override fun prepareActionMode(menu: Menu) {}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
return createViewHolder(ItemLauncherLabelBinding.inflate(layoutInflater, parent, false).root)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
val item = items[position]
|
||||||
|
setupView(holder.itemView, item)
|
||||||
|
bindViewHolder(holder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
|
||||||
|
private fun removeItem(item: HomeScreenGridItem) {
|
||||||
|
val position = items.indexOfFirst { it.id == item.id }
|
||||||
|
items.removeAt(position)
|
||||||
|
notifyItemRemoved(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupView(view: View, item: HomeScreenGridItem) {
|
||||||
|
ItemLauncherLabelBinding.bind(view).apply {
|
||||||
|
launcherLabel.text = item.title
|
||||||
|
launcherLabel.setTextColor(textColor)
|
||||||
|
launcherIcon.setPadding(iconPadding, iconPadding, iconPadding, 0)
|
||||||
|
launcherIcon.setImageDrawable(item.drawable)
|
||||||
|
|
||||||
|
val mainListener = (activity as? MainActivity)?.menuListener
|
||||||
|
|
||||||
|
root.setOnClickListener { itemClick(item) }
|
||||||
|
root.setOnLongClickListener {
|
||||||
|
popupAnchor.y = launcherIcon.y
|
||||||
|
activity.handleGridItemPopupMenu(popupAnchor, item, false, object : ItemMenuListenerAdapter() {
|
||||||
|
override fun appInfo(gridItem: HomeScreenGridItem) {
|
||||||
|
mainListener?.appInfo(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(gridItem: HomeScreenGridItem) {
|
||||||
|
mainListener?.remove(gridItem)
|
||||||
|
removeItem(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun uninstall(gridItem: HomeScreenGridItem) {
|
||||||
|
mainListener?.uninstall(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun rename(gridItem: HomeScreenGridItem) {
|
||||||
|
mainListener?.rename(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeShow(menu: Menu) {
|
||||||
|
var visibleMenuItems = 0
|
||||||
|
for (menuItem in menu.iterator()) {
|
||||||
|
if (menuItem.isVisible) {
|
||||||
|
visibleMenuItems++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val yOffset = resources.getDimension(R.dimen.long_press_anchor_button_offset_y) * (visibleMenuItems - 1)
|
||||||
|
popupAnchor.y -= yOffset
|
||||||
|
}
|
||||||
|
})
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateItems(items: List<HomeScreenGridItem>) {
|
||||||
|
this.items.clear()
|
||||||
|
this.items.addAll(items)
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
@ -68,8 +68,8 @@ abstract class AppsDatabase : RoomDatabase() {
|
|||||||
|
|
||||||
private val MIGRATION_4_5 = object : Migration(4, 5) {
|
private val MIGRATION_4_5 = object : Migration(4, 5) {
|
||||||
override fun migrate(database: SupportSQLiteDatabase) {
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
database.execSQL("CREATE TABLE `home_screen_grid_items_new` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `left` INTEGER NOT NULL, `top` INTEGER NOT NULL, `right` INTEGER NOT NULL, `bottom` INTEGER NOT NULL, `page` INTEGER NOT NULL, `package_name` TEXT NOT NULL, `activity_name` TEXT NOT NULL, `title` TEXT NOT NULL, `type` INTEGER NOT NULL, `class_name` TEXT NOT NULL, `widget_id` INTEGER NOT NULL, `shortcut_id` TEXT NOT NULL, `icon` BLOB, `docked` INTEGER NOT NULL DEFAULT 0)")
|
database.execSQL("CREATE TABLE `home_screen_grid_items_new` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `left` INTEGER NOT NULL, `top` INTEGER NOT NULL, `right` INTEGER NOT NULL, `bottom` INTEGER NOT NULL, `page` INTEGER NOT NULL, `package_name` TEXT NOT NULL, `activity_name` TEXT NOT NULL, `title` TEXT NOT NULL, `type` INTEGER NOT NULL, `class_name` TEXT NOT NULL, `widget_id` INTEGER NOT NULL, `shortcut_id` TEXT NOT NULL, `icon` BLOB, `docked` INTEGER NOT NULL DEFAULT 0, `parent_id` INTEGER)")
|
||||||
database.execSQL("INSERT INTO `home_screen_grid_items_new` (`id`, `left`, `top`, `right`, `bottom`, `page`, `package_name`, `activity_name`, `title`, `type`, `class_name`, `widget_id`, `shortcut_id`, `icon`, `docked`) SELECT `id`, `left`, `top`, `right`, `bottom`, 0 as `page`, `package_name`, `activity_name`, `title`, `type`, `class_name`, `widget_id`, `shortcut_id`, `icon`, CASE WHEN `type` != 1 AND `top` = 5 THEN 1 ELSE 0 END AS `docked` FROM `home_screen_grid_items` WHERE `intent` IS NULL OR `intent` = ''")
|
database.execSQL("INSERT INTO `home_screen_grid_items_new` (`id`, `left`, `top`, `right`, `bottom`, `page`, `package_name`, `activity_name`, `title`, `type`, `class_name`, `widget_id`, `shortcut_id`, `icon`, `docked`, `parent_id`) SELECT `id`, `left`, `top`, `right`, `bottom`, 0 as `page`, `package_name`, `activity_name`, `title`, `type`, `class_name`, `widget_id`, `shortcut_id`, `icon`, CASE WHEN `type` != 1 AND `top` = 5 THEN 1 ELSE 0 END AS `docked`, NULL AS `parent_id` FROM `home_screen_grid_items` WHERE `intent` IS NULL OR `intent` = ''")
|
||||||
database.execSQL("DROP TABLE `home_screen_grid_items`")
|
database.execSQL("DROP TABLE `home_screen_grid_items`")
|
||||||
database.execSQL("ALTER TABLE `home_screen_grid_items_new` RENAME TO `home_screen_grid_items`")
|
database.execSQL("ALTER TABLE `home_screen_grid_items_new` RENAME TO `home_screen_grid_items`")
|
||||||
database.execSQL("CREATE UNIQUE INDEX `index_home_screen_grid_items_id` ON `home_screen_grid_items` (`id`)")
|
database.execSQL("CREATE UNIQUE INDEX `index_home_screen_grid_items_id` ON `home_screen_grid_items` (`id`)")
|
||||||
|
@ -6,9 +6,21 @@ import android.content.Intent
|
|||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.view.ContextThemeWrapper
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.PopupMenu
|
||||||
|
import com.simplemobiletools.commons.extensions.getPopupMenuTheme
|
||||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||||
|
import com.simplemobiletools.commons.helpers.isQPlus
|
||||||
|
import com.simplemobiletools.launcher.R
|
||||||
import com.simplemobiletools.launcher.activities.SettingsActivity
|
import com.simplemobiletools.launcher.activities.SettingsActivity
|
||||||
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_FOLDER
|
||||||
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_ICON
|
||||||
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_WIDGET
|
||||||
import com.simplemobiletools.launcher.helpers.UNINSTALL_APP_REQUEST_CODE
|
import com.simplemobiletools.launcher.helpers.UNINSTALL_APP_REQUEST_CODE
|
||||||
|
import com.simplemobiletools.launcher.interfaces.ItemMenuListener
|
||||||
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
|
|
||||||
fun Activity.launchApp(packageName: String, activityName: String) {
|
fun Activity.launchApp(packageName: String, activityName: String) {
|
||||||
// if this is true, launch the app settings
|
// if this is true, launch the app settings
|
||||||
@ -56,3 +68,40 @@ fun Activity.uninstallApp(packageName: String) {
|
|||||||
startActivityForResult(this, UNINSTALL_APP_REQUEST_CODE)
|
startActivityForResult(this, UNINSTALL_APP_REQUEST_CODE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Activity.handleGridItemPopupMenu(anchorView: View, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean, listener: ItemMenuListener): PopupMenu {
|
||||||
|
val contextTheme = ContextThemeWrapper(this, getPopupMenuTheme())
|
||||||
|
return PopupMenu(contextTheme, anchorView, Gravity.TOP or Gravity.END).apply {
|
||||||
|
if (isQPlus()) {
|
||||||
|
setForceShowIcon(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
inflate(R.menu.menu_app_icon)
|
||||||
|
menu.findItem(R.id.rename).isVisible = (gridItem.type == ITEM_TYPE_ICON || gridItem.type == ITEM_TYPE_FOLDER) && !isOnAllAppsFragment
|
||||||
|
menu.findItem(R.id.hide_icon).isVisible = gridItem.type == ITEM_TYPE_ICON && isOnAllAppsFragment
|
||||||
|
menu.findItem(R.id.resize).isVisible = gridItem.type == ITEM_TYPE_WIDGET
|
||||||
|
menu.findItem(R.id.app_info).isVisible = gridItem.type == ITEM_TYPE_ICON
|
||||||
|
menu.findItem(R.id.uninstall).isVisible = gridItem.type == ITEM_TYPE_ICON && canAppBeUninstalled(gridItem.packageName)
|
||||||
|
menu.findItem(R.id.remove).isVisible = !isOnAllAppsFragment
|
||||||
|
setOnMenuItemClickListener { item ->
|
||||||
|
listener.onAnyClick()
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.hide_icon -> listener.hide(gridItem)
|
||||||
|
R.id.rename -> listener.rename(gridItem)
|
||||||
|
R.id.resize -> listener.resize(gridItem)
|
||||||
|
R.id.app_info -> listener.appInfo(gridItem)
|
||||||
|
R.id.remove -> listener.remove(gridItem)
|
||||||
|
R.id.uninstall -> listener.uninstall(gridItem)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnDismissListener {
|
||||||
|
listener.onDismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
listener.beforeShow(menu)
|
||||||
|
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -207,6 +207,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
|||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
|
null,
|
||||||
appLauncher.drawable
|
appLauncher.drawable
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -267,6 +267,7 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
|||||||
"",
|
"",
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
|
null,
|
||||||
appWidget.widgetPreviewImage,
|
appWidget.widgetPreviewImage,
|
||||||
appWidget.providerInfo,
|
appWidget.providerInfo,
|
||||||
appWidget.activityInfo,
|
appWidget.activityInfo,
|
||||||
|
@ -27,6 +27,7 @@ const val REQUEST_CREATE_SHORTCUT = 53
|
|||||||
const val ITEM_TYPE_ICON = 0
|
const val ITEM_TYPE_ICON = 0
|
||||||
const val ITEM_TYPE_WIDGET = 1
|
const val ITEM_TYPE_WIDGET = 1
|
||||||
const val ITEM_TYPE_SHORTCUT = 2
|
const val ITEM_TYPE_SHORTCUT = 2
|
||||||
|
const val ITEM_TYPE_FOLDER = 3
|
||||||
|
|
||||||
const val WIDGET_HOST_ID = 12345
|
const val WIDGET_HOST_ID = 12345
|
||||||
const val MAX_CLICK_DURATION = 150
|
const val MAX_CLICK_DURATION = 150
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package com.simplemobiletools.launcher.interfaces
|
package com.simplemobiletools.launcher.interfaces
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.*
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.OnConflictStrategy
|
|
||||||
import androidx.room.Query
|
|
||||||
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -11,6 +8,9 @@ interface HomeScreenGridItemsDao {
|
|||||||
@Query("SELECT * FROM home_screen_grid_items")
|
@Query("SELECT * FROM home_screen_grid_items")
|
||||||
fun getAllItems(): List<HomeScreenGridItem>
|
fun getAllItems(): List<HomeScreenGridItem>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM home_screen_grid_items WHERE parent_id = :folderId")
|
||||||
|
fun getFolderItems(folderId: Long): List<HomeScreenGridItem>
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
fun insert(item: HomeScreenGridItem): Long
|
fun insert(item: HomeScreenGridItem): Long
|
||||||
|
|
||||||
@ -23,12 +23,33 @@ 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, `page` = :page, `docked` = :docked WHERE id = :id")
|
@Query("UPDATE home_screen_grid_items SET `left` = :left, `top` = :top, `right` = :right, `bottom` = :bottom, `page` = :page, `docked` = :docked , `parent_id` = :parentId WHERE id = :id")
|
||||||
fun updateItemPosition(left: Int, top: Int, right: Int, bottom: Int, page: Int, docked: Boolean, id: Long)
|
fun updateItemPosition(left: Int, top: Int, right: Int, bottom: Int, page: Int, docked: Boolean, parentId: Long?, 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 deleteItemById(id: Long)
|
||||||
|
|
||||||
|
@Query("DELETE FROM home_screen_grid_items WHERE parent_id = :id")
|
||||||
|
fun deleteItemsWithParentId(id: Long)
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
fun deleteById(id: Long) {
|
||||||
|
deleteItemById(id)
|
||||||
|
deleteItemsWithParentId(id)
|
||||||
|
}
|
||||||
|
|
||||||
@Query("DELETE FROM home_screen_grid_items WHERE package_name = :packageName")
|
@Query("DELETE FROM home_screen_grid_items WHERE package_name = :packageName")
|
||||||
fun deleteByPackageName(packageName: String)
|
fun deleteItemByPackageName(packageName: String)
|
||||||
|
|
||||||
|
@Query("DELETE FROM home_screen_grid_items WHERE parent_id IN (SELECT id FROM home_screen_grid_items WHERE package_name = :packageName)")
|
||||||
|
fun deleteItemsByParentPackageName(packageName: String)
|
||||||
|
|
||||||
|
@Query("UPDATE home_screen_grid_items SET `left` = `left` + :shiftBy WHERE parent_id == :folderId AND `left` > :shiftFrom AND id != :excludingId")
|
||||||
|
fun shiftFolderItems(folderId: Long, shiftFrom: Int, shiftBy: Int, excludingId: Long? = null)
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
fun deleteByPackageName(packageName: String) {
|
||||||
|
deleteItemByPackageName(packageName)
|
||||||
|
deleteItemsByParentPackageName(packageName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.simplemobiletools.launcher.interfaces
|
||||||
|
|
||||||
|
import android.view.Menu
|
||||||
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
|
|
||||||
|
interface ItemMenuListener {
|
||||||
|
fun onAnyClick()
|
||||||
|
fun hide(gridItem: HomeScreenGridItem)
|
||||||
|
fun rename(gridItem: HomeScreenGridItem)
|
||||||
|
fun resize(gridItem: HomeScreenGridItem)
|
||||||
|
fun appInfo(gridItem: HomeScreenGridItem)
|
||||||
|
fun remove(gridItem: HomeScreenGridItem)
|
||||||
|
fun uninstall(gridItem: HomeScreenGridItem)
|
||||||
|
fun onDismiss()
|
||||||
|
fun beforeShow(menu: Menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ItemMenuListenerAdapter : ItemMenuListener {
|
||||||
|
override fun onAnyClick() = Unit
|
||||||
|
override fun hide(gridItem: HomeScreenGridItem) = Unit
|
||||||
|
override fun rename(gridItem: HomeScreenGridItem) = Unit
|
||||||
|
override fun resize(gridItem: HomeScreenGridItem) = Unit
|
||||||
|
override fun appInfo(gridItem: HomeScreenGridItem) = Unit
|
||||||
|
override fun remove(gridItem: HomeScreenGridItem) = Unit
|
||||||
|
override fun uninstall(gridItem: HomeScreenGridItem) = Unit
|
||||||
|
override fun onDismiss() = Unit
|
||||||
|
override fun beforeShow(menu: Menu) = Unit
|
||||||
|
}
|
@ -3,6 +3,7 @@ package com.simplemobiletools.launcher.models
|
|||||||
import android.appwidget.AppWidgetProviderInfo
|
import android.appwidget.AppWidgetProviderInfo
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Point
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_ICON
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_ICON
|
||||||
@ -25,6 +26,7 @@ data class HomeScreenGridItem(
|
|||||||
@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
|
@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
|
||||||
|
@ColumnInfo(name = "parent_id") var parentId: Long? = null, // id of folder this item is in (if it is in any)
|
||||||
|
|
||||||
@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
|
||||||
@ -32,7 +34,11 @@ 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, 0, "", "", "", ITEM_TYPE_ICON, "", -1, "", null, false, null, null, null, 1, 1)
|
companion object {
|
||||||
|
const val FOLDER_MAX_CAPACITY = 16
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() : this(null, -1, -1, -1, -1, 0, "", "", "", ITEM_TYPE_ICON, "", -1, "", null, false, null, null, null, null, 1, 1)
|
||||||
|
|
||||||
fun getWidthInCells() = if (right == -1 || left == -1) {
|
fun getWidthInCells() = if (right == -1 || left == -1) {
|
||||||
widthCells
|
widthCells
|
||||||
@ -63,4 +69,6 @@ data class HomeScreenGridItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getItemIdentifier() = "$packageName/$activityName"
|
fun getItemIdentifier() = "$packageName/$activityName"
|
||||||
|
|
||||||
|
fun getTopLeft() = Point(left, top)
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
26
app/src/main/res/layout/dialog_folder_icons.xml
Normal file
26
app/src/main/res/layout/dialog_folder_icons.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/dialog_folder_icons_holder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="@dimen/small_margin"
|
||||||
|
android:layout_marginTop="@dimen/medium_margin"
|
||||||
|
android:layout_marginEnd="@dimen/small_margin"
|
||||||
|
android:minHeight="@dimen/min_folder_view_height"
|
||||||
|
app:layout_constraintHeight_max="@dimen/max_folder_view_height">
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
|
android:id="@+id/dialog_folder_icons_grid"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:itemCount="10"
|
||||||
|
tools:listitem="@layout/item_launcher_label" />
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</FrameLayout>
|
@ -27,4 +27,10 @@
|
|||||||
android:maxLines="2"
|
android:maxLines="2"
|
||||||
android:textSize="@dimen/smaller_text_size" />
|
android:textSize="@dimen/smaller_text_size" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/popup_anchor"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:gravity="center_horizontal|top" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -9,4 +9,6 @@
|
|||||||
<dimen name="page_indicator_dot_radius">6dp</dimen>
|
<dimen name="page_indicator_dot_radius">6dp</dimen>
|
||||||
<dimen name="page_indicator_stroke_width">1dp</dimen>
|
<dimen name="page_indicator_stroke_width">1dp</dimen>
|
||||||
<dimen name="page_indicator_margin">6dp</dimen>
|
<dimen name="page_indicator_margin">6dp</dimen>
|
||||||
|
<dimen name="min_folder_view_height">200dp</dimen>
|
||||||
|
<dimen name="max_folder_view_height">500dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user