mirror of
https://github.com/SimpleMobileTools/Simple-Calculator.git
synced 2025-02-19 21:10:39 +01:00
move the functionality to an interface
- that way we can reuse all the code in the widget
This commit is contained in:
parent
aecabbe7e0
commit
de3e1312ca
@ -0,0 +1,9 @@
|
|||||||
|
package calculator.simplemobiletools.com.simple_calculator;
|
||||||
|
|
||||||
|
public interface Calculator {
|
||||||
|
String getDisplayedNumber();
|
||||||
|
|
||||||
|
void setValue(String value);
|
||||||
|
|
||||||
|
void setValueDouble(double d);
|
||||||
|
}
|
@ -0,0 +1,224 @@
|
|||||||
|
package calculator.simplemobiletools.com.simple_calculator;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public class CalculatorImpl {
|
||||||
|
private double baseValue;
|
||||||
|
private double secondValue;
|
||||||
|
private boolean resetValue;
|
||||||
|
private int lastKey;
|
||||||
|
private int lastOperation;
|
||||||
|
private Calculator callback;
|
||||||
|
|
||||||
|
public CalculatorImpl(Calculator calculatorInterface) {
|
||||||
|
callback = calculatorInterface;
|
||||||
|
resetValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetValueIfNeeded() {
|
||||||
|
if (resetValue)
|
||||||
|
callback.setValue("0");
|
||||||
|
|
||||||
|
resetValue = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetValues() {
|
||||||
|
baseValue = 0;
|
||||||
|
secondValue = 0;
|
||||||
|
resetValue = false;
|
||||||
|
lastKey = 0;
|
||||||
|
lastOperation = 0;
|
||||||
|
callback.setValue("0");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDigit(int number) {
|
||||||
|
final String currentValue = callback.getDisplayedNumber();
|
||||||
|
final String newValue = removeLeadingZero(currentValue + number);
|
||||||
|
callback.setValue(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeLeadingZero(String str) {
|
||||||
|
final double doubleValue = Double.parseDouble(str);
|
||||||
|
return Formatter.doubleToString(doubleValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateResult(double value) {
|
||||||
|
callback.setValue(Formatter.doubleToString(value));
|
||||||
|
baseValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayedNumber() {
|
||||||
|
return callback.getDisplayedNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDisplayedNumberAsDouble() {
|
||||||
|
return Double.parseDouble(getDisplayedNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleResult() {
|
||||||
|
secondValue = getDisplayedNumberAsDouble();
|
||||||
|
calculateResult();
|
||||||
|
baseValue = getDisplayedNumberAsDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculateResult() {
|
||||||
|
switch (lastOperation) {
|
||||||
|
case Constants.PLUS:
|
||||||
|
updateResult(baseValue + secondValue);
|
||||||
|
break;
|
||||||
|
case Constants.MINUS:
|
||||||
|
updateResult(baseValue - secondValue);
|
||||||
|
break;
|
||||||
|
case Constants.MULTIPLY:
|
||||||
|
updateResult(baseValue * secondValue);
|
||||||
|
break;
|
||||||
|
case Constants.DIVIDE:
|
||||||
|
divideNumbers();
|
||||||
|
break;
|
||||||
|
case Constants.MODULO:
|
||||||
|
moduloNumbers();
|
||||||
|
break;
|
||||||
|
case Constants.POWER:
|
||||||
|
powerNumbers();
|
||||||
|
break;
|
||||||
|
case Constants.ROOT:
|
||||||
|
updateResult(Math.sqrt(baseValue));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void divideNumbers() {
|
||||||
|
double resultValue = 0;
|
||||||
|
if (secondValue != 0)
|
||||||
|
resultValue = baseValue / secondValue;
|
||||||
|
|
||||||
|
updateResult(resultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moduloNumbers() {
|
||||||
|
double resultValue = 0;
|
||||||
|
if (secondValue != 0)
|
||||||
|
resultValue = baseValue % secondValue;
|
||||||
|
|
||||||
|
updateResult(resultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void powerNumbers() {
|
||||||
|
double resultValue = Math.pow(baseValue, secondValue);
|
||||||
|
if (Double.isInfinite(resultValue) || Double.isNaN(resultValue))
|
||||||
|
resultValue = 0;
|
||||||
|
updateResult(resultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleOperation(int operation) {
|
||||||
|
if (lastKey == operation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lastKey == Constants.DIGIT)
|
||||||
|
handleResult();
|
||||||
|
|
||||||
|
resetValue = true;
|
||||||
|
lastKey = operation;
|
||||||
|
lastOperation = operation;
|
||||||
|
|
||||||
|
if (operation == Constants.ROOT)
|
||||||
|
calculateResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleClear() {
|
||||||
|
final String oldValue = getDisplayedNumber();
|
||||||
|
String newValue;
|
||||||
|
final int len = oldValue.length();
|
||||||
|
int minLen = 1;
|
||||||
|
if (oldValue.contains("-"))
|
||||||
|
minLen++;
|
||||||
|
|
||||||
|
if (len > minLen)
|
||||||
|
newValue = oldValue.substring(0, len - 1);
|
||||||
|
else
|
||||||
|
newValue = "0";
|
||||||
|
|
||||||
|
if (newValue.equals("-0"))
|
||||||
|
newValue = "0";
|
||||||
|
|
||||||
|
callback.setValue(newValue);
|
||||||
|
baseValue = Double.parseDouble(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleLongClear() {
|
||||||
|
resetValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleEquals() {
|
||||||
|
if (lastKey == Constants.EQUALS)
|
||||||
|
calculateResult();
|
||||||
|
|
||||||
|
if (lastKey != Constants.DIGIT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
secondValue = getDisplayedNumberAsDouble();
|
||||||
|
calculateResult();
|
||||||
|
lastKey = Constants.EQUALS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void decimalClicked() {
|
||||||
|
String value = getDisplayedNumber();
|
||||||
|
if (!value.contains("."))
|
||||||
|
value += ".";
|
||||||
|
callback.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void zeroClicked() {
|
||||||
|
String value = getDisplayedNumber();
|
||||||
|
if (!value.equals("0"))
|
||||||
|
value += "0";
|
||||||
|
callback.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void numpadClicked(View view) {
|
||||||
|
if (lastKey == Constants.EQUALS)
|
||||||
|
lastOperation = Constants.EQUALS;
|
||||||
|
lastKey = Constants.DIGIT;
|
||||||
|
resetValueIfNeeded();
|
||||||
|
|
||||||
|
switch (view.getId()) {
|
||||||
|
case R.id.btn_decimal:
|
||||||
|
decimalClicked();
|
||||||
|
break;
|
||||||
|
case R.id.btn_0:
|
||||||
|
zeroClicked();
|
||||||
|
break;
|
||||||
|
case R.id.btn_1:
|
||||||
|
addDigit(1);
|
||||||
|
break;
|
||||||
|
case R.id.btn_2:
|
||||||
|
addDigit(2);
|
||||||
|
break;
|
||||||
|
case R.id.btn_3:
|
||||||
|
addDigit(3);
|
||||||
|
break;
|
||||||
|
case R.id.btn_4:
|
||||||
|
addDigit(4);
|
||||||
|
break;
|
||||||
|
case R.id.btn_5:
|
||||||
|
addDigit(5);
|
||||||
|
break;
|
||||||
|
case R.id.btn_6:
|
||||||
|
addDigit(6);
|
||||||
|
break;
|
||||||
|
case R.id.btn_7:
|
||||||
|
addDigit(7);
|
||||||
|
break;
|
||||||
|
case R.id.btn_8:
|
||||||
|
addDigit(8);
|
||||||
|
break;
|
||||||
|
case R.id.btn_9:
|
||||||
|
addDigit(9);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package calculator.simplemobiletools.com.simple_calculator;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
public static final int DIGIT = 0;
|
||||||
|
public static final int EQUALS = 1;
|
||||||
|
public static final int PLUS = 2;
|
||||||
|
public static final int MINUS = 3;
|
||||||
|
public static final int MULTIPLY = 4;
|
||||||
|
public static final int DIVIDE = 5;
|
||||||
|
public static final int MODULO = 6;
|
||||||
|
public static final int POWER = 7;
|
||||||
|
public static final int ROOT = 8;
|
||||||
|
}
|
@ -10,299 +10,89 @@ import butterknife.ButterKnife;
|
|||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import butterknife.OnLongClick;
|
import butterknife.OnLongClick;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity implements Calculator {
|
||||||
@Bind(R.id.result) TextView result;
|
@Bind(R.id.result) TextView result;
|
||||||
|
|
||||||
private double baseValue;
|
private CalculatorImpl calc;
|
||||||
private double secondValue;
|
|
||||||
private boolean resetValue;
|
|
||||||
private int lastKey;
|
|
||||||
private int lastOperation;
|
|
||||||
|
|
||||||
public static final int DIGIT = 0;
|
|
||||||
public static final int EQUALS = 1;
|
|
||||||
public static final int PLUS = 2;
|
|
||||||
public static final int MINUS = 3;
|
|
||||||
public static final int MULTIPLY = 4;
|
|
||||||
public static final int DIVIDE = 5;
|
|
||||||
public static final int MODULO = 6;
|
|
||||||
public static final int POWER = 7;
|
|
||||||
public static final int ROOT = 8;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
resetValues();
|
calc = new CalculatorImpl(this);
|
||||||
}
|
|
||||||
|
|
||||||
public void resetValues() {
|
|
||||||
baseValue = 0;
|
|
||||||
secondValue = 0;
|
|
||||||
resetValue = false;
|
|
||||||
lastKey = 0;
|
|
||||||
lastOperation = 0;
|
|
||||||
setValueDouble(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addDigit(int number) {
|
|
||||||
final String currentValue = getDisplayedNumber();
|
|
||||||
final String newValue = removeLeadingZero(currentValue + number);
|
|
||||||
setValue(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
result.setText(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValueDouble(double d) {
|
|
||||||
setValue(Formatter.doubleToString(d));
|
|
||||||
lastKey = DIGIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String removeLeadingZero(String str) {
|
|
||||||
final double doubleValue = Double.parseDouble(str);
|
|
||||||
return Formatter.doubleToString(doubleValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplayedNumber() {
|
public String getDisplayedNumber() {
|
||||||
return result.getText().toString();
|
return result.getText().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getDisplayedNumberAsDouble() {
|
|
||||||
return Double.parseDouble(getDisplayedNumber());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetValueIfNeeded() {
|
|
||||||
if (resetValue)
|
|
||||||
setValueDouble(0);
|
|
||||||
|
|
||||||
resetValue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void divideNumbers() {
|
|
||||||
double resultValue = 0;
|
|
||||||
if (secondValue != 0)
|
|
||||||
resultValue = baseValue / secondValue;
|
|
||||||
|
|
||||||
updateResult(resultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moduloNumbers() {
|
|
||||||
double resultValue = 0;
|
|
||||||
if (secondValue != 0)
|
|
||||||
resultValue = baseValue % secondValue;
|
|
||||||
|
|
||||||
updateResult(resultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void powerNumbers() {
|
|
||||||
double resultValue = Math.pow(baseValue, secondValue);
|
|
||||||
if (Double.isInfinite(resultValue) || Double.isNaN(resultValue))
|
|
||||||
resultValue = 0;
|
|
||||||
updateResult(resultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleOperation(int operation) {
|
|
||||||
if (lastKey == operation)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (lastKey == DIGIT)
|
|
||||||
handleResult();
|
|
||||||
|
|
||||||
resetValue = true;
|
|
||||||
lastKey = operation;
|
|
||||||
lastOperation = operation;
|
|
||||||
|
|
||||||
if (operation == ROOT)
|
|
||||||
calculateResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleClear() {
|
|
||||||
final String oldValue = getDisplayedNumber();
|
|
||||||
String newValue;
|
|
||||||
final int len = oldValue.length();
|
|
||||||
int minLen = 1;
|
|
||||||
if (oldValue.contains("-"))
|
|
||||||
minLen++;
|
|
||||||
|
|
||||||
if (len > minLen)
|
|
||||||
newValue = oldValue.substring(0, len - 1);
|
|
||||||
else
|
|
||||||
newValue = "0";
|
|
||||||
|
|
||||||
if (newValue.equals("-0"))
|
|
||||||
newValue = "0";
|
|
||||||
|
|
||||||
setValue(newValue);
|
|
||||||
baseValue = Double.parseDouble(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleLongClear() {
|
|
||||||
resetValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleEquals() {
|
|
||||||
if (lastKey == EQUALS)
|
|
||||||
calculateResult();
|
|
||||||
|
|
||||||
if (lastKey != DIGIT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
secondValue = getDisplayedNumberAsDouble();
|
|
||||||
calculateResult();
|
|
||||||
lastKey = EQUALS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.btn_plus)
|
@OnClick(R.id.btn_plus)
|
||||||
public void plusClicked() {
|
public void plusClicked() {
|
||||||
handleOperation(PLUS);
|
calc.handleOperation(Constants.PLUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_minus)
|
@OnClick(R.id.btn_minus)
|
||||||
public void minusClicked() {
|
public void minusClicked() {
|
||||||
handleOperation(MINUS);
|
calc.handleOperation(Constants.MINUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_multiply)
|
@OnClick(R.id.btn_multiply)
|
||||||
public void multiplyClicked() {
|
public void multiplyClicked() {
|
||||||
handleOperation(MULTIPLY);
|
calc.handleOperation(Constants.MULTIPLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_divide)
|
@OnClick(R.id.btn_divide)
|
||||||
public void divideClicked() {
|
public void divideClicked() {
|
||||||
handleOperation(DIVIDE);
|
calc.handleOperation(Constants.DIVIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_modulo)
|
@OnClick(R.id.btn_modulo)
|
||||||
public void moduloClicked() {
|
public void moduloClicked() {
|
||||||
handleOperation(MODULO);
|
calc.handleOperation(Constants.MODULO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_power)
|
@OnClick(R.id.btn_power)
|
||||||
public void powerClicked() {
|
public void powerClicked() {
|
||||||
handleOperation(POWER);
|
calc.handleOperation(Constants.POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_root)
|
@OnClick(R.id.btn_root)
|
||||||
public void rootClicked() {
|
public void rootClicked() {
|
||||||
handleOperation(ROOT);
|
calc.handleOperation(Constants.ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_clear)
|
@OnClick(R.id.btn_clear)
|
||||||
public void clearClicked() {
|
public void clearClicked() {
|
||||||
handleClear();
|
calc.handleClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnLongClick(R.id.btn_clear)
|
@OnLongClick(R.id.btn_clear)
|
||||||
public boolean clearLongClicked() {
|
public boolean clearLongClicked() {
|
||||||
handleLongClear();
|
calc.handleLongClear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btn_equals)
|
@OnClick(R.id.btn_equals)
|
||||||
public void equalsClicked() {
|
public void equalsClicked() {
|
||||||
handleEquals();
|
calc.handleEquals();
|
||||||
}
|
|
||||||
|
|
||||||
public void decimalClicked() {
|
|
||||||
String value = getDisplayedNumber();
|
|
||||||
if (!value.contains("."))
|
|
||||||
value += ".";
|
|
||||||
setValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void zeroClicked() {
|
|
||||||
String value = getDisplayedNumber();
|
|
||||||
if (!value.equals("0"))
|
|
||||||
value += "0";
|
|
||||||
setValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateResult(double value) {
|
|
||||||
setValue(Formatter.doubleToString(value));
|
|
||||||
baseValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleResult() {
|
|
||||||
secondValue = getDisplayedNumberAsDouble();
|
|
||||||
calculateResult();
|
|
||||||
baseValue = getDisplayedNumberAsDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void calculateResult() {
|
|
||||||
switch (lastOperation) {
|
|
||||||
case PLUS:
|
|
||||||
updateResult(baseValue + secondValue);
|
|
||||||
break;
|
|
||||||
case MINUS:
|
|
||||||
updateResult(baseValue - secondValue);
|
|
||||||
break;
|
|
||||||
case MULTIPLY:
|
|
||||||
updateResult(baseValue * secondValue);
|
|
||||||
break;
|
|
||||||
case DIVIDE:
|
|
||||||
divideNumbers();
|
|
||||||
break;
|
|
||||||
case MODULO:
|
|
||||||
moduloNumbers();
|
|
||||||
break;
|
|
||||||
case POWER:
|
|
||||||
powerNumbers();
|
|
||||||
break;
|
|
||||||
case ROOT:
|
|
||||||
updateResult(Math.sqrt(baseValue));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick({R.id.btn_decimal, R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8,
|
@OnClick({R.id.btn_decimal, R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8,
|
||||||
R.id.btn_9})
|
R.id.btn_9})
|
||||||
public void numpadClicked(View view) {
|
public void numpadClicked(View view) {
|
||||||
if (lastKey == EQUALS)
|
calc.numpadClicked(view);
|
||||||
lastOperation = EQUALS;
|
}
|
||||||
lastKey = DIGIT;
|
|
||||||
resetValueIfNeeded();
|
|
||||||
|
|
||||||
switch (view.getId()) {
|
@Override
|
||||||
case R.id.btn_decimal:
|
public void setValue(String value) {
|
||||||
decimalClicked();
|
result.setText(value);
|
||||||
break;
|
}
|
||||||
case R.id.btn_0:
|
|
||||||
zeroClicked();
|
@Override
|
||||||
break;
|
public void setValueDouble(double d) {
|
||||||
case R.id.btn_1:
|
setValue(Formatter.doubleToString(d));
|
||||||
addDigit(1);
|
//lastKey = Constants.DIGIT;
|
||||||
break;
|
|
||||||
case R.id.btn_2:
|
|
||||||
addDigit(2);
|
|
||||||
break;
|
|
||||||
case R.id.btn_3:
|
|
||||||
addDigit(3);
|
|
||||||
break;
|
|
||||||
case R.id.btn_4:
|
|
||||||
addDigit(4);
|
|
||||||
break;
|
|
||||||
case R.id.btn_5:
|
|
||||||
addDigit(5);
|
|
||||||
break;
|
|
||||||
case R.id.btn_6:
|
|
||||||
addDigit(6);
|
|
||||||
break;
|
|
||||||
case R.id.btn_7:
|
|
||||||
addDigit(7);
|
|
||||||
break;
|
|
||||||
case R.id.btn_8:
|
|
||||||
addDigit(8);
|
|
||||||
break;
|
|
||||||
case R.id.btn_9:
|
|
||||||
addDigit(9);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user