diff options
| author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-12-18 14:58:25 +0330 | 
|---|---|---|
| committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-12-18 14:58:25 +0330 | 
| commit | 9313767a800f16e01a05c577183b5e6399c3f76d (patch) | |
| tree | 8bca2a5c5e409c73e59c56880f23f6e3c32efb55 /app/src/main | |
| parent | 5a670d6cae41d77280a98936f2baddf31f069656 (diff) | |
great appreciations to https://github.com/hadibolty/ for reporting bugs, a lot of bugs got fixed
Diffstat (limited to 'app/src/main')
6 files changed, 224 insertions, 38 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8d7bca4..74b91e0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@      xmlns:tools="http://schemas.android.com/tools">      <application +        android:name="com.a404m.calculator.ContextHelper"          android:allowBackup="true"          android:dataExtractionRules="@xml/data_extraction_rules"          android:fullBackupContent="@xml/backup_rules" diff --git a/app/src/main/java/com/a404m/calculator/ContextHelper.kt b/app/src/main/java/com/a404m/calculator/ContextHelper.kt new file mode 100644 index 0000000..4e5e3fc --- /dev/null +++ b/app/src/main/java/com/a404m/calculator/ContextHelper.kt @@ -0,0 +1,19 @@ +package com.a404m.calculator + +import android.app.Application +import android.content.Context + +class ContextHelper : Application() { +    companion object { +        var context: Context? = null + +        fun getAppContext(): Context? { +            return context +        } +    } + +    override fun onCreate() { +        super.onCreate() +        context = applicationContext +    } +}
\ No newline at end of file diff --git a/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt b/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt index c6a10da..4384448 100644 --- a/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt +++ b/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt @@ -4,98 +4,148 @@ import com.a404m.calculator.util.MathHelper  data class CalcButtonModel(      val text: String, -    val weight:Float = 1F, +    val weight: Float = 1F,      val op: (expression: String) -> String,  ) {      companion object {          val K_0 = CalcButtonModel(              text = "0",              op = { -                it + '0' +                addNumber( +                    it, +                    '0' +                )              }          )          val K_1 = CalcButtonModel(              text = "1",              op = { -                it + '1' +                addNumber( +                    it, +                    '1' +                )              }          )          val K_2 = CalcButtonModel(              text = "2",              op = { -                it + '2' +                addNumber( +                    it, +                    '2' +                )              }          )          val K_3 = CalcButtonModel(              text = "3",              op = { -                it + '3' +                addNumber( +                    it, +                    '3' +                )              }          )          val K_4 = CalcButtonModel(              text = "4",              op = { -                it + '4' +                addNumber( +                    it, +                    '4' +                )              }          )          val K_5 = CalcButtonModel(              text = "5",              op = { -                it + '5' +                addNumber( +                    it, +                    '5' +                )              }          )          val K_6 = CalcButtonModel(              text = "6",              op = { -                it + '6' +                addNumber( +                    it, +                    '6' +                )              }          )          val K_7 = CalcButtonModel(              text = "7",              op = { -                it + '7' +                addNumber( +                    it, +                    '7' +                )              }          )          val K_8 = CalcButtonModel(              text = "8",              op = { -                it + '8' +                addNumber( +                    it, +                    '8' +                )              }          )          val K_9 = CalcButtonModel(              text = "9",              op = { -                it + '9' +                addNumber( +                    it, +                    '9' +                )              }          )          val K_PLUS = CalcButtonModel(              text = "+",              op = { -                it + '+' +                addOperator( +                    it, +                    '+', +                    true +                )              }          )          val K_MINUS = CalcButtonModel(              text = "-",              op = { -                it + '-' +                addOperator( +                    it, +                    '-', +                    true +                )              }          )          val K_MULTIPLY = CalcButtonModel(              text = "×",              op = { -                it + '×' +                addOperator( +                    it, +                    '×', +                    false +                )              }          )          val K_DIVISION = CalcButtonModel(              text = "÷",              op = { -                it + '÷' +                addOperator( +                    it, +                    '÷', +                    false +                )              }          )          val K_REMINDER = CalcButtonModel(              text = "%",              op = { -                it + '%' +                addOperator( +                    it, +                    '%', +                    false +                )              }          )          val K_EQUAL = CalcButtonModel( @@ -107,20 +157,25 @@ data class CalcButtonModel(          val K_DOT = CalcButtonModel(              text = ".",              op = { -                it + '.' +                when (MathHelper.getInWriting(it)) { +                    MathHelper.InWriting.NONE -> "0." +                    MathHelper.InWriting.NUMBER_INT -> "$it." +                    MathHelper.InWriting.NUMBER_FLOAT -> it +                    MathHelper.InWriting.OPERATOR -> "${it}0." +                }              }          )          val K_C = CalcButtonModel(              text = "C",              op = { -                "" +                "0"              }          )          val K_BACKSPACE = CalcButtonModel(              text = "⌫",              op = {                  if (it.length <= 1) { -                    "" +                    "0"                  } else {                      it.substring(                          0, @@ -135,5 +190,50 @@ data class CalcButtonModel(                  it              }          ) + +        private fun addOperator( +            expression: String, +            operator: Char, +            canBePrefix: Boolean +        ): String { +            return if (expression == "0") { +                if (canBePrefix) operator.toString() +                else expression + operator +            } else { +                when (MathHelper.getInWriting(expression)) { +                    MathHelper.InWriting.NONE -> +                        if (canBePrefix) operator.toString() +                        else "" + +                    MathHelper.InWriting.NUMBER_INT -> +                        expression + operator + +                    MathHelper.InWriting.NUMBER_FLOAT -> +                        if (expression.last() == '.') "${expression}0$operator" +                        else expression + operator + +                    MathHelper.InWriting.OPERATOR -> expression.substring( +                        0, +                        expression.length - 1 +                    ) + operator +                } +            } +        } + +        private fun addNumber( +            expression: String, +            number: Char +        ): String { +            val value = MathHelper.getLastNumber(expression) + +            return if (value == "0") { +                expression.substring( +                    0, +                    expression.length - 1 +                ) + number +            } else { +                expression + number +            } +        }      }  } diff --git a/app/src/main/java/com/a404m/calculator/ui/page/Home.kt b/app/src/main/java/com/a404m/calculator/ui/page/Home.kt index ba9a21e..a2c4846 100644 --- a/app/src/main/java/com/a404m/calculator/ui/page/Home.kt +++ b/app/src/main/java/com/a404m/calculator/ui/page/Home.kt @@ -34,7 +34,7 @@ import com.a404m.calculator.ui.util.CalcGrid  @Composable  fun HomePage(modifier: Modifier = Modifier) {      var expression by rememberSaveable { -        mutableStateOf("") +        mutableStateOf("0")      }      Scaffold(          modifier = modifier, diff --git a/app/src/main/java/com/a404m/calculator/ui/util/Toast.kt b/app/src/main/java/com/a404m/calculator/ui/util/Toast.kt new file mode 100644 index 0000000..5041472 --- /dev/null +++ b/app/src/main/java/com/a404m/calculator/ui/util/Toast.kt @@ -0,0 +1,12 @@ +package com.a404m.calculator.ui.util + +import android.widget.Toast +import com.a404m.calculator.ContextHelper + +fun showToast(text:String){ +    Toast.makeText( +        ContextHelper.context, +        text, +        Toast.LENGTH_SHORT +    ).show() +}
\ No newline at end of file diff --git a/app/src/main/java/com/a404m/calculator/util/MathHelper.kt b/app/src/main/java/com/a404m/calculator/util/MathHelper.kt index d0c3ee3..77244b0 100644 --- a/app/src/main/java/com/a404m/calculator/util/MathHelper.kt +++ b/app/src/main/java/com/a404m/calculator/util/MathHelper.kt @@ -1,9 +1,13 @@  package com.a404m.calculator.util  import android.util.Log +import com.a404m.calculator.ui.util.showToast  import com.a404m.calculator.util.MathHelper.Operator.Kind +import java.math.BigDecimal  import java.nio.charset.UnsupportedCharsetException +typealias MathNumberType = BigDecimal +  object MathHelper {      private val operatorStrings = arrayOf(          '+', @@ -44,35 +48,35 @@ object MathHelper {          '+',          Kind.INFIX,          { -            Operand(it.first().value+it.last().value) +            Operand(it.first().value + it.last().value)          }      )      private val sub = Operator(          '-',          Kind.INFIX,          { -            Operand(it.first().value-it.last().value) +            Operand(it.first().value - it.last().value)          }      )      private val mul = Operator(          '×',          Kind.INFIX,          { -            Operand(it.first().value*it.last().value) +            Operand(it.first().value * it.last().value)          }      )      private val div = Operator(          '÷',          Kind.INFIX,          { -            Operand(it.first().value/it.last().value) +            Operand(it.first().value / it.last().value)          }      )      private val rem = Operator(          '%',          Kind.INFIX,          { -            Operand(it.first().value%it.last().value) +            Operand(it.first().value % it.last().value)          }      )      private val operatorOrders = arrayOf( @@ -104,7 +108,8 @@ object MathHelper {          return try {              parse(lex(expression)).eval().toString()          } catch (e: Exception) { -            e.message ?: "Exception" +            showToast(e.message ?: "Exception") +            expression          }      } @@ -114,7 +119,7 @@ object MathHelper {                  break              }              var i = -1 -            while(++i < lexed.size) { +            while (++i < lexed.size) {                  val item = lexed[i]                  if (item is BasicOperator) {                      var op = item.toOperator( @@ -175,7 +180,7 @@ object MathHelper {                              value = expression.substring(                                  start,                                  i -                            ).toDouble() +                            ).toBigDecimal()                          )                      )                      --i @@ -198,7 +203,7 @@ object MathHelper {      private class Operator(          val operator: Char,          val kind: Kind, -        val operate: (operands:List<Operand>)-> Operand, +        val operate: (operands: List<Operand>) -> Operand,          val operands: ArrayList<Any> = arrayListOf(),      ) {          fun cloneWithoutOperands(): Operator { @@ -223,14 +228,14 @@ object MathHelper {                  "A404M",                  "eval: $operator $operands"              ) -            if(operandSize() != operands.size){ +            if (operandSize() != operands.size) {                  throw UnsupportedOperationException("Not enough operands")              }              val evaledOperands = operands.map { -                if(it is Operator){ +                if (it is Operator) {                      it.eval() -                }else{ +                } else {                      it as Operand                  }              } @@ -277,7 +282,7 @@ object MathHelper {              )              val right = rightItem is Operand || rightItem is Operator -            val k:Kind +            val k: Kind              if (left) {                  if (right) { @@ -302,13 +307,62 @@ object MathHelper {      }      private class Operand( -        val value: Double, -    ){ +        val value: MathNumberType, +    ) {          override fun toString(): String { -            if(value % 1 == 0.0){ -                return "%.0f".format(value) +            var str = value.toString() +            if(str.contains('.')){ +                while (str.last() == '0'){ +                    str = str.removeRange(str.length-1,str.length) +                } +                if(str.last() == '.'){ +                    str = str.removeRange(str.length-1,str.length) +                } +            } +            return str +        } +    } + +    enum class InWriting { +        NONE, +        NUMBER_INT, +        NUMBER_FLOAT, +        OPERATOR, +    } + +    fun getInWriting(expression: String): InWriting { +        return when (expression.lastOrNull()) { +            in operatorStrings -> InWriting.OPERATOR +            in numberStrings -> { +                var i = expression.length +                var hasDot = false +                while (--i >= 0 && expression[i] in numberStrings) { +                    if (expression[i] == '.') { +                        hasDot = true +                    } +                } + +                if (hasDot) InWriting.NUMBER_FLOAT +                else InWriting.NUMBER_INT              } -            return value.toString() + +            else -> InWriting.NONE +        } +    } + +    fun getLastNumber(expression: String): String? { +        return when (expression.lastOrNull()) { +            in numberStrings -> { +                var i = expression.length +                var number = "" +                while (--i >= 0 && expression[i] in numberStrings) { +                    number = "${expression[i]}$number" +                } + +                number +            } + +            else -> null          }      }  }
\ No newline at end of file  |