Initial implementation Drag pref group

This commit is contained in:
MrSluffy
2024-07-27 20:13:52 +08:00
parent cb99d8f4e5
commit 291f716b97
5 changed files with 185 additions and 34 deletions
@@ -80,30 +80,36 @@ class LawnchairOverviewActionsView @JvmOverloads constructor(
prefs.recentsActionScreenshot.subscribeChanges(this, ::updateVisibilities)
prefs.recentsActionShare.subscribeChanges(this, ::updateVisibilities)
prefs.recentsActionLocked.subscribeChanges(this, ::updateVisibilities)
prefs.recentActionOrder.subscribeChanges(this, ::updateVisibilities)
updateVisibilities()
}
private fun updateVisibilities() {
val buttons = mutableListOf<View>()
val order = prefs.recentActionOrder.get().split(",").map { it.toInt() }
val buttonMap = mutableMapOf<Int, View>()
if (prefs.recentsActionScreenshot.get() && !isOnePlusStock) {
buttons.add(screenshotAction)
buttonMap[0] = screenshotAction
}
if (prefs.recentsActionShare.get()) {
buttons.add(shareAction)
buttonMap[1] = shareAction
}
if (prefs.recentsActionLens.get() && isLensAvailable()) {
buttons.add(lensAction)
buttonMap[2] = lensAction
}
if (prefs.recentsActionLocked.get()) {
buttons.add(lockedAction)
buttonMap[3] = lockedAction
}
if (prefs.recentsActionClearAll.get()) {
buttons.add(clearAllAction)
buttonMap[4] = clearAllAction
}
val buttonsInOrder = order.mapNotNull { buttonMap[it] }
container.removeAllViews()
container.addView(createSpace())
buttons.forEach { view ->
buttonsInOrder.forEach { view ->
view.isVisible = true
container.addView(view)
container.addView(createSpace())
@@ -66,6 +66,8 @@ class PreferenceManager private constructor(private val context: Context) : Base
override fun unflattenValue(value: String) = value
}
val recentActionOrder = StringPref("pref_recentActionOrder", "0,1,2,3,4", recreate)
private val fontCache = FontCache.INSTANCE.get(context)
val fontWorkspace = FontPref("pref_workspaceFont", fontCache.uiText, recreate)
val fontHeading = FontPref("pref_fontHeading", fontCache.uiRegular, recreate)
@@ -0,0 +1,116 @@
package app.lawnchair.ui.preferences.components.layout
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Divider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import app.lawnchair.preferences.BasePreferenceManager
import kotlin.math.roundToInt
import kotlinx.coroutines.runBlocking
@Composable
fun DraggablePreferenceGroup(
pref: BasePreferenceManager.StringPref,
items: List<@Composable () -> Unit>,
modifier: Modifier = Modifier,
heading: String? = null,
description: String? = null,
showDescription: Boolean = true,
showDividers: Boolean = true,
dividerStartIndent: Dp = 16.dp,
dividerEndIndent: Dp = 16.dp,
) {
var order by remember {
mutableStateOf(
pref.get().split(",").map { it.toInt() }
?: items.indices.toList(),
)
}
var draggingItemIndex by remember { mutableStateOf<Int?>(null) }
var draggingOffset by remember { mutableFloatStateOf(0f) }
fun saveOrder(order: List<Int>) {
runBlocking {
pref.set(order.joinToString(","))
}
}
Column(
modifier = modifier,
) {
PreferenceGroupHeading(heading)
Surface(
modifier = Modifier.padding(horizontal = 16.dp),
shape = MaterialTheme.shapes.large,
tonalElevation = 1.dp,
) {
if (showDividers) {
Column {
order.forEachIndexed { index, itemIndex ->
val isDragging = draggingItemIndex == index
Box(
modifier = Modifier
.offset { IntOffset(0, if (isDragging) draggingOffset.roundToInt() else 0) }
.draggable(
state = rememberDraggableState { delta ->
if (isDragging) {
draggingOffset += delta
}
},
orientation = Orientation.Vertical,
onDragStarted = {
draggingItemIndex = index
draggingOffset = 0f
},
onDragStopped = {
draggingItemIndex?.let {
val newIndex = (index + (draggingOffset / 100).roundToInt()).coerceIn(0, order.lastIndex)
order = order.toMutableList().apply {
add(newIndex, removeAt(it))
}
saveOrder(order)
}
draggingItemIndex = null
draggingOffset = 0f
},
),
) {
items[itemIndex]()
}
if (index != order.lastIndex) {
Divider(
Modifier
.padding(start = dividerStartIndent, end = dividerEndIndent),
)
}
}
}
} else {
Column {
items.forEach { item ->
Box {
item()
}
}
}
}
}
PreferenceGroupDescription(description = description, showDescription = showDescription)
}
}
@@ -44,11 +44,6 @@ fun ExperimentalFeaturesPreferences(
label = stringResource(id = R.string.always_reload_icons_label),
description = stringResource(id = R.string.always_reload_icons_description),
)
SwitchPreference(
adapter = prefs.recentsActionLocked.getAdapter(),
label = stringResource(id = R.string.recents_lock_unlock),
description = stringResource(id = R.string.recents_lock_unlock_description),
)
}
}
}
@@ -18,6 +18,7 @@ import app.lawnchair.preferences2.preferenceManager2
import app.lawnchair.ui.preferences.components.controls.SliderPreference
import app.lawnchair.ui.preferences.components.controls.SwitchPreference
import app.lawnchair.ui.preferences.components.controls.WarningPreference
import app.lawnchair.ui.preferences.components.layout.DraggablePreferenceGroup
import app.lawnchair.ui.preferences.components.layout.ExpandAndShrink
import app.lawnchair.ui.preferences.components.layout.PreferenceGroup
import app.lawnchair.ui.preferences.components.layout.PreferenceLayout
@@ -37,6 +38,52 @@ fun QuickstepPreferences(
context.packageManager.getLaunchIntentForPackage("com.google.ar.lens") != null
}
val screenshotPreference: @Composable () -> Unit = {
if (!isOnePlusStock) {
SwitchPreference(
adapter = prefs.recentsActionScreenshot.getAdapter(),
label = stringResource(id = R.string.action_screenshot),
)
}
}
val lockUnlockPreference: @Composable () -> Unit = {
SwitchPreference(
adapter = prefs.recentsActionLocked.getAdapter(),
label = stringResource(id = R.string.recents_lock_unlock),
description = stringResource(id = R.string.recents_lock_unlock_description),
)
}
val sharePreference: @Composable () -> Unit = {
SwitchPreference(
adapter = prefs.recentsActionShare.getAdapter(),
label = stringResource(id = R.string.action_share),
)
}
val lensPreference: @Composable () -> Unit = {
if (lensAvailable) {
SwitchPreference(
adapter = prefs.recentsActionLens.getAdapter(),
label = stringResource(id = R.string.action_lens),
)
}
}
val clearAllPreference: @Composable () -> Unit = {
SwitchPreference(
adapter = prefs.recentsActionClearAll.getAdapter(),
label = stringResource(id = R.string.recents_clear_all),
)
}
val items = listOf(
screenshotPreference,
lockUnlockPreference,
sharePreference,
lensPreference,
clearAllPreference,
)
PreferenceLayout(
label = stringResource(id = R.string.quickstep_label),
modifier = modifier,
@@ -58,28 +105,13 @@ fun QuickstepPreferences(
)
}
}
PreferenceGroup(heading = stringResource(id = R.string.recents_actions_label)) {
if (!isOnePlusStock) {
SwitchPreference(
adapter = prefs.recentsActionScreenshot.getAdapter(),
label = stringResource(id = R.string.action_screenshot),
)
}
SwitchPreference(
adapter = prefs.recentsActionShare.getAdapter(),
label = stringResource(id = R.string.action_share),
)
if (lensAvailable) {
SwitchPreference(
adapter = prefs.recentsActionLens.getAdapter(),
label = stringResource(id = R.string.action_lens),
)
}
SwitchPreference(
adapter = prefs.recentsActionClearAll.getAdapter(),
label = stringResource(id = R.string.recents_clear_all),
)
}
DraggablePreferenceGroup(
heading = stringResource(id = R.string.recents_actions_label),
items = items,
pref = prefs.recentActionOrder,
)
val overrideWindowCornerRadius by prefs.overrideWindowCornerRadius.observeAsState()
PreferenceGroup(
heading = stringResource(id = R.string.window_corner_radius_label),