adding some Drag & Drop related improvements
This commit is contained in:
parent
d1a38d8a02
commit
92fd30eec2
|
@ -15,11 +15,8 @@ import android.telecom.TelecomManager
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
import android.widget.RelativeLayout
|
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.core.view.GestureDetectorCompat
|
import androidx.core.view.GestureDetectorCompat
|
||||||
import androidx.core.view.marginLeft
|
|
||||||
import androidx.core.view.marginTop
|
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.launcher.BuildConfig
|
import com.simplemobiletools.launcher.BuildConfig
|
||||||
|
@ -68,11 +65,6 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
fragment.beVisible()
|
fragment.beVisible()
|
||||||
}
|
}
|
||||||
|
|
||||||
(home_screen_grid.layoutParams as RelativeLayout.LayoutParams).apply {
|
|
||||||
topMargin = statusBarHeight
|
|
||||||
bottomMargin = navigationBarHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.wasHomeScreenInit) {
|
if (!config.wasHomeScreenInit) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
getDefaultAppPackages()
|
getDefaultAppPackages()
|
||||||
|
@ -248,17 +240,15 @@ class MainActivity : SimpleActivity(), FlingListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun homeScreenClicked(x: Float, y: Float) {
|
fun homeScreenClicked(x: Float, y: Float) {
|
||||||
if (x >= home_screen_grid.left && x <= home_screen_grid.right && y >= home_screen_grid.top && y <= home_screen_grid.bottom) {
|
val clickedGridItem = home_screen_grid.isClickingGridItem(getGridTouchedX(x), getGridTouchedY(y))
|
||||||
val clickedGridItem = home_screen_grid.isClickingGridItem(getGridTouchedX(x), getGridTouchedY(y))
|
if (clickedGridItem != null) {
|
||||||
if (clickedGridItem != null) {
|
launchApp(clickedGridItem.packageName)
|
||||||
launchApp(clickedGridItem.packageName)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGridTouchedX(x: Float) = Math.min(Math.max(x.toInt() - home_screen_grid.marginLeft, 0), home_screen_grid.width)
|
private fun getGridTouchedX(x: Float) = Math.min(Math.max(x.toInt(), 0), home_screen_grid.width)
|
||||||
|
|
||||||
private fun getGridTouchedY(y: Float) = Math.min(Math.max(y.toInt() - home_screen_grid.marginTop, 0), home_screen_grid.height)
|
private fun getGridTouchedY(y: Float) = Math.min(Math.max(y.toInt(), 0), home_screen_grid.height)
|
||||||
|
|
||||||
fun showHomeIconMenu(x: Float, y: Float, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean) {
|
fun showHomeIconMenu(x: Float, y: Float, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean) {
|
||||||
mLongPressedIcon = gridItem
|
mLongPressedIcon = gridItem
|
||||||
|
|
|
@ -5,12 +5,15 @@ import android.content.Context
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
|
import android.graphics.Rect
|
||||||
import android.text.Layout
|
import android.text.Layout
|
||||||
import android.text.StaticLayout
|
import android.text.StaticLayout
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.simplemobiletools.commons.extensions.navigationBarHeight
|
||||||
|
import com.simplemobiletools.commons.extensions.statusBarHeight
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.launcher.R
|
import com.simplemobiletools.launcher.R
|
||||||
import com.simplemobiletools.launcher.extensions.getDrawableForPackageName
|
import com.simplemobiletools.launcher.extensions.getDrawableForPackageName
|
||||||
|
@ -39,6 +42,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Vie
|
||||||
private var gridCenters = ArrayList<Pair<Int, Int>>()
|
private var gridCenters = ArrayList<Pair<Int, Int>>()
|
||||||
private var draggedItemCurrentCoords = Pair(-1, -1)
|
private var draggedItemCurrentCoords = Pair(-1, -1)
|
||||||
|
|
||||||
|
var sideMargins = Rect() // apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides
|
||||||
|
|
||||||
init {
|
init {
|
||||||
textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply {
|
textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
color = Color.WHITE
|
color = Color.WHITE
|
||||||
|
@ -52,6 +57,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Vie
|
||||||
style = Paint.Style.STROKE
|
style = Paint.Style.STROKE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val sideMargin = context.resources.getDimension(R.dimen.normal_margin).toInt()
|
||||||
|
sideMargins.apply {
|
||||||
|
top = context.statusBarHeight
|
||||||
|
bottom = context.navigationBarHeight
|
||||||
|
left = sideMargin
|
||||||
|
right = sideMargin
|
||||||
|
}
|
||||||
|
|
||||||
fetchGridItems()
|
fetchGridItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +111,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Vie
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val center = gridCenters.minBy { Math.abs(it.first - x) + Math.abs(it.second - y) }
|
val center = gridCenters.minBy { Math.abs(it.first - x + sideMargins.left) + Math.abs(it.second - y + sideMargins.top) }
|
||||||
var redrawIcons = false
|
var redrawIcons = false
|
||||||
|
|
||||||
val gridCells = getClosestGridCells(center)
|
val gridCells = getClosestGridCells(center)
|
||||||
|
@ -159,12 +172,16 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Vie
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFakeWidth() = width - sideMargins.left - sideMargins.right
|
||||||
|
|
||||||
|
fun getFakeHeight() = height - sideMargins.top - sideMargins.bottom
|
||||||
|
|
||||||
@SuppressLint("DrawAllocation")
|
@SuppressLint("DrawAllocation")
|
||||||
override fun onDraw(canvas: Canvas) {
|
override fun onDraw(canvas: Canvas) {
|
||||||
super.onDraw(canvas)
|
super.onDraw(canvas)
|
||||||
if (rowXCoords.isEmpty()) {
|
if (rowXCoords.isEmpty()) {
|
||||||
rowWidth = width / (COLUMN_COUNT)
|
rowWidth = getFakeWidth() / COLUMN_COUNT
|
||||||
rowHeight = height / ROW_COUNT
|
rowHeight = getFakeHeight() / ROW_COUNT
|
||||||
iconSize = rowWidth - 2 * iconMargin
|
iconSize = rowWidth - 2 * iconMargin
|
||||||
for (i in 0 until COLUMN_COUNT) {
|
for (i in 0 until COLUMN_COUNT) {
|
||||||
rowXCoords.add(i, i * rowWidth)
|
rowXCoords.add(i, i * rowWidth)
|
||||||
|
@ -183,18 +200,19 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Vie
|
||||||
|
|
||||||
gridItems.filter { it.drawable != null }.forEach { item ->
|
gridItems.filter { it.drawable != null }.forEach { item ->
|
||||||
if (item.id != draggedItem?.id) {
|
if (item.id != draggedItem?.id) {
|
||||||
val drawableX = rowXCoords[item.left] + iconMargin
|
val drawableX = rowXCoords[item.left] + iconMargin + sideMargins.left
|
||||||
|
|
||||||
// icons at the bottom are drawn at the bottom of the grid and they have no label
|
// icons at the bottom are drawn at the bottom of the grid and they have no label
|
||||||
if (item.top == ROW_COUNT - 1) {
|
if (item.top == ROW_COUNT - 1) {
|
||||||
val drawableY = rowYCoords[item.top] + rowHeight - iconSize - iconMargin * 2
|
val drawableY = rowYCoords[item.top] + rowHeight - iconSize - iconMargin * 2 + sideMargins.top
|
||||||
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
||||||
} else {
|
} else {
|
||||||
val drawableY = rowYCoords[item.top] + iconSize / 2
|
val drawableY = rowYCoords[item.top] + iconSize / 2 + sideMargins.top
|
||||||
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
item.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
||||||
|
|
||||||
if (item.id != draggedItem?.id) {
|
if (item.id != draggedItem?.id) {
|
||||||
val textY = rowYCoords[item.top] + iconSize * 1.5f + labelSideMargin
|
val textX = rowXCoords[item.left].toFloat() + labelSideMargin + sideMargins.left
|
||||||
|
val textY = rowYCoords[item.top] + iconSize * 1.5f + labelSideMargin + sideMargins.top
|
||||||
val staticLayout = StaticLayout.Builder
|
val staticLayout = StaticLayout.Builder
|
||||||
.obtain(item.title, 0, item.title.length, textPaint, rowWidth - 2 * labelSideMargin)
|
.obtain(item.title, 0, item.title.length, textPaint, rowWidth - 2 * labelSideMargin)
|
||||||
.setMaxLines(2)
|
.setMaxLines(2)
|
||||||
|
@ -203,7 +221,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Vie
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
canvas.save()
|
canvas.save()
|
||||||
canvas.translate(rowXCoords[item.left].toFloat() + labelSideMargin, textY)
|
canvas.translate(textX, textY)
|
||||||
staticLayout.draw(canvas)
|
staticLayout.draw(canvas)
|
||||||
canvas.restore()
|
canvas.restore()
|
||||||
}
|
}
|
||||||
|
@ -215,30 +233,39 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Vie
|
||||||
|
|
||||||
if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) {
|
if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) {
|
||||||
// draw a circle under the current cell
|
// draw a circle under the current cell
|
||||||
val center = gridCenters.minBy { Math.abs(it.first - draggedItemCurrentCoords.first) + Math.abs(it.second - draggedItemCurrentCoords.second) }
|
val center =
|
||||||
|
gridCenters.minBy { Math.abs(it.first - draggedItemCurrentCoords.first + sideMargins.left) + Math.abs(it.second - draggedItemCurrentCoords.second + sideMargins.top) }
|
||||||
val gridCells = getClosestGridCells(center)
|
val gridCells = getClosestGridCells(center)
|
||||||
if (gridCells != null) {
|
if (gridCells != null) {
|
||||||
val shadowX = rowXCoords[gridCells.first] + iconMargin.toFloat() + iconSize / 2
|
val shadowX = rowXCoords[gridCells.first] + iconMargin.toFloat() + iconSize / 2 + sideMargins.left
|
||||||
val shadowY = if (gridCells.second == ROW_COUNT - 1) {
|
val shadowY = if (gridCells.second == ROW_COUNT - 1) {
|
||||||
rowYCoords[gridCells.second] + rowHeight - iconSize / 2 - iconMargin * 2
|
rowYCoords[gridCells.second] + rowHeight - iconSize / 2 - iconMargin * 2
|
||||||
} else {
|
} else {
|
||||||
rowYCoords[gridCells.second] + iconSize
|
rowYCoords[gridCells.second] + iconSize
|
||||||
}
|
} + sideMargins.top
|
||||||
|
|
||||||
canvas.drawCircle(shadowX, shadowY.toFloat(), iconSize / 2f, dragShadowCirclePaint)
|
canvas.drawCircle(shadowX, shadowY.toFloat(), iconSize / 2f, dragShadowCirclePaint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// show the app icon itself at dragging
|
// show the app icon itself at dragging, move it above the finger a bit to make it visible
|
||||||
val drawableX = draggedItemCurrentCoords.first - iconSize
|
val drawableX = (draggedItemCurrentCoords.first - iconSize / 1.5f).toInt()
|
||||||
val drawableY = draggedItemCurrentCoords.second - iconSize
|
val drawableY = (draggedItemCurrentCoords.second - iconSize / 1.2f).toInt()
|
||||||
draggedItem!!.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
draggedItem!!.drawable!!.setBounds(drawableX, drawableY, drawableX + iconSize, drawableY + iconSize)
|
||||||
draggedItem!!.drawable!!.draw(canvas)
|
draggedItem!!.drawable!!.draw(canvas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the clickable area around the icon, it includes text too
|
||||||
|
private fun getClickableRect(item: HomeScreenGridItem): Rect {
|
||||||
|
val debugLeft = item.left * rowWidth + sideMargins.left
|
||||||
|
val debugTop = rowYCoords[item.top] + iconSize / 3 + sideMargins.top
|
||||||
|
return Rect(debugLeft, debugTop, debugLeft + rowWidth, debugTop + iconSize * 2)
|
||||||
|
}
|
||||||
|
|
||||||
fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? {
|
fun isClickingGridItem(x: Int, y: Int): HomeScreenGridItem? {
|
||||||
for (gridItem in gridItems) {
|
for (gridItem in gridItems) {
|
||||||
if (x >= gridItem.left * rowWidth && x <= gridItem.right * rowWidth && y >= gridItem.top * rowHeight && y <= gridItem.bottom * rowHeight) {
|
val rect = getClickableRect(gridItem)
|
||||||
|
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
|
||||||
return gridItem
|
return gridItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
<com.simplemobiletools.launcher.views.HomeScreenGrid
|
<com.simplemobiletools.launcher.views.HomeScreenGrid
|
||||||
android:id="@+id/home_screen_grid"
|
android:id="@+id/home_screen_grid"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" />
|
||||||
android:layout_marginStart="@dimen/icon_side_margin"
|
|
||||||
android:layout_marginEnd="@dimen/icon_side_margin" />
|
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/all_apps_fragment"
|
android:id="@+id/all_apps_fragment"
|
||||||
|
|
Loading…
Reference in New Issue