1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-11-08 12:02:33 +01:00

Test out enabled state

This commit is contained in:
Allan Wang 2023-06-22 15:39:23 -07:00
parent 09bb021e66
commit 4e9672c078
No known key found for this signature in database
GPG Key ID: C93E3F9C679D7A56
5 changed files with 181 additions and 61 deletions

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 Allan Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.pitchedapps.frost.compose.settings
/**
* Basic state container for settings.
*
* Allows for getting and assigning values. It is expected that assigning values will cause
* recompositions as needed.
*/
interface SettingState<T> {
val enabled: Boolean
var value: T
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2023 Allan Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.pitchedapps.frost.compose.settings
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Switch
import androidx.compose.runtime.Composable
fun SettingsContentScope.checkbox(state: SettingState<Boolean>): SettingsContent =
object : SettingsContent {
override fun onClick() {
state.value = !state.value
}
@Composable
override fun compose() {
Checkbox(
enabled = state.enabled,
checked = state.value,
onCheckedChange = { state.value = it },
)
}
}
fun SettingsContentScope.switch(
state: SettingState<Boolean>,
): SettingsContent =
object : SettingsContent {
override fun onClick() {
state.value = !state.value
}
@Composable
override fun compose() {
Switch(
enabled = state.enabled,
checked = state.value,
onCheckedChange = { state.value = it },
)
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright 2023 Allan Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.pitchedapps.frost.compose.settings
import androidx.compose.foundation.layout.LayoutScopeMarker
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@LayoutScopeMarker
interface SettingsContentScope {
@Composable
fun <T, R> T.rememberSetting(
enabler: T.() -> Boolean = { true },
getter: T.() -> R,
setter: T.(R) -> Unit
): SettingState<R> {
return remember(this) {
object : SettingState<R> {
override val enabled: Boolean
get() = enabler()
override var value: R
get() = getter()
set(value) {
setter(value)
}
}
}
}
@Composable
fun <T> MutableState<T>.asSettingState(): SettingState<T> {
return remember(this) {
object : SettingState<T> {
override val enabled: Boolean = true
override var value: T by this@asSettingState
}
}
}
}
interface SettingsContent {
fun onClick()
@Composable fun compose()
}

View File

@ -17,22 +17,16 @@
package com.pitchedapps.frost.compose.settings
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.LayoutScopeMarker
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material3.Checkbox as MaterialCheckbox
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
@ -90,67 +84,14 @@ private fun SettingsListItemPreview() {
private object SettingsContentScopeImpl : SettingsContentScope
@LayoutScopeMarker
interface SettingsContentScope {
@Composable
fun <T, R> T.rememberSetting(getter: T.() -> R, setter: T.(R) -> Unit): SettingState<R> {
return remember(this) {
object : SettingState<R> {
override var value: R
get() = getter()
set(value) {
setter(value)
}
}
}
}
@Composable
fun <T> MutableState<T>.asSettingState(): SettingState<T> {
return remember(this) {
object : SettingState<T> {
override var value: T by this@asSettingState
}
}
}
}
interface SettingsContent {
fun onClick()
@Composable fun compose()
}
private class SettingsContentClickOnly(private val action: () -> Unit) : SettingsContent {
override fun onClick() {
action()
}
@Composable final override fun compose() = Unit
}
@Stable
interface SettingState<T> {
var value: T
@Composable override fun compose() = Unit
}
fun SettingsContentScope.click(action: () -> Unit): SettingsContent =
SettingsContentClickOnly(action)
fun SettingsContentScope.checkbox(state: SettingState<Boolean>): SettingsContent =
object : SettingsContent {
override fun onClick() {
state.value = !state.value
}
@Composable
override fun compose() {
MaterialCheckbox(
checked = state.value,
onCheckedChange = { state.value = it },
)
}
}

View File

@ -32,7 +32,11 @@ import androidx.compose.ui.tooling.preview.Preview
@Composable
fun SettingsScreenPreview() {
data class Model(val check1: Boolean = false)
data class Model(
val check1: Boolean = false,
val switch1: Boolean = false,
val switch2: Boolean = false,
)
var state by remember { mutableStateOf(Model()) }
@ -63,6 +67,32 @@ fun SettingsScreenPreview() {
)
}
},
{
SettingsListItem(
title = "Switch 1",
) {
switch(
state.rememberSetting(
getter = { state.switch1 },
setter = { state = state.copy(switch1 = it) },
),
)
}
},
{
SettingsListItem(
title = "Switch 2",
description = "Enabled by switch 1",
) {
switch(
state.rememberSetting(
enabler = { state.switch1 },
getter = { state.switch2 },
setter = { state = state.copy(switch2 = it) },
),
)
}
},
)
}