Merge branch 'main' into feature/60-row-column-count-customization
This commit is contained in:
commit
26b4d777e4
|
@ -23,6 +23,7 @@ import android.os.Handler
|
|||
import android.provider.Telephony
|
||||
import android.telecom.TelecomManager
|
||||
import android.view.*
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.widget.PopupMenu
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
|
@ -139,6 +140,14 @@ 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? {
|
||||
|
@ -223,7 +232,9 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
|
||||
override fun onBackPressed() {
|
||||
if (isAllAppsFragmentExpanded()) {
|
||||
hideFragment(all_apps_fragment)
|
||||
if ((all_apps_fragment as? AllAppsFragment)?.onBackPressed() == false) {
|
||||
hideFragment(all_apps_fragment)
|
||||
}
|
||||
} else if (isWidgetsFragmentExpanded()) {
|
||||
hideFragment(widgets_fragment)
|
||||
} else if (home_screen_grid.resize_frame.isVisible) {
|
||||
|
@ -243,6 +254,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
refetchLaunchers()
|
||||
}
|
||||
}
|
||||
|
||||
REQUEST_ALLOW_BINDING_WIDGET -> mActionOnCanBindWidget?.invoke(resultCode == Activity.RESULT_OK)
|
||||
REQUEST_CONFIGURE_WIDGET -> mActionOnWidgetConfiguredWidget?.invoke(resultCode == Activity.RESULT_OK)
|
||||
REQUEST_CREATE_SHORTCUT -> {
|
||||
|
@ -405,6 +417,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
window.navigationBarColor = resources.getColor(R.color.semitransparent_navigation)
|
||||
home_screen_grid.fragmentExpanded()
|
||||
home_screen_grid.hideResizeLines()
|
||||
fragment.performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
}
|
||||
|
||||
private fun hideFragment(fragment: View) {
|
||||
|
@ -436,12 +449,7 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
mIgnoreMoveEvents = true
|
||||
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
||||
if (clickedGridItem != null) {
|
||||
if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||
main_holder.performHapticFeedback()
|
||||
}
|
||||
|
||||
val anchorY = home_screen_grid.sideMargins.top + (clickedGridItem.top * home_screen_grid.cellHeight.toFloat())
|
||||
showHomeIconMenu(x, anchorY, clickedGridItem, false)
|
||||
performItemLongClick(x, clickedGridItem)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -454,24 +462,37 @@ class MainActivity : SimpleActivity(), FlingListener {
|
|||
val (x, y) = home_screen_grid.intoViewSpaceCoords(eventX, eventY)
|
||||
val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt())
|
||||
if (clickedGridItem != null) {
|
||||
if (clickedGridItem.type == ITEM_TYPE_ICON) {
|
||||
launchApp(clickedGridItem.packageName, clickedGridItem.activityName)
|
||||
} else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||
if (clickedGridItem.intent.isNotEmpty()) {
|
||||
launchShortcutIntent(clickedGridItem)
|
||||
} else {
|
||||
// launch pinned shortcuts
|
||||
val id = clickedGridItem.shortcutId
|
||||
val packageName = clickedGridItem.packageName
|
||||
val userHandle = android.os.Process.myUserHandle()
|
||||
val shortcutBounds = home_screen_grid.getClickableRect(clickedGridItem)
|
||||
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle)
|
||||
}
|
||||
performItemClick(clickedGridItem)
|
||||
}
|
||||
}
|
||||
|
||||
private fun performItemClick(clickedGridItem: HomeScreenGridItem) {
|
||||
if (clickedGridItem.type == ITEM_TYPE_ICON) {
|
||||
launchApp(clickedGridItem.packageName, clickedGridItem.activityName)
|
||||
} else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||
if (clickedGridItem.intent.isNotEmpty()) {
|
||||
launchShortcutIntent(clickedGridItem)
|
||||
} else {
|
||||
// launch pinned shortcuts
|
||||
val id = clickedGridItem.shortcutId
|
||||
val packageName = clickedGridItem.packageName
|
||||
val userHandle = android.os.Process.myUserHandle()
|
||||
val shortcutBounds = home_screen_grid.getClickableRect(clickedGridItem)
|
||||
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun performItemLongClick(x: Float, clickedGridItem: HomeScreenGridItem) {
|
||||
if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
|
||||
main_holder.performHapticFeedback()
|
||||
}
|
||||
|
||||
val anchorY = home_screen_grid.sideMargins.top + (clickedGridItem.top * home_screen_grid.cellHeight.toFloat())
|
||||
showHomeIconMenu(x, anchorY, clickedGridItem, false)
|
||||
}
|
||||
|
||||
fun showHomeIconMenu(x: Float, y: Float, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean) {
|
||||
home_screen_grid.hideResizeLines()
|
||||
mLongPressedIcon = gridItem
|
||||
|
|
|
@ -39,6 +39,7 @@ class SettingsActivity : SimpleActivity() {
|
|||
setupCustomizeColors()
|
||||
setupUseEnglish()
|
||||
setupDrawerColumnCount()
|
||||
setupDrawerSearchBar()
|
||||
setupHomeRowCount()
|
||||
setupHomeColumnCount()
|
||||
setupLanguage()
|
||||
|
@ -110,6 +111,15 @@ class SettingsActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun setupDrawerSearchBar() {
|
||||
val showSearchBar = config.showSearchBar
|
||||
settings_show_search_bar.isChecked = showSearchBar
|
||||
settings_drawer_search_holder.setOnClickListener {
|
||||
settings_show_search_bar.toggle()
|
||||
config.showSearchBar = settings_show_search_bar.isChecked
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupHomeRowCount() {
|
||||
val currentRowCount = config.homeRowCount
|
||||
settings_home_screen_row_count.text = currentRowCount.toString()
|
||||
|
|
|
@ -22,7 +22,7 @@ import kotlinx.android.synthetic.main.item_launcher_label.view.*
|
|||
|
||||
class LaunchersAdapter(
|
||||
val activity: SimpleActivity,
|
||||
var launchers: ArrayList<AppLauncher>,
|
||||
launchers: ArrayList<AppLauncher>,
|
||||
val allAppsListener: AllAppsListener,
|
||||
val itemClick: (Any) -> Unit
|
||||
) : RecyclerView.Adapter<LaunchersAdapter.ViewHolder>(), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
@ -30,6 +30,14 @@ class LaunchersAdapter(
|
|||
private var textColor = activity.getProperTextColor()
|
||||
private var iconPadding = 0
|
||||
private var wereFreshIconsLoaded = false
|
||||
private var filterQuery: String? = null
|
||||
private var filteredLaunchers: List<AppLauncher> = launchers
|
||||
|
||||
var launchers: ArrayList<AppLauncher> = launchers
|
||||
set(value) {
|
||||
field = value
|
||||
updateFilter()
|
||||
}
|
||||
|
||||
init {
|
||||
calculateIconWidth()
|
||||
|
@ -41,10 +49,10 @@ class LaunchersAdapter(
|
|||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bindView(launchers[position])
|
||||
holder.bindView(filteredLaunchers[position])
|
||||
}
|
||||
|
||||
override fun getItemCount() = launchers.size
|
||||
override fun getItemCount() = filteredLaunchers.size
|
||||
|
||||
private fun calculateIconWidth() {
|
||||
val currentColumnCount = activity.config.drawerColumnCount
|
||||
|
@ -57,8 +65,10 @@ class LaunchersAdapter(
|
|||
val itemToRemove = launchers.firstOrNull { it.getLauncherIdentifier() == item.getItemIdentifier() }
|
||||
if (itemToRemove != null) {
|
||||
val position = launchers.indexOfFirst { it.getLauncherIdentifier() == item.getItemIdentifier() }
|
||||
val filteredPosition = filteredLaunchers.indexOfFirst { it.getLauncherIdentifier() == item.getItemIdentifier() }
|
||||
launchers.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
updateFilter()
|
||||
notifyItemRemoved(filteredPosition)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,6 +82,14 @@ class LaunchersAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
fun updateSearchQuery(newQuery: String?) {
|
||||
if (filterQuery != newQuery) {
|
||||
filterQuery = newQuery
|
||||
updateFilter()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateTextColor(newTextColor: Int) {
|
||||
if (newTextColor != textColor) {
|
||||
textColor = newTextColor
|
||||
|
@ -79,6 +97,10 @@ class LaunchersAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateFilter() {
|
||||
filteredLaunchers = launchers.filter { filterQuery == null || it.title.contains(filterQuery!!, ignoreCase = true) }
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bindView(launcher: AppLauncher): View {
|
||||
itemView.apply {
|
||||
|
@ -107,5 +129,5 @@ class LaunchersAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = launchers.getOrNull(position)?.getBubbleText() ?: ""
|
||||
override fun onChange(position: Int) = filteredLaunchers.getOrNull(position)?.getBubbleText() ?: ""
|
||||
}
|
||||
|
|
|
@ -174,6 +174,21 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
|||
setPadding(0, topPadding, 0, 0)
|
||||
background = ColorDrawable(context.getProperBackgroundColor())
|
||||
(all_apps_grid.adapter as? LaunchersAdapter)?.updateTextColor(context.getProperTextColor())
|
||||
|
||||
search_bar.beVisibleIf(context.config.showSearchBar)
|
||||
search_bar.getToolbar()?.beGone()
|
||||
search_bar.updateColors()
|
||||
search_bar.setupMenu()
|
||||
|
||||
search_bar.onSearchTextChangedListener = {
|
||||
(all_apps_grid.adapter as? LaunchersAdapter)?.updateSearchQuery(it)
|
||||
showNoResultsPlaceholderIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showNoResultsPlaceholderIfNeeded() {
|
||||
val itemCount = all_apps_grid.adapter?.itemCount
|
||||
no_results_placeholder.beVisibleIf(itemCount != null && itemCount == 0)
|
||||
}
|
||||
|
||||
override fun onAppLauncherLongPressed(x: Float, y: Float, appLauncher: AppLauncher) {
|
||||
|
@ -197,5 +212,16 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
|
|||
|
||||
activity?.showHomeIconMenu(x, y, gridItem, true)
|
||||
ignoreTouches = true
|
||||
|
||||
search_bar.closeSearch()
|
||||
}
|
||||
|
||||
fun onBackPressed(): Boolean {
|
||||
if (search_bar.isSearchOpen) {
|
||||
search_bar.closeSearch()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,4 +24,8 @@ class Config(context: Context) : BaseConfig(context) {
|
|||
var drawerColumnCount: Int
|
||||
get() = prefs.getInt(DRAWER_COLUMN_COUNT, context.resources.getInteger(R.integer.portrait_column_count))
|
||||
set(drawerColumnCount) = prefs.edit().putInt(DRAWER_COLUMN_COUNT, drawerColumnCount).apply()
|
||||
|
||||
var showSearchBar: Boolean
|
||||
get() = prefs.getBoolean(SHOW_SEARCH_BAR, true)
|
||||
set(showSearchBar) = prefs.edit().putBoolean(SHOW_SEARCH_BAR, showSearchBar).apply()
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ 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 SHOW_SEARCH_BAR = "show_search_bar"
|
||||
|
||||
// default home screen grid size
|
||||
const val ROW_COUNT = 6
|
||||
|
|
|
@ -15,8 +15,12 @@ import android.text.TextUtils
|
|||
import android.util.AttributeSet
|
||||
import android.util.Size
|
||||
import android.util.SizeF
|
||||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||
import androidx.customview.widget.ExploreByTouchHelper
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.helpers.isSPlus
|
||||
|
@ -66,7 +70,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
|||
val appWidgetHost = MyAppWidgetHost(context, WIDGET_HOST_ID)
|
||||
private val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
|
||||
var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null
|
||||
var itemLongClickListener: ((HomeScreenGridItem) -> Unit)? = null
|
||||
|
||||
init {
|
||||
ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this))
|
||||
|
||||
textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
color = Color.WHITE
|
||||
textSize = context.resources.getDimension(R.dimen.smaller_text_size)
|
||||
|
@ -767,4 +776,59 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
|||
private fun HomeScreenGridItem.outOfBounds(): Boolean {
|
||||
return (left >= cellXCoords.size || right >= cellXCoords.size || top >= cellYCoords.size || bottom >= cellYCoords.size)
|
||||
}
|
||||
|
||||
private inner class HomeScreenGridTouchHelper(host: View) : ExploreByTouchHelper(host) {
|
||||
override fun getVirtualViewAt(x: Float, y: Float): Int {
|
||||
val item = isClickingGridItem(x.toInt(), y.toInt())
|
||||
|
||||
return if (item != null) {
|
||||
item.id?.toInt() ?: INVALID_ID
|
||||
} else {
|
||||
INVALID_ID
|
||||
}
|
||||
}
|
||||
|
||||
override fun getVisibleVirtualViews(virtualViewIds: MutableList<Int>?) {
|
||||
val sorted = gridItems.sortedBy { it.top * 100 + it.left }
|
||||
sorted.forEachIndexed { index, homeScreenGridItem ->
|
||||
virtualViewIds?.add(index, homeScreenGridItem.id?.toInt() ?: index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPopulateNodeForVirtualView(virtualViewId: Int, node: AccessibilityNodeInfoCompat) {
|
||||
val item = gridItems.firstOrNull { it.id?.toInt() == virtualViewId } ?: throw IllegalArgumentException("Unknown id")
|
||||
|
||||
node.text = item.title
|
||||
|
||||
val viewLocation = IntArray(2)
|
||||
getLocationOnScreen(viewLocation)
|
||||
|
||||
val viewBounds = getClickableRect(item)
|
||||
val onScreenBounds = Rect(viewBounds)
|
||||
onScreenBounds.offset(viewLocation[0], viewLocation[1])
|
||||
node.setBoundsInScreen(onScreenBounds)
|
||||
node.setBoundsInParent(viewBounds)
|
||||
|
||||
node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK)
|
||||
node.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK)
|
||||
node.setParent(this@HomeScreenGrid)
|
||||
}
|
||||
|
||||
override fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, arguments: Bundle?): Boolean {
|
||||
val item = gridItems.firstOrNull { it.id?.toInt() == virtualViewId } ?: throw IllegalArgumentException("Unknown id")
|
||||
when (action) {
|
||||
AccessibilityNodeInfoCompat.ACTION_CLICK -> itemClickListener?.apply {
|
||||
invoke(item)
|
||||
return true
|
||||
}
|
||||
|
||||
AccessibilityNodeInfoCompat.ACTION_LONG_CLICK -> itemLongClickListener?.apply {
|
||||
invoke(item)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,6 +171,22 @@
|
|||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_drawer_search_holder"
|
||||
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_bottom_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_show_search_bar"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/show_search" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/settings_drawer_settings_divider"
|
||||
layout="@layout/divider" />
|
||||
|
|
|
@ -5,10 +5,16 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.simplemobiletools.commons.views.MySearchMenu
|
||||
android:id="@+id/search_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
android:id="@+id/all_apps_fastscroller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/search_bar"
|
||||
app:fastScrollEnabled="false">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
|
@ -20,4 +26,21 @@
|
|||
app:spanCount="@integer/portrait_column_count" />
|
||||
|
||||
</com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/no_results_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/search_bar"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="@dimen/bigger_margin"
|
||||
android:alpha="0.8"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/activity_margin"
|
||||
android:paddingRight="@dimen/activity_margin"
|
||||
android:text="@string/no_items_found"
|
||||
android:textSize="@dimen/bigger_text_size"
|
||||
android:textStyle="italic"
|
||||
android:visibility="gone" />
|
||||
|
||||
</com.simplemobiletools.launcher.fragments.AllAppsFragment>
|
||||
|
|
Loading…
Reference in New Issue