mirror of
				https://github.com/SimpleMobileTools/Simple-Launcher.git
				synced 2025-06-05 21:59:15 +02:00 
			
		
		
		
	Merge branch 'main' into feature/folders
Added proper handling of folder closing when swiping pages
This commit is contained in:
		| @@ -61,6 +61,8 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|     private var mMoveGestureThreshold = 0 |     private var mMoveGestureThreshold = 0 | ||||||
|     private var mIgnoreUpEvent = false |     private var mIgnoreUpEvent = false | ||||||
|     private var mIgnoreMoveEvents = false |     private var mIgnoreMoveEvents = false | ||||||
|  |     private var mIgnoreXMoveEvents = false | ||||||
|  |     private var mIgnoreYMoveEvents = false | ||||||
|     private var mLongPressedIcon: HomeScreenGridItem? = null |     private var mLongPressedIcon: HomeScreenGridItem? = null | ||||||
|     private var mOpenPopupMenu: PopupMenu? = null |     private var mOpenPopupMenu: PopupMenu? = null | ||||||
|     private var mCachedLaunchers = ArrayList<AppLauncher>() |     private var mCachedLaunchers = ArrayList<AppLauncher>() | ||||||
| @@ -290,7 +292,10 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|  |  | ||||||
|                 if (hasFingerMoved && !mIgnoreMoveEvents) { |                 if (hasFingerMoved && !mIgnoreMoveEvents) { | ||||||
|                     val diffY = mTouchDownY - event.y |                     val diffY = mTouchDownY - event.y | ||||||
|  |                     val diffX = mTouchDownX - event.x | ||||||
|  |  | ||||||
|  |                     if (abs(diffY) > abs(diffX) && !mIgnoreYMoveEvents) { | ||||||
|  |                         mIgnoreXMoveEvents = true | ||||||
|                         if (isWidgetsFragmentExpanded()) { |                         if (isWidgetsFragmentExpanded()) { | ||||||
|                             val newY = mWidgetsFragmentY - diffY |                             val newY = mWidgetsFragmentY - diffY | ||||||
|                             binding.widgetsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) |                             binding.widgetsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) | ||||||
| @@ -298,6 +303,10 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|                             val newY = mAllAppsFragmentY - diffY |                             val newY = mAllAppsFragmentY - diffY | ||||||
|                             binding.allAppsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) |                             binding.allAppsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) | ||||||
|                         } |                         } | ||||||
|  |                     } else if (abs(diffX) > abs(diffY) && !mIgnoreXMoveEvents) { | ||||||
|  |                         mIgnoreYMoveEvents = true | ||||||
|  |                         binding.homeScreenGrid.root.setSwipeMovement(diffX) | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 mLastTouchCoords = Pair(event.x, event.y) |                 mLastTouchCoords = Pair(event.x, event.y) | ||||||
| @@ -314,6 +323,7 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|                 binding.homeScreenGrid.root.itemDraggingStopped() |                 binding.homeScreenGrid.root.itemDraggingStopped() | ||||||
|  |  | ||||||
|                 if (!mIgnoreUpEvent) { |                 if (!mIgnoreUpEvent) { | ||||||
|  |                     if (!mIgnoreYMoveEvents) { | ||||||
|                         if (binding.allAppsFragment.root.y < mScreenHeight * 0.5) { |                         if (binding.allAppsFragment.root.y < mScreenHeight * 0.5) { | ||||||
|                             showFragment(binding.allAppsFragment) |                             showFragment(binding.allAppsFragment) | ||||||
|                         } else if (isAllAppsFragmentExpanded()) { |                         } else if (isAllAppsFragmentExpanded()) { | ||||||
| @@ -326,6 +336,14 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|                             hideFragment(binding.widgetsFragment) |                             hideFragment(binding.widgetsFragment) | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|  |                     if (!mIgnoreXMoveEvents) { | ||||||
|  |                         binding.homeScreenGrid.root.finalizeSwipe() | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 mIgnoreXMoveEvents = false | ||||||
|  |                 mIgnoreYMoveEvents = false | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -743,6 +761,10 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onFlingUp() { |     override fun onFlingUp() { | ||||||
|  |         if (mIgnoreYMoveEvents) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (!isWidgetsFragmentExpanded()) { |         if (!isWidgetsFragmentExpanded()) { | ||||||
|             mIgnoreUpEvent = true |             mIgnoreUpEvent = true | ||||||
|             showFragment(binding.allAppsFragment) |             showFragment(binding.allAppsFragment) | ||||||
| @@ -751,6 +773,10 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|  |  | ||||||
|     @SuppressLint("WrongConstant") |     @SuppressLint("WrongConstant") | ||||||
|     override fun onFlingDown() { |     override fun onFlingDown() { | ||||||
|  |         if (mIgnoreYMoveEvents) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|         mIgnoreUpEvent = true |         mIgnoreUpEvent = true | ||||||
|         if (isAllAppsFragmentExpanded()) { |         if (isAllAppsFragmentExpanded()) { | ||||||
|             hideFragment(binding.allAppsFragment) |             hideFragment(binding.allAppsFragment) | ||||||
| @@ -765,11 +791,19 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onFlingRight() { |     override fun onFlingRight() { | ||||||
|  |         if (mIgnoreXMoveEvents) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|         mIgnoreUpEvent = true |         mIgnoreUpEvent = true | ||||||
|         binding.homeScreenGrid.root.prevPage(redraw = true) |         binding.homeScreenGrid.root.prevPage(redraw = true) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onFlingLeft() { |     override fun onFlingLeft() { | ||||||
|  |         if (mIgnoreXMoveEvents) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|         mIgnoreUpEvent = true |         mIgnoreUpEvent = true | ||||||
|         binding.homeScreenGrid.root.nextPage(redraw = true) |         binding.homeScreenGrid.root.nextPage(redraw = true) | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import android.graphics.* | |||||||
| import android.graphics.drawable.BitmapDrawable | import android.graphics.drawable.BitmapDrawable | ||||||
| import android.graphics.drawable.Drawable | import android.graphics.drawable.Drawable | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
|  | import android.os.Handler | ||||||
| import android.text.Layout | import android.text.Layout | ||||||
| import android.text.StaticLayout | import android.text.StaticLayout | ||||||
| import android.text.TextPaint | import android.text.TextPaint | ||||||
| @@ -75,13 +76,15 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|     private var redrawWidgets = false |     private var redrawWidgets = false | ||||||
|     private var iconSize = 0 |     private var iconSize = 0 | ||||||
|  |  | ||||||
|     private var lastPage = 0 |     private val pager = AnimatedGridPager( | ||||||
|     private var currentPage = 0 |         getMaxPage = ::getMaxPage, | ||||||
|     private var pageChangeLastArea = PageChangeArea.MIDDLE |         redrawGrid = ::redrawGrid, | ||||||
|     private var pageChangeLastAreaEntryTime = 0L |         getWidth = { width }, | ||||||
|     private var pageChangeAnimLeftPercentage = 0f |         getHandler = { handler }, | ||||||
|     private var pageChangeEnabled = true |         getNextPageBound = { right - sideMargins.right - cellWidth / 2 }, | ||||||
|     private var pageChangeIndicatorsAlpha = 0f |         getPrevPageBound = { left + sideMargins.left + cellWidth / 2 }, | ||||||
|  |         pageChangeStarted = { closeFolder() } | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     private var currentlyOpenFolder: HomeScreenFolder? = null |     private var currentlyOpenFolder: HomeScreenFolder? = null | ||||||
|     private var draggingLeftFolderAt: Long? = null |     private var draggingLeftFolderAt: Long? = null | ||||||
| @@ -101,26 +104,6 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|     var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null |     var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null | ||||||
|     var itemLongClickListener: ((HomeScreenGridItem) -> Unit)? = null |     var itemLongClickListener: ((HomeScreenGridItem) -> Unit)? = null | ||||||
|  |  | ||||||
|     private val checkAndExecuteDelayedPageChange: Runnable = Runnable { |  | ||||||
|         if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { |  | ||||||
|             when (pageChangeLastArea) { |  | ||||||
|                 PageChangeArea.RIGHT -> nextOrAdditionalPage(true) |  | ||||||
|                 PageChangeArea.LEFT -> prevPage(true) |  | ||||||
|                 else -> clearPageChangeFlags() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private val startFadingIndicators: Runnable = Runnable { |  | ||||||
|         ValueAnimator.ofFloat(1f, 0f) |  | ||||||
|             .apply { |  | ||||||
|                 addUpdateListener { |  | ||||||
|                     pageChangeIndicatorsAlpha = it.animatedValue as Float |  | ||||||
|                     redrawGrid() |  | ||||||
|                 } |  | ||||||
|                 start() |  | ||||||
|             } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     init { |     init { | ||||||
|         ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this)) |         ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this)) | ||||||
| @@ -242,7 +225,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             gridItems.removeIf { it.id == item.id } |             gridItems.removeIf { it.id == item.id } | ||||||
|             if (currentPage > getMaxPage()) { |             if (pager.isOutsideOfPageRange()) { | ||||||
|                 post { |                 post { | ||||||
|                     prevPage() |                     prevPage() | ||||||
|                 } |                 } | ||||||
| @@ -300,8 +283,6 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         pageChangeIndicatorsAlpha = 1f |  | ||||||
|         removeCallbacks(startFadingIndicators) |  | ||||||
|         if (draggedItemCurrentCoords.first == -1 && draggedItemCurrentCoords.second == -1 && draggedItem != null) { |         if (draggedItemCurrentCoords.first == -1 && draggedItemCurrentCoords.second == -1 && draggedItem != null) { | ||||||
|             if (draggedItem!!.type == ITEM_TYPE_WIDGET) { |             if (draggedItem!!.type == ITEM_TYPE_WIDGET) { | ||||||
|                 val draggedWidgetView = widgetViews.firstOrNull { it.tag == draggedItem?.widgetId } |                 val draggedWidgetView = widgetViews.firstOrNull { it.tag == draggedItem?.widgetId } | ||||||
| @@ -343,47 +324,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             draggingEnteredNewFolderAt = null |             draggingEnteredNewFolderAt = null | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (x > right - sideMargins.right - cellWidth / 2) { |         pager.handleItemMovement(x, y) | ||||||
|             doWithPageChangeDelay(PageChangeArea.RIGHT) { |  | ||||||
|                 nextOrAdditionalPage() |  | ||||||
|             } |  | ||||||
|         } else if (x < left + sideMargins.left + cellWidth / 2) { |  | ||||||
|             doWithPageChangeDelay(PageChangeArea.LEFT) { |  | ||||||
|                 prevPage() |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             clearPageChangeFlags() |  | ||||||
|         } |  | ||||||
|         redrawGrid() |         redrawGrid() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun clearPageChangeFlags() { |  | ||||||
|         pageChangeLastArea = PageChangeArea.MIDDLE |  | ||||||
|         pageChangeLastAreaEntryTime = 0 |  | ||||||
|         removeCallbacks(checkAndExecuteDelayedPageChange) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun schedulePageChange() { |  | ||||||
|         pageChangeLastAreaEntryTime = System.currentTimeMillis() |  | ||||||
|         postDelayed(checkAndExecuteDelayedPageChange, PAGE_CHANGE_HOLD_THRESHOLD) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun scheduleIndicatorsFade() { |  | ||||||
|         pageChangeIndicatorsAlpha = 1f |  | ||||||
|         postDelayed(startFadingIndicators, PAGE_INDICATORS_FADE_DELAY) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun doWithPageChangeDelay(needed: PageChangeArea, pageChangeFunction: () -> Boolean) { |  | ||||||
|         if (pageChangeLastArea != needed) { |  | ||||||
|             pageChangeLastArea = needed |  | ||||||
|             schedulePageChange() |  | ||||||
|         } else if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { |  | ||||||
|             if (pageChangeFunction()) { |  | ||||||
|                 clearPageChangeFlags() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // figure out at which cell was the item dropped, if it is empty |     // figure out at which cell was the item dropped, if it is empty | ||||||
|     fun itemDraggingStopped() { |     fun itemDraggingStopped() { | ||||||
|         widgetViews.forEach { |         widgetViews.forEach { | ||||||
| @@ -394,7 +338,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             return |             return | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         scheduleIndicatorsFade() |         pager.itemMovementStopped() | ||||||
|         when (draggedItem!!.type) { |         when (draggedItem!!.type) { | ||||||
|             ITEM_TYPE_FOLDER -> moveItem() |             ITEM_TYPE_FOLDER -> moveItem() | ||||||
|             ITEM_TYPE_ICON, ITEM_TYPE_SHORTCUT -> addAppIconOrShortcut() |             ITEM_TYPE_ICON, ITEM_TYPE_SHORTCUT -> addAppIconOrShortcut() | ||||||
| @@ -496,7 +440,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                     top = yIndex |                     top = yIndex | ||||||
|                     right = xIndex |                     right = xIndex | ||||||
|                     bottom = yIndex |                     bottom = yIndex | ||||||
|                     page = currentPage |                     page = pager.getCurrentPage() | ||||||
|                     docked = yIndex == rowCount - 1 |                     docked = yIndex == rowCount - 1 | ||||||
|  |  | ||||||
|                     ensureBackgroundThread { |                     ensureBackgroundThread { | ||||||
| @@ -659,7 +603,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                 top = yIndex |                 top = yIndex | ||||||
|                 right = finalXIndex |                 right = finalXIndex | ||||||
|                 bottom = yIndex |                 bottom = yIndex | ||||||
|                 page = currentPage |                 page = pager.getCurrentPage() | ||||||
|                 docked = yIndex == rowCount - 1 |                 docked = yIndex == rowCount - 1 | ||||||
|                 parentId = newParentId |                 parentId = newParentId | ||||||
|  |  | ||||||
| @@ -699,7 +643,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                 yIndex, |                 yIndex, | ||||||
|                 finalXIndex, |                 finalXIndex, | ||||||
|                 yIndex, |                 yIndex, | ||||||
|                 currentPage, |                 pager.getCurrentPage(), | ||||||
|                 draggedItem!!.packageName, |                 draggedItem!!.packageName, | ||||||
|                 draggedItem!!.activityName, |                 draggedItem!!.activityName, | ||||||
|                 draggedItem!!.title, |                 draggedItem!!.title, | ||||||
| @@ -790,7 +734,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                     top = widgetRect.top |                     top = widgetRect.top | ||||||
|                     right = widgetRect.right |                     right = widgetRect.right | ||||||
|                     bottom = widgetRect.bottom |                     bottom = widgetRect.bottom | ||||||
|                     page = currentPage |                     page = pager.getCurrentPage() | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 ensureBackgroundThread { |                 ensureBackgroundThread { | ||||||
| @@ -807,7 +751,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                             widgetItem.top, |                             widgetItem.top, | ||||||
|                             widgetItem.right, |                             widgetItem.right, | ||||||
|                             widgetItem.bottom, |                             widgetItem.bottom, | ||||||
|                             currentPage, |                             pager.getCurrentPage(), | ||||||
|                             false, |                             false, | ||||||
|                             null, |                             null, | ||||||
|                             widgetItem.id!! |                             widgetItem.id!! | ||||||
| @@ -867,7 +811,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                     removeItemFromHomeScreen(item) |                     removeItemFromHomeScreen(item) | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (currentPage > getMaxPage()) { |                 if (pager.isOutsideOfPageRange()) { | ||||||
|                     prevPage(redraw = true) |                     prevPage(redraw = true) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -902,25 +846,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun updateWidgetPositionAndSize(widgetView: AppWidgetHostView, item: HomeScreenGridItem): Size { |     private fun updateWidgetPositionAndSize(widgetView: AppWidgetHostView, item: HomeScreenGridItem): Size { | ||||||
|         var x = calculateWidgetX(item.left) + width * item.page - width * lastPage |         val currentViewPosition = pager.getCurrentViewPositionInFullPageSpace() * width.toFloat() | ||||||
|         if (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f && (item.page == currentPage || item.page == lastPage)) { |         val x = calculateWidgetX(item.left) + width * item.page - currentViewPosition | ||||||
|             val xFactor = if (currentPage > lastPage) { |  | ||||||
|                 pageChangeAnimLeftPercentage |  | ||||||
|             } else { |  | ||||||
|                 -pageChangeAnimLeftPercentage |  | ||||||
|             } |  | ||||||
|             val lastXFactor = if (currentPage > lastPage) { |  | ||||||
|                 pageChangeAnimLeftPercentage - 1 |  | ||||||
|             } else { |  | ||||||
|                 1 - pageChangeAnimLeftPercentage |  | ||||||
|             } |  | ||||||
|             if (item.page == currentPage) { |  | ||||||
|                 x += width * xFactor |  | ||||||
|             } |  | ||||||
|             if (item.page == lastPage) { |  | ||||||
|                 x += width * lastXFactor |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         widgetView.x = x |         widgetView.x = x | ||||||
|         widgetView.y = calculateWidgetY(item.top) |         widgetView.y = calculateWidgetY(item.top) | ||||||
|         val widgetWidth = item.getWidthInCells() * cellWidth |         val widgetWidth = item.getWidthInCells() * cellWidth | ||||||
| @@ -977,16 +904,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             fillCellSizes() |             fillCellSizes() | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         val currentXFactor = if (currentPage > lastPage) { |         val currentXFactor = pager.getXFactorForCurrentPage() | ||||||
|             pageChangeAnimLeftPercentage |         val lastXFactor = pager.getXFactorForLastPage() | ||||||
|         } else { |  | ||||||
|             -pageChangeAnimLeftPercentage |  | ||||||
|         } |  | ||||||
|         val lastXFactor = if (currentPage > lastPage) { |  | ||||||
|             pageChangeAnimLeftPercentage - 1 |  | ||||||
|         } else { |  | ||||||
|             1 - pageChangeAnimLeftPercentage |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         fun handleGridItemDrawing(item: HomeScreenGridItem, baseItemX: Int, baseItemY: Int) { |         fun handleGridItemDrawing(item: HomeScreenGridItem, baseItemX: Int, baseItemY: Int) { | ||||||
|             if (item.id != draggedItem?.id) { |             if (item.id != draggedItem?.id) { | ||||||
| @@ -1040,7 +959,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT || it.type == ITEM_TYPE_FOLDER) && it.page == currentPage && !it.docked && it.parentId == null } |         gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT || it.type == ITEM_TYPE_FOLDER) && pager.isItemOnCurrentPage(it) && !it.docked && it.parentId == null } | ||||||
|             .forEach { item -> |             .forEach { item -> | ||||||
|                 if (item.outOfBounds()) { |                 if (item.outOfBounds()) { | ||||||
|                     return@forEach |                     return@forEach | ||||||
| @@ -1056,8 +975,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|  |  | ||||||
|                 handleMainGridItemDrawing(item, 0f) |                 handleMainGridItemDrawing(item, 0f) | ||||||
|             } |             } | ||||||
|         if (pageChangeAnimLeftPercentage > 0f) { |         if (pager.isAnimatingPageChange()) { | ||||||
|             gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT || it.type == ITEM_TYPE_FOLDER) && it.page == lastPage && !it.docked && it.parentId == null } |             gridItems.filter { (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT || it.type == ITEM_TYPE_FOLDER) && pager.isItemOnLastPage(it) && !it.docked && it.parentId == null } | ||||||
|                 .forEach { item -> |                 .forEach { item -> | ||||||
|                     if (item.outOfBounds()) { |                     if (item.outOfBounds()) { | ||||||
|                         return@forEach |                         return@forEach | ||||||
| @@ -1067,6 +986,21 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (pager.isSwiped()) { | ||||||
|  |             gridItems.filter { | ||||||
|  |                 (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT || it.type == ITEM_TYPE_FOLDER) | ||||||
|  |                     && pager.isItemInSwipeRange(it) | ||||||
|  |                     && !it.docked | ||||||
|  |                     && it.parentId == null | ||||||
|  |             }.forEach { item -> | ||||||
|  |                 if (item.outOfBounds()) { | ||||||
|  |                     return@forEach | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 handleMainGridItemDrawing(item, lastXFactor) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (isFirstDraw) { |         if (isFirstDraw) { | ||||||
|             gridItems.filter { it.type == ITEM_TYPE_WIDGET && !it.outOfBounds() }.forEach { item -> |             gridItems.filter { it.type == ITEM_TYPE_WIDGET && !it.outOfBounds() }.forEach { item -> | ||||||
|                 bindWidget(item, true) |                 bindWidget(item, true) | ||||||
| @@ -1080,19 +1014,15 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Only draw page indicators when there is a need for it |         // Only draw page indicators when there is a need for it | ||||||
|         if (pageChangeAnimLeftPercentage > 0f || pageChangeIndicatorsAlpha != 0f) { |         if (pager.shouldDisplayPageChangeIndicator()) { | ||||||
|             val pageCount = max(getMaxPage(), currentPage) + 1 |             val pageCount = pager.getPageCount() | ||||||
|             val pageIndicatorsRequiredWidth = pageCount * pageIndicatorRadius * 2 + pageCount * (pageIndicatorMargin - 1) |             val pageIndicatorsRequiredWidth = pageCount * pageIndicatorRadius * 2 + pageCount * (pageIndicatorMargin - 1) | ||||||
|             val usableWidth = getFakeWidth() |             val usableWidth = getFakeWidth() | ||||||
|             val pageIndicatorsStart = (usableWidth - pageIndicatorsRequiredWidth) / 2 + sideMargins.left |             val pageIndicatorsStart = (usableWidth - pageIndicatorsRequiredWidth) / 2 + sideMargins.left | ||||||
|             var currentPageIndicatorLeft = pageIndicatorsStart |             var currentPageIndicatorLeft = pageIndicatorsStart | ||||||
|             val pageIndicatorY = cellYCoords[rowCount - 1].toFloat() + sideMargins.top + extraYMargin + iconMargin |             val pageIndicatorY = cellYCoords[rowCount - 1].toFloat() + sideMargins.top + extraYMargin + iconMargin | ||||||
|             val pageIndicatorStep = pageIndicatorRadius * 2 + pageIndicatorMargin |             val pageIndicatorStep = pageIndicatorRadius * 2 + pageIndicatorMargin | ||||||
|             if (pageChangeIndicatorsAlpha != 0f) { |             emptyPageIndicatorPaint.alpha = pager.getPageChangeIndicatorsAlpha() | ||||||
|                 emptyPageIndicatorPaint.alpha = (pageChangeIndicatorsAlpha * 255.0f).toInt() |  | ||||||
|             } else { |  | ||||||
|                 emptyPageIndicatorPaint.alpha = 255 |  | ||||||
|             } |  | ||||||
|             // Draw empty page indicators |             // Draw empty page indicators | ||||||
|             for (page in 0 until pageCount) { |             for (page in 0 until pageCount) { | ||||||
|                 canvas.drawCircle(currentPageIndicatorLeft + pageIndicatorRadius, pageIndicatorY, pageIndicatorRadius, emptyPageIndicatorPaint) |                 canvas.drawCircle(currentPageIndicatorLeft + pageIndicatorRadius, pageIndicatorY, pageIndicatorRadius, emptyPageIndicatorPaint) | ||||||
| @@ -1100,14 +1030,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             // Draw current page indicator on exact position |             // Draw current page indicator on exact position | ||||||
|             val currentIndicatorRangeStart = pageIndicatorsStart + lastPage * pageIndicatorStep |             val currentIndicatorPosition = pageIndicatorsStart + pager.getCurrentViewPositionInFullPageSpace() * pageIndicatorStep | ||||||
|             val currentIndicatorRangeEnd = pageIndicatorsStart + currentPage * pageIndicatorStep |             currentPageIndicatorPaint.alpha = pager.getPageChangeIndicatorsAlpha() | ||||||
|             val currentIndicatorPosition = MathUtils.lerp(currentIndicatorRangeStart, currentIndicatorRangeEnd, 1 - pageChangeAnimLeftPercentage) |  | ||||||
|             if (pageChangeIndicatorsAlpha != 0f) { |  | ||||||
|                 currentPageIndicatorPaint.alpha = (pageChangeIndicatorsAlpha * 255.0f).toInt() |  | ||||||
|             } else { |  | ||||||
|                 currentPageIndicatorPaint.alpha = 255 |  | ||||||
|             } |  | ||||||
|             canvas.drawCircle(currentIndicatorPosition + pageIndicatorRadius, pageIndicatorY, pageIndicatorRadius, currentPageIndicatorPaint) |             canvas.drawCircle(currentIndicatorPosition + pageIndicatorRadius, pageIndicatorY, pageIndicatorRadius, currentPageIndicatorPaint) | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -1117,6 +1041,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             val folderRect = folder.getDrawingRect() |             val folderRect = folder.getDrawingRect() | ||||||
|             val folderItemsRect = folder.getItemsDrawingRect() |             val folderItemsRect = folder.getItemsDrawingRect() | ||||||
|  |  | ||||||
|  |             val currentViewPosition = pager.getCurrentViewPositionInFullPageSpace() * width.toFloat() | ||||||
|  |             val rectOffset = width * folder.item.page - currentViewPosition | ||||||
|  |             folderRect.offset(rectOffset, 0f) | ||||||
|  |  | ||||||
|             canvas.drawRoundRect(folderRect, roundedCornerRadius, roundedCornerRadius, folderBackgroundPaint) |             canvas.drawRoundRect(folderRect, roundedCornerRadius, roundedCornerRadius, folderBackgroundPaint) | ||||||
|  |  | ||||||
|             canvas.withScale(folder.scale, folder.scale, folderRect.centerX(), folderRect.centerY()) { |             canvas.withScale(folder.scale, folder.scale, folderRect.centerX(), folderRect.centerY()) { | ||||||
| @@ -1427,48 +1355,29 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|  |  | ||||||
|     private fun getMaxPage() = gridItems.filter { !it.docked && !it.outOfBounds() }.maxOfOrNull { it.page } ?: 0 |     private fun getMaxPage() = gridItems.filter { !it.docked && !it.outOfBounds() }.maxOfOrNull { it.page } ?: 0 | ||||||
|  |  | ||||||
|     private fun nextOrAdditionalPage(redraw: Boolean = false): Boolean { |  | ||||||
|         if (currentPage < getMaxPage() + 1 && pageChangeEnabled) { |  | ||||||
|             lastPage = currentPage |  | ||||||
|             currentPage++ |  | ||||||
|             handlePageChange(redraw) |  | ||||||
|             return true |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return false |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fun nextPage(redraw: Boolean = false): Boolean { |     fun nextPage(redraw: Boolean = false): Boolean { | ||||||
|         if (currentPage < getMaxPage() && pageChangeEnabled) { |         return pager.nextPage(redraw) | ||||||
|             lastPage = currentPage |  | ||||||
|             currentPage++ |  | ||||||
|             handlePageChange(redraw) |  | ||||||
|             return true |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return false |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun prevPage(redraw: Boolean = false): Boolean { |     fun prevPage(redraw: Boolean = false): Boolean { | ||||||
|         if (currentPage > 0 && pageChangeEnabled) { |         return pager.prevPage(redraw) | ||||||
|             lastPage = currentPage |  | ||||||
|             currentPage-- |  | ||||||
|             handlePageChange(redraw) |  | ||||||
|             return true |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return false |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun skipToPage(targetPage: Int): Boolean { |     fun skipToPage(targetPage: Int): Boolean { | ||||||
|         if (currentPage != targetPage && targetPage < getMaxPage() + 1) { |         return pager.skipToPage(targetPage) | ||||||
|             lastPage = currentPage |  | ||||||
|             currentPage = targetPage |  | ||||||
|             handlePageChange() |  | ||||||
|             return true |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|         return false |     fun getCurrentIconSize(): Int = iconSize | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     fun setSwipeMovement(diffX: Float) { | ||||||
|  |         if (draggedItem == null) { | ||||||
|  |             pager.setSwipeMovement(diffX) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun finalizeSwipe() { | ||||||
|  |         pager.finalizeSwipe() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun openFolder(folder: HomeScreenGridItem) { |     fun openFolder(folder: HomeScreenGridItem) { | ||||||
| @@ -1489,42 +1398,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun getCurrentIconSize(): Int = iconSize |     private fun ArrayList<HomeScreenGridItem>.filterVisibleOnly() = filter { (pager.isItemOnCurrentPage(it) || it.docked) && it.parentId == null } | ||||||
|  |  | ||||||
|     fun getCurrentCellSize(): Int = cellWidth |  | ||||||
|  |  | ||||||
|     fun getCurrentCellMargin(): Int = iconMargin |  | ||||||
|  |  | ||||||
|     private fun handlePageChange(redraw: Boolean = false) { |  | ||||||
|         pageChangeEnabled = false |  | ||||||
|         pageChangeIndicatorsAlpha = 0f |  | ||||||
|         closeFolder() |  | ||||||
|         removeCallbacks(startFadingIndicators) |  | ||||||
|         if (redraw) { |  | ||||||
|             redrawGrid() |  | ||||||
|         } |  | ||||||
|         ValueAnimator.ofFloat(1f, 0f) |  | ||||||
|             .apply { |  | ||||||
|                 addUpdateListener { |  | ||||||
|                     pageChangeAnimLeftPercentage = it.animatedValue as Float |  | ||||||
|                     redrawGrid() |  | ||||||
|                 } |  | ||||||
|                 addListener(object : AnimatorListenerAdapter() { |  | ||||||
|                     override fun onAnimationEnd(animation: Animator) { |  | ||||||
|                         super.onAnimationEnd(animation) |  | ||||||
|                         pageChangeAnimLeftPercentage = 0f |  | ||||||
|                         pageChangeEnabled = true |  | ||||||
|                         lastPage = currentPage |  | ||||||
|                         schedulePageChange() |  | ||||||
|                         scheduleIndicatorsFade() |  | ||||||
|                         redrawGrid() |  | ||||||
|                     } |  | ||||||
|                 }) |  | ||||||
|                 start() |  | ||||||
|             } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun ArrayList<HomeScreenGridItem>.filterVisibleOnly() = filter { (it.page == currentPage || it.docked) && it.parentId == null } |  | ||||||
|  |  | ||||||
|     private fun HomeScreenGridItem.toFolder(animateOpening: Boolean = false) = HomeScreenFolder(this, animateOpening) |     private fun HomeScreenGridItem.toFolder(animateOpening: Boolean = false) = HomeScreenFolder(this, animateOpening) | ||||||
|  |  | ||||||
| @@ -1533,6 +1407,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|         animateOpening: Boolean |         animateOpening: Boolean | ||||||
|     ) { |     ) { | ||||||
|         var scale: Float = 1f |         var scale: Float = 1f | ||||||
|  |         private var closing = false | ||||||
|  |  | ||||||
|         init { |         init { | ||||||
|             if (animateOpening) { |             if (animateOpening) { | ||||||
| @@ -1659,6 +1534,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|  |  | ||||||
|         fun animateClosing(callback: () -> Unit) { |         fun animateClosing(callback: () -> Unit) { | ||||||
|             post { |             post { | ||||||
|  |                 if (closing) { | ||||||
|  |                     return@post | ||||||
|  |                 } | ||||||
|  |                 closing = true | ||||||
|                 ValueAnimator.ofFloat(scale, 0.2f) |                 ValueAnimator.ofFloat(scale, 0.2f) | ||||||
|                     .apply { |                     .apply { | ||||||
|                         interpolator = DecelerateInterpolator() |                         interpolator = DecelerateInterpolator() | ||||||
| @@ -1695,3 +1574,291 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Helper class responsible for managing current page and providing utilities for animating page changes, | ||||||
|  |  * as well as partial dragigng between pages | ||||||
|  |  */ | ||||||
|  | private class AnimatedGridPager( | ||||||
|  |     private val getMaxPage: () -> Int, | ||||||
|  |     private val redrawGrid: () -> Unit, | ||||||
|  |     private val getWidth: () -> Int, | ||||||
|  |     private val getHandler: () -> Handler, | ||||||
|  |     private val getNextPageBound: () -> Int, | ||||||
|  |     private val getPrevPageBound: () -> Int, | ||||||
|  |     private val pageChangeStarted: () -> Unit | ||||||
|  | ) { | ||||||
|  |  | ||||||
|  |     companion object { | ||||||
|  |         private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L | ||||||
|  |         private const val PAGE_INDICATORS_FADE_DELAY = PAGE_CHANGE_HOLD_THRESHOLD + 300L | ||||||
|  |  | ||||||
|  |         private enum class PageChangeArea { | ||||||
|  |             LEFT, | ||||||
|  |             MIDDLE, | ||||||
|  |             RIGHT | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private var lastPage = 0 | ||||||
|  |     private var currentPage = 0 | ||||||
|  |     private var pageChangeLastArea = PageChangeArea.MIDDLE | ||||||
|  |     private var pageChangeLastAreaEntryTime = 0L | ||||||
|  |     private var pageChangeAnimLeftPercentage = 0f | ||||||
|  |     private var pageChangeEnabled = true | ||||||
|  |     private var pageChangeIndicatorsAlpha = 0f | ||||||
|  |     private var pageChangeSwipedPercentage = 0f | ||||||
|  |  | ||||||
|  |     fun getCurrentPage() = currentPage | ||||||
|  |  | ||||||
|  |     fun isItemOnCurrentPage(item: HomeScreenGridItem) = item.page == currentPage | ||||||
|  |  | ||||||
|  |     fun isItemOnLastPage(item: HomeScreenGridItem) = item.page == lastPage | ||||||
|  |  | ||||||
|  |     fun getPageCount() = max(getMaxPage(), currentPage) + 1 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     fun isOutsideOfPageRange() = currentPage > getMaxPage() | ||||||
|  |  | ||||||
|  |     fun isItemInSwipeRange(item: HomeScreenGridItem) = | ||||||
|  |         ((pageChangeSwipedPercentage > 0f && item.page == currentPage - 1) || (pageChangeSwipedPercentage < 0f && item.page == currentPage + 1)) | ||||||
|  |  | ||||||
|  |     fun isSwiped() = abs(pageChangeSwipedPercentage) > 0f | ||||||
|  |  | ||||||
|  |     fun isAnimatingPageChange() = pageChangeAnimLeftPercentage > 0f | ||||||
|  |  | ||||||
|  |     fun shouldDisplayPageChangeIndicator() = isSwiped() || isAnimatingPageChange() || pageChangeIndicatorsAlpha > 0f | ||||||
|  |  | ||||||
|  |     fun getPageChangeIndicatorsAlpha() = if (pageChangeIndicatorsAlpha != 0f) { | ||||||
|  |         (pageChangeIndicatorsAlpha * 255.0f).toInt() | ||||||
|  |     } else { | ||||||
|  |         255 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun getXFactorForCurrentPage(): Float { | ||||||
|  |         return if (abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|  |             pageChangeSwipedPercentage | ||||||
|  |         } else { | ||||||
|  |             if (currentPage > lastPage) { | ||||||
|  |                 pageChangeAnimLeftPercentage | ||||||
|  |             } else { | ||||||
|  |                 -pageChangeAnimLeftPercentage | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun getXFactorForLastPage(): Float { | ||||||
|  |         return if (abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|  |             (1 - abs(pageChangeSwipedPercentage)) * -sign(pageChangeSwipedPercentage) | ||||||
|  |         } else { | ||||||
|  |             if (currentPage > lastPage) { | ||||||
|  |                 pageChangeAnimLeftPercentage - 1 | ||||||
|  |             } else { | ||||||
|  |                 1 - pageChangeAnimLeftPercentage | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun getCurrentViewPositionInFullPageSpace(): Float { | ||||||
|  |         val rangeStart = lastPage.toFloat() | ||||||
|  |         val rangeEndPage = if (abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|  |             if (pageChangeSwipedPercentage > 0f) { | ||||||
|  |                 currentPage - 1 | ||||||
|  |             } else { | ||||||
|  |                 currentPage + 1 | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             currentPage | ||||||
|  |         } | ||||||
|  |         val rangeEnd = rangeEndPage.toFloat() | ||||||
|  |         val lerpAmount = if (pageChangeAnimLeftPercentage > 0f) { | ||||||
|  |             1 - pageChangeAnimLeftPercentage | ||||||
|  |         } else { | ||||||
|  |             abs(pageChangeSwipedPercentage) | ||||||
|  |         } | ||||||
|  |         return MathUtils.lerp(rangeStart, rangeEnd, lerpAmount) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun setSwipeMovement(diffX: Float) { | ||||||
|  |         if (!pageChangeEnabled) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (currentPage < getMaxPage() && diffX > 0f || currentPage > 0 && diffX < 0f) { | ||||||
|  |             pageChangeSwipedPercentage = (-diffX / getWidth().toFloat()).coerceIn(-1f, 1f) | ||||||
|  |             pageChangeStarted() | ||||||
|  |             redrawGrid() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun finalizeSwipe() { | ||||||
|  |         if (abs(pageChangeSwipedPercentage) == 0f) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (abs(pageChangeSwipedPercentage) > 0.5f) { | ||||||
|  |             lastPage = currentPage | ||||||
|  |             currentPage = if (pageChangeSwipedPercentage > 0f) { | ||||||
|  |                 currentPage - 1 | ||||||
|  |             } else { | ||||||
|  |                 currentPage + 1 | ||||||
|  |             } | ||||||
|  |             handlePageChange(true) | ||||||
|  |         } else { | ||||||
|  |             lastPage = if (pageChangeSwipedPercentage > 0f) { | ||||||
|  |                 currentPage - 1 | ||||||
|  |             } else { | ||||||
|  |                 currentPage + 1 | ||||||
|  |             } | ||||||
|  |             pageChangeSwipedPercentage = sign(pageChangeSwipedPercentage) * (1 - abs(pageChangeSwipedPercentage)) | ||||||
|  |             handlePageChange(true) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun handleItemMovement(x: Int, y: Int) { | ||||||
|  |         showIndicators() | ||||||
|  |         if (x > getNextPageBound()) { | ||||||
|  |             doWithPageChangeDelay(PageChangeArea.RIGHT) { | ||||||
|  |                 nextOrAdditionalPage() | ||||||
|  |             } | ||||||
|  |         } else if (x < getPrevPageBound()) { | ||||||
|  |             doWithPageChangeDelay(PageChangeArea.LEFT) { | ||||||
|  |                 prevPage() | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             clearPageChangeFlags() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun itemMovementStopped() { | ||||||
|  |         scheduleIndicatorsFade() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun nextPage(redraw: Boolean = false): Boolean { | ||||||
|  |         if (currentPage < getMaxPage() && pageChangeEnabled) { | ||||||
|  |             lastPage = currentPage | ||||||
|  |             currentPage++ | ||||||
|  |             handlePageChange(redraw) | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return false | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun prevPage(redraw: Boolean = false): Boolean { | ||||||
|  |         if (currentPage > 0 && pageChangeEnabled) { | ||||||
|  |             lastPage = currentPage | ||||||
|  |             currentPage-- | ||||||
|  |             handlePageChange(redraw) | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return false | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun skipToPage(targetPage: Int): Boolean { | ||||||
|  |         if (currentPage != targetPage && targetPage < getMaxPage() + 1) { | ||||||
|  |             lastPage = currentPage | ||||||
|  |             currentPage = targetPage | ||||||
|  |             handlePageChange() | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return false | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private val checkAndExecuteDelayedPageChange: Runnable = Runnable { | ||||||
|  |         if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { | ||||||
|  |             when (pageChangeLastArea) { | ||||||
|  |                 PageChangeArea.RIGHT -> nextOrAdditionalPage(true) | ||||||
|  |                 PageChangeArea.LEFT -> prevPage(true) | ||||||
|  |                 else -> clearPageChangeFlags() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private val startFadingIndicators: Runnable = Runnable { | ||||||
|  |         ValueAnimator.ofFloat(1f, 0f) | ||||||
|  |             .apply { | ||||||
|  |                 addUpdateListener { | ||||||
|  |                     pageChangeIndicatorsAlpha = it.animatedValue as Float | ||||||
|  |                     redrawGrid() | ||||||
|  |                 } | ||||||
|  |                 start() | ||||||
|  |             } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun showIndicators() { | ||||||
|  |         pageChangeIndicatorsAlpha = 1f | ||||||
|  |         getHandler().removeCallbacks(startFadingIndicators) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun clearPageChangeFlags() { | ||||||
|  |         pageChangeLastArea = PageChangeArea.MIDDLE | ||||||
|  |         pageChangeLastAreaEntryTime = 0 | ||||||
|  |         getHandler().removeCallbacks(checkAndExecuteDelayedPageChange) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun schedulePageChange() { | ||||||
|  |         pageChangeLastAreaEntryTime = System.currentTimeMillis() | ||||||
|  |         getHandler().postDelayed(checkAndExecuteDelayedPageChange, PAGE_CHANGE_HOLD_THRESHOLD) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun scheduleIndicatorsFade() { | ||||||
|  |         pageChangeIndicatorsAlpha = 1f | ||||||
|  |         getHandler().postDelayed(startFadingIndicators, PAGE_INDICATORS_FADE_DELAY) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun doWithPageChangeDelay(needed: PageChangeArea, pageChangeFunction: () -> Boolean) { | ||||||
|  |         if (pageChangeLastArea != needed) { | ||||||
|  |             pageChangeLastArea = needed | ||||||
|  |             schedulePageChange() | ||||||
|  |         } else if (System.currentTimeMillis() - pageChangeLastAreaEntryTime > PAGE_CHANGE_HOLD_THRESHOLD) { | ||||||
|  |             if (pageChangeFunction()) { | ||||||
|  |                 clearPageChangeFlags() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun nextOrAdditionalPage(redraw: Boolean = false): Boolean { | ||||||
|  |         if (currentPage < getMaxPage() + 1 && pageChangeEnabled) { | ||||||
|  |             lastPage = currentPage | ||||||
|  |             currentPage++ | ||||||
|  |             handlePageChange(redraw) | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return false | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun handlePageChange(redraw: Boolean = false) { | ||||||
|  |         pageChangeEnabled = false | ||||||
|  |         pageChangeIndicatorsAlpha = 0f | ||||||
|  |         pageChangeStarted() | ||||||
|  |         val startingAt = 1 - abs(pageChangeSwipedPercentage) | ||||||
|  |         pageChangeSwipedPercentage = 0f | ||||||
|  |         getHandler().removeCallbacks(startFadingIndicators) | ||||||
|  |         if (redraw) { | ||||||
|  |             redrawGrid() | ||||||
|  |         } | ||||||
|  |         ValueAnimator.ofFloat(startingAt, 0f) | ||||||
|  |             .apply { | ||||||
|  |                 addUpdateListener { | ||||||
|  |                     pageChangeAnimLeftPercentage = it.animatedValue as Float | ||||||
|  |                     redrawGrid() | ||||||
|  |                 } | ||||||
|  |                 addListener(object : AnimatorListenerAdapter() { | ||||||
|  |                     override fun onAnimationEnd(animation: Animator) { | ||||||
|  |                         super.onAnimationEnd(animation) | ||||||
|  |                         pageChangeAnimLeftPercentage = 0f | ||||||
|  |                         pageChangeEnabled = true | ||||||
|  |                         lastPage = currentPage | ||||||
|  |                         clearPageChangeFlags() | ||||||
|  |                         scheduleIndicatorsFade() | ||||||
|  |                         redrawGrid() | ||||||
|  |                     } | ||||||
|  |                 }) | ||||||
|  |                 start() | ||||||
|  |             } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,8 +11,8 @@ | |||||||
|     <string name="manage_hidden_icons">Gérer les icônes cachées</string> |     <string name="manage_hidden_icons">Gérer les icônes cachées</string> | ||||||
|     <string name="hidden_icons">Icônes cachées</string> |     <string name="hidden_icons">Icônes cachées</string> | ||||||
|     <string name="hidden_icons_placeholder">Certaines applications ne peuvent pas être désinstallées en raison de restrictions du système, mais vous pouvez au moins masquer leurs icônes pour éviter de les voir.</string> |     <string name="hidden_icons_placeholder">Certaines applications ne peuvent pas être désinstallées en raison de restrictions du système, mais vous pouvez au moins masquer leurs icônes pour éviter de les voir.</string> | ||||||
|     <string name="app_drawer_settings">App drawer</string> |     <string name="app_drawer_settings">Tiroir d\'appli</string> | ||||||
|     <string name="close_app_drawer_on_app_open">Close app drawer on opening an app</string> |     <string name="close_app_drawer_on_app_open">Fermer le tiroir de l\'appli à l\'ouverture d\'une application</string> | ||||||
|     <string name="home_screen_settings">Home screen</string> |     <string name="home_screen_settings">Home screen</string> | ||||||
|     <string name="widget_too_big">Widget is too big for current home screen size</string> |     <string name="widget_too_big">Le widget est trop grand pour la taille actuelle de l\'écran</string> | ||||||
| </resources> | </resources> | ||||||
| @@ -11,8 +11,8 @@ | |||||||
|     <string name="manage_hidden_icons">Gestisci le icone nascoste</string> |     <string name="manage_hidden_icons">Gestisci le icone nascoste</string> | ||||||
|     <string name="hidden_icons">Icone nascoste</string> |     <string name="hidden_icons">Icone nascoste</string> | ||||||
|     <string name="hidden_icons_placeholder">Alcune applicazioni non possono essere disinstallate a causa di restrizioni di sistema, ma è possibile almeno nascondere le loro icone per evitare di vederle.</string> |     <string name="hidden_icons_placeholder">Alcune applicazioni non possono essere disinstallate a causa di restrizioni di sistema, ma è possibile almeno nascondere le loro icone per evitare di vederle.</string> | ||||||
|     <string name="app_drawer_settings">App drawer</string> |     <string name="app_drawer_settings">Cassetto app</string> | ||||||
|     <string name="close_app_drawer_on_app_open">Close app drawer on opening an app</string> |     <string name="close_app_drawer_on_app_open">Chiudi il cassetto app all\'apertura di un\'app</string> | ||||||
|     <string name="home_screen_settings">Home screen</string> |     <string name="home_screen_settings">Home screen</string> | ||||||
|     <string name="widget_too_big">Widget is too big for current home screen size</string> |     <string name="widget_too_big">Il widget è troppo grande per le dimensioni attuali della schermata principale</string> | ||||||
| </resources> | </resources> | ||||||
| @@ -12,7 +12,7 @@ | |||||||
|     <string name="hidden_icons">Dolda ikoner</string> |     <string name="hidden_icons">Dolda ikoner</string> | ||||||
|     <string name="hidden_icons_placeholder">Vissa appar kan inte avinstalleras på grund av systembegränsningar, men du kan åtminstone dölja deras ikoner för att slippa se dem.</string> |     <string name="hidden_icons_placeholder">Vissa appar kan inte avinstalleras på grund av systembegränsningar, men du kan åtminstone dölja deras ikoner för att slippa se dem.</string> | ||||||
|     <string name="app_drawer_settings">Applåda</string> |     <string name="app_drawer_settings">Applåda</string> | ||||||
|     <string name="close_app_drawer_on_app_open">Close app drawer on opening an app</string> |     <string name="close_app_drawer_on_app_open">Stäng applådan när en app öppnas</string> | ||||||
|     <string name="home_screen_settings">Startskärm</string> |     <string name="home_screen_settings">Startskärm</string> | ||||||
|     <string name="widget_too_big">Widgeten är för stor för startskärmens aktuella storlek</string> |     <string name="widget_too_big">Widgeten är för stor för startskärmens aktuella storlek</string> | ||||||
| </resources> | </resources> | ||||||
		Reference in New Issue
	
	Block a user