Skip to content

Commit

Permalink
Initial implementation Drag pref group
Browse files Browse the repository at this point in the history
  • Loading branch information
MrSluffy committed Jul 27, 2024
1 parent cb99d8f commit 291f716
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
2 changes: 2 additions & 0 deletions lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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),
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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),
Expand Down

0 comments on commit 291f716

Please sign in to comment.