handle storing and redrawing widgets
This commit is contained in:
parent
e83aef8d9d
commit
5fca4ff4f1
|
@ -34,6 +34,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
private var textPaint: TextPaint
|
private var textPaint: TextPaint
|
||||||
private var dragShadowCirclePaint: Paint
|
private var dragShadowCirclePaint: Paint
|
||||||
private var draggedItem: HomeScreenGridItem? = null
|
private var draggedItem: HomeScreenGridItem? = null
|
||||||
|
private var isFirstDraw = true
|
||||||
|
|
||||||
// let's use a 6x5 grid for now with 1 special row at the bottom, prefilled with default apps
|
// let's use a 6x5 grid for now with 1 special row at the bottom, prefilled with default apps
|
||||||
private var rowXCoords = ArrayList<Int>(COLUMN_COUNT)
|
private var rowXCoords = ArrayList<Int>(COLUMN_COUNT)
|
||||||
|
@ -236,25 +237,17 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
if (areAllCellsEmpty) {
|
if (areAllCellsEmpty) {
|
||||||
val infoList = AppWidgetManager.getInstance(context).installedProviders
|
val widgetItem = draggedItem!!.copy()
|
||||||
val appWidgetProviderInfo = infoList.firstOrNull { it.provider.shortClassName == draggedItem?.shortClassName }
|
widgetItem.apply {
|
||||||
if (appWidgetProviderInfo != null) {
|
left = widgetRect.left
|
||||||
val appWidgetHost = AppWidgetHost(context, WIDGET_HOST_ID)
|
top = widgetRect.top
|
||||||
val appWidgetId = appWidgetHost.allocateAppWidgetId()
|
right = widgetRect.right
|
||||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
bottom = widgetRect.bottom
|
||||||
val canCreateWidget = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, appWidgetProviderInfo.provider)
|
}
|
||||||
if (canCreateWidget) {
|
|
||||||
if (appWidgetProviderInfo.configure != null) {
|
bindWidget(widgetItem, false)
|
||||||
appWidgetHost.startAppWidgetConfigureActivityForResult(context as MainActivity, appWidgetId, 0, REQUEST_CONFIGURE_WIDGET, null)
|
ensureBackgroundThread {
|
||||||
} else {
|
context.homeScreenGridItemsDB.insert(widgetItem)
|
||||||
val widgetView = appWidgetHost.createView(context, appWidgetId, appWidgetProviderInfo)
|
|
||||||
widgetView.x = widgetRect.left * rowWidth + sideMargins.left.toFloat()
|
|
||||||
widgetView.y = widgetRect.top * rowHeight + sideMargins.top.toFloat()
|
|
||||||
val widgetWidth = draggedItem!!.widthCells * rowWidth
|
|
||||||
val widgetHeight = draggedItem!!.heightCells * rowHeight
|
|
||||||
addView(widgetView, widgetWidth, widgetHeight)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
performHapticFeedback()
|
performHapticFeedback()
|
||||||
|
@ -266,6 +259,29 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
redrawGrid()
|
redrawGrid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun bindWidget(item: HomeScreenGridItem, isInitialDrawAfterLaunch: Boolean) {
|
||||||
|
val infoList = AppWidgetManager.getInstance(context).installedProviders
|
||||||
|
val appWidgetProviderInfo = infoList.firstOrNull { it.provider.shortClassName == item.shortClassName }
|
||||||
|
if (appWidgetProviderInfo != null) {
|
||||||
|
val appWidgetHost = AppWidgetHost(context, WIDGET_HOST_ID)
|
||||||
|
val appWidgetId = appWidgetHost.allocateAppWidgetId()
|
||||||
|
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
|
val canCreateWidget = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, appWidgetProviderInfo.provider)
|
||||||
|
if (canCreateWidget) {
|
||||||
|
if (appWidgetProviderInfo.configure != null && !isInitialDrawAfterLaunch) {
|
||||||
|
appWidgetHost.startAppWidgetConfigureActivityForResult(context as MainActivity, appWidgetId, 0, REQUEST_CONFIGURE_WIDGET, null)
|
||||||
|
} else {
|
||||||
|
val widgetView = appWidgetHost.createView(context, appWidgetId, appWidgetProviderInfo)
|
||||||
|
widgetView.x = item.left * rowWidth + sideMargins.left.toFloat()
|
||||||
|
widgetView.y = item.top * rowHeight + sideMargins.top.toFloat()
|
||||||
|
val widgetWidth = item.widthCells * rowWidth
|
||||||
|
val widgetHeight = item.heightCells * rowHeight
|
||||||
|
addView(widgetView, widgetWidth, widgetHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// convert stuff like 102x192 to grid cells like 0x1
|
// convert stuff like 102x192 to grid cells like 0x1
|
||||||
private fun getClosestGridCells(center: Pair<Int, Int>): Pair<Int, Int>? {
|
private fun getClosestGridCells(center: Pair<Int, Int>): Pair<Int, Int>? {
|
||||||
rowXCoords.forEachIndexed { xIndex, xCell ->
|
rowXCoords.forEachIndexed { xIndex, xCell ->
|
||||||
|
@ -280,8 +296,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun redrawGrid() {
|
private fun redrawGrid() {
|
||||||
setWillNotDraw(false)
|
post {
|
||||||
invalidate()
|
setWillNotDraw(false)
|
||||||
|
invalidate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFakeWidth() = width - sideMargins.left - sideMargins.right
|
private fun getFakeWidth() = width - sideMargins.left - sideMargins.right
|
||||||
|
@ -310,7 +328,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gridItems.filter { it.drawable != null }.forEach { item ->
|
gridItems.filter { it.drawable != null && it.type == ITEM_TYPE_ICON }.forEach { item ->
|
||||||
if (item.id != draggedItem?.id) {
|
if (item.id != draggedItem?.id) {
|
||||||
val drawableX = rowXCoords[item.left] + iconMargin + sideMargins.left
|
val drawableX = rowXCoords[item.left] + iconMargin + sideMargins.left
|
||||||
|
|
||||||
|
@ -343,6 +361,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFirstDraw) {
|
||||||
|
gridItems.filter { it.type == ITEM_TYPE_WIDGET }.forEach { item ->
|
||||||
|
bindWidget(item, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) {
|
if (draggedItem != null && draggedItemCurrentCoords.first != -1 && draggedItemCurrentCoords.second != -1) {
|
||||||
if (draggedItem!!.type == ITEM_TYPE_ICON || draggedItem!!.type == ITEM_TYPE_SHORTCUT) {
|
if (draggedItem!!.type == ITEM_TYPE_ICON || draggedItem!!.type == ITEM_TYPE_SHORTCUT) {
|
||||||
// draw a circle under the current cell
|
// draw a circle under the current cell
|
||||||
|
@ -368,35 +392,40 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
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)
|
||||||
} else if (draggedItem!!.type == ITEM_TYPE_WIDGET) {
|
} else if (draggedItem!!.type == ITEM_TYPE_WIDGET) {
|
||||||
val center = gridCenters.minBy {
|
// at first draw we are loading the widget from the database at some exact spot, not dragging it
|
||||||
Math.abs(it.first - draggedItemCurrentCoords.first + sideMargins.left) + Math.abs(it.second - draggedItemCurrentCoords.second + sideMargins.top)
|
if (!isFirstDraw) {
|
||||||
}
|
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 widgetRect = getWidgetOccupiedRect(gridCells)
|
val widgetRect = getWidgetOccupiedRect(gridCells)
|
||||||
val leftSide = widgetRect.left * rowWidth + sideMargins.left + iconMargin.toFloat()
|
val leftSide = widgetRect.left * rowWidth + sideMargins.left + iconMargin.toFloat()
|
||||||
val topSide = widgetRect.top * rowHeight + sideMargins.top + iconMargin.toFloat()
|
val topSide = widgetRect.top * rowHeight + sideMargins.top + iconMargin.toFloat()
|
||||||
val rightSide = leftSide + draggedItem!!.widthCells * rowWidth - sideMargins.right - iconMargin.toFloat()
|
val rightSide = leftSide + draggedItem!!.widthCells * rowWidth - sideMargins.right - iconMargin.toFloat()
|
||||||
val bottomSide = topSide + draggedItem!!.heightCells * rowHeight - sideMargins.top
|
val bottomSide = topSide + draggedItem!!.heightCells * rowHeight - sideMargins.top
|
||||||
canvas.drawRoundRect(leftSide, topSide, rightSide, bottomSide, roundedCornerRadius, roundedCornerRadius, dragShadowCirclePaint)
|
canvas.drawRoundRect(leftSide, topSide, rightSide, bottomSide, roundedCornerRadius, roundedCornerRadius, dragShadowCirclePaint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// show the widget preview itself at dragging
|
// show the widget preview itself at dragging
|
||||||
val drawable = draggedItem!!.drawable!!
|
val drawable = draggedItem!!.drawable!!
|
||||||
val aspectRatio = drawable.minimumHeight / drawable.minimumWidth.toFloat()
|
val aspectRatio = drawable.minimumHeight / drawable.minimumWidth.toFloat()
|
||||||
val drawableX = (draggedItemCurrentCoords.first - drawable.minimumWidth / 2f).toInt()
|
val drawableX = (draggedItemCurrentCoords.first - drawable.minimumWidth / 2f).toInt()
|
||||||
val drawableY = (draggedItemCurrentCoords.second - drawable.minimumHeight / 3f).toInt()
|
val drawableY = (draggedItemCurrentCoords.second - drawable.minimumHeight / 3f).toInt()
|
||||||
val drawableWidth = draggedItem!!.widthCells * rowWidth - iconMargin * (draggedItem!!.widthCells - 1)
|
val drawableWidth = draggedItem!!.widthCells * rowWidth - iconMargin * (draggedItem!!.widthCells - 1)
|
||||||
drawable.setBounds(
|
drawable.setBounds(
|
||||||
drawableX,
|
drawableX,
|
||||||
drawableY,
|
drawableY,
|
||||||
drawableX + drawableWidth,
|
drawableX + drawableWidth,
|
||||||
(drawableY + drawableWidth * aspectRatio).toInt()
|
(drawableY + drawableWidth * aspectRatio).toInt()
|
||||||
)
|
)
|
||||||
drawable.draw(canvas)
|
drawable.draw(canvas)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isFirstDraw = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the clickable area around the icon, it includes text too
|
// get the clickable area around the icon, it includes text too
|
||||||
|
|
Loading…
Reference in New Issue