parent
0d1b6fa33b
commit
f1b606d8e4
@ -10,7 +10,6 @@ import androidx.compose.foundation.lazy.items
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.key
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||||
@ -25,7 +24,7 @@ import de.mm20.launcher2.ui.ktx.toDp
|
|||||||
@Composable
|
@Composable
|
||||||
fun AppWidgetList(
|
fun AppWidgetList(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
widgets: List<AppWidgetProviderInfo>,
|
widgets: List<AppWidgetGroup>,
|
||||||
onWidgetSelected: (AppWidgetProviderInfo) -> Unit = {}
|
onWidgetSelected: (AppWidgetProviderInfo) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@ -33,8 +32,20 @@ fun AppWidgetList(
|
|||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
) {
|
) {
|
||||||
items(widgets) {
|
for (group in widgets) {
|
||||||
key(it.provider.toShortString()) {
|
item() {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(
|
||||||
|
top = 16.dp,
|
||||||
|
start = 8.dp,
|
||||||
|
end = 8.dp,
|
||||||
|
bottom = 8.dp
|
||||||
|
),
|
||||||
|
text = group.appName,
|
||||||
|
style = MaterialTheme.typography.titleLarge
|
||||||
|
)
|
||||||
|
}
|
||||||
|
items(group.widgets) {
|
||||||
LauncherCard(
|
LauncherCard(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
@ -81,10 +92,6 @@ fun AppWidgetList(
|
|||||||
modifier = mod
|
modifier = mod
|
||||||
) {
|
) {
|
||||||
drawIntoCanvas {
|
drawIntoCanvas {
|
||||||
val aspectRatio =
|
|
||||||
image.intrinsicWidth / image.intrinsicHeight
|
|
||||||
|
|
||||||
|
|
||||||
image.setBounds(
|
image.setBounds(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -106,5 +113,6 @@ fun AppWidgetList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,12 +10,16 @@ import androidx.activity.compose.setContent
|
|||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.ArrowBack
|
||||||
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import de.mm20.launcher2.ui.MdcLauncherTheme
|
import de.mm20.launcher2.ui.MdcLauncherTheme
|
||||||
|
import de.mm20.launcher2.ui.R
|
||||||
import de.mm20.launcher2.ui.base.BaseActivity
|
import de.mm20.launcher2.ui.base.BaseActivity
|
||||||
import de.mm20.launcher2.ui.base.ProvideSettings
|
import de.mm20.launcher2.ui.base.ProvideSettings
|
||||||
|
|
||||||
@ -27,6 +31,7 @@ class PickAppWidgetActivity : BaseActivity() {
|
|||||||
private lateinit var appWidgetManager: AppWidgetManager
|
private lateinit var appWidgetManager: AppWidgetManager
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
widgetHost = AppWidgetHost(this, 44203)
|
widgetHost = AppWidgetHost(this, 44203)
|
||||||
@ -37,24 +42,44 @@ class PickAppWidgetActivity : BaseActivity() {
|
|||||||
setContent {
|
setContent {
|
||||||
MdcLauncherTheme {
|
MdcLauncherTheme {
|
||||||
ProvideSettings {
|
ProvideSettings {
|
||||||
val available by availableWidgets.observeAsState()
|
Scaffold(
|
||||||
val selected by selectedAppWidget.observeAsState()
|
topBar = {
|
||||||
val widgets = available
|
CenterAlignedTopAppBar(
|
||||||
if (selected == null) {
|
title = {
|
||||||
if (widgets != null) {
|
Text(stringResource(R.string.widget_add_widget))
|
||||||
AppWidgetList(
|
},
|
||||||
modifier = Modifier.fillMaxSize(),
|
navigationIcon = {
|
||||||
widgets = widgets,
|
IconButton(onClick = { finish() }) {
|
||||||
onWidgetSelected = {
|
Icon(
|
||||||
selectAppWidget(it)
|
imageVector = Icons.Rounded.ArrowBack,
|
||||||
|
contentDescription = stringResource(
|
||||||
|
id = R.string.menu_back
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
Box(
|
) {
|
||||||
modifier = Modifier.fillMaxSize(),
|
val available by availableWidgets.observeAsState()
|
||||||
contentAlignment = Alignment.Center
|
val selected by selectedAppWidget.observeAsState()
|
||||||
) {
|
val widgets = available
|
||||||
CircularProgressIndicator()
|
if (selected == null) {
|
||||||
|
if (widgets != null) {
|
||||||
|
AppWidgetList(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
widgets = widgets,
|
||||||
|
onWidgetSelected = {
|
||||||
|
selectAppWidget(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,14 +3,24 @@ package de.mm20.launcher2.ui.launcher.widgets.picker
|
|||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.appwidget.AppWidgetProviderInfo
|
import android.appwidget.AppWidgetProviderInfo
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import androidx.compose.ui.text.toLowerCase
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.liveData
|
import androidx.lifecycle.liveData
|
||||||
|
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class PickAppWidgetVM: ViewModel() {
|
typealias AppWidgetGroup = Pair<String, List<AppWidgetProviderInfo>>
|
||||||
|
|
||||||
|
inline val AppWidgetGroup.appName: String
|
||||||
|
get() = this.first
|
||||||
|
inline val AppWidgetGroup.widgets: List<AppWidgetProviderInfo>
|
||||||
|
get() = this.second
|
||||||
|
|
||||||
|
class PickAppWidgetVM : ViewModel() {
|
||||||
var appWidgetId: MutableLiveData<Int?> = MutableLiveData(null)
|
var appWidgetId: MutableLiveData<Int?> = MutableLiveData(null)
|
||||||
val selectedAppWidget: MutableLiveData<AppWidgetProviderInfo?> = MutableLiveData(null)
|
val selectedAppWidget: MutableLiveData<AppWidgetProviderInfo?> = MutableLiveData(null)
|
||||||
|
|
||||||
@ -19,11 +29,24 @@ class PickAppWidgetVM: ViewModel() {
|
|||||||
this.selectedAppWidget.value = appWidget
|
this.selectedAppWidget.value = appWidget
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAvailableWidgets(context: Context): LiveData<List<AppWidgetProviderInfo>?> = liveData {
|
fun getAvailableWidgets(context: Context): LiveData<List<AppWidgetGroup>?> = liveData {
|
||||||
emit(null)
|
emit(null)
|
||||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
val widgets = withContext(Dispatchers.IO) {
|
val widgets = withContext(Dispatchers.IO) {
|
||||||
appWidgetManager.installedProviders.sortedBy { it.loadLabel(context.packageManager) }
|
appWidgetManager.installedProviders
|
||||||
|
.sortedBy { it.loadLabel(context.packageManager).lowercase() }
|
||||||
|
.groupBy {
|
||||||
|
val pkg = it.provider.packageName
|
||||||
|
val appInfo = try {
|
||||||
|
context.packageManager.getApplicationInfo(pkg, 0)
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
CrashReporter.logException(e)
|
||||||
|
return@groupBy ""
|
||||||
|
}
|
||||||
|
appInfo.loadLabel(context.packageManager).toString()
|
||||||
|
}
|
||||||
|
.toList()
|
||||||
|
.sortedBy { it.first.lowercase() }
|
||||||
}
|
}
|
||||||
emit(widgets)
|
emit(widgets)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user