Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78ccd5e3 authored by Mohammed Althaf T's avatar Mohammed Althaf T 😊
Browse files

SettingsLib: replace compose switch with our own

parent 8dbe674b
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ android_library {
        "androidx.window_window",
        "androidx.window_window",
        "com.google.android.material_material",
        "com.google.android.material_material",
        "lottie_compose",
        "lottie_compose",
        "elib",
    ],
    ],
    kotlincflags: [
    kotlincflags: [
        "-Xjvm-default=all",
        "-Xjvm-default=all",
+1 −3
Original line number Original line Diff line number Diff line
@@ -146,9 +146,7 @@ internal fun InternalSwitchPreference(
        SettingsSwitch(
        SettingsSwitch(
            checked = checked,
            checked = checked,
            changeable = { changeable },
            changeable = { changeable },
            // The onCheckedChange is handled on the whole SwitchPreference.
            onCheckedChange = onChangeWithLog,
            // DO NOT set it on SettingsSwitch.
            onCheckedChange = null,
            interactionSource = interactionSource,
            interactionSource = interactionSource,
        )
        )
    }
    }
+79 −32
Original line number Original line Diff line number Diff line
@@ -16,8 +16,20 @@


package com.android.settingslib.spa.widget.ui
package com.android.settingslib.spa.widget.ui


import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Close
@@ -25,11 +37,18 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Switch
import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
import androidx.compose.material3.SwitchDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.android.settingslib.spa.framework.compose.contentDescription
import com.android.settingslib.spa.framework.compose.contentDescription
import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled
import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled
import com.android.settingslib.spa.framework.util.wrapOnSwitchWithLog
import com.android.settingslib.spa.framework.util.wrapOnSwitchWithLog
import foundation.e.elib.R
import kotlin.math.roundToInt


@Composable
@Composable
internal fun SettingsSwitch(
internal fun SettingsSwitch(
@@ -40,48 +59,76 @@ internal fun SettingsSwitch(
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
) {
) {
    if (checked != null) {
    if (checked != null) {
        Switch(
        ESwitch(
            checked = checked,
            checked = checked,
            onCheckedChange = wrapOnSwitchWithLog(onCheckedChange),
            onCheckedChange = wrapOnSwitchWithLog(onCheckedChange),
            modifier = Modifier.contentDescription(contentDescription),
            enabled = changeable(),
            enabled = changeable(),
            interactionSource = interactionSource,
            interactionSource = interactionSource,
            thumbContent =
                if (isSpaExpressiveEnabled) {
                    if (checked) {
                        {
                            Icon(
                                imageVector = Icons.Filled.Check,
                                contentDescription = null,
                                modifier = Modifier.size(SwitchDefaults.IconSize),
        )
        )
                        }
                    } else {
                        {
                            Icon(
                                imageVector = Icons.Filled.Close,
                                contentDescription = null,
                                modifier = Modifier.size(SwitchDefaults.IconSize),
                            )
                        }
                    }
                } else null)
    } else {
    } else {
        Switch(
        ESwitch(
            checked = false,
            checked = false,
            onCheckedChange = null,
            onCheckedChange = null,
            enabled = false,
            enabled = false,
            interactionSource = interactionSource,
            interactionSource = interactionSource,
            thumbContent =
            if (isSpaExpressiveEnabled) {
                {
                    Icon(
                        imageVector = Icons.Filled.Close,
                        contentDescription = null,
                        modifier = Modifier.size(SwitchDefaults.IconSize),
        )
        )
    }
    }
            } else null
}

@Composable
fun ESwitch(
    checked: Boolean,
    onCheckedChange: ((newChecked: Boolean) -> Unit)? = null,
    enabled: Boolean,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
    val thumbSize = 24.dp
    val trackWidth = 52.dp
    val trackHeight = 28.dp
    val switchPadding = 2.dp

    val transition = updateTransition(targetState = checked, label = "switch")

    val thumbOffsetX by
    transition.animateDp(
        transitionSpec = {
            spring(
                dampingRatio = Spring.DampingRatioNoBouncy,
                stiffness = Spring.StiffnessMediumLow
            )
        },
        label = "Thumb offset"
    ) { state ->
        if (state) trackWidth - thumbSize - switchPadding else switchPadding
    }

    val trackColor = if (checked && enabled) colorResource(R.color.e_switch_track_on)
    else colorResource(R.color.e_switch_track_off)

    val thumbColor = if (checked && enabled) colorResource(R.color.e_switch_thumb_on)
    else colorResource(R.color.e_switch_thumb_off)

    Box(
        modifier =
        Modifier.width(trackWidth)
            .height(trackHeight)
            .clip(RoundedCornerShape(14.dp))
            .background(color = trackColor)
            .clickable(
                enabled = enabled,  // Handle whether switch can be clicked
                onClick = { onCheckedChange?.invoke(!checked) },
                interactionSource = interactionSource,
                indication = null
            )
    ) {
        Box(
            modifier =
            Modifier.size(thumbSize)
                .offset {
                    IntOffset(thumbOffsetX.roundToPx(), switchPadding.toPx().roundToInt())
                }
                .clip(CircleShape)
                .background(color = thumbColor)
        )
        )
    }
    }
}
}