diff --git a/res/layout/calc_eight_digit_button.xml b/res/layout/calc_eight_digit_button.xml
index 650dff8f..ed3f46ad 100644
--- a/res/layout/calc_eight_digit_button.xml
+++ b/res/layout/calc_eight_digit_button.xml
@@ -10,6 +10,7 @@
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/eightDigitButton" a:text="8"
calc:textUp="ln"
+ calc:textLeft="0b:"
calc:textDown="lg"
calc:directionTextScale="0.5"
diff --git a/res/layout/calc_five_digit_button.xml b/res/layout/calc_five_digit_button.xml
index a1250be7..c18062ec 100644
--- a/res/layout/calc_five_digit_button.xml
+++ b/res/layout/calc_five_digit_button.xml
@@ -10,6 +10,7 @@
a:id="@+id/fiveDigitButton"
a:text="5"
calc:textUp="t"
+ calc:textLeft="e"
calc:textDown="j"
style="?digitButtonStyle"
a:onClick="digitButtonClickHandler"/>
\ No newline at end of file
diff --git a/res/layout/calc_four_digit_button.xml b/res/layout/calc_four_digit_button.xml
index 9cca9b65..d7475560 100644
--- a/res/layout/calc_four_digit_button.xml
+++ b/res/layout/calc_four_digit_button.xml
@@ -10,6 +10,7 @@
a:id="@+id/fourDigitButton"
a:text="4"
calc:textUp="x"
+ calc:textLeft="d"
calc:textDown="y"
style="?digitButtonStyle"
a:onClick="digitButtonClickHandler"/>
\ No newline at end of file
diff --git a/res/layout/calc_nine_digit_button.xml b/res/layout/calc_nine_digit_button.xml
index fe28538f..327d5e6f 100644
--- a/res/layout/calc_nine_digit_button.xml
+++ b/res/layout/calc_nine_digit_button.xml
@@ -10,6 +10,7 @@
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/nineDigitButton" a:text="9"
calc:textDown="e"
+ calc:textLeft="0o:"
calc:textUp="π"
calc:directionTextScale="0.5"
style="?digitButtonStyle"
diff --git a/res/layout/calc_one_digit_button.xml b/res/layout/calc_one_digit_button.xml
index 4be170b3..f01a399c 100644
--- a/res/layout/calc_one_digit_button.xml
+++ b/res/layout/calc_one_digit_button.xml
@@ -11,6 +11,7 @@
a:id="@+id/oneDigitButton"
a:text="1"
calc:textUp="sin"
+ calc:textLeft="a"
calc:textDown="asin"
style="?digitButtonStyle"
a:onClick="digitButtonClickHandler"/>
\ No newline at end of file
diff --git a/res/layout/calc_seven_digit_button.xml b/res/layout/calc_seven_digit_button.xml
index ebbb8fcf..c467479b 100644
--- a/res/layout/calc_seven_digit_button.xml
+++ b/res/layout/calc_seven_digit_button.xml
@@ -10,6 +10,7 @@
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/sevenDigitButton" a:text="7"
calc:textUp="i"
+ calc:textLeft="0x:"
calc:textDown="!"
calc:directionTextScale="0.5"
diff --git a/res/layout/calc_six_digit_button.xml b/res/layout/calc_six_digit_button.xml
index 170391d6..91b54339 100644
--- a/res/layout/calc_six_digit_button.xml
+++ b/res/layout/calc_six_digit_button.xml
@@ -11,6 +11,7 @@
calc:textUp="deg"
a:id="@+id/sixDigitButton"
a:text="6"
+ calc:textLeft="f"
calc:textDown="rad"
style="?digitButtonStyle"
a:onClick="digitButtonClickHandler"/>
\ No newline at end of file
diff --git a/res/layout/calc_three_digit_button.xml b/res/layout/calc_three_digit_button.xml
index 75883444..a7ecee06 100644
--- a/res/layout/calc_three_digit_button.xml
+++ b/res/layout/calc_three_digit_button.xml
@@ -11,6 +11,7 @@
a:id="@+id/threeDigitButton"
a:text="3"
calc:textUp="tan"
+ calc:textLeft="c"
calc:textDown="atan"
style="?digitButtonStyle"
a:onClick="digitButtonClickHandler"/>
\ No newline at end of file
diff --git a/res/layout/calc_title.xml b/res/layout/calc_title.xml
new file mode 100644
index 00000000..1837e073
--- /dev/null
+++ b/res/layout/calc_title.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/calc_two_digit_button.xml b/res/layout/calc_two_digit_button.xml
index f2897ad6..8c05fac1 100644
--- a/res/layout/calc_two_digit_button.xml
+++ b/res/layout/calc_two_digit_button.xml
@@ -11,6 +11,7 @@
a:id="@+id/twoDigitButton"
a:text="2"
calc:textUp="cos"
+ calc:textLeft="b"
calc:textDown="acos"
style="?digitButtonStyle"
a:onClick="digitButtonClickHandler"/>
\ No newline at end of file
diff --git a/res/values/default_values.xml b/res/values/default_values.xml
index fb28c9bc..215dfecf 100644
--- a/res/values/default_values.xml
+++ b/res/values/default_values.xml
@@ -8,8 +8,10 @@
org.solovyev.android.calculator.DragButtonCalibrationActivity_distance
15;350
+
org.solovyev.android.calculator.DragButtonCalibrationActivity_angle
0;45
+
org.solovyev.android.calculator.DragButtonCalibrationActivity_duration
40;2500
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 276197f4..4ede49f7 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -6,6 +6,20 @@
+
+
+
+
+
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
index 73491017..450cab28 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
@@ -66,6 +66,8 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(this.getClass().getName(), "org.solovyev.android.calculator.CalculatorActivity.onCreate()");
+ final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
setDefaultValues(preferences);
@@ -74,6 +76,13 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
super.onCreate(savedInstanceState);
setLayout(preferences);
+ if (customTitleSupported) {
+ getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.calc_title);
+ final CalculatorAdditionalTitle additionalAdditionalTitleText = (CalculatorAdditionalTitle)findViewById(R.id.additional_title_text);
+ additionalAdditionalTitleText.init(preferences);
+ preferences.registerOnSharedPreferenceChangeListener(additionalAdditionalTitleText);
+ }
+
ResourceCache.instance.initCaptions(ApplicationContext.getInstance(), R.string.class);
firstTimeInit(preferences);
@@ -137,6 +146,8 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
private class AngleUnitsChanger implements SimpleOnDragListener.DragProcessor {
+ private final DigitButtonDragProcessor processor = new DigitButtonDragProcessor(calculatorModel);
+
@Override
public boolean processDragEvent(@NotNull DragDirection dragDirection,
@NotNull DragButton dragButton,
@@ -144,22 +155,26 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
@NotNull MotionEvent motionEvent) {
boolean result = false;
- if ( dragButton instanceof AngleUnitsButton ) {
- final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection);
- if ( directionText != null ) {
- try {
+ if (dragButton instanceof AngleUnitsButton) {
+ if (dragDirection == DragDirection.up || dragDirection == DragDirection.down ) {
+ final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection);
+ if ( directionText != null ) {
+ try {
- final AngleUnit angleUnits = AngleUnit.valueOf(directionText);
+ final AngleUnit angleUnits = AngleUnit.valueOf(directionText);
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorActivity.this);
- final SharedPreferences.Editor editor = preferences.edit();
- editor.putString(CalculatorEngine.ANGLE_UNITS_P_KEY, angleUnits.name());
- editor.commit();
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorActivity.this);
+ final SharedPreferences.Editor editor = preferences.edit();
+ editor.putString(CalculatorEngine.ANGLE_UNITS_P_KEY, angleUnits.name());
+ editor.commit();
- result = true;
- } catch (IllegalArgumentException e) {
- Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText);
+ result = true;
+ } catch (IllegalArgumentException e) {
+ Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText);
+ }
}
+ } else if ( dragDirection == DragDirection.left ) {
+ result = processor.processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
}
}
@@ -533,6 +548,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
}
calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
+ calculatorModel.evaluate();
}
@Override
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorAdditionalTitle.java b/src/main/java/org/solovyev/android/calculator/CalculatorAdditionalTitle.java
new file mode 100644
index 00000000..047c1597
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorAdditionalTitle.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.AttributeSet;
+import android.widget.TextView;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.android.calculator.model.CalculatorEngine;
+
+/**
+ * User: serso
+ * Date: 12/10/11
+ * Time: 10:34 PM
+ */
+public class CalculatorAdditionalTitle extends TextView implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ public CalculatorAdditionalTitle(Context context) {
+ super(context);
+ }
+
+ public CalculatorAdditionalTitle(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public CalculatorAdditionalTitle(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void init(@NotNull SharedPreferences preferences) {
+ onSharedPreferenceChanged(preferences, null);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String key) {
+ setText(CalculatorEngine.instance.getNumeralBaseFromPrefs(preferences) + " / " + CalculatorEngine.instance.getAngleUnitsFromPrefs(preferences));
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java b/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java
index 240156ba..325a3114 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java
@@ -35,7 +35,7 @@ public class CalculatorDisplay extends AutoResizeTextView {
private JsclOperation jsclOperation = JsclOperation.numeric;
@NotNull
- private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine());
+ private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine());
@Nullable
private Generic genericResult;
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java b/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java
index 63c2c515..56f1fa81 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java
@@ -31,7 +31,7 @@ public class CalculatorEditor extends EditText implements SharedPreferences.OnSh
private boolean highlightText = true;
@NotNull
- private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
+ private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
public CalculatorEditor(Context context) {
super(context);
diff --git a/src/main/java/org/solovyev/android/calculator/TextHighlighter.java b/src/main/java/org/solovyev/android/calculator/TextHighlighter.java
index 96c879cd..bdfb54f1 100644
--- a/src/main/java/org/solovyev/android/calculator/TextHighlighter.java
+++ b/src/main/java/org/solovyev/android/calculator/TextHighlighter.java
@@ -8,18 +8,27 @@ package org.solovyev.android.calculator;
import jscl.MathContext;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.NumberBuilder;
import org.solovyev.android.calculator.model.CalculatorParseException;
import org.solovyev.android.calculator.model.TextProcessor;
import org.solovyev.common.utils.MutableObject;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* User: serso
* Date: 10/12/11
* Time: 9:47 PM
*/
-public class TextHighlighter implements TextProcessor {
+public class TextHighlighter implements TextProcessor {
+
+ private static final Map nbFontAttributes = new HashMap();
+ static {
+ nbFontAttributes.put("color", "#008000");
+ }
@NotNull
public final MathContext mathContext;
@@ -99,6 +108,7 @@ public class TextHighlighter implements TextProcessor {
numberBuilder.process(text1, mathType, localNumberOffset);
numberOffset += localNumberOffset.getObject();
+ final String match = mathType.getMatch();
switch (mathType.getMathType()) {
case open_group_symbol:
numberOfOpenGroupSymbols++;
@@ -110,19 +120,26 @@ public class TextHighlighter implements TextProcessor {
text1.append(text.charAt(i));
break;
case operator:
- text1.append(mathType.getMatch());
- if (mathType.getMatch().length() > 1) {
- i += mathType.getMatch().length() - 1;
+ text1.append(match);
+ if (match.length() > 1) {
+ i += match.length() - 1;
}
break;
case function:
- i = processHighlightedText(text1, i, mathType.getMatch(), "i");
+ i = processHighlightedText(text1, i, match, "i", null);
break;
case constant:
- i = processHighlightedText(text1, i, mathType.getMatch(), "b");
+ i = processHighlightedText(text1, i, match, "b", null);
+ break;
+ case numeral_base:
+ i = processHighlightedText(text1, i, match, "font", nbFontAttributes);
break;
default:
- text1.append(text.charAt(i));
+ if (mathType.getMathType() == MathType.text || match.length() <= 1) {
+ text1.append(text.charAt(i));
+ } else {
+ i += match.length() - 1;
+ }
}
}
@@ -150,10 +167,19 @@ public class TextHighlighter implements TextProcessor {
return new Result(result, numberOffset);
}
- private int processHighlightedText(@NotNull StringBuilder result, int i, @NotNull String functionName, @NotNull String tag) {
- result.append("<").append(tag).append(">").append(functionName).append("").append(tag).append(">");
- if (functionName.length() > 1) {
- return i + functionName.length() - 1;
+ private int processHighlightedText(@NotNull StringBuilder result, int i, @NotNull String match, @NotNull String tag, @Nullable Map tagAttributes) {
+ result.append("<").append(tag);
+
+ if ( tagAttributes != null ) {
+ for (Map.Entry entry : tagAttributes.entrySet()) {
+ // attr1="attr1_value" attr2="attr2_value"
+ result.append(" ").append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
+ }
+ }
+
+ result.append(">").append(match).append("").append(tag).append(">");
+ if (match.length() > 1) {
+ return i + match.length() - 1;
} else {
return i;
}
diff --git a/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java b/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java
index 6ca419a6..be30865c 100644
--- a/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java
+++ b/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java
@@ -6,121 +6,21 @@
package org.solovyev.android.calculator.jscl;
-import jscl.text.msg.Messages;
+import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.solovyev.android.calculator.math.MathType;
-import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.android.calculator.model.CalculatorParseException;
import org.solovyev.android.calculator.model.TextProcessor;
-import org.solovyev.common.utils.StringUtils;
/**
* User: serso
* Date: 10/6/11
* Time: 9:48 PM
*/
-class FromJsclNumericTextProcessor implements TextProcessor {
+class FromJsclNumericTextProcessor implements TextProcessor {
@NotNull
@Override
- public String process(@NotNull String result) throws CalculatorParseException {
- try {
- final Double doubleValue = Double.valueOf(result);
-
- if (doubleValue.isInfinite()) {
- result = MathType.INFINITY;
- } else {
- result = CalculatorEngine.instance.format(doubleValue);
- }
- } catch (NumberFormatException e) {
- result = result.replace(MathType.INFINITY_JSCL, MathType.INFINITY);
- try {
- result = createResultForComplexNumber(result.replace(MathType.IMAGINARY_NUMBER_JSCL, MathType.IMAGINARY_NUMBER));
- } catch (NumberFormatException e1) {
- // throw original one
- throw new CalculatorParseException(new jscl.text.ParseException(Messages.msg_8, 0, result, result));
- }
- }
-
- return result;
+ public String process(@NotNull Generic numeric) throws CalculatorParseException {
+ return numeric.toString().replace("*", "");
}
-
- private String format(@NotNull String value) throws java.lang.NumberFormatException {
- return CalculatorEngine.instance.format(Double.valueOf(value));
- }
-
- protected String createResultForComplexNumber(@NotNull final String s) {
- final Complex complex = new Complex();
-
- final StringBuilder result = new StringBuilder();
-
- // may be it's just complex number
- int signIndex = tryRealPart(s, complex, result, "+");
- if (signIndex < 0) {
- signIndex = tryRealPart(s, complex, result, "-");
- }
-
- int multiplyIndex = s.indexOf("*");
- if (multiplyIndex >= 0) {
- complex.setImaginary(format(s.substring(signIndex >= 0 ? signIndex + 1 : 0, multiplyIndex)));
- result.append(complex.getImaginary());
-
- }
-
- result.append(MathType.IMAGINARY_NUMBER);
-
- return result.toString();
- }
-
- private int tryRealPart(@NotNull String s,
- @NotNull Complex complex,
- @NotNull StringBuilder result,
- @NotNull String sign) {
- int index = s.lastIndexOf(sign);
- if (index >= 0) {
- final String substring = s.substring(0, index);
-
- if (!StringUtils.isEmpty(substring)) {
- try {
- complex.setReal(format(substring));
- result.append(complex.getReal());
- } catch (NumberFormatException e) {
- // do nothing
- }
- }
-
- result.append(sign);
- }
-
- return index;
- }
-
- private class Complex {
-
- @Nullable
- private String real;
-
- @Nullable
- private String imaginary;
-
- @Nullable
- public String getReal() {
- return real;
- }
-
- public void setReal(@Nullable String real) {
- this.real = real;
- }
-
- @Nullable
- public String getImaginary() {
- return imaginary;
- }
-
- public void setImaginary(@Nullable String imaginary) {
- this.imaginary = imaginary;
- }
- }
-
}
diff --git a/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java b/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java
index 3f0487a2..a521b709 100644
--- a/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java
+++ b/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java
@@ -60,14 +60,14 @@ public enum JsclOperation {
};
@NotNull
- private final TextProcessor fromProcessor;
+ private final TextProcessor fromProcessor;
- JsclOperation(@NotNull TextProcessor fromProcessor) {
+ JsclOperation(@NotNull TextProcessor fromProcessor) {
this.fromProcessor = fromProcessor;
}
@NotNull
- public TextProcessor getFromProcessor() {
+ public TextProcessor getFromProcessor() {
return fromProcessor;
}
diff --git a/src/main/java/org/solovyev/android/calculator/math/MathType.java b/src/main/java/org/solovyev/android/calculator/math/MathType.java
index 4d8dcd24..fe20a4f0 100644
--- a/src/main/java/org/solovyev/android/calculator/math/MathType.java
+++ b/src/main/java/org/solovyev/android/calculator/math/MathType.java
@@ -5,6 +5,7 @@
package org.solovyev.android.calculator.math;
+import jscl.JsclMathEngine;
import jscl.NumeralBase;
import jscl.math.function.Constant;
import org.jetbrains.annotations.NotNull;
@@ -336,6 +337,14 @@ public enum MathType {
for (MathType mathType : getMathTypesByPriority()) {
final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder);
if (s != null) {
+ if ( s.length() == 1 ) {
+ if (JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) {
+ final Character ch = s.charAt(0);
+ if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) ) {
+ return new Result(MathType.digit, s);
+ }
+ }
+ }
return new Result(mathType, s);
}
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java b/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java
index 454ea55c..0ae0510d 100644
--- a/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java
+++ b/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java
@@ -20,10 +20,7 @@ import org.solovyev.common.msg.MessageRegistry;
import org.solovyev.common.utils.MutableObject;
import org.solovyev.common.utils.StringUtils;
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
-import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -38,7 +35,6 @@ public enum CalculatorEngine {
instance;
public static final String GROUPING_SEPARATOR_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator";
- private static final String GROUPING_SEPARATOR_DEFAULT = " ";
public static final String ROUND_RESULT_P_KEY = "org.solovyev.android.calculator.CalculatorModel_round_result";
public static final boolean ROUND_RESULT_DEFAULT = true;
@@ -57,15 +53,11 @@ public enum CalculatorEngine {
@NotNull
private final Object lock = new Object();
- private boolean roundResult = true;
-
- private int precision = 5;
-
@NotNull
private MathEngine engine = JsclMathEngine.instance;
@NotNull
- public final TextProcessor preprocessor = new ToJsclTextProcessor();
+ public final TextProcessor preprocessor = new ToJsclTextProcessor();
@NotNull
private final AndroidVarsRegistry varsRegister = new AndroidVarsRegistryImpl(engine.getConstantsRegistry());
@@ -78,46 +70,20 @@ public enum CalculatorEngine {
private final AndroidMathRegistry postfixFunctionsRegistry = new AndroidPostfixFunctionsRegistry(engine.getPostfixFunctionsRegistry());
- @NotNull
- private DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
-
- {
- decimalGroupSymbols.setDecimalSeparator('.');
- decimalGroupSymbols.setGroupingSeparator(GROUPING_SEPARATOR_DEFAULT.charAt(0));
- }
-
- private boolean useGroupingSeparator = true;
-
@NotNull
private ThreadKiller threadKiller = new AndroidThreadKiller();
// calculation thread timeout in milliseconds, after timeout thread would be interrupted
private int timeout = DEFAULT_TIMEOUT;
- @NotNull
- public String format(@NotNull Double value) {
- return format(value, true);
+ CalculatorEngine() {
+ this.engine.setRoundResult(true);
+ this.engine.setUseGroupingSeparator(true);
}
@NotNull
public String format(@NotNull Double value, boolean round) {
- if (!value.isInfinite() && !value.isNaN()) {
- final DecimalFormat df = new DecimalFormat();
- df.setDecimalFormatSymbols(decimalGroupSymbols);
- df.setGroupingUsed(useGroupingSeparator);
- if (round) {
- if (isRoundResult()) {
- df.setMaximumFractionDigits(instance.getPrecision());
- return df.format(new BigDecimal(value).setScale(instance.getPrecision(), BigDecimal.ROUND_HALF_UP).doubleValue());
- } else {
- return String.valueOf(value);
- }
- } else {
- return df.format(value);
- }
- } else {
- return String.valueOf(value);
- }
+ return getEngine().format(value, round);
}
public static class Result {
@@ -267,24 +233,16 @@ public enum CalculatorEngine {
final Generic genericResult = calculationResult.getObject();
- return new Result(operation.getFromProcessor().process(genericResult.toString()), operation, genericResult);
+ return new Result(operation.getFromProcessor().process(genericResult), operation, genericResult);
}
}
- private int getPrecision() {
- return precision;
- }
-
public void setPrecision(int precision) {
- this.precision = precision;
- }
-
- private boolean isRoundResult() {
- return roundResult;
+ this.getEngine().setPrecision(precision);
}
public void setRoundResult(boolean roundResult) {
- this.roundResult = roundResult;
+ this.getEngine().setRoundResult(roundResult);
}
public void init(@Nullable Context context, @Nullable SharedPreferences preferences) {
@@ -300,15 +258,15 @@ public enum CalculatorEngine {
//noinspection ConstantConditions
this.setPrecision(integerNumberMapper.parseValue(preferences.getString(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT)));
this.setRoundResult(preferences.getBoolean(ROUND_RESULT_P_KEY, ROUND_RESULT_DEFAULT));
- this.setAngleUnits(AngleUnit.valueOf(preferences.getString(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT)));
- this.setNumeralBase(NumeralBase.valueOf(preferences.getString(NUMERAL_BASES_P_KEY, NUMERAL_BASES_DEFAULT)));
+ this.setAngleUnits(getAngleUnitsFromPrefs(preferences));
+ this.setNumeralBase(getNumeralBaseFromPrefs(preferences));
- final String groupingSeparator = preferences.getString(GROUPING_SEPARATOR_P_KEY, GROUPING_SEPARATOR_DEFAULT);
+ final String groupingSeparator = preferences.getString(GROUPING_SEPARATOR_P_KEY, JsclMathEngine.GROUPING_SEPARATOR_DEFAULT);
if (StringUtils.isEmpty(groupingSeparator)) {
- this.useGroupingSeparator = false;
+ this.getEngine().setUseGroupingSeparator(false);
} else {
- this.useGroupingSeparator = true;
- this.decimalGroupSymbols.setGroupingSeparator(groupingSeparator.charAt(0));
+ this.getEngine().setUseGroupingSeparator(true);
+ this.getEngine().setGroupingSeparator(groupingSeparator.charAt(0));
}
}
@@ -316,10 +274,20 @@ public enum CalculatorEngine {
}
}
+ @NotNull
+ public NumeralBase getNumeralBaseFromPrefs(@NotNull SharedPreferences preferences) {
+ return NumeralBase.valueOf(preferences.getString(NUMERAL_BASES_P_KEY, NUMERAL_BASES_DEFAULT));
+ }
+
+ @NotNull
+ public AngleUnit getAngleUnitsFromPrefs(@NotNull SharedPreferences preferences) {
+ return AngleUnit.valueOf(preferences.getString(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT));
+ }
+
//for tests only
void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
synchronized (lock) {
- this.decimalGroupSymbols = decimalGroupSymbols;
+ this.getEngine().setDecimalGroupSymbols(decimalGroupSymbols);
}
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java
index d7859404..19cbc293 100644
--- a/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java
+++ b/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java
@@ -6,6 +6,7 @@
package org.solovyev.android.calculator.model;
+import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
/**
@@ -13,13 +14,13 @@ import org.jetbrains.annotations.NotNull;
* Date: 10/18/11
* Time: 10:39 PM
*/
-public enum DummyTextProcessor implements TextProcessor {
+public enum DummyTextProcessor implements TextProcessor {
instance;
@NotNull
@Override
- public String process(@NotNull String s) throws CalculatorParseException {
- return s;
+ public String process(@NotNull Generic s) throws CalculatorParseException {
+ return s.toString();
}
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java
index 2222324c..930c8364 100644
--- a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java
+++ b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java
@@ -1,6 +1,7 @@
package org.solovyev.android.calculator.model;
import jscl.MathContext;
+import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
@@ -13,7 +14,7 @@ import java.util.List;
* Date: 10/20/11
* Time: 2:59 PM
*/
-public class FromJsclSimplifyTextProcessor implements TextProcessor {
+public class FromJsclSimplifyTextProcessor implements TextProcessor {
@NotNull
private final MathContext mathContext;
@@ -24,7 +25,12 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor {
@NotNull
@Override
- public String process(@NotNull String s) throws CalculatorParseException {
+ public String process(@NotNull Generic from) throws CalculatorParseException {
+ final String s = from.toString();
+ return process(s);
+ }
+
+ public String process(@NotNull String s) {
final StringBuilder sb = new StringBuilder();
final NumberBuilder numberBuilder = new NumberBuilder(true, mathContext.getNumeralBase());
diff --git a/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java b/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java
index 96072790..7042622a 100644
--- a/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java
+++ b/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java
@@ -49,7 +49,7 @@ public class NumberBuilder {
final MathType.Result possibleResult;
if ((CollectionsUtils.contains(mathTypeResult.getMathType(), MathType.digit, MathType.numeral_base, MathType.dot, MathType.grouping_separator, MathType.power_10) ||
- isSignAfterE(mathTypeResult)) && numeralBaseCheck(mathTypeResult)) {
+ isSignAfterE(mathTypeResult)) && numeralBaseCheck(mathTypeResult) && numeralBaseInTheStart(mathTypeResult.getMathType())) {
if (numberBuilder == null) {
numberBuilder = new StringBuilder();
}
@@ -68,6 +68,10 @@ public class NumberBuilder {
return possibleResult == null ? mathTypeResult : possibleResult;
}
+ private boolean numeralBaseInTheStart(@NotNull MathType mathType) {
+ return mathType != MathType.numeral_base || numberBuilder == null;
+ }
+
private boolean numeralBaseCheck( @NotNull MathType.Result mathType ) {
if ( mathType.getMathType() == MathType.digit ) {
final Character ch = mathType.getMatch().charAt(0);
diff --git a/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java
index 5134d988..48b3b1a3 100644
--- a/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java
+++ b/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java
@@ -7,8 +7,8 @@ import org.jetbrains.annotations.NotNull;
* Date: 9/26/11
* Time: 12:12 PM
*/
-public interface TextProcessor {
+public interface TextProcessor {
@NotNull
- T process(@NotNull String s) throws CalculatorParseException;
+ TO process(@NotNull FROM from) throws CalculatorParseException;
}
diff --git a/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java
index 2769ee54..f434cbb1 100644
--- a/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java
+++ b/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java
@@ -15,7 +15,7 @@ import org.solovyev.common.utils.CollectionsUtils;
import java.util.ArrayList;
import java.util.List;
-class ToJsclTextProcessor implements TextProcessor {
+class ToJsclTextProcessor implements TextProcessor {
@NotNull
private static final Integer MAX_DEPTH = 20;
diff --git a/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java b/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java
index 830f2b8a..21b1061d 100644
--- a/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java
+++ b/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java
@@ -120,7 +120,18 @@ public class DirectionDragButton extends DragButton {
@NotNull
@Override
public Point2d getTextPosition(@NotNull Paint paint, @NotNull Paint basePaint, @NotNull CharSequence text, CharSequence baseText, int w, int h) {
- throw new UnsupportedOperationException("Not implemented yet!");
+ final Point2d result = new Point2d();
+
+ float width = paint.measureText(" ");
+ result.setX(width);
+
+ float selfHeight = paint.ascent() + paint.descent();
+
+ basePaint.measureText(StringUtils.getNotEmpty(baseText, "|"));
+
+ result.setY(h / 2 - selfHeight / 2);
+
+ return result;
}
}/*,
right(DragDirection.right) {
@@ -163,9 +174,9 @@ public class DirectionDragButton extends DragButton {
}
@Nullable
- public static GuiDragDirection valueOf ( @NotNull DragDirection dragDirection ) {
+ public static GuiDragDirection valueOf(@NotNull DragDirection dragDirection) {
for (GuiDragDirection guiDragDirection : values()) {
- if ( guiDragDirection.dragDirection == dragDirection ) {
+ if (guiDragDirection.dragDirection == dragDirection) {
return guiDragDirection;
}
}
@@ -204,7 +215,7 @@ public class DirectionDragButton extends DragButton {
default:
// try drag direction text
for (GuiDragDirection guiDragDirection : GuiDragDirection.values()) {
- if ( guiDragDirection.getAttributeId() == attr ) {
+ if (guiDragDirection.getAttributeId() == attr) {
this.directionTextDataMap.put(guiDragDirection, new DirectionTextData(guiDragDirection, attrValue));
break;
}
diff --git a/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java b/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java
index 5d8c0eee..1e4938c5 100644
--- a/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java
+++ b/src/main/java/org/solovyev/android/view/widgets/SimpleOnDragListener.java
@@ -62,6 +62,7 @@ public class SimpleOnDragListener implements OnDragListener, DragPreferencesChan
DragDirection direction = null;
for (Map.Entry directionEntry : distancePreferences.getDirectionPreferences().entrySet()) {
+ Log.d(String.valueOf(dragButton.getId()), "Drag direction: " + directionEntry.getKey());
Log.d(String.valueOf(dragButton.getId()), "Trying direction interval: " + directionEntry.getValue().getInterval());
if (isInInterval(directionEntry.getValue().getInterval(), distance)) {
@@ -180,7 +181,7 @@ public class SimpleOnDragListener implements OnDragListener, DragPreferencesChan
transformInterval(preferenceType, dragDirection, intervalPref);
- Log.d(SimpleOnDragListener.class.getName(), "Preference loaded. Id: " + preferenceId + ", value: " + intervalPref.toString());
+ Log.d(SimpleOnDragListener.class.getName(), "Preference loaded for " + dragDirection +". Id: " + preferenceId + ", value: " + intervalPref.toString());
final DragPreference directionPreference = new DragPreference(dragDirection, intervalPref);
@@ -207,9 +208,12 @@ public class SimpleOnDragListener implements OnDragListener, DragPreferencesChan
if (dragDirection == DragDirection.up) {
interval.setLeftBorder(180f - rightBorder);
interval.setRightBorder(180f - leftBorder);
- } else if (dragDirection == DragDirection.left || dragDirection == DragDirection.right) {
+ } else if (dragDirection == DragDirection.left ) {
interval.setLeftBorder(90f - rightBorder / 2);
- interval.setRightBorder(90f + leftBorder / 2);
+ interval.setRightBorder(90f + rightBorder / 2);
+ } else if ( dragDirection == DragDirection.right ) {
+ interval.setLeftBorder(180f + 90f - rightBorder / 2);
+ interval.setRightBorder(180f + 90f + rightBorder / 2);
}
}
diff --git a/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java b/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java
index b1d609ee..a9435605 100644
--- a/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java
+++ b/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java
@@ -48,6 +48,11 @@ public class TextHighlighterTest {
textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance);
Assert.assertEquals("0.1E3", textHighlighter.process("0.1E3").toString());
Assert.assertEquals("1E3", textHighlighter.process("1E3").toString());
+ Assert.assertEquals("20x:", textHighlighter.process("20x:").toString());
+ Assert.assertEquals("20x", textHighlighter.process("20x").toString());
+ Assert.assertEquals("22x", textHighlighter.process("22x").toString());
+ Assert.assertEquals("20t", textHighlighter.process("20t").toString());
+ Assert.assertEquals("20k", textHighlighter.process("20k").toString());
Assert.assertEquals("1 000 000E3", textHighlighter.process("1000000E3").toString());
Assert.assertEquals("-1 000 000E3", textHighlighter.process("-1000000E3").toString());
Assert.assertEquals("-1 000 000E-3", textHighlighter.process("-1000000E-3").toString());
diff --git a/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java b/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java
index 61840a50..c2bbf2d7 100644
--- a/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java
+++ b/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java
@@ -6,8 +6,12 @@
package org.solovyev.android.calculator.jscl;
+import jscl.math.Expression;
+import jscl.math.Generic;
import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.solovyev.android.calculator.model.CalculatorEngine;
/**
* User: serso
@@ -16,13 +20,20 @@ import org.junit.Test;
*/
public class FromJsclNumericTextProcessorTest {
+ @BeforeClass
+ public static void setUp() throws Exception {
+ CalculatorEngine.instance.init(null, null);
+ }
+
@Test
public void testCreateResultForComplexNumber() throws Exception {
final FromJsclNumericTextProcessor cm = new FromJsclNumericTextProcessor();
- Assert.assertEquals("1.22133+23 123i", cm.createResultForComplexNumber("1.22133232+23123*i"));
- Assert.assertEquals("1.22133+1.2i", cm.createResultForComplexNumber("1.22133232+1.2*i"));
- Assert.assertEquals("1.22i", cm.createResultForComplexNumber("1.22*i"));
- Assert.assertEquals("i", cm.createResultForComplexNumber("i"));
+ Assert.assertEquals("1.22133+23 123i", cm.process(Expression.valueOf("1.22133232+23123*i").numeric()));
+ Assert.assertEquals("1.22133+1.2i", cm.process(Expression.valueOf("1.22133232+1.2*i").numeric()));
+ Assert.assertEquals("1.22i", cm.process(Expression.valueOf("1.22*i").numeric()));
+ Assert.assertEquals("i", cm.process(Expression.valueOf("i").numeric()));
+ Generic numeric = Expression.valueOf("e^(π*i)+1").numeric();
+ junit.framework.Assert.assertEquals("0i", cm.process(numeric));
}
}
diff --git a/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java b/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java
index bb294452..92d8009f 100644
--- a/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java
+++ b/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java
@@ -132,8 +132,8 @@ public class CalculatorEngineTest {
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2.0+2.0)!").getResult());
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4.0!").getResult());
junit.framework.Assert.assertEquals("720", cm.evaluate(JsclOperation.numeric, "3!!").getResult());
- junit.framework.Assert.assertEquals("36.0", Expression.valueOf("3!^2").numeric().toString());
- junit.framework.Assert.assertEquals("3.0", Expression.valueOf("cubic(27)").numeric().toString());
+ junit.framework.Assert.assertEquals("36", Expression.valueOf("3!^2").numeric().toString());
+ junit.framework.Assert.assertEquals("3", Expression.valueOf("cubic(27)").numeric().toString());
try {
junit.framework.Assert.assertEquals("√(-1)!", cm.evaluate(JsclOperation.numeric, "i!").getResult());
fail();
@@ -369,8 +369,12 @@ public class CalculatorEngineTest {
} catch (CalculatorEvalException e) {
// ok
}
+
+ cm.getEngine().setNumeralBase(NumeralBase.hex);
+ Assert.assertEquals("637b", cm.evaluate(JsclOperation.numeric, "56ce+cad").getResult());
} finally {
cm.setNumeralBase(defaultNumeralBase);
}
}
+
}
diff --git a/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java b/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java
index a0f05808..b0066679 100644
--- a/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java
+++ b/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java
@@ -62,6 +62,11 @@ public class FromJsclSimplifyTextProcessorTest {
Assert.assertEquals("tlog(3)", tp.process("t*log(3)"));
Assert.assertEquals("t√(3)", tp.process("t*√(3)"));
+ Assert.assertEquals("20x", tp.process("20*x"));
+ Assert.assertEquals("20x", tp.process("20x"));
+ Assert.assertEquals("2×0x3", tp.process("2*0x3"));
+ Assert.assertEquals("2×0x:3", tp.process("2*0x:3"));
+ Assert.assertEquals("0x:3 000 000", tp.process("0x:3 000 000.00000000000001"));
}
}
diff --git a/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java b/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java
index 92c472ba..3f023dac 100644
--- a/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java
+++ b/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java
@@ -6,6 +6,8 @@
package org.solovyev.android.calculator.model;
+import jscl.JsclMathEngine;
+import jscl.NumeralBase;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -120,4 +122,20 @@ public class ToJsclTextProcessorTest {
@Test
public void testPostfixFunction() throws Exception {
}
+
+ @Test
+ public void testNumeralBases() throws Exception {
+ final ToJsclTextProcessor processor = new ToJsclTextProcessor();
+
+ final NumeralBase defaultNumeralBase = JsclMathEngine.instance.getNumeralBase();
+ try{
+ JsclMathEngine.instance.setNumeralBase(NumeralBase.bin);
+ Assert.assertEquals("101", JsclMathEngine.instance.evaluate("10+11"));
+
+ JsclMathEngine.instance.setNumeralBase(NumeralBase.hex);
+ Assert.assertEquals("56ce+cad", processor.process("56ce+cad").getExpression());
+ } finally {
+ JsclMathEngine.instance.setNumeralBase(defaultNumeralBase);
+ }
+ }
}