Add support for viewing folders as dialogs
This commit is contained in:
parent
a9f879628c
commit
5e58c04338
|
@ -63,7 +63,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:fad9b2cdb0'
|
implementation 'com.github.SimpleMobileTools:Simple-Commons:2a2c17151e'
|
||||||
|
|
||||||
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"
|
||||||
|
|
|
@ -37,6 +37,7 @@ import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.*
|
import com.simplemobiletools.commons.helpers.*
|
||||||
import com.simplemobiletools.launcher.BuildConfig
|
import com.simplemobiletools.launcher.BuildConfig
|
||||||
import com.simplemobiletools.launcher.R
|
import com.simplemobiletools.launcher.R
|
||||||
|
import com.simplemobiletools.launcher.dialogs.FolderIconsDialog
|
||||||
import com.simplemobiletools.launcher.dialogs.RenameItemDialog
|
import com.simplemobiletools.launcher.dialogs.RenameItemDialog
|
||||||
import com.simplemobiletools.launcher.extensions.*
|
import com.simplemobiletools.launcher.extensions.*
|
||||||
import com.simplemobiletools.launcher.fragments.AllAppsFragment
|
import com.simplemobiletools.launcher.fragments.AllAppsFragment
|
||||||
|
@ -44,6 +45,7 @@ import com.simplemobiletools.launcher.fragments.MyFragment
|
||||||
import com.simplemobiletools.launcher.fragments.WidgetsFragment
|
import com.simplemobiletools.launcher.fragments.WidgetsFragment
|
||||||
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
|
||||||
|
@ -64,6 +66,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
private var mIgnoreMoveEvents = false
|
private var mIgnoreMoveEvents = false
|
||||||
private var mLongPressedIcon: HomeScreenGridItem? = null
|
private var mLongPressedIcon: HomeScreenGridItem? = null
|
||||||
private var mOpenPopupMenu: PopupMenu? = null
|
private var mOpenPopupMenu: PopupMenu? = null
|
||||||
|
private var mOpenFolderDialog: FolderIconsDialog? = null
|
||||||
private var mCachedLaunchers = ArrayList<AppLauncher>()
|
private var mCachedLaunchers = ArrayList<AppLauncher>()
|
||||||
private var mLastTouchCoords = Pair(-1f, -1f)
|
private var mLastTouchCoords = Pair(-1f, -1f)
|
||||||
private var mActionOnCanBindWidget: ((granted: Boolean) -> Unit)? = null
|
private var mActionOnCanBindWidget: ((granted: Boolean) -> Unit)? = null
|
||||||
|
@ -72,6 +75,52 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
|
|
||||||
private lateinit var mDetector: GestureDetectorCompat
|
private lateinit var mDetector: GestureDetectorCompat
|
||||||
|
|
||||||
|
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) {
|
||||||
|
home_screen_grid.widgetLongPressed(gridItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun appInfo(gridItem: HomeScreenGridItem) {
|
||||||
|
launchAppInfo(gridItem.packageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(gridItem: HomeScreenGridItem) {
|
||||||
|
home_screen_grid.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)
|
||||||
|
home_screen_popup_menu_anchor.y -= yOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var mLastUpEvent = 0L
|
private var mLastUpEvent = 0L
|
||||||
private const val ANIMATION_DURATION = 150L
|
private const val ANIMATION_DURATION = 150L
|
||||||
|
@ -330,11 +379,12 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
hasFingerMoved(event)
|
hasFingerMoved(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mLongPressedIcon != null && mOpenPopupMenu != null && hasFingerMoved) {
|
if (mLongPressedIcon != null && (mOpenPopupMenu != null || mOpenFolderDialog != null) && hasFingerMoved) {
|
||||||
mOpenPopupMenu?.dismiss()
|
mOpenPopupMenu?.dismiss()
|
||||||
mOpenPopupMenu = null
|
mOpenPopupMenu = null
|
||||||
home_screen_grid.itemDraggingStarted(mLongPressedIcon!!)
|
home_screen_grid.itemDraggingStarted(mLongPressedIcon!!)
|
||||||
hideFragment(all_apps_fragment)
|
hideFragment(all_apps_fragment)
|
||||||
|
mOpenFolderDialog?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mLongPressedIcon != null && hasFingerMoved) {
|
if (mLongPressedIcon != null && hasFingerMoved) {
|
||||||
|
@ -385,6 +435,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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))
|
||||||
|
@ -405,6 +456,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
|
|
||||||
if (hasDeletedAnything) {
|
if (hasDeletedAnything) {
|
||||||
home_screen_grid.fetchGridItems()
|
home_screen_grid.fetchGridItems()
|
||||||
|
mOpenFolderDialog?.fetchItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
mCachedLaunchers = launchers
|
mCachedLaunchers = launchers
|
||||||
|
@ -500,9 +552,10 @@ 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 -> showFolderDialog(clickedGridItem)
|
||||||
|
ITEM_TYPE_SHORTCUT -> {
|
||||||
val id = clickedGridItem.shortcutId
|
val id = clickedGridItem.shortcutId
|
||||||
val packageName = clickedGridItem.packageName
|
val packageName = clickedGridItem.packageName
|
||||||
val userHandle = android.os.Process.myUserHandle()
|
val userHandle = android.os.Process.myUserHandle()
|
||||||
|
@ -511,6 +564,22 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle)
|
launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showFolderDialog(folder: HomeScreenGridItem) {
|
||||||
|
mOpenFolderDialog = FolderIconsDialog(
|
||||||
|
activity = this,
|
||||||
|
folder = folder,
|
||||||
|
iconWidth = home_screen_grid.getCurrentCellSize(),
|
||||||
|
iconPadding = home_screen_grid.getCurrentCellMargin(),
|
||||||
|
dismissListener = {
|
||||||
|
mOpenFolderDialog = null
|
||||||
|
},
|
||||||
|
itemClick = {
|
||||||
|
performItemClick(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -521,6 +590,11 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
showHomeIconMenu(x, anchorY, clickedGridItem, false)
|
showHomeIconMenu(x, anchorY, clickedGridItem, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun startHandlingItem(gridItem: HomeScreenGridItem) {
|
||||||
|
mLongPressedIcon = gridItem
|
||||||
|
mOpenFolderDialog?.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
fun showHomeIconMenu(x: Float, y: Float, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean) {
|
fun showHomeIconMenu(x: Float, y: Float, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean) {
|
||||||
home_screen_grid.hideResizeLines()
|
home_screen_grid.hideResizeLines()
|
||||||
mLongPressedIcon = gridItem
|
mLongPressedIcon = gridItem
|
||||||
|
@ -536,7 +610,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
home_screen_popup_menu_anchor.y = anchorY
|
home_screen_popup_menu_anchor.y = anchorY
|
||||||
|
|
||||||
if (mOpenPopupMenu == null) {
|
if (mOpenPopupMenu == null) {
|
||||||
mOpenPopupMenu = handleGridItemPopupMenu(home_screen_popup_menu_anchor, gridItem, isOnAllAppsFragment)
|
mOpenPopupMenu = handleGridItemPopupMenu(home_screen_popup_menu_anchor, gridItem, isOnAllAppsFragment, menuListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,52 +638,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 -> home_screen_grid.widgetLongPressed(gridItem)
|
|
||||||
R.id.app_info -> launchAppInfo(gridItem.packageName)
|
|
||||||
R.id.remove -> home_screen_grid.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() {
|
||||||
(widgets_fragment as WidgetsFragment).apply {
|
(widgets_fragment as WidgetsFragment).apply {
|
||||||
touchDownY = -1
|
touchDownY = -1
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
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.extensions.handleGridItemPopupMenu
|
||||||
|
import com.simplemobiletools.launcher.interfaces.ItemMenuListenerAdapter
|
||||||
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
|
import kotlinx.android.synthetic.main.item_launcher_label.view.launcher_icon
|
||||||
|
import kotlinx.android.synthetic.main.item_launcher_label.view.launcher_label
|
||||||
|
import kotlinx.android.synthetic.main.item_launcher_label.view.popup_anchor
|
||||||
|
|
||||||
|
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(R.layout.item_launcher_label, parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
view.apply {
|
||||||
|
launcher_label.text = item.title
|
||||||
|
launcher_label.setTextColor(textColor)
|
||||||
|
launcher_icon.setPadding(iconPadding, iconPadding, iconPadding, 0)
|
||||||
|
launcher_icon.setImageDrawable(item.drawable)
|
||||||
|
|
||||||
|
val mainListener = (activity as? MainActivity)?.menuListener
|
||||||
|
|
||||||
|
setOnClickListener { itemClick(item) }
|
||||||
|
setOnLongClickListener {
|
||||||
|
popup_anchor.y = launcher_icon.y
|
||||||
|
activity.handleGridItemPopupMenu(popup_anchor, 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)
|
||||||
|
popup_anchor.y -= yOffset
|
||||||
|
}
|
||||||
|
})
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateItems(items: List<HomeScreenGridItem>) {
|
||||||
|
this.items.clear()
|
||||||
|
this.items.addAll(items)
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.simplemobiletools.launcher.dialogs
|
||||||
|
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
|
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||||
|
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||||
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
|
import com.simplemobiletools.commons.views.AutoGridLayoutManager
|
||||||
|
import com.simplemobiletools.launcher.R
|
||||||
|
import com.simplemobiletools.launcher.adapters.FolderIconsAdapter
|
||||||
|
import com.simplemobiletools.launcher.extensions.getDrawableForPackageName
|
||||||
|
import com.simplemobiletools.launcher.extensions.homeScreenGridItemsDB
|
||||||
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_ICON
|
||||||
|
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_SHORTCUT
|
||||||
|
import com.simplemobiletools.launcher.models.HomeScreenGridItem
|
||||||
|
import kotlinx.android.synthetic.main.dialog_folder_icons.view.dialog_folder_icons_grid
|
||||||
|
|
||||||
|
class FolderIconsDialog(
|
||||||
|
val activity: BaseSimpleActivity,
|
||||||
|
private val folder: HomeScreenGridItem,
|
||||||
|
private val iconWidth: Int,
|
||||||
|
private val iconPadding: Int,
|
||||||
|
private val dismissListener: () -> Unit,
|
||||||
|
private val itemClick: (HomeScreenGridItem) -> Unit
|
||||||
|
) {
|
||||||
|
private var dialog: AlertDialog? = null
|
||||||
|
private val view: View = activity.layoutInflater.inflate(R.layout.dialog_folder_icons, null)
|
||||||
|
|
||||||
|
init {
|
||||||
|
|
||||||
|
view.dialog_folder_icons_grid.layoutManager = AutoGridLayoutManager(activity, iconWidth)
|
||||||
|
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val items = activity.homeScreenGridItemsDB.getFolderItems(folder.id!!)
|
||||||
|
items.forEach { item ->
|
||||||
|
if (item.type == ITEM_TYPE_ICON) {
|
||||||
|
item.drawable = activity.getDrawableForPackageName(item.packageName)
|
||||||
|
} else if (item.type == ITEM_TYPE_SHORTCUT) {
|
||||||
|
item.drawable = BitmapDrawable(item.icon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
activity.runOnUiThread {
|
||||||
|
initDialog(items, view)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initDialog(items: List<HomeScreenGridItem>, view: View) {
|
||||||
|
view.dialog_folder_icons_grid.adapter = FolderIconsAdapter(activity, items.toMutableList(), iconPadding, view.dialog_folder_icons_grid) {
|
||||||
|
it as HomeScreenGridItem
|
||||||
|
itemClick(it)
|
||||||
|
dialog?.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
activity.getAlertDialogBuilder()
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setOnDismissListener { dismissListener() }
|
||||||
|
.apply {
|
||||||
|
activity.setupDialogStuff(view, this, 0, folder.title) { alertDialog ->
|
||||||
|
dialog = alertDialog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetchItems() {
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val items = activity.homeScreenGridItemsDB.getFolderItems(folder.id!!)
|
||||||
|
items.forEach { item ->
|
||||||
|
if (item.type == ITEM_TYPE_ICON) {
|
||||||
|
item.drawable = activity.getDrawableForPackageName(item.packageName)
|
||||||
|
} else if (item.type == ITEM_TYPE_SHORTCUT) {
|
||||||
|
item.drawable = BitmapDrawable(item.icon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
activity.runOnUiThread {
|
||||||
|
(view.dialog_folder_icons_grid.adapter as FolderIconsAdapter).updateItems(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dismiss() {
|
||||||
|
dialog?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -20,7 +20,6 @@ import android.util.Size
|
||||||
import android.util.SizeF
|
import android.util.SizeF
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import androidx.core.content.res.ResourcesCompat
|
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.core.graphics.drawable.toDrawable
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
|
@ -1186,6 +1185,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
|
|
||||||
fun getCurrentIconSize(): Int = iconSize
|
fun getCurrentIconSize(): Int = iconSize
|
||||||
|
|
||||||
|
fun getCurrentCellSize(): Int = cellWidth
|
||||||
|
|
||||||
|
fun getCurrentCellMargin(): Int = iconMargin
|
||||||
|
|
||||||
private fun handlePageChange(redraw: Boolean = false) {
|
private fun handlePageChange(redraw: Boolean = false) {
|
||||||
pageChangeEnabled = false
|
pageChangeEnabled = false
|
||||||
pageChangeIndicatorsAlpha = 0f
|
pageChangeIndicatorsAlpha = 0f
|
||||||
|
|
|
@ -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…
Reference in New Issue