From dffe704039d28d17d1767adc8de88b4c5bdb6381 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sun, 30 Jun 2024 15:38:42 +0200 Subject: [PATCH] feat(graphing): automatically select distinct function names, e.g. f(x), g(x), ... --- .../net/youapps/calcyou/data/graphing/Defaults.kt | 1 + .../net/youapps/calcyou/data/graphing/EvalConfig.kt | 1 - .../net/youapps/calcyou/data/graphing/Function.kt | 5 +++-- .../calcyou/ui/components/AddNewFunctionDialog.kt | 10 +++++++--- .../calcyou/ui/screens/graphing/GraphingScreen.kt | 9 +++++++-- .../net/youapps/calcyou/viewmodels/GraphViewModel.kt | 11 +++++++---- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/net/youapps/calcyou/data/graphing/Defaults.kt b/app/src/main/java/net/youapps/calcyou/data/graphing/Defaults.kt index b5ff60b..d87bcb4 100644 --- a/app/src/main/java/net/youapps/calcyou/data/graphing/Defaults.kt +++ b/app/src/main/java/net/youapps/calcyou/data/graphing/Defaults.kt @@ -45,6 +45,7 @@ object Defaults { ) val defaultVarNameChars: Set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$".toCharArray().toSet() + val defaultFuncNameChars: List = "fghijklmnopqrstuvw".toList() fun getDefaultGenericFunctions(): Map { return mapOf( diff --git a/app/src/main/java/net/youapps/calcyou/data/graphing/EvalConfig.kt b/app/src/main/java/net/youapps/calcyou/data/graphing/EvalConfig.kt index e680b44..17753d2 100644 --- a/app/src/main/java/net/youapps/calcyou/data/graphing/EvalConfig.kt +++ b/app/src/main/java/net/youapps/calcyou/data/graphing/EvalConfig.kt @@ -82,6 +82,5 @@ class EvalConfiguration( this.varNameChars = Defaults.defaultVarNameChars this.genericConstants = Defaults.defaultGenericConstants.toMutableMap() this.genericFunctions = Defaults.getDefaultGenericFunctions().toMutableMap() - } } \ No newline at end of file diff --git a/app/src/main/java/net/youapps/calcyou/data/graphing/Function.kt b/app/src/main/java/net/youapps/calcyou/data/graphing/Function.kt index e86ebe6..52887a1 100644 --- a/app/src/main/java/net/youapps/calcyou/data/graphing/Function.kt +++ b/app/src/main/java/net/youapps/calcyou/data/graphing/Function.kt @@ -5,14 +5,15 @@ import androidx.compose.ui.graphics.Color class Function( val expression: String, val color: Color, + val name: String, val function: (Float) -> Float? ) { companion object { - fun create(expression: String, color: Color): Function { + fun create(expression: String, color: Color, functionName: String): Function { val compiled: CompiledExpression = Evaluator.compile(expression) return Function( - expression, color + expression, color, functionName ) { value -> compiled.execute("x" to value.toDouble())?.toFloat() } diff --git a/app/src/main/java/net/youapps/calcyou/ui/components/AddNewFunctionDialog.kt b/app/src/main/java/net/youapps/calcyou/ui/components/AddNewFunctionDialog.kt index a5900e2..1b6d688 100644 --- a/app/src/main/java/net/youapps/calcyou/ui/components/AddNewFunctionDialog.kt +++ b/app/src/main/java/net/youapps/calcyou/ui/components/AddNewFunctionDialog.kt @@ -39,6 +39,7 @@ import net.youapps.calcyou.viewmodels.GraphViewModel @Composable fun AddNewFunctionDialog( graphViewModel: GraphViewModel, + functionName: String, initialExpression: String, initialColor: Color, onDismissRequest: () -> Unit @@ -46,13 +47,14 @@ fun AddNewFunctionDialog( Dialog(onDismissRequest) { DialogContent( onConfirm = { expression, color -> - graphViewModel.addFunction(expression, color) + graphViewModel.addFunction(expression, color, functionName) onDismissRequest() }, onCancel = onDismissRequest, checkExpression = graphViewModel::checkExpression, isError = graphViewModel.isError, errorMessage = graphViewModel.errorText, + functionName = functionName, initialExpression = initialExpression, initialColor = initialColor ) @@ -67,6 +69,7 @@ private fun DialogContent( checkExpression: (String) -> Unit, isError: Boolean, errorMessage: String, + functionName: String, initialExpression: String = "", initialColor: Color = rainbowColors.first(), ) { @@ -92,7 +95,7 @@ private fun DialogContent( isError = isError, prefix = { Text( - text = "f(x) = ", style = TextStyle( + text = "${functionName}(x) = ", style = TextStyle( fontFamily = FontFamily.Serif, fontWeight = FontWeight.Medium, fontSize = MaterialTheme.typography.bodyLarge.fontSize, @@ -149,6 +152,7 @@ private fun DialogContentPreview() { onCancel = {}, checkExpression = {}, isError = true, - errorMessage = "Invalid token at index 0" + errorMessage = "Invalid token at index 0", + functionName = "f" ) } \ No newline at end of file diff --git a/app/src/main/java/net/youapps/calcyou/ui/screens/graphing/GraphingScreen.kt b/app/src/main/java/net/youapps/calcyou/ui/screens/graphing/GraphingScreen.kt index 76152d3..f849f13 100644 --- a/app/src/main/java/net/youapps/calcyou/ui/screens/graphing/GraphingScreen.kt +++ b/app/src/main/java/net/youapps/calcyou/ui/screens/graphing/GraphingScreen.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel +import net.youapps.calcyou.data.graphing.Defaults import net.youapps.calcyou.data.graphing.Function import net.youapps.calcyou.ui.components.AddNewFunctionDialog import net.youapps.calcyou.viewmodels.GraphViewModel @@ -82,6 +83,9 @@ fun GraphingScreen(graphViewModel: GraphViewModel = viewModel()) { graphViewModel.updateSelectedFunction(-1) showAddFunctionDialog = false }, + functionName = remember(graphViewModel.selectedFunctionIndex) { graphViewModel.functionName }.ifEmpty { + Defaults.defaultFuncNameChars[graphViewModel.functions.size % Defaults.defaultFuncNameChars.size].toString() + }, initialColor = remember(graphViewModel.selectedFunctionIndex) { graphViewModel.functionColor }, initialExpression = @@ -100,6 +104,7 @@ fun FunctionList( Column(modifier = modifier) { functions.forEachIndexed { index, function -> FunctionRow( + functionName = function.name, text = function.expression, color = function.color, onClick = { onClickFunction(index) }, @@ -112,7 +117,7 @@ fun FunctionList( } @Composable -fun FunctionRow(text: String, color: Color, onClick: () -> Unit, onClickRemove: () -> Unit) { +fun FunctionRow(functionName: String, text: String, color: Color, onClick: () -> Unit, onClickRemove: () -> Unit) { Row( modifier = Modifier .fillMaxWidth() @@ -122,7 +127,7 @@ fun FunctionRow(text: String, color: Color, onClick: () -> Unit, onClickRemove: ) { Text( - text = "f(x) = ", style = TextStyle( + text = "${functionName}(x) = ", style = TextStyle( fontFamily = FontFamily.Serif, fontWeight = FontWeight.Bold, fontSize = MaterialTheme.typography.titleMedium.fontSize, diff --git a/app/src/main/java/net/youapps/calcyou/viewmodels/GraphViewModel.kt b/app/src/main/java/net/youapps/calcyou/viewmodels/GraphViewModel.kt index 15c33f1..8e9d21f 100644 --- a/app/src/main/java/net/youapps/calcyou/viewmodels/GraphViewModel.kt +++ b/app/src/main/java/net/youapps/calcyou/viewmodels/GraphViewModel.kt @@ -18,7 +18,7 @@ import java.text.ParseException import kotlin.random.Random class GraphViewModel(private val application: Application) : AndroidViewModel(application) { - val context: Context + private val context: Context get() = application.applicationContext var window by mutableStateOf(Window(), neverEqualPolicy()) val functions = mutableStateListOf() @@ -30,6 +30,8 @@ class GraphViewModel(private val application: Application) : AndroidViewModel(ap var selectedFunctionIndex by mutableIntStateOf(-1) private set + var functionName by mutableStateOf("") + var functionColor by mutableStateOf(Color.Red) var expression by mutableStateOf("") @@ -41,6 +43,7 @@ class GraphViewModel(private val application: Application) : AndroidViewModel(ap return } val function = functions[index] + functionName = function.name functionColor = function.color expression = function.expression } @@ -64,13 +67,13 @@ class GraphViewModel(private val application: Application) : AndroidViewModel(ap } } - fun addFunction(expression: String, color: Color) { + fun addFunction(expression: String, color: Color, functionName: String) { if (selectedFunctionIndex != -1) { - functions[selectedFunctionIndex] = Function.create(expression, color) + functions[selectedFunctionIndex] = Function.create(expression, color, functionName) updateSelectedFunction(-1) return } - functions.add(Function.create(expression, color)) + functions.add(Function.create(expression, color, functionName)) } fun removeFunction(index: Int) {