mirror of
https://github.com/jrpie/Launcher.git
synced 2025-06-30 12:55:30 +02:00
fix #162 - place new widgets in free area if possible
This commit is contained in:
parent
30e9fcd20f
commit
33ccea8cbc
2 changed files with 60 additions and 15 deletions
|
@ -17,9 +17,12 @@ import de.jrpie.android.launcher.databinding.ActivityManageWidgetsBinding
|
||||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||||
import de.jrpie.android.launcher.ui.UIObject
|
import de.jrpie.android.launcher.ui.UIObject
|
||||||
import de.jrpie.android.launcher.widgets.AppWidget
|
import de.jrpie.android.launcher.widgets.AppWidget
|
||||||
|
import de.jrpie.android.launcher.widgets.GRID_SIZE
|
||||||
import de.jrpie.android.launcher.widgets.WidgetPanel
|
import de.jrpie.android.launcher.widgets.WidgetPanel
|
||||||
import de.jrpie.android.launcher.widgets.WidgetPosition
|
import de.jrpie.android.launcher.widgets.WidgetPosition
|
||||||
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
// http://coderender.blogspot.com/2012/01/hosting-android-widgets-my.html
|
// http://coderender.blogspot.com/2012/01/hosting-android-widgets-my.html
|
||||||
|
@ -143,14 +146,12 @@ class ManageWidgetsActivity : UIObject, Activity() {
|
||||||
|
|
||||||
val display = windowManager.defaultDisplay
|
val display = windowManager.defaultDisplay
|
||||||
|
|
||||||
val position = WidgetPosition.fromAbsoluteRect(
|
val widgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId)
|
||||||
Rect(
|
|
||||||
0, 0,
|
val position = WidgetPosition.findFreeSpace(
|
||||||
min(400, appWidgetManager.getAppWidgetInfo(appWidgetId).minWidth),
|
WidgetPanel.byId(panelId),
|
||||||
min(400, appWidgetManager.getAppWidgetInfo(appWidgetId).minHeight)
|
max(3, (GRID_SIZE * (widgetInfo.minWidth) / display.width.toFloat()).roundToInt()),
|
||||||
),
|
max(3, (GRID_SIZE * (widgetInfo.minHeight) / display.height.toFloat()).roundToInt())
|
||||||
display.width,
|
|
||||||
display.height
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val widget = AppWidget(appWidgetId, position, panelId, provider)
|
val widget = AppWidget(appWidgetId, position, panelId, provider)
|
||||||
|
|
|
@ -11,9 +11,20 @@ const val GRID_SIZE: Short = 12
|
||||||
@Serializable
|
@Serializable
|
||||||
data class WidgetPosition(var x: Short, var y: Short, var width: Short, var height: Short) {
|
data class WidgetPosition(var x: Short, var y: Short, var width: Short, var height: Short) {
|
||||||
|
|
||||||
|
constructor(rect: Rect) : this(
|
||||||
|
rect.left.toShort(),
|
||||||
|
rect.top.toShort(),
|
||||||
|
(rect.right - rect.left).toShort(),
|
||||||
|
(rect.bottom - rect.top).toShort()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun toRect(): Rect {
|
||||||
|
return Rect(x.toInt(), y.toInt(), x + width, y + height)
|
||||||
|
}
|
||||||
|
|
||||||
fun getAbsoluteRect(screenWidth: Int, screenHeight: Int): Rect {
|
fun getAbsoluteRect(screenWidth: Int, screenHeight: Int): Rect {
|
||||||
val gridWidth = screenWidth / GRID_SIZE.toFloat()
|
val gridWidth = screenWidth / GRID_SIZE.toFloat()
|
||||||
val gridHeight= screenHeight / GRID_SIZE.toFloat()
|
val gridHeight = screenHeight / GRID_SIZE.toFloat()
|
||||||
|
|
||||||
return Rect(
|
return Rect(
|
||||||
(x * gridWidth).toInt(),
|
(x * gridWidth).toInt(),
|
||||||
|
@ -23,25 +34,33 @@ data class WidgetPosition(var x: Short, var y: Short, var width: Short, var heig
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromAbsoluteRect(absolute: Rect, screenWidth: Int, screenHeight: Int): WidgetPosition {
|
fun fromAbsoluteRect(absolute: Rect, screenWidth: Int, screenHeight: Int): WidgetPosition {
|
||||||
val gridWidth = screenWidth / GRID_SIZE.toFloat()
|
val gridWidth = screenWidth / GRID_SIZE.toFloat()
|
||||||
val gridHeight= screenHeight / GRID_SIZE.toFloat()
|
val gridHeight = screenHeight / GRID_SIZE.toFloat()
|
||||||
|
|
||||||
val x = (absolute.left / gridWidth).roundToInt().toShort().coerceIn(0, (GRID_SIZE-1).toShort())
|
val x = (absolute.left / gridWidth).roundToInt().toShort()
|
||||||
val y = (absolute.top / gridHeight).roundToInt().toShort().coerceIn(0, (GRID_SIZE-1).toShort())
|
.coerceIn(0, (GRID_SIZE - 1).toShort())
|
||||||
|
val y = (absolute.top / gridHeight).roundToInt().toShort()
|
||||||
|
.coerceIn(0, (GRID_SIZE - 1).toShort())
|
||||||
|
|
||||||
|
|
||||||
val w = max(2, ((absolute.right - absolute.left) / gridWidth).roundToInt()).toShort()
|
val w = max(2, ((absolute.right - absolute.left) / gridWidth).roundToInt()).toShort()
|
||||||
val h = max(2, ((absolute.bottom - absolute.top) / gridHeight).roundToInt()).toShort()
|
val h = max(2, ((absolute.bottom - absolute.top) / gridHeight).roundToInt()).toShort()
|
||||||
|
|
||||||
return WidgetPosition(x,y,w,h)
|
return WidgetPosition(x, y, w, h)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun center(minWidth: Int, minHeight: Int, screenWidth: Int, screenHeight: Int): WidgetPosition {
|
fun center(
|
||||||
|
minWidth: Int,
|
||||||
|
minHeight: Int,
|
||||||
|
screenWidth: Int,
|
||||||
|
screenHeight: Int
|
||||||
|
): WidgetPosition {
|
||||||
val gridWidth = screenWidth / GRID_SIZE.toFloat()
|
val gridWidth = screenWidth / GRID_SIZE.toFloat()
|
||||||
val gridHeight= screenHeight / GRID_SIZE.toFloat()
|
val gridHeight = screenHeight / GRID_SIZE.toFloat()
|
||||||
|
|
||||||
val cellsWidth = ceil(minWidth / gridWidth).toInt().toShort()
|
val cellsWidth = ceil(minWidth / gridWidth).toInt().toShort()
|
||||||
val cellsHeight = ceil(minHeight / gridHeight).toInt().toShort()
|
val cellsHeight = ceil(minHeight / gridHeight).toInt().toShort()
|
||||||
|
@ -52,7 +71,32 @@ data class WidgetPosition(var x: Short, var y: Short, var width: Short, var heig
|
||||||
cellsWidth,
|
cellsWidth,
|
||||||
cellsHeight
|
cellsHeight
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findFreeSpace(
|
||||||
|
widgetPanel: WidgetPanel?,
|
||||||
|
minWidth: Int,
|
||||||
|
minHeight: Int
|
||||||
|
): WidgetPosition {
|
||||||
|
val rect = Rect(0, 0, minWidth, minHeight)
|
||||||
|
if (widgetPanel == null) {
|
||||||
|
return WidgetPosition(rect)
|
||||||
|
}
|
||||||
|
|
||||||
|
val widgets = widgetPanel.getWidgets().map { it.position.toRect() }
|
||||||
|
|
||||||
|
for (x in 0..<GRID_SIZE - minWidth) {
|
||||||
|
rect.left = x
|
||||||
|
rect.right = x + minWidth
|
||||||
|
for (y in 0..<GRID_SIZE - minHeight) {
|
||||||
|
rect.top = y
|
||||||
|
rect.bottom = y + minHeight
|
||||||
|
if (!widgets.any { Rect(it).intersect(rect) }) {
|
||||||
|
return WidgetPosition(rect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return WidgetPosition(0, 0, minWidth.toShort(), minHeight.toShort())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue