package com.rizoma.trazo import android.content.Context import android.content.Intent import android.os.Bundle import android.provider.Settings import android.view.inputmethod.InputMethodManager import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.view.WindowCompat import androidx.lifecycle.lifecycleScope import com.rizoma.trazo.data.HapticLevel import com.rizoma.trazo.data.TrazoSettings import com.rizoma.trazo.ui.theme.NeonCian import com.rizoma.trazo.ui.theme.NeonRosa import com.rizoma.trazo.ui.theme.NeonVerde import com.rizoma.trazo.ui.theme.Tecla import com.rizoma.trazo.ui.theme.Tenue import com.rizoma.trazo.ui.theme.TrazoTheme import com.rizoma.trazo.ui.theme.Vacio /** Pantalla para activar Trazo, elegirlo como teclado y ajustar sus preferencias. */ class MainActivity : ComponentActivity() { private lateinit var settings: TrazoSettings override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) settings = TrazoSettings(this, lifecycleScope) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { TrazoTheme { Setup( settings = settings, onActivar = { startActivity(Intent(Settings.ACTION_INPUT_METHOD_SETTINGS)) }, onElegir = { (getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) .showInputMethodPicker() }, ) } } } } @Composable private fun Setup(settings: TrazoSettings, onActivar: () -> Unit, onElegir: () -> Unit) { Column( Modifier .fillMaxSize() .background(Vacio) .verticalScroll(rememberScrollState()) .padding(horizontal = 32.dp, vertical = 56.dp), ) { Text("Trazo", color = NeonVerde, fontSize = 44.sp, fontWeight = FontWeight.Light) Spacer(Modifier.height(8.dp)) Text("teclado de trazos — un toque, ocho gestos.", color = Tenue, fontSize = 15.sp) Spacer(Modifier.height(36.dp)) Paso("1", "activa Trazo en ajustes del sistema", NeonCian, onActivar) Spacer(Modifier.height(16.dp)) Paso("2", "elígelo como teclado actual", NeonRosa, onElegir) Spacer(Modifier.height(40.dp)) Seccion("ajustes") Spacer(Modifier.height(12.dp)) Toggle("vibración al teclear", settings.haptics, NeonCian) { settings.setHaptics(it) } if (settings.haptics) { Spacer(Modifier.height(10.dp)) NivelHaptico(settings.hapticLevel) { settings.setHapticLevel(it) } } Spacer(Modifier.height(10.dp)) Toggle("doble espacio → punto", settings.doubleSpacePeriod, NeonVerde) { settings.setDoubleSpacePeriod(it) } Spacer(Modifier.height(24.dp)) Seccion("idiomas de predicción") Spacer(Modifier.height(12.dp)) Toggle("español", settings.spanish, NeonRosa) { settings.setSpanish(it) } Spacer(Modifier.height(10.dp)) Toggle("inglés", settings.english, NeonCian) { settings.setEnglish(it) } } } @Composable private fun Seccion(titulo: String) { Text(titulo, color = Tenue, fontSize = 13.sp, fontWeight = FontWeight.Medium) } @Composable private fun Paso(num: String, label: String, accent: Color, onClick: () -> Unit) { Column( Modifier .fillMaxWidth() .clip(RoundedCornerShape(18.dp)) .background(Tecla) .border(1.dp, accent.copy(alpha = 0.4f), RoundedCornerShape(18.dp)) .clickable(onClick = onClick) .padding(20.dp), ) { Text(num, color = accent, fontSize = 13.sp, fontWeight = FontWeight.Bold) Spacer(Modifier.height(6.dp)) Text(label, color = Color.White, fontSize = 17.sp) } } @Composable private fun Toggle(label: String, value: Boolean, accent: Color, onChange: (Boolean) -> Unit) { Row( Modifier .fillMaxWidth() .clip(RoundedCornerShape(14.dp)) .background(Tecla) .clickable { onChange(!value) } .padding(horizontal = 18.dp, vertical = 16.dp), verticalAlignment = Alignment.CenterVertically, ) { Text(label, color = Color.White, fontSize = 16.sp, modifier = Modifier.weight(1f)) Pill(value, accent) } } /** Indicador tipo interruptor: relleno y a la derecha cuando está activo. */ @Composable private fun Pill(on: Boolean, accent: Color) { Box( Modifier .width(46.dp) .height(26.dp) .clip(RoundedCornerShape(13.dp)) .background(if (on) accent.copy(alpha = 0.28f) else Color(0xFF1B1B26)) .border(1.dp, if (on) accent else Tenue, RoundedCornerShape(13.dp)), contentAlignment = if (on) Alignment.CenterEnd else Alignment.CenterStart, ) { Box( Modifier .padding(3.dp) .width(20.dp) .height(20.dp) .clip(RoundedCornerShape(10.dp)) .background(if (on) accent else Tenue), ) } } @Composable private fun NivelHaptico(level: HapticLevel, onSelect: (HapticLevel) -> Unit) { Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) { HapticLevel.entries.forEach { opt -> val selected = opt == level Box( Modifier .weight(1f) .clip(RoundedCornerShape(12.dp)) .background(if (selected) NeonCian.copy(alpha = 0.18f) else Tecla) .border( 1.dp, if (selected) NeonCian else Tenue.copy(alpha = 0.4f), RoundedCornerShape(12.dp), ) .clickable { onSelect(opt) } .padding(vertical = 12.dp), contentAlignment = Alignment.Center, ) { Text( text = opt.name.lowercase(), color = if (selected) NeonCian else Tenue, fontSize = 14.sp, ) } } } }