├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml └── runConfigurations.xml ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── codewithcal │ │ └── au │ │ └── calculatorappexample │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── codewithcal │ │ │ └── au │ │ │ └── calculatorappexample │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── codewithcal │ └── au │ └── calculatorappexample │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 20 | 21 | 22 | 23 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | xmlns:android 32 | 33 | ^$ 34 | 35 | 36 | 37 |
38 |
39 | 40 | 41 | 42 | xmlns:.* 43 | 44 | ^$ 45 | 46 | 47 | BY_NAME 48 | 49 |
50 |
51 | 52 | 53 | 54 | .*:id 55 | 56 | http://schemas.android.com/apk/res/android 57 | 58 | 59 | 60 |
61 |
62 | 63 | 64 | 65 | .*:name 66 | 67 | http://schemas.android.com/apk/res/android 68 | 69 | 70 | 71 |
72 |
73 | 74 | 75 | 76 | name 77 | 78 | ^$ 79 | 80 | 81 | 82 |
83 |
84 | 85 | 86 | 87 | style 88 | 89 | ^$ 90 | 91 | 92 | 93 |
94 |
95 | 96 | 97 | 98 | .* 99 | 100 | ^$ 101 | 102 | 103 | BY_NAME 104 | 105 |
106 |
107 | 108 | 109 | 110 | .* 111 | 112 | http://schemas.android.com/apk/res/android 113 | 114 | 115 | ANDROID_ATTRIBUTE_ORDER 116 | 117 |
118 |
119 | 120 | 121 | 122 | .* 123 | 124 | .* 125 | 126 | 127 | BY_NAME 128 | 129 |
130 |
131 |
132 |
133 |
134 |
-------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | 6 | defaultConfig { 7 | applicationId "codewithcal.au.calculatorappexample" 8 | minSdkVersion 19 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | } 15 | 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(dir: "libs", include: ["*.jar"]) 26 | implementation 'androidx.appcompat:appcompat:1.2.0' 27 | implementation 'androidx.constraintlayout:constraintlayout:2.0.1' 28 | implementation 'io.apisense:rhino-android:1.0' 29 | testImplementation 'junit:junit:4.12' 30 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 31 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 32 | 33 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/codewithcal/au/calculatorappexample/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package codewithcal.au.calculatorappexample; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("codewithcal.au.calculatorappexample", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/codewithcal/au/calculatorappexample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package codewithcal.au.calculatorappexample; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.TextView; 8 | import android.widget.Toast; 9 | 10 | import java.util.ArrayList; 11 | 12 | import javax.script.ScriptEngine; 13 | import javax.script.ScriptEngineManager; 14 | import javax.script.ScriptException; 15 | 16 | public class MainActivity extends AppCompatActivity 17 | { 18 | 19 | TextView workingsTV; 20 | TextView resultsTV; 21 | 22 | String workings = ""; 23 | String formula = ""; 24 | String tempFormula = ""; 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) 28 | { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_main); 31 | initTextViews(); 32 | } 33 | 34 | private void initTextViews() 35 | { 36 | workingsTV = (TextView)findViewById(R.id.workingsTextView); 37 | resultsTV = (TextView)findViewById(R.id.resultTextView); 38 | } 39 | 40 | private void setWorkings(String givenValue) 41 | { 42 | workings = workings + givenValue; 43 | workingsTV.setText(workings); 44 | } 45 | 46 | 47 | public void equalsOnClick(View view) 48 | { 49 | Double result = null; 50 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino"); 51 | checkForPowerOf(); 52 | 53 | try { 54 | result = (double)engine.eval(formula); 55 | } catch (ScriptException e) 56 | { 57 | Toast.makeText(this, "Invalid Input", Toast.LENGTH_SHORT).show(); 58 | } 59 | 60 | if(result != null) 61 | resultsTV.setText(String.valueOf(result.doubleValue())); 62 | 63 | } 64 | 65 | private void checkForPowerOf() 66 | { 67 | ArrayList indexOfPowers = new ArrayList<>(); 68 | for(int i = 0; i < workings.length(); i++) 69 | { 70 | if (workings.charAt(i) == '^') 71 | indexOfPowers.add(i); 72 | } 73 | 74 | formula = workings; 75 | tempFormula = workings; 76 | for(Integer index: indexOfPowers) 77 | { 78 | changeFormula(index); 79 | } 80 | formula = tempFormula; 81 | } 82 | 83 | private void changeFormula(Integer index) 84 | { 85 | String numberLeft = ""; 86 | String numberRight = ""; 87 | 88 | for(int i = index + 1; i< workings.length(); i++) 89 | { 90 | if(isNumeric(workings.charAt(i))) 91 | numberRight = numberRight + workings.charAt(i); 92 | else 93 | break; 94 | } 95 | 96 | for(int i = index - 1; i >= 0; i--) 97 | { 98 | if(isNumeric(workings.charAt(i))) 99 | numberLeft = numberLeft + workings.charAt(i); 100 | else 101 | break; 102 | } 103 | 104 | String original = numberLeft + "^" + numberRight; 105 | String changed = "Math.pow("+numberLeft+","+numberRight+")"; 106 | tempFormula = tempFormula.replace(original,changed); 107 | } 108 | 109 | private boolean isNumeric(char c) 110 | { 111 | if((c <= '9' && c >= '0') || c == '.') 112 | return true; 113 | 114 | return false; 115 | } 116 | 117 | 118 | public void clearOnClick(View view) 119 | { 120 | workingsTV.setText(""); 121 | workings = ""; 122 | resultsTV.setText(""); 123 | leftBracket = true; 124 | } 125 | 126 | boolean leftBracket = true; 127 | 128 | public void bracketsOnClick(View view) 129 | { 130 | if(leftBracket) 131 | { 132 | setWorkings("("); 133 | leftBracket = false; 134 | } 135 | else 136 | { 137 | setWorkings(")"); 138 | leftBracket = true; 139 | } 140 | } 141 | 142 | public void powerOfOnClick(View view) 143 | { 144 | setWorkings("^"); 145 | } 146 | 147 | public void divisionOnClick(View view) 148 | { 149 | setWorkings("/"); 150 | } 151 | 152 | public void sevenOnClick(View view) 153 | { 154 | setWorkings("7"); 155 | } 156 | 157 | public void eightOnClick(View view) 158 | { 159 | setWorkings("8"); 160 | } 161 | 162 | public void nineOnClick(View view) 163 | { 164 | setWorkings("9"); 165 | } 166 | 167 | public void timesOnClick(View view) 168 | { 169 | setWorkings("*"); 170 | } 171 | 172 | public void fourOnClick(View view) 173 | { 174 | setWorkings("4"); 175 | } 176 | 177 | public void fiveOnClick(View view) 178 | { 179 | setWorkings("5"); 180 | } 181 | 182 | public void sixOnClick(View view) 183 | { 184 | setWorkings("6"); 185 | } 186 | 187 | public void minusOnClick(View view) 188 | { 189 | setWorkings("-"); 190 | } 191 | 192 | public void oneOnClick(View view) 193 | { 194 | setWorkings("1"); 195 | } 196 | 197 | public void twoOnClick(View view) 198 | { 199 | setWorkings("2"); 200 | } 201 | 202 | public void threeOnClick(View view) 203 | { 204 | setWorkings("3"); 205 | } 206 | 207 | public void plusOnClick(View view) 208 | { 209 | setWorkings("+"); 210 | } 211 | 212 | public void decimalOnClick(View view) 213 | { 214 | setWorkings("."); 215 | } 216 | 217 | public void zeroOnClick(View view) 218 | { 219 | setWorkings("0"); 220 | } 221 | 222 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 18 | 30 | 31 | 43 | 44 | 45 | 46 | 51 | 52 | 56 | 57 |