changes
This commit is contained in:
parent
cfe1adad08
commit
2c27a10540
@ -1,27 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<manifest xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
package="org.solovyev.android.calculator"
|
||||
versionCode="1"
|
||||
versionName="1.0">
|
||||
package="org.solovyev.android.calculator"
|
||||
versionCode="1"
|
||||
versionName="1.0">
|
||||
|
||||
<uses-sdk a:minSdkVersion="8"/>
|
||||
|
||||
<application a:icon="@drawable/icon" a:label="@string/c_app_name">
|
||||
<application a:icon="@drawable/icon" a:label="@string/c_app_name">
|
||||
|
||||
<activity a:name=".CalculatorActivity" a:label="@string/c_app_name">
|
||||
<intent-filter>
|
||||
<action a:name="android.intent.action.MAIN" />
|
||||
<category a:name="android.intent.category.LAUNCHER" />
|
||||
<activity a:name=".CalculatorActivity"
|
||||
a:windowSoftInputMode="stateHidden"
|
||||
a:label="@string/c_app_name">
|
||||
<intent-filter>
|
||||
<action a:name="android.intent.action.MAIN"/>
|
||||
<category a:name="android.intent.category.LAUNCHER"/>
|
||||
<action a:name="org.solovyev.android.calculator.CalculatorActivity.insertText"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity a:name=".CalculatorPreferencesActivity" a:label="@string/c_app_settings"/>
|
||||
<activity a:name=".AboutActivity" a:label="@string/c_about"/>
|
||||
<activity a:name=".CalculatorVarsActivity"
|
||||
a:label="@string/c_vars_and_constants"
|
||||
a:configChanges="orientation|keyboardHidden" />
|
||||
<activity a:name=".CalculatorPreferencesActivity"
|
||||
a:label="@string/c_app_settings"/>
|
||||
|
||||
</application>
|
||||
<activity a:name=".AboutActivity"
|
||||
a:label="@string/c_about"/>
|
||||
|
||||
<activity a:name=".CalculatorVarsActivity"
|
||||
a:label="@string/c_vars_and_constants"
|
||||
a:configChanges="orientation|keyboardHidden"/>
|
||||
|
||||
</application>
|
||||
</manifest>
|
BIN
res/drawable/copy.png
Normal file
BIN
res/drawable/copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
BIN
res/drawable/heart.png
Normal file
BIN
res/drawable/heart.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
res/drawable/heart_original.png
Normal file
BIN
res/drawable/heart_original.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.1 KiB |
@ -17,73 +17,68 @@
|
||||
|
||||
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/leftButton"
|
||||
calc:textUp="↞"
|
||||
a:text="←"
|
||||
a:layout_weight="1.5"
|
||||
style="@style/control_button_style"
|
||||
a:onClick="moveLeftButtonClickHandler"/>
|
||||
<include layout="@layout/calc_left_button"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1.5"/>
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/eraseButton"
|
||||
a:text="@string/c_erase"
|
||||
a:layout_weight="1.5"
|
||||
style="@style/control_button_style"
|
||||
a:onClick="eraseButtonClickHandler"/>
|
||||
|
||||
<include layout="@layout/calc_display"/>
|
||||
<include layout="@layout/calc_erase_button"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1.5"/>
|
||||
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/clearButton"
|
||||
a:text="@string/c_clear"
|
||||
a:layout_weight="1.5"
|
||||
style="@style/control_button_style"
|
||||
a:onClick="clearButtonClickHandler"/>
|
||||
<include layout="@layout/calc_display"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1"/>
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/rightButton"
|
||||
calc:textUp="↠"
|
||||
a:text="→"
|
||||
a:layout_weight="1.5"
|
||||
style="@style/control_button_style"
|
||||
a:onClick="moveRightButtonClickHandler"/>
|
||||
<include layout="@layout/calc_clear_button"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1.5"/>
|
||||
|
||||
<include layout="@layout/calc_right_button"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1.5"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
||||
|
||||
<include layout="@layout/calc_equals_button"/>
|
||||
<include layout="@layout/calc_paste_button"/>
|
||||
<include layout="@layout/calc_one_digit_button"/>
|
||||
<include layout="@layout/calc_two_digit_button"/>
|
||||
<include layout="@layout/calc_three_digit_button"/>
|
||||
<include layout="@layout/calc_multiplication_button"/>
|
||||
<include layout="@layout/calc_division_button"/>
|
||||
<include layout="@layout/calc_equals_button"/>
|
||||
<include layout="@layout/calc_paste_button"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
||||
|
||||
<include layout="@layout/calc_history_button"/>
|
||||
<include layout="@layout/calc_copy_button"/>
|
||||
<include layout="@layout/calc_four_digit_button"/>
|
||||
<include layout="@layout/calc_five_digit_button"/>
|
||||
<include layout="@layout/calc_six_digit_button"/>
|
||||
<include layout="@layout/calc_plus_button"/>
|
||||
<include layout="@layout/calc_subtraction_button"/>
|
||||
<include layout="@layout/calc_square_brackets_button"/>
|
||||
<include layout="@layout/calc_history_button"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
||||
|
||||
<include layout="@layout/calc_vars_button"/>
|
||||
<include layout="@layout/calc_square_brackets_button"/>
|
||||
<include layout="@layout/calc_seven_digit_button"/>
|
||||
<include layout="@layout/calc_eight_digit_button"/>
|
||||
<include layout="@layout/calc_nine_digit_button"/>
|
||||
<include layout="@layout/calc_zero_digit_button"/>
|
||||
<include layout="@layout/calc_round_brackets_button"/>
|
||||
<include layout="@layout/calc_vars_button"/>
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton a:text="" style="@style/control_button_style"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -17,15 +17,15 @@
|
||||
|
||||
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton
|
||||
xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:id="@+id/equalsButton"
|
||||
a:text="="
|
||||
a:layout_weight="4"
|
||||
style="@style/control_button_style"
|
||||
a:onClick="numericButtonClickHandler"/>
|
||||
<include layout="@layout/calc_equals_button"
|
||||
a:layout_weight="4"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_width="match_parent" />
|
||||
|
||||
<include layout="@layout/calc_display"/>
|
||||
<include layout="@layout/calc_display"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -65,7 +65,7 @@
|
||||
<include layout="@layout/calc_zero_digit_button"/>
|
||||
<include layout="@layout/calc_square_brackets_button"/>
|
||||
<include layout="@layout/calc_subtraction_button"/>
|
||||
<include layout="@layout/calc_history_button"/>
|
||||
<include layout="@layout/calc_copy_button"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -75,11 +75,8 @@
|
||||
<include layout="@layout/calc_left_button"/>
|
||||
<include layout="@layout/calc_right_button"/>
|
||||
<include layout="@layout/calc_vars_button"/>
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton a:text="" style="@style/control_button_style"/>
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton a:text="" style="@style/control_button_style"/>
|
||||
|
||||
<include layout="@layout/calc_donate_button"/>
|
||||
<include layout="@layout/calc_history_button"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
15
res/layout/calc_copy_button.xml
Normal file
15
res/layout/calc_copy_button.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ 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
|
||||
-->
|
||||
|
||||
<ImageButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/pasteButton"
|
||||
a:src="@drawable/copy"
|
||||
style="@style/control_button_style"
|
||||
a:padding="6dp"
|
||||
a:onClick="copyButtonClickHandler"/>
|
@ -8,7 +8,7 @@
|
||||
|
||||
<org.solovyev.android.calculator.CalculatorDisplay
|
||||
xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:id="@+id/resultEditText"
|
||||
a:id="@+id/calculatorDisplay"
|
||||
style="@style/display_style"
|
||||
a:layout_weight="1"
|
||||
a:minLines="1"
|
||||
|
15
res/layout/calc_donate_button.xml
Normal file
15
res/layout/calc_donate_button.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ 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
|
||||
-->
|
||||
|
||||
<ImageButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/pasteButton"
|
||||
a:src="@drawable/heart"
|
||||
style="@style/control_button_style"
|
||||
a:padding="6dp"
|
||||
a:onClick="donateButtonClickHandler"/>
|
@ -12,7 +12,7 @@
|
||||
a:layout_height="0dp">
|
||||
|
||||
<org.solovyev.android.calculator.CalculatorEditor
|
||||
a:id="@+id/editText"
|
||||
a:id="@+id/calculatorEditor"
|
||||
style="@style/editor_style"
|
||||
a:inputType="textMultiLine"
|
||||
a:maxLines="4"
|
||||
|
@ -55,4 +55,5 @@
|
||||
<string name="c_pi_description">Отношение длины окружности к диаметру</string>
|
||||
<string name="c_e_description">Вещесвтенное число, такое что производная функции f(x) = e^x в точке x = 0 равно 1</string>
|
||||
<string name="c_i_description">Мнимая единица, определённая как i^2 = −1</string>
|
||||
<string name="c_calc_editor_hint">Введите новое выражение</string>
|
||||
</resources>
|
||||
|
@ -58,5 +58,6 @@
|
||||
<string name="c_pi_description">Ratio of any circle\'s circumference to its diameter</string>
|
||||
<string name="c_e_description">Unique real number such that the value of the derivative (slope of the tangent line) of the function f(x) = e^x at the point x = 0 is equal to 1</string>
|
||||
<string name="c_i_description">Imaginary unit, defined such that i^2 = −1</string>
|
||||
<string name="c_calc_editor_hint"></string>
|
||||
<string name="c_calc_editor_hint">Enter new expression</string>
|
||||
<string name="c_press_to_copy">Press to copy</string>
|
||||
</resources>
|
||||
|
@ -7,6 +7,7 @@ package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.*;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.ClipboardManager;
|
||||
@ -100,6 +101,9 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
}
|
||||
|
||||
private void init() {
|
||||
|
||||
calculatorView = new CalculatorView(this, CalculatorModel.instance);
|
||||
|
||||
insertTextReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@ -128,9 +132,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
// todo serso: create serso runtime exception
|
||||
throw new RuntimeException("Could not initialize interpreter!");
|
||||
}
|
||||
|
||||
this.calculatorView = new CalculatorView(this, CalculatorModel.instance);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
@ -191,6 +192,11 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void copyButtonClickHandler(@NotNull View v) {
|
||||
calculatorView.copyResult(this);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void clearButtonClickHandler(@NotNull View v) {
|
||||
calculatorView.clear();
|
||||
@ -207,6 +213,14 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
startActivity(new Intent(this, CalculatorVarsActivity.class));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void donateButtonClickHandler(@NotNull View v) {
|
||||
final String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=android%2ecalculator%40se%2esolovyev¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted";
|
||||
final Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse(paypalDonateUrl));
|
||||
startActivity(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@ -12,19 +13,24 @@ import org.jetbrains.annotations.Nullable;
|
||||
* Date: 9/17/11
|
||||
* Time: 11:05 PM
|
||||
*/
|
||||
public class CalculatorDisplayHistoryState extends EditorHistoryState {
|
||||
public class CalculatorDisplayHistoryState {
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
@NotNull
|
||||
private final EditorHistoryState editorHistoryState;
|
||||
|
||||
public CalculatorDisplayHistoryState() {
|
||||
this.editorHistoryState = new EditorHistoryState();
|
||||
}
|
||||
|
||||
public CalculatorDisplayHistoryState(boolean valid) {
|
||||
this.editorHistoryState = new EditorHistoryState();
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public CalculatorDisplayHistoryState(int cursorPosition, @Nullable String text, boolean valid) {
|
||||
super(cursorPosition, text);
|
||||
this.editorHistoryState = new EditorHistoryState(cursorPosition, text);
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
@ -35,4 +41,29 @@ public class CalculatorDisplayHistoryState extends EditorHistoryState {
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public EditorHistoryState getEditorHistoryState() {
|
||||
return editorHistoryState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof CalculatorDisplayHistoryState)) return false;
|
||||
|
||||
CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o;
|
||||
|
||||
if (valid != that.valid) return false;
|
||||
if (editorHistoryState != null ? !editorHistoryState.equals(that.editorHistoryState) : that.editorHistoryState != null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (valid ? 1 : 0);
|
||||
result = 31 * result + (editorHistoryState != null ? editorHistoryState.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.utils.history.HistoryAction;
|
||||
import org.solovyev.common.utils.history.HistoryHelper;
|
||||
import org.solovyev.common.utils.history.SimpleHistoryHelper;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/9/11
|
||||
* Time: 6:35 PM
|
||||
*/
|
||||
public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
|
||||
|
||||
instance;
|
||||
|
||||
private final HistoryHelper<CalculatorHistoryState> historyHelper = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.historyHelper.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState getLastHistoryState() {
|
||||
return this.historyHelper.getLastHistoryState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoAvailable() {
|
||||
return historyHelper.isUndoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
|
||||
return historyHelper.undo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRedoAvailable() {
|
||||
return historyHelper.isRedoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
|
||||
return historyHelper.redo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
|
||||
return historyHelper.isActionAvailable(historyAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
|
||||
return historyHelper.doAction(historyAction, currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addState(@Nullable CalculatorHistoryState currentState) {
|
||||
historyHelper.addState(currentState);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.text.ClipboardManager;
|
||||
import android.util.Log;
|
||||
@ -21,11 +22,10 @@ import org.solovyev.android.calculator.model.CalculatorModel;
|
||||
import org.solovyev.android.calculator.model.ParseException;
|
||||
import org.solovyev.android.view.CursorControl;
|
||||
import org.solovyev.android.view.HistoryControl;
|
||||
import org.solovyev.android.view.widgets.SoftKeyboardDisabler;
|
||||
import org.solovyev.common.utils.MutableObject;
|
||||
import org.solovyev.common.utils.StringUtils;
|
||||
import org.solovyev.common.utils.history.HistoryAction;
|
||||
import org.solovyev.common.utils.history.HistoryHelper;
|
||||
import org.solovyev.common.utils.history.SimpleHistoryHelper;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@ -46,35 +46,43 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
@NotNull
|
||||
private final CalculatorModel calculatorModel;
|
||||
|
||||
@NotNull
|
||||
private final HistoryHelper<CalculatorHistoryState> history;
|
||||
|
||||
public CalculatorView(@NotNull final Activity activity, @NotNull CalculatorModel calculator) {
|
||||
this.calculatorModel = calculator;
|
||||
|
||||
this.editor = (CalculatorEditor) activity.findViewById(R.id.editText);
|
||||
this.editor = (CalculatorEditor) activity.findViewById(R.id.calculatorEditor);
|
||||
this.editor.setOnTouchListener(new SoftKeyboardDisabler());
|
||||
|
||||
this.display = (CalculatorDisplay) activity.findViewById(R.id.resultEditText);
|
||||
this.display = (CalculatorDisplay) activity.findViewById(R.id.calculatorDisplay);
|
||||
this.display.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (((CalculatorDisplay) v).isValid()) {
|
||||
final CharSequence text = ((TextView) v).getText();
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
final ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text);
|
||||
Toast.makeText(activity, activity.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
copyResult(activity);
|
||||
}
|
||||
});
|
||||
|
||||
this.history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
saveHistoryState();
|
||||
|
||||
final CalculatorHistoryState lastState = CalculatorHistory.instance.getLastHistoryState();
|
||||
if ( lastState == null ) {
|
||||
saveHistoryState();
|
||||
} else {
|
||||
setCurrentHistoryState(lastState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void copyResult(@NotNull Context context) {
|
||||
if (display.isValid()) {
|
||||
final CharSequence text = display.getText();
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text);
|
||||
Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveHistoryState() {
|
||||
history.addState(getCurrentHistoryState());
|
||||
CalculatorHistory.instance.addState(getCurrentHistoryState());
|
||||
}
|
||||
|
||||
|
||||
@ -117,14 +125,14 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
// allow only one runner at one time
|
||||
synchronized (currentRunner) {
|
||||
//lock all operations with history
|
||||
synchronized (history) {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
// do only if nothing was post delayed before current instance was posted
|
||||
if (currentRunner.getObject() == this) {
|
||||
// actually nothing shall be logged while text operations are done
|
||||
evaluate(editorStateAfter);
|
||||
|
||||
if (history.isUndoAvailable()) {
|
||||
history.undo(getCurrentHistoryState());
|
||||
if (CalculatorHistory.instance.isUndoAvailable()) {
|
||||
CalculatorHistory.instance.undo(getCurrentHistoryState());
|
||||
}
|
||||
|
||||
saveHistoryState();
|
||||
@ -212,9 +220,9 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
|
||||
@Override
|
||||
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
||||
synchronized (history) {
|
||||
if (history.isActionAvailable(historyAction)) {
|
||||
final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState());
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
if (CalculatorHistory.instance.isActionAvailable(historyAction)) {
|
||||
final CalculatorHistoryState newState = CalculatorHistory.instance.doAction(historyAction, getCurrentHistoryState());
|
||||
if (newState != null) {
|
||||
setCurrentHistoryState(newState);
|
||||
}
|
||||
@ -224,7 +232,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
|
||||
@Override
|
||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||
synchronized (history) {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
setValuesFromHistory(this.editor, editorHistoryState.getEditorState());
|
||||
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
|
||||
|
||||
@ -233,7 +241,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
}
|
||||
|
||||
private void setValuesFromHistory(@NotNull CalculatorDisplay display, CalculatorDisplayHistoryState editorHistoryState) {
|
||||
setValuesFromHistory(display, (EditorHistoryState)editorHistoryState);
|
||||
setValuesFromHistory(display, editorHistoryState.getEditorHistoryState());
|
||||
display.setValid(editorHistoryState.isValid());
|
||||
}
|
||||
|
||||
@ -247,7 +255,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
@Override
|
||||
@NotNull
|
||||
public CalculatorHistoryState getCurrentHistoryState() {
|
||||
synchronized (history) {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
return new CalculatorHistoryState(getEditorHistoryState(this.editor), getCalculatorDisplayHistoryState(this.display));
|
||||
}
|
||||
}
|
||||
@ -264,8 +272,8 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
private CalculatorDisplayHistoryState getCalculatorDisplayHistoryState(@NotNull CalculatorDisplay display) {
|
||||
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
|
||||
|
||||
result.setText(String.valueOf(display.getText()));
|
||||
result.setCursorPosition(display.getSelectionStart());
|
||||
result.getEditorHistoryState().setText(String.valueOf(display.getText()));
|
||||
result.getEditorHistoryState().setCursorPosition(display.getSelectionStart());
|
||||
result.setValid(display.isValid());
|
||||
|
||||
return result;
|
||||
|
@ -39,5 +39,23 @@ public class EditorHistoryState {
|
||||
return cursorPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof EditorHistoryState)) return false;
|
||||
|
||||
EditorHistoryState that = (EditorHistoryState) o;
|
||||
|
||||
if (cursorPosition != that.cursorPosition) return false;
|
||||
if (text != null ? !text.equals(that.text) : that.text != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = cursorPosition;
|
||||
result = 31 * result + (text != null ? text.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -37,11 +37,13 @@ public class Functions {
|
||||
public final static String EXP = "exp";
|
||||
public final static String SQRT_SIGN = "√";
|
||||
public final static String SQRT = "sqrt";
|
||||
public final static String E = "E";
|
||||
public final static String E_POWER = "10^";
|
||||
|
||||
public static final List<String> allPrefix;
|
||||
|
||||
static {
|
||||
final List<String> functions = new ArrayList<String>(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP));
|
||||
final List<String> functions = new ArrayList<String>(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP, E));
|
||||
Collections.sort(functions, new MathEntityComparator());
|
||||
allPrefix = functions;
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ class ToJsclTextProcessor implements TextProcessor {
|
||||
sb.append(')');
|
||||
} else if (ch == '×' || ch == '∙') {
|
||||
sb.append("*");
|
||||
} else if ( mathType == MathType.function ){
|
||||
} else if (mathType == MathType.function) {
|
||||
sb.append(toJsclFunction(mathTypeResult.getMatch()));
|
||||
i += mathTypeResult.getMatch().length() - 1;
|
||||
} else if ( mathType == MathType.constant ) {
|
||||
} else if (mathType == MathType.constant) {
|
||||
sb.append(mathTypeResult.getMatch());
|
||||
i += mathTypeResult.getMatch().length() - 1;
|
||||
} else {
|
||||
@ -148,6 +148,8 @@ class ToJsclTextProcessor implements TextProcessor {
|
||||
result = Functions.LOG;
|
||||
} else if (function.equals(Functions.SQRT_SIGN)) {
|
||||
result = Functions.SQRT;
|
||||
} else if (function.equals(Functions.E)) {
|
||||
result = Functions.E_POWER;
|
||||
} else {
|
||||
result = function;
|
||||
}
|
||||
@ -178,9 +180,9 @@ class ToJsclTextProcessor implements TextProcessor {
|
||||
|
||||
@NotNull
|
||||
private static MathType.Result checkMultiplicationSignBeforeFunction(@NotNull StringBuilder sb,
|
||||
@NotNull String s,
|
||||
int i,
|
||||
@Nullable MathType.Result mathTypeBeforeResult) {
|
||||
@NotNull String s,
|
||||
int i,
|
||||
@Nullable MathType.Result mathTypeBeforeResult) {
|
||||
MathType.Result result = MathType.getType(s, i);
|
||||
|
||||
if (i > 0) {
|
||||
|
@ -13,8 +13,6 @@ import android.text.TextPaint;
|
||||
import android.util.AttributeSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.view.widgets.DragButton;
|
||||
import org.solovyev.android.view.widgets.DragDirection;
|
||||
import org.solovyev.common.utils.Point2d;
|
||||
import org.solovyev.common.utils.StringUtils;
|
||||
|
||||
@ -101,11 +99,11 @@ public class DirectionDragButton extends DragButton {
|
||||
initUpDownTextPaint(basePaint);
|
||||
|
||||
if (textUp != null) {
|
||||
textUpPosition = getTextPosition(upDownTextPaint, basePaint, textUp, 1);
|
||||
textUpPosition = getTextPosition(upDownTextPaint, basePaint, textUp, getText(), 1, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
if (textDown != null) {
|
||||
textDownPosition = getTextPosition(upDownTextPaint, basePaint, textDown, -1);
|
||||
textDownPosition = getTextPosition(upDownTextPaint, basePaint, textDown, getText(), -1, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
if ( textDownPosition != null && textUpPosition != null ) {
|
||||
@ -118,21 +116,21 @@ public class DirectionDragButton extends DragButton {
|
||||
|
||||
}
|
||||
|
||||
private Point2d getTextPosition(@NotNull Paint paint, @NotNull Paint basePaint, @NotNull CharSequence text, float direction) {
|
||||
public static Point2d getTextPosition(@NotNull Paint paint, @NotNull Paint basePaint, @NotNull CharSequence text, CharSequence baseText, float direction, int w, int h) {
|
||||
final Point2d result = new Point2d();
|
||||
|
||||
float width = paint.measureText(text.toString() + " ");
|
||||
result.setX(getWidth() - width);
|
||||
result.setX(w - width);
|
||||
|
||||
float selfHeight = paint.ascent() + paint.descent();
|
||||
|
||||
basePaint.measureText(StringUtils.getNotEmpty(getText(), "|"));
|
||||
basePaint.measureText(StringUtils.getNotEmpty(baseText, "|"));
|
||||
|
||||
float height = getHeight() - basePaint.ascent() - basePaint.descent();
|
||||
float height = h - basePaint.ascent() - basePaint.descent();
|
||||
if (direction < 0) {
|
||||
result.setY(height / 2 - direction * height / 3 + selfHeight);
|
||||
result.setY(height / 2 + height / 3 + selfHeight);
|
||||
} else {
|
||||
result.setY(height / 2 - direction * height / 3);
|
||||
result.setY(height / 2 - height / 3);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.view.widgets;
|
||||
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/9/11
|
||||
* Time: 4:27 PM
|
||||
*/
|
||||
public class SoftKeyboardDisabler implements View.OnTouchListener {
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
boolean result;
|
||||
Log.d(this.getClass().getName(), "org.solovyev.android.view.widgets.SoftKeyboardDisabler.onTouch(): action=" + event.getAction() + ", event=" + event);
|
||||
|
||||
if (v instanceof EditText) {
|
||||
final EditText editText = (EditText) v;
|
||||
int inputType = editText.getInputType();
|
||||
int selectionStart = editText.getSelectionStart();
|
||||
int selectionEnd = editText.getSelectionEnd();
|
||||
|
||||
// disable soft input
|
||||
editText.setInputType(InputType.TYPE_NULL);
|
||||
editText.onTouchEvent(event);
|
||||
|
||||
// restore input type
|
||||
editText.setInputType(inputType);
|
||||
editText.setSelection(selectionStart, selectionEnd);
|
||||
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
package org.solovyev.android.calculator.model;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@ -16,16 +17,23 @@ import org.junit.Test;
|
||||
*/
|
||||
public class ToJsclPreprocessorTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
CalculatorModel.instance.init(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcess() throws Exception {
|
||||
final ToJsclTextProcessor preprocessor = new ToJsclTextProcessor();
|
||||
|
||||
Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)"));
|
||||
Assert.assertEquals( "pi*sin(4)*pi*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))"));
|
||||
Assert.assertEquals( "pi*sin(4)+pi*cos(sqrt(5))", preprocessor.process("πsin(4)+πcos(√(5))"));
|
||||
Assert.assertEquals( "pi*sin(4)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4)+πcos(√(5+i))"));
|
||||
Assert.assertEquals( "pi*sin(4.01)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4.01)+πcos(√(5+i))"));
|
||||
Assert.assertEquals( "exp(1)^pi*sin(4.01)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))"));
|
||||
Assert.assertEquals( "3.141592653589793*sin(4)*3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))"));
|
||||
Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)+πcos(√(5))"));
|
||||
Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4)+πcos(√(5+i))"));
|
||||
Assert.assertEquals( "3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4.01)+πcos(√(5+i))"));
|
||||
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))"));
|
||||
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))*10^2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2"));
|
||||
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))*10^-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -44,7 +52,7 @@ public class ToJsclPreprocessorTest {
|
||||
Assert.assertEquals(4, preprocessor.getPostfixFunctionStart("2.23+(5.4434234*sin(5.1+1))!", 26));
|
||||
Assert.assertEquals(0, preprocessor.getPostfixFunctionStart("sin(5)!", 5));
|
||||
Assert.assertEquals(0, preprocessor.getPostfixFunctionStart("sin(5sin(5sin(5)))!", 17));
|
||||
Assert.assertEquals(1, preprocessor.getPostfixFunctionStart("2+sin(5sin(5sin(5)))!", 19));
|
||||
Assert.assertEquals(4, preprocessor.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1+1))!", 29));
|
||||
Assert.assertEquals(2, preprocessor.getPostfixFunctionStart("2+sin(5sin(5sin(5)))!", 19));
|
||||
Assert.assertEquals(5, preprocessor.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1+1))!", 29));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user